Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
72 commits
Select commit Hold shift + click to select a range
4fb2ae6
Implement reliable range sync for PeerDAS
dapplion May 22, 2025
801659d
Resolve some TODOs
dapplion May 22, 2025
b383f7a
More comments
dapplion May 26, 2025
7d0fb93
Reduce conversions
dapplion May 26, 2025
c8a0c9e
Remove CustodyByRoot and CustodyByRange types
dapplion May 27, 2025
01329ab
Improve RangeBlockComponent type
dapplion May 27, 2025
34b37b9
Remove unused module
dapplion May 27, 2025
8f74adc
Use DataColumnSidecarList
dapplion May 27, 2025
86ad87e
Lint tests
dapplion May 27, 2025
52722b7
Resolve TODO(das)
dapplion May 27, 2025
fc3922f
Resolve more TODOs
dapplion May 27, 2025
0ef95dd
Remove stale TODO
dapplion May 27, 2025
144b83e
Remove BatchStateSummary
dapplion May 27, 2025
02d9737
Address review comments
dapplion May 27, 2025
c6b39e9
Merge remote-tracking branch 'sigp/peerdas-devnet-7' into peerdas-ran…
dapplion May 27, 2025
1b72871
Merge branch 'peerdas-devnet-7' into peerdas-rangesync
jimmygchen Jun 3, 2025
2b4a9bd
Merge branch 'peerdas-devnet-7' into peerdas-rangesync
jimmygchen Jun 4, 2025
ae0ef8f
Fix finalized_sync_permanent_custody_peer_failure
dapplion Jun 5, 2025
6f754bf
Merge branch 'peerdas-devnet-7' into peerdas-rangesync
jimmygchen Jun 5, 2025
28d9d8b
lint
dapplion Jun 11, 2025
7a03578
Remove total_requests_per_peer
dapplion Jun 11, 2025
4e13b3b
Fix failed_peers post fulu
dapplion Jun 11, 2025
e426e45
Don't use failed_peers for download errors, rely on randomness to ski…
dapplion Jun 11, 2025
82c8e82
Re-add NoPeers error
dapplion Jun 11, 2025
a7a3457
Merge branch 'peerdas-devnet-7' into peerdas-rangesync
dapplion Jun 12, 2025
8c8a812
Merge remote-tracking branch 'sigp/peerdas-devnet-7' into peerdas-ran…
dapplion Jun 12, 2025
56fcf28
lint
dapplion Jun 12, 2025
aa726cc
lint
dapplion Jun 12, 2025
cb5f76f
Add peers to backfill if FullySynced
dapplion Jun 12, 2025
6a4dde0
Design with roots and tips
dapplion Jun 18, 2025
f4b0e62
Happy case works in test
dapplion Jun 19, 2025
d3d1457
Cleanup requests
dapplion Jun 20, 2025
b1b0bf8
Delete by_range code
dapplion Jun 20, 2025
8d227f4
Compiles src
dapplion Jun 20, 2025
805d284
Add error handling in fowards sync
dapplion Jun 20, 2025
060e5e2
More lints
dapplion Jun 21, 2025
e62dc91
Resolve todos
dapplion Jun 21, 2025
6b0e161
Temp
dapplion Jun 21, 2025
43ac04d
more todos
dapplion Jun 21, 2025
623a517
Rename to forward sync
dapplion Jun 21, 2025
b152735
Resolve TODOs
dapplion Jun 21, 2025
c07d6d3
Basic tests compile
dapplion Jun 22, 2025
3af217a
base and fulu tests pass
dapplion Jun 22, 2025
397de5a
Remove unnecessary async from tests
dapplion Jun 22, 2025
ed4171b
pass deneb tests
dapplion Jun 22, 2025
bf0015c
WIP processor tests
dapplion Jun 22, 2025
10953a8
Remove artifact file
dapplion Jun 23, 2025
bff65e7
Add basic metrics
dapplion Jun 23, 2025
7c903b9
Fix logs and metrics
dapplion Jun 23, 2025
3c30197
Add todo
dapplion Jun 24, 2025
c567a95
Introduce chains to group blocks with same peer set
dapplion Jul 9, 2025
8c85725
Fix some lints and document
dapplion Jul 9, 2025
ef7c6b2
Remove remaining todo
dapplion Jul 10, 2025
7d864ab
Add better logging
dapplion Jul 14, 2025
be99c7a
Add metrics for stage duration
dapplion Jul 14, 2025
b16a427
Remove empty chains
dapplion Jul 14, 2025
c3373c9
Ignore AddPeer message on race condition
dapplion Jul 14, 2025
9a758e8
Track the reason chains are removed
dapplion Jul 14, 2025
ab36b78
Add extra logging for dropping
dapplion Jul 14, 2025
dba5901
Simplify compute children
dapplion Jul 14, 2025
72b5e46
More logs with chain_id
dapplion Jul 14, 2025
b4058ab
Log chains every interval
dapplion Jul 14, 2025
bc30717
Simplify transition to forward sync
dapplion Jul 14, 2025
8e791e5
Fix to_ready_to_sync
dapplion Jul 15, 2025
fd304d4
Log when chain splits
dapplion Jul 15, 2025
6d48a1e
Log recursive chains
dapplion Jul 15, 2025
d40cc35
Recurse forward sync block too
dapplion Jul 15, 2025
9cf94a7
Consider imported blocks
dapplion Jul 15, 2025
def7886
Fix split_by logic
dapplion Jul 15, 2025
b009b37
Implement merge operation
dapplion Jul 24, 2025
47c9357
Implement headers_by_root consumer side
dapplion Jul 24, 2025
cdfb74f
Simplify forward sync design
dapplion Nov 27, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 2 additions & 6 deletions beacon_node/beacon_chain/src/block_verification_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ impl<E: EthSpec> RpcBlock<E> {
block: Arc<SignedBeaconBlock<E>>,
custody_columns: Vec<CustodyDataColumn<E>>,
spec: &ChainSpec,
) -> Result<Self, AvailabilityCheckError> {
) -> Result<Self, String> {
let block_root = block_root.unwrap_or_else(|| get_block_root(&block));

let inner = RpcBlockInner::BlockAndCustodyColumns {
Expand All @@ -197,11 +197,7 @@ impl<E: EthSpec> RpcBlock<E> {
custody_columns,
spec.number_of_columns as usize,
)
.map_err(|e| {
AvailabilityCheckError::Unexpected(format!(
"custody_columns len exceeds number_of_columns: {e:?}"
))
})?,
.map_err(|e| format!("custody_columns len exceeds number_of_columns: {e:?}"))?,
};
Ok(Self {
block_root,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1183,8 +1183,13 @@ mod pending_components_tests {
pub fn pre_setup() -> Setup<E> {
let mut rng = StdRng::seed_from_u64(0xDEADBEEF0BAD5EEDu64);
let spec = test_spec::<E>();
let (block, blobs_vec) =
generate_rand_block_and_blobs::<E>(ForkName::Deneb, NumBlobs::Random, &mut rng, &spec);
let (block, blobs_vec) = generate_rand_block_and_blobs::<E>(
ForkName::Deneb,
NumBlobs::Random,
None,
&mut rng,
&spec,
);
let max_len = spec.max_blobs_per_block(block.epoch()) as usize;
let mut blobs: RuntimeFixedVector<Option<Arc<BlobSidecar<E>>>> =
RuntimeFixedVector::default(max_len);
Expand Down
13 changes: 10 additions & 3 deletions beacon_node/beacon_chain/src/test_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2392,7 +2392,8 @@ where
.take(sampling_column_count)
.map(CustodyDataColumn::from_asserted_custody)
.collect::<Vec<_>>();
RpcBlock::new_with_custody_columns(Some(block_root), block, columns, &self.spec)?
RpcBlock::new_with_custody_columns(Some(block_root), block, columns, &self.spec)
.map_err(BlockError::InternalError)?
} else {
RpcBlock::new_without_blobs(Some(block_root), block)
}
Expand Down Expand Up @@ -3144,10 +3145,14 @@ pub enum NumBlobs {
pub fn generate_rand_block_and_blobs<E: EthSpec>(
fork_name: ForkName,
num_blobs: NumBlobs,
parent_root: Option<Hash256>,
rng: &mut impl Rng,
spec: &ChainSpec,
) -> (SignedBeaconBlock<E, FullPayload<E>>, Vec<BlobSidecar<E>>) {
let inner = map_fork_name!(fork_name, BeaconBlock, <_>::random_for_test(rng));
let mut inner = map_fork_name!(fork_name, BeaconBlock, <_>::random_for_test(rng));
if let Some(parent_root) = parent_root {
*inner.parent_root_mut() = parent_root;
}

let mut block = SignedBeaconBlock::from_block(inner, types::Signature::random_for_test(rng));
let max_blobs = spec.max_blobs_per_block(block.epoch()) as usize;
Expand Down Expand Up @@ -3246,13 +3251,15 @@ pub fn generate_rand_block_and_blobs<E: EthSpec>(
pub fn generate_rand_block_and_data_columns<E: EthSpec>(
fork_name: ForkName,
num_blobs: NumBlobs,
parent_root: Option<Hash256>,
rng: &mut impl Rng,
spec: &ChainSpec,
) -> (
SignedBeaconBlock<E, FullPayload<E>>,
DataColumnSidecarList<E>,
) {
let (block, _blobs) = generate_rand_block_and_blobs(fork_name, num_blobs, rng, spec);
let (block, _blobs) =
generate_rand_block_and_blobs(fork_name, num_blobs, parent_root, rng, spec);
let data_columns = generate_data_column_sidecars_from_block(&block, spec);
(block, data_columns)
}
Expand Down
4 changes: 1 addition & 3 deletions beacon_node/beacon_chain/tests/store_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2603,7 +2603,7 @@ async fn weak_subjectivity_sync_test(slots: Vec<Slot>, checkpoint_slot: Slot) {
.deconstruct();
if wss_fork.fulu_enabled() {
info!(block_slot = %block.slot(), ?block_root, "Corrupting data column KZG proof");
let (mut data_columns, expected_column_indices) = cols.unwrap();
let mut data_columns = cols.unwrap();
assert!(
!data_columns.is_empty(),
"data column sidecars shouldn't be empty"
Expand All @@ -2618,7 +2618,6 @@ async fn weak_subjectivity_sync_test(slots: Vec<Slot>, checkpoint_slot: Slot) {
Some(block_root),
block,
data_columns.to_vec(),
expected_column_indices,
&harness.spec,
)
.unwrap()
Expand Down Expand Up @@ -3819,7 +3818,6 @@ fn available_to_rpc_block<E: EthSpec>(block: AvailableBlock<E>, spec: &ChainSpec
.into_iter()
.map(|d| CustodyDataColumn::from_asserted_custody(d))
.collect(),
vec![],
spec,
)
.unwrap(),
Expand Down
4 changes: 1 addition & 3 deletions beacon_node/client/src/notifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,9 +146,7 @@ pub fn spawn_notifier<T: BeaconChainTypes>(
Instant::now(),
);
}
SyncState::SyncingFinalized { .. }
| SyncState::SyncingHead { .. }
| SyncState::SyncTransition => {
SyncState::Syncing { .. } | SyncState::SyncTransition => {
speedo.observe(head_slot, Instant::now());
}
SyncState::Stalled | SyncState::Synced => {}
Expand Down
7 changes: 3 additions & 4 deletions beacon_node/http_api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -472,7 +472,8 @@ pub fn serve<T: BeaconChainTypes>(
move |network_globals: Arc<NetworkGlobals<T::EthSpec>>,
chain: Arc<BeaconChain<T>>| async move {
match *network_globals.sync_state.read() {
SyncState::SyncingFinalized { .. } => {
// TODO(tree-sync): review, we don't have a notion of finalized sync now
SyncState::Syncing { .. } => {
let head_slot = chain.canonical_head.cached_head().head_slot();

let current_slot =
Expand All @@ -494,9 +495,7 @@ pub fn serve<T: BeaconChainTypes>(
)))
}
}
SyncState::SyncingHead { .. }
| SyncState::SyncTransition
| SyncState::BackFillSyncing { .. } => Ok(()),
SyncState::SyncTransition | SyncState::BackFillSyncing { .. } => Ok(()),
SyncState::Synced => Ok(()),
SyncState::Stalled => Ok(()),
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,7 @@ impl<E: EthSpec> NetworkBehaviour for PeerManager<E> {
}
}

if !matches!(
self.network_globals.sync_state(),
SyncState::SyncingFinalized { .. } | SyncState::SyncingHead { .. }
) {
if !matches!(self.network_globals.sync_state(), SyncState::Syncing { .. }) {
loop {
match self.status_peers.poll_next_unpin(cx) {
Poll::Ready(Some(Ok(peer_id))) => {
Expand Down
7 changes: 6 additions & 1 deletion beacon_node/lighthouse_network/src/rpc/codec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1088,7 +1088,12 @@ mod tests {
}

fn bbroot_request_v2(fork_name: ForkName) -> BlocksByRootRequest {
BlocksByRootRequest::new(vec![Hash256::zero()], &fork_context(fork_name))
let fork_context = fork_context(fork_name);
BlocksByRootRequest::new(
vec![Hash256::zero()],
&fork_context.spec,
fork_context.current_fork(),
)
}

fn blbroot_request(fork_name: ForkName) -> BlobsByRootRequest {
Expand Down
12 changes: 5 additions & 7 deletions beacon_node/lighthouse_network/src/rpc/methods.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ use types::blob_sidecar::BlobIdentifier;
use types::light_client_update::MAX_REQUEST_LIGHT_CLIENT_UPDATES;
use types::{
blob_sidecar::BlobSidecar, ChainSpec, ColumnIndex, DataColumnSidecar,
DataColumnsByRootIdentifier, Epoch, EthSpec, ForkContext, Hash256, LightClientBootstrap,
LightClientFinalityUpdate, LightClientOptimisticUpdate, LightClientUpdate, RuntimeVariableList,
SignedBeaconBlock, Slot,
DataColumnsByRootIdentifier, Epoch, EthSpec, ForkContext, ForkName, Hash256,
LightClientBootstrap, LightClientFinalityUpdate, LightClientOptimisticUpdate,
LightClientUpdate, RuntimeVariableList, SignedBeaconBlock, Slot,
};

/// Maximum length of error message.
Expand Down Expand Up @@ -440,10 +440,8 @@ pub struct BlocksByRootRequest {
}

impl BlocksByRootRequest {
pub fn new(block_roots: Vec<Hash256>, fork_context: &ForkContext) -> Self {
let max_request_blocks = fork_context
.spec
.max_request_blocks(fork_context.current_fork());
pub fn new(block_roots: Vec<Hash256>, spec: &ChainSpec, current_fork: ForkName) -> Self {
let max_request_blocks = spec.max_request_blocks(current_fork);
let block_roots = RuntimeVariableList::from_vec(block_roots, max_request_blocks);
Self::V2(BlocksByRootRequestV2 { block_roots })
}
Expand Down
61 changes: 29 additions & 32 deletions beacon_node/lighthouse_network/src/rpc/self_limiter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -313,13 +313,22 @@ mod tests {
use crate::rpc::rate_limiter::Quota;
use crate::rpc::self_limiter::SelfRateLimiter;
use crate::rpc::{Ping, Protocol, RPCSend, RequestType};
use crate::service::api_types::{AppRequestId, SingleLookupReqId, SyncRequestId};
use crate::service::api_types::{
AppRequestId, BlocksByRootRequestId, BlocksByRootRequester, HeaderLookupId, SyncRequestId,
};
use libp2p::PeerId;
use logging::create_test_tracing_subscriber;
use std::num::NonZeroU64;
use std::time::Duration;
use types::{EthSpec, ForkContext, Hash256, MainnetEthSpec, Slot};

fn get_parent_request_id() -> BlocksByRootRequester {
BlocksByRootRequester::Header(HeaderLookupId {
id: 0,
block_root: Hash256::ZERO,
})
}

/// Test that `next_peer_request_ready` correctly maintains the queue.
#[tokio::test]
async fn test_next_peer_request_ready() {
Expand All @@ -336,17 +345,15 @@ mod tests {
let mut limiter: SelfRateLimiter<AppRequestId, MainnetEthSpec> =
SelfRateLimiter::new(Some(config), fork_context).unwrap();
let peer_id = PeerId::random();
let lookup_id = 0;
let parent_request_id = get_parent_request_id();

for i in 1..=5u32 {
let _ = limiter.allows(
peer_id,
AppRequestId::Sync(SyncRequestId::SingleBlock {
id: SingleLookupReqId {
lookup_id,
req_id: i,
},
}),
AppRequestId::Sync(SyncRequestId::BlocksByRoot(BlocksByRootRequestId {
id: i,
parent_request_id,
})),
RequestType::Ping(Ping { data: i as u64 }),
);
}
Expand All @@ -363,9 +370,7 @@ mod tests {
for i in 2..=5u32 {
assert!(matches!(
iter.next().unwrap().request_id,
AppRequestId::Sync(SyncRequestId::SingleBlock {
id: SingleLookupReqId { req_id, .. },
}) if req_id == i,
AppRequestId::Sync(SyncRequestId::BlocksByRoot(BlocksByRootRequestId{id,..})) if id == i,
));
}

Expand All @@ -388,9 +393,7 @@ mod tests {
for i in 3..=5 {
assert!(matches!(
iter.next().unwrap().request_id,
AppRequestId::Sync(SyncRequestId::SingleBlock {
id: SingleLookupReqId { req_id, .. },
}) if req_id == i,
AppRequestId::Sync(SyncRequestId::BlocksByRoot(BlocksByRootRequestId{id,..})) if id == i,
));
}

Expand All @@ -409,16 +412,15 @@ mod tests {
let mut limiter: SelfRateLimiter<AppRequestId, MainnetEthSpec> =
SelfRateLimiter::new(None, fork_context).unwrap();
let peer_id = PeerId::random();
let parent_request_id = get_parent_request_id();

for i in 1..=5u32 {
let result = limiter.allows(
peer_id,
AppRequestId::Sync(SyncRequestId::SingleBlock {
id: SingleLookupReqId {
lookup_id: i,
req_id: i,
},
}),
AppRequestId::Sync(SyncRequestId::BlocksByRoot(BlocksByRootRequestId {
id: i,
parent_request_id,
})),
RequestType::Ping(Ping { data: i as u64 }),
);

Expand Down Expand Up @@ -469,9 +471,7 @@ mod tests {

assert!(matches!(
request_id,
AppRequestId::Sync(SyncRequestId::SingleBlock {
id: SingleLookupReqId { req_id, .. },
}) if *req_id == i
AppRequestId::Sync(SyncRequestId::BlocksByRoot(BlocksByRootRequestId {id,..})) if *id == i
));
}
}
Expand All @@ -487,17 +487,16 @@ mod tests {
SelfRateLimiter::new(None, fork_context).unwrap();
let peer1 = PeerId::random();
let peer2 = PeerId::random();
let parent_request_id = get_parent_request_id();

for peer in [peer1, peer2] {
for i in 1..=5u32 {
let result = limiter.allows(
peer,
AppRequestId::Sync(SyncRequestId::SingleBlock {
id: SingleLookupReqId {
lookup_id: i,
req_id: i,
},
}),
AppRequestId::Sync(SyncRequestId::BlocksByRoot(BlocksByRootRequestId {
id: i,
parent_request_id,
})),
RequestType::Ping(Ping { data: i as u64 }),
);

Expand Down Expand Up @@ -525,9 +524,7 @@ mod tests {
let (request_id, _) = failed_requests.remove(0);
assert!(matches!(
request_id,
AppRequestId::Sync(SyncRequestId::SingleBlock {
id: SingleLookupReqId { req_id, .. },
}) if req_id == i
AppRequestId::Sync(SyncRequestId::BlocksByRoot(BlocksByRootRequestId{id,..})) if id == i
));
}

Expand Down
Loading
Loading