mirror of
https://github.com/sigp/lighthouse.git
synced 2026-06-15 09:48:20 +00:00
Update PR
This commit is contained in:
@@ -6221,10 +6221,10 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
||||
.contains_block(root)
|
||||
}
|
||||
|
||||
// TODO(gloas): implement this once issue #8956 is resolved
|
||||
pub fn envelope_is_known_to_fork_choice(&self, root: &Hash256) -> bool {
|
||||
// for now just check the database
|
||||
self.store.payload_envelope_exists(root).unwrap_or(false)
|
||||
self.canonical_head
|
||||
.fork_choice_read_lock()
|
||||
.is_payload_received(root)
|
||||
}
|
||||
|
||||
/// Determines the beacon proposer for the next slot. If that proposer is registered in the
|
||||
|
||||
@@ -720,17 +720,19 @@ impl<T: BeaconChainTypes> NetworkBeaconProcessor<T> {
|
||||
MessageAcceptance::Accept,
|
||||
);
|
||||
}
|
||||
GossipDataColumnError::ParentUnknown { parent_root, .. } => {
|
||||
GossipDataColumnError::ParentUnknown { parent_root, slot } => {
|
||||
debug!(
|
||||
action = "requesting parent",
|
||||
%block_root,
|
||||
%parent_root,
|
||||
"Unknown parent hash for column"
|
||||
);
|
||||
self.send_sync_message(SyncMessage::UnknownParentDataColumn(
|
||||
self.send_sync_message(SyncMessage::UnknownParentSidecarHeader {
|
||||
peer_id,
|
||||
column_sidecar,
|
||||
));
|
||||
block_root,
|
||||
parent_root,
|
||||
slot,
|
||||
});
|
||||
}
|
||||
GossipDataColumnError::PubkeyCacheTimeout
|
||||
| GossipDataColumnError::BeaconChainError(_) => {
|
||||
@@ -926,7 +928,7 @@ impl<T: BeaconChainTypes> NetworkBeaconProcessor<T> {
|
||||
%parent_root,
|
||||
"Unknown parent hash for partial column"
|
||||
);
|
||||
self.send_sync_message(SyncMessage::UnknownParentPartialDataColumn {
|
||||
self.send_sync_message(SyncMessage::UnknownParentSidecarHeader {
|
||||
peer_id,
|
||||
block_root,
|
||||
parent_root,
|
||||
@@ -1143,10 +1145,12 @@ impl<T: BeaconChainTypes> NetworkBeaconProcessor<T> {
|
||||
%commitment,
|
||||
"Unknown parent hash for blob"
|
||||
);
|
||||
self.send_sync_message(SyncMessage::UnknownParentBlob(
|
||||
self.send_sync_message(SyncMessage::UnknownParentSidecarHeader {
|
||||
peer_id,
|
||||
blob_sidecar,
|
||||
));
|
||||
block_root: root,
|
||||
parent_root,
|
||||
slot,
|
||||
});
|
||||
}
|
||||
GossipBlobError::PubkeyCacheTimeout | GossipBlobError::BeaconChainError(_) => {
|
||||
crit!(
|
||||
|
||||
@@ -21,16 +21,14 @@
|
||||
//! returned to this module as `LookupRequestResult` variants.
|
||||
|
||||
use self::parent_chain::{NodeChain, compute_parent_chains};
|
||||
pub use self::single_block_lookup::DownloadResult;
|
||||
use self::single_block_lookup::{
|
||||
AwaitingParent, LookupRequestError, LookupResult, PeerType, SingleBlockLookup,
|
||||
};
|
||||
pub use self::single_block_lookup::{AwaitingParent, DownloadResult};
|
||||
use self::single_block_lookup::{LookupRequestError, LookupResult, SingleBlockLookup};
|
||||
use super::manager::{BlockProcessType, BlockProcessingResult, SLOT_IMPORT_TOLERANCE};
|
||||
use super::network_context::{PeerGroup, RpcResponseError, SyncNetworkContext};
|
||||
use crate::metrics;
|
||||
use crate::sync::SyncMessage;
|
||||
use crate::sync::block_lookups::parent_chain::find_oldest_fork_ancestor;
|
||||
use beacon_chain::block_verification_types::AsBlock;
|
||||
use crate::sync::block_lookups::single_block_lookup::PeerType;
|
||||
use beacon_chain::data_availability_checker::{
|
||||
AvailabilityCheckError, AvailabilityCheckErrorCategory,
|
||||
};
|
||||
@@ -87,28 +85,7 @@ type PayloadDownloadResponse<E> =
|
||||
|
||||
pub enum BlockComponent<E: EthSpec> {
|
||||
Block(DownloadResult<Arc<SignedBeaconBlock<E>>>),
|
||||
Blob(DownloadResult<Hash256>),
|
||||
DataColumn(DownloadResult<Hash256>),
|
||||
PartialDataColumn(DownloadResult<Hash256>),
|
||||
}
|
||||
|
||||
impl<E: EthSpec> BlockComponent<E> {
|
||||
fn parent_root(&self) -> Hash256 {
|
||||
match self {
|
||||
BlockComponent::Block(block) => block.value.parent_root(),
|
||||
BlockComponent::Blob(parent_root)
|
||||
| BlockComponent::DataColumn(parent_root)
|
||||
| BlockComponent::PartialDataColumn(parent_root) => parent_root.value,
|
||||
}
|
||||
}
|
||||
fn get_type(&self) -> &'static str {
|
||||
match self {
|
||||
BlockComponent::Block(_) => "block",
|
||||
BlockComponent::Blob(_) => "blob",
|
||||
BlockComponent::DataColumn(_) => "data_column",
|
||||
BlockComponent::PartialDataColumn(_) => "partial_data_column",
|
||||
}
|
||||
}
|
||||
Sidecar,
|
||||
}
|
||||
|
||||
pub type SingleLookupId = u32;
|
||||
@@ -200,31 +177,26 @@ impl<T: BeaconChainTypes> BlockLookups<T> {
|
||||
&mut self,
|
||||
block_root: Hash256,
|
||||
block_component: BlockComponent<T::EthSpec>,
|
||||
awaiting_parent: AwaitingParent,
|
||||
peer_id: PeerId,
|
||||
cx: &mut SyncNetworkContext<T>,
|
||||
) -> bool {
|
||||
let parent_root = block_component.parent_root();
|
||||
|
||||
// We don't know the child's fork yet (no block downloaded), use PreGloas conservatively.
|
||||
// The correct AwaitingParent will be set when the child's block downloads.
|
||||
let awaiting = AwaitingParent::pre_gloas(parent_root);
|
||||
let parent_lookup_exists =
|
||||
self.search_parent_of_child(awaiting, block_root, &[peer_id], cx);
|
||||
self.search_parent_of_child(awaiting_parent, block_root, &[peer_id], cx);
|
||||
// Only create the child lookup if the parent exists
|
||||
if parent_lookup_exists {
|
||||
// `search_parent_of_child` ensures that the parent lookup exists so we can safely wait for it
|
||||
self.new_current_lookup(
|
||||
block_root,
|
||||
Some(block_component),
|
||||
Some(parent_root),
|
||||
Some(awaiting_parent),
|
||||
// On a `UnknownParentBlock` or `UnknownParentBlob` event the peer is not required
|
||||
// to have the rest of the block components (refer to decoupled blob gossip). Create
|
||||
// the lookup with zero peers to house the block components.
|
||||
&[],
|
||||
&PeerType {
|
||||
data: false,
|
||||
payload: false,
|
||||
},
|
||||
&PeerType::PreGloas,
|
||||
cx,
|
||||
)
|
||||
} else {
|
||||
@@ -242,41 +214,7 @@ impl<T: BeaconChainTypes> BlockLookups<T> {
|
||||
peer_source: &[PeerId],
|
||||
cx: &mut SyncNetworkContext<T>,
|
||||
) -> bool {
|
||||
self.new_current_lookup(
|
||||
block_root,
|
||||
None,
|
||||
None,
|
||||
peer_source,
|
||||
&PeerType {
|
||||
data: false,
|
||||
payload: false,
|
||||
},
|
||||
cx,
|
||||
)
|
||||
}
|
||||
|
||||
/// Search for a block triggered by a Gloas data column. The peer that sent the data column
|
||||
/// is a valid data source, so mark it as data-capable.
|
||||
///
|
||||
/// Returns true if the lookup is created or already exists
|
||||
#[must_use = "only reference the new lookup if returns true"]
|
||||
pub fn search_unknown_block_with_data_peer(
|
||||
&mut self,
|
||||
block_root: Hash256,
|
||||
peer_source: &[PeerId],
|
||||
cx: &mut SyncNetworkContext<T>,
|
||||
) -> bool {
|
||||
self.new_current_lookup(
|
||||
block_root,
|
||||
None,
|
||||
None,
|
||||
peer_source,
|
||||
&PeerType {
|
||||
data: true,
|
||||
payload: false,
|
||||
},
|
||||
cx,
|
||||
)
|
||||
self.new_current_lookup(block_root, None, None, peer_source, &PeerType::PreGloas, cx)
|
||||
}
|
||||
|
||||
/// A block or blob triggers the search of a parent.
|
||||
@@ -391,24 +329,10 @@ impl<T: BeaconChainTypes> BlockLookups<T> {
|
||||
// Child's peers can serve block, and data + payload if the parent is full.
|
||||
// In Gloas, data and payload are coupled: empty blocks have neither.
|
||||
// Pre-Gloas: data is always needed with block, payload is never needed.
|
||||
let peer_type = if awaiting_parent.is_post_gloas() {
|
||||
let is_full = self
|
||||
.single_block_lookups
|
||||
.values()
|
||||
.find(|l| l.is_for_block(block_root_to_search))
|
||||
.map(|parent| parent.is_full_payload(&awaiting_parent))
|
||||
.unwrap_or(false);
|
||||
PeerType {
|
||||
data: is_full,
|
||||
payload: is_full,
|
||||
}
|
||||
} else {
|
||||
PeerType {
|
||||
data: true,
|
||||
payload: false,
|
||||
}
|
||||
let peer_type = match awaiting_parent.parent_hash() {
|
||||
Some(parent_hash) => PeerType::PostGloas(parent_hash),
|
||||
None => PeerType::PreGloas,
|
||||
};
|
||||
|
||||
// `block_root_to_search` is a failed chain check happens inside new_current_lookup
|
||||
self.new_current_lookup(block_root_to_search, None, None, peers, &peer_type, cx)
|
||||
}
|
||||
@@ -421,7 +345,7 @@ impl<T: BeaconChainTypes> BlockLookups<T> {
|
||||
&mut self,
|
||||
block_root: Hash256,
|
||||
block_component: Option<BlockComponent<T::EthSpec>>,
|
||||
awaiting_parent: Option<Hash256>,
|
||||
awaiting_parent: Option<AwaitingParent>,
|
||||
peers: &[PeerId],
|
||||
peer_type: &PeerType,
|
||||
cx: &mut SyncNetworkContext<T>,
|
||||
@@ -436,16 +360,12 @@ impl<T: BeaconChainTypes> BlockLookups<T> {
|
||||
if let Some((&lookup_id, lookup)) = self
|
||||
.single_block_lookups
|
||||
.iter_mut()
|
||||
.find(|(_id, lookup)| lookup.is_for_block(block_root))
|
||||
.find(|(_id, lookup)| lookup.block_root() == block_root)
|
||||
{
|
||||
if let Some(block_component) = block_component {
|
||||
let component_type = block_component.get_type();
|
||||
let imported = lookup.add_child_components(block_component);
|
||||
if !imported {
|
||||
debug!(
|
||||
?block_root,
|
||||
component_type, "Lookup child component ignored"
|
||||
);
|
||||
debug!(?block_root, "Lookup child component ignored");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -462,7 +382,7 @@ impl<T: BeaconChainTypes> BlockLookups<T> {
|
||||
&& !self
|
||||
.single_block_lookups
|
||||
.iter()
|
||||
.any(|(_, lookup)| lookup.is_for_block(awaiting_parent))
|
||||
.any(|(_, lookup)| lookup.block_root() == awaiting_parent.parent_root())
|
||||
{
|
||||
warn!(block_root = ?awaiting_parent, "Ignoring child lookup parent lookup not found");
|
||||
return false;
|
||||
@@ -477,13 +397,8 @@ impl<T: BeaconChainTypes> BlockLookups<T> {
|
||||
|
||||
// If we know that this lookup has unknown parent (is awaiting a parent lookup to resolve),
|
||||
// signal here to hold processing downloaded data.
|
||||
let mut lookup = SingleBlockLookup::new(
|
||||
block_root,
|
||||
peers,
|
||||
peer_type,
|
||||
cx.next_id(),
|
||||
awaiting_parent.map(AwaitingParent::pre_gloas),
|
||||
);
|
||||
let mut lookup =
|
||||
SingleBlockLookup::new(block_root, peers, peer_type, cx.next_id(), awaiting_parent);
|
||||
let _guard = lookup.span.clone().entered();
|
||||
|
||||
// Add block components to the new request
|
||||
@@ -771,10 +686,7 @@ impl<T: BeaconChainTypes> BlockLookups<T> {
|
||||
|
||||
// Use the data kind to pick a penalty string the peer-scoring tests
|
||||
// distinguish on (blobs vs custody columns).
|
||||
let penalty_msg = match lookup.data_is_columns() {
|
||||
Some(true) => "lookup_custody_column_processing_failure",
|
||||
_ => "lookup_blobs_processing_failure",
|
||||
};
|
||||
let penalty_msg = "lookup_data_processing_failure";
|
||||
|
||||
match &e {
|
||||
// No penalization for internal / non-attributable errors
|
||||
@@ -818,7 +730,7 @@ impl<T: BeaconChainTypes> BlockLookups<T> {
|
||||
let Some((id, lookup)) = self
|
||||
.single_block_lookups
|
||||
.iter_mut()
|
||||
.find(|(_, lookup)| lookup.is_for_block(block_root))
|
||||
.find(|(_, lookup)| lookup.block_root() == block_root)
|
||||
else {
|
||||
// Ok to ignore gossip process events
|
||||
return;
|
||||
@@ -1111,18 +1023,7 @@ impl<T: BeaconChainTypes> BlockLookups<T> {
|
||||
.iter()
|
||||
.find(|(_, l)| l.block_root() == parent_root)
|
||||
{
|
||||
let peer_type = if awaiting.is_post_gloas() {
|
||||
let is_full = parent_lookup.is_full_payload(&awaiting);
|
||||
PeerType {
|
||||
data: is_full,
|
||||
payload: is_full,
|
||||
}
|
||||
} else {
|
||||
PeerType {
|
||||
data: true,
|
||||
payload: false,
|
||||
}
|
||||
};
|
||||
let peer_type = PeerType::from_awaiting_parent(awaiting);
|
||||
self.add_peers_to_lookup_and_ancestors(parent_id, peers, &peer_type, cx)
|
||||
} else {
|
||||
Err(format!("Lookup references unknown parent {parent_root:?}"))
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -43,7 +43,7 @@ use super::range_sync::{EPOCHS_PER_BATCH, RangeSync, RangeSyncType};
|
||||
use crate::network_beacon_processor::{ChainSegmentProcessId, NetworkBeaconProcessor};
|
||||
use crate::service::NetworkMessage;
|
||||
use crate::status::ToStatusMessage;
|
||||
use crate::sync::block_lookups::{BlockComponent, DownloadResult};
|
||||
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;
|
||||
@@ -71,7 +71,7 @@ use strum::IntoStaticStr;
|
||||
use tokio::sync::mpsc;
|
||||
use tracing::{debug, error, info, trace};
|
||||
use types::{
|
||||
BlobSidecar, DataColumnSidecar, EthSpec, ForkContext, Hash256, SignedBeaconBlock,
|
||||
BlobSidecar, ChainSpec, DataColumnSidecar, EthSpec, ForkContext, Hash256, SignedBeaconBlock,
|
||||
SignedExecutionPayloadEnvelope, Slot,
|
||||
};
|
||||
|
||||
@@ -142,14 +142,8 @@ pub enum SyncMessage<E: EthSpec> {
|
||||
/// A block with an unknown parent has been received.
|
||||
UnknownParentBlock(PeerId, Arc<SignedBeaconBlock<E>>, Hash256),
|
||||
|
||||
/// A blob with an unknown parent has been received.
|
||||
UnknownParentBlob(PeerId, Arc<BlobSidecar<E>>),
|
||||
|
||||
/// A data column with an unknown parent has been received.
|
||||
UnknownParentDataColumn(PeerId, Arc<DataColumnSidecar<E>>),
|
||||
|
||||
/// A partial data column with an unknown parent has been received.
|
||||
UnknownParentPartialDataColumn {
|
||||
/// A sidecar with an unknown parent has been received.
|
||||
UnknownParentSidecarHeader {
|
||||
peer_id: PeerId,
|
||||
block_root: Hash256,
|
||||
parent_root: Hash256,
|
||||
@@ -874,8 +868,8 @@ impl<T: BeaconChainTypes> SyncManager<T> {
|
||||
self.handle_unknown_parent(
|
||||
peer_id,
|
||||
block_root,
|
||||
parent_root,
|
||||
block_slot,
|
||||
AwaitingParent::from_block(&block),
|
||||
BlockComponent::Block(DownloadResult {
|
||||
value: block.block_cloned(),
|
||||
block_root,
|
||||
@@ -884,97 +878,34 @@ impl<T: BeaconChainTypes> SyncManager<T> {
|
||||
}),
|
||||
);
|
||||
}
|
||||
SyncMessage::UnknownParentBlob(peer_id, blob) => {
|
||||
let blob_slot = blob.slot();
|
||||
let block_root = blob.block_root();
|
||||
let parent_root = blob.block_parent_root();
|
||||
debug!(%block_root, %parent_root, "Received unknown parent blob message");
|
||||
self.handle_unknown_parent(
|
||||
peer_id,
|
||||
block_root,
|
||||
parent_root,
|
||||
blob_slot,
|
||||
BlockComponent::Blob(DownloadResult {
|
||||
value: parent_root,
|
||||
block_root,
|
||||
seen_timestamp: self.chain.slot_clock.now_duration().unwrap_or_default(),
|
||||
peer_group: PeerGroup::from_single(peer_id),
|
||||
}),
|
||||
);
|
||||
}
|
||||
SyncMessage::UnknownParentDataColumn(peer_id, data_column) => {
|
||||
let data_column_slot = data_column.slot();
|
||||
let block_root = data_column.block_root();
|
||||
match data_column.as_ref() {
|
||||
DataColumnSidecar::Fulu(column) => {
|
||||
let parent_root = column.block_parent_root();
|
||||
debug!(%block_root, %parent_root, "Received unknown parent data column message");
|
||||
self.handle_unknown_parent(
|
||||
peer_id,
|
||||
block_root,
|
||||
parent_root,
|
||||
data_column_slot,
|
||||
BlockComponent::DataColumn(DownloadResult {
|
||||
value: parent_root,
|
||||
block_root,
|
||||
seen_timestamp: self
|
||||
.chain
|
||||
.slot_clock
|
||||
.now_duration()
|
||||
.unwrap_or_default(),
|
||||
peer_group: PeerGroup::from_single(peer_id),
|
||||
}),
|
||||
);
|
||||
}
|
||||
// In Gloas, data columns identify the beacon block root but do not carry
|
||||
// parent root. Treat as an unknown block-root trigger (attestation-style).
|
||||
// The peer is marked as data-capable since it sent us a data column.
|
||||
DataColumnSidecar::Gloas(_) => {
|
||||
match self.should_search_for_block(Some(data_column_slot), &peer_id) {
|
||||
Ok(_) => {
|
||||
if self.block_lookups.search_unknown_block_with_data_peer(
|
||||
block_root,
|
||||
&[peer_id],
|
||||
&mut self.network,
|
||||
) {
|
||||
debug!(
|
||||
?block_root,
|
||||
"Created unknown block lookup from Gloas data column"
|
||||
);
|
||||
} else {
|
||||
debug!(?block_root, "No lookup created from Gloas data column");
|
||||
}
|
||||
}
|
||||
Err(reason) => {
|
||||
debug!(
|
||||
%block_root,
|
||||
reason,
|
||||
"Ignoring Gloas data column unknown block request"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
SyncMessage::UnknownParentPartialDataColumn {
|
||||
SyncMessage::UnknownParentSidecarHeader {
|
||||
peer_id,
|
||||
block_root,
|
||||
parent_root,
|
||||
slot,
|
||||
} => {
|
||||
debug!(%block_root, %parent_root, "Received unknown parent partial column message");
|
||||
self.handle_unknown_parent(
|
||||
peer_id,
|
||||
block_root,
|
||||
debug!(%block_root, %parent_root, "Received unknown parent sidecar message");
|
||||
match AwaitingParent::from_block_header::<T::EthSpec>(
|
||||
parent_root,
|
||||
slot,
|
||||
BlockComponent::PartialDataColumn(DownloadResult {
|
||||
value: parent_root,
|
||||
block_root,
|
||||
seen_timestamp: self.chain.slot_clock.now_duration().unwrap_or_default(),
|
||||
peer_group: PeerGroup::from_single(peer_id),
|
||||
}),
|
||||
);
|
||||
self.spec(),
|
||||
) {
|
||||
Ok(awaiting_parent) => {
|
||||
self.handle_unknown_parent(
|
||||
peer_id,
|
||||
block_root,
|
||||
slot,
|
||||
awaiting_parent,
|
||||
BlockComponent::Sidecar,
|
||||
);
|
||||
}
|
||||
Err(e) => {
|
||||
tracing::warn!(
|
||||
?e,
|
||||
"Sent UnknownParentSidecarHeader with post-Gloas sidecar"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
SyncMessage::UnknownBlockHashFromAttestation(peer_id, block_root) => {
|
||||
if !self.notified_unknown_roots.contains(&(peer_id, block_root)) {
|
||||
@@ -1054,8 +985,8 @@ impl<T: BeaconChainTypes> SyncManager<T> {
|
||||
&mut self,
|
||||
peer_id: PeerId,
|
||||
block_root: Hash256,
|
||||
parent_root: Hash256,
|
||||
slot: Slot,
|
||||
awaiting_parent: AwaitingParent,
|
||||
block_component: BlockComponent<T::EthSpec>,
|
||||
) {
|
||||
match self.should_search_for_block(Some(slot), &peer_id) {
|
||||
@@ -1063,6 +994,7 @@ impl<T: BeaconChainTypes> SyncManager<T> {
|
||||
if self.block_lookups.search_child_and_parent(
|
||||
block_root,
|
||||
block_component,
|
||||
awaiting_parent,
|
||||
peer_id,
|
||||
&mut self.network,
|
||||
) {
|
||||
@@ -1070,13 +1002,18 @@ impl<T: BeaconChainTypes> SyncManager<T> {
|
||||
} else {
|
||||
debug!(
|
||||
?block_root,
|
||||
?parent_root,
|
||||
%awaiting_parent,
|
||||
"No lookup created for child and parent"
|
||||
);
|
||||
}
|
||||
}
|
||||
Err(reason) => {
|
||||
debug!(%block_root, %parent_root, reason, "Ignoring unknown parent request");
|
||||
debug!(
|
||||
%block_root,
|
||||
%awaiting_parent,
|
||||
reason,
|
||||
"Ignoring unknown parent request"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1526,6 +1463,10 @@ impl<T: BeaconChainTypes> SyncManager<T> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn spec(&self) -> &ChainSpec {
|
||||
&self.network_globals().spec
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Result<AvailabilityProcessingStatus, BlockError>> for BlockProcessingResult {
|
||||
|
||||
@@ -55,8 +55,9 @@ use tokio::sync::mpsc;
|
||||
use tracing::{Span, debug, debug_span, error, warn};
|
||||
use types::data::FixedBlobSidecarList;
|
||||
use types::{
|
||||
BlobSidecar, BlockImportSource, ColumnIndex, DataColumnSidecar, DataColumnSidecarList, EthSpec,
|
||||
ForkContext, Hash256, SignedBeaconBlock, SignedExecutionPayloadEnvelope, Slot,
|
||||
BlobSidecar, BlockImportSource, ChainSpec, ColumnIndex, DataColumnSidecar,
|
||||
DataColumnSidecarList, EthSpec, ForkContext, Hash256, SignedBeaconBlock,
|
||||
SignedExecutionPayloadEnvelope, Slot,
|
||||
};
|
||||
|
||||
pub mod custody;
|
||||
@@ -315,6 +316,10 @@ impl<T: BeaconChainTypes> SyncNetworkContext<T> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn spec(&self) -> &ChainSpec {
|
||||
&self.chain.spec
|
||||
}
|
||||
|
||||
pub fn send_sync_message(&mut self, sync_message: SyncMessage<T::EthSpec>) {
|
||||
self.network_beacon_processor
|
||||
.send_sync_message(sync_message);
|
||||
|
||||
Reference in New Issue
Block a user