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 Mar 17, 2024
1 parent a3ea043 commit 2a08d1c
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 34 deletions.
42 changes: 14 additions & 28 deletions crates/cast/bin/cmd/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,26 +8,16 @@ use foundry_cli::{
init_progress,
opts::RpcOpts,
update_progress,
utils::{handle_traces, TraceResult},
};
use foundry_common::{is_known_system_sender, SYSTEM_TRANSACTION_TYPE,
compile::ProjectCompiler, fs,
utils::{generate_local_signatures, handle_traces, TraceResult},
};
use foundry_common::{compile::ProjectCompiler, is_known_system_sender, SYSTEM_TRANSACTION_TYPE};
use foundry_compilers::EvmVersion;
use foundry_config::{find_project_root_path, Config};
use foundry_evm::{
executors::{EvmError, TracingExecutor},
opts::EvmOpts,
utils::configure_tx_env,
};
use std::collections::BTreeMap;
use serde::{Deserialize, Serialize};

#[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 @@ -84,7 +74,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 @@ -233,21 +227,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 @@ -117,6 +117,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 @@ -16,7 +16,7 @@ use foundry_evm::{
executors::{DeployResult, EvmError, ExecutionErr, RawCallResult},
opts::EvmOpts,
traces::{
identifier::{EtherscanIdentifier, SignaturesIdentifier},
identifier::{CachedSignatures, EtherscanIdentifier, SignaturesIdentifier},
render_trace_arena, CallTraceDecoder, CallTraceDecoderBuilder, TraceKind, Traces,
},
};
Expand Down Expand Up @@ -442,3 +442,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 @@ -12,9 +12,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
15 changes: 14 additions & 1 deletion 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, SkipBuildFilter, SkipBuildFilters};
use foundry_compilers::{Project, ProjectCompileOutput};
use foundry_config::{
Expand Down Expand Up @@ -103,6 +106,16 @@ impl BuildArgs {
println!("{}", serde_json::to_string_pretty(&output.clone().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 2a08d1c

Please sign in to comment.