From 8980316eee95009a45039e3b28f869c8b10e7d66 Mon Sep 17 00:00:00 2001 From: grandizzy Date: Tue, 15 Oct 2024 10:28:45 +0300 Subject: [PATCH 1/2] fix(cheatcodes): convert fixed bytes to bytes in vm.rpc tuple result --- crates/cheatcodes/src/evm/fork.rs | 10 ++++++++++ testdata/default/cheats/Fork2.t.sol | 6 ++++++ 2 files changed, 16 insertions(+) diff --git a/crates/cheatcodes/src/evm/fork.rs b/crates/cheatcodes/src/evm/fork.rs index e1d66538de72..aa5389cbb32e 100644 --- a/crates/cheatcodes/src/evm/fork.rs +++ b/crates/cheatcodes/src/evm/fork.rs @@ -385,6 +385,16 @@ fn rpc_call(url: &str, method: &str, params: &str) -> Result { DynSolValue::Bytes(bytes.as_slice()[..size].to_vec()) } DynSolValue::Address(addr) => DynSolValue::Bytes(addr.to_vec()), + DynSolValue::Tuple(mut vals) => { + vals.iter_mut().for_each(|val| { + // Convert fixed bytes to bytes in tuple to prevent encoding issues. + // See: + if let DynSolValue::FixedBytes(bytes, size) = *val { + *val = DynSolValue::Bytes(bytes.as_slice()[..size].to_vec()); + } + }); + DynSolValue::Tuple(vals) + } val => val, }; diff --git a/testdata/default/cheats/Fork2.t.sol b/testdata/default/cheats/Fork2.t.sol index 7b6b4275990f..d0703ce7fa6c 100644 --- a/testdata/default/cheats/Fork2.t.sol +++ b/testdata/default/cheats/Fork2.t.sol @@ -234,6 +234,12 @@ contract ForkTest is DSTest { uint256 decodedResult = vm.parseUint(vm.toString(result)); assertGt(decodedResult, 20_000_000); } + + // + function testRpcTransactionByHash() public { + string memory param = string.concat('["0xe1a0fba63292976050b2fbf4379a1901691355ed138784b4e0d1854b4cf9193e"]'); + vm.rpc("sepolia", "eth_getTransactionByHash", param); + } } contract DummyContract { From f38f5784e30451bf0c647bf431f4d0fc61e83d11 Mon Sep 17 00:00:00 2001 From: grandizzy Date: Wed, 16 Oct 2024 08:23:29 +0300 Subject: [PATCH 2/2] Changes after review: recursive convert_to_bytes fn --- crates/cheatcodes/src/evm/fork.rs | 40 +++++++++++++++---------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/crates/cheatcodes/src/evm/fork.rs b/crates/cheatcodes/src/evm/fork.rs index aa5389cbb32e..83942cdbefa5 100644 --- a/crates/cheatcodes/src/evm/fork.rs +++ b/crates/cheatcodes/src/evm/fork.rs @@ -1,4 +1,7 @@ -use crate::{Cheatcode, Cheatcodes, CheatcodesExecutor, CheatsCtxt, DatabaseExt, Result, Vm::*}; +use crate::{ + json::json_value_to_token, Cheatcode, Cheatcodes, CheatcodesExecutor, CheatsCtxt, DatabaseExt, + Result, Vm::*, +}; use alloy_dyn_abi::DynSolValue; use alloy_primitives::{B256, U256}; use alloy_provider::Provider; @@ -375,28 +378,25 @@ fn rpc_call(url: &str, method: &str, params: &str) -> Result { let result = foundry_common::block_on(provider.raw_request(method.to_string().into(), params_json)) .map_err(|err| fmt_err!("{method:?}: {err}"))?; + let result_as_tokens = convert_to_bytes( + &json_value_to_token(&result).map_err(|err| fmt_err!("failed to parse result: {err}"))?, + ); - let result_as_tokens = match crate::json::json_value_to_token(&result) - .map_err(|err| fmt_err!("failed to parse result: {err}"))? - { - // Convert fixed bytes to bytes to prevent encoding issues. + Ok(result_as_tokens.abi_encode()) +} + +/// Convert fixed bytes and address values to bytes in order to prevent encoding issues. +fn convert_to_bytes(token: &DynSolValue) -> DynSolValue { + match token { + // Convert fixed bytes to prevent encoding issues. // See: DynSolValue::FixedBytes(bytes, size) => { - DynSolValue::Bytes(bytes.as_slice()[..size].to_vec()) + DynSolValue::Bytes(bytes.as_slice()[..*size].to_vec()) } DynSolValue::Address(addr) => DynSolValue::Bytes(addr.to_vec()), - DynSolValue::Tuple(mut vals) => { - vals.iter_mut().for_each(|val| { - // Convert fixed bytes to bytes in tuple to prevent encoding issues. - // See: - if let DynSolValue::FixedBytes(bytes, size) = *val { - *val = DynSolValue::Bytes(bytes.as_slice()[..size].to_vec()); - } - }); - DynSolValue::Tuple(vals) - } - val => val, - }; - - Ok(result_as_tokens.abi_encode()) + // Convert tuple values to prevent encoding issues. + // See: + DynSolValue::Tuple(vals) => DynSolValue::Tuple(vals.iter().map(convert_to_bytes).collect()), + val => val.clone(), + } }