contracts: Emit event on contract termination (#8014)

* contracts: Remove redundant bool argument from the eviction event

* contracts: Improve event documentation

* contracts: Emit event on contract termination
This commit is contained in:
Alexander Theißen
2021-02-02 11:48:35 +01:00
committed by GitHub
parent de838f9464
commit 815409f31e
4 changed files with 74 additions and 27 deletions
+2 -1
View File
@@ -582,6 +582,7 @@ where
)?;
if let Some(ContractInfo::Alive(info)) = ContractInfoOf::<T>::take(&self_id) {
Storage::<T>::queue_trie_for_deletion(&info)?;
Contracts::<T>::deposit_event(RawEvent::Terminated(self_id, beneficiary.clone()));
Ok(())
} else {
panic!(
@@ -671,7 +672,7 @@ where
fn deposit_event(&mut self, topics: Vec<T::Hash>, data: Vec<u8>) {
deposit_event::<Self::T>(
topics,
RawEvent::ContractExecution(self.ctx.self_account.clone(), data)
RawEvent::ContractEmitted(self.ctx.self_account.clone(), data)
);
}
+39 -21
View File
@@ -756,39 +756,57 @@ decl_event! {
<T as frame_system::Config>::AccountId,
<T as frame_system::Config>::Hash
{
/// Contract deployed by address at the specified address. \[owner, contract\]
/// Contract deployed by address at the specified address. \[deployer, contract\]
Instantiated(AccountId, AccountId),
/// Contract has been evicted and is now in tombstone state.
/// \[contract, tombstone\]
///
/// # Params
///
/// - `contract`: `AccountId`: The account ID of the evicted contract.
/// - `tombstone`: `bool`: True if the evicted contract left behind a tombstone.
Evicted(AccountId, bool),
/// Contract has been evicted and is now in tombstone state. \[contract\]
Evicted(AccountId),
/// Restoration for a contract has been successful.
/// \[donor, dest, code_hash, rent_allowance\]
/// Contract has been terminated without leaving a tombstone.
/// \[contract, beneficiary\]
///
/// # Params
///
/// - `donor`: `AccountId`: Account ID of the restoring contract
/// - `dest`: `AccountId`: Account ID of the restored contract
/// - `code_hash`: `Hash`: Code hash of the restored contract
/// - `rent_allowance: `Balance`: Rent allowance of the restored contract
/// - `contract`: The contract that was terminated.
/// - `beneficiary`: The account that received the contracts remaining balance.
///
/// # Note
///
/// The only way for a contract to be removed without a tombstone and emitting
/// this event is by calling `seal_terminate`.
Terminated(AccountId, AccountId),
/// Restoration of a contract has been successful.
/// \[restorer, dest, code_hash, rent_allowance\]
///
/// # Params
///
/// - `restorer`: Account ID of the restoring contract.
/// - `dest`: Account ID of the restored contract.
/// - `code_hash`: Code hash of the restored contract.
/// - `rent_allowance`: Rent allowance of the restored contract.
Restored(AccountId, AccountId, Hash, Balance),
/// Code with the specified hash has been stored.
/// \[code_hash\]
/// Code with the specified hash has been stored. \[code_hash\]
CodeStored(Hash),
/// Triggered when the current \[schedule\] is updated.
/// Triggered when the current schedule is updated.
/// \[version\]
///
/// # Params
///
/// - `version`: The version of the newly set schedule.
ScheduleUpdated(u32),
/// An event deposited upon execution of a contract from the account.
/// \[account, data\]
ContractExecution(AccountId, Vec<u8>),
/// A custom event emitted by the contract.
/// \[contract, data\]
///
/// # Params
///
/// - `contract`: The contract that emitted the event.
/// - `data`: Data supplied by the contract. Metadata generated during contract
/// compilation is needed to decode it.
ContractEmitted(AccountId, Vec<u8>),
}
}
+1 -1
View File
@@ -261,7 +261,7 @@ where
);
let tombstone_info = ContractInfo::Tombstone(tombstone);
<ContractInfoOf<T>>::insert(account, &tombstone_info);
<Module<T>>::deposit_event(RawEvent::Evicted(account.clone(), true));
<Module<T>>::deposit_event(RawEvent::Evicted(account.clone()));
Ok(Some(tombstone_info))
}
Verdict::Charge { amount } => {
+32 -4
View File
@@ -512,7 +512,7 @@ fn instantiate_and_call_and_deposit_event() {
EventRecord {
phase: Phase::Initialization,
event: MetaEvent::contracts(
RawEvent::ContractExecution(addr.clone(), vec![1, 2, 3, 4])
RawEvent::ContractEmitted(addr.clone(), vec![1, 2, 3, 4])
),
topics: vec![],
},
@@ -1300,7 +1300,7 @@ fn restoration(test_different_storage: bool, test_restore_to_with_dirty_storage:
EventRecord {
phase: Phase::Initialization,
event: MetaEvent::contracts(
RawEvent::Evicted(addr_bob.clone(), true)
RawEvent::Evicted(addr_bob.clone())
),
topics: vec![],
},
@@ -1385,7 +1385,7 @@ fn restoration(test_different_storage: bool, test_restore_to_with_dirty_storage:
pretty_assertions::assert_eq!(System::events(), vec![
EventRecord {
phase: Phase::Initialization,
event: MetaEvent::contracts(RawEvent::Evicted(addr_bob, true)),
event: MetaEvent::contracts(RawEvent::Evicted(addr_bob)),
topics: vec![],
},
EventRecord {
@@ -1633,6 +1633,7 @@ fn self_destruct_works() {
.build()
.execute_with(|| {
let _ = Balances::deposit_creating(&ALICE, 1_000_000);
let _ = Balances::deposit_creating(&DJANGO, 1_000_000);
assert_ok!(Contracts::put_code(Origin::signed(ALICE), wasm));
// Instantiate the BOB contract.
@@ -1652,6 +1653,9 @@ fn self_destruct_works() {
Some(ContractInfo::Alive(_))
);
// Drop all previous events
initialize_block(2);
// Call BOB without input data which triggers termination.
assert_matches!(
Contracts::call(
@@ -1664,11 +1668,35 @@ fn self_destruct_works() {
Ok(_)
);
pretty_assertions::assert_eq!(System::events(), vec![
EventRecord {
phase: Phase::Initialization,
event: MetaEvent::system(
frame_system::Event::KilledAccount(addr.clone())
),
topics: vec![],
},
EventRecord {
phase: Phase::Initialization,
event: MetaEvent::balances(
pallet_balances::RawEvent::Transfer(addr.clone(), DJANGO, 100_000)
),
topics: vec![],
},
EventRecord {
phase: Phase::Initialization,
event: MetaEvent::contracts(
RawEvent::Terminated(addr.clone(), DJANGO)
),
topics: vec![],
},
]);
// Check that account is gone
assert!(ContractInfoOf::<Test>::get(&addr).is_none());
// check that the beneficiary (django) got remaining balance
assert_eq!(Balances::free_balance(DJANGO), 100_000);
assert_eq!(Balances::free_balance(DJANGO), 1_100_000);
});
}