Skip to content

fix(network): preserve late block-sync response correlation#216

Closed
ValarDragon wants to merge 1 commit into
mainfrom
agent/preserve-block-sync-late-responses
Closed

fix(network): preserve late block-sync response correlation#216
ValarDragon wants to merge 1 commit into
mainfrom
agent/preserve-block-sync-late-responses

Conversation

@ValarDragon

Copy link
Copy Markdown
Contributor

Motivation

Sending GetBlocks arms the peer's no-progress accounting. If another delivery
path commits that height first, floor GC removes the obsolete scheduling request
and its response correlation. The requested body can then arrive on the wire,
be discarded as an unmatched stale response, and leave the healthy peer capped
until it is parked or disconnected.

This is the Covered/floor-GC late-response case discussed in #192 and #209.

Solution

  • Retain private correlation metadata for unreceived blocks removed by local
    commit GC. Entries are one-shot, expire with the peer liveness window, are
    cleared on destructive reset, and have a hard per-peer bound.
  • Before ordinary stale-response handling, accept a matching height and header
    hash only after checking its size envelope, transaction-effects Merkle root,
    and transaction uniqueness.
  • Credit that exact response as peer progress without resubmitting the
    already-committed block or sampling it for BBR.
  • Reject unrelated or malformed stale bodies without unlocking the next
    cold-start request.
  • Add regression coverage for both the valid late-response path and invalid
    response variants, and document the user-visible fix in both changelogs.

The implementation changes only private block-sync internals; it introduces no
pub or pub(crate) API changes.

Testing

  • cargo fmt --all -- --check
  • cargo clippy -p zakura-network --all-targets -- -D warnings
  • cargo test -p zakura-network --lib local_commit_gc — 2 passed
  • cargo test -p zakura-network --lib zakura::block_sync::tests — 181 passed

The positive regression test forces floor GC, proves height 2 is not requested
before the late height-1 response, then verifies the response unlocks height 2
without resubmitting height 1. The negative test verifies that a different block
and a same-header body with a bad transaction Merkle root do not unlock the
peer.

Specifications & References

Related to #192 and #209. This is a focused alternative for the Covered/floor-GC
race; it does not supersede #209's broader retired-request, ownership, reset,
timeout, and terminator-correlation work.

Follow-up Work

This patch deliberately counts an already-committed correlated body as peer
progress. #209 instead distinguishes correlation from useful block progress.
Maintainers should choose that policy before this draft is marked ready: a peer
that consistently answers only after another path commits could otherwise reset
its no-progress accounting.

Because the stale body is never submitted, this path performs local structural
checks rather than full consensus authorization-data verification. Full NU5+
body authentication would require retaining the relevant authenticated metadata
or routing the body through consensus without committing it.

AI disclosure: OpenAI Codex was used to diagnose the CI failure, implement the
private block-sync correlation state and regression tests, run validation, and
draft this PR description. The contributor reviewed the changes and test
results.

@v12-auditor

v12-auditor Bot commented Jul 16, 2026

Copy link
Copy Markdown

Note

Complete: Audit complete. No review-worthy issues remain after automatic triage. One finding was auto-invalidated.

Open the full results here.

Analyzed two files, diff 18dbc60...2e1e16e.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant