Skip to content

Commit fcbec47

Browse files
Merge branch 'unstable' into tree-states-hot-rebase
2 parents 00fbd82 + 476f3a5 commit fcbec47

File tree

59 files changed

+1527
-598
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+1527
-598
lines changed

Cargo.lock

Lines changed: 414 additions & 33 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,8 @@ ethereum_ssz = "0.8.2"
141141
ethereum_ssz_derive = "0.8.2"
142142
ethers-core = "1"
143143
ethers-providers = { version = "1", default-features = false }
144+
ethers-signers = { version = "1", default-features = false }
145+
ethers-middleware = { version = "1", default-features = false }
144146
exit-future = "0.2"
145147
fnv = "1"
146148
fs2 = "0.4"

beacon_node/beacon_chain/src/beacon_chain.rs

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4004,7 +4004,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
40044004
&mut state,
40054005
)
40064006
.unwrap_or_else(|e| {
4007-
error!("error caching light_client data {:?}", e);
4007+
debug!("error caching light_client data {:?}", e);
40084008
});
40094009
}
40104010

@@ -7132,6 +7132,31 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
71327132
}
71337133
}
71347134
}
7135+
7136+
/// Retrieves block roots (in ascending slot order) within some slot range from fork choice.
7137+
pub fn block_roots_from_fork_choice(&self, start_slot: u64, count: u64) -> Vec<Hash256> {
7138+
let head_block_root = self.canonical_head.cached_head().head_block_root();
7139+
let fork_choice_read_lock = self.canonical_head.fork_choice_read_lock();
7140+
let block_roots_iter = fork_choice_read_lock
7141+
.proto_array()
7142+
.iter_block_roots(&head_block_root);
7143+
let end_slot = start_slot.saturating_add(count);
7144+
let mut roots = vec![];
7145+
7146+
for (root, slot) in block_roots_iter {
7147+
if slot < end_slot && slot >= start_slot {
7148+
roots.push(root);
7149+
}
7150+
if slot < start_slot {
7151+
break;
7152+
}
7153+
}
7154+
7155+
drop(fork_choice_read_lock);
7156+
// return in ascending slot order
7157+
roots.reverse();
7158+
roots
7159+
}
71357160
}
71367161

71377162
impl<T: BeaconChainTypes> Drop for BeaconChain<T> {

beacon_node/beacon_chain/src/block_verification.rs

Lines changed: 0 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1267,40 +1267,6 @@ impl<T: BeaconChainTypes> IntoExecutionPendingBlock<T> for SignatureVerifiedBloc
12671267
}
12681268
}
12691269

