Skip to content

Commit 0739d77

Browse files
authored
feat: add support for passthrough of debug_codeByHash (#11053)
* feat: add support for passthrough of `debug_codeByHash` * add test for eth api debug_code_by_hash * shorter
1 parent 3d961b8 commit 0739d77

File tree

5 files changed

+54
-1
lines changed

5 files changed

+54
-1
lines changed

crates/anvil/core/src/eth/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,10 @@ pub enum EthRequest {
280280
#[serde(default)] GethDebugTracingCallOptions,
281281
),
282282

283+
/// reth's `debug_codeByHash` endpoint
284+
#[serde(rename = "debug_codeByHash")]
285+
DebugCodeByHash(B256, #[serde(default)] Option<BlockId>),
286+
283287
/// Trace transaction endpoint for parity's `trace_transaction`
284288
#[serde(rename = "trace_transaction", with = "sequence")]
285289
TraceTransaction(B256),

crates/anvil/src/eth/api.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,9 @@ impl EthApi {
330330
EthRequest::DebugTraceCall(tx, block, opts) => {
331331
self.debug_trace_call(tx, block, opts).await.to_rpc_result()
332332
}
333+
EthRequest::DebugCodeByHash(hash, block) => {
334+
self.debug_code_by_hash(hash, block).await.to_rpc_result()
335+
}
333336
EthRequest::TraceTransaction(tx) => self.trace_transaction(tx).await.to_rpc_result(),
334337
EthRequest::TraceBlock(block) => self.trace_block(block).await.to_rpc_result(),
335338
EthRequest::TraceFilter(filter) => self.trace_filter(filter).await.to_rpc_result(),
@@ -1747,6 +1750,18 @@ impl EthApi {
17471750
result
17481751
}
17491752

1753+
/// Returns code by its hash
1754+
///
1755+
/// Handler for RPC call: `debug_codeByHash`
1756+
pub async fn debug_code_by_hash(
1757+
&self,
1758+
hash: B256,
1759+
block_id: Option<BlockId>,
1760+
) -> Result<Option<Bytes>> {
1761+
node_info!("debug_codeByHash");
1762+
self.backend.debug_code_by_hash(hash, block_id).await
1763+
}
1764+
17501765
/// Returns traces for the transaction hash via parity's tracing endpoint
17511766
///
17521767
/// Handler for RPC call: `trace_transaction`

crates/anvil/src/eth/backend/fork.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,14 @@ impl ClientFork {
397397
Ok(trace)
398398
}
399399

400+
pub async fn debug_code_by_hash(
401+
&self,
402+
code_hash: B256,
403+
block_id: Option<BlockId>,
404+
) -> Result<Option<Bytes>, TransportError> {
405+
self.provider().debug_code_by_hash(code_hash, block_id).await
406+
}
407+
400408
pub async fn trace_block(&self, number: u64) -> Result<Vec<Trace>, TransportError> {
401409
if let Some(traces) = self.storage_read().block_traces.get(&number).cloned() {
402410
return Ok(traces);

crates/anvil/src/eth/backend/mem/mod.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2594,6 +2594,19 @@ impl Backend {
25942594
Ok(GethTrace::Default(Default::default()))
25952595
}
25962596

2597+
/// Returns code by its hash
2598+
pub async fn debug_code_by_hash(
2599+
&self,
2600+
code_hash: B256,
2601+
block_id: Option<BlockId>,
2602+
) -> Result<Option<Bytes>, BlockchainError> {
2603+
if let Some(fork) = self.get_fork() {
2604+
return Ok(fork.debug_code_by_hash(code_hash, block_id).await?);
2605+
}
2606+
2607+
Ok(None)
2608+
}
2609+
25972610
fn mined_geth_trace_transaction(
25982611
&self,
25992612
hash: B256,

crates/anvil/tests/it/api.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use crate::{
77
use alloy_consensus::{SignableTransaction, Transaction, TxEip1559};
88
use alloy_network::{EthereumWallet, TransactionBuilder, TxSignerSync};
99
use alloy_primitives::{
10-
Address, B256, ChainId, U256, bytes,
10+
Address, B256, ChainId, U256, b256, bytes,
1111
map::{AddressHashMap, B256HashMap, HashMap},
1212
};
1313
use alloy_provider::Provider;
@@ -17,6 +17,7 @@ use alloy_rpc_types::{
1717
};
1818
use alloy_serde::WithOtherFields;
1919
use anvil::{CHAIN_ID, EthereumHardfork, NodeConfig, eth::api::CLIENT_VERSION, spawn};
20+
use foundry_test_utils::rpc;
2021
use futures::join;
2122
use std::time::Duration;
2223

@@ -453,3 +454,15 @@ async fn can_send_tx_sync() {
453454
let receipt = api.send_transaction_sync(WithOtherFields::new(tx)).await.unwrap();
454455
assert_eq!(receipt.from, wallets[0].address());
455456
}
457+
458+
#[tokio::test(flavor = "multi_thread")]
459+
async fn can_get_code_by_hash() {
460+
let (api, _) =
461+
spawn(NodeConfig::test().with_eth_rpc_url(Some(rpc::next_http_archive_rpc_url()))).await;
462+
463+
// The code hash for DEFAULT_CREATE2_DEPLOYER_RUNTIME_CODE
464+
let code_hash = b256!("2fa86add0aed31f33a762c9d88e807c475bd51d0f52bd0955754b2608f7e4989");
465+
466+
let code = api.debug_code_by_hash(code_hash, None).await.unwrap();
467+
assert_eq!(&code.unwrap(), foundry_evm::constants::DEFAULT_CREATE2_DEPLOYER_RUNTIME_CODE);
468+
}

0 commit comments

Comments
 (0)