Skip to content

Fork And Finalized Conflict Handling

NOOSChain currently assumes deterministic finality. Once a block is committed, local finalized history is immutable. A remote peer that reports the same height with a different finalized hash is not a normal fork-choice event; it is a severe operational incident.

The conflict layer is intentionally separate from HTTP sync internals. Sync reports conflicts through the ChainConflictPolicy interface, and the default implementation is FinalizedConflictPolicy. Future deployments can replace that policy with a Raft committed-log policy, a CometBFT quorum-certificate/evidence policy, or a manual disaster-recovery policy without rewriting deterministic execution.

The Raft MVP also treats post-commit execution divergence as an incident. If a voter applies a committed Raft block entry and cannot reproduce the entry's block hash or state root, the adapter records a critical conflict and enters incident mode. It does not automatically reorg, rewrite history, or select a different log.

Default Policy

The default deterministic-finality policy does not perform automatic reorgs and does not choose the longest or heaviest chain.

  • same_height_different_hash: critical, quarantine peer, enter incident mode
  • genesis_mismatch: critical, quarantine peer
  • previous_hash_mismatch: critical, quarantine peer
  • state_root_mismatch: critical, quarantine peer, enter incident mode
  • block_hash_mismatch: critical, quarantine peer
  • merkle_root_mismatch: critical, quarantine peer
  • protocol_version_mismatch: critical, quarantine peer

Persistence

Conflicts are stored in chain_conflicts. Active incidents are stored in chain_incidents. Quarantined peers are disabled in trusted_peers and annotated with quarantine_reason / quarantined_at.

Resolving an incident is an operator action. It marks the incident resolved but never mutates chain history, never rewrites blocks, and never performs recovery by itself.

Incident Mode

While an incident is active:

  • /sync/run refuses unless explicitly forced
  • automatic sync manager loops do not run
  • /consensus/propose-block refuses to commit new blocks
  • normal read APIs remain available
  • outbound transaction propagation is suppressed for locally submitted transactions

This protects the audit trail until an operator reviews the conflicting peer, configuration, and local state.

Conflict handling also reports peer-score events. A finalized conflict records finalized_conflict, which locally quarantines the peer and heavily penalizes its score. This reputation signal is still operational metadata only; it does not suspend validators or change voting power.

Operators responding to an active finalized-history conflict should use Conflict Handling For Operators. That runbook covers evidence collection, peer quarantine, forced sync, state-root triage, snapshot recovery, and incident resolution.

Not Implemented

  • automatic reorg
  • longest-chain or heaviest-chain fork choice
  • slashing
  • Byzantine evidence verification
  • CometBFT quorum-certificate validation
  • Raft committed-log reconciliation

Those are future policy implementations behind the same conflict-policy boundary.

Audience-first NOOSChain documentation.