1270-
impl<T: BeaconChainTypes> IntoExecutionPendingBlock<T> for Arc<SignedBeaconBlock<T::EthSpec>> {
1271-
/// Verifies the `SignedBeaconBlock` by first transforming it into a `SignatureVerifiedBlock`
1272-
/// and then using that implementation of `IntoExecutionPendingBlock` to complete verification.
1273-
fn into_execution_pending_block_slashable(
1274-
self,
1275-
block_root: Hash256,
1276-
chain: &Arc<BeaconChain<T>>,
1277-
notify_execution_layer: NotifyExecutionLayer,
1278-
) -> Result<ExecutionPendingBlock<T>, BlockSlashInfo<BlockError>> {
1279-
// Perform an early check to prevent wasting time on irrelevant blocks.
1280-
let block_root = check_block_relevancy(&self, block_root, chain)
1281-
.map_err(|e| BlockSlashInfo::SignatureNotChecked(self.signed_block_header(), e))?;
1282-
let maybe_available = chain
1283-
.data_availability_checker
1284-
.verify_kzg_for_rpc_block(RpcBlock::new_without_blobs(Some(block_root), self.clone()))
1285-
.map_err(|e| {
1286-
BlockSlashInfo::SignatureNotChecked(
1287-
self.signed_block_header(),
1288-
BlockError::AvailabilityCheck(e),
1289-
)
1290-
})?;
1291-
SignatureVerifiedBlock::check_slashable(maybe_available, block_root, chain)?
1292-
.into_execution_pending_block_slashable(block_root, chain, notify_execution_layer)
1293-
}
1294-
1295-
fn block(&self) -> &SignedBeaconBlock<T::EthSpec> {
1296-
self
1297-
}
1298-
1299-
fn block_cloned(&self) -> Arc<SignedBeaconBlock<T::EthSpec>> {
1300-
self.clone()
1301-
}
1302-
}
1303-
13041270
impl<T: BeaconChainTypes> IntoExecutionPendingBlock<T> for RpcBlock<T::EthSpec> {
13051271
/// Verifies the `SignedBeaconBlock` by first transforming it into a `SignatureVerifiedBlock`
13061272
/// and then using that implementation of `IntoExecutionPendingBlock` to complete verification.

beacon_node/beacon_chain/src/block_verification_types.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,14 +103,14 @@ impl<E: EthSpec> RpcBlock<E> {
103103
pub fn new_without_blobs(
104104
block_root: Option<Hash256>,
105105
block: Arc<SignedBeaconBlock<E>>,
106+
custody_columns_count: usize,
106107
) -> Self {
107108
let block_root = block_root.unwrap_or_else(|| get_block_root(&block));
108109

109110
Self {
110111
block_root,
111112
block: RpcBlockInner::Block(block),
112-
// Block has zero columns
113-
custody_columns_count: 0,
113+
custody_columns_count,
114114
}
115115
}
116116

beacon_node/beacon_chain/src/eth1_chain.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,12 @@ pub struct DummyEth1ChainBackend<E: EthSpec>(PhantomData<E>);
362362
impl<E: EthSpec> Eth1ChainBackend<E> for DummyEth1ChainBackend<E> {
363363
/// Produce some deterministic junk based upon the current epoch.
364364
fn eth1_data(&self, state: &BeaconState<E>, _spec: &ChainSpec) -> Result<Eth1Data, Error> {
365+
// [New in Electra:EIP6110]
366+
if let Ok(deposit_requests_start_index) = state.deposit_requests_start_index() {
367+
if state.eth1_deposit_index() == deposit_requests_start_index {
368+
return Ok(state.eth1_data().clone());
369+
}
370+
}
365371
let current_epoch = state.current_epoch();
366372
let slots_per_voting_period = E::slots_per_eth1_voting_period() as u64;
367373
let current_voting_period: u64 = current_epoch.as_u64() / slots_per_voting_period;
@@ -456,6 +462,12 @@ impl<E: EthSpec> CachingEth1Backend<E> {
456462

457463
impl<E: EthSpec> Eth1ChainBackend<E> for CachingEth1Backend<E> {
458464
fn eth1_data(&self, state: &BeaconState<E>, spec: &ChainSpec) -> Result<Eth1Data, Error> {
465+
// [New in Electra:EIP6110]
466+
if let Ok(deposit_requests_start_index) = state.deposit_requests_start_index() {
467+
if state.eth1_deposit_index() == deposit_requests_start_index {
468+
return Ok(state.eth1_data().clone());
469+
}
470+
}
459471
let period = E::SlotsPerEth1VotingPeriod::to_u64();
460472
let voting_period_start_slot = (state.slot() / period) * period;
461473
let voting_period_start_seconds = slot_start_seconds(

beacon_node/beacon_chain/src/test_utils.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2366,7 +2366,7 @@ where
23662366
.blob_kzg_commitments()
23672367
.is_ok_and(|c| !c.is_empty());
23682368
if !has_blobs {
2369-
return RpcBlock::new_without_blobs(Some(block_root), block);
2369+
return RpcBlock::new_without_blobs(Some(block_root), block, 0);
23702370
}
23712371

23722372
// Blobs are stored as data columns from Fulu (PeerDAS)
@@ -2417,7 +2417,7 @@ where
24172417
&self.spec,
24182418
)?
24192419
} else {
2420-
RpcBlock::new_without_blobs(Some(block_root), block)
2420+
RpcBlock::new_without_blobs(Some(block_root), block, 0)
24212421
}
24222422
} else {
24232423
let blobs = blob_items

beacon_node/beacon_chain/tests/block_verification.rs

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ fn build_rpc_block(
147147
RpcBlock::new_with_custody_columns(None, block, columns.clone(), columns.len(), spec)
148148
.unwrap()
149149
}
150-
None => RpcBlock::new_without_blobs(None, block),
150+
None => RpcBlock::new_without_blobs(None, block, 0),
151151
}
152152
}
153153

@@ -370,6 +370,7 @@ async fn chain_segment_non_linear_parent_roots() {
370370
blocks[3] = RpcBlock::new_without_blobs(
371371
None,
372372
Arc::new(SignedBeaconBlock::from_block(block, signature)),
373+
harness.sampling_column_count,
373374
);
374375

375376
assert!(
@@ -407,6 +408,7 @@ async fn chain_segment_non_linear_slots() {
407408
blocks[3] = RpcBlock::new_without_blobs(
408409
None,
409410
Arc::new(SignedBeaconBlock::from_block(block, signature)),
411+
harness.sampling_column_count,
410412
);
411413

412414
assert!(
@@ -434,6 +436,7 @@ async fn chain_segment_non_linear_slots() {
434436
blocks[3] = RpcBlock::new_without_blobs(
435437
None,
436438
Arc::new(SignedBeaconBlock::from_block(block, signature)),
439+
harness.sampling_column_count,
437440
);
438441

439442
assert!(
@@ -575,11 +578,16 @@ async fn invalid_signature_gossip_block() {
575578
.into_block_error()
576579
.expect("should import all blocks prior to the one being tested");
577580
let signed_block = SignedBeaconBlock::from_block(block, junk_signature());
581+
let rpc_block = RpcBlock::new_without_blobs(
582+
None,
583+
Arc::new(signed_block),
584+
harness.sampling_column_count,
585+
);
578586
let process_res = harness
579587
.chain
580588
.process_block(
581-
signed_block.canonical_root(),
582-
Arc::new(signed_block),
589+
rpc_block.block_root(),
590+
rpc_block,
583591
NotifyExecutionLayer::Yes,
584592
BlockImportSource::Lookup,
585593
|| Ok(()),
@@ -1541,12 +1549,13 @@ async fn add_base_block_to_altair_chain() {
15411549
));
15421550

15431551
// Ensure that it would be impossible to import via `BeaconChain::process_block`.
1552+
let base_rpc_block = RpcBlock::new_without_blobs(None, Arc::new(base_block.clone()), 0);
15441553
assert!(matches!(
15451554
harness
15461555
.chain
15471556
.process_block(
1548-
base_block.canonical_root(),
1549-
Arc::new(base_block.clone()),
1557+
base_rpc_block.block_root(),
1558+
base_rpc_block,
15501559
NotifyExecutionLayer::Yes,
15511560
BlockImportSource::Lookup,
15521561
|| Ok(()),
@@ -1564,7 +1573,7 @@ async fn add_base_block_to_altair_chain() {
15641573
harness
15651574
.chain
15661575
.process_chain_segment(
1567-
vec![RpcBlock::new_without_blobs(None, Arc::new(base_block))],
1576+
vec![RpcBlock::new_without_blobs(None, Arc::new(base_block), 0)],
15681577
NotifyExecutionLayer::Yes,
15691578
)
15701579
.await,
@@ -1677,12 +1686,13 @@ async fn add_altair_block_to_base_chain() {
16771686
));
16781687

16791688
// Ensure that it would be impossible to import via `BeaconChain::process_block`.
1689+
let altair_rpc_block = RpcBlock::new_without_blobs(None, Arc::new(altair_block.clone()), 0);
16801690
assert!(matches!(
16811691
harness
16821692
.chain
16831693
.process_block(
1684-
altair_block.canonical_root(),
1685-
Arc::new(altair_block.clone()),
1694+
altair_rpc_block.block_root(),
1695+
altair_rpc_block,
16861696
NotifyExecutionLayer::Yes,
16871697
BlockImportSource::Lookup,
16881698
|| Ok(()),
@@ -1700,7 +1710,7 @@ async fn add_altair_block_to_base_chain() {
17001710
harness
17011711
.chain
17021712
.process_chain_segment(
1703-
vec![RpcBlock::new_without_blobs(None, Arc::new(altair_block))],
1713+
vec![RpcBlock::new_without_blobs(None, Arc::new(altair_block), 0)],
17041714
NotifyExecutionLayer::Yes
17051715
)
17061716
.await,
@@ -1761,11 +1771,16 @@ async fn import_duplicate_block_unrealized_justification() {
17611771
// Create two verified variants of the block, representing the same block being processed in
17621772
// parallel.
17631773
let notify_execution_layer = NotifyExecutionLayer::Yes;
1764-
let verified_block1 = block
1774+
let rpc_block = RpcBlock::new_without_blobs(
1775+
Some(block_root),
1776+
block.clone(),
1777+
harness.sampling_column_count,
1778+
);
1779+
let verified_block1 = rpc_block
17651780
.clone()
17661781
.into_execution_pending_block(block_root, chain, notify_execution_layer)
17671782
.unwrap();
1768-
let verified_block2 = block
1783+
let verified_block2 = rpc_block
17691784
.into_execution_pending_block(block_root, chain, notify_execution_layer)
17701785
.unwrap();
17711786

beacon_node/beacon_chain/tests/payload_invalidation.rs

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#![cfg(not(debug_assertions))]
22

3+
use beacon_chain::block_verification_types::RpcBlock;
34
use beacon_chain::{
45
canonical_head::{CachedHead, CanonicalHead},
56
test_utils::{BeaconChainHarness, EphemeralHarnessType},
@@ -687,12 +688,14 @@ async fn invalidates_all_descendants() {
687688
assert_eq!(fork_parent_state.slot(), fork_parent_slot);
688689
let ((fork_block, _), _fork_post_state) =
689690
rig.harness.make_block(fork_parent_state, fork_slot).await;
691+
let fork_rpc_block =
692+
RpcBlock::new_without_blobs(None, fork_block.clone(), rig.harness.sampling_column_count);
690693
let fork_block_root = rig
691694
.harness
692695
.chain
693696
.process_block(
694-
fork_block.canonical_root(),
695-
fork_block,
697+
fork_rpc_block.block_root(),
698+
fork_rpc_block,
696699
NotifyExecutionLayer::Yes,
697700
BlockImportSource::Lookup,
698701
|| Ok(()),
@@ -788,12 +791,14 @@ async fn switches_heads() {
788791
let ((fork_block, _), _fork_post_state) =
789792
rig.harness.make_block(fork_parent_state, fork_slot).await;
790793
let fork_parent_root = fork_block.parent_root();
794+
let fork_rpc_block =
795+
RpcBlock::new_without_blobs(None, fork_block.clone(), rig.harness.sampling_column_count);
791796
let fork_block_root = rig
792797
.harness
793798
.chain
794799
.process_block(
795-
fork_block.canonical_root(),
796-
fork_block,
800+
fork_rpc_block.block_root(),
801+
fork_rpc_block,
797802
NotifyExecutionLayer::Yes,
798803
BlockImportSource::Lookup,
799804
|| Ok(()),
@@ -1057,8 +1062,10 @@ async fn invalid_parent() {
10571062
));
10581063

10591064
// Ensure the block built atop an invalid payload is invalid for import.
1065+
let rpc_block =
1066+
RpcBlock::new_without_blobs(None, block.clone(), rig.harness.sampling_column_count);
10601067
assert!(matches!(
1061-
rig.harness.chain.process_block(block.canonical_root(), block.clone(), NotifyExecutionLayer::Yes, BlockImportSource::Lookup,
1068+
rig.harness.chain.process_block(rpc_block.block_root(), rpc_block, NotifyExecutionLayer::Yes, BlockImportSource::Lookup,
10621069
|| Ok(()),
10631070
).await,
10641071
Err(BlockError::ParentExecutionPayloadInvalid { parent_root: invalid_root })
@@ -1380,11 +1387,13 @@ async fn recover_from_invalid_head_by_importing_blocks() {
13801387
} = InvalidHeadSetup::new().await;
13811388

13821389
// Import the fork block, it should become the head.
1390+
let fork_rpc_block =
1391+
RpcBlock::new_without_blobs(None, fork_block.clone(), rig.harness.sampling_column_count);
13831392
rig.harness
13841393
.chain
13851394
.process_block(
1386-
fork_block.canonical_root(),
1387-
fork_block.clone(),
1395+
fork_rpc_block.block_root(),
1396+
fork_rpc_block,
13881397
NotifyExecutionLayer::Yes,
13891398
BlockImportSource::Lookup,
13901399
|| Ok(()),

beacon_node/beacon_chain/tests/store_tests.rs

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#![cfg(not(debug_assertions))]
22

33
use beacon_chain::attestation_verification::Error as AttnError;
4+
use beacon_chain::block_verification_types::RpcBlock;
45
use beacon_chain::builder::BeaconChainBuilder;
56
use beacon_chain::data_availability_checker::AvailableBlock;
67
use beacon_chain::schema_change::migrate_schema;
@@ -2690,12 +2691,17 @@ async fn process_blocks_and_attestations_for_unaligned_checkpoint() {
26902691
assert_eq!(split.block_root, valid_fork_block.parent_root());
26912692
assert_ne!(split.state_root, unadvanced_split_state_root);
26922693

2694+
let invalid_fork_rpc_block = RpcBlock::new_without_blobs(
2695+
None,
2696+
invalid_fork_block.clone(),
2697+
harness.sampling_column_count,
2698+
);
26932699
// Applying the invalid block should fail.
26942700
let err = harness
26952701
.chain
26962702
.process_block(
2697-
invalid_fork_block.canonical_root(),
2698-
invalid_fork_block.clone(),
2703+
invalid_fork_rpc_block.block_root(),
2704+
invalid_fork_rpc_block,
26992705
NotifyExecutionLayer::Yes,
27002706
BlockImportSource::Lookup,
27012707
|| Ok(()),
@@ -2705,11 +2711,16 @@ async fn process_blocks_and_attestations_for_unaligned_checkpoint() {
27052711
assert!(matches!(err, BlockError::WouldRevertFinalizedSlot { .. }));
27062712

27072713
// Applying the valid block should succeed, but it should not become head.
2714+
let valid_fork_rpc_block = RpcBlock::new_without_blobs(
2715+
None,
2716+
valid_fork_block.clone(),
2717+
harness.sampling_column_count,
2718+
);
27082719
harness
27092720
.chain
27102721
.process_block(
2711-
valid_fork_block.canonical_root(),
2712-
valid_fork_block.clone(),
2722+
valid_fork_rpc_block.block_root(),
2723+
valid_fork_rpc_block,
27132724
NotifyExecutionLayer::Yes,
27142725
BlockImportSource::Lookup,
27152726
|| Ok(()),

0 commit comments

Comments
 (0)