feat: integrate builder (#6611)

This commit is contained in:
Matthias Seitz
2024-02-29 17:50:04 +01:00
committed by GitHub
parent 7d36206dfe
commit c5955f1305
73 changed files with 2201 additions and 3022 deletions

View File

@ -7,6 +7,6 @@ license.workspace = true
[dependencies]
reth.workspace = true
reth-node-ethereum.workspace = true
clap = { workspace = true, features = ["derive"] }
futures-util.workspace = true
eyre.workspace = true
futures-util.workspace = true

View File

@ -11,15 +11,11 @@
#![warn(unused_crate_dependencies)]
use clap::Parser;
use futures_util::stream::StreamExt;
use futures_util::StreamExt;
use reth::{
cli::{
components::{RethNodeComponents, RethRpcComponents, RethRpcServerHandles},
config::RethRpcConfig,
ext::{RethCliExt, RethNodeCommandConfig},
Cli,
},
primitives::{Address, BlockId, IntoRecoveredTransaction},
builder::NodeHandle,
cli::Cli,
primitives::{Address, BlockNumberOrTag, IntoRecoveredTransaction},
revm::{
inspector_handle_register,
interpreter::{Interpreter, OpCode},
@ -29,21 +25,79 @@ use reth::{
compat::transaction::transaction_to_call_request,
eth::{revm_utils::EvmOverrides, EthTransactions},
},
tasks::TaskSpawner,
transaction_pool::TransactionPool,
};
use reth_node_ethereum::node::EthereumNode;
use std::collections::HashSet;
fn main() {
Cli::<MyRethCliExt>::parse().run().unwrap();
}
Cli::<RethCliTxpoolExt>::parse()
.run(|builder, args| async move {
// launch the node
let NodeHandle { mut node, node_exit_future } =
builder.node(EthereumNode::default()).launch().await?;
/// The type that tells the reth CLI what extensions to use
struct MyRethCliExt;
let recipients = args.recipients.iter().copied().collect::<HashSet<_>>();
impl RethCliExt for MyRethCliExt {
/// This tells the reth CLI to trace addresses via `RethCliTxpoolExt`
type Node = RethCliTxpoolExt;
// create a new subscription to pending transactions
let mut pending_transactions = node.pool.new_pending_pool_transactions_listener();
// get an instance of the `trace_` API handler
let eth_api = node.rpc_registry.eth_api();
println!("Spawning trace task!");
// Spawn an async block to listen for transactions.
node.task_executor.spawn(Box::pin(async move {
// Waiting for new transactions
while let Some(event) = pending_transactions.next().await {
let tx = event.transaction;
println!("Transaction received: {tx:?}");
if recipients.is_empty() {
// convert the pool transaction
let call_request =
transaction_to_call_request(tx.to_recovered_transaction());
let result = eth_api
.spawn_with_call_at(
call_request,
BlockNumberOrTag::Latest.into(),
EvmOverrides::default(),
move |db, env| {
let mut dummy_inspector = DummyInspector::default();
{
// configure the evm with the custom inspector
let mut evm = Evm::builder()
.with_db(db)
.with_external_context(&mut dummy_inspector)
.with_env_with_handler_cfg(env)
.append_handler_register(inspector_handle_register)
.build();
// execute the transaction on a blocking task and await the
// inspector result
let _ = evm.transact()?;
}
Ok(dummy_inspector)
},
)
.await;
if let Ok(ret_val) = result {
let hash = tx.hash();
println!(
"Inspector result for transaction {}: \n {}",
hash,
ret_val.ret_val.join("\n")
);
}
}
}
}));
node_exit_future.await
})
.unwrap();
}
/// Our custom cli args extension that adds one flag to reth default CLI.
@ -74,76 +128,3 @@ where
}
}
}
impl RethNodeCommandConfig for RethCliTxpoolExt {
/// Sets up a subscription to listen for new pending transactions and traces them.
/// If the transaction is from one of the specified recipients, it will be traced.
/// If no recipients are specified, all transactions will be traced.
fn on_rpc_server_started<Conf, Reth>(
&mut self,
_config: &Conf,
components: &Reth,
rpc_components: RethRpcComponents<'_, Reth>,
_handles: RethRpcServerHandles,
) -> eyre::Result<()>
where
Conf: RethRpcConfig,
Reth: RethNodeComponents,
{
let recipients = self.recipients.iter().copied().collect::<HashSet<_>>();
// create a new subscription to pending transactions
let mut pending_transactions = components.pool().new_pending_pool_transactions_listener();
let eth_api = rpc_components.registry.eth_api();
println!("Spawning trace task!");
// Spawn an async block to listen for transactions.
components.task_executor().spawn(Box::pin(async move {
// Waiting for new transactions
while let Some(event) = pending_transactions.next().await {
let tx = event.transaction;
println!("Transaction received: {tx:?}");
if recipients.is_empty() {
// convert the pool transaction
let call_request = transaction_to_call_request(tx.to_recovered_transaction());
let result = eth_api
.spawn_with_call_at(
call_request,
BlockId::default(),
EvmOverrides::default(),
move |db, env| {
let mut dummy_inspector = DummyInspector::default();
{
// configure the evm with the custom inspector
let mut evm = Evm::builder()
.with_db(db)
.with_external_context(&mut dummy_inspector)
.with_env_with_handler_cfg(env)
.append_handler_register(inspector_handle_register)
.build();
// execute the transaction on a blocking task and await the
// inspector result
let _ = evm.transact()?;
}
Ok(dummy_inspector)
},
)
.await;
if let Ok(ret_val) = result {
let hash = tx.hash();
println!(
"Inspector result for transaction {}: \n {}",
hash,
ret_val.ret_val.join("\n")
);
}
}
}
}));
Ok(())
}
}