Skip to content

Commit

Permalink
add name() method to FunctionCallDefinition
Browse files Browse the repository at this point in the history
  • Loading branch information
jinmel committed Sep 26, 2024
1 parent 51dcc5b commit d83ab85
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 3 deletions.
33 changes: 33 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,4 @@ r2d2 = "0.8.10"
futures = "0.3.30"
async-trait = "0.1.82"
csv = "1.3.0"
regex = "1.10.6"
8 changes: 5 additions & 3 deletions src/generator/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,9 +126,11 @@ where
templater.find_fncall_placeholders(step, db, &mut placeholder_map)?;

// create txs with template values
let tx: NamedTxRequest = templater
.template_function_call(step, &placeholder_map)?
.into();
let tx: NamedTxRequest = NamedTxRequest::with_name(
&step.name(),
templater .template_function_call(step, &placeholder_map)?
);

let handle = on_setup_step(tx.to_owned())?;
if let Some(handle) = handle {
handle.await.map_err(|e| {
Expand Down
83 changes: 83 additions & 0 deletions src/generator/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use alloy::{
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use tokio::task::JoinHandle;
use regex::Regex;

pub type RpcProvider = RootProvider<Http<Client>>;

Expand Down Expand Up @@ -83,3 +84,85 @@ pub enum PlanType<F: Fn(NamedTxRequest) -> CallbackResult> {
Setup(F),
Spam(usize, F),
}

impl FunctionCallDefinition {
/// Constructs a function name string combining signature and arguments.
pub fn name(&self) -> String {
// Use regex to parse the function signature
let signature = &self.signature;
let re = Regex::new(r"(?P<func_name>\w+)\s*\((?P<params>[^\)]*)\)(\s*returns\s*\((?P<returns>[^\)]*)\))?").unwrap();

// If the signature matches the expected pattern
if let Some(caps) = re.captures(signature) {
let func_name = caps.name("func_name").unwrap().as_str();
let params_str = caps.name("params").unwrap().as_str();

// Split the parameters into a vector
let params: Vec<&str> = params_str.split(',').map(|s| s.trim()).collect();

// Prepare a vector to hold the reconstructed parameters
let mut reconstructed_params = Vec::new();

let values = self.args.as_deref().unwrap_or(&[]);

// Iterate over parameters and associate them with args[i]
for (i, param) in params.iter().enumerate() {
// Split each parameter into type and name
let parts: Vec<&str> = param.split_whitespace().collect();
let param_value = values.get(i).map(String::as_str).unwrap_or("");
if parts.len() == 2 {
let param_type = parts[0];
let param_name = parts[1];
reconstructed_params.push(format!("{} {}=[{}]", param_type, param_name, param_value));
}
}

// Reconstruct the function signature
let reconstructed_signature = format!("{}({})", func_name, reconstructed_params.join(", "));

return reconstructed_signature;
}

// If the signature doesn't match, return it as is
signature.clone()
}
}

#[cfg(test)]
pub mod tests {
use super::FunctionCallDefinition;

#[test]
fn constructs_name_from_signature() {
let fn_def_with_args = FunctionCallDefinition {
to: "0x1234".to_string(),
from: "0x5678".to_string(),
signature: "transfer(address to, uint256 amount)".to_string(),
args: Some(vec!["0x8765".to_string(), "100".to_string()]),
value: Some("100".to_string()),
fuzz: None,
};
assert_eq!(fn_def_with_args.name(), "transfer(address to=[0x8765], uint256 amount=[100])");

let fn_def_no_args = FunctionCallDefinition {
to: "0x1234".to_string(),
from: "0x5678".to_string(),
signature: "transfer()".to_string(),
args: None,
value: Some("100".to_string()),
fuzz: None,
};
assert_eq!(fn_def_no_args.name(), "transfer()");

// checks if it does not fail against invalid signature.
let fn_def_invalid_sig = FunctionCallDefinition {
to: "0x1234".to_string(),
from: "0x5678".to_string(),
signature: "transfer(address, uint256 amount)".to_string(),
args: Some(vec!["0x8765".to_string(), "100".to_string()]),
value: Some("100".to_string()),
fuzz: None,
};
assert_eq!(fn_def_invalid_sig.name(), "transfer(uint256 amount=[100])");
}
}

0 comments on commit d83ab85

Please sign in to comment.