Move processing-result classification to the producer side

Reshape BlockProcessingResult from the AC-verdict-passthrough
Ok/Err/Ignored enum to Imported(info) | Error { penalty, reason }.
The producer (network_beacon_processor) translates beacon-chain
Result<AvailabilityProcessingStatus, BlockError> into this shape via a
new classify_processing_result(), so the consumer only has to resolve
the symbolic WhichPeerToPenalize against an in-scope PeerGroup.

- on_block_processing_result and on_data_processing_result collapse
  to a single state-match each, then dispatch to
  WhichPeerToPenalize::apply(action, &peer_group, reason, cx).
- mod.rs sheds the per-BlockError policy block (-129 lines).
- Drops the now-unused data_peer_group, block_peer, BlockRequest::peer,
  peek_downloaded_peer_group accessors; their job is the consumer's
  responsibility now.
- Ignored becomes Error { penalty: None, reason: "processor_overloaded" }
  with a producer-side warn!; the lookup retries up to MAX_ATTEMPTS
  instead of dropping immediately (test updated to match).
- DuplicateFullyImported and GenesisBlock map to Imported; the test
  helper constructs the new variant directly.
This commit is contained in:
dapplion
2026-05-19 14:14:42 -06:00
parent 5c58f7e4b7
commit a98e6531bf
5 changed files with 206 additions and 226 deletions

View File

@@ -47,9 +47,7 @@ use crate::sync::block_lookups::{AwaitingParent, BlockComponent, DownloadResult}
use crate::sync::custody_backfill_sync::CustodyBackFillSync;
use crate::sync::network_context::{PeerGroup, RpcResponseResult};
use beacon_chain::block_verification_types::AsBlock;
use beacon_chain::{
AvailabilityProcessingStatus, BeaconChain, BeaconChainTypes, BlockError, EngineState,
};
use beacon_chain::{BeaconChain, BeaconChainTypes, EngineState};
use futures::StreamExt;
use lighthouse_network::SyncInfo;
use lighthouse_network::rpc::RPCError;
@@ -206,11 +204,52 @@ impl BlockProcessType {
}
}
/// The classified outcome of submitting a block / blob / column for processing. The producer
/// (`network_beacon_processor`) translates the raw beacon-chain `Result<_, BlockError>` into this
/// shape so the lookup state machine only has to resolve "which peer to penalize" symbolically.
#[derive(Debug)]
pub enum BlockProcessingResult {
Ok(AvailabilityProcessingStatus),
Err(BlockError),
Ignored,
/// Data was imported (or already present, or otherwise satisfies the lookup). `info` is a
/// short stable identifier suitable for debug logs / metrics.
Imported(&'static str),
/// Processing failed. `penalty` is `Some` when an attributable peer should be downscored.
Error {
penalty: Option<(PeerAction, WhichPeerToPenalize)>,
reason: &'static str,
},
}
/// Symbolic identifier for the peer(s) the lookup should resolve and downscore. The consumer
/// passes in the relevant `PeerGroup` (a singleton for block processing, the in-flight data peer
/// group for data processing) and `apply` selects from it.
#[derive(Debug, Clone, Copy)]
pub enum WhichPeerToPenalize {
/// All peers in the passed `PeerGroup` (typically a singleton constructed from the block peer
/// or the blob peer — i.e. the peer responsible for the component as a whole).
BlockPeer,
/// The custody peer(s) that served a specific column index in the passed `PeerGroup`.
CustodyPeerForColumn(u64),
}
impl WhichPeerToPenalize {
/// Resolve this symbolic identifier against `peer_group` and downscore the matching peer(s).
pub fn apply<T: BeaconChainTypes>(
self,
action: PeerAction,
peer_group: &crate::sync::network_context::PeerGroup,
reason: &'static str,
cx: &mut crate::sync::network_context::SyncNetworkContext<T>,
) {
let peers: Vec<PeerId> = match self {
WhichPeerToPenalize::BlockPeer => peer_group.all().copied().collect(),
WhichPeerToPenalize::CustodyPeerForColumn(idx) => {
peer_group.of_index(idx as usize).copied().collect()
}
};
for peer in peers {
cx.report_peer(peer, action, reason);
}
}
}
/// The result of processing multiple blocks (a chain segment).
@@ -1470,18 +1509,3 @@ impl<T: BeaconChainTypes> SyncManager<T> {
&self.network_globals().spec
}
}
impl From<Result<AvailabilityProcessingStatus, BlockError>> for BlockProcessingResult {
fn from(result: Result<AvailabilityProcessingStatus, BlockError>) -> Self {
match result {
Ok(status) => BlockProcessingResult::Ok(status),
Err(e) => BlockProcessingResult::Err(e),
}
}
}
impl From<BlockError> for BlockProcessingResult {
fn from(e: BlockError) -> Self {
BlockProcessingResult::Err(e)
}
}