Added Flag to Bypass New Payload Cache

This commit is contained in:
Mark Mackey
2025-11-24 12:24:43 -06:00
parent ef1aa6bd96
commit 77e1c67723
6 changed files with 24 additions and 21 deletions

View File

@@ -469,6 +469,7 @@ where
execution_endpoint: url, execution_endpoint: url,
secret_file: None, secret_file: None,
suggested_fee_recipient: Some(Address::repeat_byte(42)), suggested_fee_recipient: Some(Address::repeat_byte(42)),
bypass_new_payload_cache: true,
..Default::default() ..Default::default()
}; };
let execution_layer = let execution_layer =

View File

@@ -279,8 +279,6 @@ impl InvalidPayloadRig {
} else { } else {
mock_execution_layer.server.full_payload_verification(); mock_execution_layer.server.full_payload_verification();
} }
// wait for the new payload cache to timeout
tokio::time::sleep(std::time::Duration::from_secs(12)).await;
let root = self let root = self
.harness .harness
.process_block(slot, block.canonical_root(), (block.clone(), blobs.clone())) .process_block(slot, block.canonical_root(), (block.clone(), blobs.clone()))

View File

@@ -551,7 +551,7 @@ struct Inner<E: EthSpec> {
/// Cache for deduplicating `notify_new_payload` requests. /// Cache for deduplicating `notify_new_payload` requests.
/// ///
/// Handles both in-flight requests and recently completed requests. /// Handles both in-flight requests and recently completed requests.
new_payload_cache: NewPayloadCache, new_payload_cache: Option<NewPayloadCache>,
} }
#[derive(Debug, Default, Clone, Serialize, Deserialize)] #[derive(Debug, Default, Clone, Serialize, Deserialize)]
@@ -579,6 +579,8 @@ pub struct Config {
/// Default directory for the jwt secret if not provided through cli. /// Default directory for the jwt secret if not provided through cli.
pub default_datadir: PathBuf, pub default_datadir: PathBuf,
pub execution_timeout_multiplier: Option<u32>, pub execution_timeout_multiplier: Option<u32>,
/// Whether to bypass the new payload cache (useful for testing).
pub bypass_new_payload_cache: bool,
} }
/// Provides access to one execution engine and provides a neat interface for consumption by the /// Provides access to one execution engine and provides a neat interface for consumption by the
@@ -603,6 +605,7 @@ impl<E: EthSpec> ExecutionLayer<E> {
jwt_version, jwt_version,
default_datadir, default_datadir,
execution_timeout_multiplier, execution_timeout_multiplier,
bypass_new_payload_cache,
} = config; } = config;
let execution_url = url.ok_or(Error::NoEngine)?; let execution_url = url.ok_or(Error::NoEngine)?;
@@ -647,6 +650,12 @@ impl<E: EthSpec> ExecutionLayer<E> {
Engine::new(api, executor.clone()) Engine::new(api, executor.clone())
}; };
let new_payload_cache = if !bypass_new_payload_cache {
Some(NewPayloadCache::new())
} else {
None
};
let inner = Inner { let inner = Inner {
engine: Arc::new(engine), engine: Arc::new(engine),
builder: ArcSwapOption::empty(), builder: ArcSwapOption::empty(),
@@ -658,7 +667,7 @@ impl<E: EthSpec> ExecutionLayer<E> {
executor, executor,
payload_cache: PayloadCache::default(), payload_cache: PayloadCache::default(),
last_new_payload_errored: RwLock::new(false), last_new_payload_errored: RwLock::new(false),
new_payload_cache: NewPayloadCache::new(), new_payload_cache,
}; };
let el = Self { let el = Self {
@@ -1485,12 +1494,15 @@ impl<E: EthSpec> ExecutionLayer<E> {
) -> Result<PayloadStatus, Error> { ) -> Result<PayloadStatus, Error> {
let block_hash = new_payload_request.block_hash(); let block_hash = new_payload_request.block_hash();
self.inner if let Some(new_payload_cache) = &self.inner.new_payload_cache {
.new_payload_cache new_payload_cache
.get_or_execute(block_hash, || { .get_or_execute(block_hash, || {
self.notify_new_payload_impl(new_payload_request) self.notify_new_payload_impl(new_payload_request)
}) })
.await .await
} else {
self.notify_new_payload_impl(new_payload_request).await
}
} }
/// Internal implementation of notify_new_payload without deduplication logic. /// Internal implementation of notify_new_payload without deduplication logic.

View File

@@ -76,6 +76,7 @@ impl<E: EthSpec> MockExecutionLayer<E> {
execution_endpoint: Some(url), execution_endpoint: Some(url),
secret_file: Some(path), secret_file: Some(path),
suggested_fee_recipient: Some(Address::repeat_byte(42)), suggested_fee_recipient: Some(Address::repeat_byte(42)),
bypass_new_payload_cache: true,
..Default::default() ..Default::default()
}; };
let el = ExecutionLayer::from_config(config, executor.clone()).unwrap(); let el = ExecutionLayer::from_config(config, executor.clone()).unwrap();

View File

@@ -134,9 +134,6 @@ async fn el_error_on_new_payload() {
assert!(!api_response.is_optimistic); assert!(!api_response.is_optimistic);
assert!(!api_response.is_syncing); assert!(!api_response.is_syncing);
// sleep for just past the cache TTL
tokio::time::sleep(std::time::Duration::from_secs(12)).await;
// Processing a block successfully should remove the status. // Processing a block successfully should remove the status.
mock_el.server.set_new_payload_status( mock_el.server.set_new_payload_status(
block_hash, block_hash,

View File

@@ -136,6 +136,7 @@ impl<Engine: GenericExecutionEngine> TestRig<Engine> {
secret_file: None, secret_file: None,
suggested_fee_recipient: Some(Address::repeat_byte(42)), suggested_fee_recipient: Some(Address::repeat_byte(42)),
default_datadir: execution_engine.datadir(), default_datadir: execution_engine.datadir(),
bypass_new_payload_cache: true,
..Default::default() ..Default::default()
}; };
let execution_layer = ExecutionLayer::from_config(config, executor.clone()).unwrap(); let execution_layer = ExecutionLayer::from_config(config, executor.clone()).unwrap();
@@ -154,6 +155,7 @@ impl<Engine: GenericExecutionEngine> TestRig<Engine> {
secret_file: None, secret_file: None,
suggested_fee_recipient: fee_recipient, suggested_fee_recipient: fee_recipient,
default_datadir: execution_engine.datadir(), default_datadir: execution_engine.datadir(),
bypass_new_payload_cache: true,
..Default::default() ..Default::default()
}; };
let execution_layer = ExecutionLayer::from_config(config, executor).unwrap(); let execution_layer = ExecutionLayer::from_config(config, executor).unwrap();
@@ -463,14 +465,6 @@ impl<Engine: GenericExecutionEngine> TestRig<Engine> {
// TODO: again think about forks here // TODO: again think about forks here
let mut invalid_payload = valid_payload.clone(); let mut invalid_payload = valid_payload.clone();
// reverse the block hash to bypass the new payload cache
let reversed: [u8; 32] = {
let mut arr = [0; 32];
arr.copy_from_slice(invalid_payload.block_hash().0.as_slice());
arr.reverse();
arr
};
*invalid_payload.block_hash_mut().0 = reversed;
*invalid_payload.prev_randao_mut() = Hash256::from_low_u64_be(42); *invalid_payload.prev_randao_mut() = Hash256::from_low_u64_be(42);
let status = self let status = self
.ee_a .ee_a