Insufficient asset quota and deposits (#10382)

* Allow asset accounts to exist by deposit

* Place limit on consumers (and therefore freebie asset accounts)

* Maximum number of assets

* Fixes

* Fixes

* Formatting

* Docs

* Formatting

* Destroyed assets are properly tidied

* Update frame/assets/src/types.rs

Co-authored-by: Guillaume Thiolliere <gui.thiolliere@gmail.com>

* Docs

* Docs

* Formatting

* Docs

* Docs

* Fixes

* Fixes

Co-authored-by: Guillaume Thiolliere <gui.thiolliere@gmail.com>
This commit is contained in:
Gavin Wood
2021-12-09 13:22:54 +01:00
committed by GitHub
parent 73bc2f420e
commit 3dd8f83a3a
84 changed files with 513 additions and 154 deletions
+97 -6
View File
@@ -34,6 +34,97 @@ fn basic_minting_should_work() {
});
}
#[test]
fn minting_too_many_insufficient_assets_fails() {
new_test_ext().execute_with(|| {
assert_ok!(Assets::force_create(Origin::root(), 0, 1, false, 1));
assert_ok!(Assets::force_create(Origin::root(), 1, 1, false, 1));
assert_ok!(Assets::force_create(Origin::root(), 2, 1, false, 1));
Balances::make_free_balance_be(&1, 100);
assert_ok!(Assets::mint(Origin::signed(1), 0, 1, 100));
assert_ok!(Assets::mint(Origin::signed(1), 1, 1, 100));
assert_noop!(Assets::mint(Origin::signed(1), 2, 1, 100), TokenError::CannotCreate);
Balances::make_free_balance_be(&2, 1);
assert_ok!(Assets::transfer(Origin::signed(1), 0, 2, 100));
assert_ok!(Assets::mint(Origin::signed(1), 2, 1, 100));
});
}
#[test]
fn minting_insufficient_asset_with_deposit_should_work_when_consumers_exhausted() {
new_test_ext().execute_with(|| {
assert_ok!(Assets::force_create(Origin::root(), 0, 1, false, 1));
assert_ok!(Assets::force_create(Origin::root(), 1, 1, false, 1));
assert_ok!(Assets::force_create(Origin::root(), 2, 1, false, 1));
Balances::make_free_balance_be(&1, 100);
assert_ok!(Assets::mint(Origin::signed(1), 0, 1, 100));
assert_ok!(Assets::mint(Origin::signed(1), 1, 1, 100));
assert_noop!(Assets::mint(Origin::signed(1), 2, 1, 100), TokenError::CannotCreate);
assert_ok!(Assets::touch(Origin::signed(1), 2));
assert_eq!(Balances::reserved_balance(&1), 10);
assert_ok!(Assets::mint(Origin::signed(1), 2, 1, 100));
});
}
#[test]
fn minting_insufficient_assets_with_deposit_without_consumer_should_work() {
new_test_ext().execute_with(|| {
assert_ok!(Assets::force_create(Origin::root(), 0, 1, false, 1));
assert_noop!(Assets::mint(Origin::signed(1), 0, 1, 100), TokenError::CannotCreate);
Balances::make_free_balance_be(&1, 100);
assert_ok!(Assets::touch(Origin::signed(1), 0));
assert_ok!(Assets::mint(Origin::signed(1), 0, 1, 100));
assert_eq!(Balances::reserved_balance(&1), 10);
assert_eq!(System::consumers(&1), 0);
});
}
#[test]
fn refunding_asset_deposit_with_burn_should_work() {
new_test_ext().execute_with(|| {
assert_ok!(Assets::force_create(Origin::root(), 0, 1, false, 1));
Balances::make_free_balance_be(&1, 100);
assert_ok!(Assets::touch(Origin::signed(1), 0));
assert_ok!(Assets::mint(Origin::signed(1), 0, 1, 100));
assert_ok!(Assets::refund(Origin::signed(1), 0, true));
assert_eq!(Balances::reserved_balance(&1), 0);
assert_eq!(Assets::balance(1, 0), 0);
});
}
#[test]
fn refunding_asset_deposit_with_burn_disallowed_should_fail() {
new_test_ext().execute_with(|| {
assert_ok!(Assets::force_create(Origin::root(), 0, 1, false, 1));
Balances::make_free_balance_be(&1, 100);
assert_ok!(Assets::touch(Origin::signed(1), 0));
assert_ok!(Assets::mint(Origin::signed(1), 0, 1, 100));
assert_noop!(Assets::refund(Origin::signed(1), 0, false), Error::<Test>::WouldBurn);
});
}
#[test]
fn refunding_asset_deposit_without_burn_should_work() {
new_test_ext().execute_with(|| {
assert_ok!(Assets::force_create(Origin::root(), 0, 1, false, 1));
assert_noop!(Assets::mint(Origin::signed(1), 0, 1, 100), TokenError::CannotCreate);
Balances::make_free_balance_be(&1, 100);
assert_ok!(Assets::touch(Origin::signed(1), 0));
assert_ok!(Assets::mint(Origin::signed(1), 0, 1, 100));
Balances::make_free_balance_be(&2, 100);
assert_ok!(Assets::transfer(Origin::signed(1), 0, 2, 100));
assert_eq!(Assets::balance(0, 2), 100);
assert_eq!(Assets::balance(0, 1), 0);
assert_eq!(Balances::reserved_balance(&1), 10);
assert_ok!(Assets::refund(Origin::signed(1), 0, false));
assert_eq!(Balances::reserved_balance(&1), 0);
assert_eq!(Assets::balance(1, 0), 0);
});
}
#[test]
fn approval_lifecycle_works() {
new_test_ext().execute_with(|| {
@@ -299,17 +390,17 @@ fn min_balance_should_work() {
// When deducting from an account to below minimum, it should be reaped.
assert_ok!(Assets::transfer(Origin::signed(1), 0, 2, 91));
assert!(Assets::balance(0, 1).is_zero());
assert!(Assets::maybe_balance(0, 1).is_none());
assert_eq!(Assets::balance(0, 2), 100);
assert_eq!(Asset::<Test>::get(0).unwrap().accounts, 1);
assert_ok!(Assets::force_transfer(Origin::signed(1), 0, 2, 1, 91));
assert!(Assets::balance(0, 2).is_zero());
assert!(Assets::maybe_balance(0, 2).is_none());
assert_eq!(Assets::balance(0, 1), 100);
assert_eq!(Asset::<Test>::get(0).unwrap().accounts, 1);
assert_ok!(Assets::burn(Origin::signed(1), 0, 1, 91));
assert!(Assets::balance(0, 1).is_zero());
assert!(Assets::maybe_balance(0, 1).is_none());
assert_eq!(Asset::<Test>::get(0).unwrap().accounts, 0);
});
}
@@ -488,7 +579,7 @@ fn transferring_amount_more_than_available_balance_should_not_work() {
assert_eq!(Assets::balance(0, 2), 50);
assert_ok!(Assets::burn(Origin::signed(1), 0, 1, u64::MAX));
assert_eq!(Assets::balance(0, 1), 0);
assert_noop!(Assets::transfer(Origin::signed(1), 0, 1, 50), Error::<Test>::BalanceLow);
assert_noop!(Assets::transfer(Origin::signed(1), 0, 1, 50), Error::<Test>::NoAccount);
assert_noop!(Assets::transfer(Origin::signed(2), 0, 1, 51), Error::<Test>::BalanceLow);
});
}
@@ -536,7 +627,7 @@ fn burning_asset_balance_with_zero_balance_does_nothing() {
assert_ok!(Assets::force_create(Origin::root(), 0, 1, true, 1));
assert_ok!(Assets::mint(Origin::signed(1), 0, 1, 100));
assert_eq!(Assets::balance(0, 2), 0);
assert_ok!(Assets::burn(Origin::signed(1), 0, 2, u64::MAX));
assert_noop!(Assets::burn(Origin::signed(1), 0, 2, u64::MAX), Error::<Test>::NoAccount);
assert_eq!(Assets::balance(0, 2), 0);
assert_eq!(Assets::total_supply(0), 100);
});
@@ -688,7 +779,7 @@ fn force_metadata_should_work() {
);
// string length limit check
let limit = StringLimit::get() as usize;
let limit = 50usize;
assert_noop!(
Assets::force_set_metadata(
Origin::root(),