Skip to content

Commit

Permalink
add xyk benchmarks
Browse files Browse the repository at this point in the history
  • Loading branch information
enthusiastmartin committed Apr 25, 2024
1 parent dc9ef81 commit a7d079d
Show file tree
Hide file tree
Showing 3 changed files with 295 additions and 60 deletions.
1 change: 1 addition & 0 deletions runtime/basilisk/src/benchmarking/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ pub mod multi_payment;
pub mod route_executor;
pub mod tokens;
pub mod vesting;
pub mod xyk;

pub use helper::BenchmarkHelper;

Expand Down
286 changes: 286 additions & 0 deletions runtime/basilisk/src/benchmarking/xyk.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,286 @@
use crate::{AccountId, AssetId, Balance, Currencies, MultiTransactionPayment, Price, Runtime, RuntimeOrigin, XYK};

use super::*;

use frame_benchmarking::{account, BenchmarkError};
use frame_system::RawOrigin;
use orml_benchmarking::runtime_benchmarks;
use orml_traits::{MultiCurrency, MultiCurrencyExtended};
use sp_std::prelude::*;

use hydradx_traits::router::{PoolType, TradeExecution};

const SEED: u32 = 1;

const INITIAL_BALANCE: Balance = 1_000_000_000_000_000;

fn funded_account<T: pallet_xyk::Config>(name: &'static str, index: u32, assets: &[AssetId]) -> T::AccountId {
let caller: T::AccountId = account(name, index, SEED);
//Necessary for ED for insufficient assets.
T::Currency::update_balance(0, &caller, INITIAL_BALANCE as i128).unwrap();

for a in assets {
T::Currency::update_balance(*a, &caller, INITIAL_BALANCE as i128).unwrap();
}

caller
}

#[allow(clippy::result_large_err)]
fn init_fee_asset(fee_asset: AssetId) -> Result<(), BenchmarkError> {
MultiTransactionPayment::add_currency(RawOrigin::Root.into(), fee_asset, Price::from(1))
.map_err(|_| BenchmarkError::Stop("Failed to add fee asset as supported currency"))?;

pallet_transaction_multi_payment::pallet::AcceptedCurrencyPrice::<Runtime>::insert(fee_asset, Price::from(1));

Ok(())
}

