Skip to content

Commit a11e17f

Browse files
prestwichclaude
andcommitted
feat(rpc): wire Parity trace namespace into router
Creates trace/mod.rs with the router constructor and wires it into the combined router. Fixes HashSet type mismatch (std to alloy) and removes erroneous accept_state() call on already-needs-tx state. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent ee4b288 commit a11e17f

4 files changed

Lines changed: 61 additions & 50 deletions

File tree

crates/rpc/src/lib.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ pub use interest::{ChainEvent, NewBlockNotification, RemovedBlock, ReorgNotifica
2525
mod debug;
2626
pub use debug::DebugError;
2727

28+
mod trace;
29+
pub use trace::TraceError;
30+
2831
mod signet;
2932
pub use signet::error::SignetError;
3033

@@ -34,8 +37,8 @@ mod web3;
3437
pub mod serve;
3538
pub use serve::{RpcServerGuard, ServeConfig, ServeConfigEnv, ServeError};
3639

37-
/// Instantiate a combined router with `eth`, `debug`, `signet`, `web3`, and
38-
/// `net` namespaces.
40+
/// Instantiate a combined router with `eth`, `debug`, `trace`, `signet`,
41+
/// `web3`, and `net` namespaces.
3942
pub fn router<H>() -> ajj::Router<StorageRpcCtx<H>>
4043
where
4144
H: signet_hot::HotKv + Send + Sync + 'static,
@@ -44,6 +47,7 @@ where
4447
ajj::Router::new()
4548
.nest("eth", eth::eth())
4649
.nest("debug", debug::debug())
50+
.nest("trace", trace::trace())
4751
.nest("signet", signet::signet())
4852
.nest("web3", web3::web3())
4953
.nest("net", net::net())

crates/rpc/src/trace/endpoints.rs

Lines changed: 12 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use ajj::HandlerCtx;
1616
use alloy::{
1717
consensus::BlockHeader,
1818
eips::BlockId,
19-
primitives::{B256, Bytes, map::HashSet},
19+
primitives::{B256, map::HashSet},
2020
rpc::types::trace::parity::{
2121
LocalizedTransactionTrace, TraceResults, TraceResultsWithTransactionHash, TraceType,
2222
},
@@ -286,9 +286,8 @@ where
286286
TraceError::Resolve(e)
287287
})?;
288288

289-
let sealed = ctx
290-
.resolve_header(BlockId::Number(block_num.into()))
291-
.map_err(|e| TraceError::Resolve(e))?;
289+
let sealed =
290+
ctx.resolve_header(BlockId::Number(block_num.into())).map_err(TraceError::Resolve)?;
292291

