Merge branch 'unstable' into gloas-lookup-sync-fixes

This commit is contained in:
Pawan Dhananjay
2026-05-07 16:13:50 -07:00
270 changed files with 13056 additions and 2486 deletions

View File

@@ -45,9 +45,7 @@ use std::time::Duration;
use store::Hash256;
use tracing::{debug, error, warn};
use types::data::FixedBlobSidecarList;
use types::{
BlobSidecar, DataColumnSidecar, EthSpec, SignedBeaconBlock, SignedExecutionPayloadEnvelope,
};
use types::{EthSpec, SignedBeaconBlock, SignedExecutionPayloadEnvelope};
pub mod parent_chain;
mod single_block_lookup;
@@ -89,20 +87,18 @@ type PayloadDownloadResponse<E> =
pub enum BlockComponent<E: EthSpec> {
Block(DownloadResult<Arc<SignedBeaconBlock<E>>>),
Blob(DownloadResult<Arc<BlobSidecar<E>>>),
DataColumn(DownloadResult<Arc<DataColumnSidecar<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(blob) => blob.value.block_parent_root(),
BlockComponent::DataColumn(column) => match column.value.as_ref() {
DataColumnSidecar::Fulu(column) => column.block_parent_root(),
// TODO(gloas) we don't have a parent root post gloas, not sure what to do here
DataColumnSidecar::Gloas(column) => column.beacon_block_root,
},
BlockComponent::Blob(parent_root)
| BlockComponent::DataColumn(parent_root)
| BlockComponent::PartialDataColumn(parent_root) => parent_root.value,
}
}
fn get_type(&self) -> &'static str {
@@ -110,6 +106,7 @@ impl<E: EthSpec> BlockComponent<E> {
BlockComponent::Block(_) => "block",
BlockComponent::Blob(_) => "blob",
BlockComponent::DataColumn(_) => "data_column",
BlockComponent::PartialDataColumn(_) => "partial_data_column",
}
}
}

View File

