From cd90045a6e0810ee2d2c338113ab442c38c59f20 Mon Sep 17 00:00:00 2001 From: Ape Dev Date: Thu, 20 Jul 2023 16:37:31 +0200 Subject: [PATCH] draft: allow simulations within a block --- src/simulation.rs | 67 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 64 insertions(+), 3 deletions(-) diff --git a/src/simulation.rs b/src/simulation.rs index 989b214..40ebdd9 100644 --- a/src/simulation.rs +++ b/src/simulation.rs @@ -4,7 +4,8 @@ use std::sync::Arc; use dashmap::mapref::one::RefMut; use ethers::abi::{Address, Uint}; use ethers::core::types::Log; -use ethers::types::Bytes; +use ethers::providers::{Http, Middleware, Provider}; +use ethers::types::{Bytes, H256}; use foundry_evm::CallKind; use revm::interpreter::InstructionResult; use serde::{Deserialize, Serialize}; @@ -37,6 +38,8 @@ pub struct SimulationRequest { pub block_number: Option, #[serde(rename = "formatTrace")] pub format_trace: Option, + #[serde(rename = "transactionBlockIndex")] + pub transaction_block_index: Option, } #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] @@ -208,7 +211,7 @@ pub async fn simulate_bundle( .unwrap_or(chain_id_to_fork_url(first_chain_id)?); let mut evm = Evm::new( None, - fork_url, + fork_url.clone(), first_block_number, transactions[0].gas_limit, true, @@ -239,7 +242,65 @@ pub async fn simulate_bundle( .await .expect("Failed to set block timestamp"); } - response.push(run(&mut evm, transaction, true).await?); + + if transaction.clone().transaction_block_index.is_some() + { + let provider = Provider::::try_from(&fork_url); + let pre_transactions = provider + .unwrap() + .get_block_with_txs( + transaction + .clone() + .block_number + .expect("Transaction has no block number"), + ) + .await + .unwrap() + .unwrap(); + let relevant_transactions: Vec<_> = pre_transactions + .transactions + .iter() + .map(|x| SimulationRequest { + chain_id: x.chain_id.unwrap().as_u64(), + from: x.from, + to: x.to.unwrap(), + value: Some(x.value.to_string()), + data: Some(x.input.clone()), + gas_limit: x.gas.as_u64(), + block_number: None, + format_trace: None, + transaction_block_index: None, + }) + .collect(); + + let transaction_block_index = transaction.clone().transaction_block_index.unwrap(); + let transactions_before_index = relevant_transactions + .iter() + .take(transaction_block_index as usize) + .collect::>(); + + let transactions_after_index = relevant_transactions.iter().skip( + transaction_block_index + .checked_add(1) + .expect("Overflow") + as usize, + ); + + for before_tx in transactions_before_index { + let result = run(&mut evm, before_tx.clone(), true).await; + result.expect("Failed to run transactions in block prior to transaction index"); + } + + response.push(run(&mut evm, transaction, true).await?); + + for after_tx in transactions_after_index { + let result = run(&mut evm, after_tx.clone(), true).await; + result.expect("Failed to run transactions in block after transaction index"); + } + + } else { + response.push(run(&mut evm, transaction, true).await?); + } } Ok(warp::reply::json(&response))