Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: orderbook bench helper #1558

Merged
merged 9 commits into from
Sep 22, 2023
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions libs/mocks/src/pools.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,16 +124,16 @@ pub mod pallet {
}

#[cfg(feature = "runtime-benchmarks")]
impl<T: Config> cfg_traits::PoolBenchmarkHelper for Pallet<T> {
impl<T: Config> cfg_traits::benchmarking::PoolBenchmarkHelper for Pallet<T> {
type AccountId = T::AccountId;
type Balance = T::Balance;
type PoolId = T::PoolId;

fn benchmark_create_pool(a: Self::PoolId, b: &Self::AccountId) {
fn bench_create_pool(a: Self::PoolId, b: &Self::AccountId) {
execute_call!((a, b))
}

fn benchmark_give_ausd(a: &Self::AccountId, b: Self::Balance) {
fn bench_mint_pool_currency_into(a: &Self::AccountId, b: Self::Balance) {
execute_call!((a, b))
}
}
Expand Down
69 changes: 69 additions & 0 deletions libs/traits/src/benchmarking.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// Copyright 2023 Centrifuge Foundation (centrifuge.io).
//
// This file is part of the Centrifuge chain project.
// Centrifuge is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version (see http://www.gnu.org/licenses).
// Centrifuge is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.

/// Benchmark utility to create pools
pub trait PoolBenchmarkHelper {
type PoolId;
type AccountId;
type Balance;

/// Create a pool for the given the pool id and the admin.
fn bench_create_pool(pool_id: Self::PoolId, admin: &Self::AccountId);

/// Give pool currency to the account
fn bench_mint_pool_currency_into(account: &Self::AccountId, balance: Self::Balance);
}

/// Benchmark utility for adding currency trading pairs
pub trait OrderBookBenchmarkHelper {
type AccountId;
type Balance;
type CurrencyId;
type OrderIdNonce;

/// Adds the corresponding trading pair, creates trader accounts and mints
/// appropriate amounts of balance into these
fn bench_setup_trading_pair(
asset_in: Self::CurrencyId,
asset_out: Self::CurrencyId,
amount_in: Self::Balance,
amount_out: Self::Balance,
decimals_in: u32,
decimals_out: u32,
) -> (Self::AccountId, Self::AccountId);

/// Fulfills the given swap order from the trader account
fn bench_fill_order_full(trader: Self::AccountId, order_id: Self::OrderIdNonce);
}

/// Benchmark utility for updating/collecting foreign investments and
/// redemptions.

pub trait ForeignInvestmentsBenchmarkHelper {
type AccountId;
type AssetRegistry;
type Balance;
type CurrencyId;
type InvestmentId;

fn bench_foreign_investment_setup();

fn bench_increase_foreign_investment(
investor: Self::AccountId,
investment_id: Self::InvestmentId,
foreign_currency: Self::CurrencyId,
pool_currency: Self::CurrencyId,
amount_foreign_denominated: Self::Balance,
);

fn bench_enable_lp_transferability(currency: Self::CurrencyId);
}
18 changes: 4 additions & 14 deletions libs/traits/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ pub mod liquidity_pools;
/// Traits related to rewards.
pub mod rewards;

#[cfg(feature = "runtime-benchmarks")]
/// Traits related to benchmarking tooling.
pub mod benchmarking;

/// A trait used for loosely coupling the claim pallet with a reward mechanism.
///
/// ## Overview
Expand Down Expand Up @@ -257,20 +261,6 @@ pub trait PoolWriteOffPolicyMutate<PoolId> {
fn worst_case_policy() -> Self::Policy;
}

/// Utility to benchmark pools easily
#[cfg(feature = "runtime-benchmarks")]
pub trait PoolBenchmarkHelper {
type PoolId;
type AccountId;
type Balance;

/// Create a benchmark pool giving the id and the admin.
fn benchmark_create_pool(pool_id: Self::PoolId, admin: &Self::AccountId);

/// Give AUSD to the account
fn benchmark_give_ausd(account: &Self::AccountId, balance: Self::Balance);
}

/// A trait that can be used to retrieve the current price for a currency
pub struct CurrencyPair<CurrencyId> {
pub base: CurrencyId,
Expand Down
7 changes: 4 additions & 3 deletions pallets/loans/src/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,11 @@

use cfg_primitives::CFG;
use cfg_traits::{
benchmarking::PoolBenchmarkHelper,
changes::ChangeGuard,
data::DataRegistry,
interest::{CompoundingSchedule, InterestAccrual, InterestRate},
Permissions, PoolBenchmarkHelper, PoolWriteOffPolicyMutate,
Permissions, PoolWriteOffPolicyMutate,
};
use cfg_types::{
adjustments::Adjustment,
Expand Down Expand Up @@ -107,7 +108,7 @@ where
let pool_id = Default::default();

let pool_admin = account("pool_admin", 0, 0);
T::Pool::benchmark_create_pool(pool_id, &pool_admin);
T::Pool::bench_create_pool(pool_id, &pool_admin);

let loan_admin = account("loan_admin", 0, 0);
T::Permissions::add(
Expand All @@ -118,7 +119,7 @@ where
.unwrap();

let borrower = account::<T::AccountId>("borrower", 0, 0);
T::Pool::benchmark_give_ausd(&borrower, (FUNDS * CFG).into());
T::Pool::bench_mint_pool_currency_into(&borrower, (FUNDS * CFG).into());
T::NonFungible::create_collection(&COLLECION_ID.into(), &borrower, &borrower).unwrap();
T::Permissions::add(
PermissionScope::Pool(pool_id),
Expand Down
148 changes: 67 additions & 81 deletions pallets/order-book/src/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,22 @@

#![cfg(feature = "runtime-benchmarks")]

use cfg_traits::benchmarking::OrderBookBenchmarkHelper;
use cfg_types::tokens::{CurrencyId, CustomMetadata};
use frame_benchmarking::*;
use frame_support::traits::fungibles::Mutate as FungiblesMutate;
use frame_system::RawOrigin;
use orml_traits::asset_registry::{Inspect, Mutate};
use sp_runtime::FixedPointNumber;

// use pallet_pool_system::benchmarking::prepare_asset_registry;
use super::*;

const CURRENCY_0: u128 = 1_000_000;
const CURRENCY_1: u128 = 1_000_000_000_000;
const AMOUNT_IN: u128 = 1_000_000;
const AMOUNT_OUT: u128 = 1_000_000_000_000;
const BUY_AMOUNT: u128 = 100 * AMOUNT_IN;
const ASSET_IN: CurrencyId = CurrencyId::ForeignAsset(1);
const ASSET_OUT: CurrencyId = CurrencyId::ForeignAsset(2);
const DECIMALS_IN: u32 = 12;
const DECIMALS_OUT: u32 = 6;

benchmarks! {
where_clause {
Expand All @@ -33,110 +37,92 @@ benchmarks! {
}

create_order {
let (account_0, _, asset_0, asset_1) = set_up_users_currencies::<T>()?;
}:create_order(RawOrigin::Signed(account_0.clone()), asset_0, asset_1, 100 * CURRENCY_0, T::SellRatio::saturating_from_integer(2))
let (account_out, _) = Pallet::<T>::bench_setup_trading_pair(ASSET_IN, ASSET_OUT, 1000 * AMOUNT_IN, 1000 * AMOUNT_OUT, DECIMALS_IN, DECIMALS_OUT);
}:create_order(RawOrigin::Signed(account_out.clone()), ASSET_IN, ASSET_OUT, BUY_AMOUNT, T::SellRatio::saturating_from_integer(2))


user_update_order {
let (account_0, _, asset_0, asset_1) = set_up_users_currencies::<T>()?;
let (account_out, _) = Pallet::<T>::bench_setup_trading_pair(ASSET_IN, ASSET_OUT, 1000 * AMOUNT_IN, 1000 * AMOUNT_OUT, DECIMALS_IN, DECIMALS_OUT);

let order_id = Pallet::<T>::place_order(account_0.clone(), asset_0, asset_1, 100 * CURRENCY_0, T::SellRatio::saturating_from_integer(2).into(), 100 * CURRENCY_0)?;
let order_id = Pallet::<T>::place_order(account_out.clone(), ASSET_IN, ASSET_OUT, BUY_AMOUNT, T::SellRatio::saturating_from_integer(2).into(), BUY_AMOUNT)?;

}:user_update_order(RawOrigin::Signed(account_0.clone()), order_id, 150 * CURRENCY_0, T::SellRatio::saturating_from_integer(1))
}:user_update_order(RawOrigin::Signed(account_out.clone()), order_id, 10 * BUY_AMOUNT, T::SellRatio::saturating_from_integer(1))

user_cancel_order {
let (account_0, _, asset_0, asset_1) = set_up_users_currencies::<T>()?;
let (account_out, _) = Pallet::<T>::bench_setup_trading_pair(ASSET_IN, ASSET_OUT, 1000 * AMOUNT_IN, 1000 * AMOUNT_OUT, DECIMALS_IN, DECIMALS_OUT);

let order_id = Pallet::<T>::place_order(account_0.clone(), asset_0, asset_1, 100 * CURRENCY_0, T::SellRatio::saturating_from_integer(2).into(), 100 * CURRENCY_0)?;
let order_id = Pallet::<T>::place_order(account_out.clone(), ASSET_IN, ASSET_OUT, BUY_AMOUNT, T::SellRatio::saturating_from_integer(2).into(), BUY_AMOUNT)?;

}:user_cancel_order(RawOrigin::Signed(account_0.clone()), order_id)
}:user_cancel_order(RawOrigin::Signed(account_out.clone()), order_id)

fill_order_full {
let (account_0, account_1, asset_0, asset_1) = set_up_users_currencies::<T>()?;
let (account_out, account_in) = Pallet::<T>::bench_setup_trading_pair(ASSET_IN, ASSET_OUT, 1000 * AMOUNT_IN, 1000 * AMOUNT_OUT, DECIMALS_IN, DECIMALS_OUT);

let order_id = Pallet::<T>::place_order(account_0.clone(), asset_0, asset_1, 100 * CURRENCY_0, T::SellRatio::saturating_from_integer(2).into(), 100 * CURRENCY_0)?;
let order_id = Pallet::<T>::place_order(account_out.clone(), ASSET_IN, ASSET_OUT, BUY_AMOUNT, T::SellRatio::saturating_from_integer(2).into(), BUY_AMOUNT)?;

}:fill_order_full(RawOrigin::Signed(account_1.clone()), order_id)
}:fill_order_full(RawOrigin::Signed(account_in.clone()), order_id)

add_trading_pair {
let asset_0 = CurrencyId::ForeignAsset(1);
let asset_1 = CurrencyId::ForeignAsset(2);
}:add_trading_pair(RawOrigin::Root, asset_0, asset_1, 100 * CURRENCY_0)
}:add_trading_pair(RawOrigin::Root, ASSET_IN, ASSET_OUT, BUY_AMOUNT)

rm_trading_pair {
let (account_0, _, asset_0, asset_1) = set_up_users_currencies::<T>()?;
}:rm_trading_pair(RawOrigin::Root, asset_0, asset_1)
let (account_out, _) = Pallet::<T>::bench_setup_trading_pair(ASSET_IN, ASSET_OUT, 1000 * AMOUNT_IN, 1000 * AMOUNT_OUT, DECIMALS_IN, DECIMALS_OUT);
}:rm_trading_pair(RawOrigin::Root, ASSET_IN, ASSET_OUT)

update_min_order {
let (account_0, _, asset_0, asset_1) = set_up_users_currencies::<T>()?;
}:update_min_order(RawOrigin::Root, asset_0, asset_1, 1 * CURRENCY_0)


let (account_out, _) = Pallet::<T>::bench_setup_trading_pair(ASSET_IN, ASSET_OUT, 1000 * AMOUNT_IN, 1000 * AMOUNT_OUT, DECIMALS_IN, DECIMALS_OUT);
}:update_min_order(RawOrigin::Root, ASSET_IN, ASSET_OUT, AMOUNT_IN)
}

fn set_up_users_currencies<T: Config<AssetCurrencyId = CurrencyId, Balance = u128>>() -> Result<
(
T::AccountId,
T::AccountId,
T::AssetCurrencyId,
T::AssetCurrencyId,
),
&'static str,
>
where
<T as pallet::Config>::AssetRegistry: orml_traits::asset_registry::Mutate,
{
let account_0: T::AccountId = account::<T::AccountId>("Account0", 1, 0);
let account_1: T::AccountId = account::<T::AccountId>("Account1", 2, 0);
let asset_0 = CurrencyId::ForeignAsset(1);
let asset_1 = CurrencyId::ForeignAsset(2);
prepare_asset_registry::<T>();
T::TradeableAsset::mint_into(asset_0, &account_0, 1_000 * CURRENCY_0)?;
T::TradeableAsset::mint_into(asset_1, &account_0, 1_000 * CURRENCY_1)?;
T::TradeableAsset::mint_into(asset_0, &account_1, 1_000 * CURRENCY_0)?;
T::TradeableAsset::mint_into(asset_1, &account_1, 1_000 * CURRENCY_1)?;
TradingPair::<T>::insert(asset_0, asset_1, 1 * CURRENCY_0);
Ok((account_0, account_1, asset_0, asset_1))
}
impl_benchmark_test_suite!(Pallet, crate::mock::new_test_ext(), crate::mock::Runtime,);

pub fn prepare_asset_registry<T: Config>()
pub(crate) struct Helper<T>(sp_std::marker::PhantomData<T>);

impl<T: Config> Helper<T>
where
T::AssetRegistry: Mutate<AssetId = CurrencyId, Balance = u128, CustomMetadata = CustomMetadata>,
T::AssetRegistry:
Mutate<AssetId = T::AssetCurrencyId, Balance = T::Balance, CustomMetadata = CustomMetadata>,
{
match T::AssetRegistry::metadata(&CurrencyId::ForeignAsset(1)) {
Some(_) => (),
None => {
T::AssetRegistry::register_asset(
Some(CurrencyId::ForeignAsset(1)),
orml_asset_registry::AssetMetadata {
decimals: 12,
name: "MOCK TOKEN".as_bytes().to_vec(),
symbol: "MOCK".as_bytes().to_vec(),
existential_deposit: 0,
location: None,
additional: CustomMetadata::default(),
},
)
.expect("Registering Pool asset must work");
pub fn register_trading_assets(
asset_in: T::AssetCurrencyId,
asset_out: T::AssetCurrencyId,
decimals_in: u32,
decimals_out: u32,
) {
match T::AssetRegistry::metadata(&asset_in) {
Some(_) => (),
None => {
T::AssetRegistry::register_asset(
Some(asset_in),
orml_asset_registry::AssetMetadata {
decimals: decimals_in,
name: "ASSET IN".as_bytes().to_vec(),
symbol: "INC".as_bytes().to_vec(),
existential_deposit: T::Balance::zero(),
location: None,
additional: CustomMetadata::default(),
},
)
.expect("Registering Pool asset must work");
}
}
}

match T::AssetRegistry::metadata(&CurrencyId::ForeignAsset(2)) {
Some(_) => (),
None => {
T::AssetRegistry::register_asset(
Some(CurrencyId::ForeignAsset(2)),
orml_asset_registry::AssetMetadata {
decimals: 6,
name: "MOCK TOKEN 1".as_bytes().to_vec(),
symbol: "MOCK1".as_bytes().to_vec(),
existential_deposit: 0,
location: None,
additional: CustomMetadata::default(),
},
)
.expect("Registering Pool asset must work");
match T::AssetRegistry::metadata(&asset_out) {
Some(_) => (),
None => {
T::AssetRegistry::register_asset(
Some(asset_out),
orml_asset_registry::AssetMetadata {
decimals: decimals_out,
name: "ASSET OUT".as_bytes().to_vec(),
symbol: "OUT".as_bytes().to_vec(),
existential_deposit: T::Balance::zero(),
location: None,
additional: CustomMetadata::default(),
},
)
.expect("Registering Pool asset must work");
}
}
}
}
Loading
Loading