diff --git a/crates/core/src/driver/mod.rs b/crates/core/src/driver/mod.rs index d4583a5..581457a 100644 --- a/crates/core/src/driver/mod.rs +++ b/crates/core/src/driver/mod.rs @@ -2,7 +2,8 @@ use alloy::json_abi::JsonAbi; use alloy::primitives::Bytes; -use alloy::rpc::types::TransactionInput; +use alloy::rpc::types::trace::geth::GethTrace; +use alloy::rpc::types::{TransactionInput, TransactionReceipt}; use alloy::{ primitives::{Address, TxKind, map::HashMap}, rpc::types::{ @@ -17,6 +18,7 @@ use revive_dt_node_interaction::EthereumNode; use revive_dt_report::reporter::{CompilationTask, Report, Span}; use revive_solc_json_interface::SolcStandardJsonOutput; use serde_json::Value; +use std::collections::HashMap as StdHashMap; use crate::Platform; @@ -29,8 +31,8 @@ pub struct State<'a, T: Platform> { config: &'a Arguments, span: Span, contracts: Contracts, - deployed_contracts: HashMap, - deployed_abis: HashMap, + deployed_contracts: StdHashMap, + deployed_abis: StdHashMap, } impl<'a, T> State<'a, T> diff --git a/crates/format/src/input.rs b/crates/format/src/input.rs index b88e136..f1ad8f4 100644 --- a/crates/format/src/input.rs +++ b/crates/format/src/input.rs @@ -6,6 +6,8 @@ use alloy::{ primitives::{Address, Bytes, TxKind}, rpc::types::{TransactionInput, TransactionRequest}, }; +use alloy_primitives::U256; +use alloy_sol_types::SolValue; use semver::VersionReq; use serde::{Deserialize, de::Deserializer}; use serde_json::Value; @@ -142,35 +144,68 @@ impl Input { _ => anyhow::bail!("Expected compound calldata for function call"), }; - // Convert each argument - let mut tokens = Vec::new(); - for (i, param) in function.inputs.iter().enumerate() { - let arg = calldata_args - .get(i) - .ok_or_else(|| anyhow::anyhow!("Missing calldata argument {}", i))?; - let token = match arg { - CalldataArg::Literal(value) => match param.ty.to_string().as_str() { - "uint256" | "uint" => Token::Uint(value.parse()?), - "address" => Token::Address(value.parse()?), - _ => anyhow::bail!("Unsupported literal type {}", param.ty), - }, - CalldataArg::AddressRef(name) => { - let addr = if name.ends_with(".address") { - let contract_name = name.trim_end_matches(".address"); - deployed_contracts.get(contract_name).copied() - } else { - None - }; - Token::Address( - addr.ok_or_else(|| anyhow::anyhow!("Address for '{}' not found", name))?, - ) - } - }; - tokens.push(token); + if calldata_args.len() != function.inputs.len() { + anyhow::bail!( + "Function expects {} args, but got {}", + function.inputs.len(), + calldata_args.len() + ); + } + + let mut encoded = selector.to_vec(); + + for (i, param) in function.inputs.iter().enumerate() { + let arg = calldata_args.get(i).unwrap(); + let encoded_arg = match arg { + CalldataArg::Literal(value) => match param.ty.as_str() { + "uint256" | "uint" => { + let val: U256 = value.parse()?; + val.abi_encode() + } + "uint24" => { + let val: u32 = value.parse()?; + (val & 0xFFFFFF).abi_encode() + } + "bool" => { + let val: bool = value.parse()?; + val.abi_encode() + } + "address" => { + let addr: Address = value.parse()?; + addr.abi_encode() + } + "string" => value.abi_encode(), + "bytes32" => { + let val = hex::decode(value.trim_start_matches("0x"))?; + let mut fixed = [0u8; 32]; + fixed[..val.len()].copy_from_slice(&val); + fixed.abi_encode() + } + "uint256[]" | "uint[]" => { + let nums: Vec = serde_json::from_str(value)?; + nums.abi_encode() + } + "bytes" => { + let val = hex::decode(value.trim_start_matches("0x"))?; + val.abi_encode() + } + _ => anyhow::bail!("Unsupported type: {}", param.ty), + }, + CalldataArg::AddressRef(name) => { + let contract_name = name.trim_end_matches(".address"); + let addr = deployed_contracts + .get(contract_name) + .copied() + .ok_or_else(|| { + anyhow::anyhow!("Address for '{}' not found", contract_name) + })?; + addr.abi_encode() + } + }; + + encoded.extend(encoded_arg); } - // Encode - let encoded = function.encode_input(&tokens)?; Ok(Bytes::from(encoded)) } diff --git a/crates/node/src/geth.rs b/crates/node/src/geth.rs index f35dea5..29c2b66 100644 --- a/crates/node/src/geth.rs +++ b/crates/node/src/geth.rs @@ -1,6 +1,7 @@ //! The go-ethereum node implementation. use std::{ + collections::HashMap as StdHashMap, fs::{File, create_dir_all, remove_dir_all}, io::{BufRead, BufReader, Read, Write}, path::PathBuf, @@ -50,7 +51,7 @@ pub struct Instance { network_id: u64, start_timeout: u64, wallet: EthereumWallet, - nonces: Mutex>, + nonces: Mutex>, } impl Instance { @@ -158,6 +159,8 @@ impl EthereumNode for Instance { let connection_string = self.connection_string(); let wallet = self.wallet.clone(); + log::debug!("Submitting transaction: {:#?}", transaction); + execute_transaction(Box::pin(async move { Ok(ProviderBuilder::new() .wallet(wallet) @@ -235,7 +238,7 @@ impl Node for Instance { network_id: config.network_id, start_timeout: config.geth_start_timeout, wallet: config.wallet(), - nonces: Mutex::new(HashMap::new()), + nonces: Mutex::new(StdHashMap::new()), } } diff --git a/crates/node/src/kitchensink.rs b/crates/node/src/kitchensink.rs index 0285d24..d9fa886 100644 --- a/crates/node/src/kitchensink.rs +++ b/crates/node/src/kitchensink.rs @@ -1,4 +1,5 @@ use std::{ + collections::HashMap as StdHashMap, fs::create_dir_all, io::BufRead, path::PathBuf, @@ -44,7 +45,7 @@ pub struct KitchensinkNode { base_directory: PathBuf, process_substrate: Option, process_proxy: Option, - nonces: Mutex>, + nonces: Mutex>, } impl KitchensinkNode { @@ -251,6 +252,8 @@ impl EthereumNode for KitchensinkNode { let url = self.rpc_url.clone(); let wallet = self.wallet.clone(); + log::debug!("Submitting transaction: {:#?}", transaction); + execute_transaction(Box::pin(async move { Ok(ProviderBuilder::new() .wallet(wallet) @@ -325,7 +328,7 @@ impl Node for KitchensinkNode { base_directory, process_substrate: None, process_proxy: None, - nonces: Mutex::new(HashMap::new()), + nonces: Mutex::new(StdHashMap::new()), } }