Skip to content

dash-spv: protect fork recovery against malicious headers #1103

Open

Description

@ZocoLini

Follow-up from #1102 (fork recovery) and its CodeRabbit review.

Problem

BlockHeadersManager::fork_height emits SyncEvent::ForkDetected as soon as a peer sends a header whose parent is a stored block below our tip, and handle_fork truncates headers, filter headers, filters and blocks down to that parent.

Headers are checked for continuity and PoW before fork detection (#1102), but PoW is only checked against the header's own bits; the expected difficulty (DGW) is not enforced. A peer can therefore mine a header with trivial bits on top of any stored block and make the client drop and re-download everything above it, at any depth.

Proposal

Bound forks by the last validated ChainLock:

  • A fork below the last ChainLock is invalid by definition: ignore it (and penalise the peer).
  • A fork above it: handle_fork truncates down to the ChainLock height instead of the height the peer chose, so a fake fork can cost at most re-syncing the few blocks above the ChainLock.
  • BlockHeadersManager must know the best ChainLock from startup (it is persisted in metadata, but today only re-broadcast once masternode sync is ready).

Open questions

  • What to do while no ChainLock is known (regtest, initial sync before masternodes are ready): fall back to the fork height, or ignore forks.
  • Whether to also require the branch to carry more chain work than the stored chain above the fork, with bits bounded against our stored blocks at the same height.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions