-
Notifications
You must be signed in to change notification settings - Fork 1
feat(rpc): add debug/trace API and eth_getProof (RPC-4, RPC-5) #115
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
When consensus decides on a new height, The Since This was established as a pattern in commit 5e68970 which added the cipherbft/crates/node/src/node.rs Lines 862 to 868 in b41fb79
|
|
Fixed in c6ac6b8:
Thanks for catching this! 👍 |
8ee42e3 to
9aac2b9
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR aims to add debug namespace RPC methods for transaction tracing and the eth_getProof method for EIP-1186 Merkle proof generation to CipherBFT. The changes include new trait definitions (DebugExecutionApi, RpcProofStorage), real EVM inspector implementations (CallTracer, OpcodeTracer), and Merkle proof generation infrastructure.
Changes:
- Added debug_* RPC namespace with four methods (traceTransaction, traceCall, traceBlockByNumber, traceBlockByHash)
- Added EIP-1186 proof generation infrastructure in execution crate
- Integrated BlockStore and ReceiptStore for historical transaction replay
Reviewed changes
Copilot reviewed 15 out of 16 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
| crates/rpc/src/traits.rs | Added DebugExecutionApi and RpcProofStorage trait definitions |
| crates/rpc/src/server.rs | Updated RpcServer to require RpcProofStorage and accept DebugExecutionApi |
| crates/rpc/src/lib.rs | Exported new debug API types and implementations |
| crates/rpc/src/debug/mod.rs | New debug namespace implementation with trace methods |
| crates/rpc/src/eth/api.rs | Removed comments indicating eth_getProof is unsupported |
| crates/rpc/src/adapters.rs | Added StubDebugExecutionApi, EvmDebugExecutionApi, and RpcProofStorage implementations |
| crates/execution/src/lib.rs | Re-exported inspector and proof types |
| crates/execution/src/proof.rs | New EIP-1186 Merkle proof generation implementation |
| crates/execution/src/inspector/mod.rs | New inspector module with CallTracer and OpcodeTracer |
| crates/execution/src/inspector/types.rs | Trace result types compatible with Geth debug API |
| crates/execution/src/inspector/call_tracer.rs | CallTracer inspector implementation |
| crates/execution/src/inspector/opcode_tracer.rs | OpcodeTracer inspector implementation |
| crates/execution/Cargo.toml | Added serde_json dependency |
| crates/node/src/node.rs | Updated node to create and pass StubDebugExecutionApi to RpcServer |
| crates/rpc/tests/e2e_transaction_test.rs | Updated test to include StubDebugExecutionApi parameter |
| .gitignore | Changed debug/ and release/ to /debug/ and /release/ |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Add revm Inspector implementations for debug/trace RPC methods: - CallTracer: tracks call stack during execution (call/create ops) - OpcodeTracer: step-by-step opcode execution tracing - Trace types: CallFrame, OpcodeStep, TraceResult, TraceOptions These tracers enable debug_traceTransaction, debug_traceCall, and similar RPC endpoints for Ethereum-compatible debugging.
Add Merkle proof generation for EIP-1186 eth_getProof: - AccountProof struct with account state and proofs - StorageProof struct for storage slot proofs - generate_account_proof function using alloy-trie ProofRetainer Enables verification of account state and storage against state root.
- Add DebugApi with debug_traceTransaction, debug_traceCall, debug_traceBlockByNumber, debug_traceBlockByHash methods - Add eth_getProof method to EthApi for EIP-1186 account proofs - Add DebugExecutionApi and RpcProofStorage traits - Add StubDebugExecutionApi for testing - Implement RpcProofStorage for StubRpcStorage and ProviderBasedRpcStorage - Register debug namespace in RPC server - Update e2e tests for new server signature
- Implement EvmDebugExecutionApi using actual revm Inspector integration - trace_call supports both callTracer and opcode tracer (structLogs) - CallTracer builds nested call frame trees - OpcodeTracer records step-by-step opcode execution - trace_transaction and trace_block return not-implemented until block indexing is available - Export EvmDebugExecutionApi for production use
- Apply cargo fmt to all modified files - Auto-fix clippy lints where possible
- Add missing crates/rpc/src/debug/mod.rs (was previously ignored by .gitignore) - Fix .gitignore to only ignore root /debug/ directory - Add StubDebugExecutionApi to node RpcServer initialization - Add #[allow(dead_code)] for unused but reserved code - Fix unused import in opcode_tracer
Fix clippy::iter_cloned_collect warning in opcode_tracer.
These trace functions need multiple parameters for the EVM call context.
… storage - Add cipherbft-storage dependency to rpc crate - Update EvmDebugExecutionApi to optionally use BlockStore and ReceiptStore - Implement trace_transaction: fetches tx from receipt store, traces it - Implement trace_block: fetches all txs in block, traces each one - Add EvmDebugExecutionApi::with_storage() constructor for full functionality - Methods still work without storage (return MethodNotSupported) The implementation uses the actual cipherbft_storage::BlockStore and ReceiptStore traits to fetch transaction and block data for tracing.
Address code review feedback: - Add set_latest_block() to StubDebugExecutionApi for consistency - Store rpc_debug_executor reference outside RPC block - Pass debug_executor to run_event_loop - Update debug_executor.set_latest_block() when consensus decides This ensures debug trace methods use the correct block context instead of always using block 0.
9aac2b9 to
5d0fbf4
Compare
| } | ||
|
|
||
| /// Push a new call frame onto the stack. | ||
| fn push_frame(&mut self, frame: CallFrame) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When only_top_call is enabled, push_frame skips nested calls without incrementing depth, but pop_frame still executes for those nested call ends because its guard depth > 1 is false (depth remains 1).
I think this causes the root frame to be popped prematurely when a nested call ends.
Summary
New RPC Methods
Architecture
EvmDebugExecutionApi
Storage Integration
cipherbft_storage::BlockStorefor block datacipherbft_storage::ReceiptStorefor transaction/receipt dataMethodNotSupportedif storage not configuredTest plan
🤖 Generated with Claude Code