293292
let Some(sealed) = sealed else {
294293
return Ok(None);
@@ -349,7 +348,7 @@ where
349348
let block_num = meta.block_number();
350349

351350
let block_id = BlockId::Number(block_num.into());
352-
let sealed = ctx.resolve_header(block_id).map_err(|e| TraceError::Resolve(e))?;
351+
let sealed = ctx.resolve_header(block_id).map_err(TraceError::Resolve)?;
353352
let header = sealed.ok_or(TraceError::BlockNotFound(block_id))?.into_inner();
354353

355354
let txs = cold.get_transactions_in_block(block_num).await.map_err(TraceError::from)?;
@@ -467,12 +466,11 @@ where
467466

468467
for (request, trace_types) in calls {
469468
let filled = trevm.fill_tx(&request);
470-
let (trace_res, next) =
471-
crate::debug::tracer::trace_parity_replay(filled, &trace_types)
472-
.map_err(|e| TraceError::EvmHalt { reason: e.to_string() })?;
469+
let (trace_res, next) = crate::debug::tracer::trace_parity_replay(filled, &trace_types)
470+
.map_err(|e| TraceError::EvmHalt { reason: e.to_string() })?;
473471

474472
results.push(trace_res);
475-
trevm = next.accept_state();
473+
trevm = next;
476474
}
477475

478476
Ok(results)
@@ -506,8 +504,7 @@ where
506504
let tx: signet_storage_types::TransactionSigned =
507505
alloy::rlp::Decodable::decode(&mut rlp_bytes.as_ref())
508506
.map_err(|e| TraceError::RlpDecode(e.to_string()))?;
509-
let recovered =
510-
tx.try_into_recovered().map_err(|_| TraceError::SenderRecovery)?;
507+
let recovered = tx.try_into_recovered().map_err(|_| TraceError::SenderRecovery)?;
511508

512509
let EvmBlockContext { header, db, spec_id } =
513510
ctx.resolve_evm_block(id).map_err(|e| match e {
@@ -517,10 +514,8 @@ where
517514

518515
let mut evm = signet_evm::signet_evm(db, ctx.constants().clone());
519516
evm.set_spec_id(spec_id);
520-
let trevm = evm
521-
.fill_cfg(&CfgFiller(ctx.chain_id()))
522-
.fill_block(&header)
523-
.fill_tx(&recovered);
517+
let trevm =
518+
evm.fill_cfg(&CfgFiller(ctx.chain_id())).fill_block(&header).fill_tx(&recovered);
524519

525520
let (results, _) = crate::debug::tracer::trace_parity_replay(trevm, &trace_types)
526521
.map_err(|e| TraceError::EvmHalt { reason: e.to_string() })?;
@@ -600,9 +595,7 @@ where
600595
let cold = ctx.cold();
601596
let block_id = BlockId::Number(block_num.into());
602597

603-
let sealed = ctx
604-
.resolve_header(block_id)
605-
.map_err(TraceError::Resolve)?;
598+
let sealed = ctx.resolve_header(block_id).map_err(TraceError::Resolve)?;
606599

607600
let Some(sealed) = sealed else {
608601
continue;
@@ -611,10 +604,7 @@ where
611604
let block_hash = sealed.hash();
612605
let header = sealed.into_inner();
613606

614-
let txs = cold
615-
.get_transactions_in_block(block_num)
616-
.await
617-
.map_err(TraceError::from)?;
607+
let txs = cold.get_transactions_in_block(block_num).await.map_err(TraceError::from)?;
618608

619609
let db = ctx
620610
.revm_state_at_height(header.number.saturating_sub(1))

crates/rpc/src/trace/mod.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
//! Parity `trace` namespace RPC router backed by storage.
2+
3+
mod endpoints;
4+
use endpoints::{
5+
replay_block_transactions, replay_transaction, trace_block, trace_call, trace_call_many,
6+
trace_filter, trace_get, trace_raw_transaction, trace_transaction,
7+
};
8+
mod error;
9+
pub use error::TraceError;
10+
mod types;
11+
12+
use crate::config::StorageRpcCtx;
13+
use signet_hot::{HotKv, model::HotKvRead};
14+
use trevm::revm::database::DBErrorMarker;
15+
16+
/// Instantiate a `trace` API router backed by storage.
17+
pub(crate) fn trace<H>() -> ajj::Router<StorageRpcCtx<H>>
18+
where
19+
H: HotKv + Send + Sync + 'static,
20+
<H::RoTx as HotKvRead>::Error: DBErrorMarker,
21+
{
22+
ajj::Router::new()
23+
.route("block", trace_block::<H>)
24+
.route("transaction", trace_transaction::<H>)
25+
.route("replayBlockTransactions", replay_block_transactions::<H>)
26+
.route("replayTransaction", replay_transaction::<H>)
27+
.route("call", trace_call::<H>)
28+
.route("callMany", trace_call_many::<H>)
29+
.route("rawTransaction", trace_raw_transaction::<H>)
30+
.route("get", trace_get::<H>)
31+
.route("filter", trace_filter::<H>)
32+
}

crates/rpc/src/trace/types.rs

Lines changed: 11 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,13 @@
22
33
use alloy::{
44
eips::BlockId,
5-
primitives::{Bytes, B256},
5+
primitives::{B256, Bytes, map::HashSet},
66
rpc::types::{
7-
state::StateOverride, BlockNumberOrTag, BlockOverrides,
8-
TransactionRequest,
7+
BlockNumberOrTag, BlockOverrides, TransactionRequest,
8+
state::StateOverride,
99
trace::{filter::TraceFilter, parity::TraceType},
1010
},
1111
};
12-
use std::collections::HashSet;
1312

1413
/// Params for `trace_block`.
1514
#[derive(Debug, serde::Deserialize)]
@@ -21,54 +20,40 @@ pub(crate) struct TraceTransactionParams(pub(crate) B256);
2120

2221
/// Params for `trace_replayBlockTransactions`.
2322
#[derive(Debug, serde::Deserialize)]
24-
pub(crate) struct ReplayBlockParams(
25-
pub(crate) BlockNumberOrTag,
26-
pub(crate) HashSet<TraceType>,
27-
);
23+
pub(crate) struct ReplayBlockParams(pub(crate) BlockNumberOrTag, pub(crate) HashSet<TraceType>);
2824

2925
/// Params for `trace_replayTransaction`.
3026
#[derive(Debug, serde::Deserialize)]
31-
pub(crate) struct ReplayTransactionParams(
32-
pub(crate) B256,
33-
pub(crate) HashSet<TraceType>,
34-
);
27+
pub(crate) struct ReplayTransactionParams(pub(crate) B256, pub(crate) HashSet<TraceType>);
3528

3629
/// Params for `trace_call`.
3730
#[derive(Debug, serde::Deserialize)]
3831
pub(crate) struct TraceCallParams(
3932
pub(crate) TransactionRequest,
4033
pub(crate) HashSet<TraceType>,
41-
#[serde(default)]
42-
pub(crate) Option<BlockId>,
43-
#[serde(default)]
44-
pub(crate) Option<StateOverride>,
45-
#[serde(default)]
46-
pub(crate) Option<Box<BlockOverrides>>,
34+
#[serde(default)] pub(crate) Option<BlockId>,
35+
#[serde(default)] pub(crate) Option<StateOverride>,
36+
#[serde(default)] pub(crate) Option<Box<BlockOverrides>>,
4737
);
4838

4939
/// Params for `trace_callMany`.
5040
#[derive(Debug, serde::Deserialize)]
5141
pub(crate) struct TraceCallManyParams(
5242
pub(crate) Vec<(TransactionRequest, HashSet<TraceType>)>,
53-
#[serde(default)]
54-
pub(crate) Option<BlockId>,
43+
#[serde(default)] pub(crate) Option<BlockId>,
5544
);
5645

5746
/// Params for `trace_rawTransaction`.
5847
#[derive(Debug, serde::Deserialize)]
5948
pub(crate) struct TraceRawTransactionParams(
6049
pub(crate) Bytes,
6150
pub(crate) HashSet<TraceType>,
62-
#[serde(default)]
63-
pub(crate) Option<BlockId>,
51+
#[serde(default)] pub(crate) Option<BlockId>,
6452
);
6553

6654
/// Params for `trace_get`.
6755
#[derive(Debug, serde::Deserialize)]
68-
pub(crate) struct TraceGetParams(
69-
pub(crate) B256,
70-
pub(crate) Vec<usize>,
71-
);
56+
pub(crate) struct TraceGetParams(pub(crate) B256, pub(crate) Vec<usize>);
7257

7358
/// Params for `trace_filter`.
7459
#[derive(Debug, serde::Deserialize)]

0 commit comments

Comments
 (0)