diff --git a/core/node/api_server/src/web3/namespaces/debug.rs b/core/node/api_server/src/web3/namespaces/debug.rs index 400711de8593..17d02661740c 100644 --- a/core/node/api_server/src/web3/namespaces/debug.rs +++ b/core/node/api_server/src/web3/namespaces/debug.rs @@ -63,6 +63,10 @@ impl DebugNamespace { options: Option, ) -> Result, Web3Error> { self.current_method().set_block_id(block_id); + if matches!(block_id, BlockId::Number(BlockNumber::Pending)) { + // See `EthNamespace::get_block_impl()` for an explanation why this check is needed. + return Ok(vec![]); + } let only_top_call = options .map(|options| options.tracer_config.only_top_call) diff --git a/core/node/api_server/src/web3/namespaces/eth.rs b/core/node/api_server/src/web3/namespaces/eth.rs index b1541f7261bf..e2224ce92cd2 100644 --- a/core/node/api_server/src/web3/namespaces/eth.rs +++ b/core/node/api_server/src/web3/namespaces/eth.rs @@ -223,8 +223,15 @@ impl EthNamespace { full_transactions: bool, ) -> Result>, Web3Error> { self.current_method().set_block_id(block_id); - let mut storage = self.state.acquire_connection().await?; + if matches!(block_id, BlockId::Number(BlockNumber::Pending)) { + // Shortcut here on a somewhat unlikely case of the client requesting a pending block. + // Otherwise, since we don't read DB data in a transaction, + // we might resolve a block number to a block that will be inserted to the DB immediately after, + // and return `Ok(Some(_))`. + return Ok(None); + } + let mut storage = self.state.acquire_connection().await?; self.state .start_info .ensure_not_pruned(block_id, &mut storage) @@ -288,8 +295,12 @@ impl EthNamespace { block_id: BlockId, ) -> Result, Web3Error> { self.current_method().set_block_id(block_id); - let mut storage = self.state.acquire_connection().await?; + if matches!(block_id, BlockId::Number(BlockNumber::Pending)) { + // See `get_block_impl()` for an explanation why this check is needed. + return Ok(None); + } + let mut storage = self.state.acquire_connection().await?; self.state .start_info .ensure_not_pruned(block_id, &mut storage) @@ -319,8 +330,12 @@ impl EthNamespace { block_id: BlockId, ) -> Result>, Web3Error> { self.current_method().set_block_id(block_id); - let mut storage = self.state.acquire_connection().await?; + if matches!(block_id, BlockId::Number(BlockNumber::Pending)) { + // See `get_block_impl()` for an explanation why this check is needed. + return Ok(None); + } + let mut storage = self.state.acquire_connection().await?; self.state .start_info .ensure_not_pruned(block_id, &mut storage) @@ -457,6 +472,11 @@ impl EthNamespace { .map_err(DalError::generalize)?, TransactionId::Block(block_id, idx) => { + if matches!(block_id, BlockId::Number(BlockNumber::Pending)) { + // See `get_block_impl()` for an explanation why this check is needed. + return Ok(None); + } + let Ok(idx) = u32::try_from(idx) else { return Ok(None); // index overflow means no transaction };