Freeze Assets and Asset Metadata (#7346)

* Features needed for reserve-backed stablecoins

* Builds & tests.

* Double map for an efficient destroy.

* Update frame/assets/src/lib.rs

Co-authored-by: Nikolay Volf <nikvolf@gmail.com>

* ED/zombie-count/refs

Feature: ED/minimum balance enforcement
Feature: enforce zombie count
Feature: allow system-alive accounts to exist, but add reference

* Update frame/assets/src/lib.rs

Co-authored-by: Nikolay Volf <nikvolf@gmail.com>

* Update frame/assets/Cargo.toml

Co-authored-by: Niklas Adolfsson <niklasadolfsson1@gmail.com>

* Docs

* Some tests

* More tests

* Allow for max_zombies to be adjusted

* Test for set_max_zombies

* Tests and a couple of fixes

* First few benchmarks

* Benchmarks.

* Fix error message in test

* Fixes

* Fixes

* Fixes

* cargo run --release --features runtime-benchmarks --manifest-path bin/node/cli/Cargo.toml -- benchmark --chain dev --steps 50 --repeat 20 --extrinsic * --execution=wasm --wasm-execution=compiled --output ./bin/node/runtime/src/weights --header ./HEADER --pallet pallet_assets

* Update frame/assets/src/lib.rs

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

* Fixes

* Fixes

* Fixes

* cargo run --release --features runtime-benchmarks --manifest-path bin/node/cli/Cargo.toml -- benchmark --chain dev --steps 50 --repeat 20 --extrinsic * --execution=wasm --wasm-execution=compiled --output ./bin/node/runtime/src/weights --header ./HEADER --pallet pallet_assets

* Fixes

* Update default weight

* Add proper verification to benchmarks

* minor improvements to tests

* Add `freeze_asset` and `thaw_asset`

* Add metadata

* fix build

* Update benchmarks

* fix line width

* cargo run --release --features runtime-benchmarks --manifest-path bin/node/cli/Cargo.toml -- benchmark --chain dev --steps 50 --repeat 20 --extrinsic * --execution=wasm --wasm-execution=compiled --output ./bin/node/runtime/src/weights --header ./HEADER --pallet pallet_assets

* update default weights

* destroy cleans up metadata

* more comprehensive lifecycle test

* update docs

* Update frame/assets/src/benchmarking.rs

Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com>

* Fix

* New weights system

* fix compile

* cargo run --release --features=runtime-benchmarks --manifest-path=bin/node/cli/Cargo.toml -- benchmark --chain=dev --steps=50 --repeat=20 --pallet=pallet_assets --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --output=./frame/assets/src/weights.rs --template=./.maintain/frame-weight-template.hbs

* fix compile

* fix up

* cargo run --release --features=runtime-benchmarks --manifest-path=bin/node/cli/Cargo.toml -- benchmark --chain=dev --steps=50 --repeat=20 --pallet=pallet_assets --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --output=./frame/assets/src/weights.rs --template=./.maintain/frame-weight-template.hbs

* fixes to pallet compile

* fix node build

* remote diff artifacts

* less diff

* cargo run --release --features=runtime-benchmarks --manifest-path=bin/node/cli/Cargo.toml -- benchmark --chain=dev --steps=50 --repeat=20 --pallet=pallet_assets --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --output=./frame/assets/src/weights.rs --template=./.maintain/frame-weight-template.hbs

* Update frame/assets/src/lib.rs

* Update frame/assets/src/lib.rs

* usize to u32

* missed some usize

* cargo run --release --features=runtime-benchmarks --manifest-path=bin/node/cli/Cargo.toml -- benchmark --chain=dev --steps=50 --repeat=20 --pallet=pallet_assets --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --output=./frame/assets/src/weights.rs --template=./.maintain/frame-weight-template.hbs

Co-authored-by: Gav Wood <gavin@parity.io>
Co-authored-by: Nikolay Volf <nikvolf@gmail.com>
Co-authored-by: Niklas Adolfsson <niklasadolfsson1@gmail.com>
Co-authored-by: Parity Benchmarking Bot <admin@parity.io>
Co-authored-by: Guillaume Thiolliere <gui.thiolliere@gmail.com>
Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com>
This commit is contained in:
Shawn Tabrizi
2021-01-19 07:14:32 -04:00
committed by GitHub
parent 8e04515912
commit 748bdf65d3
4 changed files with 416 additions and 41 deletions
+6
View File
@@ -979,6 +979,9 @@ impl pallet_lottery::Config for Runtime {
parameter_types! {
pub const AssetDepositBase: Balance = 100 * DOLLARS;
pub const AssetDepositPerZombie: Balance = 1 * DOLLARS;
pub const StringLimit: u32 = 50;
pub const MetadataDepositBase: Balance = 10 * DOLLARS;
pub const MetadataDepositPerByte: Balance = 1 * DOLLARS;
}
impl pallet_assets::Config for Runtime {
@@ -989,6 +992,9 @@ impl pallet_assets::Config for Runtime {
type ForceOrigin = EnsureRoot<AccountId>;
type AssetDepositBase = AssetDepositBase;
type AssetDepositPerZombie = AssetDepositPerZombie;
type StringLimit = StringLimit;
type MetadataDepositBase = MetadataDepositBase;
type MetadataDepositPerByte = MetadataDepositPerByte;
type WeightInfo = pallet_assets::weights::SubstrateWeight<Runtime>;
}
+57 -4
View File
@@ -18,7 +18,6 @@
//! Assets pallet benchmarking.
use super::*;
use sp_std::prelude::*;
use sp_runtime::traits::Bounded;
use frame_system::RawOrigin as SystemOrigin;
use frame_benchmarking::{benchmarks, account, whitelisted_caller};
@@ -154,16 +153,34 @@ benchmarks! {
thaw {
let (caller, caller_lookup) = create_default_minted_asset::<T>(10, 100u32.into());
assert!(Assets::<T>::freeze(
Assets::<T>::freeze(
SystemOrigin::Signed(caller.clone()).into(),
Default::default(),
caller_lookup.clone()
).is_ok());
caller_lookup.clone(),
)?;
}: _(SystemOrigin::Signed(caller.clone()), Default::default(), caller_lookup)
verify {
assert_last_event::<T>(RawEvent::Thawed(Default::default(), caller).into());
}
freeze_asset {
let (caller, caller_lookup) = create_default_minted_asset::<T>(10, 100u32.into());
}: _(SystemOrigin::Signed(caller.clone()), Default::default())
verify {
assert_last_event::<T>(RawEvent::AssetFrozen(Default::default()).into());
}
thaw_asset {
let (caller, caller_lookup) = create_default_minted_asset::<T>(10, 100u32.into());
Assets::<T>::freeze_asset(
SystemOrigin::Signed(caller.clone()).into(),
Default::default(),
)?;
}: _(SystemOrigin::Signed(caller.clone()), Default::default())
verify {
assert_last_event::<T>(RawEvent::AssetThawed(Default::default()).into());
}
transfer_ownership {
let (caller, _) = create_default_asset::<T>(10);
let target: T::AccountId = account("target", 0, SEED);
@@ -196,6 +213,21 @@ benchmarks! {
verify {
assert_last_event::<T>(RawEvent::MaxZombiesChanged(Default::default(), max_zombies).into());
}
set_metadata {
let n in 0 .. T::StringLimit::get();
let s in 0 .. T::StringLimit::get();
let name = vec![0u8; n as usize];
let symbol = vec![0u8; s as usize];
let decimals = 12;
let (caller, _) = create_default_asset::<T>(10);
T::Currency::make_free_balance_be(&caller, BalanceOf::<T>::max_value());
}: _(SystemOrigin::Signed(caller), Default::default(), name.clone(), symbol.clone(), decimals)
verify {
assert_last_event::<T>(RawEvent::MetadataSet(Default::default(), name, symbol, decimals).into());
}
}
#[cfg(test)]
@@ -273,6 +305,20 @@ mod tests {
});
}
#[test]
fn freeze_asset() {
new_test_ext().execute_with(|| {
assert!(test_benchmark_freeze_asset::<Test>().is_ok());
});
}
#[test]
fn thaw_asset() {
new_test_ext().execute_with(|| {
assert!(test_benchmark_thaw_asset::<Test>().is_ok());
});
}
#[test]
fn transfer_ownership() {
new_test_ext().execute_with(|| {
@@ -293,4 +339,11 @@ mod tests {
assert!(test_benchmark_set_max_zombies::<Test>().is_ok());
});
}
#[test]
fn set_metadata() {
new_test_ext().execute_with(|| {
assert!(test_benchmark_set_metadata::<Test>().is_ok());
});
}
}
+275 -4
View File
@@ -113,7 +113,7 @@
mod benchmarking;
pub mod weights;
use sp_std::{fmt::Debug};
use sp_std::{fmt::Debug, prelude::*};
use sp_runtime::{RuntimeDebug, traits::{
Member, AtLeast32BitUnsigned, Zero, StaticLookup, Saturating, CheckedSub, CheckedAdd
}};
@@ -151,6 +151,16 @@ pub trait Config: frame_system::Config {
/// supports.
type AssetDepositPerZombie: Get<BalanceOf<Self>>;
/// The maximum length of a name or symbol stored on-chain.
type StringLimit: Get<u32>;
/// The basic amount of funds that must be reserved when adding metadata to your asset.
type MetadataDepositBase: Get<BalanceOf<Self>>;
/// The additional funds that must be reserved for the number of bytes you store in your
/// metadata.
type MetadataDepositPerByte: Get<BalanceOf<Self>>;
/// Weight information for extrinsics in this pallet.
type WeightInfo: WeightInfo;
}
@@ -184,6 +194,8 @@ pub struct AssetDetails<
zombies: u32,
/// The total number of accounts.
accounts: u32,
/// Whether the asset is frozen for permissionless transfers.
is_frozen: bool,
}
#[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, Default)]
@@ -198,6 +210,20 @@ pub struct AssetBalance<
is_zombie: bool,
}
#[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, Default)]
pub struct AssetMetadata<DepositBalance> {
/// The balance deposited for this metadata.
///
/// This pays for the data stored in this struct.
deposit: DepositBalance,
/// The user friendly name of this asset. Limited in length by `StringLimit`.
name: Vec<u8>,
/// The ticker symbol for this asset. Limited in length by `StringLimit`.
symbol: Vec<u8>,
/// The number of decimals this asset uses to represent one unit.
decimals: u8,
}
decl_storage! {
trait Store for Module<T: Config> as Assets {
/// Details of an asset.
@@ -212,6 +238,9 @@ decl_storage! {
hasher(blake2_128_concat) T::AssetId,
hasher(blake2_128_concat) T::AccountId
=> AssetBalance<T::Balance>;
/// Metadata of an asset.
Metadata: map hasher(blake2_128_concat) T::AssetId => AssetMetadata<BalanceOf<T>>;
}
}
@@ -239,12 +268,18 @@ decl_event! {
Frozen(AssetId, AccountId),
/// Some account `who` was thawed. \[asset_id, who\]
Thawed(AssetId, AccountId),
/// Some asset `asset_id` was frozen. \[asset_id\]
AssetFrozen(AssetId),
/// Some asset `asset_id` was thawed. \[asset_id\]
AssetThawed(AssetId),
/// An asset class was destroyed.
Destroyed(AssetId),
/// Some asset class was force-created. \[asset_id, owner\]
ForceCreated(AssetId, AccountId),
/// The maximum amount of zombies allowed has changed. \[asset_id, max_zombies\]
MaxZombiesChanged(AssetId, u32),
/// New metadata has been set for an asset. \[asset_id, name, symbol, decimals\]
MetadataSet(AssetId, Vec<u8>, Vec<u8>, u8),
}
}
@@ -276,6 +311,8 @@ decl_error! {
Overflow,
/// Some internal state is broken.
BadState,
/// Invalid metadata given.
BadMetadata,
}
}
@@ -337,6 +374,7 @@ decl_module! {
min_balance,
zombies: Zero::zero(),
accounts: Zero::zero(),
is_frozen: false,
});
Self::deposit_event(RawEvent::Created(id, owner, admin));
}
@@ -386,6 +424,7 @@ decl_module! {
min_balance,
zombies: Zero::zero(),
accounts: Zero::zero(),
is_frozen: false,
});
Self::deposit_event(RawEvent::ForceCreated(id, owner));
}
@@ -412,7 +451,9 @@ decl_module! {
ensure!(details.owner == origin, Error::<T>::NoPermission);
ensure!(details.accounts == details.zombies, Error::<T>::RefsLeft);
ensure!(details.zombies <= zombies_witness, Error::<T>::BadWitness);
T::Currency::unreserve(&details.owner, details.deposit);
let metadata = Metadata::<T>::take(&id);
T::Currency::unreserve(&details.owner, details.deposit.saturating_add(metadata.deposit));
*maybe_details = None;
Account::<T>::remove_prefix(&id);
@@ -442,7 +483,9 @@ decl_module! {
let details = maybe_details.take().ok_or(Error::<T>::Unknown)?;
ensure!(details.accounts == details.zombies, Error::<T>::RefsLeft);
ensure!(details.zombies <= zombies_witness, Error::<T>::BadWitness);
T::Currency::unreserve(&details.owner, details.deposit);
let metadata = Metadata::<T>::take(&id);
T::Currency::unreserve(&details.owner, details.deposit.saturating_add(metadata.deposit));
*maybe_details = None;
Account::<T>::remove_prefix(&id);
@@ -580,6 +623,7 @@ decl_module! {
let dest = T::Lookup::lookup(target)?;
Asset::<T>::try_mutate(id, |maybe_details| {
let details = maybe_details.as_mut().ok_or(Error::<T>::Unknown)?;
ensure!(!details.is_frozen, Error::<T>::Frozen);
if dest == origin {
return Ok(())
@@ -739,6 +783,54 @@ decl_module! {
Self::deposit_event(Event::<T>::Thawed(id, who));
}
/// Disallow further unprivileged transfers for the asset class.
///
/// Origin must be Signed and the sender should be the Freezer of the asset `id`.
///
/// - `id`: The identifier of the asset to be frozen.
///
/// Emits `Frozen`.
///
/// Weight: `O(1)`
#[weight = T::WeightInfo::freeze_asset()]
fn freeze_asset(origin, #[compact] id: T::AssetId) -> DispatchResult {
let origin = ensure_signed(origin)?;
Asset::<T>::try_mutate(id, |maybe_details| {
let d = maybe_details.as_mut().ok_or(Error::<T>::Unknown)?;
ensure!(&origin == &d.freezer, Error::<T>::NoPermission);
d.is_frozen = true;
Self::deposit_event(Event::<T>::AssetFrozen(id));
Ok(())
})
}
/// Allow unprivileged transfers for the asset again.
///
/// Origin must be Signed and the sender should be the Admin of the asset `id`.
///
/// - `id`: The identifier of the asset to be frozen.
///
/// Emits `Thawed`.
///
/// Weight: `O(1)`
#[weight = T::WeightInfo::thaw_asset()]
fn thaw_asset(origin, #[compact] id: T::AssetId) -> DispatchResult {
let origin = ensure_signed(origin)?;
Asset::<T>::try_mutate(id, |maybe_details| {
let d = maybe_details.as_mut().ok_or(Error::<T>::Unknown)?;
ensure!(&origin == &d.admin, Error::<T>::NoPermission);
d.is_frozen = false;
Self::deposit_event(Event::<T>::AssetThawed(id));
Ok(())
})
}
/// Change the Owner of an asset.
///
/// Origin must be Signed and the sender should be the Owner of the asset `id`.
@@ -809,6 +901,20 @@ decl_module! {
})
}
/// Set the maximum number of zombie accounts for an asset.
///
/// Origin must be Signed and the sender should be the Owner of the asset `id`.
///
/// Funds of sender are reserved according to the formula:
/// `AssetDepositBase + AssetDepositPerZombie * max_zombies` taking into account
/// any already reserved funds.
///
/// - `id`: The identifier of the asset to update zombie count.
/// - `max_zombies`: The new number of zombies allowed for this asset.
///
/// Emits `MaxZombiesChanged`.
///
/// Weight: `O(1)`
#[weight = T::WeightInfo::set_max_zombies()]
fn set_max_zombies(origin,
#[compact] id: T::AssetId,
@@ -837,6 +943,76 @@ decl_module! {
Ok(())
})
}
/// Set the metadata for an asset.
///
/// NOTE: There is no `unset_metadata` call. Simply pass an empty name, symbol,
/// and 0 decimals to this function to remove the metadata of an asset and
/// return your deposit.
///
/// Origin must be Signed and the sender should be the Owner of the asset `id`.
///
/// Funds of sender are reserved according to the formula:
/// `MetadataDepositBase + MetadataDepositPerByte * (name.len + symbol.len)` taking into
/// account any already reserved funds.
///
/// - `id`: The identifier of the asset to update.
/// - `name`: The user friendly name of this asset. Limited in length by `StringLimit`.
/// - `symbol`: The exchange symbol for this asset. Limited in length by `StringLimit`.
/// - `decimals`: The number of decimals this asset uses to represent one unit.
///
/// Emits `MaxZombiesChanged`.
///
/// Weight: `O(1)`
#[weight = T::WeightInfo::set_metadata(name.len() as u32, symbol.len() as u32)]
fn set_metadata(origin,
#[compact] id: T::AssetId,
name: Vec<u8>,
symbol: Vec<u8>,
decimals: u8,
) -> DispatchResult {
let origin = ensure_signed(origin)?;
ensure!(name.len() <= T::StringLimit::get() as usize, Error::<T>::BadMetadata);
ensure!(symbol.len() <= T::StringLimit::get() as usize, Error::<T>::BadMetadata);
let d = Asset::<T>::get(id).ok_or(Error::<T>::Unknown)?;
ensure!(&origin == &d.owner, Error::<T>::NoPermission);
Metadata::<T>::try_mutate_exists(id, |metadata| {
let bytes_used = name.len() + symbol.len();
let old_deposit = match metadata {
Some(m) => m.deposit,
None => Default::default()
};
// Metadata is being removed
if bytes_used.is_zero() && decimals.is_zero() {
T::Currency::unreserve(&origin, old_deposit);
*metadata = None;
} else {
let new_deposit = T::MetadataDepositPerByte::get()
.saturating_mul(((name.len() + symbol.len()) as u32).into())
.saturating_add(T::MetadataDepositBase::get());
if new_deposit > old_deposit {
T::Currency::reserve(&origin, new_deposit - old_deposit)?;
} else {
T::Currency::unreserve(&origin, old_deposit - new_deposit);
}
*metadata = Some(AssetMetadata {
deposit: new_deposit,
name: name.clone(),
symbol: symbol.clone(),
decimals,
})
}
Self::deposit_event(RawEvent::MetadataSet(id, name, symbol, decimals));
Ok(())
})
}
}
}
@@ -912,6 +1088,7 @@ mod tests {
use frame_support::{impl_outer_origin, assert_ok, assert_noop, parameter_types, impl_outer_event};
use sp_core::H256;
use sp_runtime::{traits::{BlakeTwo256, IdentityLookup}, testing::Header};
use pallet_balances::Error as BalancesError;
mod pallet_assets {
pub use crate::Event;
@@ -976,6 +1153,9 @@ mod tests {
parameter_types! {
pub const AssetDepositBase: u64 = 1;
pub const AssetDepositPerZombie: u64 = 1;
pub const StringLimit: u32 = 50;
pub const MetadataDepositBase: u64 = 1;
pub const MetadataDepositPerByte: u64 = 1;
}
impl Config for Test {
@@ -986,6 +1166,9 @@ mod tests {
type ForceOrigin = frame_system::EnsureRoot<u64>;
type AssetDepositBase = AssetDepositBase;
type AssetDepositPerZombie = AssetDepositPerZombie;
type StringLimit = StringLimit;
type MetadataDepositBase = MetadataDepositBase;
type MetadataDepositPerByte = MetadataDepositPerByte;
type WeightInfo = ();
}
type System = frame_system::Module<Test>;
@@ -1013,15 +1196,41 @@ mod tests {
Balances::make_free_balance_be(&1, 100);
assert_ok!(Assets::create(Origin::signed(1), 0, 1, 10, 1));
assert_eq!(Balances::reserved_balance(&1), 11);
assert!(Asset::<Test>::contains_key(0));
assert_ok!(Assets::set_metadata(Origin::signed(1), 0, vec![0], vec![0], 12));
assert_eq!(Balances::reserved_balance(&1), 14);
assert!(Metadata::<Test>::contains_key(0));
assert_ok!(Assets::mint(Origin::signed(1), 0, 10, 100));
assert_ok!(Assets::mint(Origin::signed(1), 0, 20, 100));
assert_eq!(Account::<Test>::iter_prefix(0).count(), 2);
assert_ok!(Assets::destroy(Origin::signed(1), 0, 100));
assert_eq!(Balances::reserved_balance(&1), 0);
assert!(!Asset::<Test>::contains_key(0));
assert!(!Metadata::<Test>::contains_key(0));
assert_eq!(Account::<Test>::iter_prefix(0).count(), 0);
assert_ok!(Assets::create(Origin::signed(1), 0, 1, 10, 1));
assert_eq!(Balances::reserved_balance(&1), 11);
assert!(Asset::<Test>::contains_key(0));
assert_ok!(Assets::set_metadata(Origin::signed(1), 0, vec![0], vec![0], 12));
assert_eq!(Balances::reserved_balance(&1), 14);
assert!(Metadata::<Test>::contains_key(0));
assert_ok!(Assets::mint(Origin::signed(1), 0, 10, 100));
assert_ok!(Assets::mint(Origin::signed(1), 0, 20, 100));
assert_eq!(Account::<Test>::iter_prefix(0).count(), 2);
assert_ok!(Assets::force_destroy(Origin::root(), 0, 100));
assert_eq!(Balances::reserved_balance(&1), 0);
assert!(!Asset::<Test>::contains_key(0));
assert!(!Metadata::<Test>::contains_key(0));
assert_eq!(Account::<Test>::iter_prefix(0).count(), 0);
});
}
@@ -1172,7 +1381,7 @@ mod tests {
}
#[test]
fn transferring_frozen_balance_should_not_work() {
fn transferring_frozen_user_should_not_work() {
new_test_ext().execute_with(|| {
assert_ok!(Assets::force_create(Origin::root(), 0, 1, 10, 1));
assert_ok!(Assets::mint(Origin::signed(1), 0, 1, 100));
@@ -1184,6 +1393,19 @@ mod tests {
});
}
#[test]
fn transferring_frozen_asset_should_not_work() {
new_test_ext().execute_with(|| {
assert_ok!(Assets::force_create(Origin::root(), 0, 1, 10, 1));
assert_ok!(Assets::mint(Origin::signed(1), 0, 1, 100));
assert_eq!(Assets::balance(0, 1), 100);
assert_ok!(Assets::freeze_asset(Origin::signed(1), 0));
assert_noop!(Assets::transfer(Origin::signed(1), 0, 2, 50), Error::<Test>::Frozen);
assert_ok!(Assets::thaw_asset(Origin::signed(1), 0));
assert_ok!(Assets::transfer(Origin::signed(1), 0, 2, 50));
});
}
#[test]
fn origin_guards_should_work() {
new_test_ext().execute_with(|| {
@@ -1306,4 +1528,53 @@ mod tests {
assert_noop!(Assets::burn(Origin::signed(1), 0, 2, u64::max_value()), Error::<Test>::BalanceZero);
});
}
#[test]
fn set_metadata_should_work() {
new_test_ext().execute_with(|| {
// Cannot add metadata to unknown asset
assert_noop!(
Assets::set_metadata(Origin::signed(1), 0, vec![0u8; 10], vec![0u8; 10], 12),
Error::<Test>::Unknown,
);
assert_ok!(Assets::force_create(Origin::root(), 0, 1, 10, 1));
// Cannot add metadata to unowned asset
assert_noop!(
Assets::set_metadata(Origin::signed(2), 0, vec![0u8; 10], vec![0u8; 10], 12),
Error::<Test>::NoPermission,
);
// Cannot add oversized metadata
assert_noop!(
Assets::set_metadata(Origin::signed(1), 0, vec![0u8; 100], vec![0u8; 10], 12),
Error::<Test>::BadMetadata,
);
assert_noop!(
Assets::set_metadata(Origin::signed(1), 0, vec![0u8; 10], vec![0u8; 100], 12),
Error::<Test>::BadMetadata,
);
// Successfully add metadata and take deposit
Balances::make_free_balance_be(&1, 30);
assert_ok!(Assets::set_metadata(Origin::signed(1), 0, vec![0u8; 10], vec![0u8; 10], 12));
assert_eq!(Balances::free_balance(&1), 9);
// Update deposit
assert_ok!(Assets::set_metadata(Origin::signed(1), 0, vec![0u8; 10], vec![0u8; 5], 12));
assert_eq!(Balances::free_balance(&1), 14);
assert_ok!(Assets::set_metadata(Origin::signed(1), 0, vec![0u8; 10], vec![0u8; 15], 12));
assert_eq!(Balances::free_balance(&1), 4);
// Cannot over-reserve
assert_noop!(
Assets::set_metadata(Origin::signed(1), 0, vec![0u8; 20], vec![0u8; 20], 12),
BalancesError::<Test, _>::InsufficientBalance,
);
// Clear Metadata
assert!(Metadata::<Test>::contains_key(0));
assert_ok!(Assets::set_metadata(Origin::signed(1), 0, vec![], vec![], 0));
assert!(!Metadata::<Test>::contains_key(0));
});
}
}
+78 -33
View File
@@ -1,6 +1,6 @@
// This file is part of Substrate.
// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd.
// Copyright (C) 2021 Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: Apache-2.0
// Licensed under the Apache License, Version 2.0 (the "License");
@@ -17,8 +17,8 @@
//! Autogenerated weights for pallet_assets
//!
//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 2.0.0
//! DATE: 2020-12-03, STEPS: [50, ], REPEAT: 20, LOW RANGE: [], HIGH RANGE: []
//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 2.0.1
//! DATE: 2021-01-18, STEPS: [50, ], REPEAT: 20, LOW RANGE: [], HIGH RANGE: []
//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 128
// Executed Command:
@@ -54,154 +54,199 @@ pub trait WeightInfo {
fn force_transfer() -> Weight;
fn freeze() -> Weight;
fn thaw() -> Weight;
fn freeze_asset() -> Weight;
fn thaw_asset() -> Weight;
fn transfer_ownership() -> Weight;
fn set_team() -> Weight;
fn set_max_zombies() -> Weight;
fn set_metadata(n: u32, s: u32, ) -> Weight;
}
/// Weights for pallet_assets using the Substrate node and recommended hardware.
pub struct SubstrateWeight<T>(PhantomData<T>);
impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
fn create() -> Weight {
(58_077_000 as Weight)
(44_459_000 as Weight)
.saturating_add(T::DbWeight::get().reads(1 as Weight))
.saturating_add(T::DbWeight::get().writes(1 as Weight))
}
fn force_create() -> Weight {
(30_497_000 as Weight)
(21_480_000 as Weight)
.saturating_add(T::DbWeight::get().reads(1 as Weight))
.saturating_add(T::DbWeight::get().writes(1 as Weight))
}
fn destroy(z: u32, ) -> Weight {
(0 as Weight)
.saturating_add((1_153_000 as Weight).saturating_mul(z as Weight))
.saturating_add(T::DbWeight::get().reads(1 as Weight))
// Standard Error: 2_000
.saturating_add((1_149_000 as Weight).saturating_mul(z as Weight))
.saturating_add(T::DbWeight::get().reads(2 as Weight))
.saturating_add(T::DbWeight::get().writes(1 as Weight))
.saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(z as Weight)))
}
fn force_destroy(z: u32, ) -> Weight {
(0 as Weight)
.saturating_add((1_153_000 as Weight).saturating_mul(z as Weight))
.saturating_add(T::DbWeight::get().reads(1 as Weight))
// Standard Error: 2_000
.saturating_add((1_146_000 as Weight).saturating_mul(z as Weight))
.saturating_add(T::DbWeight::get().reads(2 as Weight))
.saturating_add(T::DbWeight::get().writes(1 as Weight))
.saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(z as Weight)))
}
fn mint() -> Weight {
(45_600_000 as Weight)
(32_995_000 as Weight)
.saturating_add(T::DbWeight::get().reads(2 as Weight))
.saturating_add(T::DbWeight::get().writes(2 as Weight))
}
fn burn() -> Weight {
(40_143_000 as Weight)
(29_245_000 as Weight)
.saturating_add(T::DbWeight::get().reads(2 as Weight))
.saturating_add(T::DbWeight::get().writes(2 as Weight))
}
fn transfer() -> Weight {
(58_903_000 as Weight)
(42_211_000 as Weight)
.saturating_add(T::DbWeight::get().reads(4 as Weight))
.saturating_add(T::DbWeight::get().writes(3 as Weight))
}
fn force_transfer() -> Weight {
(59_025_000 as Weight)
(42_218_000 as Weight)
.saturating_add(T::DbWeight::get().reads(4 as Weight))
.saturating_add(T::DbWeight::get().writes(3 as Weight))
}
fn freeze() -> Weight {
(43_308_000 as Weight)
(31_079_000 as Weight)
.saturating_add(T::DbWeight::get().reads(2 as Weight))
.saturating_add(T::DbWeight::get().writes(1 as Weight))
}
fn thaw() -> Weight {
(43_383_000 as Weight)
(30_853_000 as Weight)
.saturating_add(T::DbWeight::get().reads(2 as Weight))
.saturating_add(T::DbWeight::get().writes(1 as Weight))
}
fn freeze_asset() -> Weight {
(22_383_000 as Weight)
.saturating_add(T::DbWeight::get().reads(1 as Weight))
.saturating_add(T::DbWeight::get().writes(1 as Weight))
}
fn thaw_asset() -> Weight {
(22_341_000 as Weight)
.saturating_add(T::DbWeight::get().reads(1 as Weight))
.saturating_add(T::DbWeight::get().writes(1 as Weight))
}
fn transfer_ownership() -> Weight {
(31_380_000 as Weight)
(22_782_000 as Weight)
.saturating_add(T::DbWeight::get().reads(1 as Weight))
.saturating_add(T::DbWeight::get().writes(1 as Weight))
}
fn set_team() -> Weight {
(32_049_000 as Weight)
(23_293_000 as Weight)
.saturating_add(T::DbWeight::get().reads(1 as Weight))
.saturating_add(T::DbWeight::get().writes(1 as Weight))
}
fn set_max_zombies() -> Weight {
(57_745_000 as Weight)
(44_525_000 as Weight)
.saturating_add(T::DbWeight::get().reads(1 as Weight))
.saturating_add(T::DbWeight::get().writes(1 as Weight))
}
fn set_metadata(n: u32, s: u32, ) -> Weight {
(49_456_000 as Weight)
// Standard Error: 0
.saturating_add((1_000 as Weight).saturating_mul(n as Weight))
// Standard Error: 0
.saturating_add((6_000 as Weight).saturating_mul(s as Weight))
.saturating_add(T::DbWeight::get().reads(2 as Weight))
.saturating_add(T::DbWeight::get().writes(1 as Weight))
}
}
// For backwards compatibility and tests
impl WeightInfo for () {
fn create() -> Weight {
(58_077_000 as Weight)
(44_459_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(1 as Weight))
.saturating_add(RocksDbWeight::get().writes(1 as Weight))
}
fn force_create() -> Weight {
(30_497_000 as Weight)
(21_480_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(1 as Weight))
.saturating_add(RocksDbWeight::get().writes(1 as Weight))
}
fn destroy(z: u32, ) -> Weight {
(0 as Weight)
.saturating_add((1_153_000 as Weight).saturating_mul(z as Weight))
.saturating_add(RocksDbWeight::get().reads(1 as Weight))
// Standard Error: 2_000
.saturating_add((1_149_000 as Weight).saturating_mul(z as Weight))
.saturating_add(RocksDbWeight::get().reads(2 as Weight))
.saturating_add(RocksDbWeight::get().writes(1 as Weight))
.saturating_add(RocksDbWeight::get().writes((1 as Weight).saturating_mul(z as Weight)))
}
fn force_destroy(z: u32, ) -> Weight {
(0 as Weight)
.saturating_add((1_153_000 as Weight).saturating_mul(z as Weight))
.saturating_add(RocksDbWeight::get().reads(1 as Weight))
// Standard Error: 2_000
.saturating_add((1_146_000 as Weight).saturating_mul(z as Weight))
.saturating_add(RocksDbWeight::get().reads(2 as Weight))
.saturating_add(RocksDbWeight::get().writes(1 as Weight))
.saturating_add(RocksDbWeight::get().writes((1 as Weight).saturating_mul(z as Weight)))
}
fn mint() -> Weight {
(45_600_000 as Weight)
(32_995_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(2 as Weight))
.saturating_add(RocksDbWeight::get().writes(2 as Weight))
}
fn burn() -> Weight {
(40_143_000 as Weight)
(29_245_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(2 as Weight))
.saturating_add(RocksDbWeight::get().writes(2 as Weight))
}
fn transfer() -> Weight {
(58_903_000 as Weight)
(42_211_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(4 as Weight))
.saturating_add(RocksDbWeight::get().writes(3 as Weight))
}
fn force_transfer() -> Weight {
(59_025_000 as Weight)
(42_218_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(4 as Weight))
.saturating_add(RocksDbWeight::get().writes(3 as Weight))
}
fn freeze() -> Weight {
(43_308_000 as Weight)
(31_079_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(2 as Weight))
.saturating_add(RocksDbWeight::get().writes(1 as Weight))
}
fn thaw() -> Weight {
(43_383_000 as Weight)
(30_853_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(2 as Weight))
.saturating_add(RocksDbWeight::get().writes(1 as Weight))
}
fn freeze_asset() -> Weight {
(22_383_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(1 as Weight))
.saturating_add(RocksDbWeight::get().writes(1 as Weight))
}
fn thaw_asset() -> Weight {
(22_341_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(1 as Weight))
.saturating_add(RocksDbWeight::get().writes(1 as Weight))
}
fn transfer_ownership() -> Weight {
(31_380_000 as Weight)
(22_782_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(1 as Weight))
.saturating_add(RocksDbWeight::get().writes(1 as Weight))
}
fn set_team() -> Weight {
(32_049_000 as Weight)
(23_293_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(1 as Weight))
.saturating_add(RocksDbWeight::get().writes(1 as Weight))
}
fn set_max_zombies() -> Weight {
(57_745_000 as Weight)
(44_525_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(1 as Weight))
.saturating_add(RocksDbWeight::get().writes(1 as Weight))
}
fn set_metadata(n: u32, s: u32, ) -> Weight {
(49_456_000 as Weight)
// Standard Error: 0
.saturating_add((1_000 as Weight).saturating_mul(n as Weight))
// Standard Error: 0
.saturating_add((6_000 as Weight).saturating_mul(s as Weight))
.saturating_add(RocksDbWeight::get().reads(2 as Weight))
.saturating_add(RocksDbWeight::get().writes(1 as Weight))
}
}