From 32d5653492f89dc6f3480e29402da150396801a5 Mon Sep 17 00:00:00 2001 From: Adegbite Ademola Kelvin Date: Tue, 3 Dec 2024 15:10:52 +0100 Subject: [PATCH 1/2] feat: add example for trace_call_many and debug_trace_call_many --- .../examples/debug_trace_call_many.rs | 51 +++++++++++++++++++ .../transactions/examples/trace_call_many.rs | 43 ++++++++++++++++ 2 files changed, 94 insertions(+) create mode 100644 examples/transactions/examples/debug_trace_call_many.rs create mode 100644 examples/transactions/examples/trace_call_many.rs diff --git a/examples/transactions/examples/debug_trace_call_many.rs b/examples/transactions/examples/debug_trace_call_many.rs new file mode 100644 index 00000000..95548c54 --- /dev/null +++ b/examples/transactions/examples/debug_trace_call_many.rs @@ -0,0 +1,51 @@ +//! Example of how to trace a transaction using `debug_trace_call_many`. + +use alloy::{ + network::TransactionBuilder, + primitives::{address, U256}, + providers::{ext::DebugApi, ProviderBuilder}, + rpc::types::{ + trace::geth::GethDebugTracingCallOptions, Bundle, StateContext, TransactionRequest, + }, +}; +use eyre::Result; + +#[tokio::main] +async fn main() -> Result<()> { + // create a provider + let rpc_url = "https://eth.merkle.io".parse()?; + let provider = ProviderBuilder::new().on_http(rpc_url); + + let alice = address!("f39Fd6e51aad88F6F4ce6aB8827279cffFb92266"); + let bob = address!("d8dA6BF26964aF9D7eEd9e03E53415D37aA96045"); + + let jon = address!("f29Fd6e51aad88F6F4ce6aB8827279cffFb92377"); + let vitalik = address!("f9dA6BF26964aF9D7eEd9e03E53415D37aA96033"); + + // Define transactions + let tx1 = + TransactionRequest::default().with_from(alice).with_to(bob).with_value(U256::from(150)); + let tx2 = + TransactionRequest::default().with_from(jon).with_to(vitalik).with_value(U256::from(250)); + + // Create the bundle of transactions. + let bundles = vec![Bundle { transactions: vec![tx1, tx2], block_override: None }]; + + // Define the State context and trace option + let state_context = StateContext::default(); + let trace_options = GethDebugTracingCallOptions::default(); + + //Call `debug_trace_call_many` on the provider. + let result = provider.debug_trace_call_many(bundles, state_context, trace_options).await; + + match result { + Ok(traces) => { + println!("Traces:\n{:?}", traces); + } + Err(err) => { + println!("Error tracing transactions: {:?}", err); + } + } + + Ok(()) +} diff --git a/examples/transactions/examples/trace_call_many.rs b/examples/transactions/examples/trace_call_many.rs new file mode 100644 index 00000000..b73a81fa --- /dev/null +++ b/examples/transactions/examples/trace_call_many.rs @@ -0,0 +1,43 @@ +//! Example of how to trace a transaction using `trace_call_many`. + +use alloy::{ + network::TransactionBuilder, + primitives::{address, U256}, + providers::{ext::TraceApi, ProviderBuilder}, + rpc::types::{trace::parity::TraceType, TransactionRequest}, +}; + +use eyre::{Ok, Result}; + +#[tokio::main] +async fn main() -> Result<()> { + // create a provider + let rpc_url = "https://eth.merkle.io".parse()?; + let provider = ProviderBuilder::new().on_http(rpc_url); + + let alice = address!("f39Fd6e51aad88F6F4ce6aB8827279cffFb92266"); + let bob = address!("d8dA6BF26964aF9D7eEd9e03E53415D37aA96045"); + + let jon = address!("f29Fd6e51aad88F6F4ce6aB8827279cffFb92377"); + let vitalik = address!("f9dA6BF26964aF9D7eEd9e03E53415D37aA96033"); + + // Define transactions + let tx1 = + TransactionRequest::default().with_from(alice).with_to(bob).with_value(U256::from(150)); + let tx2 = + TransactionRequest::default().with_from(jon).with_to(vitalik).with_value(U256::from(250)); + + // Define the trace for the trace_list + let trace_type: &[TraceType] = &[TraceType::Trace]; + + // Trace the transaction on top of the latest block. + let trace_call_list = &[(tx1, trace_type), (tx2, trace_type)]; + + let result = provider.trace_call_many(trace_call_list).await?; + + // Print the trace results. + for (index, trace_result) in result.iter().enumerate() { + println!("Trace result for transaction {}: {:?}", index, trace_result); + } + Ok(()) +} From 06aeb8eb1f02db35a6de0eae78cd95f8b2c478f5 Mon Sep 17 00:00:00 2001 From: zerosnacks Date: Wed, 4 Dec 2024 09:30:27 +0100 Subject: [PATCH 2/2] update examples to use Reth bindings, ignore from CI, add to examples list --- README.md | 2 ++ .../examples/debug_trace_call_many.rs | 20 ++++++++++--------- .../transactions/examples/trace_call_many.rs | 20 ++++++++++--------- scripts/run.sh | 2 ++ 4 files changed, 26 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index dc8bcd31..f8f17a83 100644 --- a/README.md +++ b/README.md @@ -85,6 +85,8 @@ This repository contains the following examples: - [x] [Decode input](./examples/transactions/examples/decode_input.rs) - [x] [Encode and decode EIP-1559 transaction](./examples/transactions/examples/encode_decode_eip1559.rs) - [x] [Get gas price in USD](./examples/transactions/examples/gas_price_usd.rs) + - [x] [Simulate using `debug_traceCallMany`](./examples/transactions/examples/debug_trace_call_many.rs) + - [x] [Simulate using `trace_callMany`](./examples/transactions/examples/trace_call_many.rs) - [x] [Trace call](./examples/transactions/examples/trace_call.rs) - [x] [Trace transaction](./examples/transactions/examples/trace_transaction.rs) - [x] [Transfer ERC20 token](./examples/transactions/examples/transfer_erc20.rs) diff --git a/examples/transactions/examples/debug_trace_call_many.rs b/examples/transactions/examples/debug_trace_call_many.rs index 95548c54..83bd223d 100644 --- a/examples/transactions/examples/debug_trace_call_many.rs +++ b/examples/transactions/examples/debug_trace_call_many.rs @@ -2,6 +2,7 @@ use alloy::{ network::TransactionBuilder, + node_bindings::Reth, primitives::{address, U256}, providers::{ext::DebugApi, ProviderBuilder}, rpc::types::{ @@ -12,21 +13,22 @@ use eyre::Result; #[tokio::main] async fn main() -> Result<()> { - // create a provider - let rpc_url = "https://eth.merkle.io".parse()?; - let provider = ProviderBuilder::new().on_http(rpc_url); + // Spin up a local Reth node. + // Ensure `reth` is available in $PATH. + let reth = Reth::new().dev().disable_discovery().instance(1).spawn(); + let provider = ProviderBuilder::new().on_http(reth.endpoint().parse()?); - let alice = address!("f39Fd6e51aad88F6F4ce6aB8827279cffFb92266"); - let bob = address!("d8dA6BF26964aF9D7eEd9e03E53415D37aA96045"); - - let jon = address!("f29Fd6e51aad88F6F4ce6aB8827279cffFb92377"); - let vitalik = address!("f9dA6BF26964aF9D7eEd9e03E53415D37aA96033"); + // Get users, these have allocated balances in the dev genesis block. + let alice = address!("70997970C51812dc3A010C7d01b50e0d17dc79C8"); + let bob = address!("3C44CdDdB6a900fa2b585dd299e03d12FA4293BC"); + let charlie = address!("90F79bf6EB2c4f870365E785982E1f101E93b906"); + let dan = address!("15d34AAf54267DB7D7c367839AAf71A00a2C6A65"); // Define transactions let tx1 = TransactionRequest::default().with_from(alice).with_to(bob).with_value(U256::from(150)); let tx2 = - TransactionRequest::default().with_from(jon).with_to(vitalik).with_value(U256::from(250)); + TransactionRequest::default().with_from(charlie).with_to(dan).with_value(U256::from(250)); // Create the bundle of transactions. let bundles = vec![Bundle { transactions: vec![tx1, tx2], block_override: None }]; diff --git a/examples/transactions/examples/trace_call_many.rs b/examples/transactions/examples/trace_call_many.rs index b73a81fa..bda63766 100644 --- a/examples/transactions/examples/trace_call_many.rs +++ b/examples/transactions/examples/trace_call_many.rs @@ -2,6 +2,7 @@ use alloy::{ network::TransactionBuilder, + node_bindings::Reth, primitives::{address, U256}, providers::{ext::TraceApi, ProviderBuilder}, rpc::types::{trace::parity::TraceType, TransactionRequest}, @@ -11,21 +12,22 @@ use eyre::{Ok, Result}; #[tokio::main] async fn main() -> Result<()> { - // create a provider - let rpc_url = "https://eth.merkle.io".parse()?; - let provider = ProviderBuilder::new().on_http(rpc_url); + // Spin up a local Reth node. + // Ensure `reth` is available in $PATH. + let reth = Reth::new().dev().disable_discovery().instance(1).spawn(); + let provider = ProviderBuilder::new().on_http(reth.endpoint().parse()?); - let alice = address!("f39Fd6e51aad88F6F4ce6aB8827279cffFb92266"); - let bob = address!("d8dA6BF26964aF9D7eEd9e03E53415D37aA96045"); - - let jon = address!("f29Fd6e51aad88F6F4ce6aB8827279cffFb92377"); - let vitalik = address!("f9dA6BF26964aF9D7eEd9e03E53415D37aA96033"); + // Get users, these have allocated balances in the dev genesis block. + let alice = address!("70997970C51812dc3A010C7d01b50e0d17dc79C8"); + let bob = address!("3C44CdDdB6a900fa2b585dd299e03d12FA4293BC"); + let charlie = address!("90F79bf6EB2c4f870365E785982E1f101E93b906"); + let dan = address!("15d34AAf54267DB7D7c367839AAf71A00a2C6A65"); // Define transactions let tx1 = TransactionRequest::default().with_from(alice).with_to(bob).with_value(U256::from(150)); let tx2 = - TransactionRequest::default().with_from(jon).with_to(vitalik).with_value(U256::from(250)); + TransactionRequest::default().with_from(charlie).with_to(dan).with_value(U256::from(250)); // Define the trace for the trace_list let trace_type: &[TraceType] = &[TraceType::Trace]; diff --git a/scripts/run.sh b/scripts/run.sh index b0aeda66..a9d5762d 100755 --- a/scripts/run.sh +++ b/scripts/run.sh @@ -15,6 +15,7 @@ function main () { | grep -v \ -e 'any_network' \ -e 'builtin' \ + -e 'debug_trace_call_many' \ -e 'geth_local_instance' \ -e 'ipc' \ -e 'ledger_signer' \ @@ -24,6 +25,7 @@ function main () { -e 'subscribe_all_logs' \ -e 'subscribe_logs' \ -e 'subscribe_pending_transactions' \ + -e 'trace_call_many' \ -e 'trace_call' \ -e 'trace_transaction' \ -e 'trezor_signer' \