get things compiling

This commit is contained in:
realbigsean
2023-04-20 13:38:05 -04:00
parent 374ec4800a
commit c7142495fd
12 changed files with 369 additions and 194 deletions

View File

@@ -911,6 +911,7 @@ impl<T: BeaconChainTypes> Worker<T> {
);
return None;
}
_ => todo!(), //TODO(sean)
};
metrics::inc_counter(&metrics::BEACON_PROCESSOR_GOSSIP_BLOCK_VERIFIED_TOTAL);

View File

@@ -19,7 +19,7 @@ use slog::{debug, error, info, warn};
use ssz_types::FixedVector;
use std::sync::Arc;
use tokio::sync::mpsc;
use types::{BlobSidecar, Epoch, Hash256, SignedBeaconBlock};
use types::{BlobSidecar, Epoch, EthSpec, Hash256, SignedBeaconBlock};
/// Id associated to a batch processing request, either a sync batch or a parent lookup.
#[derive(Clone, Debug, PartialEq)]
@@ -90,8 +90,6 @@ impl<T: BeaconChainTypes> Worker<T> {
let slot = block.slot();
let parent_root = block.message().parent_root();
// TODO(sean) check availability here and send information to sync?
let result = self
.chain
.process_block(
@@ -151,9 +149,20 @@ impl<T: BeaconChainTypes> Worker<T> {
seen_timestamp: Duration,
process_type: BlockProcessType,
) {
let Some(slot) = blobs.iter().find_map(|blob|{
if let Some(blob) = blob {
Some(blob.slot)
} else {
None
}
}) else {
return;
};
let result = self
.chain
.check_availability_and_maybe_import(
slot,
|chain| {
chain
.data_availability_checker
@@ -167,7 +176,7 @@ impl<T: BeaconChainTypes> Worker<T> {
self.send_sync_message(SyncMessage::BlockPartProcessed {
process_type,
result: result.into(),
response_type: ResponseType::Blobs,
response_type: ResponseType::Blob,
});
}

View File

@@ -24,6 +24,7 @@ use super::{
};
use crate::beacon_processor::{ChainSegmentProcessId, WorkEvent};
use crate::metrics;
use crate::sync::block_lookups::single_block_lookup::LookupVerifyError;
mod parent_lookup;
mod single_block_lookup;
@@ -121,14 +122,19 @@ impl<T: BeaconChainTypes> BlockLookups<T> {
.single_block_lookups
.iter_mut()
.any(|(block_id, blob_id, single_block_request)| {
single_block_request.add_peer(&hash, &peer_id)
if single_block_request.requested_block_root == hash {
single_block_request.block_request_state.add_peer(&peer_id);
single_block_request.blob_request_state.add_peer(&peer_id);
return true;
}
false
})
{
return;
}
if self.parent_lookups.iter_mut().any(|parent_req| {
parent_req.add_block_peer(&hash, &peer_id) || parent_req.contains_block(&hash)
parent_req.add_peer(&hash, &peer_id) || parent_req.contains_block(&hash)
}) {
// If the block was already downloaded, or is being downloaded in this moment, do not
// request it.
@@ -187,7 +193,7 @@ impl<T: BeaconChainTypes> BlockLookups<T> {
) {
self.search_block_with(
|request| {
let _ = request.add_block_wrapper(block_root, block);
let _ = request.add_block_wrapper(block_root, block.clone());
},
block_root,
peer_id,
@@ -215,8 +221,7 @@ impl<T: BeaconChainTypes> BlockLookups<T> {
// Make sure this block is not already downloaded, and that neither it or its parent is
// being searched for.
if self.parent_lookups.iter_mut().any(|parent_req| {
parent_req.contains_block(&block_root)
|| parent_req.add_block_peer(&block_root, &peer_id)
parent_req.contains_block(&block_root) || parent_req.add_peer(&block_root, &peer_id)
}) {
// we are already searching for this block, ignore it
return;
@@ -247,62 +252,57 @@ impl<T: BeaconChainTypes> BlockLookups<T> {
cx: &mut SyncNetworkContext<T>,
) {
let stream_terminator = block.is_none().into();
let log = self.log.clone();
let Some((request_id_ref, request_ref)) = self.find_single_lookup_request(id, stream_terminator, ResponseType::Block) else {
let Some((triggered_parent_request, request_id_ref, request_ref)) = self.find_single_lookup_request(id, stream_terminator, ResponseType::Block) else {
return;
};
if let Err(error) = request_ref.verify_block(block).and_then(|root_block_opt| {
if let Some((root, block)) = root_block_opt {
// Only send for processing if we don't have parent requests that were triggered by
// this block.
let triggered_parent_request = self
.parent_lookups
.iter()
.any(|lookup| lookup.chain_hash() == root);
let should_remove = match request_ref.verify_block(block) {
Ok(Some((root, block))) => {
if triggered_parent_request {
// The lookup status here is irrelevant because we wait until the parent chain
// is complete before processing the block.
let _ = request_ref.add_block(root, block)?;
if let Err(e) = request_ref.add_block(root, block) {
Self::handle_block_lookup_verify_error(
id,
peer_id,
cx,
request_id_ref,
request_ref,
e,
&log,
)
} else {
false
}
} else {
// This is the correct block, send it for processing
if self
.send_block_for_processing(
root,
BlockWrapper::Block(block),
seen_timestamp,
BlockProcessType::SingleBlock { id },
cx,
)
.is_err()
{
// Remove to avoid inconsistencies
self.single_block_lookups
.retain(|(block_id, _, _)| block_id != &Some(id));
}
self.send_block_for_processing(
root,
BlockWrapper::Block(block),
seen_timestamp,
BlockProcessType::SingleBlock { id },
cx,
)
.is_err()
}
}
Ok(None) => false,
Err(e) => Self::handle_blob_lookup_verify_error(
id,
peer_id,
cx,
request_id_ref,
request_ref,
e,
&log,
),
};
Ok(())
}) {
let msg: &str = error.into();
cx.report_peer(peer_id, PeerAction::LowToleranceError, msg);
debug!(self.log, "Single block lookup failed";
"peer_id" => %peer_id, "error" => msg, "block_root" => %request_ref.requested_block_root);
// try the request again if possible
if let Ok((peer_id, request)) = request_ref.request_block() {
if let Ok(id) = cx.single_block_lookup_request(peer_id, request) {
*request_id_ref = id;
} else {
self.single_block_lookups
.retain(|(block_id, _, _)| block_id != &Some(id));
}
} else {
self.single_block_lookups
.retain(|(block_id, _, _)| block_id != &Some(id));
}
if should_remove {
self.single_block_lookups
.retain(|(block_id, _, _)| block_id != &Some(id));
}
metrics::set_gauge(
@@ -321,60 +321,58 @@ impl<T: BeaconChainTypes> BlockLookups<T> {
) {
let stream_terminator = blob.is_none().into();
let Some((request_id_ref, request_ref)) = self.find_single_lookup_request(id, stream_terminator, ResponseType::Blob) else {
let log = self.log.clone();
let Some((triggered_parent_request, request_id_ref, request_ref)) =
self.find_single_lookup_request(id, stream_terminator, ResponseType::Blob) else {
return;
};
if let Err(error) = request_ref.verify_blob(blob).and_then(|root_blobs_opt| {
if let Some((block_root, blobs)) = root_blobs_opt {
// Only send for processing if we don't have parent requests that were triggered by
// this block.
let triggered_parent_request = self
.parent_lookups
.iter()
.any(|lookup| lookup.chain_hash() == block_root);
let should_remove = match request_ref.verify_blob(blob) {
Ok(Some((block_root, blobs))) => {
if triggered_parent_request {
// The lookup status here is irrelevant because we wait until the parent chain
// is complete before processing the block.
let _ = request_ref.add_blobs(block_root, blobs)?;
if let Err(e) = request_ref.add_blobs(block_root, blobs) {
Self::handle_blob_lookup_verify_error(
id,
peer_id,
cx,
request_id_ref,
request_ref,
e,
&log,
)
} else {
false
}
} else {
// These are the correct blobs, send them for processing
if self
.send_blobs_for_processing(
block_root,
blobs,
seen_timestamp,
BlockProcessType::SingleBlock { id },
cx,
)
.is_err()
{
// Remove to avoid inconsistencies
self.single_block_lookups
.retain(|(_, blob_id, _)| blob_id != &Some(id));
}
self.send_blobs_for_processing(
block_root,
blobs,
seen_timestamp,
BlockProcessType::SingleBlock { id },
cx,
)
.is_err()
}
}
Ok(())
}) {
let msg: &str = error.into();
cx.report_peer(peer_id, PeerAction::LowToleranceError, msg);
Ok(None) => false,
Err(e) => Self::handle_blob_lookup_verify_error(
id,
peer_id,
cx,
request_id_ref,
request_ref,
e,
&log,
),
};
debug!(self.log, "Single block lookup failed";
"peer_id" => %peer_id, "error" => msg, "block_root" => %request_ref.requested_block_root);
// try the request again if possible
if let Ok((peer_id, request)) = request_ref.request_blobs() {
if let Ok(id) = cx.single_blobs_lookup_request(peer_id, request) {
*request_id_ref = id;
} else {
self.single_block_lookups
.retain(|(_, blob_id, _)| blob_id != &Some(id));
}
} else {
self.single_block_lookups
.retain(|(_, blob_id, _)| blob_id != &Some(id));
}
if should_remove {
self.single_block_lookups
.retain(|(_, blob_id, _)| blob_id != &Some(id));
}
metrics::set_gauge(
@@ -383,16 +381,89 @@ impl<T: BeaconChainTypes> BlockLookups<T> {
);
}
//TODO(sean) reduce duplicate code
fn handle_block_lookup_verify_error(
id: Id,
peer_id: PeerId,
cx: &mut SyncNetworkContext<T>,
request_id_ref: &mut Id,
request_ref: &mut SingleBlockLookup<3, T>,
error: LookupVerifyError,
log: &Logger,
) -> bool {
let requested_block_root = request_ref.requested_block_root;
let msg: &str = error.into();
cx.report_peer(peer_id, PeerAction::LowToleranceError, msg);
debug!(log, "Single block lookup failed";
"peer_id" => %peer_id, "error" => msg, "block_root" => ?requested_block_root);
// try the request again if possible
match request_ref.request_block() {
Ok(Some((peer_id, request))) => {
if let Ok(id) = cx.single_block_lookup_request(peer_id, request) {
*request_id_ref = id;
} else {
return true;
}
}
Ok(None) => {}
Err(e) => {
debug!(log, "Single block lookup failed";
"peer_id" => %peer_id, "error" => ?e, "block_root" => %requested_block_root);
return true;
}
}
false
}
fn handle_blob_lookup_verify_error(
id: Id,
peer_id: PeerId,
cx: &mut SyncNetworkContext<T>,
request_id_ref: &mut Id,
request_ref: &mut SingleBlockLookup<3, T>,
error: LookupVerifyError,
log: &Logger,
) -> bool {
let requested_block_root = request_ref.requested_block_root;
let msg: &str = error.into();
cx.report_peer(peer_id, PeerAction::LowToleranceError, msg);
debug!(log, "Single block lookup failed";
"peer_id" => %peer_id, "error" => msg, "block_root" => ?requested_block_root);
// try the request again if possible
match request_ref.request_blobs() {
Ok(Some((peer_id, request))) => {
if let Ok(id) = cx.single_blobs_lookup_request(peer_id, request) {
*request_id_ref = id;
} else {
return true;
}
}
Ok(None) => {}
Err(e) => {
debug!(log, "Single block lookup failed";
"peer_id" => %peer_id, "error" => ?e, "block_root" => %requested_block_root);
return true;
}
}
false
}
fn find_single_lookup_request(
&mut self,
target_id: Id,
stream_terminator: StreamTerminator,
response_type: ResponseType,
) -> Option<(
bool,
&mut Id,
&mut SingleBlockLookup<SINGLE_BLOCK_LOOKUP_MAX_ATTEMPTS, T>,
)> {
let lookup: Option<(
bool,
&mut Id,
&mut SingleBlockLookup<SINGLE_BLOCK_LOOKUP_MAX_ATTEMPTS, T>,
)> = self
@@ -404,27 +475,36 @@ impl<T: BeaconChainTypes> BlockLookups<T> {
ResponseType::Blob => blob_id_opt,
};
if let Some(lookup_id) = id_opt {
if lookup_id == target_id {
Some((lookup_id, req))
if *lookup_id == target_id {
// Only send for processing if we don't have parent requests that were triggered by
// this block.
let triggered_parent_request = self
.parent_lookups
.iter()
.any(|lookup| lookup.chain_hash() == req.requested_block_root);
return Some((triggered_parent_request, lookup_id, req));
}
}
None
});
let (id_ref, request) = match lookup {
Some((id_ref, req)) => (id_ref, req),
let (triggered_parent_request, id_ref, request) = match lookup {
Some((triggered_parent_request, id_ref, req)) => {
(triggered_parent_request, id_ref, req)
}
None => {
if matches!(StreamTerminator::False, stream_terminator) {
debug!(
self.log,
"Block returned for single block lookup not present";
"response_type" => response_type,
"response_type" => ?response_type,
);
}
return None;
}
};
Some((id_ref, request))
Some((triggered_parent_request, id_ref, request))
}
/// Process a response received from a parent lookup request.
@@ -451,7 +531,7 @@ impl<T: BeaconChainTypes> BlockLookups<T> {
match parent_lookup.verify_block(block, &mut self.failed_chains) {
Ok(Some((block_root, block))) => {
let process_or_search = parent_lookup.add_block(block_root, block);
let process_or_search = parent_lookup.add_block(block_root, block).unwrap(); //TODO(sean) fix
match process_or_search {
LookupDownloadStatus::Process(wrapper) => {
let chain_hash = parent_lookup.chain_hash();
@@ -486,7 +566,7 @@ impl<T: BeaconChainTypes> BlockLookups<T> {
| ParentVerifyError::UnrequestedBlobId
| ParentVerifyError::ExtraBlobsReturned
| ParentVerifyError::InvalidIndex(_)
| ParentVerifyError::AvailabilityCheck(_) => {
| ParentVerifyError::AvailabilityCheck => {
let e = e.into();
warn!(self.log, "Peer sent invalid response to parent request.";
"peer_id" => %peer_id, "reason" => %e);
@@ -545,7 +625,7 @@ impl<T: BeaconChainTypes> BlockLookups<T> {
match parent_lookup.verify_blob(blob, &mut self.failed_chains) {
Ok(Some((block_root, blobs))) => {
let processed_or_search = parent_lookup.add_blobs(block_root, blobs);
let processed_or_search = parent_lookup.add_blobs(block_root, blobs).unwrap(); //TODO(sean) fix
match processed_or_search {
LookupDownloadStatus::Process(wrapper) => {
let chain_hash = parent_lookup.chain_hash();
@@ -573,14 +653,14 @@ impl<T: BeaconChainTypes> BlockLookups<T> {
// processing result arrives.
self.parent_lookups.push(parent_lookup);
}
Err(e) => match e.into() {
Err(e) => match e {
ParentVerifyError::RootMismatch
| ParentVerifyError::NoBlockReturned
| ParentVerifyError::ExtraBlocksReturned
| ParentVerifyError::UnrequestedBlobId
| ParentVerifyError::ExtraBlobsReturned
| ParentVerifyError::InvalidIndex(_)
| ParentVerifyError::AvailabilityCheck(_) => {
| ParentVerifyError::AvailabilityCheck => {
let e = e.into();
warn!(self.log, "Peer sent invalid response to parent request.";
"peer_id" => %peer_id, "reason" => %e);
@@ -1127,25 +1207,35 @@ impl<T: BeaconChainTypes> BlockLookups<T> {
.enumerate()
.find(|(index, (_, _, req))| req.requested_block_root == chain_hash)
{
self.single_block_lookups
if let Some((block_id, blob_id, block_wrapper)) = self
.single_block_lookups
.get_mut(index)
.and_then(|(_, _, lookup)| lookup.get_downloaded_block())
.map(|block_wrapper| {
// This is the correct block, send it for processing
if self
.send_block_for_processing(
chain_hash,
block_wrapper,
Duration::from_secs(0), //TODO(sean) pipe this through
BlockProcessType::SingleBlock { id },
cx,
)
.is_err()
{
// Remove to avoid inconsistencies
self.single_block_lookups.remove(index);
}
});
.and_then(|(block_id, blob_id, lookup)| {
lookup
.get_downloaded_block()
.map(|block| (block_id, blob_id, block))
})
{
let Some(id) = block_id.or(*blob_id) else {
warn!(self.log, "No id found for single block lookup"; "chain_hash" => %chain_hash);
return;
};
// This is the correct block, send it for processing
if self
.send_block_for_processing(
chain_hash,
block_wrapper,
Duration::from_secs(0), //TODO(sean) pipe this through
BlockProcessType::SingleBlock { id },
cx,
)
.is_err()
{
// Remove to avoid inconsistencies
self.single_block_lookups.remove(index);
}
}
}
}
BatchProcessResult::FaultyFailure {

View File

@@ -5,8 +5,8 @@ use crate::sync::{
manager::{Id, SLOT_IMPORT_TOLERANCE},
network_context::SyncNetworkContext,
};
use beacon_chain::blob_verification::AsBlock;
use beacon_chain::blob_verification::BlockWrapper;
use beacon_chain::blob_verification::{AsBlock, MaybeAvailableBlock};
use beacon_chain::data_availability_checker::AvailabilityCheckError;
use beacon_chain::data_availability_checker::DataAvailabilityChecker;
use beacon_chain::BeaconChainTypes;
@@ -48,7 +48,7 @@ pub enum ParentVerifyError {
ExtraBlobsReturned,
InvalidIndex(u64),
PreviousFailure { parent_root: Hash256 },
AvailabilityCheck(AvailabilityCheckError),
AvailabilityCheck, //TODO(sean) wrap the underlying error
}
#[derive(Debug, PartialEq, Eq)]
@@ -107,11 +107,11 @@ impl<T: BeaconChainTypes> ParentLookup<T> {
match cx.parent_lookup_block_request(peer_id, request) {
Ok(request_id) => {
self.current_parent_request_id = Some(request_id);
Ok(())
return Ok(());
}
Err(reason) => {
self.current_parent_request_id = None;
Err(RequestError::SendFailed(reason))
return Err(RequestError::SendFailed(reason));
}
}
}
@@ -131,11 +131,11 @@ impl<T: BeaconChainTypes> ParentLookup<T> {
match cx.parent_lookup_blobs_request(peer_id, request) {
Ok(request_id) => {
self.current_parent_blob_request_id = Some(request_id);
Ok(())
return Ok(());
}
Err(reason) => {
self.current_parent_blob_request_id = None;
Err(RequestError::SendFailed(reason))
return Err(RequestError::SendFailed(reason));
}
}
}
@@ -161,15 +161,6 @@ impl<T: BeaconChainTypes> ParentLookup<T> {
self.downloaded_blocks.push((current_root, block));
self.current_parent_request.requested_block_root = next_parent;
let mut blob_ids = Vec::with_capacity(T::EthSpec::max_blobs_per_block());
for i in 0..T::EthSpec::max_blobs_per_block() {
blob_ids.push(BlobIdentifier {
block_root: current_root,
index: i as u64,
});
}
self.current_parent_request.requested_ids = blob_ids;
self.current_parent_request.block_request_state.state =
single_block_lookup::State::AwaitingDownload;
self.current_parent_request.blob_request_state.state =
@@ -312,15 +303,14 @@ impl<T: BeaconChainTypes> ParentLookup<T> {
)>,
ParentVerifyError,
> {
let block_root = self.current_parent_request.requested_block_root;
let blobs = self.current_parent_request.verify_blob(blob)?;
// check if the parent of this block isn't in the failed cache. If it is, this chain should
// be dropped and the peer downscored.
if let Some(parent_root) = blobs
.as_ref()
.and_then(|blobs| blobs.first())
.map(|blob| blob.block_parent_root_id)
.and_then(|(_, blobs)| blobs.first())
.and_then(|blob| blob.as_ref().map(|b| b.block_parent_root))
{
if failed_chains.contains(&parent_root) {
self.current_parent_request
@@ -331,7 +321,7 @@ impl<T: BeaconChainTypes> ParentLookup<T> {
}
}
Ok((block_root, blobs))
Ok(blobs)
}
pub fn get_block_processing_peer(&self, chain_hash: Hash256) -> Option<PeerId> {
@@ -361,28 +351,26 @@ impl<T: BeaconChainTypes> ParentLookup<T> {
self.current_parent_request.failed_attempts()
}
pub fn add_block_peer(&mut self, block_root: &Hash256, peer_id: &PeerId) -> bool {
self.current_parent_request.add_peer(block_root, peer_id)
//TODO(sean) fix this up
pub fn add_peer(&mut self, block_root: &Hash256, peer_id: &PeerId) -> bool {
if block_root == &self.chain_hash {
return false;
}
self.current_parent_request
.block_request_state
.add_peer(peer_id);
self.current_parent_request
.blob_request_state
.add_peer(peer_id);
true
}
//TODO(sean) fix this up
pub fn used_block_peers(&self) -> impl Iterator<Item = &PeerId> + '_ {
self.current_parent_request.used_peers.iter()
}
#[cfg(test)]
pub fn failed_blob_attempts(&self) -> u8 {
self.current_parent_blob_request
.map_or(0, |req| req.failed_attempts())
}
pub fn add_blobs_peer(&mut self, blobs: &[BlobIdentifier], peer_id: &PeerId) -> bool {
self.current_parent_blob_request
.map_or(false, |mut req| req.add_peer(blobs, peer_id))
}
pub fn used_blob_peers(&self) -> impl Iterator<Item = &PeerId> + '_ {
self.current_parent_blob_request
.map_or(iter::empty(), |req| req.used_peers.iter())
self.current_parent_request
.block_request_state
.used_peers
.iter()
}
}
@@ -396,7 +384,7 @@ impl From<LookupVerifyError> for ParentVerifyError {
E::UnrequestedBlobId => ParentVerifyError::UnrequestedBlobId,
E::ExtraBlobsReturned => ParentVerifyError::ExtraBlobsReturned,
E::InvalidIndex(index) => ParentVerifyError::InvalidIndex(index),
E::AvailabilityCheck(e) => ParentVerifyError::AvailabilityCheck(e),
E::AvailabilityCheck => ParentVerifyError::AvailabilityCheck,
}
}
}

View File

@@ -30,7 +30,7 @@ pub struct SingleBlockLookup<const MAX_ATTEMPTS: u8, T: BeaconChainTypes> {
/// Object representing a single block lookup request.
///
//previously assumed we would have a single block. Now we may have the block but not the blobs
#[derive(PartialEq, Eq)]
#[derive(PartialEq, Eq, Debug)]
pub struct SingleLookupRequestState<const MAX_ATTEMPTS: u8> {
/// State of this request.
pub state: State,
@@ -59,7 +59,7 @@ pub enum LookupVerifyError {
UnrequestedBlobId,
ExtraBlobsReturned,
InvalidIndex(u64),
AvailabilityCheck(AvailabilityCheckError),
AvailabilityCheck, //TODO(sean) wrap the underlying error
}
#[derive(Debug, PartialEq, Eq, IntoStaticStr)]
@@ -112,17 +112,17 @@ impl<const MAX_ATTEMPTS: u8, T: BeaconChainTypes> SingleBlockLookup<MAX_ATTEMPTS
for (index, blob_opt) in self.downloaded_blobs.iter_mut().enumerate() {
if let Some(Some(downloaded_blob)) = blobs.get(index) {
//TODO(sean) should we log a warn if there is already a downloaded blob?
blob_opt = Some(downloaded_blob);
*blob_opt = Some(downloaded_blob.clone());
}
}
if let Some(block) = self.downloaded_block.as_ref() {
match self.da_checker.wrap_block(block_root, block, blobs) {
match self.da_checker.wrap_block(block_root, block.clone(), blobs) {
Ok(wrapper) => Ok(LookupDownloadStatus::Process(wrapper)),
Err(AvailabilityCheckError::MissingBlobs) => {
Ok(LookupDownloadStatus::SearchBlock(block_root))
}
Err(e) => Err(LookupVerifyError::AvailabilityCheck(e)),
Err(_e) => Err(LookupVerifyError::AvailabilityCheck),
}
} else {
Ok(LookupDownloadStatus::SearchBlock(block_root))
@@ -135,17 +135,17 @@ impl<const MAX_ATTEMPTS: u8, T: BeaconChainTypes> SingleBlockLookup<MAX_ATTEMPTS
block: Arc<SignedBeaconBlock<T::EthSpec>>,
) -> Result<LookupDownloadStatus<T::EthSpec>, LookupVerifyError> {
//TODO(sean) check for existing block?
self.downloaded_block = Some(block);
self.downloaded_block = Some(block.clone());
match self
.da_checker
.wrap_block(block_root, block, self.downloaded_blobs)
.wrap_block(block_root, block, self.downloaded_blobs.clone())
{
Ok(wrapper) => Ok(LookupDownloadStatus::Process(wrapper)),
Err(AvailabilityCheckError::MissingBlobs) => {
Ok(LookupDownloadStatus::SearchBlock(block_root))
}
Err(e) => LookupVerifyError::AvailabilityCheck(e),
Err(_e) => Err(LookupVerifyError::AvailabilityCheck),
}
}
@@ -193,7 +193,7 @@ impl<const MAX_ATTEMPTS: u8, T: BeaconChainTypes> SingleBlockLookup<MAX_ATTEMPTS
}
}
None => {
self.register_failure_downloading();
self.block_request_state.register_failure_downloading();
Err(LookupVerifyError::NoBlockReturned)
}
},
@@ -216,12 +216,13 @@ impl<const MAX_ATTEMPTS: u8, T: BeaconChainTypes> SingleBlockLookup<MAX_ATTEMPTS
&mut self,
blob: Option<Arc<BlobSidecar<T::EthSpec>>>,
) -> Result<
Option<
Option<(
Hash256,
FixedVector<
Option<Arc<BlobSidecar<T::EthSpec>>>,
<<T as BeaconChainTypes>::EthSpec as EthSpec>::MaxBlobsPerBlock,
>,
>,
)>,
LookupVerifyError,
> {
match self.block_request_state.state {
@@ -237,9 +238,13 @@ impl<const MAX_ATTEMPTS: u8, T: BeaconChainTypes> SingleBlockLookup<MAX_ATTEMPTS
Err(LookupVerifyError::UnrequestedBlobId)
} else {
// State should remain downloading until we receive the stream terminator.
self.requested_ids.retain(|id| id != received_id);
if let Some(blob_opt) = self.downloaded_blobs.get_mut(blob.index) {
self.requested_ids.retain(|id| *id != received_id);
if let Some(blob_opt) = self.downloaded_blobs.get_mut(blob.index as usize) {
*blob_opt = Some(blob);
Ok(Some((
self.requested_block_root,
self.downloaded_blobs.clone(),
)))
} else {
return Err(LookupVerifyError::InvalidIndex(blob.index));
}
@@ -247,7 +252,10 @@ impl<const MAX_ATTEMPTS: u8, T: BeaconChainTypes> SingleBlockLookup<MAX_ATTEMPTS
}
None => {
self.blob_request_state.state = State::Processing { peer_id };
Ok(Some(self.downloaded_blobs.clone()))
Ok(Some((
self.requested_block_root,
self.downloaded_blobs.clone(),
)))
}
},
State::Processing { peer_id: _ } => match blob {
@@ -268,7 +276,8 @@ impl<const MAX_ATTEMPTS: u8, T: BeaconChainTypes> SingleBlockLookup<MAX_ATTEMPTS
pub fn request_block(
&mut self,
) -> Result<Option<(PeerId, BlocksByRootRequest)>, LookupRequestError> {
if self.da_checker.has_block(self.requested_block_root) || self.downloaded_block.is_some() {
if self.da_checker.has_block(&self.requested_block_root) || self.downloaded_block.is_some()
{
return Ok(None);
}
@@ -276,7 +285,7 @@ impl<const MAX_ATTEMPTS: u8, T: BeaconChainTypes> SingleBlockLookup<MAX_ATTEMPTS
self.block_request_state.state,
State::AwaitingDownload
));
if self.failed_attempts() >= MAX_ATTEMPTS {
if self.block_request_state.failed_attempts() >= MAX_ATTEMPTS {
Err(LookupRequestError::TooManyAttempts {
cannot_process: self.block_request_state.failed_processing
>= self.block_request_state.failed_downloading,
@@ -301,15 +310,18 @@ impl<const MAX_ATTEMPTS: u8, T: BeaconChainTypes> SingleBlockLookup<MAX_ATTEMPTS
pub fn request_blobs(
&mut self,
) -> Result<Option<(PeerId, BlobsByRootRequest)>, LookupRequestError> {
if self.da_checker.has_block(self.requested_block_root) || self.downloaded_block.is_some() {
let missing_ids = self
.da_checker
.get_missing_blob_ids(&self.requested_block_root);
if missing_ids.is_empty() || self.downloaded_block.is_some() {
return Ok(None);
}
debug_assert!(matches!(
self.block_request_state.state,
self.blob_request_state.state,
State::AwaitingDownload
));
if self.failed_attempts() >= MAX_ATTEMPTS {
if self.blob_request_state.failed_attempts() >= MAX_ATTEMPTS {
Err(LookupRequestError::TooManyAttempts {
cannot_process: self.blob_request_state.failed_processing
>= self.blob_request_state.failed_downloading,
@@ -321,7 +333,7 @@ impl<const MAX_ATTEMPTS: u8, T: BeaconChainTypes> SingleBlockLookup<MAX_ATTEMPTS
.choose(&mut rand::thread_rng())
{
let request = BlobsByRootRequest {
blob_ids: VariableList::from(self.requested_ids.clone()),
blob_ids: VariableList::from(missing_ids),
};
self.blob_request_state.state = State::Downloading { peer_id };
self.blob_request_state.used_peers.insert(peer_id);
@@ -397,7 +409,28 @@ impl<const MAX_ATTEMPTS: u8, T: BeaconChainTypes> slog::Value
serializer: &mut dyn slog::Serializer,
) -> slog::Result {
serializer.emit_str("request", key)?;
serializer.emit_arguments("hash", &format_args!("{}", self.requested_thing))?;
serializer.emit_arguments("hash", &format_args!("{}", self.requested_block_root))?;
serializer.emit_arguments("blob_ids", &format_args!("{:?}", self.requested_ids))?;
serializer.emit_arguments(
"block_request_state",
&format_args!("{:?}", self.block_request_state),
)?;
serializer.emit_arguments(
"blob_request_state",
&format_args!("{:?}", self.blob_request_state),
)?;
slog::Result::Ok(())
}
}
impl<const MAX_ATTEMPTS: u8> slog::Value for SingleLookupRequestState<MAX_ATTEMPTS> {
fn serialize(
&self,
record: &slog::Record,
key: slog::Key,
serializer: &mut dyn slog::Serializer,
) -> slog::Result {
serializer.emit_str("request_state", key)?;
match &self.state {
State::AwaitingDownload => {
"awaiting_download".serialize(record, "state", serializer)?

View File

@@ -60,7 +60,7 @@ impl<T: EthSpec> BlocksAndBlobsRequestInfo<T> {
for blob in blob_list {
let blob_index = blob.index as usize;
if blob_index >= T::max_blobs_per_block() {
return Err(format!("Invalid blob index {blob_index:?}").as_str());
return Err("Invalid blob index");
}
blobs_fixed.insert(blob_index, Some(blob));
}

View File

@@ -255,6 +255,8 @@ pub fn spawn<T: BeaconChainTypes>(
log: log.clone(),
};
let log_clone = log.clone();
let sync_send_clone = sync_send.clone();
executor.spawn(
async move {
let slot_duration = beacon_chain.slot_clock.slot_duration();
@@ -299,9 +301,9 @@ pub fn spawn<T: BeaconChainTypes>(
);
// spawn the sync manager thread
debug!(log, "Sync Manager started");
debug!(log_clone, "Sync Manager started");
executor.spawn(async move { Box::pin(sync_manager.main()).await }, "sync");
sync_send
sync_send_clone
}
impl<T: BeaconChainTypes> SyncManager<T> {
@@ -660,7 +662,9 @@ impl<T: BeaconChainTypes> SyncManager<T> {
}
};
if block.slot() == slot {
let block_slot = block.slot();
if block_slot == slot {
if let Err(e) = self
.delayed_lookups
.try_send(SyncMessage::UnknownBlock(peer_id, block, block_root))
@@ -676,7 +680,7 @@ impl<T: BeaconChainTypes> SyncManager<T> {
);
}
self.block_lookups.search_parent(
block.slot(),
block_slot,
block_root,
parent_root,
peer_id,