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 <frank@r0gue.io>
  • Loading branch information
Daanvdplas and evilrobot-01 committed Jul 26, 2024
1 parent e683e16 commit 28d971b
Show file tree
Hide file tree
Showing 43 changed files with 1,610 additions and 3,291 deletions.
231 changes: 117 additions & 114 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ members = [
"runtime/devnet",
"runtime/testnet",
"integration-tests",
"pallets/*",
"primitives",
"scripts/fund-dev-accounts",
]
Expand Down Expand Up @@ -51,6 +52,7 @@ substrate-wasm-builder = "18.0.1"
substrate-build-script-utils = "11.0.0"

# Local
pallet-api = { path = "pallets/api", default-features = false }
pop-runtime-devnet = { path = "runtime/devnet", default-features = true } # default-features=true required for `-p pop-node` builds
pop-runtime-testnet = { path = "runtime/testnet", default-features = true } # default-features=true required for `-p pop-node` builds
pop-runtime-common = { path = "runtime/common", default-features = false }
Expand Down
13 changes: 2 additions & 11 deletions node/src/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,18 +64,9 @@ impl RuntimeResolver for PathBuf {

fn load_spec(id: &str) -> std::result::Result<Box<dyn ChainSpec>, String> {
Ok(match id {
#[cfg(not(feature = "paseo"))]
"dev-rococo" => Box::new(chain_spec::development_config(Relay::RococoLocal)),
#[cfg(feature = "paseo")]
"dev-paseo" => Box::new(chain_spec::development_config(Relay::PaseoLocal)),
#[cfg(not(feature = "paseo"))]
"pop-rococo" => Box::new(chain_spec::testnet_config(Relay::Rococo)),
#[cfg(feature = "paseo")]
"pop-paseo" => Box::new(chain_spec::testnet_config(Relay::Paseo)),
#[cfg(feature = "paseo")]
"dev" | "dev-paseo" => Box::new(chain_spec::development_config(Relay::PaseoLocal)),
"test" | "pop-paseo" => Box::new(chain_spec::testnet_config(Relay::Paseo)),
"" | "local" => Box::new(chain_spec::development_config(Relay::PaseoLocal)),
#[cfg(not(feature = "paseo"))]
"" | "local" => Box::new(chain_spec::development_config(Relay::RococoLocal)),
path => {
let path: PathBuf = path.into();
match path.runtime() {
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 28d971b

Please sign in to comment.