From 99f00eb8c2a475aeb67cdee33263060ad9596c19 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Thu, 13 Jul 2023 20:22:01 +0200 Subject: [PATCH] fix: return null withdrawals (#3762) --- crates/rpc/rpc-api/src/engine.rs | 6 +++--- crates/rpc/rpc-engine-api/src/engine_api.rs | 14 +++++++------ .../rpc/rpc-types/src/eth/engine/payload.rs | 20 +++++++++++-------- 3 files changed, 23 insertions(+), 17 deletions(-) diff --git a/crates/rpc/rpc-api/src/engine.rs b/crates/rpc/rpc-api/src/engine.rs index be4825a5b6..756cb5473c 100644 --- a/crates/rpc/rpc-api/src/engine.rs +++ b/crates/rpc/rpc-api/src/engine.rs @@ -2,7 +2,7 @@ use jsonrpsee::{core::RpcResult, proc_macros::rpc}; use reth_primitives::{Address, BlockHash, BlockId, BlockNumberOrTag, Bytes, H256, U256, U64}; use reth_rpc_types::{ engine::{ - ExecutionPayload, ExecutionPayloadBodies, ExecutionPayloadEnvelope, ForkchoiceState, + ExecutionPayload, ExecutionPayloadBodiesV1, ExecutionPayloadEnvelope, ForkchoiceState, ForkchoiceUpdated, PayloadAttributes, PayloadId, PayloadStatus, TransitionConfiguration, }, state::StateOverride, @@ -64,7 +64,7 @@ pub trait EngineApi { async fn get_payload_bodies_by_hash_v1( &self, block_hashes: Vec, - ) -> RpcResult; + ) -> RpcResult; /// See also /// @@ -83,7 +83,7 @@ pub trait EngineApi { &self, start: U64, count: U64, - ) -> RpcResult; + ) -> RpcResult; /// See also #[method(name = "exchangeTransitionConfigurationV1")] diff --git a/crates/rpc/rpc-engine-api/src/engine_api.rs b/crates/rpc/rpc-engine-api/src/engine_api.rs index f461f4928d..2a0581595f 100644 --- a/crates/rpc/rpc-engine-api/src/engine_api.rs +++ b/crates/rpc/rpc-engine-api/src/engine_api.rs @@ -8,7 +8,7 @@ use reth_primitives::{BlockHash, BlockHashOrNumber, BlockNumber, ChainSpec, Hard use reth_provider::{BlockReader, EvmEnvProvider, HeaderProvider, StateProviderFactory}; use reth_rpc_api::EngineApiServer; use reth_rpc_types::engine::{ - ExecutionPayload, ExecutionPayloadBodies, ExecutionPayloadEnvelope, ForkchoiceUpdated, + ExecutionPayload, ExecutionPayloadBodiesV1, ExecutionPayloadEnvelope, ForkchoiceUpdated, PayloadAttributes, PayloadId, PayloadStatus, TransitionConfiguration, CAPABILITIES, }; use reth_tasks::TaskSpawner; @@ -183,7 +183,7 @@ where &self, start: BlockNumber, count: u64, - ) -> EngineApiResult { + ) -> EngineApiResult { let (tx, rx) = oneshot::channel(); let inner = self.inner.clone(); @@ -223,7 +223,7 @@ where pub fn get_payload_bodies_by_hash( &self, hashes: Vec, - ) -> EngineApiResult { + ) -> EngineApiResult { let len = hashes.len() as u64; if len > MAX_PAYLOAD_BODIES_LIMIT { return Err(EngineApiError::PayloadRequestTooLarge { len }) @@ -414,7 +414,7 @@ where async fn get_payload_bodies_by_hash_v1( &self, block_hashes: Vec, - ) -> RpcResult { + ) -> RpcResult { trace!(target: "rpc::engine", "Serving engine_getPayloadBodiesByHashV1"); Ok(EngineApi::get_payload_bodies_by_hash(self, block_hashes)?) } @@ -432,11 +432,13 @@ where /// Implementors should take care when acting on the input to this method, specifically /// ensuring that the range is limited properly, and that the range boundaries are computed /// correctly and without panics. + /// + /// Note: If a block is pre shanghai, `withdrawals` field will be `null async fn get_payload_bodies_by_range_v1( &self, start: U64, count: U64, - ) -> RpcResult { + ) -> RpcResult { trace!(target: "rpc::engine", "Serving engine_getPayloadBodiesByRangeV1"); Ok(EngineApi::get_payload_bodies_by_range(self, start.as_u64(), count.as_u64()).await?) } @@ -482,7 +484,7 @@ mod tests { let provider = Arc::new(MockEthProvider::default()); let payload_store = spawn_test_payload_service(); let (to_engine, engine_rx) = unbounded_channel(); - let task_executor = Box::new(TokioTaskExecutor::default()); + let task_executor = Box::::default(); let api = EngineApi::new( provider.clone(), chain_spec.clone(), diff --git a/crates/rpc/rpc-types/src/eth/engine/payload.rs b/crates/rpc/rpc-types/src/eth/engine/payload.rs index 5b4da25aab..5b63e1b8cc 100644 --- a/crates/rpc/rpc-types/src/eth/engine/payload.rs +++ b/crates/rpc/rpc-types/src/eth/engine/payload.rs @@ -8,7 +8,7 @@ use reth_rlp::Decodable; use serde::{ser::SerializeMap, Deserialize, Serialize, Serializer}; /// The execution payload body response that allows for `null` values. -pub type ExecutionPayloadBodies = Vec>; +pub type ExecutionPayloadBodiesV1 = Vec>; /// And 8-byte identifier for an execution payload. #[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize, Hash)] @@ -220,21 +220,25 @@ impl PayloadError { /// /// See also: #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] -pub struct ExecutionPayloadBody { +pub struct ExecutionPayloadBodyV1 { + /// Enveloped encoded transactions. pub transactions: Vec, - pub withdrawals: Vec, + /// All withdrawals in the block. + /// + /// Will always be `None` if pre shanghai. + pub withdrawals: Option>, } -impl From for ExecutionPayloadBody { +impl From for ExecutionPayloadBodyV1 { fn from(value: Block) -> Self { let transactions = value.body.into_iter().map(|tx| { let mut out = Vec::new(); tx.encode_enveloped(&mut out); out.into() }); - ExecutionPayloadBody { + ExecutionPayloadBodyV1 { transactions: transactions.collect(), - withdrawals: value.withdrawals.unwrap_or_default(), + withdrawals: value.withdrawals, } } } @@ -456,7 +460,7 @@ mod tests { let mut rng = generators::rng(); for block in random_block_range(&mut rng, 0..=99, H256::default(), 0..2) { let unsealed = block.clone().unseal(); - let payload_body: ExecutionPayloadBody = unsealed.into(); + let payload_body: ExecutionPayloadBodyV1 = unsealed.into(); assert_eq!( Ok(block.body), @@ -467,7 +471,7 @@ mod tests { .collect::, _>>(), ); - assert_eq!(block.withdrawals.unwrap_or_default(), payload_body.withdrawals); + assert_eq!(block.withdrawals, payload_body.withdrawals); } }