Skip to content

Commit 2e995a2

Browse files
authored
feat(script): additional contracts name in broadcast log (#11197)
feat(script): identify and record name of additional contracts
1 parent 8e7efbc commit 2e995a2

File tree

5 files changed

+112
-4
lines changed

5 files changed

+112
-4
lines changed

crates/forge/tests/cli/script.rs

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3009,3 +3009,95 @@ ONCHAIN EXECUTION COMPLETE & SUCCESSFUL.
30093009
assert_eq!(receiver2.nonce, 0);
30103010
assert_eq!(receiver2.balance.to_string(), "101000000000000000000");
30113011
});
3012+
3013+
// <https://github.com/foundry-rs/foundry/issues/11159>
3014+
forgetest_async!(check_broadcast_log_with_additional_contracts, |prj, cmd| {
3015+
foundry_test_utils::util::initialize(prj.root());
3016+
prj.add_source(
3017+
"Counter.sol",
3018+
r#"
3019+
contract Counter {
3020+
uint256 public number;
3021+
3022+
function setNumber(uint256 newNumber) public {
3023+
number = newNumber;
3024+
}
3025+
3026+
function increment() public {
3027+
number++;
3028+
}
3029+
}
3030+
"#,
3031+
)
3032+
.unwrap();
3033+
prj.add_source(
3034+
"Factory.sol",
3035+
r#"
3036+
import {Counter} from "./Counter.sol";
3037+
3038+
contract Factory {
3039+
function deployCounter() public returns (Counter) {
3040+
return new Counter();
3041+
}
3042+
}
3043+
"#,
3044+
)
3045+
.unwrap();
3046+
let deploy_script = prj
3047+
.add_script(
3048+
"Factory.s.sol",
3049+
r#"
3050+
import "forge-std/Script.sol";
3051+
import {Factory} from "../src/Factory.sol";
3052+
import {Counter} from "../src/Counter.sol";
3053+
3054+
contract FactoryScript is Script {
3055+
Factory public factory;
3056+
Counter public counter;
3057+
3058+
function setUp() public {}
3059+
3060+
function run() public {
3061+
vm.startBroadcast();
3062+
3063+
factory = new Factory();
3064+
counter = factory.deployCounter();
3065+
3066+
vm.stopBroadcast();
3067+
}
3068+
}
3069+
"#,
3070+
)
3071+
.unwrap();
3072+
3073+
let deploy_contract = deploy_script.display().to_string() + ":FactoryScript";
3074+
let (_api, handle) = spawn(NodeConfig::test()).await;
3075+
cmd.args([
3076+
"script",
3077+
&deploy_contract,
3078+
"--root",
3079+
prj.root().to_str().unwrap(),
3080+
"--fork-url",
3081+
&handle.http_endpoint(),
3082+
"--slow",
3083+
"--broadcast",
3084+
"--private-key",
3085+
"ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80",
3086+
])
3087+
.assert_success();
3088+
3089+
let broadcast_log = prj.root().join("broadcast/Factory.s.sol/31337/run-latest.json");
3090+
let script_sequence: ScriptSequence = serde_json::from_reader(
3091+
fs::File::open(prj.artifacts().join(broadcast_log)).expect("no broadcast log"),
3092+
)
3093+
.expect("no script sequence");
3094+
3095+
let counter_contract = script_sequence
3096+
.transactions
3097+
.get(1)
3098+
.expect("no tx")
3099+
.additional_contracts
3100+
.first()
3101+
.expect("no Counter contract");
3102+
assert_eq!(counter_contract.contract_name, Some("Counter".to_string()));
3103+
});

crates/script-sequence/src/transaction.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use serde::{Deserialize, Serialize};
88
pub struct AdditionalContract {
99
#[serde(rename = "transactionType")]
1010
pub opcode: CallKind,
11+
pub contract_name: Option<String>,
1112
pub address: Address,
1213
pub init_code: Bytes,
1314
}

crates/script/src/lib.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -538,16 +538,24 @@ pub struct ScriptResult {
538538
}
539539

540540
impl ScriptResult {
541-
pub fn get_created_contracts(&self) -> Vec<AdditionalContract> {
541+
pub fn get_created_contracts(
542+
&self,
543+
known_contracts: &ContractsByArtifact,
544+
) -> Vec<AdditionalContract> {
542545
self.traces
543546
.iter()
544547
.flat_map(|(_, traces)| {
545548
traces.nodes().iter().filter_map(|node| {
546549
if node.trace.kind.is_any_create() {
550+
let init_code = node.trace.data.clone();
551+
let contract_name = known_contracts
552+
.find_by_creation_code(init_code.as_ref())
553+
.map(|artifact| artifact.0.name.clone());
547554
return Some(AdditionalContract {
548555
opcode: node.trace.kind,
549556
address: node.trace.address,
550-
init_code: node.trace.data.clone(),
557+
contract_name,
558+
init_code,
551559
});
552560
}
553561
None

crates/script/src/simulate.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,11 @@ impl PreSimulationState {
149149
};
150150

151151
let transaction = ScriptTransactionBuilder::from(transaction)
152-
.with_execution_result(&result, self.args.gas_estimate_multiplier)
152+
.with_execution_result(
153+
&result,
154+
self.args.gas_estimate_multiplier,
155+
&self.build_data,
156+
)
153157
.build();
154158

155159
eyre::Ok((Some(transaction), is_noop_tx, result.traces))

crates/script/src/transaction.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use super::ScriptResult;
2+
use crate::build::LinkedBuildData;
23
use alloy_dyn_abi::JsonAbiExt;
34
use alloy_primitives::{Address, B256, TxKind, hex};
45
use eyre::Result;
@@ -146,8 +147,10 @@ impl ScriptTransactionBuilder {
146147
mut self,
147148
result: &ScriptResult,
148149
gas_estimate_multiplier: u64,
150+
linked_build_data: &LinkedBuildData,
149151
) -> Self {
150-
let mut created_contracts = result.get_created_contracts();
152+
let mut created_contracts =
153+
result.get_created_contracts(&linked_build_data.known_contracts);
151154

152155
// Add the additional contracts created in this transaction, so we can verify them later.
153156
created_contracts.retain(|contract| {

0 commit comments

Comments
 (0)