@@ -579,7 +579,9 @@ impl<T: BeaconChainTypes> SingleBlockLookup<T> {
pub fn add_child_components(&mut self, block_component: BlockComponent<T::EthSpec>) -> bool {
match block_component {
BlockComponent::Block(block) => self.block_request.insert_verified_response(block),
BlockComponent::Blob(_) | BlockComponent::DataColumn(_) => {
BlockComponent::Blob(_)
| BlockComponent::DataColumn(_)
| BlockComponent::PartialDataColumn(_) => {
// For now ignore single blobs and columns, as the blob request state assumes all
// blobs are attributed to the same peer = the peer serving the remaining blobs.
false

View File

@@ -501,10 +501,9 @@ mod tests {
DataColumnsByRangeRequestId, DataColumnsByRangeRequester, Id, RangeRequestId,
},
};
use rand::SeedableRng;
use std::{collections::HashMap, sync::Arc};
use tracing::Span;
use types::{Epoch, ForkName, MinimalEthSpec as E, SignedBeaconBlock, test_utils::XorShiftRng};
use types::{Epoch, ForkName, MinimalEthSpec as E, SignedBeaconBlock};
fn components_id() -> ComponentsByRangeRequestId {
ComponentsByRangeRequestId {
@@ -549,10 +548,11 @@ mod tests {
#[test]
fn no_blobs_into_responses() {
let mut rng = XorShiftRng::from_seed([42; 16]);
let mut u = types::test_utils::test_unstructured();
let blocks = (0..4)
.map(|_| {
generate_rand_block_and_blobs::<E>(ForkName::Base, NumBlobs::None, &mut rng)
generate_rand_block_and_blobs::<E>(ForkName::Base, NumBlobs::None, &mut u)
.unwrap()
.0
.into()
})
@@ -574,11 +574,12 @@ mod tests {
#[test]
fn empty_blobs_into_responses() {
let mut rng = XorShiftRng::from_seed([42; 16]);
let mut u = types::test_utils::test_unstructured();
let blocks = (0..4)
.map(|_| {
// Always generate some blobs.
generate_rand_block_and_blobs::<E>(ForkName::Deneb, NumBlobs::Number(3), &mut rng)
generate_rand_block_and_blobs::<E>(ForkName::Deneb, NumBlobs::Number(3), &mut u)
.unwrap()
.0
.into()
})
@@ -619,15 +620,16 @@ mod tests {
.custody_context()
.sampling_columns_for_epoch(Epoch::new(0), &spec)
.to_vec();
let mut rng = XorShiftRng::from_seed([42; 16]);
let mut u = types::test_utils::test_unstructured();
let blocks = (0..4)
.map(|_| {
generate_rand_block_and_data_columns::<E>(
ForkName::Fulu,
NumBlobs::Number(1),
&mut rng,
&mut u,
&spec,
)
.unwrap()
})
.collect::<Vec<_>>();
@@ -729,15 +731,16 @@ mod tests {
Span::none(),
);
let mut rng = XorShiftRng::from_seed([42; 16]);
let mut u = types::test_utils::test_unstructured();
let blocks = (0..4)
.map(|_| {
generate_rand_block_and_data_columns::<E>(
ForkName::Fulu,
NumBlobs::Number(1),
&mut rng,
&mut u,
&spec,
)
.unwrap()
})
.collect::<Vec<_>>();
@@ -787,15 +790,16 @@ mod tests {
.custody_context()
.sampling_columns_for_epoch(Epoch::new(0), &spec)
.to_vec();
let mut rng = XorShiftRng::from_seed([42; 16]);
let mut u = types::test_utils::test_unstructured();
let blocks = (0..2)
.map(|_| {
generate_rand_block_and_data_columns::<E>(
ForkName::Fulu,
NumBlobs::Number(1),
&mut rng,
&mut u,
&spec,
)
.unwrap()
})
.collect::<Vec<_>>();
@@ -884,15 +888,16 @@ mod tests {
.custody_context()
.sampling_columns_for_epoch(Epoch::new(0), &spec)
.to_vec();
let mut rng = XorShiftRng::from_seed([42; 16]);
let mut u = types::test_utils::test_unstructured();
let blocks = (0..2)
.map(|_| {
generate_rand_block_and_data_columns::<E>(
ForkName::Fulu,
NumBlobs::Number(1),
&mut rng,
&mut u,
&spec,
)
.unwrap()
})
.collect::<Vec<_>>();
@@ -999,15 +1004,16 @@ mod tests {
.custody_context()
.sampling_columns_for_epoch(Epoch::new(0), &spec)
.to_vec();
let mut rng = XorShiftRng::from_seed([42; 16]);
let mut u = types::test_utils::test_unstructured();
let blocks = (0..1)
.map(|_| {
generate_rand_block_and_data_columns::<E>(
ForkName::Fulu,
NumBlobs::Number(1),
&mut rng,
&mut u,
&spec,
)
.unwrap()
})
.collect::<Vec<_>>();

View File

@@ -148,6 +148,14 @@ pub enum SyncMessage<E: EthSpec> {
/// 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 {
peer_id: PeerId,
block_root: Hash256,
parent_root: Hash256,
slot: Slot,
},
/// A peer has sent an attestation that references a block that is unknown. This triggers the
/// manager to attempt to find the block matching the unknown hash.
UnknownBlockHashFromAttestation(PeerId, Hash256),
@@ -887,7 +895,7 @@ impl<T: BeaconChainTypes> SyncManager<T> {
parent_root,
blob_slot,
BlockComponent::Blob(DownloadResult {
value: blob,
value: parent_root,
block_root,
seen_timestamp: self.chain.slot_clock.now_duration().unwrap_or_default(),
peer_group: PeerGroup::from_single(peer_id),
@@ -907,7 +915,7 @@ impl<T: BeaconChainTypes> SyncManager<T> {
parent_root,
data_column_slot,
BlockComponent::DataColumn(DownloadResult {
value: data_column,
value: parent_root,
block_root,
seen_timestamp: self
.chain
@@ -948,6 +956,26 @@ impl<T: BeaconChainTypes> SyncManager<T> {
}
}
}
SyncMessage::UnknownParentPartialDataColumn {
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,
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),
}),
);
}
SyncMessage::UnknownBlockHashFromAttestation(peer_id, block_root) => {
if !self.notified_unknown_roots.contains(&(peer_id, block_root)) {
self.notified_unknown_roots.insert((peer_id, block_root));

View File

@@ -38,7 +38,6 @@ use tracing::info;
use types::{
BlobSidecar, BlockImportSource, ColumnIndex, DataColumnSidecar, EthSpec, ForkContext, ForkName,
Hash256, MinimalEthSpec as E, SignedBeaconBlock, SignedExecutionPayloadEnvelope, Slot,
test_utils::{SeedableRng, XorShiftRng},
};
const D: Duration = Duration::new(0, 0);
@@ -285,7 +284,6 @@ impl TestRig {
// deterministic seed
let rng_08 = <rand_chacha_03::ChaCha20Rng as rand_08::SeedableRng>::from_seed([0u8; 32]);
let rng = ChaCha20Rng::from_seed([0u8; 32]);
init_tracing();
@@ -297,7 +295,7 @@ impl TestRig {
sync_rx,
sync_rx_queue: vec![],
rng_08,
rng,
unstructured: types::test_utils::test_unstructured(),
network_globals: beacon_processor.network_globals.clone(),
sync_manager: SyncManager::new(
chain,
@@ -1550,8 +1548,7 @@ impl TestRig {
num_blobs: NumBlobs,
) -> (SignedBeaconBlock<E>, Vec<BlobSidecar<E>>) {
let fork_name = self.fork_name;
let rng = &mut self.rng;
generate_rand_block_and_blobs::<E>(fork_name, num_blobs, rng)
generate_rand_block_and_blobs::<E>(fork_name, num_blobs, &mut self.unstructured).unwrap()
}
pub fn send_sync_message(&mut self, sync_message: SyncMessage<E>) {
@@ -1887,16 +1884,17 @@ impl TestRig {
}
#[test]
fn stable_rng() {
let mut rng = XorShiftRng::from_seed([42; 16]);
let (block, _) = generate_rand_block_and_blobs::<E>(ForkName::Base, NumBlobs::None, &mut rng);
fn stable_arbitrary() {
let mut u = types::test_utils::test_unstructured();
let (block, _) =
generate_rand_block_and_blobs::<E>(ForkName::Base, NumBlobs::None, &mut u).unwrap();
assert_eq!(
block.canonical_root(),
Hash256::from_slice(
&hex::decode("adfd2e9e7a7976e8ccaed6eaf0257ed36a5b476732fee63ff44966602fd099ec")
&hex::decode("7348573d99ca404b502e2be790593203a1d899f9cf04f42ec9c5b4975803e3c5")
.unwrap()
),
"rng produces a consistent value"
"arbitrary produces a consistent value"
);
}

View File

@@ -11,7 +11,6 @@ use beacon_processor::WorkEvent;
use lighthouse_network::rpc::RequestType;
use lighthouse_network::service::api_types::{AppRequestId, Id};
use lighthouse_network::{NetworkGlobals, PeerId};
use rand_chacha::ChaCha20Rng;
use slot_clock::ManualSlotClock;
use std::collections::{HashMap, HashSet};
use std::fs::OpenOptions;
@@ -72,9 +71,8 @@ struct TestRig {
network_globals: Arc<NetworkGlobals<E>>,
/// Beacon chain harness
harness: BeaconChainHarness<EphemeralHarnessType<E>>,
/// `rng` for generating test blocks and blobs.
rng_08: rand_chacha_03::ChaCha20Rng,
rng: ChaCha20Rng,
unstructured: arbitrary::Unstructured<'static>,
fork_name: ForkName,
/// Blocks that will be used in the test but may not be known to `harness` yet.
network_blocks_by_root: HashMap<Hash256, RangeSyncBlock<E>>,
@@ -152,13 +150,13 @@ pub fn init_tracing() {
INIT_TRACING.call_once(|| {
if std::env::var(CI_LOGGER_DIR_ENV_VAR).is_ok() {
// Enable logging to log files for each test and each fork.
tracing_subscriber::registry()
let _ = tracing_subscriber::registry()
.with(
tracing_subscriber::fmt::layer()
.with_ansi(false)
.with_writer(CILogWriter),
)
.init();
.try_init();
}
});
}