diff --git a/crates/common/src/transactions/receipt.rs b/crates/common/src/transactions/receipt.rs index ea657f2ea352d..363eaedca8cea 100644 --- a/crates/common/src/transactions/receipt.rs +++ b/crates/common/src/transactions/receipt.rs @@ -1,12 +1,32 @@ use alloy_network::{AnyNetwork, AnyTransactionReceipt, Network, TransactionResponse}; +use alloy_primitives::Address; use alloy_provider::{ Provider, network::{ReceiptResponse, TransactionBuilder}, }; -use alloy_rpc_types::BlockId; +use alloy_rpc_types::{BlockId, TransactionReceipt}; use eyre::Result; use foundry_common_fmt::{UIfmt, UIfmtReceiptExt, get_pretty_receipt_attr}; use serde::{Deserialize, Serialize}; +use tempo_alloy::rpc::TempoTransactionReceipt; + +/// Helper trait providing `contract_address` setter for generic `ReceiptResponse` +pub trait FoundryReceiptResponse { + /// Sets address of the created contract, or `None` if the transaction was not a deployment. + fn set_contract_address(&mut self, contract_address: Address); +} + +impl FoundryReceiptResponse for TransactionReceipt { + fn set_contract_address(&mut self, contract_address: Address) { + self.contract_address = Some(contract_address); + } +} + +impl FoundryReceiptResponse for TempoTransactionReceipt { + fn set_contract_address(&mut self, contract_address: Address) { + self.contract_address = Some(contract_address); + } +} /// Helper type to carry a transaction along with an optional revert reason #[derive(Clone, Debug, Serialize, Deserialize)] diff --git a/crates/evm/core/src/evm.rs b/crates/evm/core/src/evm.rs index 965517c36c6ba..77afe8e7d84da 100644 --- a/crates/evm/core/src/evm.rs +++ b/crates/evm/core/src/evm.rs @@ -9,15 +9,17 @@ use crate::{ backend::{DatabaseExt, JournaledState, LocalForkId}, constants::DEFAULT_CREATE2_DEPLOYER_CODEHASH, }; -use alloy_consensus::{constants::KECCAK_EMPTY, transaction::SignerRecoverable}; +use alloy_consensus::{ + SignableTransaction, Signed, constants::KECCAK_EMPTY, transaction::SignerRecoverable, +}; use alloy_evm::{ EthEvmFactory, Evm, EvmEnv, EvmFactory, FromRecoveredTx, eth::EthEvmContext, precompiles::PrecompilesMap, }; use alloy_network::{Ethereum, Network}; -use alloy_primitives::{Address, B256, Bytes, U256}; +use alloy_primitives::{Address, B256, Bytes, Signature, U256}; use alloy_rlp::Decodable; -use foundry_common::FoundryTransactionBuilder; +use foundry_common::{FoundryReceiptResponse, FoundryTransactionBuilder, fmt::UIfmt}; use foundry_config::FromEvmVersion; use foundry_fork_db::{DatabaseError, ForkBlockEnv}; use op_revm::OpHaltReason; @@ -38,6 +40,7 @@ use revm::{ }, primitives::hardfork::SpecId, }; +use serde::{Deserialize, Serialize}; use tempo_alloy::TempoNetwork; use tempo_chainspec::hardfork::TempoHardfork; use tempo_evm::evm::TempoEvmFactory; @@ -78,8 +81,17 @@ impl IntoInstructionResult for TempoHaltReason { /// Foundry's supertrait associating [Network] with [FoundryEvmFactory] pub trait FoundryEvmNetwork: Copy + Debug + Default + 'static { type Network: Network< - TxEnvelope: Decodable + SignerRecoverable, - TransactionRequest: FoundryTransactionBuilder, + TxEnvelope: Decodable + + SignerRecoverable + + From::UnsignedTx>> + + for<'d> Deserialize<'d> + + Serialize + + UIfmt, + UnsignedTx: SignableTransaction, + TransactionRequest: FoundryTransactionBuilder + + for<'d> Deserialize<'d> + + Serialize, + ReceiptResponse: FoundryReceiptResponse, >; type EvmFactory: FoundryEvmFactory::TxEnvelope>>; } diff --git a/crates/script/src/broadcast.rs b/crates/script/src/broadcast.rs index 4a971041922cf..65612ed11888c 100644 --- a/crates/script/src/broadcast.rs +++ b/crates/script/src/broadcast.rs @@ -25,11 +25,10 @@ use foundry_common::{ shell, }; use foundry_config::Config; -use foundry_evm::core::evm::EthEvmNetwork; +use foundry_evm::core::evm::FoundryEvmNetwork; use foundry_wallets::{TempoAccessKeyConfig, WalletSigner, wallet_browser::signer::BrowserSigner}; use futures::{FutureExt, StreamExt, future::join_all, stream::FuturesUnordered}; use itertools::Itertools; -use serde::{Deserialize, Serialize}; pub async fn estimate_gas>( tx: &mut N::TransactionRequest, @@ -265,24 +264,16 @@ impl SendTransactionsKind { /// State after we have bundled all /// [`TransactionWithMetadata`](forge_script_sequence::TransactionWithMetadata) objects into a /// single [`ScriptSequenceKind`] object containing one or more script sequences. -pub struct BundledState -where - N::TxEnvelope: for<'d> Deserialize<'d> + Serialize, - N::TransactionRequest: for<'d> Deserialize<'d> + Serialize, -{ +pub struct BundledState { pub args: ScriptArgs, - pub script_config: ScriptConfig, + pub script_config: ScriptConfig, pub script_wallets: Wallets, - pub browser_wallet: Option>, + pub browser_wallet: Option>, pub build_data: LinkedBuildData, - pub sequence: ScriptSequenceKind, + pub sequence: ScriptSequenceKind, } -impl BundledState -where - N::TxEnvelope: for<'d> Deserialize<'d> + Serialize, - N::TransactionRequest: for<'d> Deserialize<'d> + Serialize, -{ +impl BundledState { pub async fn wait_for_pending(mut self) -> Result { let progress = ScriptProgress::default(); let progress_ref = &progress; @@ -317,12 +308,7 @@ where } /// Broadcasts transactions from all sequences. - pub async fn broadcast(mut self) -> Result> - where - N::TxEnvelope: From>, - N::UnsignedTx: SignableTransaction, - N::TransactionRequest: FoundryTransactionBuilder, - { + pub async fn broadcast(mut self) -> Result> { let required_addresses = self .sequence .sequences() diff --git a/crates/script/src/build.rs b/crates/script/src/build.rs index 1dd0250843b45..bf8cfcddf6f64 100644 --- a/crates/script/src/build.rs +++ b/crates/script/src/build.rs @@ -2,7 +2,7 @@ use crate::{ ScriptArgs, ScriptConfig, broadcast::BundledState, execute::LinkedState, multi_sequence::MultiChainSequence, sequence::ScriptSequenceKind, }; -use alloy_network::{AnyNetwork, Ethereum}; +use alloy_network::AnyNetwork; use alloy_primitives::{B256, Bytes}; use alloy_provider::Provider; use eyre::{OptionExt, Result}; @@ -18,7 +18,7 @@ use foundry_compilers::{ info::ContractInfo, utils::source_files_iter, }; -use foundry_evm::{core::evm::EthEvmNetwork, traces::debug::ContractSources}; +use foundry_evm::{core::evm::FoundryEvmNetwork, traces::debug::ContractSources}; use foundry_linking::Linker; use foundry_wallets::wallet_browser::signer::BrowserSigner; use std::{path::PathBuf, str::FromStr, sync::Arc}; @@ -41,9 +41,9 @@ impl BuildData { /// Links contracts. Uses CREATE2 linking when possible, otherwise falls back to /// default linking with sender nonce and address. - pub async fn link( + pub async fn link( self, - script_config: &ScriptConfig, + script_config: &ScriptConfig, ) -> Result { let create2_deployer = script_config.evm_opts.create2_deployer; let can_use_create2 = if let Some(fork_url) = &script_config.evm_opts.fork_url { @@ -157,17 +157,17 @@ impl LinkedBuildData { } /// First state basically containing only inputs of the user. -pub struct PreprocessedState { +pub struct PreprocessedState { pub args: ScriptArgs, - pub script_config: ScriptConfig, + pub script_config: ScriptConfig, pub script_wallets: Wallets, - pub browser_wallet: Option>, + pub browser_wallet: Option>, } -impl PreprocessedState { +impl PreprocessedState { /// Parses user input and compiles the contracts depending on script target. /// After compilation, finds exact [ArtifactId] of the target contract. - pub fn compile(self) -> Result { + pub fn compile(self) -> Result> { let Self { args, script_config, script_wallets, browser_wallet } = self; let project = script_config.config.project()?; @@ -243,17 +243,17 @@ impl PreprocessedState { } /// State after we have determined and compiled target contract to be executed. -pub struct CompiledState { +pub struct CompiledState { pub args: ScriptArgs, - pub script_config: ScriptConfig, + pub script_config: ScriptConfig, pub script_wallets: Wallets, - pub browser_wallet: Option>, + pub browser_wallet: Option>, pub build_data: BuildData, } -impl CompiledState { +impl CompiledState { /// Uses provided sender address to compute library addresses and link contracts with them. - pub async fn link(self) -> Result { + pub async fn link(self) -> Result> { let Self { args, script_config, script_wallets, browser_wallet, build_data } = self; let build_data = build_data.link(&script_config).await?; @@ -262,7 +262,7 @@ impl CompiledState { } /// Tries loading the resumed state from the cache files, skipping simulation stage. - pub async fn resume(self) -> Result> { + pub async fn resume(self) -> Result> { let chain = if self.args.multi { None } else { @@ -358,7 +358,7 @@ impl CompiledState { &self, chain: Option, dry_run: bool, - ) -> Result> { + ) -> Result> { if let Some(chain) = chain { let sequence = ScriptSequence::load( &self.script_config.config, diff --git a/crates/script/src/execute.rs b/crates/script/src/execute.rs index 574181faffa22..68df630bd1127 100644 --- a/crates/script/src/execute.rs +++ b/crates/script/src/execute.rs @@ -6,13 +6,13 @@ use crate::{ }; use alloy_dyn_abi::FunctionExt; use alloy_json_abi::{Function, InternalType, JsonAbi}; -use alloy_network::{AnyNetwork, Ethereum, Network}; +use alloy_network::{AnyNetwork, Network, TransactionBuilder}; use alloy_primitives::{ Address, Bytes, map::{HashMap, HashSet}, }; use alloy_provider::Provider; -use alloy_rpc_types::TransactionInput; +use alloy_rpc_types::TransactionInputKind; use eyre::{OptionExt, Result}; use foundry_cheatcodes::Wallets; use foundry_cli::utils::{ensure_clean_constructor, needs_setup}; @@ -24,7 +24,7 @@ use foundry_common::{ use foundry_config::NamedChain; use foundry_debugger::Debugger; use foundry_evm::{ - core::evm::EthEvmNetwork, + core::evm::FoundryEvmNetwork, decode::decode_console_logs, inspectors::cheatcodes::BroadcastableTransactions, traces::{ @@ -41,11 +41,11 @@ use yansi::Paint; /// State after linking, contains the linked build data along with library addresses and optional /// array of libraries that need to be predeployed. -pub struct LinkedState { +pub struct LinkedState { pub args: ScriptArgs, - pub script_config: ScriptConfig, + pub script_config: ScriptConfig, pub script_wallets: Wallets, - pub browser_wallet: Option>, + pub browser_wallet: Option>, pub build_data: LinkedBuildData, } @@ -62,10 +62,10 @@ pub struct ExecutionData { pub abi: JsonAbi, } -impl LinkedState { +impl LinkedState { /// Given linked and compiled artifacts, prepares data we need for execution. /// This includes the function to call and the calldata to pass to it. - pub async fn prepare_execution(self) -> Result { + pub async fn prepare_execution(self) -> Result> { let Self { args, script_config, script_wallets, browser_wallet, build_data } = self; let target_contract = build_data.get_target_contract()?; @@ -94,19 +94,19 @@ impl LinkedState { /// Same as [LinkedState], but also contains [ExecutionData]. #[derive(Debug)] -pub struct PreExecutionState { +pub struct PreExecutionState { pub args: ScriptArgs, - pub script_config: ScriptConfig, + pub script_config: ScriptConfig, pub script_wallets: Wallets, - pub browser_wallet: Option>, + pub browser_wallet: Option>, pub build_data: LinkedBuildData, pub execution_data: ExecutionData, } -impl PreExecutionState { +impl PreExecutionState { /// Executes the script and returns the state after execution. /// Might require executing script twice in cases when we determine sender from execution. - pub async fn execute(mut self) -> Result { + pub async fn execute(mut self) -> Result> { let mut runner = self .script_config .get_runner_with_cheatcodes( @@ -149,8 +149,8 @@ impl PreExecutionState { /// Executes the script using the provided runner and returns the [ScriptResult]. pub async fn execute_with_runner( &self, - runner: &mut ScriptRunner, - ) -> Result> { + runner: &mut ScriptRunner, + ) -> Result> { let (address, mut setup_result) = runner.setup( &self.build_data.predeploy_libraries, self.execution_data.bytecode.clone(), @@ -190,7 +190,7 @@ impl PreExecutionState { /// them instead. fn maybe_new_sender( &self, - transactions: Option<&BroadcastableTransactions>, + transactions: Option<&BroadcastableTransactions>, ) -> Result> { let mut new_sender = None; @@ -230,7 +230,7 @@ pub struct RpcData { impl RpcData { /// Iterates over script transactions and collects RPC urls. - fn from_transactions(txs: &BroadcastableTransactions) -> Self { + fn from_transactions(txs: &BroadcastableTransactions) -> Self { let missing_rpc = txs.iter().any(|tx| tx.rpc.is_none()); let total_rpcs = txs.iter().filter_map(|tx| tx.rpc.as_ref().cloned()).collect::>(); @@ -282,32 +282,33 @@ pub struct ExecutionArtifacts { } /// State after the script has been executed. -pub struct ExecutedState { +pub struct ExecutedState { pub args: ScriptArgs, - pub script_config: ScriptConfig, + pub script_config: ScriptConfig, pub script_wallets: Wallets, - pub browser_wallet: Option>, + pub browser_wallet: Option>, pub build_data: LinkedBuildData, pub execution_data: ExecutionData, - pub execution_result: ScriptResult, + pub execution_result: ScriptResult, } -impl ExecutedState { +impl ExecutedState { /// Collects the data we need for simulation and various post-execution tasks. - pub async fn prepare_simulation(self) -> Result> { + pub async fn prepare_simulation(self) -> Result> { let returns = self.get_returns()?; let decoder = self.build_trace_decoder(&self.build_data.known_contracts).await?; - let mut txs: BroadcastableTransactions = + let mut txs: BroadcastableTransactions = self.execution_result.transactions.clone().unwrap_or_default(); // Ensure that unsigned transactions have both `data` and `input` populated to avoid // issues with eth_estimateGas and eth_sendTransaction requests. for tx in &mut txs { - if let Some(req) = tx.transaction.as_unsigned_mut() { - req.input = - TransactionInput::maybe_both(std::mem::take(&mut req.input).into_input()); + if let Some(req) = tx.transaction.as_unsigned_mut() + && let Some(input) = req.input().cloned() + { + *req = req.clone().with_input_kind(input, TransactionInputKind::Both); } } let rpc_data = RpcData::from_transactions(&txs); @@ -400,7 +401,7 @@ impl ExecutedState { } } -impl PreSimulationState { +impl PreSimulationState { pub async fn show_json(&self) -> Result<()> { let mut result = self.execution_result.clone(); diff --git a/crates/script/src/lib.rs b/crates/script/src/lib.rs index 357df58ce6f89..4f15c4b05dea7 100644 --- a/crates/script/src/lib.rs +++ b/crates/script/src/lib.rs @@ -2,6 +2,7 @@ //! //! Smart contract scripting. +#![recursion_limit = "256"] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg))] @@ -13,7 +14,7 @@ extern crate tracing; use crate::runner::ScriptRunner; use alloy_json_abi::{Function, JsonAbi}; -use alloy_network::{Ethereum, Network}; +use alloy_network::Network; use alloy_primitives::{ Address, Bytes, Log, U256, hex, map::{AddressHashMap, HashMap}, @@ -45,7 +46,10 @@ use foundry_config::{ }; use foundry_evm::{ backend::Backend, - core::{Breakpoints, evm::FoundryEvmNetwork}, + core::{ + Breakpoints, + evm::{EthEvmNetwork, FoundryEvmNetwork, TempoEvmNetwork}, + }, executors::ExecutorBuilder, inspectors::{ CheatsConfig, @@ -227,9 +231,9 @@ pub struct ScriptArgs { } impl ScriptArgs { - pub async fn preprocess(self) -> Result { + pub async fn preprocess(self) -> Result> { let script_wallets = Wallets::new(self.wallets.get_multi_wallet().await?, self.evm.sender); - let browser_wallet = self.wallets.browser_signer::().await?; + let browser_wallet = self.wallets.browser_signer::().await?; let (config, mut evm_opts) = self.load_config_and_evm_opts()?; @@ -257,7 +261,15 @@ impl ScriptArgs { pub async fn run_script(self) -> Result<()> { trace!(target: "script", "executing script command"); - let state = self.preprocess().await?; + if self.load_config_and_evm_opts()?.1.networks.is_tempo() { + self.run_generic_script::().await + } else { + self.run_generic_script::().await + } + } + + async fn run_generic_script(self) -> Result<()> { + let state = self.preprocess::().await?; let create2_deployer = state.script_config.evm_opts.create2_deployer; let compiled = state.compile()?; @@ -415,9 +427,9 @@ impl ScriptArgs { /// /// If `self.broadcast` is enabled, it asks confirmation of the user. Otherwise, it just warns /// the user. - fn check_contract_sizes( + fn check_contract_sizes( &self, - result: &ScriptResult, + result: &ScriptResult, known_contracts: &ContractsByArtifact, create2_deployer: Address, ) -> Result<()> { @@ -713,6 +725,7 @@ impl ScriptConfig { #[cfg(test)] mod tests { use super::*; + use alloy_network::Ethereum; use foundry_config::{NamedChain, UnresolvedEnvVarError}; use std::fs; use tempfile::tempdir; @@ -766,7 +779,7 @@ mod tests { ScriptArgs::parse_from(["foundry-cli", "Contract.sol", "--disable-code-size-limit"]); assert!(args.disable_code_size_limit); - let result = ScriptResult::default(); + let result = ScriptResult::::default(); let contracts = ContractsByArtifact::default(); let create = Address::ZERO; assert!(args.check_contract_sizes(&result, &contracts, create).is_ok()); diff --git a/crates/script/src/receipts.rs b/crates/script/src/receipts.rs index 217cfc36c088a..dc6f8755d042b 100644 --- a/crates/script/src/receipts.rs +++ b/crates/script/src/receipts.rs @@ -1,27 +1,14 @@ use alloy_chains::{Chain, NamedChain}; use alloy_network::{Network, ReceiptResponse}; -use alloy_primitives::{Address, TxHash, U256, utils::format_units}; +use alloy_primitives::{TxHash, U256, utils::format_units}; use alloy_provider::{ PendingTransactionBuilder, PendingTransactionError, Provider, RootProvider, WatchTxError, }; -use alloy_rpc_types::TransactionReceipt; use eyre::{Result, eyre}; use forge_script_sequence::ScriptSequence; use foundry_common::{retry, retry::RetryError, shell}; use std::time::Duration; -/// Helper trait providing `contract_address` setter for generic `ReceiptResponse` -pub trait FoundryReceiptResponse { - /// Sets address of the created contract, or `None` if the transaction was not a deployment. - fn set_contract_address(&mut self, contract_address: Address); -} - -impl FoundryReceiptResponse for TransactionReceipt { - fn set_contract_address(&mut self, contract_address: Address) { - self.contract_address = Some(contract_address); - } -} - /// Marker error type for pending receipts #[derive(Debug, thiserror::Error)] #[error( @@ -196,6 +183,7 @@ mod tests { use super::*; use alloy_network::Ethereum; use alloy_primitives::B256; + use alloy_rpc_types::TransactionReceipt; use std::collections::VecDeque; fn mock_receipt(tx_hash: B256, success: bool) -> TransactionReceipt { diff --git a/crates/script/src/simulate.rs b/crates/script/src/simulate.rs index 42fdce5661210..2d942670af066 100644 --- a/crates/script/src/simulate.rs +++ b/crates/script/src/simulate.rs @@ -10,22 +10,22 @@ use crate::{ sequence::get_commit_hash, }; use alloy_chains::NamedChain; -use alloy_network::{Network, TransactionBuilder}; +use alloy_evm::revm::context::Block; +use alloy_network::TransactionBuilder; use alloy_primitives::{Address, U256, map::HashMap, utils::format_units}; use dialoguer::Confirm; use eyre::{Context, Result}; use forge_script_sequence::{ScriptSequence, TransactionWithMetadata}; use foundry_cheatcodes::Wallets; use foundry_cli::utils::{has_different_gas_calc, now}; -use foundry_common::{ContractData, FoundryTransactionBuilder, shell}; +use foundry_common::{ContractData, shell}; use foundry_evm::{ - core::evm::EthEvmNetwork, + core::{FoundryBlock, evm::FoundryEvmNetwork}, traces::{decode_trace_arena, render_trace_arena}, }; use foundry_wallets::wallet_browser::signer::BrowserSigner; use futures::future::{join_all, try_join_all}; use parking_lot::RwLock; -use serde::{Deserialize, Serialize}; use std::{ collections::{BTreeMap, VecDeque}, mem, @@ -37,27 +37,24 @@ use std::{ /// /// Can be either converted directly to [BundledState] or driven to it through /// [FilledTransactionsState]. -pub struct PreSimulationState { +pub struct PreSimulationState { pub args: ScriptArgs, - pub script_config: ScriptConfig, + pub script_config: ScriptConfig, pub script_wallets: Wallets, - pub browser_wallet: Option>, + pub browser_wallet: Option>, pub build_data: LinkedBuildData, pub execution_data: ExecutionData, - pub execution_result: ScriptResult, + pub execution_result: ScriptResult, pub execution_artifacts: ExecutionArtifacts, } -impl PreSimulationState -where - N::TransactionRequest: FoundryTransactionBuilder, -{ +impl PreSimulationState { /// If simulation is enabled, simulates transactions against fork and fills gas estimation and /// metadata. Otherwise, metadata (e.g. additional contracts, created contract names) is /// left empty. /// /// Both modes will panic if any of the transactions have None for the `rpc` field. - pub async fn fill_metadata(self) -> Result> { + pub async fn fill_metadata(self) -> Result> { let address_to_abi = self.build_address_to_abi_map(); let mut transactions = self @@ -111,8 +108,8 @@ where /// Collects gas usage and metadata for each transaction. pub async fn simulate_and_fill( &self, - transactions: VecDeque>, - ) -> Result>> { + transactions: VecDeque>, + ) -> Result>> { trace!(target: "script", "executing onchain simulation"); let runners = Arc::new( @@ -150,7 +147,8 @@ where // Simulate mining the transaction if the user passes `--slow`. if self.args.slow { - runner.executor.evm_env_mut().block_env.number += U256::from(1); + let block_number = runner.executor.evm_env().block_env.number() + U256::from(1); + runner.executor.evm_env_mut().block_env.set_number(block_number); } let is_noop_tx = if let Some(to) = to { @@ -237,7 +235,7 @@ where } /// Build [ScriptRunner] forking given RPC for each RPC used in the script. - async fn build_runners(&self) -> Result)>> { + async fn build_runners(&self) -> Result)>> { let rpcs = self.execution_artifacts.rpc_data.total_rpcs.clone(); if !shell::is_json() { @@ -259,27 +257,23 @@ where /// At this point we have converted transactions collected during script execution to /// [TransactionWithMetadata] objects which contain additional metadata needed for broadcasting and /// verification. -pub struct FilledTransactionsState { +pub struct FilledTransactionsState { pub args: ScriptArgs, - pub script_config: ScriptConfig, + pub script_config: ScriptConfig, pub script_wallets: Wallets, - pub browser_wallet: Option>, + pub browser_wallet: Option>, pub build_data: LinkedBuildData, pub execution_artifacts: ExecutionArtifacts, - pub transactions: VecDeque>, + pub transactions: VecDeque>, } -impl FilledTransactionsState -where - N::TxEnvelope: for<'d> Deserialize<'d> + Serialize, - N::TransactionRequest: for<'d> Deserialize<'d> + Serialize + FoundryTransactionBuilder, -{ +impl FilledTransactionsState { /// Bundles all transactions of the [`TransactionWithMetadata`] type in a list of /// [`ScriptSequence`]. List length will be higher than 1, if we're dealing with a multi /// chain deployment. /// /// Each transaction will be added with the correct transaction type and gas estimation. - pub async fn bundle(mut self) -> Result> { + pub async fn bundle(mut self) -> Result> { let is_multi_deployment = self.execution_artifacts.rpc_data.total_rpcs.len() > 1; if is_multi_deployment && !self.build_data.libraries.is_empty() { @@ -290,7 +284,7 @@ where // Batches sequence of transactions from different rpcs. let mut new_sequence = VecDeque::new(); - let mut manager = ProvidersManager::::default(); + let mut manager = ProvidersManager::::default(); let mut sequences = vec![]; // Peeking is used to check if the next rpc url is different. If so, it creates a @@ -440,14 +434,14 @@ where &self, multi: bool, chain: u64, - transactions: VecDeque>, - ) -> Result> { + transactions: VecDeque>, + ) -> Result> { // Paths are set to None for multi-chain sequences parts, because they don't need to be // saved to a separate file. let paths = if multi { None } else { - Some(ScriptSequence::::get_paths( + Some(ScriptSequence::::get_paths( &self.script_config.config, &self.args.sig, &self.build_data.build_data.target, diff --git a/crates/script/src/transaction.rs b/crates/script/src/transaction.rs index 6d47be97ecd84..2a2bbf3e47bf0 100644 --- a/crates/script/src/transaction.rs +++ b/crates/script/src/transaction.rs @@ -1,7 +1,7 @@ use super::ScriptResult; use crate::build::LinkedBuildData; use alloy_dyn_abi::JsonAbiExt; -use alloy_network::{Ethereum, Network, TransactionBuilder}; +use alloy_network::{Network, TransactionBuilder}; use alloy_primitives::{Address, B256, hex}; use eyre::Result; use forge_script_sequence::TransactionWithMetadata; @@ -146,7 +146,7 @@ impl ScriptTransactionBuilder { /// Populates additional data from the transaction execution result. pub fn with_execution_result( mut self, - result: &ScriptResult, + result: &ScriptResult, gas_estimate_multiplier: u64, linked_build_data: &LinkedBuildData, ) -> Self { diff --git a/crates/script/src/verify.rs b/crates/script/src/verify.rs index 4b9c1c1f73049..0a2b171b379ba 100644 --- a/crates/script/src/verify.rs +++ b/crates/script/src/verify.rs @@ -1,7 +1,6 @@ use crate::{ ScriptArgs, ScriptConfig, build::LinkedBuildData, - receipts::FoundryReceiptResponse, sequence::{ScriptSequenceKind, get_commit_hash}, }; use alloy_network::{Network, ReceiptResponse}; @@ -10,33 +9,23 @@ use eyre::{Result, eyre}; use forge_script_sequence::{AdditionalContract, ScriptSequence}; use forge_verify::{RetryArgs, VerifierArgs, VerifyArgs, provider::VerificationProviderType}; use foundry_cli::opts::{EtherscanOpts, ProjectPathOpts}; -use foundry_common::ContractsByArtifact; +use foundry_common::{ContractsByArtifact, FoundryReceiptResponse}; use foundry_compilers::{Project, artifacts::EvmVersion, info::ContractInfo}; use foundry_config::{Chain, Config}; -use foundry_evm::core::evm::EthEvmNetwork; +use foundry_evm::core::evm::FoundryEvmNetwork; use semver::Version; -use serde::{Deserialize, Serialize}; /// State after we have broadcasted the script. /// It is assumed that at this point [BroadcastedState::sequence] contains receipts for all /// broadcasted transactions. -pub struct BroadcastedState -where - N::TxEnvelope: for<'d> Deserialize<'d> + Serialize, - N::TransactionRequest: for<'d> Deserialize<'d> + Serialize, -{ +pub struct BroadcastedState { pub args: ScriptArgs, - pub script_config: ScriptConfig, + pub script_config: ScriptConfig, pub build_data: LinkedBuildData, - pub sequence: ScriptSequenceKind, + pub sequence: ScriptSequenceKind, } -impl BroadcastedState -where - N::TxEnvelope: for<'d> Deserialize<'d> + Serialize, - N::TransactionRequest: for<'d> Deserialize<'d> + Serialize, - N::ReceiptResponse: FoundryReceiptResponse, -{ +impl BroadcastedState { pub async fn verify(self) -> Result<()> { let Self { args, script_config, build_data, mut sequence, .. } = self; @@ -49,7 +38,7 @@ where ); for sequence in sequence.sequences_mut() { - verify_contracts(sequence, &script_config.config, verify.clone()).await?; + verify_contracts::(sequence, &script_config.config, verify.clone()).await?; } Ok(()) @@ -191,8 +180,8 @@ impl VerifyBundle { /// Given the broadcast log, it matches transactions with receipts, and tries to verify any /// created contract on etherscan. -async fn verify_contracts>( - sequence: &mut ScriptSequence, +async fn verify_contracts( + sequence: &mut ScriptSequence, config: &Config, mut verify: VerifyBundle, ) -> Result<()> {