From d8787f92485c624ab74a69265b22eae858248a4f Mon Sep 17 00:00:00 2001 From: highonhopium Date: Tue, 27 Aug 2024 23:53:52 +0100 Subject: [PATCH 1/8] wip --- crates/eval/src/error.rs | 2 + crates/eval/src/fork.rs | 103 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 104 insertions(+), 1 deletion(-) diff --git a/crates/eval/src/error.rs b/crates/eval/src/error.rs index b2a6d2d40..175af559e 100644 --- a/crates/eval/src/error.rs +++ b/crates/eval/src/error.rs @@ -23,6 +23,8 @@ pub enum ForkCallError { U64FromUint256(#[from] FromUintError), #[error(transparent)] Eyre(#[from] eyre::Report), + #[error("Replay transaction error: {0}")] + ReplayTransactionError(String), } #[cfg(not(target_family = "wasm"))] diff --git a/crates/eval/src/fork.rs b/crates/eval/src/fork.rs index 357b11260..2d1815b5a 100644 --- a/crates/eval/src/fork.rs +++ b/crates/eval/src/fork.rs @@ -8,6 +8,7 @@ use foundry_evm::{ opts::EvmOpts, }; use rain_error_decoding::AbiDecodedErrorType; +use revm::primitives::B256; use revm::{ interpreter::InstructionResult, primitives::{Address as Addr, Bytes, Env, HashSet, SpecId}, @@ -375,7 +376,7 @@ impl Forker { let block_number = block_number .map(BlockNumber::from) .unwrap_or(org_block_number.unwrap()); - + self.executor.env_mut().block.number = U256::from(block_number); self.executor @@ -388,6 +389,88 @@ impl Forker { ) .map_err(|v| ForkCallError::ExecutorError(v.to_string())) } + + /// Replays a transaction from the forked EVM. + /// # Arguments + /// * `tx_hash` - The transaction hash. + /// # Returns + /// A result containing the raw call result. + pub fn replay_transaction( + &mut self, + tx_hash: B256, + ) -> Result { + let active_fork_local_id = self + .executor + .backend() + .active_fork_id() + .ok_or(ForkCallError::ExecutorError("no active fork!".to_owned()))?; + + let _ = self.executor + .backend_mut().create_select_fork_at_transaction( + CreateFork { + enable_caching: true, + url: "https://eth-mainnet.alchemyapi.io/v2/WV407BEiBmjNJfKo9Uo_55u0z0ITyCOX".to_string(), + env: Env::default(), + evm_opts: EvmOpts::default() + }, + &mut Env::default(), + &mut JournaledState::new(SpecId::LATEST, HashSet::new()), + tx_hash + ); + + + let mut env = self.executor.env().clone(); + + let full_tx = self.executor.backend().active_fork_db().unwrap().db.get_transaction(tx_hash).unwrap(); + + let block_number = full_tx.block_number.unwrap(); + + let block = self.executor.backend().active_fork_db().unwrap().db.get_full_block(block_number).unwrap(); + + let first_tx = block.transactions.into_transactions().enumerate().next().unwrap().1; + println!("{:?}", first_tx); + println!("{:?}", block_number); + // let (fork_block, block) = + // self.executor.backend().db().get_block_number_and_block_for_transaction(id, transaction)?; + + // roll the fork to the transaction's block or latest if it's pending + + let mut journaled_state = JournaledState::new(SpecId::LATEST, HashSet::new()); + + env.block.timestamp = U256::from(block.header.timestamp); + env.block.coinbase = block.header.miner; + env.block.difficulty = block.header.difficulty; + env.block.prevrandao = Some(block.header.mix_hash.unwrap_or_default()); + env.block.basefee = U256::from(block.header.base_fee_per_gas.unwrap_or_default()); + env.block.gas_limit = U256::from(block.header.gas_limit); + env.block.number = U256::from(block.header.number.unwrap_or(block_number)); + + // replay all transactions that came before + let env = env.clone(); + + let tx = self.executor + .backend_mut() + .replay_until( + active_fork_local_id, + env, + tx_hash, + &mut journaled_state, + )?; + + println!("{:?}", tx); + + let res = match tx { + Some(tx) => { + match tx.to { + Some(to) => self.call(tx.from.as_slice(), to.as_slice(), &tx.input)?, + None => return Err(ForkCallError::ReplayTransactionError("Transaction has no from address".to_owned())) + } + } + None => return Err(ForkCallError::ReplayTransactionError("Transaction not found. Is the fork block number correct?".to_owned())) + }; + + Ok(res) + } } #[cfg(test)] @@ -663,4 +746,22 @@ mod tests { U256::from(POLYGON_FORK_NUMBER + 1) ); } + + #[tokio::test(flavor = "multi_thread", worker_threads = 1)] + async fn test_fork_replay() { + let args = NewForkedEvm { + fork_url: "https://eth-mainnet.alchemyapi.io/v2/WV407BEiBmjNJfKo9Uo_55u0z0ITyCOX".to_owned(), + fork_block_number: Some(20622339), + }; + let mut forker = Forker::new_with_fork(args, None, None).await.unwrap(); + + // let mut forker = Forker::new(); + let tx_hash = "0x5ee1ff6d0c58904f89200829b12f84acda2bf662009a9b3a036132ce311b6c15" + .parse::() + .unwrap(); + + let replay_result = forker.replay_transaction(tx_hash).unwrap(); + println!("{:?}", replay_result); + // assert_eq!(replay_result.exit_reason, InstructionResult::Ok); + } } From f037feab4f365dfbc7b2588d7e78639ffbdaebc0 Mon Sep 17 00:00:00 2001 From: highonhopium Date: Wed, 28 Aug 2024 12:35:30 +0100 Subject: [PATCH 2/8] wip - not working --- crates/eval/src/error.rs | 19 +++++++++++-- crates/eval/src/fork.rs | 58 ++++++++++++++++++++-------------------- 2 files changed, 46 insertions(+), 31 deletions(-) diff --git a/crates/eval/src/error.rs b/crates/eval/src/error.rs index 175af559e..456ca7e94 100644 --- a/crates/eval/src/error.rs +++ b/crates/eval/src/error.rs @@ -1,4 +1,5 @@ use alloy::primitives::ruint::FromUintError; +use foundry_evm::backend::DatabaseError; #[cfg(not(target_family = "wasm"))] use foundry_evm::executors::RawCallResult; use rain_error_decoding::{AbiDecodeFailedErrors, AbiDecodedErrorType}; @@ -23,8 +24,22 @@ pub enum ForkCallError { U64FromUint256(#[from] FromUintError), #[error(transparent)] Eyre(#[from] eyre::Report), - #[error("Replay transaction error: {0}")] - ReplayTransactionError(String), + #[error("Replay transaction error: {:#?}", .0)] + ReplayTransactionError(ReplayTransactionError), +} + +#[derive(Debug, Error)] +pub enum ReplayTransactionError { + #[error("Transaction not found for hash {0} and fork url {1}")] + TransactionNotFound(String, String), + #[error("No active fork found")] + NoActiveFork, + #[error("Database error for hash {0} and fork url {1}: {2}")] + DatabaseError(String, String, DatabaseError), + #[error("No block number found in transaction for hash {0} and fork url {1}")] + NoBlockNumberFound(String, String), + #[error("No from address found in transaction for hash {0} and fork url {1}")] + NoFromAddressFound(String, String), } #[cfg(not(target_family = "wasm"))] diff --git a/crates/eval/src/fork.rs b/crates/eval/src/fork.rs index 2d1815b5a..5e613a892 100644 --- a/crates/eval/src/fork.rs +++ b/crates/eval/src/fork.rs @@ -1,4 +1,4 @@ -use crate::error::ForkCallError; +use crate::error::{ForkCallError, ReplayTransactionError}; use alloy::primitives::{Address, BlockNumber, U256}; use alloy::sol_types::SolCall; use foundry_evm::{ @@ -397,6 +397,7 @@ impl Forker { /// A result containing the raw call result. pub fn replay_transaction( &mut self, + fork_url: String, tx_hash: B256, ) -> Result { let active_fork_local_id = self @@ -405,38 +406,40 @@ impl Forker { .active_fork_id() .ok_or(ForkCallError::ExecutorError("no active fork!".to_owned()))?; - let _ = self.executor + let fork_id = self.executor .backend_mut().create_select_fork_at_transaction( CreateFork { enable_caching: true, - url: "https://eth-mainnet.alchemyapi.io/v2/WV407BEiBmjNJfKo9Uo_55u0z0ITyCOX".to_string(), + url: fork_url.clone(), env: Env::default(), evm_opts: EvmOpts::default() }, &mut Env::default(), &mut JournaledState::new(SpecId::LATEST, HashSet::new()), tx_hash - ); + )?; + println!("Fork created "); let mut env = self.executor.env().clone(); - let full_tx = self.executor.backend().active_fork_db().unwrap().db.get_transaction(tx_hash).unwrap(); - - let block_number = full_tx.block_number.unwrap(); - - let block = self.executor.backend().active_fork_db().unwrap().db.get_full_block(block_number).unwrap(); + // get the transaction + let shared_backend = &self.executor.backend().active_fork_db().ok_or(ForkCallError::ReplayTransactionError(ReplayTransactionError::NoActiveFork))?.db; + let full_tx = shared_backend.get_transaction(tx_hash).map_err(|e| ForkCallError::ReplayTransactionError(ReplayTransactionError::DatabaseError(tx_hash.to_string(), fork_url.clone(), e)))?; + + println!("Transaction found"); - let first_tx = block.transactions.into_transactions().enumerate().next().unwrap().1; - println!("{:?}", first_tx); - println!("{:?}", block_number); - // let (fork_block, block) = - // self.executor.backend().db().get_block_number_and_block_for_transaction(id, transaction)?; + // get the block number from the transaction + let block_number = full_tx.block_number.ok_or(ForkCallError::ReplayTransactionError(ReplayTransactionError::NoBlockNumberFound(tx_hash.to_string(), fork_url.clone())))?; + + println!("Block number found"); - // roll the fork to the transaction's block or latest if it's pending + // get the block + let block = shared_backend.get_full_block(block_number).map_err(|e| ForkCallError::ReplayTransactionError(ReplayTransactionError::DatabaseError(block_number.to_string(), fork_url.clone(), e)))?; let mut journaled_state = JournaledState::new(SpecId::LATEST, HashSet::new()); + // matching env to the env from the block the transaction is in env.block.timestamp = U256::from(block.header.timestamp); env.block.coinbase = block.header.miner; env.block.difficulty = block.header.difficulty; @@ -445,28 +448,27 @@ impl Forker { env.block.gas_limit = U256::from(block.header.gas_limit); env.block.number = U256::from(block.header.number.unwrap_or(block_number)); + println!("Starting to replay"); // replay all transactions that came before let env = env.clone(); let tx = self.executor .backend_mut() .replay_until( - active_fork_local_id, + fork_id, env, tx_hash, &mut journaled_state, )?; - - println!("{:?}", tx); - + let res = match tx { Some(tx) => { match tx.to { Some(to) => self.call(tx.from.as_slice(), to.as_slice(), &tx.input)?, - None => return Err(ForkCallError::ReplayTransactionError("Transaction has no from address".to_owned())) + None => return Err(ForkCallError::ReplayTransactionError(ReplayTransactionError::NoFromAddressFound(tx_hash.to_string(), fork_url))) } } - None => return Err(ForkCallError::ReplayTransactionError("Transaction not found. Is the fork block number correct?".to_owned())) + None => return Err(ForkCallError::ReplayTransactionError(ReplayTransactionError::TransactionNotFound(tx_hash.to_string(), fork_url))) }; Ok(res) @@ -749,18 +751,16 @@ mod tests { #[tokio::test(flavor = "multi_thread", worker_threads = 1)] async fn test_fork_replay() { - let args = NewForkedEvm { - fork_url: "https://eth-mainnet.alchemyapi.io/v2/WV407BEiBmjNJfKo9Uo_55u0z0ITyCOX".to_owned(), - fork_block_number: Some(20622339), - }; - let mut forker = Forker::new_with_fork(args, None, None).await.unwrap(); + let mut forker = Forker::new_with_fork(NewForkedEvm { + fork_url: CI_DEPLOY_SEPOLIA_RPC_URL.to_string(), + fork_block_number: Some(*CI_FORK_SEPOLIA_BLOCK_NUMBER), + }, None, None).await.unwrap(); - // let mut forker = Forker::new(); - let tx_hash = "0x5ee1ff6d0c58904f89200829b12f84acda2bf662009a9b3a036132ce311b6c15" + let tx_hash = "0xcbfff7d9369afcc7a851dff42ca2769f32d77c3b9066023b887583ee9cd0809d" .parse::() .unwrap(); - let replay_result = forker.replay_transaction(tx_hash).unwrap(); + let replay_result = forker.replay_transaction(CI_DEPLOY_SEPOLIA_RPC_URL.into(), tx_hash).unwrap(); println!("{:?}", replay_result); // assert_eq!(replay_result.exit_reason, InstructionResult::Ok); } From 9092a9fd35ee18eeb3f18b4353de51e8435fff6d Mon Sep 17 00:00:00 2001 From: highonhopium Date: Wed, 28 Aug 2024 19:40:48 +0100 Subject: [PATCH 3/8] working --- crates/eval/src/fork.rs | 59 +++++++++++++++-------------------------- 1 file changed, 21 insertions(+), 38 deletions(-) diff --git a/crates/eval/src/fork.rs b/crates/eval/src/fork.rs index 5e613a892..d507a0954 100644 --- a/crates/eval/src/fork.rs +++ b/crates/eval/src/fork.rs @@ -395,50 +395,27 @@ impl Forker { /// * `tx_hash` - The transaction hash. /// # Returns /// A result containing the raw call result. - pub fn replay_transaction( + pub async fn replay_transaction( &mut self, - fork_url: String, tx_hash: B256, ) -> Result { - let active_fork_local_id = self - .executor - .backend() - .active_fork_id() - .ok_or(ForkCallError::ExecutorError("no active fork!".to_owned()))?; - - let fork_id = self.executor - .backend_mut().create_select_fork_at_transaction( - CreateFork { - enable_caching: true, - url: fork_url.clone(), - env: Env::default(), - evm_opts: EvmOpts::default() - }, - &mut Env::default(), - &mut JournaledState::new(SpecId::LATEST, HashSet::new()), - tx_hash - )?; - println!("Fork created "); - - let mut env = self.executor.env().clone(); + let fork_url = self.executor.backend().active_fork_url().unwrap_or("No fork url found".to_string()); // get the transaction let shared_backend = &self.executor.backend().active_fork_db().ok_or(ForkCallError::ReplayTransactionError(ReplayTransactionError::NoActiveFork))?.db; let full_tx = shared_backend.get_transaction(tx_hash).map_err(|e| ForkCallError::ReplayTransactionError(ReplayTransactionError::DatabaseError(tx_hash.to_string(), fork_url.clone(), e)))?; - println!("Transaction found"); - // get the block number from the transaction let block_number = full_tx.block_number.ok_or(ForkCallError::ReplayTransactionError(ReplayTransactionError::NoBlockNumberFound(tx_hash.to_string(), fork_url.clone())))?; - - println!("Block number found"); - + // get the block let block = shared_backend.get_full_block(block_number).map_err(|e| ForkCallError::ReplayTransactionError(ReplayTransactionError::DatabaseError(block_number.to_string(), fork_url.clone(), e)))?; - - let mut journaled_state = JournaledState::new(SpecId::LATEST, HashSet::new()); + let _ = &self.add_or_select(NewForkedEvm { fork_url: fork_url.clone(), fork_block_number: Some(block_number - 1) }, None).await; + + let mut env = self.executor.env().clone(); + // matching env to the env from the block the transaction is in env.block.timestamp = U256::from(block.header.timestamp); env.block.coinbase = block.header.miner; @@ -448,14 +425,19 @@ impl Forker { env.block.gas_limit = U256::from(block.header.gas_limit); env.block.number = U256::from(block.header.number.unwrap_or(block_number)); - println!("Starting to replay"); - // replay all transactions that came before - let env = env.clone(); + let active_fork_local_id = self + .executor + .backend() + .active_fork_id() + .ok_or(ForkCallError::ExecutorError("no active fork!".to_owned()))?; + + let mut journaled_state = JournaledState::new(SpecId::LATEST, HashSet::new()); + // replay all transactions that came before let tx = self.executor .backend_mut() .replay_until( - fork_id, + active_fork_local_id, env, tx_hash, &mut journaled_state, @@ -753,15 +735,16 @@ mod tests { async fn test_fork_replay() { let mut forker = Forker::new_with_fork(NewForkedEvm { fork_url: CI_DEPLOY_SEPOLIA_RPC_URL.to_string(), - fork_block_number: Some(*CI_FORK_SEPOLIA_BLOCK_NUMBER), + fork_block_number: None, }, None, None).await.unwrap(); let tx_hash = "0xcbfff7d9369afcc7a851dff42ca2769f32d77c3b9066023b887583ee9cd0809d" .parse::() .unwrap(); - let replay_result = forker.replay_transaction(CI_DEPLOY_SEPOLIA_RPC_URL.into(), tx_hash).unwrap(); - println!("{:?}", replay_result); - // assert_eq!(replay_result.exit_reason, InstructionResult::Ok); + let replay_result = forker.replay_transaction(tx_hash).await.unwrap(); + + assert!(replay_result.env.tx.caller == "0x8924274F5304277FFDdd29fad5181D98D5F65eF6".parse::
().unwrap()); + assert!(replay_result.exit_reason.is_ok()); } } From 035fb98a80517b4cd92a8a8fb048ce2aa5770c21 Mon Sep 17 00:00:00 2001 From: highonhopium Date: Wed, 28 Aug 2024 20:10:26 +0100 Subject: [PATCH 4/8] getting rain traces directly from rawcallresults --- crates/eval/src/trace.rs | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/crates/eval/src/trace.rs b/crates/eval/src/trace.rs index 22c453f96..b458c18f0 100644 --- a/crates/eval/src/trace.rs +++ b/crates/eval/src/trace.rs @@ -1,7 +1,9 @@ use crate::fork::ForkTypedReturn; use alloy::primitives::{Address, U256}; +use foundry_evm::executors::RawCallResult; use rain_interpreter_bindings::IInterpreterV3::{eval3Call, eval3Return}; +use revm::primitives::bitvec::vec; use thiserror::Error; pub const RAIN_TRACER_ADDRESS: &str = "0xF06Cd48c98d7321649dB7D8b2C396A81A2046555"; @@ -56,13 +58,11 @@ pub struct RainEvalResult { pub traces: Vec, } -impl From> for RainEvalResult { - fn from(typed_return: ForkTypedReturn) -> Self { - let eval3Return { stack, writes } = typed_return.typed_return; - +impl From for RainEvalResult { + fn from(raw_call_result: RawCallResult) -> Self { let tracer_address = RAIN_TRACER_ADDRESS.parse::
().unwrap(); - let mut traces: Vec = typed_return - .raw + + let mut traces: Vec = raw_call_result .traces .unwrap() .to_owned() @@ -79,10 +79,25 @@ impl From> for RainEvalResult { traces.reverse(); RainEvalResult { - reverted: typed_return.raw.reverted, + reverted: raw_call_result.reverted, + stack: vec![], + writes: vec![], + traces, + } + } +} + +impl From> for RainEvalResult { + fn from(typed_return: ForkTypedReturn) -> Self { + let eval3Return { stack, writes } = typed_return.typed_return; + + let res: RainEvalResult = typed_return.raw.into(); + + RainEvalResult { + reverted: res.reverted, stack, writes, - traces, + traces: res.traces, } } } From 747028856cd09fcac51f421fe460c3cd44a2d26f Mon Sep 17 00:00:00 2001 From: highonhopium Date: Wed, 28 Aug 2024 21:55:02 +0100 Subject: [PATCH 5/8] fix --- crates/eval/src/fork.rs | 133 ++++++++++++++++++++++++++++------------ 1 file changed, 93 insertions(+), 40 deletions(-) diff --git a/crates/eval/src/fork.rs b/crates/eval/src/fork.rs index d507a0954..e50ab2ecb 100644 --- a/crates/eval/src/fork.rs +++ b/crates/eval/src/fork.rs @@ -376,7 +376,7 @@ impl Forker { let block_number = block_number .map(BlockNumber::from) .unwrap_or(org_block_number.unwrap()); - + self.executor.env_mut().block.number = U256::from(block_number); self.executor @@ -399,31 +399,64 @@ impl Forker { &mut self, tx_hash: B256, ) -> Result { + let fork_url = self + .executor + .backend() + .active_fork_url() + .unwrap_or("No fork url found".to_string()); - let fork_url = self.executor.backend().active_fork_url().unwrap_or("No fork url found".to_string()); - // get the transaction - let shared_backend = &self.executor.backend().active_fork_db().ok_or(ForkCallError::ReplayTransactionError(ReplayTransactionError::NoActiveFork))?.db; - let full_tx = shared_backend.get_transaction(tx_hash).map_err(|e| ForkCallError::ReplayTransactionError(ReplayTransactionError::DatabaseError(tx_hash.to_string(), fork_url.clone(), e)))?; - + let shared_backend = &self + .executor + .backend() + .active_fork_db() + .ok_or(ForkCallError::ReplayTransactionError( + ReplayTransactionError::NoActiveFork, + ))? + .db; + let full_tx = shared_backend.get_transaction(tx_hash).map_err(|e| { + ForkCallError::ReplayTransactionError(ReplayTransactionError::DatabaseError( + tx_hash.to_string(), + fork_url.clone(), + e, + )) + })?; + // get the block number from the transaction - let block_number = full_tx.block_number.ok_or(ForkCallError::ReplayTransactionError(ReplayTransactionError::NoBlockNumberFound(tx_hash.to_string(), fork_url.clone())))?; - - // get the block - let block = shared_backend.get_full_block(block_number).map_err(|e| ForkCallError::ReplayTransactionError(ReplayTransactionError::DatabaseError(block_number.to_string(), fork_url.clone(), e)))?; - - let _ = &self.add_or_select(NewForkedEvm { fork_url: fork_url.clone(), fork_block_number: Some(block_number - 1) }, None).await; + let block_number = full_tx + .block_number + .ok_or(ForkCallError::ReplayTransactionError( + ReplayTransactionError::NoBlockNumberFound(tx_hash.to_string(), fork_url.clone()), + ))?; - let mut env = self.executor.env().clone(); + // get the block + let block = shared_backend.get_full_block(block_number).map_err(|e| { + ForkCallError::ReplayTransactionError(ReplayTransactionError::DatabaseError( + block_number.to_string(), + fork_url.clone(), + e, + )) + })?; // matching env to the env from the block the transaction is in - env.block.timestamp = U256::from(block.header.timestamp); - env.block.coinbase = block.header.miner; - env.block.difficulty = block.header.difficulty; - env.block.prevrandao = Some(block.header.mix_hash.unwrap_or_default()); - env.block.basefee = U256::from(block.header.base_fee_per_gas.unwrap_or_default()); - env.block.gas_limit = U256::from(block.header.gas_limit); - env.block.number = U256::from(block.header.number.unwrap_or(block_number)); + self.executor.env_mut().block.number = U256::from(block_number); + self.executor.env_mut().block.timestamp = U256::from(block.header.timestamp); + self.executor.env_mut().block.coinbase = block.header.miner; + self.executor.env_mut().block.difficulty = block.header.difficulty; + self.executor.env_mut().block.prevrandao = Some(block.header.mix_hash.unwrap_or_default()); + self.executor.env_mut().block.basefee = + U256::from(block.header.base_fee_per_gas.unwrap_or_default()); + self.executor.env_mut().block.gas_limit = U256::from(block.header.gas_limit); + + let _ = &self + .add_or_select( + NewForkedEvm { + fork_url: fork_url.clone(), + fork_block_number: Some(block_number - 1), + }, + None, + ) + .await; let active_fork_local_id = self .executor @@ -433,24 +466,30 @@ impl Forker { let mut journaled_state = JournaledState::new(SpecId::LATEST, HashSet::new()); + let env = self.executor.env().clone(); + // replay all transactions that came before - let tx = self.executor - .backend_mut() - .replay_until( - active_fork_local_id, - env, - tx_hash, - &mut journaled_state, - )?; - + let tx = self.executor.backend_mut().replay_until( + active_fork_local_id, + env, + tx_hash, + &mut journaled_state, + )?; + let res = match tx { - Some(tx) => { - match tx.to { - Some(to) => self.call(tx.from.as_slice(), to.as_slice(), &tx.input)?, - None => return Err(ForkCallError::ReplayTransactionError(ReplayTransactionError::NoFromAddressFound(tx_hash.to_string(), fork_url))) + Some(tx) => match tx.to { + Some(to) => self.call(tx.from.as_slice(), to.as_slice(), &tx.input)?, + None => { + return Err(ForkCallError::ReplayTransactionError( + ReplayTransactionError::NoFromAddressFound(tx_hash.to_string(), fork_url), + )) } + }, + None => { + return Err(ForkCallError::ReplayTransactionError( + ReplayTransactionError::TransactionNotFound(tx_hash.to_string(), fork_url), + )) } - None => return Err(ForkCallError::ReplayTransactionError(ReplayTransactionError::TransactionNotFound(tx_hash.to_string(), fork_url))) }; Ok(res) @@ -460,7 +499,10 @@ impl Forker { #[cfg(test)] mod tests { - use crate::namespace::CreateNamespace; + use crate::{ + namespace::CreateNamespace, + trace::{RainEvalResult, RainSourceTrace}, + }; use rain_interpreter_env::{ CI_DEPLOY_SEPOLIA_RPC_URL, CI_FORK_SEPOLIA_BLOCK_NUMBER, CI_FORK_SEPOLIA_DEPLOYER_ADDRESS, }; @@ -733,10 +775,16 @@ mod tests { #[tokio::test(flavor = "multi_thread", worker_threads = 1)] async fn test_fork_replay() { - let mut forker = Forker::new_with_fork(NewForkedEvm { - fork_url: CI_DEPLOY_SEPOLIA_RPC_URL.to_string(), - fork_block_number: None, - }, None, None).await.unwrap(); + let mut forker = Forker::new_with_fork( + NewForkedEvm { + fork_url: CI_DEPLOY_SEPOLIA_RPC_URL.to_string(), + fork_block_number: None, + }, + None, + None, + ) + .await + .unwrap(); let tx_hash = "0xcbfff7d9369afcc7a851dff42ca2769f32d77c3b9066023b887583ee9cd0809d" .parse::() @@ -744,7 +792,12 @@ mod tests { let replay_result = forker.replay_transaction(tx_hash).await.unwrap(); - assert!(replay_result.env.tx.caller == "0x8924274F5304277FFDdd29fad5181D98D5F65eF6".parse::
().unwrap()); + assert!( + replay_result.env.tx.caller + == "0x8924274F5304277FFDdd29fad5181D98D5F65eF6" + .parse::
() + .unwrap() + ); assert!(replay_result.exit_reason.is_ok()); } } From 377def2d5f4f8b6cec4721999a028aa07190d6a7 Mon Sep 17 00:00:00 2001 From: highonhopium Date: Thu, 29 Aug 2024 13:18:12 +0100 Subject: [PATCH 6/8] rm unused --- crates/eval/src/trace.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/crates/eval/src/trace.rs b/crates/eval/src/trace.rs index b458c18f0..95428ca19 100644 --- a/crates/eval/src/trace.rs +++ b/crates/eval/src/trace.rs @@ -2,8 +2,6 @@ use crate::fork::ForkTypedReturn; use alloy::primitives::{Address, U256}; use foundry_evm::executors::RawCallResult; use rain_interpreter_bindings::IInterpreterV3::{eval3Call, eval3Return}; - -use revm::primitives::bitvec::vec; use thiserror::Error; pub const RAIN_TRACER_ADDRESS: &str = "0xF06Cd48c98d7321649dB7D8b2C396A81A2046555"; From 0fe1c8e0e6527b2daee01d3578f0426802972dd1 Mon Sep 17 00:00:00 2001 From: highonhopium Date: Thu, 29 Aug 2024 14:26:13 +0100 Subject: [PATCH 7/8] wasm --- crates/eval/src/error.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/eval/src/error.rs b/crates/eval/src/error.rs index 456ca7e94..07b48cba1 100644 --- a/crates/eval/src/error.rs +++ b/crates/eval/src/error.rs @@ -1,6 +1,6 @@ use alloy::primitives::ruint::FromUintError; -use foundry_evm::backend::DatabaseError; #[cfg(not(target_family = "wasm"))] +use foundry_evm::backend::DatabaseError; use foundry_evm::executors::RawCallResult; use rain_error_decoding::{AbiDecodeFailedErrors, AbiDecodedErrorType}; use thiserror::Error; From e1f64eec68c2c83626b93c5ed4696e23c62861c4 Mon Sep 17 00:00:00 2001 From: highonhopium Date: Thu, 29 Aug 2024 14:54:24 +0100 Subject: [PATCH 8/8] wasm --- crates/eval/src/error.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/crates/eval/src/error.rs b/crates/eval/src/error.rs index 07b48cba1..f9230c7b9 100644 --- a/crates/eval/src/error.rs +++ b/crates/eval/src/error.rs @@ -1,6 +1,7 @@ use alloy::primitives::ruint::FromUintError; #[cfg(not(target_family = "wasm"))] use foundry_evm::backend::DatabaseError; +#[cfg(not(target_family = "wasm"))] use foundry_evm::executors::RawCallResult; use rain_error_decoding::{AbiDecodeFailedErrors, AbiDecodedErrorType}; use thiserror::Error; @@ -34,6 +35,7 @@ pub enum ReplayTransactionError { TransactionNotFound(String, String), #[error("No active fork found")] NoActiveFork, + #[cfg(not(target_family = "wasm"))] #[error("Database error for hash {0} and fork url {1}: {2}")] DatabaseError(String, String, DatabaseError), #[error("No block number found in transaction for hash {0} and fork url {1}")]