Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 4 additions & 0 deletions Cargo.lock

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

20 changes: 20 additions & 0 deletions crates/engine/primitives/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,8 @@ pub struct TreeConfig {
/// computation is spawned in parallel and whichever finishes first is used.
/// If `None`, the timeout fallback is disabled.
state_root_task_timeout: Option<Duration>,
/// Whether to share execution cache with the payload builder.
share_execution_cache_with_payload_builder: bool,
/// Maximum random jitter applied before each proof computation (trie-debug only).
/// When set, each proof worker sleeps for a random duration up to this value
/// before starting a proof calculation.
Expand Down Expand Up @@ -186,6 +188,7 @@ impl Default for TreeConfig {
slow_block_threshold: None,
disable_sparse_trie_cache_pruning: false,
state_root_task_timeout: Some(DEFAULT_STATE_ROOT_TASK_TIMEOUT),
share_execution_cache_with_payload_builder: false,
#[cfg(feature = "trie-debug")]
proof_jitter: None,
}
Expand Down Expand Up @@ -220,6 +223,7 @@ impl TreeConfig {
sparse_trie_max_hot_accounts: usize,
slow_block_threshold: Option<Duration>,
state_root_task_timeout: Option<Duration>,
share_execution_cache_with_payload_builder: bool,
) -> Self {
Self {
persistence_threshold,
Expand Down Expand Up @@ -247,6 +251,7 @@ impl TreeConfig {
slow_block_threshold,
disable_sparse_trie_cache_pruning: false,
state_root_task_timeout,
share_execution_cache_with_payload_builder,
#[cfg(feature = "trie-debug")]
proof_jitter: None,
}
Expand Down Expand Up @@ -559,6 +564,21 @@ impl TreeConfig {
self
}

/// Returns whether to share execution cache with the payload builder.
pub const fn share_execution_cache_with_payload_builder(&self) -> bool {
self.share_execution_cache_with_payload_builder
}

/// Setter for whether to share execution cache with the payload builder.
pub const fn with_share_execution_cache_with_payload_builder(
mut self,
share_execution_cache_with_payload_builder: bool,
) -> Self {
self.share_execution_cache_with_payload_builder =
share_execution_cache_with_payload_builder;
self
}

/// Returns the proof jitter duration, if configured (trie-debug only).
#[cfg(feature = "trie-debug")]
pub const fn proof_jitter(&self) -> Option<Duration> {
Expand Down
19 changes: 14 additions & 5 deletions crates/engine/tree/src/tree/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use reth_engine_primitives::{
};
use reth_errors::{ConsensusError, ProviderResult};
use reth_evm::ConfigureEvm;
use reth_payload_builder::PayloadBuilderHandle;
use reth_payload_builder::{BuildNewPayload, PayloadBuilderHandle};
use reth_payload_primitives::{BuiltPayload, NewPayloadError, PayloadTypes};
use reth_primitives_traits::{
FastInstant as Instant, NodePrimitives, RecoveredBlock, SealedBlock, SealedHeader,
Expand Down Expand Up @@ -3079,12 +3079,12 @@ where
/// return an error if the payload attributes are invalid.
fn process_payload_attributes(
&self,
attrs: T::PayloadAttributes,
attributes: T::PayloadAttributes,
head: &N::BlockHeader,
state: ForkchoiceState,
) -> OnForkChoiceUpdated {
if let Err(err) =
self.payload_validator.validate_payload_attributes_against_header(&attrs, head)
self.payload_validator.validate_payload_attributes_against_header(&attributes, head)
{
warn!(target: "engine::tree", %err, ?head, "Invalid payload attributes");
return OnForkChoiceUpdated::invalid_payload_attributes()
Expand All @@ -3095,10 +3095,19 @@ where
// payloadAttributes is not null and the forkchoice state has been updated successfully.
// The build process is specified in the Payload building section.

let cache = if self.config.share_execution_cache_with_payload_builder() {
self.payload_validator.cache_for(state.head_block_hash)
} else {
None
};

// send the payload to the builder and return the receiver for the pending payload
// id, initiating payload job is handled asynchronously
let pending_payload_id =
self.payload_builder.send_new_payload(state.head_block_hash, attrs);
let pending_payload_id = self.payload_builder.send_new_payload(BuildNewPayload {
parent_hash: state.head_block_hash,
attributes,
cache,
});

// Client software MUST respond to this method call in the following way:
// {
Expand Down
2 changes: 1 addition & 1 deletion crates/engine/tree/src/tree/payload_processor/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -520,7 +520,7 @@ where
/// If the given hash is different then what is recently cached, then this will create a new
/// instance.
#[instrument(level = "debug", target = "engine::caching", skip(self))]
fn cache_for(&self, parent_hash: B256) -> SavedCache {
pub fn cache_for(&self, parent_hash: B256) -> SavedCache {
if let Some(cache) = self.execution_cache.get_cache_for(parent_hash) {
debug!("reusing execution cache");
cache
Expand Down
9 changes: 8 additions & 1 deletion crates/engine/tree/src/tree/payload_validator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ use reth_evm::{
block::BlockExecutor, execute::ExecutableTxFor, ConfigureEvm, EvmEnvFor, ExecutionCtxFor,
OnStateHook, SpecFor,
};
use reth_execution_cache::CacheStats;
use reth_execution_cache::{CacheStats, SavedCache};
use reth_payload_primitives::{
BuiltPayload, InvalidPayloadAttributesError, NewPayloadError, PayloadTypes,
};
Expand Down Expand Up @@ -1941,6 +1941,9 @@ pub trait EngineValidator<
/// This is invoked when blocks are inserted via `InsertExecutedBlock` (e.g., locally built
/// blocks by sequencers) to allow implementations to update internal state such as caches.
fn on_inserted_executed_block(&self, block: ExecutedBlock<N>);

/// Returns [`SavedCache`] for the given block hash.
fn cache_for(&self, _block_hash: B256) -> Option<SavedCache>;
}

impl<N, Types, P, Evm, V> EngineValidator<Types> for BasicEngineValidator<P, Evm, V>
Expand Down Expand Up @@ -2004,6 +2007,10 @@ where
&block.execution_output.state,
);
}

fn cache_for(&self, block_hash: B256) -> Option<SavedCache> {
Some(self.payload_processor.cache_for(block_hash))
}
}

impl<P, Evm, V> WaitForCaches for BasicEngineValidator<P, Evm, V>
Expand Down
1 change: 1 addition & 0 deletions crates/ethereum/payload/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ workspace = true
# reth
reth-consensus-common.workspace = true
reth-ethereum-primitives.workspace = true
reth-execution-cache.workspace = true
reth-primitives-traits.workspace = true
reth-revm.workspace = true
reth-transaction-pool.workspace = true
Expand Down
20 changes: 17 additions & 3 deletions crates/ethereum/payload/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ use reth_evm::{
ConfigureEvm, Evm, NextBlockEnvAttributes,
};
use reth_evm_ethereum::EthEvmConfig;
use reth_execution_cache::CachedStateProvider;
use reth_payload_builder::{BlobSidecars, EthBuiltPayload};
use reth_payload_builder_primitives::PayloadBuilderError;
use reth_payload_primitives::PayloadAttributes;
Expand Down Expand Up @@ -115,7 +116,13 @@ where
&self,
config: PayloadConfig<Self::Attributes>,
) -> Result<EthBuiltPayload, PayloadBuilderError> {
let args = BuildArguments::new(Default::default(), config, Default::default(), None);
let args = BuildArguments::new(
Default::default(),
Default::default(),
config,
Default::default(),
None,
);

default_ethereum_payload(
self.evm_config.clone(),
Expand Down Expand Up @@ -150,10 +157,17 @@ where
Pool: TransactionPool<Transaction: PoolTransaction<Consensus = TransactionSigned>>,
F: FnOnce(BestTransactionsAttributes) -> BestTransactionsIter<Pool>,
{
let BuildArguments { mut cached_reads, config, cancel, best_payload } = args;
let BuildArguments { mut cached_reads, execution_cache, config, cancel, best_payload } = args;
let PayloadConfig { parent_header, attributes, payload_id } = config;

let state_provider = client.state_by_block_hash(parent_header.hash())?;
let mut state_provider = client.state_by_block_hash(parent_header.hash())?;
if let Some(execution_cache) = execution_cache {
state_provider = Box::new(CachedStateProvider::new(
state_provider,
execution_cache.cache().clone(),
execution_cache.metrics().clone(),
));
}
let state = StateProviderDatabase::new(state_provider.as_ref());
let mut db =
State::builder().with_database(cached_reads.as_db_mut(state)).with_bundle_update().build();
Expand Down
29 changes: 28 additions & 1 deletion crates/node/core/src/args/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ pub struct DefaultEngineValues {
slow_block_threshold: Option<Duration>,
disable_sparse_trie_cache_pruning: bool,
state_root_task_timeout: Option<String>,
share_execution_cache_with_payload_builder: bool,
}

impl DefaultEngineValues {
Expand Down Expand Up @@ -204,6 +205,12 @@ impl DefaultEngineValues {
self.state_root_task_timeout = v;
self
}

/// Set whether to share the execution cache with the payload builder by default
pub const fn with_share_execution_cache_with_payload_builder(mut self, v: bool) -> Self {
self.share_execution_cache_with_payload_builder = v;
self
}
}

impl Default for DefaultEngineValues {
Expand Down Expand Up @@ -233,6 +240,7 @@ impl Default for DefaultEngineValues {
slow_block_threshold: None,
disable_sparse_trie_cache_pruning: false,
state_root_task_timeout: Some("1s".to_string()),
share_execution_cache_with_payload_builder: false,
}
}
}
Expand Down Expand Up @@ -398,6 +406,19 @@ pub struct EngineArgs {
)]
pub state_root_task_timeout: Option<Duration>,

/// Whether to share execution cache with the payload builder.
///
/// When enabled, each payload job will get an instance of cross-block execution cache from the
/// engine.
///
/// Note: this should only be enabled if node would not be requested to process any payloads in
/// parallel with payload building.
#[arg(
long = "engine.share-execution-cache-with-payload-builder",
default_value_t = DefaultEngineValues::get_global().share_execution_cache_with_payload_builder,
)]
pub share_execution_cache_with_payload_builder: bool,

/// Add random jitter before each proof computation (trie-debug only).
/// Each proof worker sleeps for a random duration up to this value before
/// starting work. Useful for stress-testing timing-sensitive proof logic.
Expand Down Expand Up @@ -440,6 +461,7 @@ impl Default for EngineArgs {
slow_block_threshold,
disable_sparse_trie_cache_pruning,
state_root_task_timeout,
share_execution_cache_with_payload_builder,
} = DefaultEngineValues::get_global().clone();
Self {
persistence_threshold,
Expand Down Expand Up @@ -472,6 +494,7 @@ impl Default for EngineArgs {
state_root_task_timeout: state_root_task_timeout
.as_deref()
.map(|s| humantime::parse_duration(s).expect("valid default duration")),
share_execution_cache_with_payload_builder,
#[cfg(feature = "trie-debug")]
proof_jitter: None,
}
Expand Down Expand Up @@ -503,7 +526,10 @@ impl EngineArgs {
.with_sparse_trie_max_hot_accounts(self.sparse_trie_max_hot_accounts)
.with_slow_block_threshold(self.slow_block_threshold)
.with_disable_sparse_trie_cache_pruning(self.disable_sparse_trie_cache_pruning)
.with_state_root_task_timeout(self.state_root_task_timeout.filter(|d| !d.is_zero()));
.with_state_root_task_timeout(self.state_root_task_timeout.filter(|d| !d.is_zero()))
.with_share_execution_cache_with_payload_builder(
self.share_execution_cache_with_payload_builder,
);
#[cfg(feature = "trie-debug")]
let config = config.with_proof_jitter(self.proof_jitter);
config
Expand Down Expand Up @@ -561,6 +587,7 @@ mod tests {
slow_block_threshold: None,
disable_sparse_trie_cache_pruning: true,
state_root_task_timeout: Some(Duration::from_secs(2)),
share_execution_cache_with_payload_builder: false,
#[cfg(feature = "trie-debug")]
proof_jitter: None,
};
Expand Down
1 change: 1 addition & 0 deletions crates/payload/basic/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ workspace = true

[dependencies]
# reth
reth-execution-cache.workspace = true
reth-primitives-traits.workspace = true
reth-payload-builder.workspace = true
reth-payload-builder-primitives.workspace = true
Expand Down
Loading
Loading