DC-NODE-16
DC derived enforcedReceive idempotency: a peer-delivered block already durably present byte-identically in the ChainDb (same slot, same hash) is an idempotent no-op at the durable-admit chokepoint (pump_block) -- no validation step, no WAL append, no tip change; the post-state is identical and replay-equivalent. A DIFFERENT block (different hash) at/before the last-applied slot is NOT short-circuited: it reaches the unchanged BLUE header authority and fails closed (SlotBeforeLastApplied / BlockNoOutOfOrder). The skip is gated on HASH equality vs the durable store, never slot alone; no skip-past, no fork-choice (DC-CONS-03 untouched).
- Source
docs/clusters/PHASE4-N-AE/slices/AE.F.md; docs/planning/phase4-n-ae-f-echo-idempotency-invariants.md; docs/evidence/phase4-n-ae-ce-a5-relay-adoption.md
- Introduced in
- PHASE4-N-AE
Enforcement trace
Tests 3
- pump_block_reannounced_block_is_idempotent_noop
- pump_block_different_block_at_or_before_tip_still_fails_closed
- run_node_sync_survives_reannounced_block_in_feed
Cross-references
Evidence notes
PHASE4-N-AE.F (2026-06-07). ENFORCED. Closes the post-CE-A5 echo: after the relay adopted Ade's forged block 17 it re-announced that block over Ade's follow link, and the BLUE header authority correctly rejected SlotBeforeLastApplied{last=421,attempted=421} -- terminating the run (exit 43) AFTER AddedToCurrentChain (not a manifest blocker, but it ends a continuous run). Fix: pump_block, immediately after decode_block, queries db.get_block_by_hash(&decoded.block_hash); if Some(stored) AND stored.slot == decoded.header_input.slot it returns Ok(None) (idempotent no-op) BEFORE the RollForward/BlockDelivered reducer steps. get_block_by_hash is hash-exact, so a different block (different hash) returns None, falls through to the unchanged validate_and_apply_header, and fails closed (AE-F-INV-2). The no-op runs no reducer step and appends nothing to the WAL, so warm-start replay is unaffected (T-REC-05 / DC-WAL-02 preserved). RED chokepoint only; NO BLUE change -- a refinement of the sketch's BLUE ReceiveOutcome::AlreadyHave: get_block_by_hash is a DETERMINISTIC durable-store query (not nondeterminism), so the gate lives at the chokepoint with no new reducer input and the BLUE authority is untouched. CE-F1 pump_block_reannounced_block_is_idempotent_noop (re-pump -> Ok(None); chain-dep last_slot / WAL length / ChainDb tip unchanged); CE-F2 pump_block_different_block_at_or_before_tip_still_fails_closed (a different lower-slot block -> SlotBeforeLastApplied); CE-F4 run_node_sync_survives_reannounced_block_in_feed (run_node_sync over [block, same-block] completes, admits exactly once, no exit-43). Gate ci_check_receive_idempotency.sh fences hash-keyed + gate-before-reducer + slot-consistency.