Skip to content

Commit 3534c85

Browse files
committed
Optimize finalized chain sync by skipping newPayload messages (sigp#3738)
## Issue Addressed sigp#3704 ## Proposed Changes Adds is_syncing_finalized: bool parameter for block verification functions. Sets the payload_verification_status to Optimistic if is_syncing_finalized is true. Uses SyncState in NetworkGlobals in BeaconProcessor to retrieve the syncing status. ## Additional Info I could implement FinalizedSignatureVerifiedBlock if you think it would be nicer.
1 parent a2969ba commit 3534c85

File tree

15 files changed

+200
-62
lines changed

15 files changed

+200
-62
lines changed

beacon_node/beacon_chain/src/beacon_chain.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use crate::errors::{BeaconChainError as Error, BlockProductionError};
1818
use crate::eth1_chain::{Eth1Chain, Eth1ChainBackend};
1919
use crate::eth1_finalization_cache::{Eth1FinalizationCache, Eth1FinalizationData};
2020
use crate::events::ServerSentEventHandler;
21-
use crate::execution_payload::{get_execution_payload, PreparePayloadHandle};
21+
use crate::execution_payload::{get_execution_payload, NotifyExecutionLayer, PreparePayloadHandle};
2222
use crate::fork_choice_signal::{ForkChoiceSignalRx, ForkChoiceSignalTx, ForkChoiceWaitResult};
2323
use crate::head_tracker::HeadTracker;
2424
use crate::historical_blocks::HistoricalBlockError;
@@ -2341,6 +2341,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
23412341
self: &Arc<Self>,
23422342
chain_segment: Vec<Arc<SignedBeaconBlock<T::EthSpec>>>,
23432343
count_unrealized: CountUnrealized,
2344+
notify_execution_layer: NotifyExecutionLayer,
23442345
) -> ChainSegmentResult<T::EthSpec> {
23452346
let mut imported_blocks = 0;
23462347

@@ -2409,6 +2410,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
24092410
signature_verified_block.block_root(),
24102411
signature_verified_block,
24112412
count_unrealized,
2413+
notify_execution_layer,
24122414
)
24132415
.await
24142416
{
@@ -2497,6 +2499,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
24972499
block_root: Hash256,
24982500
unverified_block: B,
24992501
count_unrealized: CountUnrealized,
2502+
notify_execution_layer: NotifyExecutionLayer,
25002503
) -> Result<Hash256, BlockError<T::EthSpec>> {
25012504
// Start the Prometheus timer.
25022505
let _full_timer = metrics::start_timer(&metrics::BLOCK_PROCESSING_TIMES);
@@ -2510,8 +2513,11 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
25102513
// A small closure to group the verification and import errors.
25112514
let chain = self.clone();
25122515
let import_block = async move {
2513-
let execution_pending =
2514-
unverified_block.into_execution_pending_block(block_root, &chain)?;
2516+
let execution_pending = unverified_block.into_execution_pending_block(
2517+
block_root,
2518+
&chain,
2519+
notify_execution_layer,
2520+
)?;
25152521
chain
25162522
.import_execution_pending_block(execution_pending, count_unrealized)
25172523
.await

beacon_node/beacon_chain/src/block_verification.rs

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
use crate::eth1_finalization_cache::Eth1FinalizationData;
4646
use crate::execution_payload::{
4747
is_optimistic_candidate_block, validate_execution_payload_for_gossip, validate_merge_block,
48-
AllowOptimisticImport, PayloadNotifier,
48+
AllowOptimisticImport, NotifyExecutionLayer, PayloadNotifier,
4949
};
5050
use crate::snapshot_cache::PreProcessingSnapshot;
5151
use crate::validator_monitor::HISTORIC_EPOCHS as VALIDATOR_MONITOR_HISTORIC_EPOCHS;
@@ -636,8 +636,9 @@ pub trait IntoExecutionPendingBlock<T: BeaconChainTypes>: Sized {
636636
self,
637637
block_root: Hash256,
638638
chain: &Arc<BeaconChain<T>>,
639+
notify_execution_layer: NotifyExecutionLayer,
639640
) -> Result<ExecutionPendingBlock<T>, BlockError<T::EthSpec>> {
640-
self.into_execution_pending_block_slashable(block_root, chain)
641+
self.into_execution_pending_block_slashable(block_root, chain, notify_execution_layer)
641642
.map(|execution_pending| {
642643
// Supply valid block to slasher.
643644
if let Some(slasher) = chain.slasher.as_ref() {
@@ -653,6 +654,7 @@ pub trait IntoExecutionPendingBlock<T: BeaconChainTypes>: Sized {
653654
self,
654655
block_root: Hash256,
655656
chain: &Arc<BeaconChain<T>>,
657+
notify_execution_layer: NotifyExecutionLayer,
656658
) -> Result<ExecutionPendingBlock<T>, BlockSlashInfo<BlockError<T::EthSpec>>>;
657659

658660
fn block(&self) -> &SignedBeaconBlock<T::EthSpec>;
@@ -899,10 +901,15 @@ impl<T: BeaconChainTypes> IntoExecutionPendingBlock<T> for GossipVerifiedBlock<T
899901
self,
900902
block_root: Hash256,
901903
chain: &Arc<BeaconChain<T>>,
904+
notify_execution_layer: NotifyExecutionLayer,
902905
) -> Result<ExecutionPendingBlock<T>, BlockSlashInfo<BlockError<T::EthSpec>>> {
903906
let execution_pending =
904907
SignatureVerifiedBlock::from_gossip_verified_block_check_slashable(self, chain)?;
905-
execution_pending.into_execution_pending_block_slashable(block_root, chain)
908+
execution_pending.into_execution_pending_block_slashable(
909+
block_root,
910+
chain,
911+
notify_execution_layer,
912+
)
906913
}
907914

908915
fn block(&self) -> &SignedBeaconBlock<T::EthSpec> {
@@ -1032,6 +1039,7 @@ impl<T: BeaconChainTypes> IntoExecutionPendingBlock<T> for SignatureVerifiedBloc
10321039
self,
10331040
block_root: Hash256,
10341041
chain: &Arc<BeaconChain<T>>,
1042+
notify_execution_layer: NotifyExecutionLayer,
10351043
) -> Result<ExecutionPendingBlock<T>, BlockSlashInfo<BlockError<T::EthSpec>>> {
10361044
let header = self.block.signed_block_header();
10371045
let (parent, block) = if let Some(parent) = self.parent {
@@ -1047,6 +1055,7 @@ impl<T: BeaconChainTypes> IntoExecutionPendingBlock<T> for SignatureVerifiedBloc
10471055
parent,
10481056
self.consensus_context,
10491057
chain,
1058+
notify_execution_layer,
10501059
)
10511060
.map_err(|e| BlockSlashInfo::SignatureValid(header, e))
10521061
}
@@ -1063,13 +1072,14 @@ impl<T: BeaconChainTypes> IntoExecutionPendingBlock<T> for Arc<SignedBeaconBlock
10631072
self,
10641073
block_root: Hash256,
10651074
chain: &Arc<BeaconChain<T>>,
1075+
notify_execution_layer: NotifyExecutionLayer,
10661076
) -> Result<ExecutionPendingBlock<T>, BlockSlashInfo<BlockError<T::EthSpec>>> {
10671077
// Perform an early check to prevent wasting time on irrelevant blocks.
10681078
let block_root = check_block_relevancy(&self, block_root, chain)
10691079
.map_err(|e| BlockSlashInfo::SignatureNotChecked(self.signed_block_header(), e))?;
10701080

10711081
SignatureVerifiedBlock::check_slashable(self, block_root, chain)?
1072-
.into_execution_pending_block_slashable(block_root, chain)
1082+
.into_execution_pending_block_slashable(block_root, chain, notify_execution_layer)
10731083
}
10741084

10751085
fn block(&self) -> &SignedBeaconBlock<T::EthSpec> {
@@ -1091,6 +1101,7 @@ impl<T: BeaconChainTypes> ExecutionPendingBlock<T> {
10911101
parent: PreProcessingSnapshot<T::EthSpec>,
10921102
mut consensus_context: ConsensusContext<T::EthSpec>,
10931103
chain: &Arc<BeaconChain<T>>,
1104+
notify_execution_layer: NotifyExecutionLayer,
10941105
) -> Result<Self, BlockError<T::EthSpec>> {
10951106
if let Some(parent) = chain
10961107
.canonical_head
@@ -1237,7 +1248,8 @@ impl<T: BeaconChainTypes> ExecutionPendingBlock<T> {
12371248

12381249
// Define a future that will verify the execution payload with an execution engine (but
12391250
// don't execute it yet).
1240-
let payload_notifier = PayloadNotifier::new(chain.clone(), block.clone(), &state)?;
1251+
let payload_notifier =
1252+
PayloadNotifier::new(chain.clone(), block.clone(), &state, notify_execution_layer)?;
12411253
let is_valid_merge_transition_block =
12421254
is_merge_transition_block(&state, block.message().body());
12431255
let payload_verification_future = async move {

beacon_node/beacon_chain/src/execution_payload.rs

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,16 @@ pub enum AllowOptimisticImport {
3535
No,
3636
}
3737

38+
/// Signal whether the execution payloads of new blocks should be
39+
/// immediately verified with the EL or imported optimistically without
40+
/// any EL communication.
41+
#[derive(Default, Clone, Copy)]
42+
pub enum NotifyExecutionLayer {
43+
#[default]
44+
Yes,
45+
No,
46+
}
47+
3848
/// Used to await the result of executing payload with a remote EE.
3949
pub struct PayloadNotifier<T: BeaconChainTypes> {
4050
pub chain: Arc<BeaconChain<T>>,
@@ -47,21 +57,27 @@ impl<T: BeaconChainTypes> PayloadNotifier<T> {
4757
chain: Arc<BeaconChain<T>>,
4858
block: Arc<SignedBeaconBlock<T::EthSpec>>,
4959
state: &BeaconState<T::EthSpec>,
60+
notify_execution_layer: NotifyExecutionLayer,
5061
) -> Result<Self, BlockError<T::EthSpec>> {
51-
let payload_verification_status = if is_execution_enabled(state, block.message().body()) {
52-
// Perform the initial stages of payload verification.
53-
//
54-
// We will duplicate these checks again during `per_block_processing`, however these checks
55-
// are cheap and doing them here ensures we protect the execution engine from junk.
56-
partially_verify_execution_payload(
57-
state,
58-
block.message().execution_payload()?,
59-
&chain.spec,
60-
)
61-
.map_err(BlockError::PerBlockProcessingError)?;
62-
None
63-
} else {
64-
Some(PayloadVerificationStatus::Irrelevant)
62+
let payload_verification_status = match notify_execution_layer {
63+
NotifyExecutionLayer::No => Some(PayloadVerificationStatus::Optimistic),
64+
NotifyExecutionLayer::Yes => {
65+
if is_execution_enabled(state, block.message().body()) {
66+
// Perform the initial stages of payload verification.
67+
//
68+
// We will duplicate these checks again during `per_block_processing`, however these checks
69+
// are cheap and doing them here ensures we protect the execution engine from junk.
70+
partially_verify_execution_payload(
71+
state,
72+
block.message().execution_payload()?,
73+
&chain.spec,
74+
)
75+
.map_err(BlockError::PerBlockProcessingError)?;
76+
None
77+
} else {
78+
Some(PayloadVerificationStatus::Irrelevant)
79+
}
80+
}
6581
};
6682

6783
Ok(Self {

beacon_node/beacon_chain/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ pub use canonical_head::{CachedHead, CanonicalHead, CanonicalHeadRwLock};
6363
pub use eth1_chain::{Eth1Chain, Eth1ChainBackend};
6464
pub use events::ServerSentEventHandler;
6565
pub use execution_layer::EngineState;
66+
pub use execution_payload::NotifyExecutionLayer;
6667
pub use fork_choice::{ExecutionStatus, ForkchoiceUpdateParameters};
6768
pub use metrics::scrape_for_metrics;
6869
pub use parking_lot;

beacon_node/beacon_chain/src/test_utils.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ pub use crate::persisted_beacon_chain::PersistedBeaconChain;
22
pub use crate::{
33
beacon_chain::{BEACON_CHAIN_DB_KEY, ETH1_CACHE_DB_KEY, FORK_CHOICE_DB_KEY, OP_POOL_DB_KEY},
44
migrate::MigratorConfig,
5-
BeaconChainError, ProduceBlockVerification,
5+
BeaconChainError, NotifyExecutionLayer, ProduceBlockVerification,
66
};
77
use crate::{
88
builder::{BeaconChainBuilder, Witness},
@@ -1460,7 +1460,12 @@ where
14601460
self.set_current_slot(slot);
14611461
let block_hash: SignedBeaconBlockHash = self
14621462
.chain
1463-
.process_block(block_root, Arc::new(block), CountUnrealized::True)
1463+
.process_block(
1464+
block_root,
1465+
Arc::new(block),
1466+
CountUnrealized::True,
1467+
NotifyExecutionLayer::Yes,
1468+
)
14641469
.await?
14651470
.into();
14661471
self.chain.recompute_head_at_current_slot().await;
@@ -1477,6 +1482,7 @@ where
14771482
block.canonical_root(),
14781483
Arc::new(block),
14791484
CountUnrealized::True,
1485+
NotifyExecutionLayer::Yes,
14801486
)
14811487
.await?
14821488
.into();

0 commit comments

Comments
 (0)