Skip to content
This repository was archived by the owner on Jul 4, 2022. It is now read-only.

Commit 307a6e0

Browse files
Chore/benchmark ga (#151)
* Add benchmarking for generic assets
1 parent 3e2d710 commit 307a6e0

File tree

9 files changed

+306
-1
lines changed

9 files changed

+306
-1
lines changed

Cargo.lock

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

bin/node/primitives/src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ use sp_runtime::{
2828
/// An index to a block.
2929
pub type BlockNumber = u32;
3030

31+
/// Asset ID for generic asset module.
32+
pub type AssetId = u32;
33+
3134
/// Alias to 512-bit hash when used in the context of a transaction signature on the chain.
3235
pub type Signature = MultiSignature;
3336

bin/node/runtime/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ pallet-transaction-payment = { version = "2.0.0", default-features = false, path
8080
pallet-transaction-payment-rpc-runtime-api = { version = "2.0.0", default-features = false, path = "../../../frame/transaction-payment/rpc/runtime-api/" }
8181
pallet-vesting = { version = "2.0.0", default-features = false, path = "../../../frame/vesting" }
8282
prml-attestation = { version = "2.0.0", default-features = false, path = "../../../prml/attestation" }
83+
prml-generic-asset = { version = "2.0.0", default-features = false, path = "../../../prml/generic-asset"}
8384

8485
[build-dependencies]
8586
wasm-builder-runner = { version = "1.0.5", package = "substrate-wasm-builder-runner", path = "../../../utils/wasm-builder-runner" }
@@ -146,6 +147,7 @@ std = [
146147
"pallet-recovery/std",
147148
"pallet-vesting/std",
148149
"prml-attestation/std",
150+
"prml-generic-asset/std"
149151
]
150152
runtime-benchmarks = [
151153
"frame-benchmarking",
@@ -176,4 +178,5 @@ runtime-benchmarks = [
176178
"frame-system-benchmarking",
177179
"hex-literal",
178180
"prml-attestation/runtime-benchmarks",
181+
"prml-generic-asset/runtime-benchmarks",
179182
]

bin/node/runtime/src/lib.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,9 @@ use sp_core::{
4040
u32_trait::{_1, _2, _3, _4},
4141
OpaqueMetadata,
4242
};
43-
pub use node_primitives::{AccountId, Signature};
43+
pub use node_primitives::{AccountId, AssetId, Signature};
4444
use node_primitives::{AccountIndex, Balance, BlockNumber, Hash, Index, Moment};
45+
pub use prml_generic_asset::AssetInfo;
4546
use sp_api::impl_runtime_apis;
4647
use sp_runtime::{
4748
Permill, Perbill, Perquintill, Percent, ApplyExtrinsicResult,
@@ -892,6 +893,13 @@ impl prml_attestation::Trait for Runtime {
892893
type WeightInfo = weights::prml_attestation::WeightInfo;
893894
}
894895

896+
impl prml_generic_asset::Trait for Runtime {
897+
type AssetId = AssetId;
898+
type Balance = Balance;
899+
type Event = Event;
900+
type WeightInfo = weights::prml_generic_asset::WeightInfo;
901+
}
902+
895903
construct_runtime!(
896904
pub enum Runtime where
897905
Block = Block,
@@ -931,6 +939,7 @@ construct_runtime!(
931939
Proxy: pallet_proxy::{Module, Call, Storage, Event<T>},
932940
Multisig: pallet_multisig::{Module, Call, Storage, Event<T>},
933941
Attestation: prml_attestation::{Module, Call, Storage, Event<T>},
942+
GenericAsset: prml_generic_asset::{Module, Call, Storage, Event<T>},
934943
}
935944
);
936945

@@ -1228,6 +1237,7 @@ impl_runtime_apis! {
12281237
add_benchmark!(params, batches, pallet_utility, Utility);
12291238
add_benchmark!(params, batches, pallet_vesting, Vesting);
12301239
add_benchmark!(params, batches, prml_attestation, Attestation);
1240+
add_benchmark!(params, batches, prml_generic_asset, GenericAsset);
12311241

12321242
if batches.is_empty() { return Err("Benchmark not found for this pallet.".into()) }
12331243
Ok(batches)

bin/node/runtime/src/weights/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,4 @@ pub mod pallet_utility;
3333
pub mod pallet_vesting;
3434
pub mod pallet_elections_phragmen;
3535
pub mod prml_attestation;
36+
pub mod prml_generic_asset;
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// This file is part of Plug.
2+
3+
// Copyright 2019-2020 Plug New Zealand Limited
4+
//
5+
// Licensed under the Apache License, Version 2.0 (the "License");
6+
// you may not use this file except in compliance with the License.
7+
// You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing, software
12+
// distributed under the License is distributed on an "AS IS" BASIS,
13+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
// See the License for the specific language governing permissions and
15+
// limitations under the License.
16+
17+
//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 2.0.0
18+
19+
#![allow(unused_parens)]
20+
#![allow(unused_imports)]
21+
22+
use frame_support::weights::{Weight, constants::RocksDbWeight as DbWeight};
23+
24+
pub struct WeightInfo;
25+
impl prml_generic_asset::WeightInfo for WeightInfo {
26+
fn transfer() -> Weight {
27+
(155_000_000 as Weight)
28+
.saturating_add(DbWeight::get().reads(4 as Weight))
29+
.saturating_add(DbWeight::get().writes(2 as Weight))
30+
}
31+
fn burn() -> Weight {
32+
(92_000_000 as Weight)
33+
.saturating_add(DbWeight::get().reads(3 as Weight))
34+
.saturating_add(DbWeight::get().writes(2 as Weight))
35+
}
36+
fn create() -> Weight {
37+
(77_000_000 as Weight)
38+
.saturating_add(DbWeight::get().reads(1 as Weight))
39+
.saturating_add(DbWeight::get().writes(5 as Weight))
40+
}
41+
fn mint() -> Weight {
42+
(92_000_000 as Weight)
43+
.saturating_add(DbWeight::get().reads(3 as Weight))
44+
.saturating_add(DbWeight::get().writes(2 as Weight))
45+
}
46+
fn update_asset_info() -> Weight {
47+
(70_000_000 as Weight)
48+
.saturating_add(DbWeight::get().reads(2 as Weight))
49+
.saturating_add(DbWeight::get().writes(1 as Weight))
50+
}
51+
fn update_permission() -> Weight {
52+
(60_000_000 as Weight)
53+
.saturating_add(DbWeight::get().reads(1 as Weight))
54+
.saturating_add(DbWeight::get().writes(1 as Weight))
55+
}
56+
fn create_reserved() -> Weight {
57+
(87_000_000 as Weight)
58+
.saturating_add(DbWeight::get().reads(2 as Weight))
59+
.saturating_add(DbWeight::get().writes(4 as Weight))
60+
}
61+
}

prml/generic-asset/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ sp-std = { path = "../../primitives/std", default-features = false }
1414
sp-runtime = { path = "../../primitives/runtime", default-features = false }
1515
frame-support = { path = "../../frame/support", default-features = false }
1616
frame-system = { path = "../../frame/system", default-features = false }
17+
frame-benchmarking = { version = "2.0.0", default-features = false, path = "../../frame/benchmarking", optional = true }
1718

1819
[dev-dependencies]
1920
sp-io ={ path = "../../primitives/io", default-features = false }
@@ -26,6 +27,8 @@ std =[
2627
"serde/std",
2728
"sp-std/std",
2829
"sp-runtime/std",
30+
"frame-benchmarking/std",
2931
"frame-support/std",
3032
"frame-system/std",
3133
]
34+
runtime-benchmarks = ["frame-benchmarking"]
Lines changed: 221 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,221 @@
1+
// Copyright 2019-2020 Plug New Zealand Limited
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
//! Generic assets benchmarking.
16+
17+
#![cfg(feature = "runtime-benchmarks")]
18+
19+
use super::*;
20+
21+
use frame_system::RawOrigin;
22+
use frame_benchmarking::{benchmarks, account, whitelisted_caller};
23+
use crate::Module as GenericAsset;
24+
25+
const SEED: u32 = 0;
26+
27+
benchmarks! {
28+
_ { }
29+
30+
// Benchmark `transfer` extrinsic with the worst possible conditions:
31+
// Transfer will kill the sender account.
32+
// Transfer will create the recipient account.
33+
transfer {
34+
let caller: T::AccountId = whitelisted_caller();
35+
36+
// spending asset id
37+
let asset_id = GenericAsset::<T>::spending_asset_id();
38+
let initial_balance = T::Balance::from(5_000_000);
39+
GenericAsset::<T>::set_free_balance(asset_id, &caller, initial_balance);
40+
41+
let recipient: T::AccountId = account("recipient", 0, SEED);
42+
let transfer_amount = T::Balance::from(5_000_000);
43+
}: transfer(RawOrigin::Signed(caller.clone()), asset_id, recipient.clone(), transfer_amount)
44+
verify {
45+
assert_eq!(GenericAsset::<T>::free_balance(asset_id, &caller), Zero::zero());
46+
assert_eq!(GenericAsset::<T>::free_balance(asset_id, &recipient), transfer_amount);
47+
}
48+
49+
// Benchmark `burn`, GA's create comes from ROOT account. This always creates an asset.
50+
// Mint some amount of new asset to an account and burn the asset from it.
51+
burn {
52+
let caller: T::AccountId = whitelisted_caller();
53+
let initial_balance = T::Balance::from(5_000_000);
54+
let asset_id = GenericAsset::<T>::next_asset_id();
55+
let permissions = PermissionLatest::<T::AccountId>::new(caller.clone());
56+
let asset_options :AssetOptions<T::Balance, T::AccountId> = AssetOptions {
57+
initial_issuance: initial_balance,
58+
permissions,
59+
};
60+
61+
let _ = GenericAsset::<T>::create(
62+
RawOrigin::Root.into(),
63+
caller.clone(),
64+
asset_options,
65+
AssetInfo::default()
66+
);
67+
68+
let account: T::AccountId = account("bob", 0, SEED);
69+
70+
// Mint some asset to the account 'bob' so that 'bob' can burn those
71+
let mint_amount = T::Balance::from(5_000_000);
72+
let _ = GenericAsset::<T>::mint(RawOrigin::Signed(caller.clone()).into(), asset_id, account.clone(), mint_amount);
73+
74+
let burn_amount = T::Balance::from(5_000_000);
75+
}: burn(RawOrigin::Signed(caller.clone()), asset_id, account.clone(), burn_amount)
76+
verify {
77+
assert_eq!(GenericAsset::<T>::free_balance(asset_id, &account), Zero::zero());
78+
assert_eq!(GenericAsset::<T>::total_issuance(asset_id), initial_balance);
79+
}
80+
81+
// Benchmark `burn`, GA's create comes from ROOT account.
82+
create {
83+
let caller: T::AccountId = whitelisted_caller();
84+
let initial_balance = T::Balance::from(5_000_000);
85+
let permissions = PermissionLatest::<T::AccountId>::new(caller.clone());
86+
let asset_id = GenericAsset::<T>::next_asset_id();
87+
let asset_options :AssetOptions<T::Balance, T::AccountId> = AssetOptions {
88+
initial_issuance: initial_balance,
89+
permissions,
90+
};
91+
}: create(RawOrigin::Root, caller.clone(), asset_options, AssetInfo::default())
92+
verify {
93+
assert_eq!(GenericAsset::<T>::total_issuance(&asset_id), initial_balance);
94+
assert_eq!(GenericAsset::<T>::free_balance(asset_id, &caller.clone()), initial_balance);
95+
}
96+
97+
// Benchmark `mint`, create asset from ROOT account.
98+
// Owner of the asset can then mint amount to 'recipient' account
99+
mint {
100+
let caller: T::AccountId = whitelisted_caller();
101+
let mint_to: T::AccountId = account("recipient", 0, SEED);
102+
let initial_balance = T::Balance::from(5_000_000);
103+
let asset_id = GenericAsset::<T>::next_asset_id();
104+
let permissions = PermissionLatest::<T::AccountId>::new(caller.clone());
105+
let asset_options :AssetOptions<T::Balance, T::AccountId> = AssetOptions {
106+
initial_issuance: initial_balance,
107+
permissions,
108+
};
109+
let _ = GenericAsset::<T>::create(
110+
RawOrigin::Root.into(),
111+
caller.clone(),
112+
asset_options,
113+
AssetInfo::default()
114+
);
115+
116+
let mint_amount = T::Balance::from(1_000_000);
117+
}: mint(RawOrigin::Signed(caller.clone()), asset_id, mint_to.clone(), mint_amount )
118+
verify {
119+
let total_issuance = T::Balance::from(6_000_000);
120+
assert_eq!(GenericAsset::<T>::total_issuance(&asset_id), total_issuance);
121+
assert_eq!(GenericAsset::<T>::free_balance(asset_id, &mint_to.clone()), mint_amount);
122+
}
123+
124+
// Benchmark `update_asset_info`, create asset from ROOT account.
125+
// Update the asset info
126+
update_asset_info {
127+
let caller: T::AccountId = whitelisted_caller();
128+
let web3_asset_info = AssetInfo::new(b"WEB3.0".to_vec(), 3);
129+
let initial_balance = T::Balance::from(5_000_000);
130+
let asset_id = GenericAsset::<T>::next_asset_id();
131+
let permissions = PermissionLatest::<T::AccountId>::new(caller.clone());
132+
let burn_amount = T::Balance::from(5_000);
133+
let asset_options :AssetOptions<T::Balance, T::AccountId> = AssetOptions {
134+
initial_issuance: initial_balance,
135+
permissions,
136+
};
137+
let _ = GenericAsset::<T>::create(
138+
RawOrigin::Root.into(),
139+
caller.clone(),
140+
asset_options,
141+
web3_asset_info.clone()
142+
);
143+
144+
let web3_asset_info = AssetInfo::new(b"WEB3.1".to_vec(), 5);
145+
}: update_asset_info(RawOrigin::Signed(caller.clone()), asset_id, web3_asset_info.clone())
146+
verify {
147+
assert_eq!(GenericAsset::<T>::asset_meta(asset_id), web3_asset_info);
148+
}
149+
150+
// Benchmark `update_permission`, create asset from ROOT account with 'update' permission.
151+
// Update permission to include update and mint
152+
update_permission {
153+
let caller: T::AccountId = whitelisted_caller();
154+
let initial_balance = T::Balance::from(5_000_000);
155+
let permissions = PermissionLatest {
156+
update: Owner::Address(caller.clone()),
157+
mint: Owner::None,
158+
burn: Owner::None,
159+
};
160+
161+
let new_permission = PermissionLatest {
162+
update: Owner::Address(caller.clone()),
163+
mint: Owner::Address(caller.clone()),
164+
burn: Owner::None,
165+
};
166+
let asset_id = GenericAsset::<T>::next_asset_id();
167+
let asset_options :AssetOptions<T::Balance, T::AccountId> = AssetOptions {
168+
initial_issuance: initial_balance,
169+
permissions,
170+
};
171+
let _ = GenericAsset::<T>::create(
172+
RawOrigin::Root.into(),
173+
caller.clone(),
174+
asset_options,
175+
AssetInfo::default()
176+
);
177+
}: update_permission(RawOrigin::Signed(caller.clone()), asset_id, new_permission)
178+
verify {
179+
assert!(GenericAsset::<T>::check_permission(asset_id, &caller.clone(), &PermissionType::Mint));
180+
assert!(!GenericAsset::<T>::check_permission(asset_id, &caller, &PermissionType::Burn));
181+
}
182+
183+
// Benchmark `create_reserved`, create reserved asset from ROOT account.
184+
create_reserved {
185+
let caller: T::AccountId = whitelisted_caller();
186+
let initial_balance = T::Balance::from(5_000_000);
187+
let permissions = PermissionLatest::<T::AccountId>::new(caller.clone());
188+
// create reserved asset with asset_id >= next_asset_id should fail so set the next asset id to some value
189+
<NextAssetId<T>>::put(T::AssetId::from(10001));
190+
let asset_id = T::AssetId::from(1000);
191+
let asset_options :AssetOptions<T::Balance, T::AccountId> = AssetOptions {
192+
initial_issuance: initial_balance,
193+
permissions,
194+
};
195+
}: create_reserved(RawOrigin::Root, asset_id, asset_options, AssetInfo::default())
196+
verify {
197+
assert_eq!(GenericAsset::<T>::total_issuance(&asset_id), initial_balance);
198+
assert_eq!(GenericAsset::<T>::free_balance(asset_id, &T::AccountId::default()), initial_balance);
199+
assert_eq!(asset_id, T::AssetId::from(1000));
200+
}
201+
}
202+
203+
#[cfg(test)]
204+
mod tests {
205+
use super::*;
206+
use crate::mock::{ExtBuilder, Test};
207+
use frame_support::assert_ok;
208+
209+
#[test]
210+
fn generic_asset_benchmark_test() {
211+
ExtBuilder::default().build().execute_with(|| {
212+
assert_ok!(test_benchmark_transfer::<Test>());
213+
assert_ok!(test_benchmark_burn::<Test>());
214+
assert_ok!(test_benchmark_create::<Test>());
215+
assert_ok!(test_benchmark_create_reserved::<Test>());
216+
assert_ok!(test_benchmark_mint::<Test>());
217+
assert_ok!(test_update_asset_info::<Test>());
218+
assert_ok!(test_update_permission::<Test>());
219+
});
220+
}
221+
}

0 commit comments

Comments
 (0)