#![allow(dead_code)]
#[cfg(feature = "foundry-fork")]
use revm_trace::{
create_evm_from_shared_backend, create_shared_backend,
traits::TransactionTrace,
types::{SimulationBatch, SimulationTx},
TxInspector,
};
#[cfg(feature = "foundry-fork")]
use {
alloy::primitives::{TxKind, U256},
anyhow::Result,
colored::*,
std::time::{Duration, Instant},
tokio::time::sleep,
};
#[cfg(feature = "foundry-fork")]
const ETH_RPC_URL: &str = "https://eth.llamarpc.com";
#[cfg(feature = "foundry-fork")]
#[derive(Clone, Debug)]
struct WorkerTask {
id: usize,
description: String,
from: String,
to: String,
value_eth: f64,
expected_result: &'static str,
}
#[cfg(feature = "foundry-fork")]
impl WorkerTask {
fn new(
id: usize,
description: &str,
from: &str,
to: &str,
value_eth: f64,
expected: &'static str,
) -> Self {
Self {
id,
description: description.to_string(),
from: from.to_string(),
to: to.to_string(),
value_eth,
expected_result: expected,
}
}
}
#[cfg(feature = "foundry-fork")]
async fn worker_thread(
thread_id: usize,
task: WorkerTask,
shared_backend: foundry_fork_db::backend::SharedBackend,
) -> Result<(usize, String, Duration)> {
let start_time = Instant::now();
println!(
"🧵 Thread {} starting: {}",
thread_id.to_string().cyan().bold(),
task.description.yellow()
);
sleep(Duration::from_millis(thread_id as u64 * 100)).await;
let provider = revm_trace::evm::builder::get_provider(ETH_RPC_URL).await?;
let tracer = TxInspector::new();
let mut evm = create_evm_from_shared_backend(shared_backend, &provider, tracer).await?;
let from_addr = task
.from
.parse()
.map_err(|e| anyhow::anyhow!("Invalid from address: {}", e))?;
let to_addr = task
.to
.parse()
.map_err(|e| anyhow::anyhow!("Invalid to address: {}", e))?;
let value_wei = U256::from((task.value_eth * 1e18) as u64);
let tx = SimulationTx {
caller: from_addr,
transact_to: TxKind::Call(to_addr),
value: value_wei,
data: vec![].into(),
};
let batch = SimulationBatch {
transactions: vec![tx],
is_stateful: false,
overrides: None,
};
let results = evm.trace_transactions(batch);
let elapsed = start_time.elapsed();
match results.into_iter().next() {
Some(Ok((execution_result, _, trace_output))) => {
let result_status = if execution_result.is_success() {
"SUCCESS".green().bold()
} else {
"FAILED".red().bold()
};
let message = format!(
"✅ Thread {} completed in {:?} - {} - Gas: {} - Transfers: {}",
thread_id.to_string().cyan().bold(),
elapsed,
result_status,
execution_result.gas_used(),
trace_output.asset_transfers.len()
);
println!("{}", message);
Ok((thread_id, message, elapsed))
}
Some(Err(e)) => {
let message = format!(
"❌ Thread {} failed in {:?} - Error: {}",
thread_id.to_string().cyan().bold(),
elapsed,
e.to_string().red()
);
println!("{}", message);
Ok((thread_id, message, elapsed))
}
None => {
let message = format!(
"⚠️ Thread {} completed in {:?} - No results",
thread_id.to_string().cyan().bold(),
elapsed
);
println!("{}", message);
Ok((thread_id, message, elapsed))
}
}
}
#[cfg(feature = "foundry-fork")]
async fn run_concurrent_test() -> Result<()> {
println!(
"{}",
"🚀 Starting SharedBackend Concurrent Test".green().bold()
);
println!("{}", "═".repeat(60).blue());
println!("📡 Creating SharedBackend...");
let shared_backend = create_shared_backend(ETH_RPC_URL, None).await?;
println!("✅ SharedBackend created successfully");
println!();
let tasks = vec![
WorkerTask::new(
1,
"Wealthy whale transfer",
"0x8EB8a3b98659Cce290402893d0123abb75E3ab28", "0x742d35Cc6675C4D858229a9e8E44B8d7B893E9c0", 0.1,
"EXPECTED_SUCCESS",
),
WorkerTask::new(
2,
"Poor address transfer",
"0x0000000000000000000000000000000000000001", "0x742d35Cc6675C4D858229a9e8E44B8d7B893E9c0",
1.0,
"EXPECTED_FAILURE",
),
WorkerTask::new(
3,
"Another whale transfer",
"0x40B38765696e3d5d8d9d834D8AaD4bB6e418E489", "0x1234567890123456789012345678901234567890",
0.05,
"EXPECTED_SUCCESS",
),
WorkerTask::new(
4,
"High gas price transfer",
"0x8EB8a3b98659Cce290402893d0123abb75E3ab28", "0xabcdefabcdefabcdefabcdefabcdefabcdefabcd",
0.01,
"EXPECTED_SUCCESS",
),
];
println!("🧵 Spawning {} worker threads...", tasks.len());
let start_time = Instant::now();
let mut handles = Vec::new();
for task in tasks {
let backend_clone = shared_backend.clone(); let handle = tokio::spawn(async move { worker_thread(task.id, task, backend_clone).await });
handles.push(handle);
}
println!("⏳ Waiting for all threads to complete...");
println!();
let mut results = Vec::new();
for handle in handles {
match handle.await {
Ok(Ok(result)) => results.push(result),
Ok(Err(e)) => println!("❌ Thread error: {}", e),
Err(e) => println!("❌ Join error: {}", e),
}
}
let total_elapsed = start_time.elapsed();
println!();
println!("{}", "📊 SUMMARY".green().bold());
println!("{}", "═".repeat(60).blue());
results.sort_by_key(|(id, _, _)| *id);
for (thread_id, message, duration) in &results {
println!("Thread {}: {:?}, message: {}", thread_id, duration, message);
}
println!();
println!("⏱️ Total execution time: {:?}", total_elapsed);
println!("🧵 Threads completed: {}/{}", results.len(), 4);
let avg_duration = if !results.is_empty() {
results.iter().map(|(_, _, d)| d.as_millis()).sum::<u128>() / results.len() as u128
} else {
0
};
println!("📈 Average thread duration: {}ms", avg_duration);
let sequential_time = results.iter().map(|(_, _, d)| d.as_millis()).sum::<u128>();
let speedup = sequential_time as f64 / total_elapsed.as_millis() as f64;
println!("🚀 Concurrency speedup: {:.2}x", speedup);
println!();
println!(
"{}",
"✅ SUCCESS: SharedBackend Multi-Threading Test Completed!"
.green()
.bold()
);
println!("{}", "🎯 Key achievements:".cyan());
println!(
" ✓ SharedBackend successfully shared across {} threads",
results.len()
);
println!(" ✓ Each thread created its own EVM instance");
println!(" ✓ Concurrent transaction processing achieved");
println!(" ✓ Shared cache and RPC pool benefits utilized");
println!(" ✓ No thread safety issues encountered");
Ok(())
}
#[cfg(not(feature = "foundry-fork"))]
async fn run_concurrent_test() -> Result<()> {
println!(
"{}",
"⚠️ SharedBackend Multi-Threading Test Skipped"
.yellow()
.bold()
);
println!(
"{}",
"ℹ️ This test requires the 'foundry-fork' feature".cyan()
);
println!(
"{}",
"💡 Run with: cargo run --example concurrent_shared_backend --features foundry-fork"
.green()
);
Ok(())
}
#[tokio::main]
async fn main() -> anyhow::Result<()> {
println!(
"{}",
"🔬 SharedBackend Multi-Threading Demonstration"
.magenta()
.bold()
);
println!(
"{}",
"This example shows how SharedBackend enables safe multi-threading".cyan()
);
println!();
run_concurrent_test().await?;
Ok(())
}