Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion frame/contracts/src/exec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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!(
Expand Down Expand Up @@ -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)
);
}

Expand Down
54 changes: 36 additions & 18 deletions frame/contracts/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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\]
/// Contract has been evicted and is now in tombstone state. \[contract\]
Evicted(AccountId),

/// Contract has been terminated without leaving a tombstone.
/// \[contract, beneficiary\]
///
/// # 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`: 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 for a contract has been successful.
/// \[donor, dest, code_hash, rent_allowance\]
/// Restoration of a contract has been successful.
/// \[restorer, dest, code_hash, rent_allowance\]
///
/// # 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
/// - `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>),
}
}

Expand Down
2 changes: 1 addition & 1 deletion frame/contracts/src/rent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 } => {
Expand Down
36 changes: 32 additions & 4 deletions frame/contracts/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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![],
},
Expand Down Expand Up @@ -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![],
},
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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.
Expand All @@ -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(
Expand All @@ -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);
});
}

Expand Down