CN-PROD-04
CN derived enforcedEvery CoordinatorEffect::BroadcastBlock reconstructs the AcceptedBlock from artifact.bytes through the BLUE self_accept authority against the pre-forge base, then admits it to the served ServedChainSnapshot via the single ServedChainHandle::push_atomic authority before the next slot tick. If the self_accept replay rejects, push_atomic is NOT called and the loop emits structured BroadcastPushError::SelfAcceptReplayRejected. ProducerLogEvent::BlockServed is emitted only for blocks present in the served snapshot. No silently-dropped (no-op) broadcast; only self-accepted forged blocks are served.
- Source
docs/planning/phase4-n-t-invariants.md §1 (A4, A5); docs/clusters/PHASE4-N-T/cluster.md §1
- Cluster
- PHASE4-N-T
- Introduced in
- PHASE4-N-T
Enforcement trace
Code
Tests 3
- broadcast_pushes_self_accepted_block_to_served
- broadcast_rejects_non_self_accepted_block
- forge_to_served_block_fetch_roundtrip
CI 0
no CI script — gap
Cross-references
Strengthened in
Attack rationale
Cardano-specific: serving a block that failed self-accept (or silently dropping a forged block) would either propagate an invalid block to peers or advertise a chain the producer cannot actually serve. Gating push_atomic behind the self_accept replay and fail-closing on rejection makes 'served but not self-accepted' unrepresentable.
Evidence notes
S4 test broadcast_rejects_non_self_accepted_block (rejection -> no push, BroadcastPushError::SelfAcceptReplayRejected); S5 loopback test produce_forge_to_served_block_fetch_roundtrip (served block readable byte-identically via block-fetch). BlockServed is the existing closed ProducerLogEvent variant (producer_log.rs:154), emitted only for present blocks.