runtime_benchmarks! {
{ Runtime, pallet_xyk }

create_pool {
let asset_a = register_asset(b"TKNA".to_vec(), 1u128).map_err(|_| BenchmarkError::Stop("Failed to register asset"))?;
let asset_b = register_asset(b"TKNB".to_vec(), 1u128).map_err(|_| BenchmarkError::Stop("Failed to register asset"))?;
let fee_asset = register_asset(b"FEE".to_vec(), 1u128).map_err(|_| BenchmarkError::Stop("Failed to register asset"))?;

let caller = funded_account::<Runtime>("caller", 0, &[asset_a, asset_b, fee_asset]);

init_fee_asset(fee_asset)?;
MultiTransactionPayment::set_currency(RawOrigin::Signed(caller.clone()).into(), fee_asset)?;

let amount_a : Balance = INITIAL_BALANCE;
let amount_b : Balance = INITIAL_BALANCE;

assert_eq!(frame_system::Pallet::<Runtime>::account(caller.clone()).sufficients, 0);
}: _(RawOrigin::Signed(caller.clone()), asset_a, amount_a, asset_b, amount_b)
verify {
assert_eq!(Currencies::free_balance(asset_a, &caller), 0);
assert_eq!(Currencies::free_balance(asset_b, &caller), 0);

assert!(!orml_tokens::Accounts::<Runtime>::contains_key(caller.clone(), asset_a));
assert!(!orml_tokens::Accounts::<Runtime>::contains_key(caller.clone(), asset_b));

//NOTE: xyk shares are insufficinet so that's why not 0.
assert_eq!(frame_system::Pallet::<Runtime>::account(caller).sufficients, 0);
}

add_liquidity {

let asset_a = register_asset(b"TKNA".to_vec(), 1u128).map_err(|_| BenchmarkError::Stop("Failed to register asset"))?;
let asset_b = register_asset(b"TKNB".to_vec(), 1u128).map_err(|_| BenchmarkError::Stop("Failed to register asset"))?;
let fee_asset = register_asset(b"FEE".to_vec(), 1u128).map_err(|_| BenchmarkError::Stop("Failed to register asset"))?;

let caller = funded_account::<Runtime>("caller", 0, &[asset_a, asset_b, fee_asset]);
let maker = funded_account::<Runtime>("maker", 1, &[asset_a, asset_b, fee_asset]);

init_fee_asset(fee_asset)?;
MultiTransactionPayment::set_currency(RawOrigin::Signed(maker.clone()).into(), fee_asset)?;
MultiTransactionPayment::set_currency(RawOrigin::Signed(caller.clone()).into(), fee_asset)?;

let amount_a : Balance = INITIAL_BALANCE;
let amount_b : Balance = INITIAL_BALANCE;

let amount : Balance = INITIAL_BALANCE/2;
let max_limit : Balance = INITIAL_BALANCE;


XYK::create_pool(RawOrigin::Signed(maker.clone()).into(), asset_a, INITIAL_BALANCE - 10, asset_b, INITIAL_BALANCE - 10)?;

<Currencies as MultiCurrency<AccountId>>::transfer(asset_a, &caller, &maker, INITIAL_BALANCE - amount)?;

assert_eq!(frame_system::Pallet::<Runtime>::account(caller.clone()).sufficients, 0);
}: _(RawOrigin::Signed(caller.clone()), asset_a, asset_b, amount, max_limit)
verify {
assert_eq!(Currencies::free_balance(asset_a, &caller), 0);
assert_eq!(Currencies::free_balance(asset_b, &caller), 499_999_999_999_999_u128);// Due to rounding in favor of pool

//NOTE: xyk shares are insufficinet.
assert_eq!(frame_system::Pallet::<Runtime>::account(caller).sufficients, 0);
}

remove_liquidity {

let asset_a = register_asset(b"TKNA".to_vec(), 1u128).map_err(|_| BenchmarkError::Stop("Failed to register asset"))?;
let asset_b = register_asset(b"TKNB".to_vec(), 1u128).map_err(|_| BenchmarkError::Stop("Failed to register asset"))?;
let fee_asset = register_asset(b"FEE".to_vec(), 1u128).map_err(|_| BenchmarkError::Stop("Failed to register asset"))?;

let maker = funded_account::<Runtime>("maker", 0, &[asset_a, asset_b, fee_asset]);


init_fee_asset(fee_asset)?;
MultiTransactionPayment::set_currency(RawOrigin::Signed(maker.clone()).into(), fee_asset)?;

XYK::create_pool(RawOrigin::Signed(maker.clone()).into(), asset_a, INITIAL_BALANCE, asset_b, INITIAL_BALANCE)?;

//Only for XYK shares
assert_eq!(frame_system::Pallet::<Runtime>::account(maker.clone()).sufficients, 0);
}: _(RawOrigin::Signed(maker.clone()), asset_a, asset_b, INITIAL_BALANCE)
verify {
assert_eq!(Currencies::free_balance(asset_a, &maker), INITIAL_BALANCE);
assert_eq!(Currencies::free_balance(asset_b, &maker), INITIAL_BALANCE);

assert_eq!(frame_system::Pallet::<Runtime>::account(maker).sufficients, 0);
}

sell {
let asset_a = register_asset(b"TKNA".to_vec(), 1u128).map_err(|_| BenchmarkError::Stop("Failed to register asset"))?;
let asset_b = register_asset(b"TKNB".to_vec(), 1u128).map_err(|_| BenchmarkError::Stop("Failed to register asset"))?;
let fee_asset = register_asset(b"FEE".to_vec(), 1u128).map_err(|_| BenchmarkError::Stop("Failed to register asset"))?;

let maker = funded_account::<Runtime>("maker", 0, &[asset_a, asset_b, fee_asset]);
let caller = funded_account::<Runtime>("caller", 1, &[asset_a, fee_asset]);


init_fee_asset(fee_asset)?;
MultiTransactionPayment::set_currency(RawOrigin::Signed(maker.clone()).into(), fee_asset)?;
MultiTransactionPayment::set_currency(RawOrigin::Signed(caller.clone()).into(), fee_asset)?;

let discount = false;
let amount: Balance = 250_000_000_000_000;
let min_bought: Balance = 1;

XYK::create_pool(RawOrigin::Signed(maker.clone()).into(), asset_a, INITIAL_BALANCE, asset_b, INITIAL_BALANCE)?;

<Currencies as MultiCurrency<AccountId>>::transfer(asset_a, &caller, &maker, INITIAL_BALANCE - amount)?;

assert_eq!(frame_system::Pallet::<Runtime>::account(caller.clone()).sufficients, 0);
}: _(RawOrigin::Signed(caller.clone()), asset_a, asset_b, amount, min_bought, discount)
verify{
assert_eq!(Currencies::free_balance(asset_a, &caller), 0);
assert_eq!(Currencies::free_balance(asset_b, &caller), 199400000000000);

//NOTE: `asset_a`'s ED was released `asset_b`'s ED was collected.
assert_eq!(frame_system::Pallet::<Runtime>::account(caller).sufficients, 0);
}

buy {
let asset_a = register_asset(b"TKNA".to_vec(), 1u128).map_err(|_| BenchmarkError::Stop("Failed to register asset"))?;
let asset_b = register_asset(b"TKNB".to_vec(), 1u128).map_err(|_| BenchmarkError::Stop("Failed to register asset"))?;
let fee_asset = register_asset(b"FEE".to_vec(), 1u128).map_err(|_| BenchmarkError::Stop("Failed to register asset"))?;

let maker = funded_account::<Runtime>("maker", 0, &[asset_a, asset_b, fee_asset]);
let caller = funded_account::<Runtime>("caller", 1, &[asset_a, fee_asset]);


init_fee_asset(fee_asset)?;
MultiTransactionPayment::set_currency(RawOrigin::Signed(maker.clone()).into(), fee_asset)?;
MultiTransactionPayment::set_currency(RawOrigin::Signed(caller.clone()).into(), fee_asset)?;

let discount = false;
let amount: Balance = 200_000_000_000_000;
let max_sold: Balance = INITIAL_BALANCE;

XYK::create_pool(RawOrigin::Signed(maker.clone()).into(), asset_a, INITIAL_BALANCE, asset_b, INITIAL_BALANCE)?;

<Currencies as MultiCurrency<AccountId>>::transfer(asset_a, &caller, &maker, 749_249_999_999_999_u128)?;

assert_eq!(frame_system::Pallet::<Runtime>::account(caller.clone()).sufficients, 0);
}: _(RawOrigin::Signed(caller.clone()), asset_b, asset_a, amount, max_sold, discount)
verify{
assert_eq!(Currencies::free_balance(asset_a, &caller), 0);
assert_eq!(Currencies::free_balance(asset_b, &caller), amount);

assert_eq!(frame_system::Pallet::<Runtime>::account(caller).sufficients, 0);
}

router_execution_sell {
let c in 1..2; // if c == 1, calculate_sell is executed
let e in 0..1; // if e == 1, execute_sell is executed

let asset_a = register_asset(b"TKNA".to_vec(), 1u128).map_err(|_| BenchmarkError::Stop("Failed to register asset"))?;
let asset_b = register_asset(b"TKNB".to_vec(), 1u128).map_err(|_| BenchmarkError::Stop("Failed to register asset"))?;

let fee_asset = register_asset(b"FEE".to_vec(), 1u128).map_err(|_| BenchmarkError::Stop("Failed to register asset"))?;

let maker = funded_account::<Runtime>("maker", 0, &[asset_a, asset_b, fee_asset]);
let caller = funded_account::<Runtime>("caller", 1, &[asset_a, fee_asset]);


init_fee_asset(fee_asset)?;
MultiTransactionPayment::set_currency(RawOrigin::Signed(maker.clone()).into(), fee_asset)?;
MultiTransactionPayment::set_currency(RawOrigin::Signed(caller.clone()).into(), fee_asset)?;

let discount = false;
let amount: Balance = 250_000_000_000_000;
let min_bought: Balance = 1;

XYK::create_pool(RawOrigin::Signed(maker.clone()).into(), asset_a, INITIAL_BALANCE, asset_b, INITIAL_BALANCE)?;

<Currencies as MultiCurrency<AccountId>>::transfer(asset_a, &caller, &maker, INITIAL_BALANCE - amount)?;
assert_eq!(frame_system::Pallet::<Runtime>::account(caller.clone()).sufficients, 0);
}: {
for _ in 1..c {
assert!(<XYK as TradeExecution<RuntimeOrigin, AccountId, AssetId, Balance>>::calculate_sell(PoolType::XYK, asset_a, asset_b, amount).is_ok());
}
if e != 0 {
assert!(<XYK as TradeExecution<RuntimeOrigin, AccountId, AssetId, Balance>>::execute_sell(RawOrigin::Signed(caller.clone()).into(), PoolType::XYK, asset_a, asset_b, amount, min_bought).is_ok());
}
}
verify{
if e != 0 {
assert_eq!(Currencies::free_balance(asset_a, &caller), 0);
assert_eq!(Currencies::free_balance(asset_b, &caller), 199400000000000);

assert_eq!(frame_system::Pallet::<Runtime>::account(caller).sufficients, 0);
}
}

router_execution_buy {
let c in 1..3; // number of times calculate_buy is executed
let e in 0..1; // if e == 1, execute_buy is executed

let asset_a = register_asset(b"TKNA".to_vec(), 1u128).map_err(|_| BenchmarkError::Stop("Failed to register asset"))?;
let asset_b = register_asset(b"TKNB".to_vec(), 1u128).map_err(|_| BenchmarkError::Stop("Failed to register asset"))?;
let fee_asset = register_asset(b"FEE".to_vec(), 1u128).map_err(|_| BenchmarkError::Stop("Failed to register asset"))?;

let maker = funded_account::<Runtime>("maker", 0, &[asset_a, asset_b, fee_asset]);
let caller = funded_account::<Runtime>("caller", 1, &[asset_a, fee_asset]);


init_fee_asset(fee_asset)?;
MultiTransactionPayment::set_currency(RawOrigin::Signed(maker.clone()).into(), fee_asset)?;
MultiTransactionPayment::set_currency(RawOrigin::Signed(caller.clone()).into(), fee_asset)?;

let discount = false;
let amount: Balance = 200_000_000_000_000;
let max_sold: Balance = INITIAL_BALANCE;

XYK::create_pool(RawOrigin::Signed(maker.clone()).into(), asset_a, INITIAL_BALANCE, asset_b, INITIAL_BALANCE)?;

<Currencies as MultiCurrency<AccountId>>::transfer(asset_a, &caller, &maker, 749_249_999_999_999_u128)?;

assert_eq!(frame_system::Pallet::<Runtime>::account(caller.clone()).sufficients, 0);
}: {
for _ in 1..c {
assert!(<XYK as TradeExecution<RuntimeOrigin, AccountId, AssetId, Balance>>::calculate_buy(PoolType::XYK, asset_a, asset_b, amount).is_ok());
}
if e != 0 {
assert!(<XYK as TradeExecution<RuntimeOrigin, AccountId, AssetId, Balance>>::execute_buy(RawOrigin::Signed(caller.clone()).into(), PoolType::XYK, asset_a, asset_b, amount, max_sold).is_ok());
}
}
verify{
if e != 0 {
assert_eq!(Currencies::free_balance(asset_a, &caller), 0);
assert_eq!(Currencies::free_balance(asset_b, &caller), amount);

assert_eq!(frame_system::Pallet::<Runtime>::account(caller).sufficients, 0);
}
}
}

