bugfix: balances::transfer for new_account issue#722 (#731)

* bugfix: balances::transfer for new_account

issue:#722
would_create flag should depend on dest, not origin.
change 
```rust
let would_create = from_balance.is_zero();
```
to 
```rust
    let to_balance = Self::free_balance(&dest); 
    let would_create = to_balance.is_zero(); 
```
in the other hand, provide `fn new_test_ext2()` and let `transfer_fee=10`, `creation_fee=50` for test case

* Update lib.rs

* Update tests.rs

* Make `impl_outer_origin!` support generic `Origin`s (#732)

* Make `impl_outer_origin!` support generic `Origin`s

* Support empty outer origin

* Contracts: fix transfer function. (#733)

* Remove dependency on the parity repo (#734)

* Fix test

* Anothe fix
This commit is contained in:
金XX(Aton)
2018-09-13 21:54:56 +08:00
committed by Gav Wood
parent a7f8f0f1bd
commit ca8f0d6625
4 changed files with 112 additions and 3 deletions
+6
View File
@@ -121,6 +121,7 @@ mod tests {
twox_128(<balances::TransactionBaseFee<Runtime>>::key()).to_vec() => vec![70u8; 8],
twox_128(<balances::TransactionByteFee<Runtime>>::key()).to_vec() => vec![0u8; 8],
twox_128(<balances::ExistentialDeposit<Runtime>>::key()).to_vec() => vec![0u8; 8],
twox_128(<balances::CreationFee<Runtime>>::key()).to_vec() => vec![0u8; 8],
twox_128(<balances::TransferFee<Runtime>>::key()).to_vec() => vec![0u8; 8],
twox_128(<balances::NextEnumSet<Runtime>>::key()).to_vec() => vec![0u8; 8],
twox_128(&<system::BlockHash<Runtime>>::key_for(0)).to_vec() => vec![0u8; 32]
@@ -141,6 +142,7 @@ mod tests {
twox_128(<balances::TransactionBaseFee<Runtime>>::key()).to_vec() => vec![70u8; 8],
twox_128(<balances::TransactionByteFee<Runtime>>::key()).to_vec() => vec![0u8; 8],
twox_128(<balances::ExistentialDeposit<Runtime>>::key()).to_vec() => vec![0u8; 8],
twox_128(<balances::CreationFee<Runtime>>::key()).to_vec() => vec![0u8; 8],
twox_128(<balances::TransferFee<Runtime>>::key()).to_vec() => vec![0u8; 8],
twox_128(<balances::NextEnumSet<Runtime>>::key()).to_vec() => vec![0u8; 8],
twox_128(&<system::BlockHash<Runtime>>::key_for(0)).to_vec() => vec![0u8; 32]
@@ -161,6 +163,7 @@ mod tests {
twox_128(<balances::TransactionBaseFee<Runtime>>::key()).to_vec() => vec![0u8; 8],
twox_128(<balances::TransactionByteFee<Runtime>>::key()).to_vec() => vec![0u8; 8],
twox_128(<balances::ExistentialDeposit<Runtime>>::key()).to_vec() => vec![0u8; 8],
twox_128(<balances::CreationFee<Runtime>>::key()).to_vec() => vec![0u8; 8],
twox_128(<balances::TransferFee<Runtime>>::key()).to_vec() => vec![0u8; 8],
twox_128(<balances::NextEnumSet<Runtime>>::key()).to_vec() => vec![0u8; 8],
twox_128(&<system::BlockHash<Runtime>>::key_for(0)).to_vec() => vec![0u8; 32]
@@ -185,6 +188,7 @@ mod tests {
twox_128(<balances::TransactionBaseFee<Runtime>>::key()).to_vec() => vec![0u8; 8],
twox_128(<balances::TransactionByteFee<Runtime>>::key()).to_vec() => vec![0u8; 8],
twox_128(<balances::ExistentialDeposit<Runtime>>::key()).to_vec() => vec![0u8; 8],
twox_128(<balances::CreationFee<Runtime>>::key()).to_vec() => vec![0u8; 8],
twox_128(<balances::TransferFee<Runtime>>::key()).to_vec() => vec![0u8; 8],
twox_128(<balances::NextEnumSet<Runtime>>::key()).to_vec() => vec![0u8; 8],
twox_128(&<system::BlockHash<Runtime>>::key_for(0)).to_vec() => vec![0u8; 32]
@@ -483,6 +487,7 @@ mod tests {
twox_128(<balances::TransactionBaseFee<Runtime>>::key()).to_vec() => vec![70u8; 8],
twox_128(<balances::TransactionByteFee<Runtime>>::key()).to_vec() => vec![0u8; 8],
twox_128(<balances::ExistentialDeposit<Runtime>>::key()).to_vec() => vec![0u8; 8],
twox_128(<balances::CreationFee<Runtime>>::key()).to_vec() => vec![0u8; 8],
twox_128(<balances::TransferFee<Runtime>>::key()).to_vec() => vec![0u8; 8],
twox_128(<balances::NextEnumSet<Runtime>>::key()).to_vec() => vec![0u8; 8],
twox_128(&<system::BlockHash<Runtime>>::key_for(0)).to_vec() => vec![0u8; 32]
@@ -504,6 +509,7 @@ mod tests {
twox_128(<balances::TransactionBaseFee<Runtime>>::key()).to_vec() => vec![0u8; 8],
twox_128(<balances::TransactionByteFee<Runtime>>::key()).to_vec() => vec![0u8; 8],
twox_128(<balances::ExistentialDeposit<Runtime>>::key()).to_vec() => vec![0u8; 8],
twox_128(<balances::CreationFee<Runtime>>::key()).to_vec() => vec![0u8; 8],
twox_128(<balances::TransferFee<Runtime>>::key()).to_vec() => vec![0u8; 8],
twox_128(<balances::NextEnumSet<Runtime>>::key()).to_vec() => vec![0u8; 8],
twox_128(&<system::BlockHash<Runtime>>::key_for(0)).to_vec() => vec![0u8; 32]
+2 -2
View File
@@ -284,7 +284,8 @@ impl<T: Trait> Module<T> {
let dest = Self::lookup(dest)?;
let from_balance = Self::free_balance(&transactor);
let would_create = from_balance.is_zero();
let to_balance = Self::free_balance(&dest);
let would_create = to_balance.is_zero();
let fee = if would_create { Self::creation_fee() } else { Self::transfer_fee() };
let liability = value + fee;
@@ -297,7 +298,6 @@ impl<T: Trait> Module<T> {
}
T::EnsureAccountLiquid::ensure_account_liquid(&transactor)?;
let to_balance = Self::free_balance(&dest);
// NOTE: total stake being stored in the same type means that this could never overflow
// but better to be safe than sorry.
let new_to_balance = match to_balance.checked_add(&value) {
+23
View File
@@ -73,5 +73,28 @@ pub fn new_test_ext(ext_deposit: u64, monied: bool) -> runtime_io::TestExternali
t.into()
}
pub fn new_test_ext2(ext_deposit: u64, monied: bool) -> runtime_io::TestExternalities<Blake2Hasher> {
let mut t = system::GenesisConfig::<Runtime>::default().build_storage().unwrap();
let balance_factor = if ext_deposit > 0 {
256
} else {
1
};
t.extend(GenesisConfig::<Runtime>{
balances: if monied {
vec![(1, 10 * balance_factor), (2, 20 * balance_factor), (3, 30 * balance_factor), (4, 40 * balance_factor)]
} else {
vec![(10, balance_factor), (20, balance_factor)]
},
transaction_base_fee: 0,
transaction_byte_fee: 0,
existential_deposit: ext_deposit,
transfer_fee: 10, // transfer_fee not zero
creation_fee: 50, // creation_fee not zero
reclaim_rebate: 0,
}.build_storage().unwrap());
t.into()
}
pub type System = system::Module<Runtime>;
pub type Balances = Module<Runtime>;
+81 -1
View File
@@ -20,7 +20,7 @@
use super::*;
use runtime_io::with_externalities;
use mock::{Balances, System, Runtime, new_test_ext};
use mock::{Balances, System, Runtime, new_test_ext, new_test_ext2};
#[test]
fn reward_should_work() {
@@ -52,6 +52,29 @@ fn default_indexing_on_new_accounts_should_work() {
});
}
#[test]
fn default_indexing_on_new_accounts_should_work2() {
with_externalities(&mut new_test_ext2(10, true), || {
assert_eq!(Balances::lookup_index(4), None);
// account 1 has 256 * 10 = 2560, account 5 is not exist, ext_deposit is 10, value is 10
assert_ok!(Balances::transfer(Some(1).into(), 5.into(), 10));
assert_eq!(Balances::lookup_index(4), Some(5));
assert_eq!(Balances::free_balance(&1), 256 * 10 - 10 - 50); // 10 is value, 50 is creation_free
});
}
#[test]
fn default_indexing_on_new_accounts_should_not_work2() {
with_externalities(&mut new_test_ext2(10, true), || {
assert_eq!(Balances::lookup_index(4), None);
// account 1 has 256 * 10 = 2560, account 5 is not exist, ext_deposit is 10, value is 9, not satisfies for ext_deposit
assert_noop!(Balances::transfer(Some(1).into(), 5.into(), 9), "value too low to create account");
assert_eq!(Balances::lookup_index(4), None); // account 5 should not exist
assert_eq!(Balances::free_balance(&1), 256 * 10);
});
}
#[test]
fn dust_account_removal_should_work() {
with_externalities(&mut new_test_ext(256 * 10, true), || {
@@ -66,6 +89,19 @@ fn dust_account_removal_should_work() {
});
}
#[test]
fn dust_account_removal_should_work2() {
with_externalities(&mut new_test_ext2(256 * 10, true), || {
System::inc_account_nonce(&2);
assert_eq!(System::account_nonce(&2), 1);
assert_eq!(Balances::total_balance(&2), 256 * 20);
assert_ok!(Balances::transfer(Some(2).into(), 5.into(), 256 * 10)); // index 1 (account 2) becomes zombie for 256*10 + 50(fee) < 256 * 10 (ext_deposit)
assert_eq!(Balances::total_balance(&2), 0);
assert_eq!(Balances::total_balance(&5), 256 * 10);
assert_eq!(System::account_nonce(&2), 0);
});
}
#[test]
fn reclaim_indexing_on_new_accounts_should_work() {
with_externalities(&mut new_test_ext(256 * 1, true), || {
@@ -82,6 +118,22 @@ fn reclaim_indexing_on_new_accounts_should_work() {
});
}
#[test]
fn reclaim_indexing_on_new_accounts_should_work2() {
with_externalities(&mut new_test_ext2(256 * 1, true), || {
assert_eq!(Balances::lookup_index(1), Some(2));
assert_eq!(Balances::lookup_index(4), None);
assert_eq!(Balances::total_balance(&2), 256 * 20);
assert_ok!(Balances::transfer(Some(2).into(), 5.into(), 256 * 20 - 50)); // account 2 becomes zombie freeing index 1 for reclaim) 50 is creation fee
assert_eq!(Balances::total_balance(&2), 0);
assert_ok!(Balances::transfer(Some(5).into(), 6.into(), 256 * 1 + 0x69)); // account 6 takes index 1.
assert_eq!(Balances::total_balance(&6), 256 * 1 + 0x69);
assert_eq!(Balances::lookup_index(1), Some(6));
});
}
#[test]
fn reserved_balance_should_prevent_reclaim_count() {
with_externalities(&mut new_test_ext(256 * 1, true), || {
@@ -110,6 +162,34 @@ fn reserved_balance_should_prevent_reclaim_count() {
});
}
#[test]
fn reserved_balance_should_prevent_reclaim_count2() {
with_externalities(&mut new_test_ext2(256 * 1, true), || {
System::inc_account_nonce(&2);
assert_eq!(Balances::lookup_index(1), Some(2));
assert_eq!(Balances::lookup_index(4), None);
assert_eq!(Balances::total_balance(&2), 256 * 20);
assert_ok!(Balances::reserve(&2, 256 * 19 + 1)); // account 2 becomes mostly reserved
assert_eq!(Balances::free_balance(&2), 0); // "free" account deleted."
assert_eq!(Balances::total_balance(&2), 256 * 19 + 1); // reserve still exists.
assert_eq!(System::account_nonce(&2), 1);
assert_ok!(Balances::transfer(Some(4).into(), 5.into(), 256 * 1 + 0x69)); // account 4 tries to take index 1 for account 5.
assert_eq!(Balances::total_balance(&5), 256 * 1 + 0x69);
assert_eq!(Balances::lookup_index(1), Some(2)); // but fails.
assert_eq!(System::account_nonce(&2), 1);
assert_eq!(Balances::slash(&2, 256 * 18 + 2), None); // account 2 gets slashed
assert_eq!(Balances::total_balance(&2), 0); // "free" account deleted."
assert_eq!(System::account_nonce(&2), 0);
assert_ok!(Balances::transfer(Some(4).into(), 6.into(), 256 * 1 + 0x69)); // account 4 tries to take index 1 again for account 6.
assert_eq!(Balances::total_balance(&6), 256 * 1 + 0x69);
assert_eq!(Balances::lookup_index(1), Some(6)); // and succeeds.
});
}
#[test]
fn balance_works() {
with_externalities(&mut new_test_ext(0, false), || {