Skip to content

Commit

Permalink
fix: add optional OpenChainClient and only use it if can get tokio ha…
Browse files Browse the repository at this point in the history
…ndle
  • Loading branch information
cuiweixie committed Aug 9, 2024
1 parent e6ad9ab commit 0301d51
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 25 deletions.
3 changes: 2 additions & 1 deletion crates/cli/src/utils/cmd.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use alloy_json_abi::JsonAbi;
use alloy_primitives::Address;
use eyre::{Result, WrapErr};
use foundry_common::{cli_warn, fs, TestFunctionExt};
use foundry_common::{cli_warn, fs, selectors::OpenChainClient, TestFunctionExt};
use foundry_compilers::{
artifacts::{CompactBytecode, CompactDeployedBytecode, Settings},
cache::{CacheEntry, CompilerCache},
Expand Down Expand Up @@ -379,6 +379,7 @@ pub async fn handle_traces(
Config::foundry_cache_dir(),
config.offline,
)?)
.with_openchain_client(OpenChainClient::new()?)
.build();

let mut etherscan_identifier = EtherscanIdentifier::new(config, chain)?;
Expand Down
54 changes: 31 additions & 23 deletions crates/evm/core/src/decode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@ use alloy_dyn_abi::JsonAbiExt;
use alloy_json_abi::{Error, JsonAbi};
use alloy_primitives::{hex, Log, Selector};
use alloy_sol_types::{SolCall, SolError, SolEventInterface, SolInterface, SolValue};
use foundry_common::{abi::get_error, selectors::decode_function_selector, SELECTOR_LEN};
use foundry_common::{abi::get_error, selectors::OpenChainClient, SELECTOR_LEN};
use itertools::Itertools;
use revm::interpreter::InstructionResult;
use rustc_hash::FxHashMap;
use std::{
sync::{mpsc, OnceLock},
thread,
};
use tokio::runtime::Handle;

/// Decode a set of logs, only returning logs from DSTest logging events and Hardhat's `console.log`
pub fn decode_console_logs(logs: &[Log]) -> Vec<String> {
Expand All @@ -32,6 +33,7 @@ pub fn decode_console_log(log: &Log) -> Option<String> {
pub struct RevertDecoder {
/// The custom errors to use for decoding.
pub errors: FxHashMap<Selector, Vec<Error>>,
pub open_chain_client: Option<OpenChainClient>,
}

impl Default for &RevertDecoder {
Expand Down Expand Up @@ -180,28 +182,34 @@ impl RevertDecoder {
}

// try from https://openchain.xyz
let (tx, rx) = mpsc::channel();
let encoded_selector = hex::encode(selector);

thread::spawn(move || {
let rt = tokio::runtime::Runtime::new().unwrap();
let result = rt.block_on(decode_function_selector(&encoded_selector));
tx.send(result).unwrap();
});

let result = match rx.recv() {
Ok(Ok(sigs)) => Some(sigs),
Ok(Err(_)) | Err(_) => None,
};
if let Some(sigs) = result {
for sig in sigs {
if let Ok(error) = get_error(&sig) {
if let Ok(decoded) = error.abi_decode_input(data, true) {
return Some(format!(
"{}({})",
error.name,
decoded.iter().map(foundry_common::fmt::format_token).format(", ")
));
if let Some(client) = self.open_chain_client.clone() {
if let Ok(handle) = Handle::try_current() {
let (tx, rx) = mpsc::channel();
let encoded_selector = hex::encode(selector);
thread::spawn(move || {
let result =
handle.block_on(client.decode_function_selector(&encoded_selector));
tx.send(result).unwrap();
});

let result = match rx.recv() {
Ok(Ok(sigs)) => Some(sigs),
Ok(Err(_)) | Err(_) => None,
};
if let Some(sigs) = result {
for sig in sigs {
if let Ok(error) = get_error(&sig) {
if let Ok(decoded) = error.abi_decode_input(data, true) {
return Some(format!(
"{}({})",
error.name,
decoded
.iter()
.map(foundry_common::fmt::format_token)
.format(", ")
));
}
}
}
}
}
Expand Down
10 changes: 9 additions & 1 deletion crates/evm/traces/src/decoder/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ use alloy_dyn_abi::{DecodedEvent, DynSolValue, EventExt, FunctionExt, JsonAbiExt
use alloy_json_abi::{Error, Event, Function, JsonAbi};
use alloy_primitives::{Address, LogData, Selector, B256};
use foundry_common::{
abi::get_indexed_event, fmt::format_token, get_contract_name, ContractsByArtifact, SELECTOR_LEN,
abi::get_indexed_event, fmt::format_token, get_contract_name, selectors::OpenChainClient,
ContractsByArtifact, SELECTOR_LEN,
};
use foundry_evm_core::{
abi::{Console, HardhatConsole, Vm, HARDHAT_CONSOLE_SELECTOR_PATCHES},
Expand Down Expand Up @@ -89,6 +90,13 @@ impl CallTraceDecoderBuilder {
self
}

/// Sets the openchain client.
#[inline]
pub fn with_openchain_client(mut self, client: OpenChainClient) -> Self {
self.decoder.revert_decoder.open_chain_client = Some(client);
self
}

/// Sets the debug identifier for the decoder.
#[inline]
pub fn with_debug_identifier(mut self, identifier: DebugTraceIdentifier) -> Self {
Expand Down

0 comments on commit 0301d51

Please sign in to comment.