From d7f4038277d8d46a02e140e7be6d4024e6305f99 Mon Sep 17 00:00:00 2001 From: Victor Oliva Date: Thu, 5 Jun 2025 17:17:51 +0200 Subject: [PATCH 1/5] feat(revive): add contract instantiated event --- substrate/frame/revive/src/exec.rs | 11 +++++++++-- substrate/frame/revive/src/exec/tests.rs | 7 +++++++ substrate/frame/revive/src/lib.rs | 3 +++ substrate/frame/revive/src/tests.rs | 24 ++++++++++++++++++++++++ 4 files changed, 43 insertions(+), 2 deletions(-) diff --git a/substrate/frame/revive/src/exec.rs b/substrate/frame/revive/src/exec.rs index e1588c1e8313b..d42a968eb9ad9 100644 --- a/substrate/frame/revive/src/exec.rs +++ b/substrate/frame/revive/src/exec.rs @@ -810,6 +810,7 @@ where salt: Option<&[u8; 32]>, skip_transfer: bool, ) -> Result<(H160, ExecReturnValue), ExecError> { + let deployer = T::AddressMapper::to_address(&origin); let (mut stack, executable) = Stack::<'_, T, E>::new( FrameArgs::Instantiate { sender: origin.clone(), @@ -825,9 +826,15 @@ where )? .expect(FRAME_ALWAYS_EXISTS_ON_INSTANTIATE); let address = T::AddressMapper::to_address(&stack.top_frame().account_id); - stack + let result = stack .run(executable, input_data) - .map(|_| (address, stack.first_frame.last_frame_output)) + .map(|_| (address, stack.first_frame.last_frame_output)); + if let Ok((contract, ref output)) = result { + if !output.did_revert() { + Contracts::::deposit_event(Event::Instantiated { deployer, contract }); + } + } + result } #[cfg(any(feature = "runtime-benchmarks", test))] diff --git a/substrate/frame/revive/src/exec/tests.rs b/substrate/frame/revive/src/exec/tests.rs index 1cba34d1f3b9f..65f58b598434a 100644 --- a/substrate/frame/revive/src/exec/tests.rs +++ b/substrate/frame/revive/src/exec/tests.rs @@ -1142,6 +1142,13 @@ fn instantiation_work_with_success_output() { ContractInfo::::load_code_hash(&instantiated_contract_id).unwrap(), dummy_ch ); + assert_eq!( + &events(), + &[Event::Instantiated { + deployer: ALICE_ADDR, + contract: instantiated_contract_address + }] + ); }); } diff --git a/substrate/frame/revive/src/lib.rs b/substrate/frame/revive/src/lib.rs index c8c0876e084ca..76931f21c6572 100644 --- a/substrate/frame/revive/src/lib.rs +++ b/substrate/frame/revive/src/lib.rs @@ -347,6 +347,9 @@ pub mod pallet { #[pallet::event] pub enum Event { + /// Contract deployed by deployer at the specified address. + Instantiated { deployer: H160, contract: H160 }, + /// A custom event emitted by the contract. ContractEmitted { /// The contract that emitted the event. diff --git a/substrate/frame/revive/src/tests.rs b/substrate/frame/revive/src/tests.rs index 821071fd4073a..4afa9f92f41ec 100644 --- a/substrate/frame/revive/src/tests.rs +++ b/substrate/frame/revive/src/tests.rs @@ -519,6 +519,14 @@ fn instantiate_and_call_and_deposit_event() { }), topics: vec![], }, + EventRecord { + phase: Phase::Initialization, + event: RuntimeEvent::Contracts(crate::Event::Instantiated { + deployer: ALICE_ADDR, + contract: addr + }), + topics: vec![], + }, ] ); }); @@ -2215,6 +2223,14 @@ fn instantiate_with_zero_balance_works() { }), topics: vec![], }, + EventRecord { + phase: Phase::Initialization, + event: RuntimeEvent::Contracts(crate::Event::Instantiated { + deployer: ALICE_ADDR, + contract: addr, + }), + topics: vec![], + }, ] ); }); @@ -2281,6 +2297,14 @@ fn instantiate_with_below_existential_deposit_works() { }), topics: vec![], }, + EventRecord { + phase: Phase::Initialization, + event: RuntimeEvent::Contracts(crate::Event::Instantiated { + deployer: ALICE_ADDR, + contract: addr, + }), + topics: vec![], + }, ] ); }); From 44872e89d7d9892a08488bb7597fec8d0201a8d1 Mon Sep 17 00:00:00 2001 From: Victor Oliva Date: Fri, 6 Jun 2025 14:44:37 +0200 Subject: [PATCH 2/5] add prdoc --- prdoc/pr_8789.prdoc | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 prdoc/pr_8789.prdoc diff --git a/prdoc/pr_8789.prdoc b/prdoc/pr_8789.prdoc new file mode 100644 index 0000000000000..6c5490235cf84 --- /dev/null +++ b/prdoc/pr_8789.prdoc @@ -0,0 +1,12 @@ +# Schema: Polkadot SDK PRDoc Schema (prdoc) v1.0.0 +# See doc at https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json + +title: '[pallet-revive] Add contract instantiated event' + +doc: + - audience: Runtime Dev + description: ' `instantiate` and `instantiate_with_code` emit a `Instantiated` event.' + +crates: + - name: pallet-revive + bump: minor From 02868c99f959e80dc0c385c6caf8108b26d594ee Mon Sep 17 00:00:00 2001 From: Victor Oliva Date: Fri, 6 Jun 2025 14:53:59 +0200 Subject: [PATCH 3/5] bump change to major --- prdoc/pr_8789.prdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/prdoc/pr_8789.prdoc b/prdoc/pr_8789.prdoc index 6c5490235cf84..f501fcb226d93 100644 --- a/prdoc/pr_8789.prdoc +++ b/prdoc/pr_8789.prdoc @@ -9,4 +9,4 @@ doc: crates: - name: pallet-revive - bump: minor + bump: major From c41a2598d72f361f15e1a41fc9f698e946f04b54 Mon Sep 17 00:00:00 2001 From: Victor Oliva Date: Tue, 24 Jun 2025 12:07:42 +0200 Subject: [PATCH 4/5] move instantiated event to keep pre-existing indices --- substrate/frame/revive/src/lib.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/substrate/frame/revive/src/lib.rs b/substrate/frame/revive/src/lib.rs index ddebdfa9fc5b9..ce7106d69327a 100644 --- a/substrate/frame/revive/src/lib.rs +++ b/substrate/frame/revive/src/lib.rs @@ -350,9 +350,6 @@ pub mod pallet { #[pallet::event] pub enum Event { - /// Contract deployed by deployer at the specified address. - Instantiated { deployer: H160, contract: H160 }, - /// A custom event emitted by the contract. ContractEmitted { /// The contract that emitted the event. @@ -364,6 +361,9 @@ pub mod pallet { /// Number of topics is capped by [`limits::NUM_EVENT_TOPICS`]. topics: Vec, }, + + /// Contract deployed by deployer at the specified address. + Instantiated { deployer: H160, contract: H160 }, } #[pallet::error] From e5eb49e0a3048d5be91307a2f2e24ba138935bc4 Mon Sep 17 00:00:00 2001 From: "cmd[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 24 Jun 2025 10:19:35 +0000 Subject: [PATCH 5/5] Update from github-actions[bot] running command 'fmt' --- substrate/frame/revive/src/exec.rs | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/substrate/frame/revive/src/exec.rs b/substrate/frame/revive/src/exec.rs index cb5d1d33d345e..8e0657f00b123 100644 --- a/substrate/frame/revive/src/exec.rs +++ b/substrate/frame/revive/src/exec.rs @@ -933,13 +933,12 @@ where // is a delegate call or not let mut contract = match (cached_info, &precompile) { (Some(info), _) => CachedContract::Cached(info), - (None, None) => { + (None, None) => if let Some(info) = >::get(&address) { CachedContract::Cached(info) } else { return Ok(None); - } - }, + }, (None, Some(precompile)) if precompile.has_contract_info() => { if let Some(info) = >::get(&address) { CachedContract::Cached(info) @@ -1185,9 +1184,9 @@ where // - Only when not delegate calling we are executing in the context of the pre-compile. // Pre-compiles itself cannot delegate call. if let Some(precompile) = executable.as_precompile() { - if precompile.has_contract_info() - && frame.delegate.is_none() - && !>::account_exists(account_id) + if precompile.has_contract_info() && + frame.delegate.is_none() && + !>::account_exists(account_id) { // prefix matching pre-compiles cannot have a contract info // hence we only mint once per pre-compile @@ -1203,12 +1202,10 @@ where .unwrap_or_default(); let output = match executable { - ExecutableOrPrecompile::Executable(executable) => { - executable.execute(self, entry_point, input_data) - }, - ExecutableOrPrecompile::Precompile { instance, .. } => { - instance.call(input_data, self) - }, + ExecutableOrPrecompile::Executable(executable) => + executable.execute(self, entry_point, input_data), + ExecutableOrPrecompile::Precompile { instance, .. } => + instance.call(input_data, self), } .map_err(|e| ExecError { error: e.error, origin: ErrorOrigin::Callee })?; @@ -1250,9 +1247,8 @@ where with_transaction(|| -> TransactionOutcome> { let output = do_transaction(); match &output { - Ok(result) if !result.did_revert() => { - TransactionOutcome::Commit(Ok((true, output))) - }, + Ok(result) if !result.did_revert() => + TransactionOutcome::Commit(Ok((true, output))), _ => TransactionOutcome::Rollback(Ok((false, output))), } });