diff --git a/prdoc/pr_8789.prdoc b/prdoc/pr_8789.prdoc new file mode 100644 index 0000000000000..f501fcb226d93 --- /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: major diff --git a/substrate/frame/revive/src/exec.rs b/substrate/frame/revive/src/exec.rs index 7521f43601ce9..8e0657f00b123 100644 --- a/substrate/frame/revive/src/exec.rs +++ b/substrate/frame/revive/src/exec.rs @@ -815,6 +815,7 @@ where skip_transfer: bool, bump_nonce: BumpNonce, ) -> Result<(H160, ExecReturnValue), ExecError> { + let deployer = T::AddressMapper::to_address(&origin); let (mut stack, executable) = Stack::<'_, T, E>::new( FrameArgs::Instantiate { sender: origin.clone(), @@ -830,9 +831,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, bump_nonce) - .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))] @@ -930,7 +937,7 @@ where if let Some(info) = >::get(&address) { CachedContract::Cached(info) } else { - return Ok(None) + return Ok(None); }, (None, Some(precompile)) if precompile.has_contract_info() => { if let Some(info) = >::get(&address) { diff --git a/substrate/frame/revive/src/exec/tests.rs b/substrate/frame/revive/src/exec/tests.rs index 406b4ad2d1f29..9fe6caf24796b 100644 --- a/substrate/frame/revive/src/exec/tests.rs +++ b/substrate/frame/revive/src/exec/tests.rs @@ -1145,6 +1145,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 c85537b6fd6b7..ce7106d69327a 100644 --- a/substrate/frame/revive/src/lib.rs +++ b/substrate/frame/revive/src/lib.rs @@ -361,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] diff --git a/substrate/frame/revive/src/tests.rs b/substrate/frame/revive/src/tests.rs index 61d540d8d1861..25d40b4ba4101 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![], + }, ] ); }); @@ -2220,6 +2228,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![], + }, ] ); }); @@ -2286,6 +2302,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![], + }, ] ); });