Add test that ensures drain funds to death works (#829)

This commit is contained in:
Sergey Pepyakin
2018-09-27 20:55:45 +01:00
committed by Gav Wood
parent 41a6f54c4a
commit 6af61b8649
3 changed files with 45 additions and 1 deletions
@@ -83,6 +83,11 @@ pub trait StorageDoubleMap {
unhashed::get(&full_key::<Self>(k1, k2)[..])
}
/// Returns `true` if value under the specified keys exists.
fn exists(k1: Self::Key1, k2: Self::Key2) -> bool {
unhashed::exists(&full_key::<Self>(k1, k2)[..])
}
/// Removes all entries that shares the `k1` as the first key.
fn remove_prefix(k1: Self::Key1) {
unhashed::kill_prefix(&first_part_of_key::<Self>(k1))
+6 -1
View File
@@ -185,9 +185,13 @@ impl<'a, T: Trait> ExecutionContext<'a, T> {
/// (transfering endowment), specified by `contract_create` flag,
/// or because of a transfer via `call`.
///
/// Note, that the fee is denominated in `T::Balance` units, but
/// NOTE: that the fee is denominated in `T::Balance` units, but
/// charged in `T::Gas` from the provided `gas_meter`. This means
/// that the actual amount charged might differ.
///
/// NOTE: that we allow for draining all funds of the contract so it
/// can go below existential deposit, essentially giving a contract
/// the chance to give up it's life.
fn transfer<'a, T: Trait>(
gas_meter: &mut GasMeter<T>,
contract_create: bool,
@@ -212,6 +216,7 @@ fn transfer<'a, T: Trait>(
return Err("not enough gas to pay transfer fee");
}
// We allow balance to go below the existential deposit here:
let from_balance = ctx.overlay.get_balance(transactor);
let new_from_balance = match from_balance.checked_sub(&value) {
Some(b) => b,
+34
View File
@@ -241,6 +241,40 @@ fn contract_transfer() {
});
}
#[test]
fn contract_transfer_to_death() {
const CONTRACT_SHOULD_TRANSFER_VALUE: u64 = 6;
let code_transfer = wabt::wat2wasm(CODE_TRANSFER).unwrap();
with_externalities(&mut ExtBuilder::default().existential_deposit(5).build(), || {
<CodeOf<Test>>::insert(1, code_transfer.to_vec());
Balances::set_free_balance(&0, 100_000_000);
Balances::increase_total_stake_by(100_000_000);
Balances::set_free_balance(&1, 6);
Balances::increase_total_stake_by(6);
<StorageOf<Test>>::insert(1, b"foo".to_vec(), b"1".to_vec());
assert_ok!(Contract::call(Origin::signed(0), 1, 0, 100_000, Vec::new()));
assert_eq!(
Balances::free_balance(&0),
// 2 * 10 - gas used by the contract (10) multiplied by gas price (2)
// 2 * 135 - base gas fee for call (by transaction)
// 2 * 135 - base gas fee for call (by the contract)
100_000_000 - (2 * 10) - (2 * 135) - (2 * 135),
);
assert!(!<CodeOf<Test>>::exists(1));
assert!(!<StorageOf<Test>>::exists(1, b"foo".to_vec()));
assert_eq!(Balances::free_balance(&1), 0);
assert_eq!(Balances::free_balance(&9), CONTRACT_SHOULD_TRANSFER_VALUE);
});
}
#[test]
fn contract_transfer_takes_creation_fee() {
const CONTRACT_SHOULD_TRANSFER_VALUE: u64 = 6;