From 0f80f4bd5cdc898b3f2603cd09bf161f24ee5aef Mon Sep 17 00:00:00 2001 From: dmoka Date: Fri, 15 Mar 2024 10:15:13 +0100 Subject: [PATCH 01/21] fix integration tests as set route validation returns the actual sell error --- integration-tests/src/router.rs | 8 ++++---- pallets/route-executor/src/lib.rs | 2 +- pallets/route-executor/src/tests/set_route.rs | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/integration-tests/src/router.rs b/integration-tests/src/router.rs index 9e26ab7ee..0f5518f09 100644 --- a/integration-tests/src/router.rs +++ b/integration-tests/src/router.rs @@ -2720,7 +2720,7 @@ mod set_route { //Act and assert assert_noop!( Router::set_route(hydradx_runtime::RuntimeOrigin::signed(ALICE.into()), asset_pair, route1), - pallet_route_executor::Error::::InvalidRoute + pallet_xyk::Error::::InsufficientAssetBalance ); }); } @@ -2792,7 +2792,7 @@ mod set_route { asset_pair, invalid_route ), - pallet_route_executor::Error::::InvalidRoute + pallet_xyk::Error::::InsufficientAssetBalance ); }); } @@ -2916,7 +2916,7 @@ mod set_route { //Act and assert assert_noop!( Router::set_route(hydradx_runtime::RuntimeOrigin::signed(ALICE.into()), asset_pair, route2), - pallet_route_executor::Error::::InvalidRoute + pallet_omnipool::Error::::MaxInRatioExceeded ); }); } @@ -2992,7 +2992,7 @@ mod set_route { //Act and assert assert_noop!( Router::set_route(hydradx_runtime::RuntimeOrigin::signed(ALICE.into()), asset_pair, route2), - pallet_route_executor::Error::::InvalidRoute + pallet_omnipool::Error::::MaxInRatioExceeded ); }); } diff --git a/pallets/route-executor/src/lib.rs b/pallets/route-executor/src/lib.rs index a86171e68..fe9c98596 100644 --- a/pallets/route-executor/src/lib.rs +++ b/pallets/route-executor/src/lib.rs @@ -552,7 +552,7 @@ impl Pallet { TransactionOutcome::Rollback(sell_result) }) - .map_err(|_| Error::::InvalidRoute.into()) + .map_err(|err| err.into()) } fn calculate_expected_amount_out( diff --git a/pallets/route-executor/src/tests/set_route.rs b/pallets/route-executor/src/tests/set_route.rs index 3e7cc8e69..24c76088b 100644 --- a/pallets/route-executor/src/tests/set_route.rs +++ b/pallets/route-executor/src/tests/set_route.rs @@ -374,7 +374,7 @@ fn set_route_should_fail_when_route_is_not_valid() { //Act and assert assert_noop!( Router::set_route(RuntimeOrigin::signed(ALICE), asset_pair, route), - Error::::InvalidRoute + orml_tokens::Error::::BalanceTooLow ); assert!(Router::route(asset_pair).is_none()); @@ -403,7 +403,7 @@ fn set_route_should_fail_when_trying_to_override_with_invalid_route() { //Act and assert assert_noop!( Router::set_route(RuntimeOrigin::signed(ALICE), asset_pair, invalid_route), - Error::::InvalidRoute + orml_tokens::Error::::BalanceTooLow ); let stored_route = Router::get_route(asset_pair); From 671eeb851e2526a64af6780c46d97f9abd62bdee Mon Sep 17 00:00:00 2001 From: dmoka Date: Fri, 15 Mar 2024 10:48:44 +0100 Subject: [PATCH 02/21] add test for checking correspondance of itnermediate assets. --- integration-tests/src/router.rs | 47 +++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/integration-tests/src/router.rs b/integration-tests/src/router.rs index 0f5518f09..d96f96be8 100644 --- a/integration-tests/src/router.rs +++ b/integration-tests/src/router.rs @@ -53,6 +53,53 @@ fn router_weights_should_be_non_zero() { mod router_different_pools_tests { use super::*; + #[test] + fn route_should_fail_when_route_is_not_consistent() { + TestNet::reset(); + + Hydra::execute_with(|| { + //Arrange + init_omnipool(); + create_xyk_pool_with_amounts(DAI, 1000000 * UNITS, DOT, 1000000 * UNITS); + create_xyk_pool_with_amounts(ETH, 1000000 * UNITS, DOT, 1000000 * UNITS); + + assert_ok!(Currencies::update_balance( + hydradx_runtime::RuntimeOrigin::root(), + BOB.into(), + ETH, + 300000000 * UNITS as i128, + )); + + let amount_to_sell = UNITS; + let limit = 0; + let trades = vec![ + Trade { + pool: PoolType::Omnipool, + asset_in: HDX, + asset_out: DAI, + }, + Trade { + pool: PoolType::XYK, + asset_in: ETH, + asset_out: DOT, + }, + ]; + + //Act + assert_noop!( + Router::sell( + RuntimeOrigiHn::signed(BOB.into()), + HDX, + DOT, + amount_to_sell, + limit, + trades + ), + pallet_route_executor::Error::::InvalidRoute + ); + }); + } + #[test] fn sell_should_work_when_route_contains_trades_with_different_pools() { TestNet::reset(); From 24fb8073f89bbc04160141bc44cdaf502ec2fc32 Mon Sep 17 00:00:00 2001 From: dmoka Date: Fri, 15 Mar 2024 10:55:06 +0100 Subject: [PATCH 03/21] fix compilation error --- integration-tests/src/router.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration-tests/src/router.rs b/integration-tests/src/router.rs index d96f96be8..4cab6c807 100644 --- a/integration-tests/src/router.rs +++ b/integration-tests/src/router.rs @@ -88,7 +88,7 @@ mod router_different_pools_tests { //Act assert_noop!( Router::sell( - RuntimeOrigiHn::signed(BOB.into()), + RuntimeOrigin::signed(BOB.into()), HDX, DOT, amount_to_sell, From 523a863660ec3afec3a67d2dabed4d355abe0105 Mon Sep 17 00:00:00 2001 From: dmoka Date: Fri, 15 Mar 2024 13:11:40 +0100 Subject: [PATCH 04/21] fix bug - add validation to check if intermediate assets are consistent in the route trades --- integration-tests/src/router.rs | 4 +-- pallets/route-executor/src/lib.rs | 7 +++++ pallets/route-executor/src/tests/sell.rs | 31 +++++++++++++++++++ pallets/route-executor/src/tests/set_route.rs | 4 +-- 4 files changed, 42 insertions(+), 4 deletions(-) diff --git a/integration-tests/src/router.rs b/integration-tests/src/router.rs index 4cab6c807..c490b9b28 100644 --- a/integration-tests/src/router.rs +++ b/integration-tests/src/router.rs @@ -2767,7 +2767,7 @@ mod set_route { //Act and assert assert_noop!( Router::set_route(hydradx_runtime::RuntimeOrigin::signed(ALICE.into()), asset_pair, route1), - pallet_xyk::Error::::InsufficientAssetBalance + pallet_route_executor::Error::::InvalidRoute ); }); } @@ -2839,7 +2839,7 @@ mod set_route { asset_pair, invalid_route ), - pallet_xyk::Error::::InsufficientAssetBalance + pallet_route_executor::Error::::InvalidRoute ); }); } diff --git a/pallets/route-executor/src/lib.rs b/pallets/route-executor/src/lib.rs index fe9c98596..76298bf78 100644 --- a/pallets/route-executor/src/lib.rs +++ b/pallets/route-executor/src/lib.rs @@ -431,6 +431,13 @@ impl Pallet { Error::::InvalidRoute ); + for i in 0..route.len().saturating_sub(1) { + let asset_out = route.get(i).ok_or(Error::::InvalidRoute)?.asset_out; + let next_trade_asset_in = route.get(i.saturating_add(1)).ok_or(Error::::InvalidRoute)?.asset_in; + + ensure!(asset_out == next_trade_asset_in, Error::::InvalidRoute) + } + Ok(()) } diff --git a/pallets/route-executor/src/tests/sell.rs b/pallets/route-executor/src/tests/sell.rs index 31ac2142b..21399b2ab 100644 --- a/pallets/route-executor/src/tests/sell.rs +++ b/pallets/route-executor/src/tests/sell.rs @@ -521,3 +521,34 @@ fn sell_should_fail_when_assets_dont_correspond_to_route() { ); }); } + +#[test] +fn sell_should_fail_when_intermediare_assets_are_inconsistent() { + ExtBuilder::default().build().execute_with(|| { + //Arrange + let amount_to_sell = 10; + let limit = 5; + let trade1 = Trade { + pool: PoolType::XYK, + asset_in: HDX, + asset_out: AUSD, + }; + let trade2 = Trade { + pool: PoolType::XYK, + asset_in: HDX, + asset_out: MOVR, + }; + let trade3 = Trade { + pool: PoolType::XYK, + asset_in: HDX, + asset_out: KSM, + }; + let trades = vec![trade1, trade2, trade3]; + + //Act + assert_noop!( + Router::sell(RuntimeOrigin::signed(ALICE), HDX, KSM, amount_to_sell, limit, trades), + Error::::InvalidRoute + ); + }); +} diff --git a/pallets/route-executor/src/tests/set_route.rs b/pallets/route-executor/src/tests/set_route.rs index 24c76088b..3e7cc8e69 100644 --- a/pallets/route-executor/src/tests/set_route.rs +++ b/pallets/route-executor/src/tests/set_route.rs @@ -374,7 +374,7 @@ fn set_route_should_fail_when_route_is_not_valid() { //Act and assert assert_noop!( Router::set_route(RuntimeOrigin::signed(ALICE), asset_pair, route), - orml_tokens::Error::::BalanceTooLow + Error::::InvalidRoute ); assert!(Router::route(asset_pair).is_none()); @@ -403,7 +403,7 @@ fn set_route_should_fail_when_trying_to_override_with_invalid_route() { //Act and assert assert_noop!( Router::set_route(RuntimeOrigin::signed(ALICE), asset_pair, invalid_route), - orml_tokens::Error::::BalanceTooLow + Error::::InvalidRoute ); let stored_route = Router::get_route(asset_pair); From 2f6fc628bd52e9c6705f76ef8fc5ee65291a98c4 Mon Sep 17 00:00:00 2001 From: dmoka Date: Fri, 15 Mar 2024 19:15:13 +0100 Subject: [PATCH 05/21] improve set route validation to use the lowest liquidity asset reference --- integration-tests/src/router.rs | 35 +++++++++++----------- pallets/route-executor/src/lib.rs | 50 +++++++++++++++++++++++-------- 2 files changed, 55 insertions(+), 30 deletions(-) diff --git a/integration-tests/src/router.rs b/integration-tests/src/router.rs index c490b9b28..b778008d8 100644 --- a/integration-tests/src/router.rs +++ b/integration-tests/src/router.rs @@ -2894,7 +2894,7 @@ mod set_route { } #[test] - fn set_route_should_not_work_when_no_existing_and_reversed_route_is_not_valid_for_trade() { + fn set_route_should_not_work_when_new_route_is_invalid() { TestNet::reset(); Hydra::execute_with(|| { @@ -2960,16 +2960,22 @@ mod set_route { }, ]; + assert_ok!(hydradx_runtime::Omnipool::set_asset_tradable_state( + hydradx_runtime::RuntimeOrigin::root(), + DOT, + Tradability::FROZEN + )); + //Act and assert assert_noop!( Router::set_route(hydradx_runtime::RuntimeOrigin::signed(ALICE.into()), asset_pair, route2), - pallet_omnipool::Error::::MaxInRatioExceeded + pallet_omnipool::Error::::NotAllowed ); }); } #[test] - fn set_route_should_not_work_when_reversed_route_is_not_valid_due_to_maxout_ratio() { + fn set_route_should_fail_when_reversed_route_is_not_valid_due_to_minout_ratio() { TestNet::reset(); Hydra::execute_with(|| { @@ -2991,11 +2997,11 @@ mod set_route { AccountId::from(BOB), )); - create_xyk_pool_with_amounts(HDX, 1000000 * UNITS, DOT, 1000000 * UNITS); - create_xyk_pool_with_amounts(DOT, 1000000 * UNITS, BTC, 1000000 * UNITS); - create_xyk_pool_with_amounts(HDX, 1000000 * UNITS, DAI, 1000000 * UNITS); create_xyk_pool_with_amounts(DAI, 1000000 * UNITS, DOT, 1000000 * UNITS); + create_xyk_pool_with_amounts(DOT, 1000000 * UNITS, BTC, 1000000 * UNITS); + + create_xyk_pool_with_amounts(HDX, 100000 * UNITS, BTC, 50000000000 * UNITS); let route1 = vec![ Trade { @@ -3023,18 +3029,11 @@ mod set_route { route1 )); - let route2 = vec![ - Trade { - pool: PoolType::Omnipool, - asset_in: HDX, - asset_out: DOT, - }, - Trade { - pool: PoolType::XYK, - asset_in: DOT, - asset_out: BTC, - }, - ]; + let route2 = vec![Trade { + pool: PoolType::XYK, + asset_in: HDX, + asset_out: BTC, + }]; //Act and assert assert_noop!( diff --git a/pallets/route-executor/src/lib.rs b/pallets/route-executor/src/lib.rs index 76298bf78..caa4d0051 100644 --- a/pallets/route-executor/src/lib.rs +++ b/pallets/route-executor/src/lib.rs @@ -38,6 +38,7 @@ pub use hydradx_traits::router::{ }; use orml_traits::arithmetic::{CheckedAdd, CheckedSub}; use sp_runtime::traits::{AccountIdConversion, CheckedDiv}; +use sp_runtime::DispatchError::BadOrigin; use sp_runtime::{ArithmeticError, DispatchError, TransactionOutcome}; use sp_std::{vec, vec::Vec}; @@ -369,17 +370,29 @@ pub mod pallet { match Self::validate_route(&existing_route) { Ok((reference_amount_in, reference_amount_in_for_inverse)) => { - let inverse_new_route = inverse_route(new_route.to_vec()); - let inverse_existing_route = inverse_route(existing_route.to_vec()); + let new_route_validation = Self::validate_sell(new_route.clone(), reference_amount_in); - Self::validate_sell(new_route.clone(), reference_amount_in)?; - Self::validate_sell(inverse_new_route.clone(), reference_amount_in_for_inverse)?; + let inverse_new_route = inverse_route(new_route.to_vec()); + let inverse_new_route_validation = + Self::validate_sell(inverse_new_route.clone(), reference_amount_in_for_inverse); + + match (new_route_validation, inverse_new_route_validation) { + (Ok(_), Ok(_)) => (), + (Err(_), Ok(amount_out)) => { + Self::validate_sell(new_route.clone().to_vec(), amount_out).map(|_| ())?; + } + (Ok(amount_out), Err(_)) => { + Self::validate_sell(inverse_new_route.clone(), amount_out).map(|_| ())?; + } + (Err(err), Err(_)) => return Err(err.into()), + } let amount_out_for_existing_route = Self::calculate_expected_amount_out(&existing_route, reference_amount_in)?; let amount_out_for_new_route = Self::calculate_expected_amount_out(&new_route, reference_amount_in)?; + let inverse_existing_route = inverse_route(existing_route.to_vec()); let amount_out_for_existing_inversed_route = Self::calculate_expected_amount_out(&inverse_existing_route, reference_amount_in_for_inverse)?; let amount_out_for_new_inversed_route = @@ -514,13 +527,22 @@ impl Pallet { fn validate_route(route: &[Trade]) -> Result<(T::Balance, T::Balance), DispatchError> { let reference_amount_in = Self::calculate_reference_amount_in(route)?; - Self::validate_sell(route.to_vec(), reference_amount_in)?; + let route_validation = Self::validate_sell(route.to_vec(), reference_amount_in); let inverse_route = inverse_route(route.to_vec()); let reference_amount_in_for_inverse_route = Self::calculate_reference_amount_in(&inverse_route)?; - Self::validate_sell(inverse_route, reference_amount_in_for_inverse_route)?; - - Ok((reference_amount_in, reference_amount_in_for_inverse_route)) + let inverse_route_validation = + Self::validate_sell(inverse_route.clone(), reference_amount_in_for_inverse_route); + + match (route_validation, inverse_route_validation) { + (Ok(_), Ok(_)) => Ok((reference_amount_in, reference_amount_in_for_inverse_route)), + (Err(_), Ok(amount_out)) => Self::validate_sell(route.clone().to_vec(), amount_out) + .map(|_| ((amount_out, reference_amount_in_for_inverse_route))), + (Ok(amount_out), Err(_)) => { + Self::validate_sell(inverse_route.clone(), amount_out).map(|_| ((reference_amount_in, amount_out))) + } + (Err(err), Err(_)) => Err(err.into()), + } } fn calculate_reference_amount_in(route: &[Trade]) -> Result { @@ -547,19 +569,23 @@ impl Pallet { Ok(one_percent_asset_in_liquidity) } - fn validate_sell(route: Vec>, amount_in: T::Balance) -> DispatchResult { + fn validate_sell(route: Vec>, amount_in: T::Balance) -> Result { let asset_in = route.first().ok_or(Error::::InvalidRoute)?.asset_in; let asset_out = route.last().ok_or(Error::::InvalidRoute)?.asset_out; - with_transaction(|| { + with_transaction::(|| { let origin: OriginFor = Origin::::Signed(Self::router_account()).into(); + let Ok(who) = ensure_signed(origin.clone()) else { + return TransactionOutcome::Rollback(Err(Error::::InvalidRoute.into())) + }; let _ = T::Currency::mint_into(asset_in, &Self::router_account(), amount_in); let sell_result = Self::sell(origin, asset_in, asset_out, amount_in, u128::MIN.into(), route.clone()); + let amount_out = + T::Currency::reducible_balance(asset_out, &who, Preservation::Expendable, Fortitude::Polite); - TransactionOutcome::Rollback(sell_result) + TransactionOutcome::Rollback(sell_result.map(|_| amount_out)) }) - .map_err(|err| err.into()) } fn calculate_expected_amount_out( From b0f2d2f6af6c575f8a32b22bbb82d45195d3e3f3 Mon Sep 17 00:00:00 2001 From: dmoka Date: Mon, 18 Mar 2024 11:43:47 +0100 Subject: [PATCH 06/21] add some integration tests to cover cases --- integration-tests/src/router.rs | 75 +++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/integration-tests/src/router.rs b/integration-tests/src/router.rs index b778008d8..100ffa548 100644 --- a/integration-tests/src/router.rs +++ b/integration-tests/src/router.rs @@ -3118,6 +3118,81 @@ mod set_route { }); } + #[test] + fn set_route_should_fail_when_no_prestored_but_inverse_route_is_invalid() { + TestNet::reset(); + + Hydra::execute_with(|| { + //Arrange + init_omnipool(); + + create_xyk_pool_with_amounts(HDX, 100 * UNITS, BTC, 100000000 * UNITS); + + let asset_pair = Pair::new(HDX, BTC); + + let route2 = vec![Trade { + pool: PoolType::XYK, + asset_in: HDX, + asset_out: BTC, + }]; + + //Act and assert + assert_noop!( + Router::set_route(hydradx_runtime::RuntimeOrigin::signed(ALICE.into()), asset_pair, route2), + sp_runtime::TokenError::BelowMinimum + ); + }); + } + + #[test] + fn set_route_should_pass_when_normal_is_broken_but_revalidated_with_amount_from_inverse() { + TestNet::reset(); + + Hydra::execute_with(|| { + //Arrange + init_omnipool(); + + assert_ok!(Currencies::update_balance( + hydradx_runtime::RuntimeOrigin::root(), + Omnipool::protocol_account(), + DOT, + 100000000 * UNITS as i128, + )); + + assert_ok!(hydradx_runtime::Omnipool::add_token( + hydradx_runtime::RuntimeOrigin::root(), + DOT, + FixedU128::from_rational(1, 2), + Permill::from_percent(1), + AccountId::from(BOB), + )); + + create_xyk_pool_with_amounts(DOT, 1 * UNITS, BTC, 1 * UNITS); + + let asset_pair = Pair::new(HDX, BTC); + + let route2 = vec![ + Trade { + pool: PoolType::Omnipool, + asset_in: HDX, + asset_out: DOT, + }, + Trade { + pool: PoolType::XYK, + asset_in: DOT, + asset_out: BTC, + }, + ]; + + //Act and assert + assert_ok!(Router::set_route( + hydradx_runtime::RuntimeOrigin::signed(ALICE.into()), + asset_pair, + route2 + ),); + }); + } + #[test] fn set_should_should_work_when_omnipool_route_does_not_exist_for_pair() { TestNet::reset(); From 7bd7d6689f5afb582deb43ffd1bc570190a35829 Mon Sep 17 00:00:00 2001 From: dmoka Date: Mon, 18 Mar 2024 11:54:40 +0100 Subject: [PATCH 07/21] remove invalid test --- integration-tests/src/router.rs | 69 --------------------------------- 1 file changed, 69 deletions(-) diff --git a/integration-tests/src/router.rs b/integration-tests/src/router.rs index 100ffa548..4fc60d5a5 100644 --- a/integration-tests/src/router.rs +++ b/integration-tests/src/router.rs @@ -2974,75 +2974,6 @@ mod set_route { }); } - #[test] - fn set_route_should_fail_when_reversed_route_is_not_valid_due_to_minout_ratio() { - TestNet::reset(); - - Hydra::execute_with(|| { - //Arrange - init_omnipool(); - - assert_ok!(Currencies::update_balance( - hydradx_runtime::RuntimeOrigin::root(), - Omnipool::protocol_account(), - DOT, - 3000 * UNITS as i128, - )); - - assert_ok!(hydradx_runtime::Omnipool::add_token( - hydradx_runtime::RuntimeOrigin::root(), - DOT, - FixedU128::from_rational(1, 2), - Permill::from_percent(1), - AccountId::from(BOB), - )); - - create_xyk_pool_with_amounts(HDX, 1000000 * UNITS, DAI, 1000000 * UNITS); - create_xyk_pool_with_amounts(DAI, 1000000 * UNITS, DOT, 1000000 * UNITS); - create_xyk_pool_with_amounts(DOT, 1000000 * UNITS, BTC, 1000000 * UNITS); - - create_xyk_pool_with_amounts(HDX, 100000 * UNITS, BTC, 50000000000 * UNITS); - - let route1 = vec![ - Trade { - pool: PoolType::XYK, - asset_in: HDX, - asset_out: DAI, - }, - Trade { - pool: PoolType::XYK, - asset_in: DAI, - asset_out: DOT, - }, - Trade { - pool: PoolType::XYK, - asset_in: DOT, - asset_out: BTC, - }, - ]; - - let asset_pair = Pair::new(HDX, BTC); - - assert_ok!(Router::set_route( - hydradx_runtime::RuntimeOrigin::signed(ALICE.into()), - asset_pair, - route1 - )); - - let route2 = vec![Trade { - pool: PoolType::XYK, - asset_in: HDX, - asset_out: BTC, - }]; - - //Act and assert - assert_noop!( - Router::set_route(hydradx_runtime::RuntimeOrigin::signed(ALICE.into()), asset_pair, route2), - pallet_omnipool::Error::::MaxInRatioExceeded - ); - }); - } - #[test] fn set_route_should_work_when_stored_route_is_broken_due_to_frozen_asset() { TestNet::reset(); From 685546d4b4f27c19733d2b4b36b1c3ea52c935e7 Mon Sep 17 00:00:00 2001 From: dmoka Date: Mon, 18 Mar 2024 12:35:23 +0100 Subject: [PATCH 08/21] add force insert route to make technical orogine be able to add any route for safety reasons. --- pallets/route-executor/src/lib.rs | 51 ++++++++ .../src/tests/force_insert_route.rs | 111 ++++++++++++++++++ pallets/route-executor/src/tests/mock.rs | 2 + pallets/route-executor/src/tests/mod.rs | 1 + traits/src/router.rs | 6 + 5 files changed, 171 insertions(+) create mode 100644 pallets/route-executor/src/tests/force_insert_route.rs diff --git a/pallets/route-executor/src/lib.rs b/pallets/route-executor/src/lib.rs index caa4d0051..c40da25e7 100644 --- a/pallets/route-executor/src/lib.rs +++ b/pallets/route-executor/src/lib.rs @@ -108,6 +108,9 @@ pub mod pallet { /// Pool type used in the default route type DefaultRoutePoolType: Get>; + /// Origin able to set route without validation + type TechnicalOrigin: EnsureOrigin; + /// Weight information for the extrinsics. type WeightInfo: AmmTradeWeights>; } @@ -413,6 +416,38 @@ pub mod pallet { Err(Error::::RouteUpdateIsNotSuccessful.into()) } + + /// Force inserts the on-chain route for a given asset pair, so there is no any validation for the route + /// + /// Can only be called by technical origin + /// + /// The route is stored in an ordered manner, based on the oder of the ids in the asset pair. + /// + /// If the route is set successfully, then the fee is payed back. + /// + /// - `origin`: The origin of the route setter + /// - `asset_pair`: The identifier of the asset-pair for which the route is set + /// - `new_route`: Series of [`Trade`] to be executed. A [`Trade`] specifies the asset pair (`asset_in`, `asset_out`) and the AMM (`pool`) in which the trade is executed. + /// + /// Emits `RouteUpdated` when successful. + /// + #[pallet::call_index(3)] + #[pallet::weight(T::WeightInfo::set_route_weight(new_route))] + #[transactional] + pub fn force_insert_route( + origin: OriginFor, + mut asset_pair: AssetPair, + mut new_route: Vec>, + ) -> DispatchResultWithPostInfo { + T::TechnicalOrigin::ensure_origin(origin)?; + + if !asset_pair.is_ordered() { + asset_pair = asset_pair.ordered_pair(); + new_route = inverse_route(new_route) + } + + Self::insert_route(asset_pair, new_route) + } } } @@ -706,6 +741,14 @@ impl RouterT DispatchResultWithPostInfo { Pallet::::set_route(origin, asset_pair, route) } + + fn force_insert_route( + origin: T::RuntimeOrigin, + asset_pair: AssetPair, + route: Vec>, + ) -> DispatchResultWithPostInfo { + Pallet::::force_insert_route(origin, asset_pair, route) + } } pub struct DummyRouter(PhantomData); @@ -761,6 +804,14 @@ impl RouterT DispatchResultWithPostInfo { Ok(Pays::Yes.into()) } + + fn force_insert_route( + _origin: T::RuntimeOrigin, + _asset_pair: AssetPair, + _route: Vec>, + ) -> DispatchResultWithPostInfo { + Ok(Pays::Yes.into()) + } } #[macro_export] diff --git a/pallets/route-executor/src/tests/force_insert_route.rs b/pallets/route-executor/src/tests/force_insert_route.rs new file mode 100644 index 000000000..3cd060907 --- /dev/null +++ b/pallets/route-executor/src/tests/force_insert_route.rs @@ -0,0 +1,111 @@ +// This file is part of HydraDX. + +// Copyright (C) 2020-2022 Intergalactic, Limited (GIB). +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use crate::tests::mock::*; +use crate::{Error, Event, Trade}; +use frame_support::pallet_prelude::*; +use frame_support::{assert_noop, assert_ok}; +use hydradx_traits::router::RouteProvider; +use hydradx_traits::router::{AssetPair, PoolType}; +use pretty_assertions::assert_eq; +use sp_runtime::DispatchError::BadOrigin; + +#[test] +fn force_insert_should_not_work_when_called_with_non_technical_origin() { + ExtBuilder::default().build().execute_with(|| { + //Arrange + let asset_pair = AssetPair::new(HDX, AUSD); + let route = vec![Trade { + pool: PoolType::XYK, + asset_in: HDX, + asset_out: AUSD, + }]; + + //Act + assert_noop!( + Router::force_insert_route(RuntimeOrigin::signed(ALICE), asset_pair, route.clone()), + BadOrigin + ); + }); +} + +#[test] +fn force_insert_should_work_when_called_with_technical_origin() { + ExtBuilder::default().build().execute_with(|| { + //Arrange + let asset_pair = AssetPair::new(HDX, AUSD); + let route = vec![Trade { + pool: PoolType::XYK, + asset_in: HDX, + asset_out: AUSD, + }]; + + //Act + assert_ok!( + Router::force_insert_route(RuntimeOrigin::root(), asset_pair, route.clone()), + Pays::No.into() + ); + }); +} + +#[test] +fn force_insert_should_fail_when_called_with_too_big_route() { + ExtBuilder::default().build().execute_with(|| { + //Arrange + let asset_pair = AssetPair::new(HDX, AUSD); + let route = vec![ + Trade { + pool: PoolType::XYK, + asset_in: HDX, + asset_out: AUSD, + }, + Trade { + pool: PoolType::XYK, + asset_in: HDX, + asset_out: AUSD, + }, + Trade { + pool: PoolType::XYK, + asset_in: HDX, + asset_out: AUSD, + }, + Trade { + pool: PoolType::XYK, + asset_in: HDX, + asset_out: AUSD, + }, + Trade { + pool: PoolType::XYK, + asset_in: HDX, + asset_out: AUSD, + }, + Trade { + pool: PoolType::XYK, + asset_in: HDX, + asset_out: AUSD, + }, + ]; + + //Act + assert_noop!( + Router::force_insert_route(RuntimeOrigin::root(), asset_pair, route.clone()), + Error::::MaxTradesExceeded + ); + }); +} + +//TODO: add test that it can add insuffucient asset diff --git a/pallets/route-executor/src/tests/mock.rs b/pallets/route-executor/src/tests/mock.rs index 2db151dbb..b6374b48f 100644 --- a/pallets/route-executor/src/tests/mock.rs +++ b/pallets/route-executor/src/tests/mock.rs @@ -21,6 +21,7 @@ use frame_support::{ parameter_types, traits::{Everything, Nothing}, }; +use frame_system::EnsureRoot; use frame_system::{ensure_signed, pallet_prelude::OriginFor}; use hydradx_traits::router::{ExecutorError, PoolType, TradeExecution}; use orml_traits::parameter_type_with_key; @@ -148,6 +149,7 @@ impl Config for Test { type InspectRegistry = MockedAssetRegistry; type AMM = Pools; type DefaultRoutePoolType = DefaultRoutePoolType; + type TechnicalOrigin = EnsureRoot; type WeightInfo = (); } diff --git a/pallets/route-executor/src/tests/mod.rs b/pallets/route-executor/src/tests/mod.rs index 145c5b2ba..922294662 100644 --- a/pallets/route-executor/src/tests/mod.rs +++ b/pallets/route-executor/src/tests/mod.rs @@ -1,4 +1,5 @@ pub mod buy; +pub mod force_insert_route; pub mod mock; pub mod sell; pub mod set_route; diff --git a/traits/src/router.rs b/traits/src/router.rs index 48da2a729..caa66cc57 100644 --- a/traits/src/router.rs +++ b/traits/src/router.rs @@ -121,6 +121,12 @@ pub trait RouterT { fn calculate_buy_trade_amounts(route: &[Trade], amount_out: Balance) -> Result, DispatchError>; fn set_route(origin: Origin, asset_pair: AssetPair, route: Vec) -> DispatchResultWithPostInfo; + + fn force_insert_route( + origin: Origin, + asset_pair: AssetPair, + route: Vec, + ) -> DispatchResultWithPostInfo; } /// All AMMs used in the router are required to implement this trait. From 89602897c3b9b8c36322f319b4665c7e553e72f3 Mon Sep 17 00:00:00 2001 From: dmoka Date: Mon, 18 Mar 2024 12:36:41 +0100 Subject: [PATCH 09/21] clean up --- pallets/route-executor/src/lib.rs | 3 --- pallets/route-executor/src/tests/force_insert_route.rs | 3 +-- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/pallets/route-executor/src/lib.rs b/pallets/route-executor/src/lib.rs index c40da25e7..80ef8651f 100644 --- a/pallets/route-executor/src/lib.rs +++ b/pallets/route-executor/src/lib.rs @@ -38,7 +38,6 @@ pub use hydradx_traits::router::{ }; use orml_traits::arithmetic::{CheckedAdd, CheckedSub}; use sp_runtime::traits::{AccountIdConversion, CheckedDiv}; -use sp_runtime::DispatchError::BadOrigin; use sp_runtime::{ArithmeticError, DispatchError, TransactionOutcome}; use sp_std::{vec, vec::Vec}; @@ -51,8 +50,6 @@ pub use pallet::*; pub const MAX_NUMBER_OF_TRADES: u32 = 5; -//TODO: rebenchmark on reference machine - #[frame_support::pallet] pub mod pallet { use super::*; diff --git a/pallets/route-executor/src/tests/force_insert_route.rs b/pallets/route-executor/src/tests/force_insert_route.rs index 3cd060907..2b4de89be 100644 --- a/pallets/route-executor/src/tests/force_insert_route.rs +++ b/pallets/route-executor/src/tests/force_insert_route.rs @@ -16,10 +16,9 @@ // limitations under the License. use crate::tests::mock::*; -use crate::{Error, Event, Trade}; +use crate::{Error, Trade}; use frame_support::pallet_prelude::*; use frame_support::{assert_noop, assert_ok}; -use hydradx_traits::router::RouteProvider; use hydradx_traits::router::{AssetPair, PoolType}; use pretty_assertions::assert_eq; use sp_runtime::DispatchError::BadOrigin; From 8fe6e63fd6d1b4f006f90e1b940c7cb7cd615928 Mon Sep 17 00:00:00 2001 From: dmoka Date: Mon, 18 Mar 2024 12:42:01 +0100 Subject: [PATCH 10/21] and super majority TE to be able to call force insert route --- runtime/hydradx/src/assets.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/runtime/hydradx/src/assets.rs b/runtime/hydradx/src/assets.rs index 4d30dfa85..88aef10ed 100644 --- a/runtime/hydradx/src/assets.rs +++ b/runtime/hydradx/src/assets.rs @@ -977,6 +977,7 @@ impl pallet_route_executor::Config for Runtime { type DefaultRoutePoolType = DefaultRoutePoolType; type NativeAssetId = NativeAssetId; type InspectRegistry = AssetRegistry; + type TechnicalOrigin = SuperMajorityTechCommittee; } parameter_types! { From 2b1616aa82a8bd4a155253ca5cb4dfd9d9abe2e2 Mon Sep 17 00:00:00 2001 From: dmoka Date: Mon, 18 Mar 2024 12:42:08 +0100 Subject: [PATCH 11/21] make clippy happy --- pallets/dca/src/tests/mock.rs | 1 + pallets/route-executor/src/lib.rs | 8 ++++---- pallets/route-executor/src/tests/force_insert_route.rs | 6 +++--- runtime/adapters/src/tests/mock.rs | 1 + 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/pallets/dca/src/tests/mock.rs b/pallets/dca/src/tests/mock.rs index 955bdb971..d24f1e671 100644 --- a/pallets/dca/src/tests/mock.rs +++ b/pallets/dca/src/tests/mock.rs @@ -397,6 +397,7 @@ impl pallet_route_executor::Config for Test { type InspectRegistry = MockedAssetRegistry; type DefaultRoutePoolType = DefaultRoutePoolType; type WeightInfo = (); + type TechnicalOrigin = EnsureRoot; } type OriginForRuntime = OriginFor; diff --git a/pallets/route-executor/src/lib.rs b/pallets/route-executor/src/lib.rs index 80ef8651f..92d3456f1 100644 --- a/pallets/route-executor/src/lib.rs +++ b/pallets/route-executor/src/lib.rs @@ -379,7 +379,7 @@ pub mod pallet { match (new_route_validation, inverse_new_route_validation) { (Ok(_), Ok(_)) => (), (Err(_), Ok(amount_out)) => { - Self::validate_sell(new_route.clone().to_vec(), amount_out).map(|_| ())?; + Self::validate_sell(new_route.to_vec(), amount_out).map(|_| ())?; } (Ok(amount_out), Err(_)) => { Self::validate_sell(inverse_new_route.clone(), amount_out).map(|_| ())?; @@ -569,11 +569,11 @@ impl Pallet { match (route_validation, inverse_route_validation) { (Ok(_), Ok(_)) => Ok((reference_amount_in, reference_amount_in_for_inverse_route)), (Err(_), Ok(amount_out)) => Self::validate_sell(route.clone().to_vec(), amount_out) - .map(|_| ((amount_out, reference_amount_in_for_inverse_route))), + .map(|_| (amount_out, reference_amount_in_for_inverse_route)), (Ok(amount_out), Err(_)) => { - Self::validate_sell(inverse_route.clone(), amount_out).map(|_| ((reference_amount_in, amount_out))) + Self::validate_sell(inverse_route, amount_out).map(|_| (reference_amount_in, amount_out)) } - (Err(err), Err(_)) => Err(err.into()), + (Err(err), Err(_)) => Err(err), } } diff --git a/pallets/route-executor/src/tests/force_insert_route.rs b/pallets/route-executor/src/tests/force_insert_route.rs index 2b4de89be..4dbd209c2 100644 --- a/pallets/route-executor/src/tests/force_insert_route.rs +++ b/pallets/route-executor/src/tests/force_insert_route.rs @@ -36,7 +36,7 @@ fn force_insert_should_not_work_when_called_with_non_technical_origin() { //Act assert_noop!( - Router::force_insert_route(RuntimeOrigin::signed(ALICE), asset_pair, route.clone()), + Router::force_insert_route(RuntimeOrigin::signed(ALICE), asset_pair, route), BadOrigin ); }); @@ -55,7 +55,7 @@ fn force_insert_should_work_when_called_with_technical_origin() { //Act assert_ok!( - Router::force_insert_route(RuntimeOrigin::root(), asset_pair, route.clone()), + Router::force_insert_route(RuntimeOrigin::root(), asset_pair, route), Pays::No.into() ); }); @@ -101,7 +101,7 @@ fn force_insert_should_fail_when_called_with_too_big_route() { //Act assert_noop!( - Router::force_insert_route(RuntimeOrigin::root(), asset_pair, route.clone()), + Router::force_insert_route(RuntimeOrigin::root(), asset_pair, route), Error::::MaxTradesExceeded ); }); diff --git a/runtime/adapters/src/tests/mock.rs b/runtime/adapters/src/tests/mock.rs index aa2a222ea..9a96428b6 100644 --- a/runtime/adapters/src/tests/mock.rs +++ b/runtime/adapters/src/tests/mock.rs @@ -361,6 +361,7 @@ impl pallet_route_executor::Config for Test { type InspectRegistry = MockedAssetRegistry; type AMM = Pools; type DefaultRoutePoolType = DefaultRoutePoolType; + type TechnicalOrigin = EnsureRoot; type WeightInfo = (); } From e3dc948068403e97dc24fce12381b4b2dfc60991 Mon Sep 17 00:00:00 2001 From: dmoka Date: Mon, 18 Mar 2024 12:52:35 +0100 Subject: [PATCH 12/21] adjust doc --- pallets/route-executor/README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pallets/route-executor/README.md b/pallets/route-executor/README.md index de3a6339b..09ad44f81 100644 --- a/pallets/route-executor/README.md +++ b/pallets/route-executor/README.md @@ -18,6 +18,9 @@ If the route is set successfully, then the fee is payed back. If the route setting fails, it emits event `RouteUpdateIsNotSuccessful` +### Force insert route +The route can be force inserted for any asset pair by technical origin without involving any validation. + ### Providing routes This pallet is also responsible for providing the best routes for asset pairs. From 5d27a81be34d20143a37cabbb7389daf4a90e6cf Mon Sep 17 00:00:00 2001 From: dmoka Date: Mon, 18 Mar 2024 13:01:52 +0100 Subject: [PATCH 13/21] bump versions --- Cargo.lock | 10 +++++----- integration-tests/Cargo.toml | 2 +- pallets/dca/Cargo.toml | 2 +- pallets/route-executor/Cargo.toml | 2 +- runtime/adapters/Cargo.toml | 2 +- runtime/hydradx/Cargo.toml | 2 +- runtime/hydradx/src/lib.rs | 2 +- 7 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7b108fd13..aeee941d1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4571,7 +4571,7 @@ dependencies = [ [[package]] name = "hydradx-adapters" -version = "1.2.4" +version = "1.2.5" dependencies = [ "cumulus-pallet-parachain-system", "cumulus-primitives-core", @@ -4621,7 +4621,7 @@ dependencies = [ [[package]] name = "hydradx-runtime" -version = "223.0.0" +version = "224.0.0" dependencies = [ "cumulus-pallet-aura-ext", "cumulus-pallet-dmp-queue", @@ -7403,7 +7403,7 @@ dependencies = [ [[package]] name = "pallet-dca" -version = "1.4.0" +version = "1.4.1" dependencies = [ "cumulus-pallet-parachain-system", "cumulus-primitives-core", @@ -8321,7 +8321,7 @@ dependencies = [ [[package]] name = "pallet-route-executor" -version = "2.1.0" +version = "2.2.0" dependencies = [ "frame-benchmarking", "frame-support", @@ -11365,7 +11365,7 @@ dependencies = [ [[package]] name = "runtime-integration-tests" -version = "1.19.9" +version = "1.19.10" dependencies = [ "cumulus-pallet-aura-ext", "cumulus-pallet-dmp-queue", diff --git a/integration-tests/Cargo.toml b/integration-tests/Cargo.toml index 4e6999ae0..7684cc98a 100644 --- a/integration-tests/Cargo.toml +++ b/integration-tests/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "runtime-integration-tests" -version = "1.19.9" +version = "1.19.10" description = "Integration tests" authors = ["GalacticCouncil"] edition = "2021" diff --git a/pallets/dca/Cargo.toml b/pallets/dca/Cargo.toml index 6a379fcc5..c921e6f6e 100644 --- a/pallets/dca/Cargo.toml +++ b/pallets/dca/Cargo.toml @@ -1,6 +1,6 @@ [package] name = 'pallet-dca' -version = "1.4.0" +version = "1.4.1" description = 'A pallet to manage DCA scheduling' authors = ['GalacticCouncil'] edition = '2021' diff --git a/pallets/route-executor/Cargo.toml b/pallets/route-executor/Cargo.toml index 28e17086f..db6487946 100644 --- a/pallets/route-executor/Cargo.toml +++ b/pallets/route-executor/Cargo.toml @@ -1,6 +1,6 @@ [package] name = 'pallet-route-executor' -version = '2.1.0' +version = '2.2.0' description = 'A pallet to execute a route containing a sequence of trades' authors = ['GalacticCouncil'] edition = '2021' diff --git a/runtime/adapters/Cargo.toml b/runtime/adapters/Cargo.toml index 494661492..01737a417 100644 --- a/runtime/adapters/Cargo.toml +++ b/runtime/adapters/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "hydradx-adapters" -version = "1.2.4" +version = "1.2.5" description = "Structs and other generic types for building runtimes." authors = ["GalacticCouncil"] edition = "2021" diff --git a/runtime/hydradx/Cargo.toml b/runtime/hydradx/Cargo.toml index e3c818bbe..c90d4e2a5 100644 --- a/runtime/hydradx/Cargo.toml +++ b/runtime/hydradx/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "hydradx-runtime" -version = "223.0.0" +version = "224.0.0" authors = ["GalacticCouncil"] edition = "2021" license = "Apache 2.0" diff --git a/runtime/hydradx/src/lib.rs b/runtime/hydradx/src/lib.rs index 0731cf3ff..f6586e87d 100644 --- a/runtime/hydradx/src/lib.rs +++ b/runtime/hydradx/src/lib.rs @@ -109,7 +109,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("hydradx"), impl_name: create_runtime_str!("hydradx"), authoring_version: 1, - spec_version: 223, + spec_version: 224, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 1, From 6ae57ce1f3ef7adc63b402480a983e594841b62f Mon Sep 17 00:00:00 2001 From: dmoka Date: Mon, 18 Mar 2024 13:05:22 +0100 Subject: [PATCH 14/21] bump traits version --- Cargo.lock | 2 +- traits/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index aeee941d1..df0c8cf8c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4747,7 +4747,7 @@ dependencies = [ [[package]] name = "hydradx-traits" -version = "3.1.0" +version = "3.1.1" dependencies = [ "frame-support", "impl-trait-for-tuples", diff --git a/traits/Cargo.toml b/traits/Cargo.toml index 115abd37b..dbc0b43e4 100644 --- a/traits/Cargo.toml +++ b/traits/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "hydradx-traits" -version = "3.1.0" +version = "3.1.1" description = "Shared traits" authors = ["GalacticCouncil"] edition = "2021" From 1766898e2eeeb56b1cadfd91935af2a5a9f572ae Mon Sep 17 00:00:00 2001 From: dmoka Date: Mon, 18 Mar 2024 13:27:37 +0100 Subject: [PATCH 15/21] fix existing benchmark --- .../src/benchmarking/route_executor.rs | 23 +++++++++++++------ 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/runtime/hydradx/src/benchmarking/route_executor.rs b/runtime/hydradx/src/benchmarking/route_executor.rs index cdba43295..605853f73 100644 --- a/runtime/hydradx/src/benchmarking/route_executor.rs +++ b/runtime/hydradx/src/benchmarking/route_executor.rs @@ -224,23 +224,20 @@ runtime_benchmarks! { create_xyk_pool(asset_3, asset_4); create_xyk_pool(asset_4, asset_5); create_xyk_pool(asset_5, asset_6); + create_xyk_pool(HDX, asset_6); //INIT OMNIPOOL - let acc = Omnipool::protocol_account(); + /*let acc = Omnipool::protocol_account(); crate::benchmarking::omnipool::init()?; // Create account for token provider and set balance let owner: AccountId = account("owner", 0, 1); - let token_price = FixedU128::from((5,1)); let token_amount = 100000 * UNITS; - //1000000000000000 - update_balance(asset_6, &acc, token_amount); - // Add the token to the pool - Omnipool::add_token(RawOrigin::Root.into(), asset_6, token_price, Permill::from_percent(100), owner)?; + Omnipool::add_token(RawOrigin::Root.into(), asset_6, token_price, Permill::from_percent(100), owner)?;*/ - let better_route = vec![Trade { + let route = vec![Trade { pool: PoolType::XYK, asset_in: HDX, asset_out: asset_2 @@ -261,6 +258,18 @@ runtime_benchmarks! { asset_in: asset_5, asset_out: asset_6 }]; + Router::set_route( + RawOrigin::Signed(caller.clone()).into(), + AssetPair::new(HDX, asset_6), + route.clone(), + )?; + + let better_route = vec![Trade { + pool: PoolType::XYK, + asset_in: HDX, + asset_out: asset_6 + },]; + }: { Router::set_route( RawOrigin::Signed(caller.clone()).into(), From eb65311f7f4ccf1eaaee72aee082c6e769bbe11d Mon Sep 17 00:00:00 2001 From: dmoka Date: Mon, 18 Mar 2024 13:42:46 +0100 Subject: [PATCH 16/21] add benchmark for force insert route --- .../src/benchmarking/route_executor.rs | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/runtime/hydradx/src/benchmarking/route_executor.rs b/runtime/hydradx/src/benchmarking/route_executor.rs index 605853f73..0de09613a 100644 --- a/runtime/hydradx/src/benchmarking/route_executor.rs +++ b/runtime/hydradx/src/benchmarking/route_executor.rs @@ -28,6 +28,7 @@ use frame_benchmarking::{account, BenchmarkError}; use frame_support::dispatch::DispatchResult; use frame_support::{assert_ok, ensure}; use frame_system::RawOrigin; +use hydradx_traits::router::inverse_route; use hydradx_traits::router::AssetPair; use hydradx_traits::router::{PoolType, RouterT, Trade}; use orml_benchmarking::runtime_benchmarks; @@ -281,6 +282,57 @@ runtime_benchmarks! { let stored_route = Router::route(AssetPair::new(HDX, asset_6)).unwrap(); assert_eq!(stored_route, better_route); } + + // Calculates the weight of xyk force insert route. Used in the calculation to determine the weight of the overhead. + force_insert_route_for_xyk { + let asset_1 = register_asset(b"AS1".to_vec(), 1u128).map_err(|_| BenchmarkError::Stop("Failed to register asset"))?; + let asset_2 = register_asset(b"AS2".to_vec(), 1u128).map_err(|_| BenchmarkError::Stop("Failed to register asset"))?; + let asset_3 = register_asset(b"AS3".to_vec(), 1u128).map_err(|_| BenchmarkError::Stop("Failed to register asset"))?; + let asset_4 = register_asset(b"AS4".to_vec(), 1u128).map_err(|_| BenchmarkError::Stop("Failed to register asset"))?; + let asset_5 = register_asset(b"AS5".to_vec(), 1u128).map_err(|_| BenchmarkError::Stop("Failed to register asset"))?; + let asset_6 = register_asset(b"AS6".to_vec(), 1u128).map_err(|_| BenchmarkError::Stop("Failed to register asset"))?; + + let caller: AccountId = funded_account("caller", 0, &[asset_1, asset_2,asset_3]); + create_xyk_pool(HDX, asset_2); + create_xyk_pool(asset_2, asset_3); + create_xyk_pool(asset_3, asset_4); + create_xyk_pool(asset_4, asset_5); + create_xyk_pool(asset_5, asset_6); + create_xyk_pool(HDX, asset_6); + + let route = vec![Trade { + pool: PoolType::XYK, + asset_in: asset_6, + asset_out: asset_5 + },Trade { + pool: PoolType::XYK, + asset_in: asset_5, + asset_out: asset_4 + },Trade { + pool: PoolType::XYK, + asset_in: asset_4, + asset_out: asset_3 + },Trade { + pool: PoolType::XYK, + asset_in: asset_3, + asset_out: asset_2 + },Trade { + pool: PoolType::XYK, + asset_in: asset_2, + asset_out: HDX + }]; + }: { + Router::force_insert_route( + RawOrigin::Root.into(), + AssetPair::new(asset_6, HDX), + route.clone(), + )?; + } + verify { + + let stored_route = Router::route(AssetPair::new(HDX, asset_6)).unwrap(); + assert_eq!(inverse_route(stored_route.to_vec()), route); + } } #[cfg(test)] From 9f5e66da6b31b47694f863438064f47d4cab0967 Mon Sep 17 00:00:00 2001 From: dmoka Date: Mon, 18 Mar 2024 13:50:18 +0100 Subject: [PATCH 17/21] rebenchmark route executor --- runtime/hydradx/src/weights/route_executor.rs | 92 +++++++------------ 1 file changed, 35 insertions(+), 57 deletions(-) diff --git a/runtime/hydradx/src/weights/route_executor.rs b/runtime/hydradx/src/weights/route_executor.rs index ad6a8b7b6..3763b1995 100644 --- a/runtime/hydradx/src/weights/route_executor.rs +++ b/runtime/hydradx/src/weights/route_executor.rs @@ -18,7 +18,7 @@ //! Autogenerated weights for `pallet_route_executor` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2024-03-05, STEPS: `10`, REPEAT: `30`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-03-18, STEPS: `10`, REPEAT: `30`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` //! HOSTNAME: `bench-bot`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: 1024 @@ -33,8 +33,8 @@ // --wasm-execution=compiled // --heap-pages=4096 // --template=.maintain/pallet-weight-template-no-back.hbs -// --pallet=pallet-route-executor -// --output=router.rs +// --pallet=pallet_route-executor +// --output=re.rs // --extrinsic=* #![cfg_attr(rustfmt, rustfmt_skip)] @@ -47,7 +47,7 @@ use core::marker::PhantomData; /// Weight functions for `pallet_route_executor`. pub struct HydraWeight(PhantomData); -impl pallet_route_executor::weights::WeightInfo for HydraWeight { +impl pallet_route_executor::WeightInfo for HydraWeight { /// Storage: `LBP::PoolData` (r:1 w:0) /// Proof: `LBP::PoolData` (`max_values`: None, `max_size`: Some(163), added: 2638, mode: `MaxEncodedLen`) /// Storage: `Tokens::Accounts` (r:5 w:5) @@ -67,10 +67,10 @@ impl pallet_route_executor::weights::WeightInfo for Hyd // Proof Size summary in bytes: // Measured: `3436` // Estimated: `13905` - // Minimum execution time: 347_725_000 picoseconds. - Weight::from_parts(351_096_698, 13905) - // Standard Error: 200_537 - .saturating_add(Weight::from_parts(50_253_676, 0).saturating_mul(c.into())) + // Minimum execution time: 343_206_000 picoseconds. + Weight::from_parts(346_501_794, 13905) + // Standard Error: 136_051 + .saturating_add(Weight::from_parts(51_792_643, 0).saturating_mul(c.into())) .saturating_add(T::DbWeight::get().reads(16)) .saturating_add(T::DbWeight::get().writes(7)) } @@ -94,78 +94,56 @@ impl pallet_route_executor::weights::WeightInfo for Hyd // Proof Size summary in bytes: // Measured: `1604 + b * (1837 ±0)` // Estimated: `6156 + b * (7749 ±99_524_913_928_918_768)` - // Minimum execution time: 76_051_000 picoseconds. - Weight::from_parts(76_610_000, 6156) - // Standard Error: 604_305 - .saturating_add(Weight::from_parts(2_329_553, 0).saturating_mul(c.into())) - // Standard Error: 1_326_623 - .saturating_add(Weight::from_parts(278_434_394, 0).saturating_mul(b.into())) + // Minimum execution time: 76_392_000 picoseconds. + Weight::from_parts(76_873_000, 6156) + // Standard Error: 610_618 + .saturating_add(Weight::from_parts(2_366_487, 0).saturating_mul(c.into())) + // Standard Error: 1_340_482 + .saturating_add(Weight::from_parts(273_016_424, 0).saturating_mul(b.into())) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().reads((13_u64).saturating_mul(b.into()))) .saturating_add(T::DbWeight::get().writes((7_u64).saturating_mul(b.into()))) .saturating_add(Weight::from_parts(0, 7749).saturating_mul(b.into())) } - /// Storage: `AssetRegistry::Assets` (r:7 w:0) + /// Storage: `AssetRegistry::Assets` (r:6 w:0) /// Proof: `AssetRegistry::Assets` (`max_values`: None, `max_size`: Some(125), added: 2600, mode: `MaxEncodedLen`) /// Storage: `Router::Routes` (r:1 w:1) /// Proof: `Router::Routes` (`max_values`: None, `max_size`: Some(90), added: 2565, mode: `MaxEncodedLen`) - /// Storage: `Omnipool::Assets` (r:2 w:0) - /// Proof: `Omnipool::Assets` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:8 w:0) + /// Storage: `System::Account` (r:7 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Tokens::Accounts` (r:16 w:0) + /// Storage: `Tokens::Accounts` (r:15 w:0) /// Proof: `Tokens::Accounts` (`max_values`: None, `max_size`: Some(108), added: 2583, mode: `MaxEncodedLen`) - /// Storage: `Omnipool::HubAssetImbalance` (r:1 w:0) - /// Proof: `Omnipool::HubAssetImbalance` (`max_values`: Some(1), `max_size`: Some(17), added: 512, mode: `MaxEncodedLen`) - /// Storage: `DynamicFees::AssetFee` (r:2 w:0) - /// Proof: `DynamicFees::AssetFee` (`max_values`: None, `max_size`: Some(24), added: 2499, mode: `MaxEncodedLen`) - /// Storage: `EmaOracle::Oracles` (r:2 w:0) - /// Proof: `EmaOracle::Oracles` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) + /// Storage: `XYK::ShareToken` (r:6 w:0) + /// Proof: `XYK::ShareToken` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) /// Storage: `Duster::AccountBlacklist` (r:7 w:0) /// Proof: `Duster::AccountBlacklist` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) /// Storage: `AssetRegistry::BannedAssets` (r:5 w:0) /// Proof: `AssetRegistry::BannedAssets` (`max_values`: None, `max_size`: Some(20), added: 2495, mode: `MaxEncodedLen`) - /// Storage: `MultiTransactionPayment::AccountCurrencyMap` (r:2 w:0) + /// Storage: `MultiTransactionPayment::AccountCurrencyMap` (r:1 w:0) /// Proof: `MultiTransactionPayment::AccountCurrencyMap` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) /// Storage: `MultiTransactionPayment::AcceptedCurrencies` (r:5 w:0) /// Proof: `MultiTransactionPayment::AcceptedCurrencies` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`) /// Storage: `EmaOracle::Accumulator` (r:1 w:0) /// Proof: `EmaOracle::Accumulator` (`max_values`: Some(1), `max_size`: Some(5921), added: 6416, mode: `MaxEncodedLen`) - /// Storage: `CircuitBreaker::AllowedTradeVolumeLimitPerAsset` (r:2 w:0) - /// Proof: `CircuitBreaker::AllowedTradeVolumeLimitPerAsset` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) - /// Storage: `CircuitBreaker::TradeVolumeLimitPerAsset` (r:2 w:0) - /// Proof: `CircuitBreaker::TradeVolumeLimitPerAsset` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`) - /// Storage: `CircuitBreaker::LiquidityAddLimitPerAsset` (r:1 w:0) - /// Proof: `CircuitBreaker::LiquidityAddLimitPerAsset` (`max_values`: None, `max_size`: Some(29), added: 2504, mode: `MaxEncodedLen`) - /// Storage: `CircuitBreaker::AllowedAddLiquidityAmountPerAsset` (r:1 w:0) - /// Proof: `CircuitBreaker::AllowedAddLiquidityAmountPerAsset` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) - /// Storage: `CircuitBreaker::LiquidityRemoveLimitPerAsset` (r:1 w:0) - /// Proof: `CircuitBreaker::LiquidityRemoveLimitPerAsset` (`max_values`: None, `max_size`: Some(29), added: 2504, mode: `MaxEncodedLen`) - /// Storage: `CircuitBreaker::AllowedRemoveLiquidityAmountPerAsset` (r:1 w:0) - /// Proof: `CircuitBreaker::AllowedRemoveLiquidityAmountPerAsset` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) - /// Storage: `Referrals::LinkedAccounts` (r:1 w:0) - /// Proof: `Referrals::LinkedAccounts` (`max_values`: None, `max_size`: Some(80), added: 2555, mode: `MaxEncodedLen`) - /// Storage: `Referrals::AssetRewards` (r:1 w:0) - /// Proof: `Referrals::AssetRewards` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) - /// Storage: `Referrals::TotalShares` (r:1 w:0) - /// Proof: `Referrals::TotalShares` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) - /// Storage: `Referrals::TraderShares` (r:1 w:0) - /// Proof: `Referrals::TraderShares` (`max_values`: None, `max_size`: Some(64), added: 2539, mode: `MaxEncodedLen`) - /// Storage: `Referrals::PendingConversions` (r:1 w:0) - /// Proof: `Referrals::PendingConversions` (`max_values`: None, `max_size`: Some(20), added: 2495, mode: `MaxEncodedLen`) - /// Storage: `Referrals::CounterForPendingConversions` (r:1 w:0) - /// Proof: `Referrals::CounterForPendingConversions` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) /// Storage: `Tokens::TotalIssuance` (r:1 w:0) /// Proof: `Tokens::TotalIssuance` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`) - /// Storage: `XYK::ShareToken` (r:5 w:0) - /// Proof: `XYK::ShareToken` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) fn set_route_for_xyk() -> Weight { // Proof Size summary in bytes: - // Measured: `7187` - // Estimated: `42318` - // Minimum execution time: 2_333_578_000 picoseconds. - Weight::from_parts(2_348_750_000, 42318) - .saturating_add(T::DbWeight::get().reads(79)) + // Measured: `6326` + // Estimated: `39735` + // Minimum execution time: 2_263_041_000 picoseconds. + Weight::from_parts(2_272_367_000, 39735) + .saturating_add(T::DbWeight::get().reads(55)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `Router::Routes` (r:0 w:1) + /// Proof: `Router::Routes` (`max_values`: None, `max_size`: Some(90), added: 2565, mode: `MaxEncodedLen`) + fn force_insert_route_for_xyk() -> Weight { + // Proof Size summary in bytes: + // Measured: `1012` + // Estimated: `0` + // Minimum execution time: 30_017_000 picoseconds. + Weight::from_parts(30_490_000, 0) .saturating_add(T::DbWeight::get().writes(1)) } } \ No newline at end of file From 34fec8250fdbaae6cbd96f1ddb95af250d8c88f8 Mon Sep 17 00:00:00 2001 From: dmoka Date: Mon, 18 Mar 2024 13:58:10 +0100 Subject: [PATCH 18/21] adjust bencmhark name --- runtime/hydradx/src/benchmarking/route_executor.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/runtime/hydradx/src/benchmarking/route_executor.rs b/runtime/hydradx/src/benchmarking/route_executor.rs index 0de09613a..6cb3bac5b 100644 --- a/runtime/hydradx/src/benchmarking/route_executor.rs +++ b/runtime/hydradx/src/benchmarking/route_executor.rs @@ -283,8 +283,7 @@ runtime_benchmarks! { assert_eq!(stored_route, better_route); } - // Calculates the weight of xyk force insert route. Used in the calculation to determine the weight of the overhead. - force_insert_route_for_xyk { + force_insert_route { let asset_1 = register_asset(b"AS1".to_vec(), 1u128).map_err(|_| BenchmarkError::Stop("Failed to register asset"))?; let asset_2 = register_asset(b"AS2".to_vec(), 1u128).map_err(|_| BenchmarkError::Stop("Failed to register asset"))?; let asset_3 = register_asset(b"AS3".to_vec(), 1u128).map_err(|_| BenchmarkError::Stop("Failed to register asset"))?; From 483ebc2d082bbe154e59ef1f70984769592c824d Mon Sep 17 00:00:00 2001 From: dmoka Date: Mon, 18 Mar 2024 13:59:24 +0100 Subject: [PATCH 19/21] revert benchmark to make it compile --- runtime/hydradx/src/weights/route_executor.rs | 92 ++++++++++++------- 1 file changed, 57 insertions(+), 35 deletions(-) diff --git a/runtime/hydradx/src/weights/route_executor.rs b/runtime/hydradx/src/weights/route_executor.rs index 3763b1995..ad6a8b7b6 100644 --- a/runtime/hydradx/src/weights/route_executor.rs +++ b/runtime/hydradx/src/weights/route_executor.rs @@ -18,7 +18,7 @@ //! Autogenerated weights for `pallet_route_executor` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2024-03-18, STEPS: `10`, REPEAT: `30`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-03-05, STEPS: `10`, REPEAT: `30`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` //! HOSTNAME: `bench-bot`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: 1024 @@ -33,8 +33,8 @@ // --wasm-execution=compiled // --heap-pages=4096 // --template=.maintain/pallet-weight-template-no-back.hbs -// --pallet=pallet_route-executor -// --output=re.rs +// --pallet=pallet-route-executor +// --output=router.rs // --extrinsic=* #![cfg_attr(rustfmt, rustfmt_skip)] @@ -47,7 +47,7 @@ use core::marker::PhantomData; /// Weight functions for `pallet_route_executor`. pub struct HydraWeight(PhantomData); -impl pallet_route_executor::WeightInfo for HydraWeight { +impl pallet_route_executor::weights::WeightInfo for HydraWeight { /// Storage: `LBP::PoolData` (r:1 w:0) /// Proof: `LBP::PoolData` (`max_values`: None, `max_size`: Some(163), added: 2638, mode: `MaxEncodedLen`) /// Storage: `Tokens::Accounts` (r:5 w:5) @@ -67,10 +67,10 @@ impl pallet_route_executor::WeightInfo for HydraWeight< // Proof Size summary in bytes: // Measured: `3436` // Estimated: `13905` - // Minimum execution time: 343_206_000 picoseconds. - Weight::from_parts(346_501_794, 13905) - // Standard Error: 136_051 - .saturating_add(Weight::from_parts(51_792_643, 0).saturating_mul(c.into())) + // Minimum execution time: 347_725_000 picoseconds. + Weight::from_parts(351_096_698, 13905) + // Standard Error: 200_537 + .saturating_add(Weight::from_parts(50_253_676, 0).saturating_mul(c.into())) .saturating_add(T::DbWeight::get().reads(16)) .saturating_add(T::DbWeight::get().writes(7)) } @@ -94,56 +94,78 @@ impl pallet_route_executor::WeightInfo for HydraWeight< // Proof Size summary in bytes: // Measured: `1604 + b * (1837 ±0)` // Estimated: `6156 + b * (7749 ±99_524_913_928_918_768)` - // Minimum execution time: 76_392_000 picoseconds. - Weight::from_parts(76_873_000, 6156) - // Standard Error: 610_618 - .saturating_add(Weight::from_parts(2_366_487, 0).saturating_mul(c.into())) - // Standard Error: 1_340_482 - .saturating_add(Weight::from_parts(273_016_424, 0).saturating_mul(b.into())) + // Minimum execution time: 76_051_000 picoseconds. + Weight::from_parts(76_610_000, 6156) + // Standard Error: 604_305 + .saturating_add(Weight::from_parts(2_329_553, 0).saturating_mul(c.into())) + // Standard Error: 1_326_623 + .saturating_add(Weight::from_parts(278_434_394, 0).saturating_mul(b.into())) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().reads((13_u64).saturating_mul(b.into()))) .saturating_add(T::DbWeight::get().writes((7_u64).saturating_mul(b.into()))) .saturating_add(Weight::from_parts(0, 7749).saturating_mul(b.into())) } - /// Storage: `AssetRegistry::Assets` (r:6 w:0) + /// Storage: `AssetRegistry::Assets` (r:7 w:0) /// Proof: `AssetRegistry::Assets` (`max_values`: None, `max_size`: Some(125), added: 2600, mode: `MaxEncodedLen`) /// Storage: `Router::Routes` (r:1 w:1) /// Proof: `Router::Routes` (`max_values`: None, `max_size`: Some(90), added: 2565, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:7 w:0) + /// Storage: `Omnipool::Assets` (r:2 w:0) + /// Proof: `Omnipool::Assets` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:8 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Tokens::Accounts` (r:15 w:0) + /// Storage: `Tokens::Accounts` (r:16 w:0) /// Proof: `Tokens::Accounts` (`max_values`: None, `max_size`: Some(108), added: 2583, mode: `MaxEncodedLen`) - /// Storage: `XYK::ShareToken` (r:6 w:0) - /// Proof: `XYK::ShareToken` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) + /// Storage: `Omnipool::HubAssetImbalance` (r:1 w:0) + /// Proof: `Omnipool::HubAssetImbalance` (`max_values`: Some(1), `max_size`: Some(17), added: 512, mode: `MaxEncodedLen`) + /// Storage: `DynamicFees::AssetFee` (r:2 w:0) + /// Proof: `DynamicFees::AssetFee` (`max_values`: None, `max_size`: Some(24), added: 2499, mode: `MaxEncodedLen`) + /// Storage: `EmaOracle::Oracles` (r:2 w:0) + /// Proof: `EmaOracle::Oracles` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) /// Storage: `Duster::AccountBlacklist` (r:7 w:0) /// Proof: `Duster::AccountBlacklist` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) /// Storage: `AssetRegistry::BannedAssets` (r:5 w:0) /// Proof: `AssetRegistry::BannedAssets` (`max_values`: None, `max_size`: Some(20), added: 2495, mode: `MaxEncodedLen`) - /// Storage: `MultiTransactionPayment::AccountCurrencyMap` (r:1 w:0) + /// Storage: `MultiTransactionPayment::AccountCurrencyMap` (r:2 w:0) /// Proof: `MultiTransactionPayment::AccountCurrencyMap` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) /// Storage: `MultiTransactionPayment::AcceptedCurrencies` (r:5 w:0) /// Proof: `MultiTransactionPayment::AcceptedCurrencies` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`) /// Storage: `EmaOracle::Accumulator` (r:1 w:0) /// Proof: `EmaOracle::Accumulator` (`max_values`: Some(1), `max_size`: Some(5921), added: 6416, mode: `MaxEncodedLen`) + /// Storage: `CircuitBreaker::AllowedTradeVolumeLimitPerAsset` (r:2 w:0) + /// Proof: `CircuitBreaker::AllowedTradeVolumeLimitPerAsset` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) + /// Storage: `CircuitBreaker::TradeVolumeLimitPerAsset` (r:2 w:0) + /// Proof: `CircuitBreaker::TradeVolumeLimitPerAsset` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`) + /// Storage: `CircuitBreaker::LiquidityAddLimitPerAsset` (r:1 w:0) + /// Proof: `CircuitBreaker::LiquidityAddLimitPerAsset` (`max_values`: None, `max_size`: Some(29), added: 2504, mode: `MaxEncodedLen`) + /// Storage: `CircuitBreaker::AllowedAddLiquidityAmountPerAsset` (r:1 w:0) + /// Proof: `CircuitBreaker::AllowedAddLiquidityAmountPerAsset` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) + /// Storage: `CircuitBreaker::LiquidityRemoveLimitPerAsset` (r:1 w:0) + /// Proof: `CircuitBreaker::LiquidityRemoveLimitPerAsset` (`max_values`: None, `max_size`: Some(29), added: 2504, mode: `MaxEncodedLen`) + /// Storage: `CircuitBreaker::AllowedRemoveLiquidityAmountPerAsset` (r:1 w:0) + /// Proof: `CircuitBreaker::AllowedRemoveLiquidityAmountPerAsset` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) + /// Storage: `Referrals::LinkedAccounts` (r:1 w:0) + /// Proof: `Referrals::LinkedAccounts` (`max_values`: None, `max_size`: Some(80), added: 2555, mode: `MaxEncodedLen`) + /// Storage: `Referrals::AssetRewards` (r:1 w:0) + /// Proof: `Referrals::AssetRewards` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) + /// Storage: `Referrals::TotalShares` (r:1 w:0) + /// Proof: `Referrals::TotalShares` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) + /// Storage: `Referrals::TraderShares` (r:1 w:0) + /// Proof: `Referrals::TraderShares` (`max_values`: None, `max_size`: Some(64), added: 2539, mode: `MaxEncodedLen`) + /// Storage: `Referrals::PendingConversions` (r:1 w:0) + /// Proof: `Referrals::PendingConversions` (`max_values`: None, `max_size`: Some(20), added: 2495, mode: `MaxEncodedLen`) + /// Storage: `Referrals::CounterForPendingConversions` (r:1 w:0) + /// Proof: `Referrals::CounterForPendingConversions` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) /// Storage: `Tokens::TotalIssuance` (r:1 w:0) /// Proof: `Tokens::TotalIssuance` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`) + /// Storage: `XYK::ShareToken` (r:5 w:0) + /// Proof: `XYK::ShareToken` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) fn set_route_for_xyk() -> Weight { // Proof Size summary in bytes: - // Measured: `6326` - // Estimated: `39735` - // Minimum execution time: 2_263_041_000 picoseconds. - Weight::from_parts(2_272_367_000, 39735) - .saturating_add(T::DbWeight::get().reads(55)) - .saturating_add(T::DbWeight::get().writes(1)) - } - /// Storage: `Router::Routes` (r:0 w:1) - /// Proof: `Router::Routes` (`max_values`: None, `max_size`: Some(90), added: 2565, mode: `MaxEncodedLen`) - fn force_insert_route_for_xyk() -> Weight { - // Proof Size summary in bytes: - // Measured: `1012` - // Estimated: `0` - // Minimum execution time: 30_017_000 picoseconds. - Weight::from_parts(30_490_000, 0) + // Measured: `7187` + // Estimated: `42318` + // Minimum execution time: 2_333_578_000 picoseconds. + Weight::from_parts(2_348_750_000, 42318) + .saturating_add(T::DbWeight::get().reads(79)) .saturating_add(T::DbWeight::get().writes(1)) } } \ No newline at end of file From 0d1fc9e3c47faac9f1c86416525d016b5bdf2612 Mon Sep 17 00:00:00 2001 From: dmoka Date: Mon, 18 Mar 2024 14:15:58 +0100 Subject: [PATCH 20/21] add benchmark for force insert and rebenchmark route executor pallet --- pallets/route-executor/src/lib.rs | 2 +- pallets/route-executor/src/weights.rs | 215 +++++++++++------- runtime/hydradx/src/assets.rs | 5 + runtime/hydradx/src/weights/route_executor.rs | 92 +++----- traits/src/router.rs | 4 + 5 files changed, 173 insertions(+), 145 deletions(-) diff --git a/pallets/route-executor/src/lib.rs b/pallets/route-executor/src/lib.rs index 272975214..85a65edeb 100644 --- a/pallets/route-executor/src/lib.rs +++ b/pallets/route-executor/src/lib.rs @@ -435,7 +435,7 @@ pub mod pallet { /// Emits `RouteUpdated` when successful. /// #[pallet::call_index(3)] - #[pallet::weight(T::WeightInfo::set_route_weight(new_route))] + #[pallet::weight(T::WeightInfo::force_insert_route_weight())] #[transactional] pub fn force_insert_route( origin: OriginFor, diff --git a/pallets/route-executor/src/weights.rs b/pallets/route-executor/src/weights.rs index 42ed0f1c4..be4375720 100644 --- a/pallets/route-executor/src/weights.rs +++ b/pallets/route-executor/src/weights.rs @@ -15,10 +15,11 @@ // See the License for the specific language governing permissions and // limitations under the License. + //! Autogenerated weights for `pallet_route_executor` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-12-12, STEPS: `5`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-03-18, STEPS: `10`, REPEAT: `30`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` //! HOSTNAME: `bench-bot`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` @@ -27,38 +28,34 @@ // target/release/hydradx // benchmark // pallet -// --pallet=pallet-route-executor +// --chain=dev +// --steps=10 +// --repeat=30 // --wasm-execution=compiled // --heap-pages=4096 -// --chain=dev +// --template=.maintain/pallet-weight-template.hbs +// --pallet=pallet_route-executor +// --output=re2.rs // --extrinsic=* -// --steps=5 -// --repeat=20 -// --output -// ./weights-1.1.0/route_executor.rs -// --template -// .maintain/pallet-weight-template-no-back.hbs +#![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] #![allow(unused_imports)] -#![allow(clippy::unnecessary_cast)] +#![allow(missing_docs)] -use frame_support::{ - traits::Get, - weights::{constants::RocksDbWeight, Weight}, -}; -use sp_std::marker::PhantomData; +use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; +use core::marker::PhantomData; -/// Weight functions needed for pallet_route_executor. +/// Weight functions needed for `pallet_route_executor`. pub trait WeightInfo { - fn calculate_and_execute_sell_in_lbp(c: u32) -> Weight; - fn calculate_and_execute_buy_in_lbp(c: u32, b: u32) -> Weight; + fn calculate_and_execute_sell_in_lbp(c: u32, ) -> Weight; + fn calculate_and_execute_buy_in_lbp(c: u32, b: u32, ) -> Weight; fn set_route_for_xyk() -> Weight; + fn force_insert_route() -> Weight; } -/// Weights for pallet_route_executor using the hydraDX node and recommended hardware. +/// Weights for `pallet_route_executor` using the HydraDX node and recommended hardware. pub struct HydraWeight(PhantomData); - impl WeightInfo for HydraWeight { /// Storage: `LBP::PoolData` (r:1 w:0) /// Proof: `LBP::PoolData` (`max_values`: None, `max_size`: Some(163), added: 2638, mode: `MaxEncodedLen`) @@ -68,18 +65,22 @@ impl WeightInfo for HydraWeight { /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// Storage: `Tokens::Locks` (r:1 w:1) /// Proof: `Tokens::Locks` (`max_values`: None, `max_size`: Some(1261), added: 3736, mode: `MaxEncodedLen`) + /// Storage: `Duster::AccountBlacklist` (r:2 w:0) + /// Proof: `Duster::AccountBlacklist` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) + /// Storage: `AssetRegistry::BannedAssets` (r:2 w:0) + /// Proof: `AssetRegistry::BannedAssets` (`max_values`: None, `max_size`: Some(20), added: 2495, mode: `MaxEncodedLen`) /// Storage: `AssetRegistry::Assets` (r:2 w:0) - /// Proof: `AssetRegistry::Assets` (`max_values`: None, `max_size`: Some(87), added: 2562, mode: `MaxEncodedLen`) + /// Proof: `AssetRegistry::Assets` (`max_values`: None, `max_size`: Some(125), added: 2600, mode: `MaxEncodedLen`) /// The range of component `c` is `[0, 1]`. - fn calculate_and_execute_sell_in_lbp(c: u32) -> Weight { + fn calculate_and_execute_sell_in_lbp(c: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `3016` + // Measured: `3436` // Estimated: `13905` - // Minimum execution time: 316_311_000 picoseconds. - Weight::from_parts(318_353_450, 13905) - // Standard Error: 164_994 - .saturating_add(Weight::from_parts(50_546_750, 0).saturating_mul(c.into())) - .saturating_add(T::DbWeight::get().reads(12_u64)) + // Minimum execution time: 342_467_000 picoseconds. + Weight::from_parts(346_028_529, 13905) + // Standard Error: 185_098 + .saturating_add(Weight::from_parts(50_586_970, 0).saturating_mul(c.into())) + .saturating_add(T::DbWeight::get().reads(16_u64)) .saturating_add(T::DbWeight::get().writes(7_u64)) } /// Storage: `LBP::PoolData` (r:1 w:0) @@ -90,55 +91,73 @@ impl WeightInfo for HydraWeight { /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// Storage: `Tokens::Locks` (r:1 w:1) /// Proof: `Tokens::Locks` (`max_values`: None, `max_size`: Some(1261), added: 3736, mode: `MaxEncodedLen`) + /// Storage: `Duster::AccountBlacklist` (r:2 w:0) + /// Proof: `Duster::AccountBlacklist` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) + /// Storage: `AssetRegistry::BannedAssets` (r:2 w:0) + /// Proof: `AssetRegistry::BannedAssets` (`max_values`: None, `max_size`: Some(20), added: 2495, mode: `MaxEncodedLen`) /// Storage: `AssetRegistry::Assets` (r:2 w:0) - /// Proof: `AssetRegistry::Assets` (`max_values`: None, `max_size`: Some(87), added: 2562, mode: `MaxEncodedLen`) + /// Proof: `AssetRegistry::Assets` (`max_values`: None, `max_size`: Some(125), added: 2600, mode: `MaxEncodedLen`) /// The range of component `c` is `[1, 2]`. /// The range of component `b` is `[0, 1]`. - fn calculate_and_execute_buy_in_lbp(c: u32, b: u32) -> Weight { + fn calculate_and_execute_buy_in_lbp(c: u32, b: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1567 + b * (1418 ±0)` + // Measured: `1604 + b * (1837 ±0)` // Estimated: `6156 + b * (7749 ±0)` - // Minimum execution time: 75_646_000 picoseconds. - Weight::from_parts(76_052_000, 6156) - // Standard Error: 1_389_058 - .saturating_add(Weight::from_parts(4_096_946, 0).saturating_mul(c.into())) - // Standard Error: 3_000_708 - .saturating_add(Weight::from_parts(250_139_938, 0).saturating_mul(b.into())) + // Minimum execution time: 75_256_000 picoseconds. + Weight::from_parts(76_245_000, 6156) + // Standard Error: 604_587 + .saturating_add(Weight::from_parts(2_376_809, 0).saturating_mul(c.into())) + // Standard Error: 1_327_242 + .saturating_add(Weight::from_parts(273_173_826, 0).saturating_mul(b.into())) .saturating_add(T::DbWeight::get().reads(3_u64)) - .saturating_add(T::DbWeight::get().reads((9_u64).saturating_mul(b.into()))) + .saturating_add(T::DbWeight::get().reads((13_u64).saturating_mul(b.into()))) .saturating_add(T::DbWeight::get().writes((7_u64).saturating_mul(b.into()))) .saturating_add(Weight::from_parts(0, 7749).saturating_mul(b.into())) } + /// Storage: `AssetRegistry::Assets` (r:6 w:0) + /// Proof: `AssetRegistry::Assets` (`max_values`: None, `max_size`: Some(125), added: 2600, mode: `MaxEncodedLen`) /// Storage: `Router::Routes` (r:1 w:1) /// Proof: `Router::Routes` (`max_values`: None, `max_size`: Some(90), added: 2565, mode: `MaxEncodedLen`) - /// Storage: `Tokens::Accounts` (r:9 w:0) - /// Proof: `Tokens::Accounts` (`max_values`: None, `max_size`: Some(108), added: 2583, mode: `MaxEncodedLen`) - /// Storage: `Tokens::TotalIssuance` (r:2 w:0) - /// Proof: `Tokens::TotalIssuance` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`) - /// Storage: `AssetRegistry::Assets` (r:3 w:0) - /// Proof: `AssetRegistry::Assets` (`max_values`: None, `max_size`: Some(87), added: 2562, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:4 w:0) + /// Storage: `System::Account` (r:7 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Tokens::Accounts` (r:15 w:0) + /// Proof: `Tokens::Accounts` (`max_values`: None, `max_size`: Some(108), added: 2583, mode: `MaxEncodedLen`) + /// Storage: `XYK::ShareToken` (r:6 w:0) + /// Proof: `XYK::ShareToken` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) + /// Storage: `Duster::AccountBlacklist` (r:7 w:0) + /// Proof: `Duster::AccountBlacklist` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) + /// Storage: `AssetRegistry::BannedAssets` (r:5 w:0) + /// Proof: `AssetRegistry::BannedAssets` (`max_values`: None, `max_size`: Some(20), added: 2495, mode: `MaxEncodedLen`) /// Storage: `MultiTransactionPayment::AccountCurrencyMap` (r:1 w:0) /// Proof: `MultiTransactionPayment::AccountCurrencyMap` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) - /// Storage: `MultiTransactionPayment::AcceptedCurrencies` (r:3 w:0) + /// Storage: `MultiTransactionPayment::AcceptedCurrencies` (r:5 w:0) /// Proof: `MultiTransactionPayment::AcceptedCurrencies` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`) - /// Storage: `XYK::ShareToken` (r:3 w:0) - /// Proof: `XYK::ShareToken` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) /// Storage: `EmaOracle::Accumulator` (r:1 w:0) /// Proof: `EmaOracle::Accumulator` (`max_values`: Some(1), `max_size`: Some(5921), added: 6416, mode: `MaxEncodedLen`) + /// Storage: `Tokens::TotalIssuance` (r:1 w:0) + /// Proof: `Tokens::TotalIssuance` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`) fn set_route_for_xyk() -> Weight { // Proof Size summary in bytes: - // Measured: `4201` - // Estimated: `24237` - // Minimum execution time: 1_126_027_000 picoseconds. - Weight::from_parts(1_133_155_000, 24237) - .saturating_add(T::DbWeight::get().reads(27_u64)) + // Measured: `6326` + // Estimated: `39735` + // Minimum execution time: 2_275_922_000 picoseconds. + Weight::from_parts(2_284_697_000, 39735) + .saturating_add(T::DbWeight::get().reads(55_u64)) + .saturating_add(T::DbWeight::get().writes(1_u64)) + } + /// Storage: `Router::Routes` (r:0 w:1) + /// Proof: `Router::Routes` (`max_values`: None, `max_size`: Some(90), added: 2565, mode: `MaxEncodedLen`) + fn force_insert_route() -> Weight { + // Proof Size summary in bytes: + // Measured: `1012` + // Estimated: `0` + // Minimum execution time: 30_072_000 picoseconds. + Weight::from_parts(30_421_000, 0) .saturating_add(T::DbWeight::get().writes(1_u64)) } } -// For backwards compatibility and tests +// For backwards compatibility and tests. impl WeightInfo for () { /// Storage: `LBP::PoolData` (r:1 w:0) /// Proof: `LBP::PoolData` (`max_values`: None, `max_size`: Some(163), added: 2638, mode: `MaxEncodedLen`) @@ -148,18 +167,22 @@ impl WeightInfo for () { /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// Storage: `Tokens::Locks` (r:1 w:1) /// Proof: `Tokens::Locks` (`max_values`: None, `max_size`: Some(1261), added: 3736, mode: `MaxEncodedLen`) + /// Storage: `Duster::AccountBlacklist` (r:2 w:0) + /// Proof: `Duster::AccountBlacklist` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) + /// Storage: `AssetRegistry::BannedAssets` (r:2 w:0) + /// Proof: `AssetRegistry::BannedAssets` (`max_values`: None, `max_size`: Some(20), added: 2495, mode: `MaxEncodedLen`) /// Storage: `AssetRegistry::Assets` (r:2 w:0) - /// Proof: `AssetRegistry::Assets` (`max_values`: None, `max_size`: Some(87), added: 2562, mode: `MaxEncodedLen`) + /// Proof: `AssetRegistry::Assets` (`max_values`: None, `max_size`: Some(125), added: 2600, mode: `MaxEncodedLen`) /// The range of component `c` is `[0, 1]`. - fn calculate_and_execute_sell_in_lbp(c: u32) -> Weight { + fn calculate_and_execute_sell_in_lbp(c: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `3016` + // Measured: `3436` // Estimated: `13905` - // Minimum execution time: 316_311_000 picoseconds. - Weight::from_parts(318_353_450, 13905) - // Standard Error: 164_994 - .saturating_add(Weight::from_parts(50_546_750, 0).saturating_mul(c.into())) - .saturating_add(RocksDbWeight::get().reads(12_u64)) + // Minimum execution time: 342_467_000 picoseconds. + Weight::from_parts(346_028_529, 13905) + // Standard Error: 185_098 + .saturating_add(Weight::from_parts(50_586_970, 0).saturating_mul(c.into())) + .saturating_add(RocksDbWeight::get().reads(16_u64)) .saturating_add(RocksDbWeight::get().writes(7_u64)) } /// Storage: `LBP::PoolData` (r:1 w:0) @@ -170,50 +193,68 @@ impl WeightInfo for () { /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// Storage: `Tokens::Locks` (r:1 w:1) /// Proof: `Tokens::Locks` (`max_values`: None, `max_size`: Some(1261), added: 3736, mode: `MaxEncodedLen`) + /// Storage: `Duster::AccountBlacklist` (r:2 w:0) + /// Proof: `Duster::AccountBlacklist` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) + /// Storage: `AssetRegistry::BannedAssets` (r:2 w:0) + /// Proof: `AssetRegistry::BannedAssets` (`max_values`: None, `max_size`: Some(20), added: 2495, mode: `MaxEncodedLen`) /// Storage: `AssetRegistry::Assets` (r:2 w:0) - /// Proof: `AssetRegistry::Assets` (`max_values`: None, `max_size`: Some(87), added: 2562, mode: `MaxEncodedLen`) + /// Proof: `AssetRegistry::Assets` (`max_values`: None, `max_size`: Some(125), added: 2600, mode: `MaxEncodedLen`) /// The range of component `c` is `[1, 2]`. /// The range of component `b` is `[0, 1]`. - fn calculate_and_execute_buy_in_lbp(c: u32, b: u32) -> Weight { + fn calculate_and_execute_buy_in_lbp(c: u32, b: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1567 + b * (1418 ±0)` + // Measured: `1604 + b * (1837 ±0)` // Estimated: `6156 + b * (7749 ±0)` - // Minimum execution time: 75_646_000 picoseconds. - Weight::from_parts(76_052_000, 6156) - // Standard Error: 1_389_058 - .saturating_add(Weight::from_parts(4_096_946, 0).saturating_mul(c.into())) - // Standard Error: 3_000_708 - .saturating_add(Weight::from_parts(250_139_938, 0).saturating_mul(b.into())) + // Minimum execution time: 75_256_000 picoseconds. + Weight::from_parts(76_245_000, 6156) + // Standard Error: 604_587 + .saturating_add(Weight::from_parts(2_376_809, 0).saturating_mul(c.into())) + // Standard Error: 1_327_242 + .saturating_add(Weight::from_parts(273_173_826, 0).saturating_mul(b.into())) .saturating_add(RocksDbWeight::get().reads(3_u64)) - .saturating_add(RocksDbWeight::get().reads((9_u64).saturating_mul(b.into()))) + .saturating_add(RocksDbWeight::get().reads((13_u64).saturating_mul(b.into()))) .saturating_add(RocksDbWeight::get().writes((7_u64).saturating_mul(b.into()))) .saturating_add(Weight::from_parts(0, 7749).saturating_mul(b.into())) } + /// Storage: `AssetRegistry::Assets` (r:6 w:0) + /// Proof: `AssetRegistry::Assets` (`max_values`: None, `max_size`: Some(125), added: 2600, mode: `MaxEncodedLen`) /// Storage: `Router::Routes` (r:1 w:1) /// Proof: `Router::Routes` (`max_values`: None, `max_size`: Some(90), added: 2565, mode: `MaxEncodedLen`) - /// Storage: `Tokens::Accounts` (r:9 w:0) - /// Proof: `Tokens::Accounts` (`max_values`: None, `max_size`: Some(108), added: 2583, mode: `MaxEncodedLen`) - /// Storage: `Tokens::TotalIssuance` (r:2 w:0) - /// Proof: `Tokens::TotalIssuance` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`) - /// Storage: `AssetRegistry::Assets` (r:3 w:0) - /// Proof: `AssetRegistry::Assets` (`max_values`: None, `max_size`: Some(87), added: 2562, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:4 w:0) + /// Storage: `System::Account` (r:7 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Tokens::Accounts` (r:15 w:0) + /// Proof: `Tokens::Accounts` (`max_values`: None, `max_size`: Some(108), added: 2583, mode: `MaxEncodedLen`) + /// Storage: `XYK::ShareToken` (r:6 w:0) + /// Proof: `XYK::ShareToken` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) + /// Storage: `Duster::AccountBlacklist` (r:7 w:0) + /// Proof: `Duster::AccountBlacklist` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) + /// Storage: `AssetRegistry::BannedAssets` (r:5 w:0) + /// Proof: `AssetRegistry::BannedAssets` (`max_values`: None, `max_size`: Some(20), added: 2495, mode: `MaxEncodedLen`) /// Storage: `MultiTransactionPayment::AccountCurrencyMap` (r:1 w:0) /// Proof: `MultiTransactionPayment::AccountCurrencyMap` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) - /// Storage: `MultiTransactionPayment::AcceptedCurrencies` (r:3 w:0) + /// Storage: `MultiTransactionPayment::AcceptedCurrencies` (r:5 w:0) /// Proof: `MultiTransactionPayment::AcceptedCurrencies` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`) - /// Storage: `XYK::ShareToken` (r:3 w:0) - /// Proof: `XYK::ShareToken` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) /// Storage: `EmaOracle::Accumulator` (r:1 w:0) /// Proof: `EmaOracle::Accumulator` (`max_values`: Some(1), `max_size`: Some(5921), added: 6416, mode: `MaxEncodedLen`) + /// Storage: `Tokens::TotalIssuance` (r:1 w:0) + /// Proof: `Tokens::TotalIssuance` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`) fn set_route_for_xyk() -> Weight { // Proof Size summary in bytes: - // Measured: `4201` - // Estimated: `24237` - // Minimum execution time: 1_126_027_000 picoseconds. - Weight::from_parts(1_133_155_000, 24237) - .saturating_add(RocksDbWeight::get().reads(27_u64)) + // Measured: `6326` + // Estimated: `39735` + // Minimum execution time: 2_275_922_000 picoseconds. + Weight::from_parts(2_284_697_000, 39735) + .saturating_add(RocksDbWeight::get().reads(55_u64)) + .saturating_add(RocksDbWeight::get().writes(1_u64)) + } + /// Storage: `Router::Routes` (r:0 w:1) + /// Proof: `Router::Routes` (`max_values`: None, `max_size`: Some(90), added: 2565, mode: `MaxEncodedLen`) + fn force_insert_route() -> Weight { + // Proof Size summary in bytes: + // Measured: `1012` + // Estimated: `0` + // Minimum execution time: 30_072_000 picoseconds. + Weight::from_parts(30_421_000, 0) .saturating_add(RocksDbWeight::get().writes(1_u64)) } } diff --git a/runtime/hydradx/src/assets.rs b/runtime/hydradx/src/assets.rs index 88aef10ed..9e7d9cd6f 100644 --- a/runtime/hydradx/src/assets.rs +++ b/runtime/hydradx/src/assets.rs @@ -961,6 +961,11 @@ impl AmmTradeWeights> for RouterWeightInfo { weight } + + fn force_insert_route_weight() -> Weight { + //Since we don't have any AMM specific thing in the extrinsic, we just return the plain weight + weights::route_executor::HydraWeight::::force_insert_route() + } } parameter_types! { diff --git a/runtime/hydradx/src/weights/route_executor.rs b/runtime/hydradx/src/weights/route_executor.rs index ad6a8b7b6..10f017e21 100644 --- a/runtime/hydradx/src/weights/route_executor.rs +++ b/runtime/hydradx/src/weights/route_executor.rs @@ -18,7 +18,7 @@ //! Autogenerated weights for `pallet_route_executor` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2024-03-05, STEPS: `10`, REPEAT: `30`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-03-18, STEPS: `10`, REPEAT: `30`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` //! HOSTNAME: `bench-bot`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: 1024 @@ -33,8 +33,8 @@ // --wasm-execution=compiled // --heap-pages=4096 // --template=.maintain/pallet-weight-template-no-back.hbs -// --pallet=pallet-route-executor -// --output=router.rs +// --pallet=pallet_route-executor +// --output=re2.rs // --extrinsic=* #![cfg_attr(rustfmt, rustfmt_skip)] @@ -67,10 +67,10 @@ impl pallet_route_executor::weights::WeightInfo for Hyd // Proof Size summary in bytes: // Measured: `3436` // Estimated: `13905` - // Minimum execution time: 347_725_000 picoseconds. - Weight::from_parts(351_096_698, 13905) - // Standard Error: 200_537 - .saturating_add(Weight::from_parts(50_253_676, 0).saturating_mul(c.into())) + // Minimum execution time: 344_173_000 picoseconds. + Weight::from_parts(347_378_169, 13905) + // Standard Error: 131_839 + .saturating_add(Weight::from_parts(49_213_080, 0).saturating_mul(c.into())) .saturating_add(T::DbWeight::get().reads(16)) .saturating_add(T::DbWeight::get().writes(7)) } @@ -93,79 +93,57 @@ impl pallet_route_executor::weights::WeightInfo for Hyd fn calculate_and_execute_buy_in_lbp(c: u32, b: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `1604 + b * (1837 ±0)` - // Estimated: `6156 + b * (7749 ±99_524_913_928_918_768)` - // Minimum execution time: 76_051_000 picoseconds. - Weight::from_parts(76_610_000, 6156) - // Standard Error: 604_305 - .saturating_add(Weight::from_parts(2_329_553, 0).saturating_mul(c.into())) - // Standard Error: 1_326_623 - .saturating_add(Weight::from_parts(278_434_394, 0).saturating_mul(b.into())) + // Estimated: `6156 + b * (7749 ±251_795_645_551_580_832)` + // Minimum execution time: 75_692_000 picoseconds. + Weight::from_parts(76_409_000, 6156) + // Standard Error: 611_234 + .saturating_add(Weight::from_parts(2_382_471, 0).saturating_mul(c.into())) + // Standard Error: 1_341_833 + .saturating_add(Weight::from_parts(272_805_599, 0).saturating_mul(b.into())) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().reads((13_u64).saturating_mul(b.into()))) .saturating_add(T::DbWeight::get().writes((7_u64).saturating_mul(b.into()))) .saturating_add(Weight::from_parts(0, 7749).saturating_mul(b.into())) } - /// Storage: `AssetRegistry::Assets` (r:7 w:0) + /// Storage: `AssetRegistry::Assets` (r:6 w:0) /// Proof: `AssetRegistry::Assets` (`max_values`: None, `max_size`: Some(125), added: 2600, mode: `MaxEncodedLen`) /// Storage: `Router::Routes` (r:1 w:1) /// Proof: `Router::Routes` (`max_values`: None, `max_size`: Some(90), added: 2565, mode: `MaxEncodedLen`) - /// Storage: `Omnipool::Assets` (r:2 w:0) - /// Proof: `Omnipool::Assets` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:8 w:0) + /// Storage: `System::Account` (r:7 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Tokens::Accounts` (r:16 w:0) + /// Storage: `Tokens::Accounts` (r:15 w:0) /// Proof: `Tokens::Accounts` (`max_values`: None, `max_size`: Some(108), added: 2583, mode: `MaxEncodedLen`) - /// Storage: `Omnipool::HubAssetImbalance` (r:1 w:0) - /// Proof: `Omnipool::HubAssetImbalance` (`max_values`: Some(1), `max_size`: Some(17), added: 512, mode: `MaxEncodedLen`) - /// Storage: `DynamicFees::AssetFee` (r:2 w:0) - /// Proof: `DynamicFees::AssetFee` (`max_values`: None, `max_size`: Some(24), added: 2499, mode: `MaxEncodedLen`) - /// Storage: `EmaOracle::Oracles` (r:2 w:0) - /// Proof: `EmaOracle::Oracles` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) + /// Storage: `XYK::ShareToken` (r:6 w:0) + /// Proof: `XYK::ShareToken` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) /// Storage: `Duster::AccountBlacklist` (r:7 w:0) /// Proof: `Duster::AccountBlacklist` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) /// Storage: `AssetRegistry::BannedAssets` (r:5 w:0) /// Proof: `AssetRegistry::BannedAssets` (`max_values`: None, `max_size`: Some(20), added: 2495, mode: `MaxEncodedLen`) - /// Storage: `MultiTransactionPayment::AccountCurrencyMap` (r:2 w:0) + /// Storage: `MultiTransactionPayment::AccountCurrencyMap` (r:1 w:0) /// Proof: `MultiTransactionPayment::AccountCurrencyMap` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) /// Storage: `MultiTransactionPayment::AcceptedCurrencies` (r:5 w:0) /// Proof: `MultiTransactionPayment::AcceptedCurrencies` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`) /// Storage: `EmaOracle::Accumulator` (r:1 w:0) /// Proof: `EmaOracle::Accumulator` (`max_values`: Some(1), `max_size`: Some(5921), added: 6416, mode: `MaxEncodedLen`) - /// Storage: `CircuitBreaker::AllowedTradeVolumeLimitPerAsset` (r:2 w:0) - /// Proof: `CircuitBreaker::AllowedTradeVolumeLimitPerAsset` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) - /// Storage: `CircuitBreaker::TradeVolumeLimitPerAsset` (r:2 w:0) - /// Proof: `CircuitBreaker::TradeVolumeLimitPerAsset` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`) - /// Storage: `CircuitBreaker::LiquidityAddLimitPerAsset` (r:1 w:0) - /// Proof: `CircuitBreaker::LiquidityAddLimitPerAsset` (`max_values`: None, `max_size`: Some(29), added: 2504, mode: `MaxEncodedLen`) - /// Storage: `CircuitBreaker::AllowedAddLiquidityAmountPerAsset` (r:1 w:0) - /// Proof: `CircuitBreaker::AllowedAddLiquidityAmountPerAsset` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) - /// Storage: `CircuitBreaker::LiquidityRemoveLimitPerAsset` (r:1 w:0) - /// Proof: `CircuitBreaker::LiquidityRemoveLimitPerAsset` (`max_values`: None, `max_size`: Some(29), added: 2504, mode: `MaxEncodedLen`) - /// Storage: `CircuitBreaker::AllowedRemoveLiquidityAmountPerAsset` (r:1 w:0) - /// Proof: `CircuitBreaker::AllowedRemoveLiquidityAmountPerAsset` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) - /// Storage: `Referrals::LinkedAccounts` (r:1 w:0) - /// Proof: `Referrals::LinkedAccounts` (`max_values`: None, `max_size`: Some(80), added: 2555, mode: `MaxEncodedLen`) - /// Storage: `Referrals::AssetRewards` (r:1 w:0) - /// Proof: `Referrals::AssetRewards` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) - /// Storage: `Referrals::TotalShares` (r:1 w:0) - /// Proof: `Referrals::TotalShares` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) - /// Storage: `Referrals::TraderShares` (r:1 w:0) - /// Proof: `Referrals::TraderShares` (`max_values`: None, `max_size`: Some(64), added: 2539, mode: `MaxEncodedLen`) - /// Storage: `Referrals::PendingConversions` (r:1 w:0) - /// Proof: `Referrals::PendingConversions` (`max_values`: None, `max_size`: Some(20), added: 2495, mode: `MaxEncodedLen`) - /// Storage: `Referrals::CounterForPendingConversions` (r:1 w:0) - /// Proof: `Referrals::CounterForPendingConversions` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) /// Storage: `Tokens::TotalIssuance` (r:1 w:0) /// Proof: `Tokens::TotalIssuance` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`) - /// Storage: `XYK::ShareToken` (r:5 w:0) - /// Proof: `XYK::ShareToken` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) fn set_route_for_xyk() -> Weight { // Proof Size summary in bytes: - // Measured: `7187` - // Estimated: `42318` - // Minimum execution time: 2_333_578_000 picoseconds. - Weight::from_parts(2_348_750_000, 42318) - .saturating_add(T::DbWeight::get().reads(79)) + // Measured: `6326` + // Estimated: `39735` + // Minimum execution time: 2_263_303_000 picoseconds. + Weight::from_parts(2_275_623_000, 39735) + .saturating_add(T::DbWeight::get().reads(55)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `Router::Routes` (r:0 w:1) + /// Proof: `Router::Routes` (`max_values`: None, `max_size`: Some(90), added: 2565, mode: `MaxEncodedLen`) + fn force_insert_route() -> Weight { + // Proof Size summary in bytes: + // Measured: `1012` + // Estimated: `0` + // Minimum execution time: 29_861_000 picoseconds. + Weight::from_parts(30_303_000, 0) .saturating_add(T::DbWeight::get().writes(1)) } } \ No newline at end of file diff --git a/traits/src/router.rs b/traits/src/router.rs index caa66cc57..defc39b4a 100644 --- a/traits/src/router.rs +++ b/traits/src/router.rs @@ -282,6 +282,7 @@ pub trait AmmTradeWeights { fn sell_and_calculate_sell_trade_amounts_weight(route: &[Trade]) -> Weight; fn buy_and_calculate_buy_trade_amounts_weight(route: &[Trade]) -> Weight; fn set_route_weight(route: &[Trade]) -> Weight; + fn force_insert_route_weight() -> Weight; } impl AmmTradeWeights for () { @@ -303,4 +304,7 @@ impl AmmTradeWeights for () { fn set_route_weight(_route: &[Trade]) -> Weight { Weight::zero() } + fn force_insert_route_weight() -> Weight { + Weight::zero() + } } From bee75f38c98a827264691b3ac63c94df16e23ab9 Mon Sep 17 00:00:00 2001 From: dmoka Date: Mon, 18 Mar 2024 14:32:26 +0100 Subject: [PATCH 21/21] make clippy happy --- runtime/hydradx/src/benchmarking/route_executor.rs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/runtime/hydradx/src/benchmarking/route_executor.rs b/runtime/hydradx/src/benchmarking/route_executor.rs index 6cb3bac5b..f52a37884 100644 --- a/runtime/hydradx/src/benchmarking/route_executor.rs +++ b/runtime/hydradx/src/benchmarking/route_executor.rs @@ -17,13 +17,11 @@ #![allow(clippy::result_large_err)] use crate::{ - AccountId, AssetId, Balance, Currencies, InsufficientEDinHDX, Omnipool, Router, Runtime, RuntimeOrigin, System, - LBP, XYK, + AccountId, AssetId, Balance, Currencies, InsufficientEDinHDX, Router, Runtime, RuntimeOrigin, System, LBP, XYK, }; use super::*; use crate::benchmarking::dca::HDX; -use crate::benchmarking::tokens::update_balance; use frame_benchmarking::{account, BenchmarkError}; use frame_support::dispatch::DispatchResult; use frame_support::{assert_ok, ensure}; @@ -34,8 +32,6 @@ use hydradx_traits::router::{PoolType, RouterT, Trade}; use orml_benchmarking::runtime_benchmarks; use orml_traits::{MultiCurrency, MultiCurrencyExtended}; use primitives::constants::currency::UNITS; -use sp_runtime::FixedU128; -use sp_runtime::Permill; use sp_std::vec; pub const INITIAL_BALANCE: Balance = 10_000_000 * UNITS; @@ -262,7 +258,7 @@ runtime_benchmarks! { Router::set_route( RawOrigin::Signed(caller.clone()).into(), AssetPair::new(HDX, asset_6), - route.clone(), + route, )?; let better_route = vec![Trade {