From ebea589a762f796dda57a904a6cd5f6719e9182b Mon Sep 17 00:00:00 2001 From: Roy Yang Date: Fri, 22 Oct 2021 18:14:17 +1300 Subject: [PATCH 01/13] Added a new extrinsic that adjusts the available_staking_balance Automatically process queued redeem request after the adjustment happened. --- modules/homa-lite/src/benchmarking.rs | 9 ++ modules/homa-lite/src/lib.rs | 88 +++++++++++++++---- modules/homa-lite/src/tests.rs | 73 +++++++++------ modules/homa-lite/src/weights.rs | 11 +++ runtime/acala/src/weights/module_homa_lite.rs | 5 ++ .../karura/src/weights/module_homa_lite.rs | 5 ++ .../mandala/src/weights/module_homa_lite.rs | 5 ++ 7 files changed, 156 insertions(+), 40 deletions(-) diff --git a/modules/homa-lite/src/benchmarking.rs b/modules/homa-lite/src/benchmarking.rs index 3bb41fbcc..937540d7a 100644 --- a/modules/homa-lite/src/benchmarking.rs +++ b/modules/homa-lite/src/benchmarking.rs @@ -75,6 +75,8 @@ benchmarks! { adjust_total_staking_currency {}: _(RawOrigin::Root, AmountOf::::default()) + adjust_available_staking_balance {}: _(RawOrigin::Root, AmountOf::::default()) + set_minting_cap { }: _(RawOrigin::Root, 1_000_000_000_000_000_000) @@ -129,6 +131,13 @@ mod tests { assert_ok!(Pallet::::test_benchmark_adjust_total_staking_currency()); }); } + #[test] + fn test_adjust_available_staking_balance() { + ExtBuilder::default().build().execute_with(|| { + assert_ok!(Pallet::::test_benchmark_adjust_available_staking_balance()); + }); + } + #[test] fn test_set_minting_cap() { ExtBuilder::default().build().execute_with(|| { diff --git a/modules/homa-lite/src/lib.rs b/modules/homa-lite/src/lib.rs index 285cfa59b..bfe1dc74f 100644 --- a/modules/homa-lite/src/lib.rs +++ b/modules/homa-lite/src/lib.rs @@ -199,6 +199,10 @@ pub mod module { /// The scheduled Unbond has been withdrew from the RelayChain. ///\[staking_amount_added\] ScheduledUnbondWithdrew(Balance), + + /// The amount of the staking currency available to be redeemed is set. + /// \[total_available_staking_balance\] + AvailableStakingBalanceSet(Balance), } /// The total amount of the staking currency on the relaychain. @@ -318,7 +322,6 @@ pub mod module { #[transactional] pub fn adjust_total_staking_currency(origin: OriginFor, by_amount: AmountOf) -> DispatchResult { T::GovernanceOrigin::ensure_origin(origin)?; - let mut current_staking_total = Self::total_staking_currency(); // Convert AmountOf into Balance safely. let by_amount_abs = if by_amount == AmountOf::::min_value() { @@ -330,18 +333,19 @@ pub mod module { let by_balance = TryInto::::try_into(by_amount_abs).map_err(|_| ArithmeticError::Overflow)?; // Adjust the current total. - if by_amount.is_positive() { - current_staking_total = current_staking_total - .checked_add(by_balance) - .ok_or(ArithmeticError::Overflow)?; + let new_total = if by_amount.is_positive() { + TotalStakingCurrency::::mutate(|current| { + *current = current.saturating_add(by_balance); + current.clone() + }) } else { - current_staking_total = current_staking_total - .checked_sub(by_balance) - .ok_or(ArithmeticError::Underflow)?; - } + TotalStakingCurrency::::mutate(|current| { + *current = current.saturating_sub(by_balance); + current.clone() + }) + }; - TotalStakingCurrency::::put(current_staking_total); - Self::deposit_event(Event::::TotalStakingCurrencySet(current_staking_total)); + Self::deposit_event(Event::::TotalStakingCurrencySet(new_total)); Ok(()) } @@ -545,6 +549,46 @@ pub mod module { Ok(()) } + + /// Adjusts the AvailableStakingBalance by the given difference. + /// Also attempt to process queued redeem request with the new Staking Balance. + /// Requires `T::GovernanceOrigin` + /// + /// Parameters: + /// - `adjustment`: The difference in amount the AvailableStakingBalance should be adjusted + /// by. + #[pallet::weight(< T as Config >::WeightInfo::adjust_available_staking_balance())] + #[transactional] + pub fn adjust_available_staking_balance(origin: OriginFor, by_amount: AmountOf) -> DispatchResult { + T::GovernanceOrigin::ensure_origin(origin)?; + + // Convert AmountOf into Balance safely. + let by_amount_abs = if by_amount == AmountOf::::min_value() { + AmountOf::::max_value() + } else { + by_amount.abs() + }; + + let by_balance = TryInto::::try_into(by_amount_abs).map_err(|_| ArithmeticError::Overflow)?; + + // Adjust the current total. + let new_amount = if by_amount.is_positive() { + AvailableStakingBalance::::mutate(|current| { + *current = current.saturating_add(by_balance); + current.clone() + }) + } else { + AvailableStakingBalance::::mutate(|current| { + *current = current.saturating_sub(by_balance); + current.clone() + }) + }; + + Self::deposit_event(Event::::AvailableStakingBalanceSet(new_amount)); + + // With new staking balance available, process pending redeem requests. + Self::process_redeem_requests_with_available_staking_balance() + } } impl Pallet { @@ -768,6 +812,9 @@ pub mod module { Ok(()) } + /// Construct XCM message and sent it to the relaychain to withdraw_unbonded Staking + /// currency. The staking currency withdrew becomes available to be redeemed. Process + /// through redeem requests to fullfill the redeem order. #[transactional] fn process_scheduled_unbond(staking_amount: Balance) -> DispatchResult { let msg = Self::construct_xcm_unreserve_message(T::ParachainAccount::get(), staking_amount); @@ -776,12 +823,24 @@ pub mod module { log::debug!("on_idle XCM result: {:?}", res); ensure!(res.is_ok(), Error::::XcmFailed); + // Update storage with the new available amount + AvailableStakingBalance::::mutate(|current| { + *current = current.saturating_add(staking_amount); + }); + + Self::deposit_event(Event::::ScheduledUnbondWithdrew(staking_amount)); + // Now that there's available staking balance, automatically match existing // redeem_requests. + Self::process_redeem_requests_with_available_staking_balance() + } + + /// Iterate through all redeem requests, then match them with available_staking_balance. + /// This should be call when new available_staking_balance becomes available. + #[transactional] + fn process_redeem_requests_with_available_staking_balance() -> DispatchResult { let mut new_balances: Vec<(T::AccountId, Balance, Permill)> = vec![]; - let mut available_staking_balance = Self::available_staking_balance() - .checked_add(staking_amount) - .ok_or(ArithmeticError::Overflow)?; + let mut available_staking_balance = Self::available_staking_balance(); for (redeemer, (request_amount, extra_fee)) in RedeemRequests::::iter() { // If all the currencies are minted, return. if available_staking_balance.is_zero() { @@ -818,7 +877,6 @@ pub mod module { Self::update_redeem_requests(&new_balances); AvailableStakingBalance::::put(available_staking_balance); - Self::deposit_event(Event::::ScheduledUnbondWithdrew(staking_amount)); Ok(()) } diff --git a/modules/homa-lite/src/tests.rs b/modules/homa-lite/src/tests.rs index d0033a8de..4d77933f3 100644 --- a/modules/homa-lite/src/tests.rs +++ b/modules/homa-lite/src/tests.rs @@ -214,23 +214,51 @@ fn can_adjust_total_staking_currency() { assert_eq!(HomaLite::total_staking_currency(), 5001); System::assert_last_event(Event::HomaLite(crate::Event::TotalStakingCurrencySet(5001))); - // Underflow / overflow causes error - assert_noop!( - HomaLite::adjust_total_staking_currency(Origin::root(), -5002), - ArithmeticError::Underflow - ); - - assert_eq!(HomaLite::total_staking_currency(), 5001); + // Underflow / overflow can be handled + assert_ok!(HomaLite::adjust_total_staking_currency(Origin::root(), -5002)); + assert_eq!(HomaLite::total_staking_currency(), 0); assert_ok!(HomaLite::set_total_staking_currency( Origin::root(), Balance::max_value() )); + assert_ok!(HomaLite::adjust_total_staking_currency(Origin::root(), 1)); + assert_eq!(HomaLite::total_staking_currency(), Balance::max_value()); + }); +} + +#[test] +fn can_adjust_available_staking_balance() { + ExtBuilder::default().build().execute_with(|| { assert_noop!( - HomaLite::adjust_total_staking_currency(Origin::root(), 1), - ArithmeticError::Overflow + HomaLite::adjust_available_staking_balance(Origin::signed(ALICE), 5000), + BadOrigin ); + + // Can adjust total_staking_currency with ROOT. + assert_ok!(HomaLite::adjust_available_staking_balance(Origin::root(), 5001)); + + assert_eq!(HomaLite::available_staking_balance(), 5001); + System::assert_last_event(Event::HomaLite(crate::Event::AvailableStakingBalanceSet(5001))); + + // Underflow / overflow can be handled due to the use of saturating arithmetic + assert_ok!(HomaLite::adjust_available_staking_balance(Origin::root(), -5002)); + assert_eq!(HomaLite::available_staking_balance(), 0); + + assert_ok!(HomaLite::adjust_available_staking_balance( + Origin::root(), + i128::max_value() + )); + assert_ok!(HomaLite::adjust_available_staking_balance( + Origin::root(), + i128::max_value() + )); + assert_ok!(HomaLite::adjust_available_staking_balance( + Origin::root(), + i128::max_value() + )); + assert_eq!(HomaLite::available_staking_balance(), Balance::max_value()); }); } @@ -411,13 +439,12 @@ fn new_available_staking_currency_can_handle_redeem_requests() { Some((dollar(1_000), Permill::zero())) ); - // Add more staking currency to fully satify the last redeem request - assert_ok!(HomaLite::replace_schedule_unbond( + // Add more staking currency by adjust_available_staking_balance also + // automatically fullfill pending redeem request. + assert_ok!(HomaLite::adjust_available_staking_balance( Origin::root(), - vec![(dollar(150), 2)], + 150_000_000_000_000 )); - MockRelayBlockNumberProvider::set(2); - HomaLite::on_idle(MockRelayBlockNumberProvider::get(), 5_000_000_000); // The last request is redeemed, the leftover is stored. assert_eq!(AvailableStakingBalance::::get(), dollar(50)); @@ -467,12 +494,11 @@ fn on_idle_can_handle_changes_in_exchange_rate() { #[test] fn request_redeem_works() { ExtBuilder::default().build().execute_with(|| { - assert_ok!(HomaLite::replace_schedule_unbond( + assert_ok!(HomaLite::adjust_available_staking_balance( Origin::root(), - vec![(dollar(50_000), 1)], + 50_000_000_000_000_000 )); - MockRelayBlockNumberProvider::set(1); - HomaLite::on_idle(MockRelayBlockNumberProvider::get(), 5_000_000_000); + assert_eq!(AvailableStakingBalance::::get(), dollar(50_000)); // Redeem amount has to be above a threshold. @@ -530,12 +556,11 @@ fn request_redeem_works() { #[test] fn request_redeem_can_handle_dust_redeem_requests() { ExtBuilder::default().build().execute_with(|| { - assert_ok!(HomaLite::replace_schedule_unbond( + assert_ok!(HomaLite::adjust_available_staking_balance( Origin::root(), - vec![(dollar(50_000), 1)], + 50_000_000_000_000_000 )); - MockRelayBlockNumberProvider::set(1); - HomaLite::on_idle(MockRelayBlockNumberProvider::get(), 5_000_000_000); + assert_eq!(AvailableStakingBalance::::get(), dollar(50_000)); // Remaining `dollar(1)` is below the xcm_unbond_fee, therefore returned and requests filled. @@ -805,9 +830,7 @@ fn redeem_can_handle_dust_available_staking_currency() { ExtBuilder::default().build().execute_with(|| { // If AvailableStakingBalance is not enough to pay for the unbonding fee, ignore it. // pub XcmUnbondFee: Balance = dollar(1); - assert_ok!(HomaLite::schedule_unbond(Origin::root(), 999_000_000, 0)); - MockRelayBlockNumberProvider::set(0); - HomaLite::on_idle(MockRelayBlockNumberProvider::get(), 5_000_000_000); + assert_ok!(HomaLite::adjust_available_staking_balance(Origin::root(), 999_000_000)); assert_eq!(AvailableStakingBalance::::get(), 999_000_000); diff --git a/modules/homa-lite/src/weights.rs b/modules/homa-lite/src/weights.rs index 2ded7545d..d6a0cb03f 100644 --- a/modules/homa-lite/src/weights.rs +++ b/modules/homa-lite/src/weights.rs @@ -52,6 +52,7 @@ pub trait WeightInfo { fn mint_for_requests() -> Weight; fn set_total_staking_currency() -> Weight; fn adjust_total_staking_currency() -> Weight; + fn adjust_available_staking_balance() -> Weight; fn set_minting_cap() -> Weight; fn set_xcm_dest_weight() -> Weight; fn request_redeem() -> Weight; @@ -86,6 +87,11 @@ impl WeightInfo for AcalaWeight { .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } + fn adjust_available_staking_balance() -> Weight { + (12_000_000 as Weight) + .saturating_add(T::DbWeight::get().reads(1 as Weight)) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) + } fn set_minting_cap() -> Weight { (10_000_000 as Weight) .saturating_add(T::DbWeight::get().writes(1 as Weight)) @@ -136,6 +142,11 @@ impl WeightInfo for () { .saturating_add(RocksDbWeight::get().reads(1 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } + fn adjust_available_staking_balance() -> Weight { + (12_000_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(1 as Weight)) + .saturating_add(RocksDbWeight::get().writes(1 as Weight)) + } fn set_minting_cap() -> Weight { (10_000_000 as Weight) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) diff --git a/runtime/acala/src/weights/module_homa_lite.rs b/runtime/acala/src/weights/module_homa_lite.rs index abd23f1f5..c988eb37a 100644 --- a/runtime/acala/src/weights/module_homa_lite.rs +++ b/runtime/acala/src/weights/module_homa_lite.rs @@ -71,6 +71,11 @@ impl module_homa_lite::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } + fn adjust_available_staking_balance() -> Weight { + (21_634_000 as Weight) + .saturating_add(T::DbWeight::get().reads(1 as Weight)) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) + } fn set_minting_cap() -> Weight { (19_501_000 as Weight) .saturating_add(T::DbWeight::get().writes(1 as Weight)) diff --git a/runtime/karura/src/weights/module_homa_lite.rs b/runtime/karura/src/weights/module_homa_lite.rs index abd23f1f5..c988eb37a 100644 --- a/runtime/karura/src/weights/module_homa_lite.rs +++ b/runtime/karura/src/weights/module_homa_lite.rs @@ -71,6 +71,11 @@ impl module_homa_lite::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } + fn adjust_available_staking_balance() -> Weight { + (21_634_000 as Weight) + .saturating_add(T::DbWeight::get().reads(1 as Weight)) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) + } fn set_minting_cap() -> Weight { (19_501_000 as Weight) .saturating_add(T::DbWeight::get().writes(1 as Weight)) diff --git a/runtime/mandala/src/weights/module_homa_lite.rs b/runtime/mandala/src/weights/module_homa_lite.rs index db4bcf179..3187b0f50 100644 --- a/runtime/mandala/src/weights/module_homa_lite.rs +++ b/runtime/mandala/src/weights/module_homa_lite.rs @@ -69,6 +69,11 @@ impl module_homa_lite::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } + fn adjust_available_staking_balance() -> Weight { + (12_000_000 as Weight) + .saturating_add(T::DbWeight::get().reads(1 as Weight)) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) + } fn set_minting_cap() -> Weight { (11_000_000 as Weight) .saturating_add(T::DbWeight::get().writes(1 as Weight)) From a1ec55d4808d250df765fef32432080d83188d3d Mon Sep 17 00:00:00 2001 From: Roy Yang Date: Fri, 22 Oct 2021 18:56:31 +1300 Subject: [PATCH 02/13] re-benchmarked the homa-lite module --- modules/homa-lite/src/weights.rs | 42 +++++++++---------- runtime/acala/src/weights/module_homa_lite.rs | 42 +++++++++---------- .../karura/src/weights/module_homa_lite.rs | 28 ++++++------- .../mandala/src/weights/module_homa_lite.rs | 20 +++++---- 4 files changed, 65 insertions(+), 67 deletions(-) diff --git a/modules/homa-lite/src/weights.rs b/modules/homa-lite/src/weights.rs index d6a0cb03f..22ba6e8d1 100644 --- a/modules/homa-lite/src/weights.rs +++ b/modules/homa-lite/src/weights.rs @@ -19,7 +19,7 @@ //! Autogenerated weights for module_homa_lite //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2021-10-03, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2021-10-22, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` //! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 128 // Executed Command: @@ -64,22 +64,20 @@ pub trait WeightInfo { pub struct AcalaWeight(PhantomData); impl WeightInfo for AcalaWeight { fn on_idle() -> Weight { - (34_000_000 as Weight) - .saturating_add(T::DbWeight::get().reads(8 as Weight)) - .saturating_add(T::DbWeight::get().writes(3 as Weight)) + (0 as Weight) } fn mint() -> Weight { - (128_000_000 as Weight) + (136_000_000 as Weight) .saturating_add(T::DbWeight::get().reads(14 as Weight)) .saturating_add(T::DbWeight::get().writes(7 as Weight)) } fn mint_for_requests() -> Weight { - (338_000_000 as Weight) + (345_000_000 as Weight) .saturating_add(T::DbWeight::get().reads(30 as Weight)) .saturating_add(T::DbWeight::get().writes(21 as Weight)) } fn set_total_staking_currency() -> Weight { - (10_000_000 as Weight) + (11_000_000 as Weight) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn adjust_total_staking_currency() -> Weight { @@ -88,12 +86,12 @@ impl WeightInfo for AcalaWeight { .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn adjust_available_staking_balance() -> Weight { - (12_000_000 as Weight) - .saturating_add(T::DbWeight::get().reads(1 as Weight)) + (17_000_000 as Weight) + .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn set_minting_cap() -> Weight { - (10_000_000 as Weight) + (11_000_000 as Weight) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn set_xcm_dest_weight() -> Weight { @@ -106,12 +104,12 @@ impl WeightInfo for AcalaWeight { .saturating_add(T::DbWeight::get().writes(3 as Weight)) } fn schedule_unbond() -> Weight { - (12_000_000 as Weight) + (13_000_000 as Weight) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn replace_schedule_unbond() -> Weight { - (10_000_000 as Weight) + (11_000_000 as Weight) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } } @@ -119,22 +117,20 @@ impl WeightInfo for AcalaWeight { // For backwards compatibility and tests impl WeightInfo for () { fn on_idle() -> Weight { - (34_000_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(8 as Weight)) - .saturating_add(RocksDbWeight::get().writes(3 as Weight)) + (0 as Weight) } fn mint() -> Weight { - (128_000_000 as Weight) + (136_000_000 as Weight) .saturating_add(RocksDbWeight::get().reads(14 as Weight)) .saturating_add(RocksDbWeight::get().writes(7 as Weight)) } fn mint_for_requests() -> Weight { - (338_000_000 as Weight) + (345_000_000 as Weight) .saturating_add(RocksDbWeight::get().reads(30 as Weight)) .saturating_add(RocksDbWeight::get().writes(21 as Weight)) } fn set_total_staking_currency() -> Weight { - (10_000_000 as Weight) + (11_000_000 as Weight) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn adjust_total_staking_currency() -> Weight { @@ -143,12 +139,12 @@ impl WeightInfo for () { .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn adjust_available_staking_balance() -> Weight { - (12_000_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(1 as Weight)) + (17_000_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(2 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn set_minting_cap() -> Weight { - (10_000_000 as Weight) + (11_000_000 as Weight) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn set_xcm_dest_weight() -> Weight { @@ -161,12 +157,12 @@ impl WeightInfo for () { .saturating_add(RocksDbWeight::get().writes(3 as Weight)) } fn schedule_unbond() -> Weight { - (12_000_000 as Weight) + (13_000_000 as Weight) .saturating_add(RocksDbWeight::get().reads(1 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn replace_schedule_unbond() -> Weight { - (10_000_000 as Weight) + (11_000_000 as Weight) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } } diff --git a/runtime/acala/src/weights/module_homa_lite.rs b/runtime/acala/src/weights/module_homa_lite.rs index c988eb37a..5b9156f8a 100644 --- a/runtime/acala/src/weights/module_homa_lite.rs +++ b/runtime/acala/src/weights/module_homa_lite.rs @@ -19,22 +19,22 @@ //! Autogenerated weights for module_homa_lite //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2021-10-04, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("karura-dev"), DB CACHE: 128 +//! DATE: 2021-10-22, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("acala-dev"), DB CACHE: 128 // Executed Command: // target/release/acala // benchmark -// --chain=karura-dev +// --chain=acala-dev // --steps=50 // --repeat=20 -// --pallet=module_homa_lite +// --pallet=module-homa-lite // --extrinsic=* // --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 // --template=./templates/runtime-weight-template.hbs -// --output=./runtime/karura/src/weights/ +// --output=./runtime/acala/src/weights/ #![cfg_attr(rustfmt, rustfmt_skip)] @@ -48,54 +48,54 @@ use sp_std::marker::PhantomData; pub struct WeightInfo(PhantomData); impl module_homa_lite::WeightInfo for WeightInfo { fn on_idle() -> Weight { - (63_233_000 as Weight) - .saturating_add(T::DbWeight::get().reads(8 as Weight)) - .saturating_add(T::DbWeight::get().writes(3 as Weight)) + (254_000_000 as Weight) + .saturating_add(T::DbWeight::get().reads(23 as Weight)) + .saturating_add(T::DbWeight::get().writes(17 as Weight)) } fn mint() -> Weight { - (238_339_000 as Weight) + (134_000_000 as Weight) .saturating_add(T::DbWeight::get().reads(14 as Weight)) .saturating_add(T::DbWeight::get().writes(7 as Weight)) } fn mint_for_requests() -> Weight { - (254_671_000 as Weight) - .saturating_add(T::DbWeight::get().reads(16 as Weight)) - .saturating_add(T::DbWeight::get().writes(7 as Weight)) + (342_000_000 as Weight) + .saturating_add(T::DbWeight::get().reads(30 as Weight)) + .saturating_add(T::DbWeight::get().writes(21 as Weight)) } fn set_total_staking_currency() -> Weight { - (18_892_000 as Weight) + (10_000_000 as Weight) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn adjust_total_staking_currency() -> Weight { - (21_634_000 as Weight) + (12_000_000 as Weight) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn adjust_available_staking_balance() -> Weight { - (21_634_000 as Weight) - .saturating_add(T::DbWeight::get().reads(1 as Weight)) + (17_000_000 as Weight) + .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn set_minting_cap() -> Weight { - (19_501_000 as Weight) + (10_000_000 as Weight) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn set_xcm_dest_weight() -> Weight { - (18_739_000 as Weight) + (10_000_000 as Weight) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn request_redeem() -> Weight { - (136_967_000 as Weight) + (74_000_000 as Weight) .saturating_add(T::DbWeight::get().reads(7 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } fn schedule_unbond() -> Weight { - (21_197_000 as Weight) + (13_000_000 as Weight) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn replace_schedule_unbond() -> Weight { - (19_289_000 as Weight) + (11_000_000 as Weight) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } } diff --git a/runtime/karura/src/weights/module_homa_lite.rs b/runtime/karura/src/weights/module_homa_lite.rs index c988eb37a..cd57c360d 100644 --- a/runtime/karura/src/weights/module_homa_lite.rs +++ b/runtime/karura/src/weights/module_homa_lite.rs @@ -19,7 +19,7 @@ //! Autogenerated weights for module_homa_lite //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2021-10-04, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2021-10-22, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` //! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("karura-dev"), DB CACHE: 128 // Executed Command: @@ -28,7 +28,7 @@ // --chain=karura-dev // --steps=50 // --repeat=20 -// --pallet=module_homa_lite +// --pallet=module-homa-lite // --extrinsic=* // --execution=wasm // --wasm-execution=compiled @@ -48,54 +48,54 @@ use sp_std::marker::PhantomData; pub struct WeightInfo(PhantomData); impl module_homa_lite::WeightInfo for WeightInfo { fn on_idle() -> Weight { - (63_233_000 as Weight) + (35_000_000 as Weight) .saturating_add(T::DbWeight::get().reads(8 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } fn mint() -> Weight { - (238_339_000 as Weight) + (134_000_000 as Weight) .saturating_add(T::DbWeight::get().reads(14 as Weight)) .saturating_add(T::DbWeight::get().writes(7 as Weight)) } fn mint_for_requests() -> Weight { - (254_671_000 as Weight) + (143_000_000 as Weight) .saturating_add(T::DbWeight::get().reads(16 as Weight)) .saturating_add(T::DbWeight::get().writes(7 as Weight)) } fn set_total_staking_currency() -> Weight { - (18_892_000 as Weight) + (11_000_000 as Weight) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn adjust_total_staking_currency() -> Weight { - (21_634_000 as Weight) + (12_000_000 as Weight) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn adjust_available_staking_balance() -> Weight { - (21_634_000 as Weight) - .saturating_add(T::DbWeight::get().reads(1 as Weight)) + (17_000_000 as Weight) + .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn set_minting_cap() -> Weight { - (19_501_000 as Weight) + (11_000_000 as Weight) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn set_xcm_dest_weight() -> Weight { - (18_739_000 as Weight) + (10_000_000 as Weight) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn request_redeem() -> Weight { - (136_967_000 as Weight) + (74_000_000 as Weight) .saturating_add(T::DbWeight::get().reads(7 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } fn schedule_unbond() -> Weight { - (21_197_000 as Weight) + (13_000_000 as Weight) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn replace_schedule_unbond() -> Weight { - (19_289_000 as Weight) + (11_000_000 as Weight) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } } diff --git a/runtime/mandala/src/weights/module_homa_lite.rs b/runtime/mandala/src/weights/module_homa_lite.rs index 3187b0f50..25221c932 100644 --- a/runtime/mandala/src/weights/module_homa_lite.rs +++ b/runtime/mandala/src/weights/module_homa_lite.rs @@ -19,7 +19,7 @@ //! Autogenerated weights for module_homa_lite //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2021-10-03, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2021-10-22, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` //! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 128 // Executed Command: @@ -48,15 +48,17 @@ use sp_std::marker::PhantomData; pub struct WeightInfo(PhantomData); impl module_homa_lite::WeightInfo for WeightInfo { fn on_idle() -> Weight { - (0 as Weight) + (258_000_000 as Weight) + .saturating_add(T::DbWeight::get().reads(23 as Weight)) + .saturating_add(T::DbWeight::get().writes(17 as Weight)) } fn mint() -> Weight { - (131_000_000 as Weight) + (137_000_000 as Weight) .saturating_add(T::DbWeight::get().reads(14 as Weight)) .saturating_add(T::DbWeight::get().writes(7 as Weight)) } fn mint_for_requests() -> Weight { - (339_000_000 as Weight) + (345_000_000 as Weight) .saturating_add(T::DbWeight::get().reads(30 as Weight)) .saturating_add(T::DbWeight::get().writes(21 as Weight)) } @@ -65,13 +67,13 @@ impl module_homa_lite::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn adjust_total_staking_currency() -> Weight { - (12_000_000 as Weight) + (13_000_000 as Weight) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn adjust_available_staking_balance() -> Weight { - (12_000_000 as Weight) - .saturating_add(T::DbWeight::get().reads(1 as Weight)) + (18_000_000 as Weight) + .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn set_minting_cap() -> Weight { @@ -83,12 +85,12 @@ impl module_homa_lite::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn request_redeem() -> Weight { - (76_000_000 as Weight) + (77_000_000 as Weight) .saturating_add(T::DbWeight::get().reads(7 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } fn schedule_unbond() -> Weight { - (12_000_000 as Weight) + (14_000_000 as Weight) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } From 9fd833e704840e5b10bd7f60af822cfba2565d07 Mon Sep 17 00:00:00 2001 From: Roy Yang Date: Tue, 26 Oct 2021 12:12:45 +1300 Subject: [PATCH 03/13] Made minor adjustment to comments --- modules/homa-lite/src/lib.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/modules/homa-lite/src/lib.rs b/modules/homa-lite/src/lib.rs index bfe1dc74f..d38c67dff 100644 --- a/modules/homa-lite/src/lib.rs +++ b/modules/homa-lite/src/lib.rs @@ -816,8 +816,8 @@ pub mod module { /// currency. The staking currency withdrew becomes available to be redeemed. Process /// through redeem requests to fullfill the redeem order. #[transactional] - fn process_scheduled_unbond(staking_amount: Balance) -> DispatchResult { - let msg = Self::construct_xcm_unreserve_message(T::ParachainAccount::get(), staking_amount); + fn process_scheduled_unbond(staking_amount_unbonded: Balance) -> DispatchResult { + let msg = Self::construct_xcm_unreserve_message(T::ParachainAccount::get(), staking_amount_unbonded); let res = pallet_xcm::Pallet::::send_xcm(Here, Parent, msg); log::debug!("on_idle XCM result: {:?}", res); @@ -825,10 +825,10 @@ pub mod module { // Update storage with the new available amount AvailableStakingBalance::::mutate(|current| { - *current = current.saturating_add(staking_amount); + *current = current.saturating_add(staking_amount_unbonded); }); - Self::deposit_event(Event::::ScheduledUnbondWithdrew(staking_amount)); + Self::deposit_event(Event::::ScheduledUnbondWithdrew(staking_amount_unbonded)); // Now that there's available staking balance, automatically match existing // redeem_requests. @@ -836,7 +836,7 @@ pub mod module { } /// Iterate through all redeem requests, then match them with available_staking_balance. - /// This should be call when new available_staking_balance becomes available. + /// This should be called when new available_staking_balance becomes available. #[transactional] fn process_redeem_requests_with_available_staking_balance() -> DispatchResult { let mut new_balances: Vec<(T::AccountId, Balance, Permill)> = vec![]; @@ -880,10 +880,10 @@ pub mod module { Ok(()) } - + /// Update the RedeemRequests storage with the new balances. + /// Remove Redeem requests that are dust, or have been filled. #[allow(clippy::ptr_arg)] fn update_redeem_requests(new_balances: &Vec<(T::AccountId, Balance, Permill)>) { - // Update storage with the new balances. Remove Redeem requests that have been filled. for (redeemer, new_balance, extra_fee) in new_balances { if Self::liquid_amount_is_above_minimum_threshold(*new_balance) { RedeemRequests::::insert(&redeemer, (*new_balance, *extra_fee)); From f8b18d36a93464a06775d5fb1e4cb9e77284a2ff Mon Sep 17 00:00:00 2001 From: Roy Yang Date: Tue, 26 Oct 2021 14:20:54 +1300 Subject: [PATCH 04/13] Fixed a clippy error --- modules/homa-lite/src/lib.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/homa-lite/src/lib.rs b/modules/homa-lite/src/lib.rs index d38c67dff..4aadd089a 100644 --- a/modules/homa-lite/src/lib.rs +++ b/modules/homa-lite/src/lib.rs @@ -336,12 +336,12 @@ pub mod module { let new_total = if by_amount.is_positive() { TotalStakingCurrency::::mutate(|current| { *current = current.saturating_add(by_balance); - current.clone() + *current }) } else { TotalStakingCurrency::::mutate(|current| { *current = current.saturating_sub(by_balance); - current.clone() + *current }) }; @@ -575,12 +575,12 @@ pub mod module { let new_amount = if by_amount.is_positive() { AvailableStakingBalance::::mutate(|current| { *current = current.saturating_add(by_balance); - current.clone() + *current }) } else { AvailableStakingBalance::::mutate(|current| { *current = current.saturating_sub(by_balance); - current.clone() + *current }) }; From 634d6fb5e549b71608f2b0170160a42fe7fb5a6b Mon Sep 17 00:00:00 2001 From: Roy Yang Date: Wed, 27 Oct 2021 18:25:54 +1300 Subject: [PATCH 05/13] Addressed an PR comment Prevented TotalStakingCurrency from becoming zero --- modules/homa-lite/src/lib.rs | 40 +++++++++++++++------------------- modules/homa-lite/src/tests.rs | 17 ++++++++++----- 2 files changed, 30 insertions(+), 27 deletions(-) diff --git a/modules/homa-lite/src/lib.rs b/modules/homa-lite/src/lib.rs index ac454fc74..9542cfe7b 100644 --- a/modules/homa-lite/src/lib.rs +++ b/modules/homa-lite/src/lib.rs @@ -332,20 +332,21 @@ pub mod module { let by_balance = TryInto::::try_into(by_amount_abs).map_err(|_| ArithmeticError::Overflow)?; + // ensure TotalStakingCurrency doesn't become 0 + ensure!( + by_amount.is_positive() || by_balance < Self::total_staking_currency(), + Error::::InvalidTotalStakingCurrency + ); + // Adjust the current total. - let new_total = if by_amount.is_positive() { - TotalStakingCurrency::::mutate(|current| { + TotalStakingCurrency::::mutate(|current| { + if by_amount.is_positive() { *current = current.saturating_add(by_balance); - *current - }) - } else { - TotalStakingCurrency::::mutate(|current| { + } else { *current = current.saturating_sub(by_balance); - *current - }) - }; - - Self::deposit_event(Event::::TotalStakingCurrencySet(new_total)); + } + Self::deposit_event(Event::::TotalStakingCurrencySet(*current)); + }); Ok(()) } @@ -594,19 +595,14 @@ pub mod module { let by_balance = TryInto::::try_into(by_amount_abs).map_err(|_| ArithmeticError::Overflow)?; // Adjust the current total. - let new_amount = if by_amount.is_positive() { - AvailableStakingBalance::::mutate(|current| { + AvailableStakingBalance::::mutate(|current| { + if by_amount.is_positive() { *current = current.saturating_add(by_balance); - *current - }) - } else { - AvailableStakingBalance::::mutate(|current| { + } else { *current = current.saturating_sub(by_balance); - *current - }) - }; - - Self::deposit_event(Event::::AvailableStakingBalanceSet(new_amount)); + } + Self::deposit_event(Event::::AvailableStakingBalanceSet(*current)); + }); // With new staking balance available, process pending redeem requests. Self::process_redeem_requests_with_available_staking_balance() diff --git a/modules/homa-lite/src/tests.rs b/modules/homa-lite/src/tests.rs index 5c89c96ee..1baef5b9e 100644 --- a/modules/homa-lite/src/tests.rs +++ b/modules/homa-lite/src/tests.rs @@ -206,14 +206,10 @@ fn can_adjust_total_staking_currency() { // Can adjust total_staking_currency with ROOT. assert_ok!(HomaLite::adjust_total_staking_currency(Origin::root(), 5000)); - assert_eq!(HomaLite::total_staking_currency(), 5001); System::assert_last_event(Event::HomaLite(crate::Event::TotalStakingCurrencySet(5001))); - // Underflow / overflow can be handled - assert_ok!(HomaLite::adjust_total_staking_currency(Origin::root(), -5002)); - assert_eq!(HomaLite::total_staking_currency(), 0); - + // overflow can be handled assert_ok!(HomaLite::set_total_staking_currency( Origin::root(), Balance::max_value() @@ -221,6 +217,17 @@ fn can_adjust_total_staking_currency() { assert_ok!(HomaLite::adjust_total_staking_currency(Origin::root(), 1)); assert_eq!(HomaLite::total_staking_currency(), Balance::max_value()); + + // Do not allow TotalStakingCurrency to become 0 + assert_ok!(HomaLite::set_total_staking_currency(Origin::root(), 5000)); + assert_noop!( + HomaLite::adjust_total_staking_currency(Origin::root(), -5000), + Error::::InvalidTotalStakingCurrency + ); + assert_eq!(HomaLite::total_staking_currency(), 5000); + + // TotalStakingCurrency must be atleast 1 + assert_ok!(HomaLite::adjust_total_staking_currency(Origin::root(), -4999)); }); } From a15b6dfc22944adeb2f859aff03bdfe47a0d3eb3 Mon Sep 17 00:00:00 2001 From: Roy Yang Date: Wed, 27 Oct 2021 19:03:12 +1300 Subject: [PATCH 06/13] Improved a unit test to ensure new AvailableStakingBalance can match multiple redeem requests --- modules/homa-lite/src/tests.rs | 42 +++++++++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 6 deletions(-) diff --git a/modules/homa-lite/src/tests.rs b/modules/homa-lite/src/tests.rs index 1baef5b9e..b945cfa8a 100644 --- a/modules/homa-lite/src/tests.rs +++ b/modules/homa-lite/src/tests.rs @@ -442,19 +442,49 @@ fn new_available_staking_currency_can_handle_redeem_requests() { Some((dollar(989), Permill::zero())) ); + // Add more redeem request + assert_ok!(Currencies::update_balance( + Origin::root(), + ALICE, + LKSM, + dollar(1_000) as i128 + )); + assert_ok!(HomaLite::request_redeem( + Origin::signed(ALICE), + dollar(1_000), + Permill::zero() + )); + // 1000 - withdraw_fee = 999 + assert_eq!( + RedeemRequests::::get(&ALICE), + Some((dollar(999), Permill::zero())) + ); // Add more staking currency by adjust_available_staking_balance also // automatically fullfill pending redeem request. assert_ok!(HomaLite::adjust_available_staking_balance( Origin::root(), - 150_000_000_000_000 + dollar(200) as i128 )); - // The last request is redeemed, the leftover is stored. - assert_eq!(AvailableStakingBalance::::get(), 51_100_000_000_000); - assert_eq!(Currencies::free_balance(KSM, &ROOT), 1_096_900_000_000_000); - assert_eq!(Currencies::free_balance(LKSM, &ROOT), dollar(989_000)); - assert_eq!(Currencies::reserved_balance(LKSM, &ROOT), dollar(0)); + // The 2 remaining requests are redeemed, the leftover is stored. + // available_staking_remain = 200 - 98.9 - 99.9 = 1.2 + assert_eq!(AvailableStakingBalance::::get(), dollar(12) / 10); + + assert_eq!(RedeemRequests::::get(&ALICE), None); + assert_eq!(HomaLite::get_exchange_rate(), Ratio::saturating_from_rational(1, 10)); + // staking_gained = 99.9 - 1 (xcm_fee) = 98.9 + assert_eq!( + Currencies::free_balance(KSM, &ALICE), + dollar(INITIAL_BALANCE) + dollar(989) / 10 + ); + assert_eq!(Currencies::free_balance(LKSM, &ALICE), 0); + assert_eq!(Currencies::reserved_balance(LKSM, &ALICE), 0); + assert_eq!(RedeemRequests::::get(&ROOT), None); + // staking = 999(first redeem) + 98.9(this redeem) - 1(xcm_fee) = 1096.9 + assert_eq!(Currencies::free_balance(KSM, &ROOT), dollar(10_969) / 10); + assert_eq!(Currencies::free_balance(LKSM, &ROOT), dollar(989_000)); + assert_eq!(Currencies::reserved_balance(LKSM, &ROOT), 0); }); } From 1b0e0182c8fc73e98bee28070731e65eed6f1558 Mon Sep 17 00:00:00 2001 From: Roy Yang Date: Wed, 27 Oct 2021 19:22:44 +1300 Subject: [PATCH 07/13] Add test for decrementing `adjust_available_staking_balance` and `adjust_total_staking_currency` --- modules/homa-lite/src/tests.rs | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/modules/homa-lite/src/tests.rs b/modules/homa-lite/src/tests.rs index b945cfa8a..58e97146e 100644 --- a/modules/homa-lite/src/tests.rs +++ b/modules/homa-lite/src/tests.rs @@ -200,34 +200,39 @@ fn can_adjust_total_staking_currency() { assert_eq!(HomaLite::total_staking_currency(), 1); assert_noop!( - HomaLite::adjust_total_staking_currency(Origin::signed(ALICE), 5000), + HomaLite::adjust_total_staking_currency(Origin::signed(ALICE), 5000i128), BadOrigin ); // Can adjust total_staking_currency with ROOT. - assert_ok!(HomaLite::adjust_total_staking_currency(Origin::root(), 5000)); + assert_ok!(HomaLite::adjust_total_staking_currency(Origin::root(), 5000i128)); assert_eq!(HomaLite::total_staking_currency(), 5001); System::assert_last_event(Event::HomaLite(crate::Event::TotalStakingCurrencySet(5001))); + // Can decrease total_staking_currency. + assert_ok!(HomaLite::adjust_total_staking_currency(Origin::root(), -5000i128)); + assert_eq!(HomaLite::total_staking_currency(), 1); + System::assert_last_event(Event::HomaLite(crate::Event::TotalStakingCurrencySet(1))); + // overflow can be handled assert_ok!(HomaLite::set_total_staking_currency( Origin::root(), Balance::max_value() )); - assert_ok!(HomaLite::adjust_total_staking_currency(Origin::root(), 1)); + assert_ok!(HomaLite::adjust_total_staking_currency(Origin::root(), 1i128)); assert_eq!(HomaLite::total_staking_currency(), Balance::max_value()); // Do not allow TotalStakingCurrency to become 0 assert_ok!(HomaLite::set_total_staking_currency(Origin::root(), 5000)); assert_noop!( - HomaLite::adjust_total_staking_currency(Origin::root(), -5000), + HomaLite::adjust_total_staking_currency(Origin::root(), -5000i128), Error::::InvalidTotalStakingCurrency ); assert_eq!(HomaLite::total_staking_currency(), 5000); // TotalStakingCurrency must be atleast 1 - assert_ok!(HomaLite::adjust_total_staking_currency(Origin::root(), -4999)); + assert_ok!(HomaLite::adjust_total_staking_currency(Origin::root(), -4999i128)); }); } @@ -235,18 +240,22 @@ fn can_adjust_total_staking_currency() { fn can_adjust_available_staking_balance() { ExtBuilder::default().build().execute_with(|| { assert_noop!( - HomaLite::adjust_available_staking_balance(Origin::signed(ALICE), 5000), + HomaLite::adjust_available_staking_balance(Origin::signed(ALICE), 5000i128), BadOrigin ); - // Can adjust total_staking_currency with ROOT. - assert_ok!(HomaLite::adjust_available_staking_balance(Origin::root(), 5001)); - + // Can adjust available_staking_balance with ROOT. + assert_ok!(HomaLite::adjust_available_staking_balance(Origin::root(), 5001i128)); assert_eq!(HomaLite::available_staking_balance(), 5001); System::assert_last_event(Event::HomaLite(crate::Event::AvailableStakingBalanceSet(5001))); + // Can decrease available_staking_balance. + assert_ok!(HomaLite::adjust_available_staking_balance(Origin::root(), -5001i128)); + assert_eq!(HomaLite::total_staking_currency(), 0); + System::assert_last_event(Event::HomaLite(crate::Event::AvailableStakingBalanceSet(0))); + // Underflow / overflow can be handled due to the use of saturating arithmetic - assert_ok!(HomaLite::adjust_available_staking_balance(Origin::root(), -5002)); + assert_ok!(HomaLite::adjust_available_staking_balance(Origin::root(), -10_000i128)); assert_eq!(HomaLite::available_staking_balance(), 0); assert_ok!(HomaLite::adjust_available_staking_balance( From d581bde5b1a9bb7b8725f1d903a6d37bd165ac18 Mon Sep 17 00:00:00 2001 From: Roy Yang Date: Thu, 28 Oct 2021 12:20:12 +1300 Subject: [PATCH 08/13] Fixed a benchmarking test --- modules/homa-lite/src/benchmarking.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/homa-lite/src/benchmarking.rs b/modules/homa-lite/src/benchmarking.rs index 937540d7a..1d197a344 100644 --- a/modules/homa-lite/src/benchmarking.rs +++ b/modules/homa-lite/src/benchmarking.rs @@ -73,9 +73,9 @@ benchmarks! { set_total_staking_currency {}: _(RawOrigin::Root, 1_000_000_000_000) - adjust_total_staking_currency {}: _(RawOrigin::Root, AmountOf::::default()) + adjust_total_staking_currency {}: _(RawOrigin::Root, AmountOf::::max_value()) - adjust_available_staking_balance {}: _(RawOrigin::Root, AmountOf::::default()) + adjust_available_staking_balance {}: _(RawOrigin::Root, AmountOf::::max_value()) set_minting_cap { }: _(RawOrigin::Root, 1_000_000_000_000_000_000) From 7827bc033d78fa0313129a9f23c709dbc5653f04 Mon Sep 17 00:00:00 2001 From: Acala Benchmarking Bot Date: Thu, 28 Oct 2021 00:16:28 +0000 Subject: [PATCH 09/13] cargo run --release --color=never --bin=acala --features=runtime-benchmarks --features=with-mandala-runtime -- benchmark --chain=dev --steps=50 --repeat=20 --pallet=module_homa_lite --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --output=./modules/homa-lite/src/weights.rs --template=./templates/module-weight-template.hbs --- modules/homa-lite/src/weights.rs | 54 ++++++++++++++++---------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/modules/homa-lite/src/weights.rs b/modules/homa-lite/src/weights.rs index 22ba6e8d1..3abfe3c72 100644 --- a/modules/homa-lite/src/weights.rs +++ b/modules/homa-lite/src/weights.rs @@ -19,7 +19,7 @@ //! Autogenerated weights for module_homa_lite //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2021-10-22, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2021-10-28, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` //! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 128 // Executed Command: @@ -28,13 +28,13 @@ // --chain=dev // --steps=50 // --repeat=20 -// --pallet=module-homa-lite +// --pallet=module_homa_lite // --extrinsic=* // --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --template=./templates/module-weight-template.hbs // --output=./modules/homa-lite/src/weights.rs +// --template=./templates/module-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] @@ -64,52 +64,52 @@ pub trait WeightInfo { pub struct AcalaWeight(PhantomData); impl WeightInfo for AcalaWeight { fn on_idle() -> Weight { - (0 as Weight) + (571_000 as Weight) } fn mint() -> Weight { - (136_000_000 as Weight) + (254_110_000 as Weight) .saturating_add(T::DbWeight::get().reads(14 as Weight)) .saturating_add(T::DbWeight::get().writes(7 as Weight)) } fn mint_for_requests() -> Weight { - (345_000_000 as Weight) + (644_150_000 as Weight) .saturating_add(T::DbWeight::get().reads(30 as Weight)) .saturating_add(T::DbWeight::get().writes(21 as Weight)) } fn set_total_staking_currency() -> Weight { - (11_000_000 as Weight) + (19_950_000 as Weight) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn adjust_total_staking_currency() -> Weight { - (12_000_000 as Weight) + (22_592_000 as Weight) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn adjust_available_staking_balance() -> Weight { - (17_000_000 as Weight) + (31_984_000 as Weight) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn set_minting_cap() -> Weight { - (11_000_000 as Weight) + (20_217_000 as Weight) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn set_xcm_dest_weight() -> Weight { - (10_000_000 as Weight) + (19_372_000 as Weight) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn request_redeem() -> Weight { - (76_000_000 as Weight) + (154_521_000 as Weight) .saturating_add(T::DbWeight::get().reads(7 as Weight)) - .saturating_add(T::DbWeight::get().writes(3 as Weight)) + .saturating_add(T::DbWeight::get().writes(4 as Weight)) } fn schedule_unbond() -> Weight { - (13_000_000 as Weight) + (24_240_000 as Weight) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn replace_schedule_unbond() -> Weight { - (11_000_000 as Weight) + (21_316_000 as Weight) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } } @@ -117,52 +117,52 @@ impl WeightInfo for AcalaWeight { // For backwards compatibility and tests impl WeightInfo for () { fn on_idle() -> Weight { - (0 as Weight) + (571_000 as Weight) } fn mint() -> Weight { - (136_000_000 as Weight) + (254_110_000 as Weight) .saturating_add(RocksDbWeight::get().reads(14 as Weight)) .saturating_add(RocksDbWeight::get().writes(7 as Weight)) } fn mint_for_requests() -> Weight { - (345_000_000 as Weight) + (644_150_000 as Weight) .saturating_add(RocksDbWeight::get().reads(30 as Weight)) .saturating_add(RocksDbWeight::get().writes(21 as Weight)) } fn set_total_staking_currency() -> Weight { - (11_000_000 as Weight) + (19_950_000 as Weight) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn adjust_total_staking_currency() -> Weight { - (12_000_000 as Weight) + (22_592_000 as Weight) .saturating_add(RocksDbWeight::get().reads(1 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn adjust_available_staking_balance() -> Weight { - (17_000_000 as Weight) + (31_984_000 as Weight) .saturating_add(RocksDbWeight::get().reads(2 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn set_minting_cap() -> Weight { - (11_000_000 as Weight) + (20_217_000 as Weight) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn set_xcm_dest_weight() -> Weight { - (10_000_000 as Weight) + (19_372_000 as Weight) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn request_redeem() -> Weight { - (76_000_000 as Weight) + (154_521_000 as Weight) .saturating_add(RocksDbWeight::get().reads(7 as Weight)) - .saturating_add(RocksDbWeight::get().writes(3 as Weight)) + .saturating_add(RocksDbWeight::get().writes(4 as Weight)) } fn schedule_unbond() -> Weight { - (13_000_000 as Weight) + (24_240_000 as Weight) .saturating_add(RocksDbWeight::get().reads(1 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn replace_schedule_unbond() -> Weight { - (11_000_000 as Weight) + (21_316_000 as Weight) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } } From 1ac33432732dd7a90c0dea23ea12cd0d22cac4aa Mon Sep 17 00:00:00 2001 From: Acala Benchmarking Bot Date: Thu, 28 Oct 2021 01:04:52 +0000 Subject: [PATCH 10/13] cargo run --release --color=never --bin=acala --features=runtime-benchmarks --features=with-karura-runtime -- benchmark --chain=karura-dev --steps=50 --repeat=20 --pallet=module_homa_lite --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --template=./templates/runtime-weight-template.hbs --output=./runtime/karura/src/weights/ --- .../karura/src/weights/module_homa_lite.rs | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/runtime/karura/src/weights/module_homa_lite.rs b/runtime/karura/src/weights/module_homa_lite.rs index cd57c360d..35ffc6419 100644 --- a/runtime/karura/src/weights/module_homa_lite.rs +++ b/runtime/karura/src/weights/module_homa_lite.rs @@ -19,7 +19,7 @@ //! Autogenerated weights for module_homa_lite //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2021-10-22, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2021-10-28, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` //! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("karura-dev"), DB CACHE: 128 // Executed Command: @@ -28,7 +28,7 @@ // --chain=karura-dev // --steps=50 // --repeat=20 -// --pallet=module-homa-lite +// --pallet=module_homa_lite // --extrinsic=* // --execution=wasm // --wasm-execution=compiled @@ -48,54 +48,54 @@ use sp_std::marker::PhantomData; pub struct WeightInfo(PhantomData); impl module_homa_lite::WeightInfo for WeightInfo { fn on_idle() -> Weight { - (35_000_000 as Weight) - .saturating_add(T::DbWeight::get().reads(8 as Weight)) - .saturating_add(T::DbWeight::get().writes(3 as Weight)) + (87_670_000 as Weight) + .saturating_add(T::DbWeight::get().reads(11 as Weight)) + .saturating_add(T::DbWeight::get().writes(4 as Weight)) } fn mint() -> Weight { - (134_000_000 as Weight) - .saturating_add(T::DbWeight::get().reads(14 as Weight)) - .saturating_add(T::DbWeight::get().writes(7 as Weight)) + (305_852_000 as Weight) + .saturating_add(T::DbWeight::get().reads(17 as Weight)) + .saturating_add(T::DbWeight::get().writes(8 as Weight)) } fn mint_for_requests() -> Weight { - (143_000_000 as Weight) - .saturating_add(T::DbWeight::get().reads(16 as Weight)) - .saturating_add(T::DbWeight::get().writes(7 as Weight)) + (317_863_000 as Weight) + .saturating_add(T::DbWeight::get().reads(19 as Weight)) + .saturating_add(T::DbWeight::get().writes(8 as Weight)) } fn set_total_staking_currency() -> Weight { - (11_000_000 as Weight) + (19_766_000 as Weight) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn adjust_total_staking_currency() -> Weight { - (12_000_000 as Weight) + (22_106_000 as Weight) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn adjust_available_staking_balance() -> Weight { - (17_000_000 as Weight) + (31_653_000 as Weight) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn set_minting_cap() -> Weight { - (11_000_000 as Weight) + (20_231_000 as Weight) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn set_xcm_dest_weight() -> Weight { - (10_000_000 as Weight) + (19_320_000 as Weight) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn request_redeem() -> Weight { - (74_000_000 as Weight) + (154_292_000 as Weight) .saturating_add(T::DbWeight::get().reads(7 as Weight)) - .saturating_add(T::DbWeight::get().writes(3 as Weight)) + .saturating_add(T::DbWeight::get().writes(4 as Weight)) } fn schedule_unbond() -> Weight { - (13_000_000 as Weight) + (24_274_000 as Weight) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn replace_schedule_unbond() -> Weight { - (11_000_000 as Weight) + (20_799_000 as Weight) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } } From 5d8e7c4feeccf70600eb443eacf3da8850ab5375 Mon Sep 17 00:00:00 2001 From: Roy Yang Date: Fri, 29 Oct 2021 10:46:09 +1300 Subject: [PATCH 11/13] Added a test that reproduces the bug --- modules/homa-lite/src/tests.rs | 65 ++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/modules/homa-lite/src/tests.rs b/modules/homa-lite/src/tests.rs index a3c8a3b44..69d20853b 100644 --- a/modules/homa-lite/src/tests.rs +++ b/modules/homa-lite/src/tests.rs @@ -942,3 +942,68 @@ fn not_overcharge_redeem_fee() { assert_eq!(Currencies::reserved_balance(LKSM, &ALICE), dollar(20) - fee * 2); }); } + +#[test] +fn available_staking_balances_can_handle_dust() { + ExtBuilder::empty().build().execute_with(|| { + assert_ok!(Currencies::update_balance( + Origin::root(), + ALICE, + LKSM, + dollar(5_000) as i128 + )); + assert_ok!(Currencies::update_balance( + Origin::root(), + BOB, + LKSM, + dollar(2_000) as i128 + )); + assert_ok!(Currencies::update_balance( + Origin::root(), + ROOT, + LKSM, + dollar(3_000) as i128 + )); + + // find exchange rate with roudning error + HomaLite::set_total_staking_currency(Origin::root(), 1000237000000000000); + let staking_amount = 999_999_999_999; + let liquid_amount = HomaLite::convert_staking_to_liquid(staking_amount).unwrap(); + let staking_amount2 = HomaLite::convert_liquid_to_staking(liquid_amount).unwrap(); + assert_ne!(staking_amount, staking_amount2); + + assert_ok!(HomaLite::request_redeem( + Origin::signed(ALICE), + dollar(5_000), + Permill::zero() + )); + assert_ok!(HomaLite::request_redeem( + Origin::signed(BOB), + dollar(2_000), + Permill::zero() + )); + assert_ok!(HomaLite::request_redeem( + Origin::signed(ROOT), + dollar(3_000), + Permill::zero() + )); + assert_ok!(HomaLite::replace_schedule_unbond( + Origin::root(), + vec![(999_999_999_999, 1)], + )); + MockRelayBlockNumberProvider::set(1); + + HomaLite::on_idle(MockRelayBlockNumberProvider::get(), 5_000_000_000); + + assert_eq!(HomaLite::available_staking_balance(), 0); + let events = System::events(); + assert_eq!( + events[events.len() - 2].event, + Event::HomaLite(crate::Event::Redeemed(ALICE, 999999999900, 9987632930)) + ); + assert_eq!( + events[events.len() - 1].event, + Event::HomaLite(crate::Event::ScheduledUnbondWithdrew(999_999_999_999)) + ); + }); +} From 0eadcb42a4fa8deecbc557b25b3dc5ac261a61ad Mon Sep 17 00:00:00 2001 From: Roy Yang Date: Mon, 1 Nov 2021 17:48:42 +1300 Subject: [PATCH 12/13] Changed the way weights are handled for on_idle and adjust_available_staking_balance adjust_available_staking_balance now takes how many redeem matches is allowed. Weight is calculated from this parameter Added unit test for the new behaviour --- modules/homa-lite/src/benchmarking.rs | 58 +++--- modules/homa-lite/src/lib.rs | 74 +++++-- modules/homa-lite/src/tests.rs | 196 ++++++++++++++++-- modules/homa-lite/src/weights.rs | 81 +++++--- runtime/acala/src/weights/module_homa_lite.rs | 15 +- .../karura/src/weights/module_homa_lite.rs | 43 ++-- .../mandala/src/weights/module_homa_lite.rs | 15 +- 7 files changed, 359 insertions(+), 123 deletions(-) diff --git a/modules/homa-lite/src/benchmarking.rs b/modules/homa-lite/src/benchmarking.rs index 1d197a344..07b318a4d 100644 --- a/modules/homa-lite/src/benchmarking.rs +++ b/modules/homa-lite/src/benchmarking.rs @@ -30,23 +30,6 @@ pub struct Module(crate::Pallet); const SEED: u32 = 0; benchmarks! { - on_idle { - let amount = 1_000_000_000_000; - let caller: T::AccountId = account("caller", 0, SEED); - let caller1: T::AccountId = account("callera", 0, SEED); - let caller2: T::AccountId = account("callerb", 0, SEED); - let caller3: T::AccountId = account("callerc", 0, SEED); - ::Currency::deposit(T::LiquidCurrencyId::get(), &caller1, amount)?; - ::Currency::deposit(T::LiquidCurrencyId::get(), &caller2, amount)?; - ::Currency::deposit(T::LiquidCurrencyId::get(), &caller3, amount)?; - let _ = crate::Pallet::::request_redeem(RawOrigin::Signed(caller1).into(), amount, Permill::default()); - let _ = crate::Pallet::::request_redeem(RawOrigin::Signed(caller2.clone()).into(), amount, Permill::default()); - let _ = crate::Pallet::::request_redeem(RawOrigin::Signed(caller3.clone()).into(), amount, Permill::default()); - let _ = crate::Pallet::::schedule_unbond(RawOrigin::Root.into(), amount*2, ::BlockNumber::default()); - }: { - let _ = crate::Pallet::::on_idle(::BlockNumber::default(), 1_000_000_000); - } - mint { let amount = 1_000_000_000_000; let caller: T::AccountId = account("caller", 0, SEED); @@ -75,7 +58,9 @@ benchmarks! { adjust_total_staking_currency {}: _(RawOrigin::Root, AmountOf::::max_value()) - adjust_available_staking_balance {}: _(RawOrigin::Root, AmountOf::::max_value()) + adjust_available_staking_balance_with_no_matches {}: { + let _ = crate::Pallet::::adjust_available_staking_balance(RawOrigin::Root.into(), AmountOf::::max_value(), 0); + } set_minting_cap { }: _(RawOrigin::Root, 1_000_000_000_000_000_000) @@ -92,6 +77,20 @@ benchmarks! { schedule_unbond {}: _(RawOrigin::Root, 1_000_000_000_000, ::BlockNumber::default()) replace_schedule_unbond {}: _(RawOrigin::Root, vec![(1_000_000, ::BlockNumber::default()), (1_000_000_000, ::BlockNumber::default())]) + + redeem_with_available_staking_balance { + let amount = 1_000_000_000_000_000; + let caller: T::AccountId = account("caller", 0, SEED); + ::Currency::deposit(T::LiquidCurrencyId::get(), &caller, amount)?; + let _ = crate::Pallet::::adjust_available_staking_balance(RawOrigin::Root.into(), AmountOf::::max_value(), 1); + let _ = crate::Pallet::::request_redeem(RawOrigin::Signed(caller).into(), amount, Permill::default()); + }: { + let _ = crate::Pallet::::process_redeem_requests_with_available_staking_balance(1); + } + + xcm_unbond {}: { + let _ = crate::Pallet::::process_scheduled_unbond(1_000_000_000_000_000); + } } #[cfg(test)] @@ -100,13 +99,6 @@ mod tests { use crate::mock::*; use frame_support::assert_ok; - #[test] - fn test_on_idle() { - ExtBuilder::default().build().execute_with(|| { - assert_ok!(Pallet::::test_benchmark_on_idle()); - }); - } - #[test] fn test_mint() { ExtBuilder::default().build().execute_with(|| { @@ -132,9 +124,9 @@ mod tests { }); } #[test] - fn test_adjust_available_staking_balance() { + fn test_adjust_available_staking_balance_with_no_matches() { ExtBuilder::default().build().execute_with(|| { - assert_ok!(Pallet::::test_benchmark_adjust_available_staking_balance()); + assert_ok!(Pallet::::test_benchmark_adjust_available_staking_balance_with_no_matches()); }); } @@ -168,4 +160,16 @@ mod tests { assert_ok!(Pallet::::test_benchmark_replace_schedule_unbond()); }); } + #[test] + fn test_redeem_with_available_staking_balance() { + ExtBuilder::default().build().execute_with(|| { + assert_ok!(Pallet::::test_benchmark_redeem_with_available_staking_balance()); + }); + } + #[test] + fn test_xcm_unbond() { + ExtBuilder::default().build().execute_with(|| { + assert_ok!(Pallet::::test_benchmark_xcm_unbond()); + }); + } } diff --git a/modules/homa-lite/src/lib.rs b/modules/homa-lite/src/lib.rs index 9542cfe7b..79a0e02ac 100644 --- a/modules/homa-lite/src/lib.rs +++ b/modules/homa-lite/src/lib.rs @@ -249,9 +249,9 @@ pub mod module { #[pallet::hooks] impl Hooks for Pallet { fn on_idle(_n: T::BlockNumber, remaining_weight: Weight) -> Weight { - let required_weight = ::WeightInfo::on_idle(); let mut current_weight = 0; - if remaining_weight > required_weight { + // If enough weight, process the next XCM unbond. + if remaining_weight > ::WeightInfo::xcm_unbond() { let mut scheduled_unbond = Self::scheduled_unbond(); if !scheduled_unbond.is_empty() { let (staking_amount, block_number) = scheduled_unbond[0]; @@ -261,7 +261,7 @@ pub mod module { debug_assert!(res.is_ok()); if res.is_ok() { - current_weight = required_weight; + current_weight = ::WeightInfo::xcm_unbond(); scheduled_unbond.remove(0); ScheduledUnbond::::put(scheduled_unbond); @@ -269,6 +269,22 @@ pub mod module { } } } + + // With remaining weight, calculate max number of redeems that can be matched + let num_redeem_matches = remaining_weight + .saturating_sub(current_weight) + .checked_div(::WeightInfo::redeem_with_available_staking_balance()) + .unwrap_or_default(); + + // Iterate through existing redeem_requests, and try to match them with `available_staking_balance` + let res = Self::process_redeem_requests_with_available_staking_balance(num_redeem_matches); + debug_assert!(res.is_ok()); + if res.is_ok() { + current_weight = current_weight.saturating_add( + ::WeightInfo::redeem_with_available_staking_balance().saturating_mul(res.unwrap()), + ); + } + current_weight } } @@ -580,9 +596,17 @@ pub mod module { /// Parameters: /// - `adjustment`: The difference in amount the AvailableStakingBalance should be adjusted /// by. - #[pallet::weight(< T as Config >::WeightInfo::adjust_available_staking_balance())] + #[pallet::weight( + < T as Config >::WeightInfo::adjust_available_staking_balance_with_no_matches().saturating_add( + max_num_matches.saturating_mul(< T as Config >::WeightInfo::redeem_with_available_staking_balance()) + ) + )] #[transactional] - pub fn adjust_available_staking_balance(origin: OriginFor, by_amount: AmountOf) -> DispatchResult { + pub fn adjust_available_staking_balance( + origin: OriginFor, + by_amount: AmountOf, + max_num_matches: u64, + ) -> DispatchResult { T::GovernanceOrigin::ensure_origin(origin)?; // Convert AmountOf into Balance safely. @@ -605,7 +629,8 @@ pub mod module { }); // With new staking balance available, process pending redeem requests. - Self::process_redeem_requests_with_available_staking_balance() + let _ = Self::process_redeem_requests_with_available_staking_balance(max_num_matches)?; + Ok(()) } } @@ -816,10 +841,9 @@ pub mod module { } /// Construct XCM message and sent it to the relaychain to withdraw_unbonded Staking - /// currency. The staking currency withdrew becomes available to be redeemed. Process - /// through redeem requests to fullfill the redeem order. + /// currency. The staking currency withdrew becomes available to be redeemed. #[transactional] - fn process_scheduled_unbond(staking_amount_unbonded: Balance) -> DispatchResult { + pub fn process_scheduled_unbond(staking_amount_unbonded: Balance) -> DispatchResult { let msg = Self::construct_xcm_unreserve_message(T::ParachainAccount::get(), staking_amount_unbonded); let res = pallet_xcm::Pallet::::send_xcm(Here, Parent, msg); @@ -832,23 +856,26 @@ pub mod module { }); Self::deposit_event(Event::::ScheduledUnbondWithdrew(staking_amount_unbonded)); - - // Now that there's available staking balance, automatically match existing - // redeem_requests. - Self::process_redeem_requests_with_available_staking_balance() + Ok(()) } /// Iterate through all redeem requests, then match them with available_staking_balance. /// This should be called when new available_staking_balance becomes available. #[transactional] - fn process_redeem_requests_with_available_staking_balance() -> DispatchResult { - let mut new_balances: Vec<(T::AccountId, Balance, Permill)> = vec![]; + pub fn process_redeem_requests_with_available_staking_balance( + max_num_matches: u64, + ) -> Result { + if max_num_matches.is_zero() { + return Ok(0); + } let mut available_staking_balance = Self::available_staking_balance(); + if available_staking_balance.is_zero() { + return Ok(0); + } + + let mut new_balances: Vec<(T::AccountId, Balance, Permill)> = vec![]; + let mut num_matched = 0u64; for (redeemer, (request_amount, extra_fee)) in RedeemRequests::::iter() { - // If all the currencies are minted, return. - if available_staking_balance.is_zero() { - break; - } let actual_liquid_amount = min( request_amount, Self::convert_staking_to_liquid(available_staking_balance)?, @@ -876,6 +903,12 @@ pub mod module { actual_staking_amount, actual_liquid_amount, )); + num_matched += 1u64; + + // If all the currencies are minted, return. + if available_staking_balance.is_zero() || num_matched >= max_num_matches { + break; + } } // Update storage to the new balances. Remove Redeem requests that have been filled. @@ -883,8 +916,9 @@ pub mod module { AvailableStakingBalance::::put(available_staking_balance); - Ok(()) + Ok(num_matched) } + /// Update the RedeemRequests storage with the new balances. /// Remove Redeem requests that are dust, or have been filled. #[allow(clippy::ptr_arg)] diff --git a/modules/homa-lite/src/tests.rs b/modules/homa-lite/src/tests.rs index 58e97146e..8fafdda53 100644 --- a/modules/homa-lite/src/tests.rs +++ b/modules/homa-lite/src/tests.rs @@ -237,38 +237,49 @@ fn can_adjust_total_staking_currency() { } #[test] -fn can_adjust_available_staking_balance() { +fn can_adjust_available_staking_balance_with_no_matches() { ExtBuilder::default().build().execute_with(|| { assert_noop!( - HomaLite::adjust_available_staking_balance(Origin::signed(ALICE), 5000i128), + HomaLite::adjust_available_staking_balance(Origin::signed(ALICE), 5000i128, 10), BadOrigin ); // Can adjust available_staking_balance with ROOT. - assert_ok!(HomaLite::adjust_available_staking_balance(Origin::root(), 5001i128)); + assert_ok!(HomaLite::adjust_available_staking_balance(Origin::root(), 5001i128, 10)); assert_eq!(HomaLite::available_staking_balance(), 5001); System::assert_last_event(Event::HomaLite(crate::Event::AvailableStakingBalanceSet(5001))); // Can decrease available_staking_balance. - assert_ok!(HomaLite::adjust_available_staking_balance(Origin::root(), -5001i128)); + assert_ok!(HomaLite::adjust_available_staking_balance( + Origin::root(), + -5001i128, + 10 + )); assert_eq!(HomaLite::total_staking_currency(), 0); System::assert_last_event(Event::HomaLite(crate::Event::AvailableStakingBalanceSet(0))); // Underflow / overflow can be handled due to the use of saturating arithmetic - assert_ok!(HomaLite::adjust_available_staking_balance(Origin::root(), -10_000i128)); + assert_ok!(HomaLite::adjust_available_staking_balance( + Origin::root(), + -10_000i128, + 10 + )); assert_eq!(HomaLite::available_staking_balance(), 0); assert_ok!(HomaLite::adjust_available_staking_balance( Origin::root(), - i128::max_value() + i128::max_value(), + 10 )); assert_ok!(HomaLite::adjust_available_staking_balance( Origin::root(), - i128::max_value() + i128::max_value(), + 10 )); assert_ok!(HomaLite::adjust_available_staking_balance( Origin::root(), - i128::max_value() + i128::max_value(), + 10 )); assert_eq!(HomaLite::available_staking_balance(), Balance::max_value()); }); @@ -472,7 +483,8 @@ fn new_available_staking_currency_can_handle_redeem_requests() { // automatically fullfill pending redeem request. assert_ok!(HomaLite::adjust_available_staking_balance( Origin::root(), - dollar(200) as i128 + dollar(200) as i128, + 10 )); // The 2 remaining requests are redeemed, the leftover is stored. @@ -538,7 +550,8 @@ fn request_redeem_works() { ExtBuilder::default().build().execute_with(|| { assert_ok!(HomaLite::adjust_available_staking_balance( Origin::root(), - 50_000_000_000_000_000 + 50_000_000_000_000_000, + 10 )); assert_eq!(AvailableStakingBalance::::get(), dollar(50_000)); @@ -600,7 +613,8 @@ fn request_redeem_can_handle_dust_redeem_requests() { ExtBuilder::default().build().execute_with(|| { assert_ok!(HomaLite::adjust_available_staking_balance( Origin::root(), - 50_000_000_000_000_000 + 50_000_000_000_000_000, + 10 )); assert_eq!(AvailableStakingBalance::::get(), dollar(50_000)); @@ -870,7 +884,11 @@ fn redeem_can_handle_dust_available_staking_currency() { ExtBuilder::default().build().execute_with(|| { // If AvailableStakingBalance is not enough to pay for the unbonding fee, ignore it. // pub XcmUnbondFee: Balance = dollar(1); - assert_ok!(HomaLite::adjust_available_staking_balance(Origin::root(), 999_000_000)); + assert_ok!(HomaLite::adjust_available_staking_balance( + Origin::root(), + 999_000_000, + 10 + )); assert_eq!(AvailableStakingBalance::::get(), 999_000_000); @@ -1011,3 +1029,157 @@ fn not_overcharge_redeem_fee() { assert_eq!(Currencies::reserved_balance(LKSM, &ALICE), dollar(20) - fee * 2); }); } + +#[test] +fn on_idle_matches_redeem_based_on_weights() { + ExtBuilder::default().build().execute_with(|| { + assert_ok!(Currencies::update_balance( + Origin::root(), + ALICE, + LKSM, + dollar(INITIAL_BALANCE) as i128 + )); + + assert_ok!(HomaLite::set_total_staking_currency( + Origin::root(), + Currencies::total_issuance(LKSM) / 10 + )); + + // Schedule an unbond. + assert_ok!(HomaLite::schedule_unbond(Origin::root(), dollar(1_000_000), 0)); + MockRelayBlockNumberProvider::set(0); + + assert_ok!(HomaLite::request_redeem( + Origin::signed(ROOT), + dollar(1_000), + Permill::zero() + )); + assert_ok!(HomaLite::request_redeem( + Origin::signed(ALICE), + dollar(1_000), + Permill::zero() + )); + + // Get the currently benchmarked weight. + let xcm_weight = ::WeightInfo::xcm_unbond(); + let redeem = ::WeightInfo::redeem_with_available_staking_balance(); + + // on_idle does nothing with insufficient weight + assert_eq!(HomaLite::on_idle(MockRelayBlockNumberProvider::get(), 0), 0); + assert_eq!(ScheduledUnbond::::get(), vec![(dollar(1_000_000), 0)]); + assert_eq!( + RedeemRequests::::get(ROOT), + Some((dollar(999), Permill::zero())) + ); + assert_eq!( + RedeemRequests::::get(ALICE), + Some((dollar(999), Permill::zero())) + ); + + // on_idle only perform XCM unbond with sufficient weight + assert_eq!( + HomaLite::on_idle(MockRelayBlockNumberProvider::get(), xcm_weight + 1), + xcm_weight + ); + assert_eq!(ScheduledUnbond::::get(), vec![]); + assert_eq!( + RedeemRequests::::get(ROOT), + Some((dollar(999), Permill::zero())) + ); + assert_eq!( + RedeemRequests::::get(ALICE), + Some((dollar(999), Permill::zero())) + ); + + // on_idle has weights to match only one redeem + assert_ok!(HomaLite::schedule_unbond(Origin::root(), dollar(1_000_000), 0)); + assert_eq!(ScheduledUnbond::::get(), vec![(dollar(1_000_000), 0)]); + assert_eq!( + HomaLite::on_idle(MockRelayBlockNumberProvider::get(), xcm_weight + redeem + 1), + xcm_weight + redeem + ); + assert_eq!(ScheduledUnbond::::get(), vec![]); + assert_eq!( + RedeemRequests::::get(ROOT), + Some((dollar(999), Permill::zero())) + ); + assert_eq!(RedeemRequests::::get(ALICE), None); + + // on_idle will match the remaining redeem request, even with no scheduled unbond. + assert_ok!(HomaLite::schedule_unbond(Origin::root(), dollar(1_000_000), 10)); + assert_eq!(ScheduledUnbond::::get(), vec![(dollar(1_000_000), 10)]); + assert_eq!( + HomaLite::on_idle(MockRelayBlockNumberProvider::get(), redeem + 1), + redeem + ); + assert_eq!(ScheduledUnbond::::get(), vec![(dollar(1_000_000), 10)]); + assert_eq!(RedeemRequests::::get(ROOT), None); + assert_eq!(RedeemRequests::::get(ALICE), None); + }); +} + +#[test] +fn adjust_available_staking_balance_matches_redeem_based_on_input() { + ExtBuilder::default().build().execute_with(|| { + assert_ok!(Currencies::update_balance( + Origin::root(), + ALICE, + LKSM, + dollar(INITIAL_BALANCE) as i128 + )); + + assert_ok!(Currencies::update_balance( + Origin::root(), + BOB, + LKSM, + dollar(INITIAL_BALANCE) as i128 + )); + + assert_ok!(HomaLite::request_redeem( + Origin::signed(ROOT), + dollar(1_000), + Permill::zero() + )); + assert_ok!(HomaLite::request_redeem( + Origin::signed(ALICE), + dollar(1_000), + Permill::zero() + )); + assert_ok!(HomaLite::request_redeem( + Origin::signed(BOB), + dollar(1_000), + Permill::zero() + )); + + assert_ok!(HomaLite::set_total_staking_currency( + Origin::root(), + Currencies::total_issuance(LKSM) / 10 + )); + + // match no redeem requests + assert_ok!(HomaLite::adjust_available_staking_balance( + Origin::root(), + dollar(1_000_000) as i128, + 0 + )); + assert_eq!(AvailableStakingBalance::::get(), dollar(1_000_000)); + + // match only one request + assert_ok!(HomaLite::adjust_available_staking_balance(Origin::root(), 1i128, 1)); + assert_eq!( + RedeemRequests::::get(ROOT), + Some((dollar(999), Permill::zero())) + ); + assert_eq!(RedeemRequests::::get(ALICE), None); + assert_eq!( + RedeemRequests::::get(BOB), + Some((dollar(999), Permill::zero())) + ); + + // match the remaining requests + assert_ok!(HomaLite::adjust_available_staking_balance(Origin::root(), 1, 10)); + assert_eq!(RedeemRequests::::get(ROOT), None); + assert_eq!(RedeemRequests::::get(ALICE), None); + assert_eq!(RedeemRequests::::get(BOB), None); + }); +} diff --git a/modules/homa-lite/src/weights.rs b/modules/homa-lite/src/weights.rs index 3abfe3c72..a027b88e6 100644 --- a/modules/homa-lite/src/weights.rs +++ b/modules/homa-lite/src/weights.rs @@ -19,7 +19,7 @@ //! Autogenerated weights for module_homa_lite //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2021-10-28, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2021-11-01, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` //! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 128 // Executed Command: @@ -28,13 +28,13 @@ // --chain=dev // --steps=50 // --repeat=20 -// --pallet=module_homa_lite +// --pallet=module-homa-lite // --extrinsic=* // --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --output=./modules/homa-lite/src/weights.rs // --template=./templates/module-weight-template.hbs +// --output=./modules/homa-lite/src/weights.rs #![cfg_attr(rustfmt, rustfmt_skip)] @@ -47,122 +47,137 @@ use sp_std::marker::PhantomData; /// Weight functions needed for module_homa_lite. pub trait WeightInfo { - fn on_idle() -> Weight; fn mint() -> Weight; fn mint_for_requests() -> Weight; fn set_total_staking_currency() -> Weight; fn adjust_total_staking_currency() -> Weight; - fn adjust_available_staking_balance() -> Weight; + fn adjust_available_staking_balance_with_no_matches() -> Weight; fn set_minting_cap() -> Weight; fn set_xcm_dest_weight() -> Weight; fn request_redeem() -> Weight; fn schedule_unbond() -> Weight; fn replace_schedule_unbond() -> Weight; + fn redeem_with_available_staking_balance() -> Weight; + fn xcm_unbond() -> Weight; } /// Weights for module_homa_lite using the Acala node and recommended hardware. pub struct AcalaWeight(PhantomData); impl WeightInfo for AcalaWeight { - fn on_idle() -> Weight { - (571_000 as Weight) - } fn mint() -> Weight { - (254_110_000 as Weight) + (138_000_000 as Weight) .saturating_add(T::DbWeight::get().reads(14 as Weight)) .saturating_add(T::DbWeight::get().writes(7 as Weight)) } fn mint_for_requests() -> Weight { - (644_150_000 as Weight) + (348_000_000 as Weight) .saturating_add(T::DbWeight::get().reads(30 as Weight)) .saturating_add(T::DbWeight::get().writes(21 as Weight)) } fn set_total_staking_currency() -> Weight { - (19_950_000 as Weight) + (11_000_000 as Weight) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn adjust_total_staking_currency() -> Weight { - (22_592_000 as Weight) + (12_000_000 as Weight) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn adjust_available_staking_balance() -> Weight { - (31_984_000 as Weight) + fn adjust_available_staking_balance_with_no_matches() -> Weight { + (17_000_000 as Weight) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn set_minting_cap() -> Weight { - (20_217_000 as Weight) + (11_000_000 as Weight) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn set_xcm_dest_weight() -> Weight { - (19_372_000 as Weight) + (11_000_000 as Weight) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn request_redeem() -> Weight { - (154_521_000 as Weight) + (82_000_000 as Weight) .saturating_add(T::DbWeight::get().reads(7 as Weight)) .saturating_add(T::DbWeight::get().writes(4 as Weight)) } fn schedule_unbond() -> Weight { - (24_240_000 as Weight) + (13_000_000 as Weight) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn replace_schedule_unbond() -> Weight { - (21_316_000 as Weight) + (11_000_000 as Weight) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) + } + fn redeem_with_available_staking_balance() -> Weight { + (6_000_000 as Weight) + .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } + fn xcm_unbond() -> Weight { + (24_000_000 as Weight) + .saturating_add(T::DbWeight::get().reads(5 as Weight)) + .saturating_add(T::DbWeight::get().writes(2 as Weight)) + } } // For backwards compatibility and tests impl WeightInfo for () { - fn on_idle() -> Weight { - (571_000 as Weight) - } fn mint() -> Weight { - (254_110_000 as Weight) + (138_000_000 as Weight) .saturating_add(RocksDbWeight::get().reads(14 as Weight)) .saturating_add(RocksDbWeight::get().writes(7 as Weight)) } fn mint_for_requests() -> Weight { - (644_150_000 as Weight) + (348_000_000 as Weight) .saturating_add(RocksDbWeight::get().reads(30 as Weight)) .saturating_add(RocksDbWeight::get().writes(21 as Weight)) } fn set_total_staking_currency() -> Weight { - (19_950_000 as Weight) + (11_000_000 as Weight) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn adjust_total_staking_currency() -> Weight { - (22_592_000 as Weight) + (12_000_000 as Weight) .saturating_add(RocksDbWeight::get().reads(1 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } - fn adjust_available_staking_balance() -> Weight { - (31_984_000 as Weight) + fn adjust_available_staking_balance_with_no_matches() -> Weight { + (17_000_000 as Weight) .saturating_add(RocksDbWeight::get().reads(2 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn set_minting_cap() -> Weight { - (20_217_000 as Weight) + (11_000_000 as Weight) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn set_xcm_dest_weight() -> Weight { - (19_372_000 as Weight) + (11_000_000 as Weight) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn request_redeem() -> Weight { - (154_521_000 as Weight) + (82_000_000 as Weight) .saturating_add(RocksDbWeight::get().reads(7 as Weight)) .saturating_add(RocksDbWeight::get().writes(4 as Weight)) } fn schedule_unbond() -> Weight { - (24_240_000 as Weight) + (13_000_000 as Weight) .saturating_add(RocksDbWeight::get().reads(1 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn replace_schedule_unbond() -> Weight { - (21_316_000 as Weight) + (11_000_000 as Weight) + .saturating_add(RocksDbWeight::get().writes(1 as Weight)) + } + fn redeem_with_available_staking_balance() -> Weight { + (6_000_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(2 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } + fn xcm_unbond() -> Weight { + (24_000_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(5 as Weight)) + .saturating_add(RocksDbWeight::get().writes(2 as Weight)) + } } diff --git a/runtime/acala/src/weights/module_homa_lite.rs b/runtime/acala/src/weights/module_homa_lite.rs index 5b9156f8a..592f8c022 100644 --- a/runtime/acala/src/weights/module_homa_lite.rs +++ b/runtime/acala/src/weights/module_homa_lite.rs @@ -47,11 +47,6 @@ use sp_std::marker::PhantomData; /// Weight functions for module_homa_lite. pub struct WeightInfo(PhantomData); impl module_homa_lite::WeightInfo for WeightInfo { - fn on_idle() -> Weight { - (254_000_000 as Weight) - .saturating_add(T::DbWeight::get().reads(23 as Weight)) - .saturating_add(T::DbWeight::get().writes(17 as Weight)) - } fn mint() -> Weight { (134_000_000 as Weight) .saturating_add(T::DbWeight::get().reads(14 as Weight)) @@ -71,7 +66,7 @@ impl module_homa_lite::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn adjust_available_staking_balance() -> Weight { + fn adjust_available_staking_balance_with_no_matches() -> Weight { (17_000_000 as Weight) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) @@ -98,4 +93,12 @@ impl module_homa_lite::WeightInfo for WeightInfo { (11_000_000 as Weight) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } + fn redeem_with_available_staking_balance() -> Weight { + (21_316_000 as Weight) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) + } + fn xcm_unbond() -> Weight { + (21_316_000 as Weight) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) + } } diff --git a/runtime/karura/src/weights/module_homa_lite.rs b/runtime/karura/src/weights/module_homa_lite.rs index 35ffc6419..300ec0565 100644 --- a/runtime/karura/src/weights/module_homa_lite.rs +++ b/runtime/karura/src/weights/module_homa_lite.rs @@ -19,7 +19,7 @@ //! Autogenerated weights for module_homa_lite //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2021-10-28, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2021-11-01, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` //! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("karura-dev"), DB CACHE: 128 // Executed Command: @@ -28,7 +28,7 @@ // --chain=karura-dev // --steps=50 // --repeat=20 -// --pallet=module_homa_lite +// --pallet=module-homa-lite // --extrinsic=* // --execution=wasm // --wasm-execution=compiled @@ -47,55 +47,60 @@ use sp_std::marker::PhantomData; /// Weight functions for module_homa_lite. pub struct WeightInfo(PhantomData); impl module_homa_lite::WeightInfo for WeightInfo { - fn on_idle() -> Weight { - (87_670_000 as Weight) - .saturating_add(T::DbWeight::get().reads(11 as Weight)) - .saturating_add(T::DbWeight::get().writes(4 as Weight)) - } fn mint() -> Weight { - (305_852_000 as Weight) + (144_000_000 as Weight) .saturating_add(T::DbWeight::get().reads(17 as Weight)) .saturating_add(T::DbWeight::get().writes(8 as Weight)) } fn mint_for_requests() -> Weight { - (317_863_000 as Weight) + (153_000_000 as Weight) .saturating_add(T::DbWeight::get().reads(19 as Weight)) .saturating_add(T::DbWeight::get().writes(8 as Weight)) } fn set_total_staking_currency() -> Weight { - (19_766_000 as Weight) + (10_000_000 as Weight) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn adjust_total_staking_currency() -> Weight { - (22_106_000 as Weight) + (12_000_000 as Weight) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn adjust_available_staking_balance() -> Weight { - (31_653_000 as Weight) - .saturating_add(T::DbWeight::get().reads(2 as Weight)) + fn adjust_available_staking_balance_with_no_matches() -> Weight { + (12_000_000 as Weight) + .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn set_minting_cap() -> Weight { - (20_231_000 as Weight) + (11_000_000 as Weight) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn set_xcm_dest_weight() -> Weight { - (19_320_000 as Weight) + (10_000_000 as Weight) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn request_redeem() -> Weight { - (154_292_000 as Weight) + (81_000_000 as Weight) .saturating_add(T::DbWeight::get().reads(7 as Weight)) .saturating_add(T::DbWeight::get().writes(4 as Weight)) } fn schedule_unbond() -> Weight { - (24_274_000 as Weight) + (12_000_000 as Weight) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn replace_schedule_unbond() -> Weight { - (20_799_000 as Weight) + (11_000_000 as Weight) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } + fn redeem_with_available_staking_balance() -> Weight { + (6_000_000 as Weight) + .saturating_add(T::DbWeight::get().reads(2 as Weight)) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) + } + fn xcm_unbond() -> Weight { + (34_000_000 as Weight) + .saturating_add(T::DbWeight::get().reads(8 as Weight)) + .saturating_add(T::DbWeight::get().writes(3 as Weight)) + } } diff --git a/runtime/mandala/src/weights/module_homa_lite.rs b/runtime/mandala/src/weights/module_homa_lite.rs index 25221c932..ec32809a0 100644 --- a/runtime/mandala/src/weights/module_homa_lite.rs +++ b/runtime/mandala/src/weights/module_homa_lite.rs @@ -47,11 +47,6 @@ use sp_std::marker::PhantomData; /// Weight functions for module_homa_lite. pub struct WeightInfo(PhantomData); impl module_homa_lite::WeightInfo for WeightInfo { - fn on_idle() -> Weight { - (258_000_000 as Weight) - .saturating_add(T::DbWeight::get().reads(23 as Weight)) - .saturating_add(T::DbWeight::get().writes(17 as Weight)) - } fn mint() -> Weight { (137_000_000 as Weight) .saturating_add(T::DbWeight::get().reads(14 as Weight)) @@ -71,7 +66,7 @@ impl module_homa_lite::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn adjust_available_staking_balance() -> Weight { + fn adjust_available_staking_balance_with_no_matches() -> Weight { (18_000_000 as Weight) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) @@ -98,4 +93,12 @@ impl module_homa_lite::WeightInfo for WeightInfo { (11_000_000 as Weight) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } + fn redeem_with_available_staking_balance() -> Weight { + (21_316_000 as Weight) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) + } + fn xcm_unbond() -> Weight { + (21_316_000 as Weight) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) + } } From 8abf2695ae4891ce12ade0fd18cd74cd915c545f Mon Sep 17 00:00:00 2001 From: Roy Yang Date: Mon, 1 Nov 2021 18:00:57 +1300 Subject: [PATCH 13/13] Replaced a .unwrap() with unwrap_or_default for safety. Minor update to the comments and documentation --- modules/homa-lite/src/lib.rs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/modules/homa-lite/src/lib.rs b/modules/homa-lite/src/lib.rs index 79a0e02ac..aed883110 100644 --- a/modules/homa-lite/src/lib.rs +++ b/modules/homa-lite/src/lib.rs @@ -281,7 +281,8 @@ pub mod module { debug_assert!(res.is_ok()); if res.is_ok() { current_weight = current_weight.saturating_add( - ::WeightInfo::redeem_with_available_staking_balance().saturating_mul(res.unwrap()), + ::WeightInfo::redeem_with_available_staking_balance() + .saturating_mul(res.unwrap_or_default()), ); } @@ -596,6 +597,9 @@ pub mod module { /// Parameters: /// - `adjustment`: The difference in amount the AvailableStakingBalance should be adjusted /// by. + /// + /// Weight: Weight(xcm unbond) + n * Weight(match redeem requests), where n is number of + /// redeem requests matched. #[pallet::weight( < T as Config >::WeightInfo::adjust_available_staking_balance_with_no_matches().saturating_add( max_num_matches.saturating_mul(< T as Config >::WeightInfo::redeem_with_available_staking_balance()) @@ -842,6 +846,9 @@ pub mod module { /// Construct XCM message and sent it to the relaychain to withdraw_unbonded Staking /// currency. The staking currency withdrew becomes available to be redeemed. + /// + /// params: + /// - `staking_amount_unbonded`: amount of staking currency to withdraw unbond via XCM #[transactional] pub fn process_scheduled_unbond(staking_amount_unbonded: Balance) -> DispatchResult { let msg = Self::construct_xcm_unreserve_message(T::ParachainAccount::get(), staking_amount_unbonded); @@ -861,6 +868,12 @@ pub mod module { /// Iterate through all redeem requests, then match them with available_staking_balance. /// This should be called when new available_staking_balance becomes available. + /// + /// params: + /// - `max_num_matches`: Maximum number of redeem requests to be matched. + /// + /// return: + /// Result: The number of redeem reqeusts actually matched. #[transactional] pub fn process_redeem_requests_with_available_staking_balance( max_num_matches: u64,