Skip to content

Commit

Permalink
make generate_local_signatures as a helper function
Browse files Browse the repository at this point in the history
  • Loading branch information
byteshijinn committed Jun 30, 2024
1 parent 5e7da8a commit 759a009
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 41 deletions.
48 changes: 15 additions & 33 deletions crates/cast/bin/cmd/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,16 @@ use clap::Parser;
use eyre::{Result, WrapErr};
use foundry_cli::{
opts::RpcOpts,
utils::{handle_traces, init_progress, TraceResult},
utils::{generate_local_signatures, handle_traces, init_progress, TraceResult},
};
use foundry_common::{
compile::ProjectCompiler, fs, is_known_system_sender, SYSTEM_TRANSACTION_TYPE,
};
use foundry_compilers::EvmVersion;
use foundry_common::{compile::ProjectCompiler, is_known_system_sender, SYSTEM_TRANSACTION_TYPE};
use foundry_compilers::artifacts::EvmVersion;
use foundry_config::{find_project_root_path, Config};
use foundry_evm::{
executors::{EvmError, TracingExecutor},
opts::EvmOpts,
utils::configure_tx_env,
};
use serde::{Deserialize, Serialize};
use std::collections::BTreeMap;

#[derive(Debug, Default, Serialize, Deserialize)]
struct CachedSignatures {
events: BTreeMap<String, String>,
functions: BTreeMap<String, String>,
}

/// CLI arguments for `cast run`.
#[derive(Clone, Debug, Parser)]
Expand Down Expand Up @@ -82,7 +72,11 @@ pub struct RunArgs {
#[arg(long, value_name = "NO_RATE_LIMITS", visible_alias = "no-rpc-rate-limit")]
pub no_rate_limit: bool,

#[arg(long, short, alias = "gs")]
/// If generate a file with the signatures of the functions and events of the project.
/// The file will be saved in the foundry cache directory.
///
/// default value: false
#[arg(long, short = 'G', visible_alias = "gs")]
pub generate_local_signatures: bool,
}

Expand Down Expand Up @@ -236,25 +230,13 @@ impl RunArgs {
if self.generate_local_signatures {
let project = config.project()?;
let compiler = ProjectCompiler::new().quiet(true);
let out = compiler.compile(&project)?;
let mut cached_signatures = CachedSignatures::default();
out.artifacts().for_each(|(_, artifact)| {
if let Some(abi) = &artifact.abi {
for func in abi.functions() {
cached_signatures
.functions
.insert(func.selector().to_string(), func.signature());
}
for event in abi.events() {
cached_signatures
.events
.insert(event.selector().to_string(), event.full_signature());
}
}
});
let path = Config::foundry_cache_dir().unwrap().join("signatures");
if path.is_file() {
let _ = fs::write_json_file(&path, &cached_signatures);
let output = compiler.compile(&project)?;
if let Err(err) =
generate_local_signatures(&output, Config::foundry_cache_dir().unwrap())
{
warn!(target: "cast::run", ?err, "failed to flush signature cache");
} else {
trace!(target: "cast::run", "flushed signature cache")
}
}

Expand Down
8 changes: 8 additions & 0 deletions crates/cli/src/opts/build/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,14 @@ pub struct CoreBuildArgs {
#[command(flatten)]
#[serde(flatten)]
pub project_paths: ProjectPathsArgs,

/// If generate a file with the signatures of the functions and events of the project.
/// The file will be saved in the foundry cache directory.
///
/// default value: false
#[arg(long, short = 'G', visible_alias = "gs")]
#[serde(skip)]
pub generate_local_signatures: bool,
}

impl CoreBuildArgs {
Expand Down
24 changes: 23 additions & 1 deletion crates/cli/src/utils/cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use foundry_evm::{
executors::{DeployResult, EvmError, RawCallResult},
opts::EvmOpts,
traces::{
identifier::{EtherscanIdentifier, SignaturesIdentifier},
identifier::{CachedSignatures, EtherscanIdentifier, SignaturesIdentifier},
render_trace_arena, CallTraceDecoder, CallTraceDecoderBuilder, TraceKind, Traces,
},
};
Expand Down Expand Up @@ -414,3 +414,25 @@ pub async fn print_traces(result: &mut TraceResult, decoder: &CallTraceDecoder)
println!("Gas used: {}", result.gas_used);
Ok(())
}

pub fn generate_local_signatures(output: &ProjectCompileOutput, cache_path: PathBuf) -> Result<()> {
let mut cached_signatures = CachedSignatures::default();
output.artifacts().for_each(|(_, artifact)| {
if let Some(abi) = &artifact.abi {
for func in abi.functions() {
cached_signatures.functions.insert(func.selector().to_string(), func.signature());
}
for event in abi.events() {
cached_signatures
.events
.insert(event.selector().to_string(), event.full_signature());
}
}
});
let path = cache_path.join("signatures");
if !path.is_file() {
std::fs::create_dir_all(&cache_path)?;
}
fs::write_json_file(&path, &cached_signatures)?;
Ok(())
}
2 changes: 1 addition & 1 deletion crates/evm/traces/src/identifier/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ mod etherscan;
pub use etherscan::EtherscanIdentifier;

mod signatures;
pub use signatures::{SignaturesIdentifier, SingleSignaturesIdentifier};
pub use signatures::{CachedSignatures, SignaturesIdentifier, SingleSignaturesIdentifier};

/// An address identity
pub struct AddressIdentity<'a> {
Expand Down
6 changes: 3 additions & 3 deletions crates/evm/traces/src/identifier/signatures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ use tokio::sync::RwLock;
pub type SingleSignaturesIdentifier = Arc<RwLock<SignaturesIdentifier>>;

#[derive(Debug, Default, Serialize, Deserialize)]
struct CachedSignatures {
events: BTreeMap<String, String>,
functions: BTreeMap<String, String>,
pub struct CachedSignatures {
pub events: BTreeMap<String, String>,
pub functions: BTreeMap<String, String>,
}

/// An identifier that tries to identify functions and events using signatures found at
Expand Down
19 changes: 16 additions & 3 deletions crates/forge/bin/cmd/build.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
use super::{install, watch::WatchArgs};
use clap::Parser;
use eyre::Result;
use foundry_cli::{opts::CoreBuildArgs, utils::LoadConfig};
use foundry_cli::{
opts::CoreBuildArgs,
utils::{generate_local_signatures, LoadConfig},
};
use foundry_common::compile::ProjectCompiler;
use foundry_compilers::{
compilers::{multi::MultiCompilerLanguage, Language},
Expand Down Expand Up @@ -80,8 +83,8 @@ impl BuildArgs {
pub fn run(self) -> Result<ProjectCompileOutput> {
let mut config = self.try_load_config_emit_warnings()?;

if install::install_missing_dependencies(&mut config, self.args.silent) &&
config.auto_detect_remappings
if install::install_missing_dependencies(&mut config, self.args.silent)
&& config.auto_detect_remappings
{
// need to re-configure here to also catch additional remappings
config = self.load_config();
Expand Down Expand Up @@ -110,6 +113,16 @@ impl BuildArgs {
println!("{}", serde_json::to_string_pretty(&output.output())?);
}

if self.args.generate_local_signatures {
if let Err(err) =
generate_local_signatures(&output, Config::foundry_cache_dir().unwrap())
{
warn!(target: "forge::build", ?err, "failed to flush signature cache");
} else {
trace!(target: "forge::build", "flushed signature cache")
}
}

Ok(output)
}

Expand Down

0 comments on commit 759a009

Please sign in to comment.