Skip to content

Commit

Permalink
feat: api fungibles pallet (#113)
Browse files Browse the repository at this point in the history
Co-authored-by: Frank Bell <[email protected]>
  • Loading branch information
2 people authored and chungquantin committed Sep 6, 2024
1 parent 2fd4cd4 commit 108f044
Show file tree
Hide file tree
Showing 35 changed files with 1,387 additions and 1,673 deletions.
1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ resolver = "2"

# Build
substrate-build-script-utils = "11.0.0"
substrate-wasm-builder = "18.0.1"
substrate-wasm-builder = "23.0.0"

# Local
Expand Down
55 changes: 55 additions & 0 deletions pallets/api/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
[package]
name = "pallet-api"
authors.workspace = true
description = "Api pallet, enabling smart(er) contracts with the power of Polkadot"
edition.workspace = true
license.workspace = true
version = "0.1.0"

[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

[dependencies]
codec.workspace = true
scale-info.workspace = true

# Substrate
frame-benchmarking.workspace = true
frame-support.workspace = true
frame-system.workspace = true
pallet-assets.workspace = true
sp-runtime.workspace = true
sp-std.workspace = true

[dev-dependencies]
pallet-balances.workspace = true
sp-core.workspace = true
sp-io.workspace = true

[features]
default = ["std"]
runtime-benchmarks = [
"frame-benchmarking/runtime-benchmarks",
"frame-support/runtime-benchmarks",
"frame-system/runtime-benchmarks",
"pallet-assets/runtime-benchmarks",
"sp-runtime/runtime-benchmarks",
]
std = [
"codec/std",
"frame-benchmarking/std",
"frame-support/std",
"frame-system/std",
"pallet-assets/std",
"pallet-balances/std",
"scale-info/std",
"sp-core/std",
"sp-io/std",
"sp-runtime/std",
"sp-std/std",
]
try-runtime = [
"frame-support/try-runtime",
"frame-system/try-runtime",
"sp-runtime/try-runtime",
]
106 changes: 106 additions & 0 deletions pallets/api/src/fungibles/benchmarking.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
//! Benchmarking setup for pallet-api::fungibles

use super::{AccountIdOf, AssetIdOf, AssetsInstanceOf, AssetsOf, BalanceOf, Call, Config, Pallet};
use frame_benchmarking::{account, v2::*};
use frame_support::{
assert_ok,
traits::{
fungibles::{
approvals::{Inspect as ApprovalInspect, Mutate},
Create, Inspect,
},
Currency,
},
};
use frame_system::RawOrigin;
use sp_runtime::traits::Zero;

const SEED: u32 = 1;

// See if `generic_event` has been emitted.
fn assert_has_event<T: Config>(
generic_event: <T as pallet_assets::Config<AssetsInstanceOf<T>>>::RuntimeEvent,
) {
frame_system::Pallet::<T>::assert_has_event(generic_event.into());
}

#[benchmarks(
where
<pallet_assets::Pallet<T, AssetsInstanceOf<T>> as Inspect<<T as frame_system::Config>::AccountId>>::AssetId: Zero,
)]
mod benchmarks {
use super::*;

// Parameter:
// - 'a': whether `approve_transfer` is required.
// - 'c': whether `cancel_approval` is required.
#[benchmark]
fn approve(a: Linear<0, 1>, c: Linear<0, 1>) -> Result<(), BenchmarkError> {
let asset_id = AssetIdOf::<T>::zero();
let min_balance = <BalanceOf<T>>::from(1u32);
let owner: AccountIdOf<T> = account("Alice", 0, SEED);
let spender: AccountIdOf<T> = account("Bob", 0, SEED);
let current_allowance = <BalanceOf<T>>::from(u32::MAX / 2);
T::Currency::make_free_balance_be(&owner, u32::MAX.into());
// Set the `current_allowance`.
assert_ok!(<AssetsOf<T> as Create<AccountIdOf<T>>>::create(
asset_id.clone(),
owner.clone(),
true,
min_balance
));
assert_ok!(<AssetsOf<T> as Mutate<AccountIdOf<T>>>::approve(
asset_id.clone(),
&owner,
&spender,
current_allowance,
));
let approval_value = match (a, c) {
// Equal to the current allowance.
(0, 0) => current_allowance,
// Greater than the current allowance.
(1, 0) => <BalanceOf<T>>::from(u32::MAX),
// Zero.
(0, 1) => <BalanceOf<T>>::from(0u32),
// Smaller than the current allowance.
(1, 1) => <BalanceOf<T>>::from(u32::MAX / 4),
_ => unreachable!("values can only be 0 or 1"),
};

#[extrinsic_call]
_(RawOrigin::Signed(owner.clone()), asset_id.clone(), spender.clone(), approval_value);

assert_eq!(AssetsOf::<T>::allowance(asset_id.clone(), &owner, &spender), approval_value);
if c == 1 {
assert_has_event::<T>(
pallet_assets::Event::ApprovalCancelled {
asset_id: asset_id.clone(),
owner: owner.clone(),
delegate: spender.clone(),
}
.into(),
);
}
if a == 1 {
let amount = match c {
// When the allowance was cancelled and then approved with the new value.
1 => approval_value,
// When the allowance was increased.
0 => approval_value - current_allowance,
_ => unreachable!("`c` can only be 0 or 1"),
};
assert_has_event::<T>(
pallet_assets::Event::ApprovedTransfer {
asset_id,
source: owner,
delegate: spender,
amount,
}
.into(),
);
}
Ok(())
}

impl_benchmark_test_suite!(Pallet, crate::mock::new_test_ext(), crate::mock::Test);
}
Loading

0 comments on commit 108f044

Please sign in to comment.