#[cfg(test)]
mod tests {
use super::*;
use orml_benchmarking::impl_benchmark_test_suite;
use sp_runtime::BuildStorage;

fn new_test_ext() -> sp_io::TestExternalities {
frame_system::GenesisConfig::<crate::Runtime>::default()
.build_storage()
.unwrap()
.into()
}

impl_benchmark_test_suite!(new_test_ext(),);
}
68 changes: 8 additions & 60 deletions runtime/basilisk/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -434,44 +434,17 @@ impl_runtime_apis! {
use pallet_xyk_liquidity_mining_benchmarking::Pallet as XYKLiquidityMiningBench;

let mut list = Vec::<BenchmarkList>::new();
list_benchmarks!(list, extra);

// Mising: XYK, uniques, primage, proxy, cumulus parachain system , collator selection, session, multisig, state trie, palle-xcm

//list_benchmark!(list, extra, pallet_xyk, XYK);
list_benchmark!(list, extra, pallet_lbp, LBP);
list_benchmark!(list, extra, pallet_nft, NFT);
list_benchmark!(list, extra, pallet_asset_registry, AssetRegistry);
list_benchmark!(list, extra, pallet_xyk_liquidity_mining, XYKLiquidityMiningBench::<Runtime>);
list_benchmark!(list, extra, pallet_transaction_pause, TransactionPause);
list_benchmark!(list, extra, pallet_ema_oracle, EmaOracle);

list_benchmark!(list, extra, frame_system, SystemBench::<Runtime>);
list_benchmark!(list, extra, pallet_balances, Balances);
//list_benchmark!(list, extra, pallet_collator_selection, CollatorSelection);
list_benchmark!(list, extra, pallet_timestamp, Timestamp);
list_benchmark!(list, extra, pallet_democracy, Democracy);
list_benchmark!(list, extra, pallet_elections_phragmen, Elections);
list_benchmark!(list, extra, pallet_treasury, Treasury);
list_benchmark!(list, extra, pallet_scheduler, Scheduler);
list_benchmark!(list, extra, pallet_utility, Utility);
list_benchmark!(list, extra, pallet_tips, Tips);
list_benchmark!(list, extra, pallet_identity, Identity);
list_benchmark!(list, extra, pallet_collective, TechnicalCommittee);
//list_benchmark!(list, extra, pallet_state_trie_migration, StateTrieMigration);
//list_benchmark!(list, extra, pallet_preimage, Preimage);

list_benchmark!(list, extra, cumulus_pallet_xcmp_queue, XcmpQueue);
list_benchmark!(list, extra, pallet_message_queue, MessageQueue);
//list_benchmark!(list, extra, pallet_xcm, PolkadotXcm);

orml_list_benchmark!(list, extra, pallet_currencies, benchmarking::currencies);
orml_list_benchmark!(list, extra, pallet_xyk, benchmarking::xyk);
orml_list_benchmark!(list, extra, orml_tokens, benchmarking::tokens);
orml_list_benchmark!(list, extra, orml_vesting, benchmarking::vesting);
orml_list_benchmark!(list, extra, pallet_duster, benchmarking::duster);
orml_list_benchmark!(list, extra, pallet_transaction_multi_payment, benchmarking::multi_payment);
orml_list_benchmark!(list, extra, pallet_route_executor, benchmarking::route_executor);
orml_list_benchmark!(list, extra, pallet_marketplace, benchmarking::marketplace);

let storage_info = AllPalletsWithSystem::storage_info();

(list, storage_info)
Expand Down Expand Up @@ -517,39 +490,10 @@ impl_runtime_apis! {

let mut batches = Vec::<BenchmarkBatch>::new();
let params = (&config, &whitelist);
add_benchmarks!(params, batches);

// Basilisk pallets
/*
//add_benchmark!(params, batches, pallet_xyk, XYK);
add_benchmark!(params, batches, pallet_lbp, LBP);
add_benchmark!(params, batches, pallet_nft, NFT);
add_benchmark!(params, batches, pallet_asset_registry, AssetRegistry);
add_benchmark!(params, batches, pallet_xyk_liquidity_mining, XYKLiquidityMiningBench::<Runtime>);
add_benchmark!(params, batches, pallet_transaction_pause, TransactionPause);
add_benchmark!(params, batches, pallet_ema_oracle, EmaOracle);
// Substrate pallets
add_benchmark!(params, batches, frame_system, SystemBench::<Runtime>);
add_benchmark!(params, batches, pallet_balances, Balances);
//add_benchmark!(params, batches, pallet_collator_selection, CollatorSelection);
add_benchmark!(params, batches, pallet_timestamp, Timestamp);
add_benchmark!(params, batches, pallet_democracy, Democracy);
add_benchmark!(params, batches, pallet_elections_phragmen, Elections);
add_benchmark!(params, batches, pallet_treasury, Treasury);
add_benchmark!(params, batches, pallet_scheduler, Scheduler);
add_benchmark!(params, batches, pallet_utility, Utility);
add_benchmark!(params, batches, pallet_tips, Tips);
add_benchmark!(params, batches, pallet_identity, Identity);
add_benchmark!(params, batches, pallet_collective, TechnicalCommittee);
//add_benchmark!(params, batches, pallet_state_trie_migration, StateTrieMigration);
//add_benchmark!(params, batches, pallet_preimage, Preimage);
add_benchmark!(params, batches, cumulus_pallet_xcmp_queue, XcmpQueue);
add_benchmark!(params, batches, pallet_message_queue, MessageQueue);
//add_benchmark!(params, batches, pallet_xcm, PolkadotXcm);
*/

orml_add_benchmark!(params, batches, pallet_xyk, benchmarking::xyk);
orml_add_benchmark!(params, batches, pallet_currencies, benchmarking::currencies);
orml_add_benchmark!(params, batches, orml_tokens, benchmarking::tokens);
orml_add_benchmark!(params, batches, orml_vesting, benchmarking::vesting);
Expand All @@ -564,6 +508,10 @@ impl_runtime_apis! {
}
}

#[cfg(feature = "runtime-benchmarks")]
#[macro_use]
extern crate orml_benchmarking;

#[cfg(feature = "runtime-benchmarks")]
mod benches {
frame_benchmarking::define_benchmarks!(
Expand Down

0 comments on commit a7d079d

Please sign in to comment.