diff --git a/crates/optimism/node/src/node.rs b/crates/optimism/node/src/node.rs index c75521352335..bd045320f527 100644 --- a/crates/optimism/node/src/node.rs +++ b/crates/optimism/node/src/node.rs @@ -253,8 +253,11 @@ where ) -> eyre::Result { let Self { rpc_add_ons, da_config } = self; // install additional OP specific rpc methods - let debug_ext = - OpDebugWitnessApi::new(ctx.node.provider().clone(), ctx.node.evm_config().clone()); + let debug_ext = OpDebugWitnessApi::new( + ctx.node.provider().clone(), + ctx.node.evm_config().clone(), + Box::new(ctx.node.task_executor().clone()), + ); let miner_ext = OpMinerExtApi::new(da_config); rpc_add_ons diff --git a/crates/optimism/rpc/src/witness.rs b/crates/optimism/rpc/src/witness.rs index 8cc4bd98ef25..d533bb187d94 100644 --- a/crates/optimism/rpc/src/witness.rs +++ b/crates/optimism/rpc/src/witness.rs @@ -3,7 +3,7 @@ use alloy_consensus::Header; use alloy_primitives::B256; use alloy_rpc_types_debug::ExecutionWitness; -use jsonrpsee_core::RpcResult; +use jsonrpsee_core::{async_trait, RpcResult}; use op_alloy_rpc_types_engine::OpPayloadAttributes; use reth_chainspec::ChainSpecProvider; use reth_evm::ConfigureEvm; @@ -13,7 +13,9 @@ use reth_primitives::{SealedHeader, TransactionSigned}; use reth_provider::{BlockReaderIdExt, ProviderError, ProviderResult, StateProviderFactory}; pub use reth_rpc_api::DebugExecutionWitnessApiServer; use reth_rpc_server_types::{result::internal_rpc_err, ToRpcResult}; +use reth_tasks::TaskSpawner; use std::{fmt::Debug, sync::Arc}; +use tokio::sync::{oneshot, Semaphore}; /// An extension to the `debug_` namespace of the RPC API. pub struct OpDebugWitnessApi { @@ -22,9 +24,14 @@ pub struct OpDebugWitnessApi { impl OpDebugWitnessApi { /// Creates a new instance of the `OpDebugWitnessApi`. - pub fn new(provider: Provider, evm_config: EvmConfig) -> Self { + pub fn new( + provider: Provider, + evm_config: EvmConfig, + task_spawner: Box, + ) -> Self { let builder = OpPayloadBuilder::new(evm_config); - let inner = OpDebugWitnessApiInner { provider, builder }; + let semaphore = Arc::new(Semaphore::new(3)); + let inner = OpDebugWitnessApiInner { provider, builder, task_spawner, semaphore }; Self { inner: Arc::new(inner) } } } @@ -42,24 +49,36 @@ where } } +#[async_trait] impl DebugExecutionWitnessApiServer for OpDebugWitnessApi where Provider: BlockReaderIdExt
+ StateProviderFactory + ChainSpecProvider + + Clone + 'static, EvmConfig: ConfigureEvm
+ 'static, { - fn execute_payload( + async fn execute_payload( &self, parent_block_hash: B256, attributes: OpPayloadAttributes, ) -> RpcResult { + let _permit = self.inner.semaphore.acquire().await; + let parent_header = self.parent_header(parent_block_hash).to_rpc_result()?; - self.inner - .builder - .payload_witness(&self.inner.provider, parent_header, attributes) + + let (tx, rx) = oneshot::channel(); + let this = self.clone(); + self.inner.task_spawner.spawn_blocking(Box::pin(async move { + let res = + this.inner.builder.payload_witness(&this.inner.provider, parent_header, attributes); + let _ = tx.send(res); + })); + + rx.await + .map_err(|err| internal_rpc_err(err.to_string()))? .map_err(|err| internal_rpc_err(err.to_string())) } } @@ -78,4 +97,6 @@ impl Debug for OpDebugWitnessApi { struct OpDebugWitnessApiInner { provider: Provider, builder: OpPayloadBuilder, + task_spawner: Box, + semaphore: Arc, } diff --git a/crates/rpc/rpc-api/src/debug.rs b/crates/rpc/rpc-api/src/debug.rs index 28ed9af5c134..c2d1c605ff14 100644 --- a/crates/rpc/rpc-api/src/debug.rs +++ b/crates/rpc/rpc-api/src/debug.rs @@ -401,8 +401,8 @@ pub trait DebugExecutionWitnessApi { /// /// The first argument is the parent block hash. The second argument is the payload /// attributes for the new block. - #[method(name = "executePayload", blocking)] - fn execute_payload( + #[method(name = "executePayload")] + async fn execute_payload( &self, parent_block_hash: B256, attributes: Attributes,