From 713103b8dde0154590b5fa02a0784f32a0858f49 Mon Sep 17 00:00:00 2001 From: Edwin Wang Date: Mon, 4 Sep 2023 16:12:43 +0800 Subject: [PATCH 1/9] Bifrost v0.9.82 --- .github/workflows/release.yml | 2 +- .github/workflows/srtool.yml | 1 - Cargo.lock | 2 +- node/cli/Cargo.toml | 2 +- runtime/bifrost-kusama/src/lib.rs | 2 +- runtime/bifrost-polkadot/src/lib.rs | 2 +- 6 files changed, 5 insertions(+), 6 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d667f1e2c..0455a10b4 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,7 +1,7 @@ name: Release env: - SUBWASM_VERSION: 0.19.0 + SUBWASM_VERSION: 0.20.0 on: push: diff --git a/.github/workflows/srtool.yml b/.github/workflows/srtool.yml index 541a077b7..7976710d5 100644 --- a/.github/workflows/srtool.yml +++ b/.github/workflows/srtool.yml @@ -31,7 +31,6 @@ jobs: with: chain: ${{ matrix.chain }} runtime_dir: runtime/${{ matrix.chain }} - tag: 1.66.1 - name: Summary run: | echo '${{ steps.srtool_build.outputs.json }}' | jq > ${{ matrix.chain }}-srtool-digest.json diff --git a/Cargo.lock b/Cargo.lock index f20b2e1d8..622546d2a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6489,7 +6489,7 @@ dependencies = [ [[package]] name = "node-cli" -version = "0.9.80" +version = "0.9.82" dependencies = [ "clap", "cumulus-client-cli", diff --git a/node/cli/Cargo.toml b/node/cli/Cargo.toml index 518a547b3..b0e4fa052 100644 --- a/node/cli/Cargo.toml +++ b/node/cli/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "node-cli" -version = "0.9.80" +version = "0.9.82" authors = ["Liebi Technologies "] description = "Bifrost Parachain Node" build = "build.rs" diff --git a/runtime/bifrost-kusama/src/lib.rs b/runtime/bifrost-kusama/src/lib.rs index f0bec2ffe..f5035dfab 100644 --- a/runtime/bifrost-kusama/src/lib.rs +++ b/runtime/bifrost-kusama/src/lib.rs @@ -133,7 +133,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("bifrost"), impl_name: create_runtime_str!("bifrost"), authoring_version: 1, - spec_version: 980, + spec_version: 982, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 1, diff --git a/runtime/bifrost-polkadot/src/lib.rs b/runtime/bifrost-polkadot/src/lib.rs index 58cdd5808..7fd1f0d4e 100644 --- a/runtime/bifrost-polkadot/src/lib.rs +++ b/runtime/bifrost-polkadot/src/lib.rs @@ -133,7 +133,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("bifrost_polkadot"), impl_name: create_runtime_str!("bifrost_polkadot"), authoring_version: 0, - spec_version: 980, + spec_version: 982, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 1, From 73af1b5ffc04cf50fe97149e303d8028128f211a Mon Sep 17 00:00:00 2001 From: Edwin Date: Wed, 6 Sep 2023 10:58:02 +0800 Subject: [PATCH 2/9] Vtoken voting test (#1031) * More tests * More tests * Rename `DelegatorTokenUnlockNotified` to `DelegatorVoteRemovedNotified` * Fix * More tests * More tests --- pallets/vtoken-voting/src/lib.rs | 11 +- pallets/vtoken-voting/src/mock.rs | 24 +- pallets/vtoken-voting/src/tests.rs | 383 ++++++++++++++++++++++++++++- 3 files changed, 404 insertions(+), 14 deletions(-) diff --git a/pallets/vtoken-voting/src/lib.rs b/pallets/vtoken-voting/src/lib.rs index 8a09d8173..0e9835054 100644 --- a/pallets/vtoken-voting/src/lib.rs +++ b/pallets/vtoken-voting/src/lib.rs @@ -175,7 +175,7 @@ pub mod pallet { poll_index: PollIndex, success: bool, }, - DelegatorTokenUnlockNotified { + DelegatorVoteRemovedNotified { vtoken: CurrencyIdOf, poll_index: PollIndex, success: bool, @@ -696,7 +696,7 @@ pub mod pallet { }, )?; } - Self::deposit_event(Event::::DelegatorTokenUnlockNotified { + Self::deposit_event(Event::::DelegatorVoteRemovedNotified { vtoken, poll_index, success, @@ -977,9 +977,14 @@ pub mod pallet { Some(ReferendumInfo::Completed(moment)) => { let locking_period = VoteLockingPeriod::::get(vtoken).ok_or(Error::::NoData)?; + ensure!( + T::RelaychainBlockNumberProvider::current_block_number() >= + moment.saturating_add(locking_period), + Error::::NotExpired + ); Ok(moment.saturating_add(locking_period)) }, - _ => Err(Error::::NotCompleted.into()), + _ => Err(Error::::NotExpired.into()), } } diff --git a/pallets/vtoken-voting/src/mock.rs b/pallets/vtoken-voting/src/mock.rs index c0100b08b..cef7c8516 100644 --- a/pallets/vtoken-voting/src/mock.rs +++ b/pallets/vtoken-voting/src/mock.rs @@ -39,7 +39,7 @@ use pallet_xcm::EnsureResponse; use sp_core::H256; use sp_runtime::{ testing::Header, - traits::{BlakeTwo256, ConstU32, IdentityLookup}, + traits::{BlakeTwo256, BlockNumberProvider, ConstU32, IdentityLookup}, }; use xcm::{prelude::*, v3::Weight as XcmWeight}; use xcm_builder::FixedWeightBounds; @@ -274,6 +274,26 @@ impl DerivativeAccountHandler for DerivativeAccount { } } +parameter_types! { + pub static RelaychainBlockNumber: BlockNumber = 1; +} + +pub struct RelaychainDataProvider; + +impl RelaychainDataProvider { + pub fn set_block_number(block: BlockNumber) { + RelaychainBlockNumber::set(block); + } +} + +impl BlockNumberProvider for RelaychainDataProvider { + type BlockNumber = BlockNumber; + + fn current_block_number() -> Self::BlockNumber { + RelaychainBlockNumber::get() + } +} + impl vtoken_voting::Config for Runtime { type RuntimeEvent = RuntimeEvent; type RuntimeOrigin = RuntimeOrigin; @@ -283,7 +303,7 @@ impl vtoken_voting::Config for Runtime { type ResponseOrigin = EnsureResponse; type XcmDestWeightAndFee = XcmDestWeightAndFee; type DerivativeAccount = DerivativeAccount; - type RelaychainBlockNumberProvider = System; + type RelaychainBlockNumberProvider = RelaychainDataProvider; type MaxVotes = ConstU32<3>; type ParachainId = ParachainId; type QueryTimeout = QueryTimeout; diff --git a/pallets/vtoken-voting/src/tests.rs b/pallets/vtoken-voting/src/tests.rs index 4ff5444d7..109e81998 100644 --- a/pallets/vtoken-voting/src/tests.rs +++ b/pallets/vtoken-voting/src/tests.rs @@ -71,6 +71,10 @@ fn response_success() -> Response { Response::DispatchResult(MaybeErrorCode::Success) } +fn response_fail() -> Response { + Response::DispatchResult(MaybeErrorCode::Error(BoundedVec::try_from(vec![0u8, 1u8]).unwrap())) +} + #[test] fn basic_voting_works() { new_test_ext().execute_with(|| { @@ -412,7 +416,7 @@ fn lock_amalgamation_valid_with_multiple_removed_votes() { } #[test] -fn errors_with_vote_work() { +fn errors_with_vote_works() { new_test_ext().execute_with(|| { let vtoken = VKSM; @@ -435,13 +439,213 @@ fn errors_with_vote_work() { }); } +#[test] +fn kill_referendum_works() { + new_test_ext().execute_with(|| { + let vtoken = VKSM; + let poll_index = 3; + + assert_ok!(VtokenVoting::vote(RuntimeOrigin::signed(ALICE), vtoken, poll_index, aye(5, 1))); + assert_ok!(VtokenVoting::set_referendum_status( + RuntimeOrigin::signed(CONTROLLER), + vtoken, + poll_index, + ReferendumInfoOf::::Completed(1), + )); + assert_ok!(VtokenVoting::kill_referendum( + RuntimeOrigin::signed(CONTROLLER), + vtoken, + poll_index + )); + System::assert_last_event(RuntimeEvent::VtokenVoting(Event::ReferendumKilled { + vtoken, + poll_index, + })); + }); +} + +#[test] +fn kill_referendum_with_origin_signed_fails() { + new_test_ext().execute_with(|| { + let vtoken = VKSM; + let poll_index = 3; + + assert_ok!(VtokenVoting::vote(RuntimeOrigin::signed(ALICE), vtoken, poll_index, aye(5, 1))); + assert_ok!(VtokenVoting::set_referendum_status( + RuntimeOrigin::signed(CONTROLLER), + vtoken, + poll_index, + ReferendumInfoOf::::Completed(1), + )); + assert_noop!( + VtokenVoting::kill_referendum(RuntimeOrigin::signed(ALICE), vtoken, poll_index), + DispatchError::BadOrigin + ); + }); +} + +#[test] +fn set_delegator_role_works() { + new_test_ext().execute_with(|| { + let vtoken = VKSM; + let derivative_index: DerivativeIndex = 100; + let role = aye(10, 3).into(); + + assert_ok!(VtokenVoting::set_delegator_role( + RuntimeOrigin::signed(CONTROLLER), + vtoken, + derivative_index, + role, + )); + + System::assert_last_event(RuntimeEvent::VtokenVoting(Event::DelegatorRoleSet { + vtoken, + role, + derivative_index, + })); + }); +} + +#[test] +fn set_referendum_status_works() { + new_test_ext().execute_with(|| { + let poll_index = 3; + let vtoken = VKSM; + let info = ReferendumInfo::Completed(3); + + assert_ok!(VtokenVoting::vote(RuntimeOrigin::signed(ALICE), vtoken, poll_index, aye(2, 5))); + assert_ok!(VtokenVoting::set_referendum_status( + RuntimeOrigin::signed(CONTROLLER), + vtoken, + poll_index, + info.clone(), + )); + + System::assert_last_event(RuntimeEvent::VtokenVoting(Event::ReferendumInfoSet { + vtoken, + poll_index, + info, + })); + }); +} + +#[test] +fn set_referendum_status_without_vote_should_fail() { + new_test_ext().execute_with(|| { + let poll_index = 3; + let vtoken = VKSM; + let info = ReferendumInfo::Completed(3); + + assert_noop!( + VtokenVoting::set_referendum_status( + RuntimeOrigin::signed(CONTROLLER), + vtoken, + poll_index, + info.clone(), + ), + Error::::NoData + ); + }); +} + +#[test] +fn set_referendum_status_with_origin_signed_should_fail() { + new_test_ext().execute_with(|| { + let poll_index = 3; + let vtoken = VKSM; + let info = ReferendumInfo::Completed(3); + + assert_noop!( + VtokenVoting::set_referendum_status( + RuntimeOrigin::signed(ALICE), + vtoken, + poll_index, + info.clone(), + ), + DispatchError::BadOrigin + ); + }); +} + +#[test] +fn set_vote_locking_period_works() { + new_test_ext().execute_with(|| { + let vtoken = VKSM; + let locking_period = 100; + + assert_ok!(VtokenVoting::set_vote_locking_period( + RuntimeOrigin::signed(CONTROLLER), + vtoken, + locking_period, + )); + + System::assert_last_event(RuntimeEvent::VtokenVoting(Event::VoteLockingPeriodSet { + vtoken, + locking_period, + })); + }); +} + +#[test] +fn set_vote_locking_period_with_origin_signed_should_fail() { + new_test_ext().execute_with(|| { + let vtoken = VKSM; + let locking_period = 100; + + assert_noop!( + VtokenVoting::set_vote_locking_period( + RuntimeOrigin::signed(ALICE), + vtoken, + locking_period, + ), + DispatchError::BadOrigin + ); + }); +} + +#[test] +fn set_undeciding_timeout_works() { + new_test_ext().execute_with(|| { + let vtoken = VKSM; + let undeciding_timeout = 100; + + assert_ok!(VtokenVoting::set_undeciding_timeout( + RuntimeOrigin::signed(CONTROLLER), + vtoken, + undeciding_timeout, + )); + + System::assert_last_event(RuntimeEvent::VtokenVoting(Event::UndecidingTimeoutSet { + vtoken, + undeciding_timeout, + })); + }); +} + +#[test] +fn set_undeciding_timeout_with_origin_signed_should_fail() { + new_test_ext().execute_with(|| { + let vtoken = VKSM; + let undeciding_timeout = 100; + + assert_noop!( + VtokenVoting::set_undeciding_timeout( + RuntimeOrigin::signed(ALICE), + vtoken, + undeciding_timeout, + ), + DispatchError::BadOrigin + ); + }); +} + #[test] fn notify_vote_success_works() { new_test_ext().execute_with(|| { let poll_index = 3; let vtoken = VKSM; let query_id = 0; - let response = Response::DispatchResult(MaybeErrorCode::Success); + let response = response_success(); assert_ok!(VtokenVoting::vote(RuntimeOrigin::signed(ALICE), vtoken, poll_index, aye(2, 5))); assert_eq!(tally(vtoken, poll_index), Tally::from_parts(10, 0, 2)); @@ -452,7 +656,25 @@ fn notify_vote_success_works() { vote: aye(2, 5), })); - assert_ok!(VtokenVoting::notify_vote(origin_response(), query_id, response)); + assert_ok!(VtokenVoting::notify_vote(origin_response(), query_id, response.clone())); + System::assert_has_event(RuntimeEvent::VtokenVoting(Event::VoteNotified { + vtoken, + poll_index, + success: true, + })); + System::assert_has_event(RuntimeEvent::VtokenVoting(Event::ReferendumInfoCreated { + vtoken, + poll_index, + info: ReferendumInfo::Ongoing(ReferendumStatus { + submitted: Some(1), + tally: TallyOf::::from_parts(10, 0, 2), + }), + })); + System::assert_last_event(RuntimeEvent::VtokenVoting(Event::ResponseReceived { + responder: Parent.into(), + query_id, + response, + })); }); } @@ -462,9 +684,7 @@ fn notify_vote_fail_works() { let poll_index = 3; let vtoken = VKSM; let query_id = 0; - let response = Response::DispatchResult(MaybeErrorCode::Error( - BoundedVec::try_from(vec![0u8, 1u8]).unwrap(), - )); + let response = response_fail(); assert_ok!(VtokenVoting::vote(RuntimeOrigin::signed(ALICE), vtoken, poll_index, aye(2, 5))); assert_eq!(tally(vtoken, poll_index), Tally::from_parts(10, 0, 2)); @@ -475,7 +695,17 @@ fn notify_vote_fail_works() { vote: aye(2, 5), })); - assert_ok!(VtokenVoting::notify_vote(origin_response(), query_id, response)); + assert_ok!(VtokenVoting::notify_vote(origin_response(), query_id, response.clone())); + System::assert_has_event(RuntimeEvent::VtokenVoting(Event::VoteNotified { + vtoken, + poll_index, + success: false, + })); + System::assert_last_event(RuntimeEvent::VtokenVoting(Event::ResponseReceived { + responder: Parent.into(), + query_id, + response, + })); }); } @@ -483,8 +713,143 @@ fn notify_vote_fail_works() { fn notify_vote_with_no_data_works() { new_test_ext().execute_with(|| { let query_id = 0; - let response = Response::DispatchResult(MaybeErrorCode::Success); + let response = response_success(); + + assert_ok!(VtokenVoting::notify_vote(origin_response(), query_id, response.clone())); + System::assert_last_event(RuntimeEvent::VtokenVoting(Event::ResponseReceived { + responder: Parent.into(), + query_id, + response, + })); + }); +} + +#[test] +fn notify_remove_delegator_vote_success_works() { + new_test_ext().execute_with(|| { + let poll_index = 3; + let vtoken = VKSM; + let mut query_id = 0; + let derivative_index = 3; + let response = response_success(); - assert_ok!(VtokenVoting::notify_vote(origin_response(), query_id, response)); + assert_ok!(VtokenVoting::vote(RuntimeOrigin::signed(ALICE), vtoken, poll_index, aye(2, 5))); + assert_eq!(tally(vtoken, poll_index), Tally::from_parts(10, 0, 2)); + System::assert_last_event(RuntimeEvent::VtokenVoting(Event::Voted { + who: ALICE, + vtoken, + poll_index, + vote: aye(2, 5), + })); + assert_ok!(VtokenVoting::notify_vote(origin_response(), query_id, response.clone())); + + assert_ok!(VtokenVoting::set_referendum_status( + RuntimeOrigin::signed(CONTROLLER), + vtoken, + poll_index, + ReferendumInfoOf::::Completed(3), + )); + assert_ok!(VtokenVoting::set_vote_locking_period( + RuntimeOrigin::signed(CONTROLLER), + vtoken, + 10, + )); + + RelaychainDataProvider::set_block_number(15); + assert_ok!(VtokenVoting::remove_delegator_vote( + RuntimeOrigin::signed(ALICE), + vtoken, + poll_index, + derivative_index, + )); + + query_id = 1; + assert_ok!(VtokenVoting::notify_remove_delegator_vote( + origin_response(), + query_id, + response.clone() + )); + System::assert_has_event(RuntimeEvent::VtokenVoting(Event::DelegatorVoteRemovedNotified { + vtoken, + poll_index, + success: true, + })); + System::assert_last_event(RuntimeEvent::VtokenVoting(Event::ResponseReceived { + responder: Parent.into(), + query_id, + response, + })); + }); +} + +#[test] +fn notify_remove_delegator_vote_fail_works() { + new_test_ext().execute_with(|| { + let poll_index = 3; + let vtoken = VKSM; + let mut query_id = 0; + let derivative_index = 3; + let response = response_fail(); + + assert_ok!(VtokenVoting::vote(RuntimeOrigin::signed(ALICE), vtoken, poll_index, aye(2, 5))); + assert_eq!(tally(vtoken, poll_index), Tally::from_parts(10, 0, 2)); + System::assert_last_event(RuntimeEvent::VtokenVoting(Event::Voted { + who: ALICE, + vtoken, + poll_index, + vote: aye(2, 5), + })); + assert_ok!(VtokenVoting::notify_vote(origin_response(), query_id, response_success())); + + assert_ok!(VtokenVoting::set_referendum_status( + RuntimeOrigin::signed(CONTROLLER), + vtoken, + poll_index, + ReferendumInfoOf::::Completed(3), + )); + assert_ok!(VtokenVoting::set_vote_locking_period( + RuntimeOrigin::signed(CONTROLLER), + vtoken, + 10, + )); + + RelaychainDataProvider::set_block_number(15); + assert_ok!(VtokenVoting::remove_delegator_vote( + RuntimeOrigin::signed(ALICE), + vtoken, + poll_index, + derivative_index, + )); + + query_id = 1; + assert_ok!(VtokenVoting::notify_remove_delegator_vote( + origin_response(), + query_id, + response.clone() + )); + System::assert_last_event(RuntimeEvent::VtokenVoting(Event::ResponseReceived { + responder: Parent.into(), + query_id, + response, + })); + }); +} + +#[test] +fn notify_remove_delegator_vote_with_no_data_works() { + new_test_ext().execute_with(|| { + let query_id = 0; + let response = response_success(); + + assert_ok!(VtokenVoting::notify_remove_delegator_vote( + origin_response(), + query_id, + response.clone(), + )); + System::assert_last_event(RuntimeEvent::VtokenVoting(Event::ResponseReceived { + responder: Parent.into(), + query_id, + response, + })); }); } From 0f7349cfc933b658664352ecea58f027658c4f8f Mon Sep 17 00:00:00 2001 From: Herry Ho <45537372+herryho@users.noreply.github.com> Date: Wed, 6 Sep 2023 17:52:50 +0800 Subject: [PATCH 3/9] Flexible fee with extra fee (#1032) * move xcmweightandfee storage out * move out xcmweightandfee storage to xcminterface pallet * put XcmInterfaceOperation to node primitives * finish flexible fee rpc and withdraw_fee logic * polkadot runtime changes * runtime fixes * fix rpc * fixes * fix tests * resolve conflicts with vtoken-voting * fix integration tests * format --- Cargo.lock | 1 + integration-tests/bifrost-kusama/src/slp.rs | 6 +- .../bifrost-kusama/src/statemine.rs | 8 + .../bifrost-kusama/src/vtoken_voting.rs | 4 +- node/primitives/src/lib.rs | 45 ++++ node/primitives/src/traits.rs | 48 ++++- pallets/fee-share/src/mock.rs | 1 + .../flexible-fee/rpc/runtime-api/src/lib.rs | 2 +- pallets/flexible-fee/rpc/src/lib.rs | 4 +- pallets/flexible-fee/src/lib.rs | 198 ++++++++++++------ pallets/flexible-fee/src/misc_fees.rs | 110 ---------- pallets/flexible-fee/src/mock.rs | 97 ++++----- pallets/flexible-fee/src/tests.rs | 33 +-- pallets/slp/src/agents/astar_agent/agent.rs | 21 +- pallets/slp/src/agents/common.rs | 13 +- .../slp/src/agents/moonbeam_agent/agent.rs | 19 +- pallets/slp/src/agents/phala_agent/agent.rs | 16 +- .../slp/src/agents/polkadot_agent/agent.rs | 22 +- pallets/slp/src/lib.rs | 27 +-- pallets/slp/src/mocks/mock.rs | 1 + pallets/slp/src/mocks/mock_kusama.rs | 1 + pallets/slp/src/primitives/mod.rs | 25 --- pallets/slp/src/tests/kusama_tests.rs | 30 --- pallets/slpx/src/mock.rs | 1 + pallets/system-maker/src/mock.rs | 1 + pallets/system-staking/src/mock.rs | 1 + pallets/ve-minting/src/mock.rs | 1 + pallets/vtoken-minting/src/mock.rs | 1 + pallets/vtoken-voting/src/lib.rs | 11 +- pallets/vtoken-voting/src/mock.rs | 25 ++- pallets/vtoken-voting/src/traits.rs | 8 +- pallets/xcm-interface/Cargo.toml | 18 +- pallets/xcm-interface/src/lib.rs | 133 +++++++----- runtime/bifrost-kusama/src/lib.rs | 130 ++++-------- runtime/bifrost-kusama/src/migration.rs | 126 +++++++++++ runtime/bifrost-kusama/src/xcm_config.rs | 9 +- runtime/bifrost-polkadot/src/lib.rs | 130 ++++-------- runtime/bifrost-polkadot/src/migration.rs | 128 +++++++++++ runtime/bifrost-polkadot/src/xcm_config.rs | 8 - 39 files changed, 824 insertions(+), 639 deletions(-) delete mode 100644 pallets/flexible-fee/src/misc_fees.rs create mode 100644 runtime/bifrost-kusama/src/migration.rs create mode 100644 runtime/bifrost-polkadot/src/migration.rs diff --git a/Cargo.lock b/Cargo.lock index 622546d2a..c59217f2b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -15384,6 +15384,7 @@ dependencies = [ "frame-benchmarking", "frame-support", "frame-system", + "node-primitives", "orml-traits", "pallet-balances", "pallet-xcm", diff --git a/integration-tests/bifrost-kusama/src/slp.rs b/integration-tests/bifrost-kusama/src/slp.rs index 637eb5556..f4d697187 100644 --- a/integration-tests/bifrost-kusama/src/slp.rs +++ b/integration-tests/bifrost-kusama/src/slp.rs @@ -81,11 +81,9 @@ delegate/undelegate/redelegate confirm_validators_by_delegator_query_response #![cfg(test)] use bifrost_kusama_runtime::{NativeCurrencyId, VtokenMinting}; -use bifrost_slp::{ - primitives::UnlockChunk, Delays, Ledger, MinimumsMaximums, SubstrateLedger, XcmOperation, -}; +use bifrost_slp::{primitives::UnlockChunk, Delays, Ledger, MinimumsMaximums, SubstrateLedger}; use frame_support::{assert_ok, BoundedVec}; -use node_primitives::TimeUnit; +use node_primitives::{TimeUnit, XcmInterfaceOperation as XcmOperation}; use orml_traits::MultiCurrency; use pallet_staking::{Nominations, StakingLedger}; use sp_runtime::Permill; diff --git a/integration-tests/bifrost-kusama/src/statemine.rs b/integration-tests/bifrost-kusama/src/statemine.rs index 095dcb72a..7d122bf30 100644 --- a/integration-tests/bifrost-kusama/src/statemine.rs +++ b/integration-tests/bifrost-kusama/src/statemine.rs @@ -19,6 +19,7 @@ use crate::{kusama_integration_tests::*, kusama_test_net::*}; use bifrost_asset_registry::AssetMetadata; use frame_support::assert_ok; +use node_primitives::XcmInterfaceOperation as XcmOperation; use polkadot_parachain::primitives::Sibling; use sp_runtime::traits::AccountIdConversion; use xcm::{ @@ -130,6 +131,13 @@ fn cross_usdt() { &sp_runtime::AccountId32::from(ALICE), 10 * USDT )); + + assert_ok!(XcmInterface::set_xcm_dest_weight_and_fee( + RelayCurrencyId::get(), + XcmOperation::StatemineTransfer, + Some((Weight::from_parts(10000000000, 1000000), 10_000_000_000)), + )); + assert_ok!(XcmInterface::transfer_statemine_assets( RuntimeOrigin::signed(ALICE.into()), 5 * USDT, diff --git a/integration-tests/bifrost-kusama/src/vtoken_voting.rs b/integration-tests/bifrost-kusama/src/vtoken_voting.rs index 326487ff4..878bf57ff 100644 --- a/integration-tests/bifrost-kusama/src/vtoken_voting.rs +++ b/integration-tests/bifrost-kusama/src/vtoken_voting.rs @@ -25,7 +25,7 @@ use frame_support::{ traits::{schedule::DispatchTime, StorePreimage}, weights::Weight, }; -use node_primitives::currency::VKSM; +use node_primitives::{currency::VKSM, XcmInterfaceOperation as XcmOperation}; use pallet_conviction_voting::{Conviction, Vote}; use xcm::v3::Parent; use xcm_emulator::TestExt; @@ -70,7 +70,7 @@ fn vote_works() { assert_ok!(Slp::set_xcm_dest_weight_and_fee( RuntimeOrigin::root(), token, - bifrost_slp::XcmOperation::Vote, + XcmOperation::VoteVtoken, Some((Weight::from_parts(4000000000, 100000), 4000000000u32.into())), )); assert_ok!(Slp::set_minimums_and_maximums( diff --git a/node/primitives/src/lib.rs b/node/primitives/src/lib.rs index 5984022e7..f74a23b72 100644 --- a/node/primitives/src/lib.rs +++ b/node/primitives/src/lib.rs @@ -142,6 +142,8 @@ pub type DistributionId = u32; pub enum ExtraFeeName { SalpContribute, StatemineTransfer, + VoteVtoken, + VoteRemoveDelegatorVote, NoExtraFee, } @@ -236,3 +238,46 @@ impl SendXcm for DoNothingRouter { Ok([0; 32]) } } + +#[derive(Encode, Decode, Eq, PartialEq, Copy, Clone, RuntimeDebug, TypeInfo)] +pub enum XcmInterfaceOperation { + // SALP operations + UmpContributeTransact, + // Statemine operations + StatemineTransfer, + // SLP operations + Bond, + WithdrawUnbonded, + BondExtra, + Unbond, + Rebond, + Delegate, + Payout, + Liquidize, + TransferBack, + TransferTo, + Chill, + Undelegate, + CancelLeave, + XtokensTransferBack, + ExecuteLeave, + ConvertAsset, + // VtokenVoting operations + VoteVtoken, + VoteRemoveDelegatorVote, + Any, +} + +pub struct ExtraFeeInfo { + pub extra_fee_name: ExtraFeeName, + pub extra_fee_currency: CurrencyId, +} + +impl Default for ExtraFeeInfo { + fn default() -> Self { + Self { + extra_fee_name: ExtraFeeName::NoExtraFee, + extra_fee_currency: CurrencyId::Native(TokenSymbol::BNC), + } + } +} diff --git a/node/primitives/src/traits.rs b/node/primitives/src/traits.rs index 52482d991..00b2dafd6 100644 --- a/node/primitives/src/traits.rs +++ b/node/primitives/src/traits.rs @@ -20,10 +20,14 @@ #![allow(clippy::unnecessary_cast)] +use crate::{ + AssetIds, ExtraFeeInfo, LeasePeriod, ParaId, PoolId, RedeemType, TokenId, TokenSymbol, + XcmInterfaceOperation, +}; use codec::{Decode, Encode, FullCodec}; use frame_support::{ dispatch::DispatchError, - pallet_prelude::DispatchResultWithPostInfo, + pallet_prelude::{DispatchResultWithPostInfo, Weight}, sp_runtime::{traits::AccountIdConversion, TokenError, TypeId}, }; use sp_runtime::{ @@ -32,8 +36,6 @@ use sp_runtime::{ }; use sp_std::{fmt::Debug, vec::Vec}; -use crate::{AssetIds, LeasePeriod, ParaId, PoolId, RedeemType, TokenId, TokenSymbol}; - pub trait TokenInfo { fn currency_id(&self) -> u64; fn name(&self) -> Option<&str>; @@ -421,3 +423,43 @@ pub trait TryConvertFrom { where Self: Sized; } + +pub trait XcmDestWeightAndFeeHandler +where + Balance: AtLeast32BitUnsigned, +{ + fn get_operation_weight_and_fee( + token: CurrencyId, + operation: XcmInterfaceOperation, + ) -> Option<(Weight, Balance)>; + + fn set_xcm_dest_weight_and_fee( + currency_id: CurrencyId, + operation: XcmInterfaceOperation, + weight_and_fee: Option<(Weight, Balance)>, + ) -> DispatchResult; +} + +impl XcmDestWeightAndFeeHandler for () +where + Balance: AtLeast32BitUnsigned, +{ + fn get_operation_weight_and_fee( + _token: CurrencyId, + _operation: XcmInterfaceOperation, + ) -> Option<(Weight, Balance)> { + Some((Zero::zero(), Zero::zero())) + } + + fn set_xcm_dest_weight_and_fee( + _currency_id: CurrencyId, + _operation: XcmInterfaceOperation, + _weight_and_fee: Option<(Weight, Balance)>, + ) -> DispatchResult { + Ok(()) + } +} + +pub trait FeeGetter { + fn get_fee_info(call: &RuntimeCall) -> ExtraFeeInfo; +} diff --git a/pallets/fee-share/src/mock.rs b/pallets/fee-share/src/mock.rs index bf58cb622..f81d06a2d 100644 --- a/pallets/fee-share/src/mock.rs +++ b/pallets/fee-share/src/mock.rs @@ -314,6 +314,7 @@ impl bifrost_slp::Config for Runtime { type ParachainStaking = (); type XcmTransfer = XTokens; type MaxLengthLimit = MaxLengthLimit; + type XcmWeightAndFeeHandler = (); } parameter_type_with_key! { diff --git a/pallets/flexible-fee/rpc/runtime-api/src/lib.rs b/pallets/flexible-fee/rpc/runtime-api/src/lib.rs index 5252aca99..2ffc4b13a 100644 --- a/pallets/flexible-fee/rpc/runtime-api/src/lib.rs +++ b/pallets/flexible-fee/rpc/runtime-api/src/lib.rs @@ -27,6 +27,6 @@ decl_runtime_apis! { AccountId: Codec, { /// get flexible fee token and amount to be deducted - fn get_fee_token_and_amount(who: AccountId, fee: Balance) -> (CurrencyId, Balance); + fn get_fee_token_and_amount(who: AccountId, fee: Balance, utx: Block::Extrinsic) -> (CurrencyId, Balance); } } diff --git a/pallets/flexible-fee/rpc/src/lib.rs b/pallets/flexible-fee/rpc/src/lib.rs index 831f6eedf..9e4f86a28 100644 --- a/pallets/flexible-fee/rpc/src/lib.rs +++ b/pallets/flexible-fee/rpc/src/lib.rs @@ -107,7 +107,7 @@ where )) })?; - let fee_details = api.query_fee_details(at, uxt, encoded_len).map_err(|e| { + let fee_details = api.query_fee_details(at, uxt.clone(), encoded_len).map_err(|e| { CallError::Custom(ErrorObject::owned( Error::RuntimeError.into(), "Unable to query fee details.", @@ -127,7 +127,7 @@ where } }; - let rs = api.get_fee_token_and_amount(at, who, total_inclusion_fee); + let rs = api.get_fee_token_and_amount(at, who, total_inclusion_fee, uxt); let try_into_rpc_balance = |value: Balance| { value.try_into().map_err(|e| { diff --git a/pallets/flexible-fee/src/lib.rs b/pallets/flexible-fee/src/lib.rs index a28efd73b..1a43f2aa4 100644 --- a/pallets/flexible-fee/src/lib.rs +++ b/pallets/flexible-fee/src/lib.rs @@ -28,11 +28,14 @@ use frame_support::{ }, }; use frame_system::pallet_prelude::*; -use node_primitives::{CurrencyId, ExtraFeeName, TryConvertFrom}; +use node_primitives::{ + traits::{FeeGetter, XcmDestWeightAndFeeHandler}, + CurrencyId, ExtraFeeName, TryConvertFrom, XcmInterfaceOperation, BNC, +}; use orml_traits::MultiCurrency; pub use pallet::*; use pallet_transaction_payment::OnChargeTransaction; -use sp_arithmetic::traits::SaturatedConversion; +use sp_arithmetic::traits::{CheckedAdd, SaturatedConversion}; use sp_runtime::{ traits::{DispatchInfoOf, PostDispatchInfoOf, Saturating, Zero}, transaction_validity::TransactionValidityError, @@ -42,18 +45,17 @@ use sp_std::{vec, vec::Vec}; pub use weights::WeightInfo; use zenlink_protocol::{AssetBalance, AssetId, ExportZenlink}; -use crate::misc_fees::{FeeDeductor, FeeGetter}; - #[cfg(feature = "runtime-benchmarks")] mod benchmarking; pub mod migrations; -pub mod misc_fees; mod mock; mod tests; pub mod weights; #[frame_support::pallet] pub mod pallet { + use node_primitives::XcmDestWeightAndFeeHandler; + use super::*; #[pallet::config] @@ -76,27 +78,10 @@ pub mod pallet { /// Filter if this transaction needs to be deducted extra fee besides basic transaction fee, /// and get the name of the fee type ExtraFeeMatcher: FeeGetter>; - /// In charge of deducting extra fees - type MiscFeeHandler: FeeDeductor< - Self::AccountId, - CurrencyIdOf, - PalletBalanceOf, - CallOf, - >; #[pallet::constant] type TreasuryAccount: Get; - #[pallet::constant] - type NativeCurrencyId: Get>; - - #[pallet::constant] - type AlternativeFeeCurrencyId: Get>; - - /// Alternative Fee currency exchange rate: ?x Fee currency: ?y Native currency - #[pallet::constant] - type AltFeeCurrencyExchangeRate: Get<(u32, u32)>; - #[pallet::constant] type MaxFeeCurrencyOrderListLen: Get; @@ -104,6 +89,8 @@ pub mod pallet { /// The only origin that can set universal fee currency order list type ControlOrigin: EnsureOrigin; + + type XcmWeightAndFeeHandler: XcmDestWeightAndFeeHandler>; } pub type AccountIdOf = ::AccountId; @@ -125,11 +112,13 @@ pub mod pallet { pub enum Event { FlexibleFeeExchanged(CurrencyIdOf, PalletBalanceOf), // token and amount FixedRateFeeExchanged(CurrencyIdOf, PalletBalanceOf), - ExtraFeeDeducted(ExtraFeeName, CurrencyIdOf, PalletBalanceOf), + // [extra_fee_name, currency_id, amount_in, BNC_amount_out] + ExtraFeeDeducted(ExtraFeeName, CurrencyIdOf, PalletBalanceOf, PalletBalanceOf), } /// The current storage version, we set to 2 our new version(after migrate stroage from vec t /// boundedVec). + #[allow(unused)] const STORAGE_VERSION: StorageVersion = StorageVersion::new(2); /// Universal fee currency order list for all users @@ -156,6 +145,8 @@ pub mod pallet { Overflow, ConversionError, WrongListLength, + WeightAndFeeNotExist, + DexFailedToGetAmountInByPath, } #[pallet::call] @@ -226,15 +217,9 @@ impl Pallet { .map_err(|_| DispatchError::Other("Fee calculation Error."))?; if let Some((currency_id, amount_in, amount_out)) = result_option { - if currency_id != T::NativeCurrencyId::get() { - let native_asset_id: AssetId = AssetId::try_convert_from( - T::NativeCurrencyId::get(), - T::ParachainId::get().into(), - ) - .map_err(|_| DispatchError::Other("Conversion Error."))?; - let asset_id: AssetId = - AssetId::try_convert_from(currency_id, T::ParachainId::get().into()) - .map_err(|_| DispatchError::Other("Conversion Error."))?; + if currency_id != BNC { + let native_asset_id = Self::get_currency_asset_id(BNC)?; + let asset_id = Self::get_currency_asset_id(currency_id)?; let path = vec![asset_id, native_asset_id]; T::DexOperator::inner_swap_assets_for_exact_assets( @@ -259,15 +244,81 @@ impl Pallet { pub fn cal_fee_token_and_amount( who: &T::AccountId, fee: PalletBalanceOf, - ) -> Result<(CurrencyIdOf, PalletBalanceOf), DispatchError> { - let result_option = Self::find_out_fee_currency_and_amount(who, fee) - .map_err(|_| DispatchError::Other("Fee calculation Error."))?; - + utx: &CallOf, + ) -> Result<(CurrencyIdOf, PalletBalanceOf), Error> { + let total_fee_info = Self::get_extrinsic_and_extra_fee_total(utx, fee)?; let (currency_id, amount_in, _amount_out) = - result_option.ok_or(DispatchError::Other("Not enough balance for fee."))?; + Self::find_out_fee_currency_and_amount(who, total_fee_info.0) + .map_err(|_| Error::::DexFailedToGetAmountInByPath)? + .ok_or(Error::::DexFailedToGetAmountInByPath)?; Ok((currency_id, amount_in)) } + + pub fn get_extrinsic_and_extra_fee_total( + call: &CallOf, + fee: PalletBalanceOf, + ) -> Result<(PalletBalanceOf, PalletBalanceOf, PalletBalanceOf, Vec), Error> + { + let mut total_fee = fee; + + let native_asset_id = Self::get_currency_asset_id(BNC)?; + // 确定path只有两个元素 + let mut path = vec![native_asset_id, native_asset_id]; + + // See if the this RuntimeCall needs to pay extra fee + let fee_info = T::ExtraFeeMatcher::get_fee_info(call); + if fee_info.extra_fee_name != ExtraFeeName::NoExtraFee { + // if the fee_info.extra_fee_name is not NoExtraFee, it means this RuntimeCall needs to + // pay extra fee + let (currency_id, operation) = match fee_info.extra_fee_name { + ExtraFeeName::SalpContribute => + (fee_info.extra_fee_currency, XcmInterfaceOperation::UmpContributeTransact), + ExtraFeeName::StatemineTransfer => + (fee_info.extra_fee_currency, XcmInterfaceOperation::StatemineTransfer), + ExtraFeeName::VoteVtoken => { + // We define error code 77 for conversion failure error + let fee_currency = fee_info + .extra_fee_currency + .to_token() + .map_err(|_| Error::::ConversionError)?; + (fee_currency, XcmInterfaceOperation::VoteVtoken) + }, + ExtraFeeName::VoteRemoveDelegatorVote => { + // We define error code 77 for conversion failure error + let fee_currency = fee_info + .extra_fee_currency + .to_token() + .map_err(|_| Error::::ConversionError)?; + (fee_currency, XcmInterfaceOperation::VoteRemoveDelegatorVote) + }, + ExtraFeeName::NoExtraFee => + (fee_info.extra_fee_currency, XcmInterfaceOperation::Any), + }; + + // We define error code 55 for WeightAndFeeNotSet error + let (_, fee_value) = + T::XcmWeightAndFeeHandler::get_operation_weight_and_fee(currency_id, operation) + .ok_or(Error::::WeightAndFeeNotExist)?; + + // We define error code 77 for conversion failure error + let asset_id = Self::get_currency_asset_id(currency_id)?; + path = vec![native_asset_id, asset_id]; + + // get the fee currency value in BNC + // we define error code 44 for DexOperator error + let extra_fee_vec = + T::DexOperator::get_amount_in_by_path(fee_value.saturated_into(), &path) + .map_err(|_| Error::::DexFailedToGetAmountInByPath)?; + + let extra_bnc_fee = PalletBalanceOf::::saturated_from(extra_fee_vec[0]); + total_fee = total_fee.checked_add(&extra_bnc_fee).ok_or(Error::::Overflow)?; + + return Ok((total_fee, extra_bnc_fee, fee_value, path)); + } else { + return Ok((total_fee, Zero::zero(), Zero::zero(), path)); + } + } } /// Default implementation for a Currency and an OnUnbalanced handler. @@ -301,11 +352,42 @@ where WithdrawReasons::TRANSACTION_PAYMENT | WithdrawReasons::TIP }; - // Make sure there are enough BNC to be deducted if the user has assets in other form of - // tokens rather than BNC. - Self::ensure_can_charge_fee(who, fee, withdraw_reason) + // See if the this RuntimeCall needs to pay extra fee + let fee_info = T::ExtraFeeMatcher::get_fee_info(&call); + let (total_fee, extra_bnc_fee, fee_value, path) = + Self::get_extrinsic_and_extra_fee_total(call, fee) + .map_err(|_| TransactionValidityError::Invalid(InvalidTransaction::Custom(55)))?; + + // Make sure there are enough BNC(extrinsic fee + extra fee) to be deducted if the user has + // assets in other form of tokens rather than BNC. + Self::ensure_can_charge_fee(who, total_fee, withdraw_reason) .map_err(|_| TransactionValidityError::Invalid(InvalidTransaction::Payment))?; + if fee_info.extra_fee_name != ExtraFeeName::NoExtraFee { + // swap BNC for fee_currency + T::DexOperator::inner_swap_assets_for_exact_assets( + who, + fee_value.saturated_into(), + extra_bnc_fee.saturated_into(), + &path, + who, + ) + .map_err(|_| TransactionValidityError::Invalid(InvalidTransaction::Custom(44)))?; + + // burn fee_currency + T::MultiCurrency::withdraw(fee_info.extra_fee_currency, who, fee_value) + .map_err(|_| TransactionValidityError::Invalid(InvalidTransaction::Payment))?; + + // deposit extra fee deducted event + Self::deposit_event(Event::ExtraFeeDeducted( + fee_info.extra_fee_name, + fee_info.extra_fee_currency, + fee_value, + extra_bnc_fee, + )); + } + + // withdraw normal extrinsic fee let rs = match T::Currency::withdraw( who, fee, @@ -316,21 +398,6 @@ where Err(_msg) => Err(InvalidTransaction::Payment.into()), }; - // See if the this RuntimeCall needs to pay extra fee - let (fee_name, if_extra_fee) = T::ExtraFeeMatcher::get_fee_info(&call); - if if_extra_fee { - // We define 77 as the error of extra fee deduction failure. - let (extra_fee_currency, extra_fee_amount) = - T::MiscFeeHandler::deduct_fee(who, &T::TreasuryAccount::get(), call).map_err( - |_| TransactionValidityError::Invalid(InvalidTransaction::Custom(77u8)), - )?; - Self::deposit_event(Event::ExtraFeeDeducted( - fee_name, - extra_fee_currency, - extra_fee_amount, - )); - } - rs } @@ -384,7 +451,7 @@ impl Pallet { // transaction in the DEX in exchange for BNC for currency_id in user_fee_charge_order_list { // If it is mainnet currency - if currency_id == T::NativeCurrencyId::get() { + if currency_id == BNC { // check native balance if is enough if T::MultiCurrency::ensure_can_withdraw(currency_id, who, fee).is_ok() { // currency, amount_in, amount_out @@ -392,17 +459,13 @@ impl Pallet { } } else { // If it is other assets, go to exchange fee amount. - let native_asset_id: AssetId = AssetId::try_convert_from( - T::NativeCurrencyId::get(), - T::ParachainId::get().into(), - ) - .map_err(|_| Error::::ConversionError)?; + let native_asset_id = + Self::get_currency_asset_id(BNC).map_err(|_| Error::::ConversionError)?; let amount_out: AssetBalance = fee.saturated_into(); - let asset_id: AssetId = - AssetId::try_convert_from(currency_id, T::ParachainId::get().into()) - .map_err(|_| Error::::ConversionError)?; + let asset_id = Self::get_currency_asset_id(currency_id) + .map_err(|_| Error::::ConversionError)?; let path = vec![asset_id, native_asset_id]; // see if path exists, if not, continue. @@ -423,4 +486,11 @@ impl Pallet { } Ok(None) } + + fn get_currency_asset_id(currency_id: CurrencyIdOf) -> Result> { + let asset_id: AssetId = + AssetId::try_convert_from(currency_id, T::ParachainId::get().into()) + .map_err(|_| Error::::ConversionError)?; + Ok(asset_id) + } } diff --git a/pallets/flexible-fee/src/misc_fees.rs b/pallets/flexible-fee/src/misc_fees.rs deleted file mode 100644 index 159fd5fd6..000000000 --- a/pallets/flexible-fee/src/misc_fees.rs +++ /dev/null @@ -1,110 +0,0 @@ -// This file is part of Bifrost. - -// Copyright (C) 2019-2022 Liebi Technologies (UK) Ltd. -// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -// The swap pool algorithm implements Balancer protocol -// For more details, refer to https://balancer.finance/whitepaper/ - -use frame_support::traits::Contains; -use node_primitives::ExtraFeeName; - -use super::*; -use crate::Config; - -pub struct MiscFeeHandler( - PhantomData<(T, FeeCurrency, FeeAmount, FeeFilter)>, -); - -impl - FeeDeductor, PalletBalanceOf, T::RuntimeCall> - for MiscFeeHandler -where - FeeCurrency: Get>, - FeeAmount: Get>, - FeeFilter: Contains>, -{ - fn deduct_fee( - who: &T::AccountId, - receiver: &T::AccountId, - call: &T::RuntimeCall, - ) -> Result<(CurrencyIdOf, PalletBalanceOf), DispatchError> { - // If this call matches a specific extra-fee call - if FeeFilter::contains(call) { - let total_fee = FeeAmount::get(); - let fee_currency = FeeCurrency::get(); - - ::MultiCurrency::transfer(fee_currency, who, receiver, total_fee)?; - Ok((fee_currency, total_fee)) - } else { - Err(DispatchError::Other("Failed to deduct extra fee.")) - } - } -} - -pub trait FeeDeductor { - fn deduct_fee( - who: &AccountId, - receiver: &AccountId, - call: &RuntimeCall, - ) -> Result<(CurrencyId, Balance), DispatchError>; -} - -#[impl_trait_for_tuples::impl_for_tuples(30)] -impl - FeeDeductor for Tuple -{ - fn deduct_fee( - who: &AccountId, - receiver: &AccountId, - call: &RuntimeCall, - ) -> Result<(CurrencyId, Balance), DispatchError> { - for_tuples!( - #( - if let Ok(result) = Tuple::deduct_fee(who, receiver, call) { - return Ok(result); - } - )* - ); - - Err(DispatchError::Other("Failed to deduct extra fee.")) - } -} - -pub trait NameGetter { - fn get_name(call: &RuntimeCall) -> ExtraFeeName; -} - -pub trait FeeGetter { - fn get_fee_info(call: &RuntimeCall) -> (ExtraFeeName, bool); -} - -pub struct ExtraFeeMatcher( - PhantomData<(T, FeeNameGetter, AggregateExtraFeeFilter)>, -); -impl FeeGetter> - for ExtraFeeMatcher -where - FeeNameGetter: NameGetter>, - AggregateExtraFeeFilter: Contains>, -{ - fn get_fee_info(call: &CallOf) -> (ExtraFeeName, bool) { - let fee_name = FeeNameGetter::get_name(&call); - let if_extra_fee = AggregateExtraFeeFilter::contains(call); - - (fee_name, if_extra_fee) - } -} diff --git a/pallets/flexible-fee/src/mock.rs b/pallets/flexible-fee/src/mock.rs index ca2395abe..d51ff1ba5 100644 --- a/pallets/flexible-fee/src/mock.rs +++ b/pallets/flexible-fee/src/mock.rs @@ -18,23 +18,23 @@ #![cfg(test)] -use cumulus_primitives_core::ParaId as Pid; -use std::convert::TryInto; - +use super::*; +use crate::{self as flexible_fee, tests::CHARLIE}; use bifrost_asset_registry::AssetIdMaps; +use cumulus_primitives_core::ParaId as Pid; #[cfg(feature = "runtime-benchmarks")] use frame_benchmarking::whitelisted_caller; use frame_support::{ ord_parameter_types, parameter_types, sp_runtime::{DispatchError, DispatchResult}, sp_std::marker::PhantomData, - traits::{Contains, Everything, Get, Nothing}, + traits::{Everything, Get, Nothing}, weights::{ConstantMultiplier, IdentityFee}, PalletId, }; use frame_system as system; use frame_system::{EnsureRoot, EnsureSignedBy}; -use node_primitives::{Balance, CurrencyId, MessageId, ParaId, TokenSymbol}; +use node_primitives::{Balance, CurrencyId, ExtraFeeInfo, MessageId, ParaId, TokenSymbol}; use orml_traits::MultiCurrency; use sp_arithmetic::Percent; use sp_core::H256; @@ -44,6 +44,7 @@ use sp_runtime::{ traits::{AccountIdConversion, BlakeTwo256, IdentityLookup, UniqueSaturatedInto}, AccountId32, SaturatedConversion, }; +use std::convert::TryInto; use xcm::prelude::*; use xcm_builder::FixedWeightBounds; use xcm_executor::XcmExecutor; @@ -52,11 +53,6 @@ use zenlink_protocol::{ AssetId as ZenlinkAssetId, LocalAssetHandler, PairLpGenerate, ZenlinkMultiAssets, }; -use super::*; -#[allow(unused_imports)] -use crate::misc_fees::{ExtraFeeMatcher, MiscFeeHandler, NameGetter}; -use crate::{self as flexible_fee, tests::CHARLIE}; - pub type AccountId = AccountId32; pub type BlockNumber = u32; pub type Amount = i128; @@ -184,48 +180,8 @@ impl orml_tokens::Config for Test { type CurrencyHooks = (); } -// Aggregate name getter to get fee names if the call needs to pay extra fees. -// If any call need to pay extra fees, it should be added as an item here. -// Used together with AggregateExtraFeeFilter below. -pub struct FeeNameGetter; -impl NameGetter for FeeNameGetter { - fn get_name(c: &RuntimeCall) -> ExtraFeeName { - match *c { - RuntimeCall::Salp(bifrost_salp::Call::contribute { .. }) => - ExtraFeeName::SalpContribute, - _ => ExtraFeeName::NoExtraFee, - } - } -} - -// Aggregate filter to filter if the call needs to pay extra fees -// If any call need to pay extra fees, it should be added as an item here. -pub struct AggregateExtraFeeFilter; -impl Contains for AggregateExtraFeeFilter { - fn contains(c: &RuntimeCall) -> bool { - match *c { - RuntimeCall::Salp(bifrost_salp::Call::contribute { .. }) => true, - _ => false, - } - } -} - -pub struct ContributeFeeFilter; -impl Contains for ContributeFeeFilter { - fn contains(c: &RuntimeCall) -> bool { - match *c { - RuntimeCall::Salp(bifrost_salp::Call::contribute { .. }) => true, - _ => false, - } - } -} - parameter_types! { - pub const NativeCurrencyId: CurrencyId = CurrencyId::Native(TokenSymbol::ASG); - pub const AlternativeFeeCurrencyId: CurrencyId = CurrencyId::Token(TokenSymbol::KSM); - pub const AltFeeCurrencyExchangeRate: (u32, u32) = (1, 100); pub const TreasuryAccount: AccountId32 = TREASURY_ACCOUNT; - pub const SalpContributeFee: Balance = 100_000_000; pub const MaxFeeCurrencyOrderListLen: u32 = 50; } @@ -239,17 +195,44 @@ impl crate::Config for Test { type RuntimeEvent = RuntimeEvent; type MultiCurrency = Currencies; type TreasuryAccount = TreasuryAccount; - type NativeCurrencyId = NativeCurrencyId; - type AlternativeFeeCurrencyId = AlternativeFeeCurrencyId; - type AltFeeCurrencyExchangeRate = AltFeeCurrencyExchangeRate; type MaxFeeCurrencyOrderListLen = MaxFeeCurrencyOrderListLen; type OnUnbalanced = (); type WeightInfo = (); - type ExtraFeeMatcher = ExtraFeeMatcher; - type MiscFeeHandler = - MiscFeeHandler; + type ExtraFeeMatcher = ExtraFeeMatcher; type ParachainId = ParaInfo; type ControlOrigin = EnsureRoot; + type XcmWeightAndFeeHandler = XcmDestWeightAndFee; +} + +pub struct XcmDestWeightAndFee; +impl XcmDestWeightAndFeeHandler for XcmDestWeightAndFee { + fn get_operation_weight_and_fee( + _token: CurrencyId, + _operation: XcmInterfaceOperation, + ) -> Option<(Weight, Balance)> { + Some((Weight::from_parts(100, 100), 100u32.into())) + } + + fn set_xcm_dest_weight_and_fee( + _currency_id: CurrencyId, + _operation: XcmInterfaceOperation, + _weight_and_fee: Option<(Weight, Balance)>, + ) -> DispatchResult { + Ok(()) + } +} + +pub struct ExtraFeeMatcher; +impl FeeGetter for ExtraFeeMatcher { + fn get_fee_info(c: &RuntimeCall) -> ExtraFeeInfo { + match *c { + RuntimeCall::Salp(bifrost_salp::Call::contribute { .. }) => ExtraFeeInfo { + extra_fee_name: ExtraFeeName::SalpContribute, + extra_fee_currency: RelayCurrencyId::get(), + }, + _ => ExtraFeeInfo::default(), + } + } } pub struct ParaInfo; @@ -260,7 +243,7 @@ impl Get for ParaInfo { } parameter_types! { - pub const GetNativeCurrencyId: CurrencyId = CurrencyId::Native(TokenSymbol::ASG); + pub const GetNativeCurrencyId: CurrencyId = CurrencyId::Native(TokenSymbol::BNC); } pub type AdaptedBasicCurrency = diff --git a/pallets/flexible-fee/src/tests.rs b/pallets/flexible-fee/src/tests.rs index af83273d1..dcfd09cfd 100644 --- a/pallets/flexible-fee/src/tests.rs +++ b/pallets/flexible-fee/src/tests.rs @@ -42,7 +42,7 @@ pub const CHARLIE: AccountId32 = AccountId32::new([0u8; 32]); pub const BOB: AccountId32 = AccountId32::new([1u8; 32]); pub const ALICE: AccountId32 = AccountId32::new([2u8; 32]); pub const DICK: AccountId32 = AccountId32::new([3u8; 32]); -pub const CURRENCY_ID_0: CurrencyId = CurrencyId::Native(TokenSymbol::ASG); +pub const CURRENCY_ID_0: CurrencyId = CurrencyId::Native(TokenSymbol::BNC); pub const CURRENCY_ID_1: CurrencyId = CurrencyId::Stable(TokenSymbol::KUSD); pub const CURRENCY_ID_2: CurrencyId = CurrencyId::Token(TokenSymbol::DOT); pub const CURRENCY_ID_3: CurrencyId = CurrencyId::VToken(TokenSymbol::DOT); @@ -380,9 +380,7 @@ fn correct_and_deposit_fee_should_work() { #[test] fn deduct_salp_fee_should_work() { new_test_ext().execute_with(|| { - // deposit some money for Charlie - assert_ok!(Currencies::deposit(CURRENCY_ID_0, &CHARLIE, 200)); // Native token - assert_ok!(Currencies::deposit(CURRENCY_ID_4, &CHARLIE, 200_000_000)); // Token KSM + basic_setup(); // prepare call variable let para_id = 2001; @@ -396,21 +394,26 @@ fn deduct_salp_fee_should_work() { let info = xt.get_dispatch_info(); // 99 inclusion fee and a tip of 8 - assert_ok!(FlexibleFee::withdraw_fee(&CHARLIE, &call, &info, 107, 8)); + assert_ok!(FlexibleFee::withdraw_fee(&CHARLIE, &call, &info, 80, 8)); - assert_eq!(::Currency::free_balance(&CHARLIE), 93); - // fee is: 133780717 + assert_eq!(::Currency::free_balance(&CHARLIE), 8); + + // Other currencies should not be affected assert_eq!( - ::MultiCurrency::free_balance(CURRENCY_ID_4, &CHARLIE), - 100000000 + ::MultiCurrency::free_balance(CURRENCY_ID_1, &CHARLIE), + 20 ); - // treasury account has the fee assert_eq!( - ::MultiCurrency::free_balance( - CURRENCY_ID_4, - &::TreasuryAccount::get() - ), - 100000000 + ::MultiCurrency::free_balance(CURRENCY_ID_2, &CHARLIE), + 30 + ); + assert_eq!( + ::MultiCurrency::free_balance(CURRENCY_ID_3, &CHARLIE), + 40 + ); + assert_eq!( + ::MultiCurrency::free_balance(CURRENCY_ID_4, &CHARLIE), + 50 ); }); } diff --git a/pallets/slp/src/agents/astar_agent/agent.rs b/pallets/slp/src/agents/astar_agent/agent.rs index 50ffde0fc..a22a64064 100644 --- a/pallets/slp/src/agents/astar_agent/agent.rs +++ b/pallets/slp/src/agents/astar_agent/agent.rs @@ -22,19 +22,21 @@ use crate::{ primitives::{ Ledger, QueryId, SubstrateLedger, SubstrateLedgerUpdateEntry, SubstrateLedgerUpdateOperation, UnlockChunk, ValidatorsByDelegatorUpdateEntry, - XcmOperation, TIMEOUT_BLOCKS, + TIMEOUT_BLOCKS, }, traits::{QueryResponseManager, StakingAgent, XcmBuilder}, AccountIdOf, BalanceOf, Config, CurrencyDelays, DelegatorLedgerXcmUpdateQueue, DelegatorLedgers, DelegatorsMultilocation2Index, LedgerUpdateEntry, MinimumsAndMaximums, - Pallet, TimeUnit, Validators, XcmDestWeightAndFee, XcmWeight, + Pallet, TimeUnit, Validators, XcmOperation, XcmWeight, }; use codec::Encode; use core::marker::PhantomData; pub use cumulus_primitives_core::ParaId; use frame_support::{ensure, traits::Get}; use frame_system::pallet_prelude::BlockNumberFor; -use node_primitives::{CurrencyId, VtokenMintingOperator, ASTR_TOKEN_ID}; +use node_primitives::{ + CurrencyId, VtokenMintingOperator, XcmDestWeightAndFeeHandler, ASTR_TOKEN_ID, +}; use polkadot_parachain::primitives::Sibling; use sp_runtime::{ traits::{ @@ -408,9 +410,11 @@ impl // Prepare parameter fee_asset_item. let fee_asset_item: u32 = 0; - let (weight_limit, _) = - XcmDestWeightAndFee::::get(currency_id, XcmOperation::TransferBack) - .ok_or(Error::::WeightAndFeeNotExists)?; + let (weight_limit, _) = T::XcmWeightAndFeeHandler::get_operation_weight_and_fee( + currency_id, + XcmOperation::TransferBack, + ) + .ok_or(Error::::WeightAndFeeNotExists)?; // Construct xcm message. let call = AstarCall::Xcm(Box::new(XcmCall::LimitedReserveTransferAssets( @@ -654,8 +658,9 @@ impl AstarAgent { Box::new(call), ))); - let (weight, fee) = XcmDestWeightAndFee::::get(currency_id, operation) - .ok_or(Error::::WeightAndFeeNotExists)?; + let (weight, fee) = + T::XcmWeightAndFeeHandler::get_operation_weight_and_fee(currency_id, operation) + .ok_or(Error::::WeightAndFeeNotExists)?; Ok((call_as_subaccount, fee, weight)) } diff --git a/pallets/slp/src/agents/common.rs b/pallets/slp/src/agents/common.rs index b1f03b6ac..6fca3130a 100644 --- a/pallets/slp/src/agents/common.rs +++ b/pallets/slp/src/agents/common.rs @@ -22,11 +22,10 @@ use crate::{ Event, Junction::{AccountId32, Parachain}, Junctions::{Here, X1}, - MinimumsAndMaximums, MultiLocation, Pallet, Validators, Xcm, XcmDestWeightAndFee, XcmOperation, - Zero, + MinimumsAndMaximums, MultiLocation, Pallet, Validators, Xcm, XcmOperation, Zero, }; use frame_support::{ensure, traits::Len}; -use node_primitives::{CurrencyId, VtokenMintingOperator}; +use node_primitives::{CurrencyId, VtokenMintingOperator, XcmDestWeightAndFeeHandler}; use orml_traits::MultiCurrency; use sp_core::{Get, U256}; use sp_runtime::{ @@ -245,9 +244,11 @@ impl Pallet { // not succeed. ensure!(from.parents.is_zero(), Error::::InvalidTransferSource); - let (weight, fee_amount) = - XcmDestWeightAndFee::::get(currency_id, XcmOperation::TransferTo) - .ok_or(Error::::WeightAndFeeNotExists)?; + let (weight, fee_amount) = T::XcmWeightAndFeeHandler::get_operation_weight_and_fee( + currency_id, + XcmOperation::TransferTo, + ) + .ok_or(Error::::WeightAndFeeNotExists)?; // Prepare parameter beneficiary. let to_32: [u8; 32] = Pallet::::multilocation_to_account_32(to)?; diff --git a/pallets/slp/src/agents/moonbeam_agent/agent.rs b/pallets/slp/src/agents/moonbeam_agent/agent.rs index e81a12120..aad27714a 100644 --- a/pallets/slp/src/agents/moonbeam_agent/agent.rs +++ b/pallets/slp/src/agents/moonbeam_agent/agent.rs @@ -25,13 +25,13 @@ use crate::{ primitives::{ Ledger, MoonbeamLedgerUpdateEntry, MoonbeamLedgerUpdateOperation, OneToManyDelegationAction, OneToManyDelegatorStatus, OneToManyLedger, - OneToManyScheduledRequest, QueryId, XcmOperation, TIMEOUT_BLOCKS, + OneToManyScheduledRequest, QueryId, TIMEOUT_BLOCKS, }, traits::{QueryResponseManager, StakingAgent, XcmBuilder}, AccountIdOf, BalanceOf, Config, CurrencyDelays, DelegationsOccupied, DelegatorLedgerXcmUpdateQueue, DelegatorLedgers, DelegatorsMultilocation2Index, FeeSources, LedgerUpdateEntry, MinimumsAndMaximums, Pallet, TimeUnit, Validators, - ValidatorsByDelegatorUpdateEntry, XcmDestWeightAndFee, + ValidatorsByDelegatorUpdateEntry, XcmOperation, }; use codec::{alloc::collections::BTreeMap, Encode}; use core::marker::PhantomData; @@ -40,7 +40,7 @@ use frame_support::{ensure, traits::Get}; use frame_system::pallet_prelude::BlockNumberFor; use node_primitives::{ currency::{GLMR, GLMR_TOKEN_ID, MOVR}, - CurrencyId, TokenSymbol, VtokenMintingOperator, + CurrencyId, TokenSymbol, VtokenMintingOperator, XcmDestWeightAndFeeHandler, }; use orml_traits::MultiCurrency; use polkadot_parachain::primitives::Sibling; @@ -1019,8 +1019,9 @@ impl MoonbeamAgent { MoonbeamUtilityCall::AsDerivative(sub_account_index, Box::new(call)), )); - let (weight, fee) = XcmDestWeightAndFee::::get(currency_id, operation) - .ok_or(Error::::WeightAndFeeNotExists)?; + let (weight, fee) = + T::XcmWeightAndFeeHandler::get_operation_weight_and_fee(currency_id, operation) + .ok_or(Error::::WeightAndFeeNotExists)?; Ok((call_as_subaccount, fee, weight)) } @@ -1101,9 +1102,11 @@ impl MoonbeamAgent { // not succeed. ensure!(from.parents.is_zero(), Error::::InvalidTransferSource); - let (weight, fee_amount) = - XcmDestWeightAndFee::::get(currency_id, XcmOperation::TransferTo) - .ok_or(Error::::WeightAndFeeNotExists)?; + let (weight, fee_amount) = T::XcmWeightAndFeeHandler::get_operation_weight_and_fee( + currency_id, + XcmOperation::TransferTo, + ) + .ok_or(Error::::WeightAndFeeNotExists)?; // Prepare parameter dest and beneficiary. let dest = Self::get_moonbeam_para_multilocation(currency_id)?; diff --git a/pallets/slp/src/agents/phala_agent/agent.rs b/pallets/slp/src/agents/phala_agent/agent.rs index 481c634bf..ac98416f1 100644 --- a/pallets/slp/src/agents/phala_agent/agent.rs +++ b/pallets/slp/src/agents/phala_agent/agent.rs @@ -22,19 +22,19 @@ use crate::{ pallet::{Error, Event}, primitives::{ Ledger, PhalaLedger, QueryId, SubstrateLedgerUpdateEntry, SubstrateLedgerUpdateOperation, - XcmOperation, TIMEOUT_BLOCKS, + TIMEOUT_BLOCKS, }, traits::{QueryResponseManager, StakingAgent, XcmBuilder}, AccountIdOf, BalanceOf, Config, CurrencyDelays, CurrencyId, DelegatorLedgerXcmUpdateQueue, DelegatorLedgers, DelegatorsMultilocation2Index, Hash, LedgerUpdateEntry, MinimumsAndMaximums, - Pallet, TimeUnit, Validators, ValidatorsByDelegatorUpdateEntry, XcmDestWeightAndFee, XcmWeight, + Pallet, TimeUnit, Validators, ValidatorsByDelegatorUpdateEntry, XcmOperation, XcmWeight, }; use codec::Encode; use core::marker::PhantomData; pub use cumulus_primitives_core::ParaId; use frame_support::{ensure, traits::Get}; use frame_system::pallet_prelude::BlockNumberFor; -use node_primitives::{TokenSymbol, VtokenMintingOperator}; +use node_primitives::{TokenSymbol, VtokenMintingOperator, XcmDestWeightAndFeeHandler}; use polkadot_parachain::primitives::Sibling; use sp_core::U256; use sp_runtime::{ @@ -839,8 +839,9 @@ impl PhalaAgent { ))) }; - let (weight, fee) = XcmDestWeightAndFee::::get(currency_id, operation) - .ok_or(Error::::WeightAndFeeNotExists)?; + let (weight, fee) = + T::XcmWeightAndFeeHandler::get_operation_weight_and_fee(currency_id, operation) + .ok_or(Error::::WeightAndFeeNotExists)?; Ok((call_as_subaccount, fee, weight)) } @@ -883,8 +884,9 @@ impl PhalaAgent { Box::new(call), ))); - let (weight, fee) = XcmDestWeightAndFee::::get(currency_id, operation) - .ok_or(Error::::WeightAndFeeNotExists)?; + let (weight, fee) = + T::XcmWeightAndFeeHandler::get_operation_weight_and_fee(currency_id, operation) + .ok_or(Error::::WeightAndFeeNotExists)?; Ok((call_as_subaccount, fee, weight)) } diff --git a/pallets/slp/src/agents/polkadot_agent/agent.rs b/pallets/slp/src/agents/polkadot_agent/agent.rs index 0c8a05f71..23b932741 100644 --- a/pallets/slp/src/agents/polkadot_agent/agent.rs +++ b/pallets/slp/src/agents/polkadot_agent/agent.rs @@ -21,20 +21,21 @@ use crate::{ primitives::{ Ledger, QueryId, SubstrateLedger, SubstrateLedgerUpdateEntry, SubstrateLedgerUpdateOperation, SubstrateValidatorsByDelegatorUpdateEntry, UnlockChunk, - ValidatorsByDelegatorUpdateEntry, XcmOperation, TIMEOUT_BLOCKS, + ValidatorsByDelegatorUpdateEntry, TIMEOUT_BLOCKS, }, traits::{QueryResponseManager, StakingAgent, XcmBuilder}, AccountIdOf, BalanceOf, BoundedVec, Config, CurrencyDelays, DelegatorLedgerXcmUpdateQueue, DelegatorLedgers, DelegatorsMultilocation2Index, LedgerUpdateEntry, MinimumsAndMaximums, - Pallet, TimeUnit, ValidatorsByDelegator, ValidatorsByDelegatorXcmUpdateQueue, - XcmDestWeightAndFee, XcmWeight, + Pallet, TimeUnit, ValidatorsByDelegator, ValidatorsByDelegatorXcmUpdateQueue, XcmOperation, + XcmWeight, }; use core::marker::PhantomData; pub use cumulus_primitives_core::ParaId; use frame_support::{ensure, traits::Get}; use frame_system::pallet_prelude::BlockNumberFor; use node_primitives::{ - currency::KSM, CurrencyId, TokenSymbol, VtokenMintingOperator, DOT, DOT_TOKEN_ID, + currency::KSM, CurrencyId, TokenSymbol, VtokenMintingOperator, XcmDestWeightAndFeeHandler, DOT, + DOT_TOKEN_ID, }; use sp_runtime::{ traits::{ @@ -684,9 +685,11 @@ impl // Prepare parameter fee_asset_item. let fee_asset_item: u32 = 0; - let (weight_limit, _) = - XcmDestWeightAndFee::::get(currency_id, XcmOperation::TransferBack) - .ok_or(Error::::WeightAndFeeNotExists)?; + let (weight_limit, _) = T::XcmWeightAndFeeHandler::get_operation_weight_and_fee( + currency_id, + XcmOperation::TransferBack, + ) + .ok_or(Error::::WeightAndFeeNotExists)?; // Construct xcm message. let call = SubstrateCall::::get_reserve_transfer_assets_call( @@ -956,8 +959,9 @@ impl PolkadotAgent { let call_as_subaccount = call.get_call_as_subaccount_from_call(sub_account_index)?; - let (weight, fee) = XcmDestWeightAndFee::::get(currency_id, operation) - .ok_or(Error::::WeightAndFeeNotExists)?; + let (weight, fee) = + T::XcmWeightAndFeeHandler::get_operation_weight_and_fee(currency_id, operation) + .ok_or(Error::::WeightAndFeeNotExists)?; Ok((call_as_subaccount, fee, weight)) } diff --git a/pallets/slp/src/lib.rs b/pallets/slp/src/lib.rs index cdeb0df0a..ee207f01a 100644 --- a/pallets/slp/src/lib.rs +++ b/pallets/slp/src/lib.rs @@ -25,7 +25,7 @@ use crate::{agents::PolkadotAgent, Junction::GeneralIndex, Junctions::X2}; pub use crate::{ primitives::{ Delays, LedgerUpdateEntry, MinimumsMaximums, QueryId, SubstrateLedger, - ValidatorsByDelegatorUpdateEntry, XcmOperation, + ValidatorsByDelegatorUpdateEntry, }, traits::{OnRefund, QueryResponseManager, StakingAgent}, Junction::AccountId32, @@ -39,7 +39,9 @@ use frame_system::{ }; use node_primitives::{ currency::{BNC, KSM, MOVR, PHA}, - CurrencyId, CurrencyIdExt, SlpOperator, TimeUnit, VtokenMintingOperator, ASTR, DOT, FIL, GLMR, + traits::XcmDestWeightAndFeeHandler, + CurrencyId, CurrencyIdExt, SlpOperator, TimeUnit, VtokenMintingOperator, + XcmInterfaceOperation as XcmOperation, ASTR, DOT, FIL, GLMR, }; use orml_traits::MultiCurrency; use parachain_staking::ParachainStakingInterface; @@ -151,12 +153,8 @@ pub mod pallet { /// If you don't need it, you can specify the type `()`. type OnRefund: OnRefund, CurrencyId, BalanceOf>; - //【For xcm v3】 - // /// This chain's Universal Location. Enabled only for xcm v3 version. - // type UniversalLocation: Get; + type XcmWeightAndFeeHandler: XcmDestWeightAndFeeHandler>; - /// The maximum number of entries to be confirmed in a block for update queue in the - /// on_initialize queue. #[pallet::constant] type MaxTypeEntryPerBlock: Get; @@ -512,10 +510,7 @@ pub mod pallet { /// boundedVec). const STORAGE_VERSION: StorageVersion = StorageVersion::new(2); - /// The dest weight limit and fee for execution XCM msg sended out. Must be - /// sufficient, otherwise the execution of XCM msg on the dest chain will fail. - /// - /// XcmDestWeightAndFee: DoubleMap: CurrencyId, XcmOperation => (XcmWeight, Balance) + /// DEPRECATED #[pallet::storage] #[pallet::getter(fn xcm_dest_weight_and_fee)] pub type XcmDestWeightAndFee = StorageDoubleMap< @@ -1546,8 +1541,6 @@ pub mod pallet { /// ***************************** /// ****** Storage Setters ****** /// ***************************** - /// - /// Update storage XcmDestWeightAndFee. #[pallet::call_index(21)] #[pallet::weight(T::WeightInfo::set_xcm_dest_weight_and_fee())] pub fn set_xcm_dest_weight_and_fee( @@ -1561,9 +1554,11 @@ pub mod pallet { // If param weight_and_fee is a none, it will delete the storage. Otherwise, revise the // storage to the new value if exists, or insert a new record if not exists before. - XcmDestWeightAndFee::::mutate_exists(currency_id, &operation, |wt_n_f| { - *wt_n_f = weight_and_fee; - }); + T::XcmWeightAndFeeHandler::set_xcm_dest_weight_and_fee( + currency_id, + operation, + weight_and_fee, + )?; // Deposit event. Pallet::::deposit_event(Event::XcmDestWeightAndFeeSet { diff --git a/pallets/slp/src/mocks/mock.rs b/pallets/slp/src/mocks/mock.rs index e10ad29ad..73d4a53a7 100644 --- a/pallets/slp/src/mocks/mock.rs +++ b/pallets/slp/src/mocks/mock.rs @@ -469,6 +469,7 @@ impl Config for Runtime { type ParachainStaking = ParachainStaking; type XcmTransfer = XTokens; type MaxLengthLimit = MaxLengthLimit; + type XcmWeightAndFeeHandler = (); } parameter_types! { diff --git a/pallets/slp/src/mocks/mock_kusama.rs b/pallets/slp/src/mocks/mock_kusama.rs index f487b2105..ad5a8f8e9 100644 --- a/pallets/slp/src/mocks/mock_kusama.rs +++ b/pallets/slp/src/mocks/mock_kusama.rs @@ -484,6 +484,7 @@ impl Config for Runtime { type ParachainStaking = ParachainStaking; type XcmTransfer = XTokens; type MaxLengthLimit = MaxLengthLimit; + type XcmWeightAndFeeHandler = (); } parameter_types! { diff --git a/pallets/slp/src/primitives/mod.rs b/pallets/slp/src/primitives/mod.rs index b51e65038..b6624c9e7 100644 --- a/pallets/slp/src/primitives/mod.rs +++ b/pallets/slp/src/primitives/mod.rs @@ -107,28 +107,3 @@ pub struct Delays { /// Leave from delegator set delay. pub leave_delegators_delay: TimeUnit, } - -/// XCM operations list -#[derive(Encode, Decode, Eq, PartialEq, Copy, Clone, RuntimeDebug, TypeInfo)] -pub enum XcmOperation { - // XTokens - XtokensTransfer, - Bond, - WithdrawUnbonded, - BondExtra, - Unbond, - Rebond, - Delegate, - Payout, - Liquidize, - TransferBack, - TransferTo, - Chill, - Undelegate, - CancelLeave, - XtokensTransferBack, - ExecuteLeave, - ConvertAsset, - Vote, - RemoveVote, -} diff --git a/pallets/slp/src/tests/kusama_tests.rs b/pallets/slp/src/tests/kusama_tests.rs index 7cbddad65..2defb4f2f 100644 --- a/pallets/slp/src/tests/kusama_tests.rs +++ b/pallets/slp/src/tests/kusama_tests.rs @@ -32,36 +32,6 @@ const SUBACCOUNT_0_32: [u8; 32] = const SUBACCOUNT_0_LOCATION: MultiLocation = MultiLocation { parents: 1, interior: X1(AccountId32 { network: None, id: SUBACCOUNT_0_32 }) }; -#[test] -fn set_xcm_dest_weight_and_fee_should_work() { - ExtBuilder::default().build().execute_with(|| { - System::set_block_number(1); - - // Insert a new record. - assert_ok!(Slp::set_xcm_dest_weight_and_fee( - RuntimeOrigin::signed(ALICE), - KSM, - XcmOperation::Bond, - Some((5_000_000_000.into(), 5_000_000_000)) - )); - - assert_eq!( - XcmDestWeightAndFee::::get(KSM, XcmOperation::Bond), - Some((5_000_000_000.into(), 5_000_000_000)) - ); - - // Delete a record. - assert_ok!(Slp::set_xcm_dest_weight_and_fee( - RuntimeOrigin::signed(ALICE), - KSM, - XcmOperation::Bond, - None - )); - - assert_eq!(XcmDestWeightAndFee::::get(KSM, XcmOperation::Bond), None); - }); -} - #[test] fn construct_xcm_and_send_as_subaccount_should_work() { let para_chain_account_right: AccountId = diff --git a/pallets/slpx/src/mock.rs b/pallets/slpx/src/mock.rs index 12b11dce0..459f1e149 100644 --- a/pallets/slpx/src/mock.rs +++ b/pallets/slpx/src/mock.rs @@ -476,6 +476,7 @@ impl bifrost_slp::Config for Test { type ParachainStaking = (); type XcmTransfer = XTokens; type MaxLengthLimit = MaxLengthLimit; + type XcmWeightAndFeeHandler = (); } #[cfg(feature = "runtime-benchmarks")] diff --git a/pallets/system-maker/src/mock.rs b/pallets/system-maker/src/mock.rs index 707d97c87..f208f55da 100644 --- a/pallets/system-maker/src/mock.rs +++ b/pallets/system-maker/src/mock.rs @@ -321,6 +321,7 @@ impl bifrost_slp::Config for Runtime { type ParachainStaking = (); type XcmTransfer = XTokens; type MaxLengthLimit = MaxLengthLimit; + type XcmWeightAndFeeHandler = (); } parameter_type_with_key! { diff --git a/pallets/system-staking/src/mock.rs b/pallets/system-staking/src/mock.rs index 0c3924af3..0137a7964 100644 --- a/pallets/system-staking/src/mock.rs +++ b/pallets/system-staking/src/mock.rs @@ -340,6 +340,7 @@ impl bifrost_slp::Config for Runtime { type ParachainStaking = (); type XcmTransfer = XTokens; type MaxLengthLimit = MaxLengthLimit; + type XcmWeightAndFeeHandler = (); } parameter_types! { diff --git a/pallets/ve-minting/src/mock.rs b/pallets/ve-minting/src/mock.rs index 5396c6321..2e8e57497 100644 --- a/pallets/ve-minting/src/mock.rs +++ b/pallets/ve-minting/src/mock.rs @@ -386,6 +386,7 @@ impl bifrost_slp::Config for Runtime { type ParachainStaking = (); type XcmTransfer = XTokens; type MaxLengthLimit = MaxLengthLimit; + type XcmWeightAndFeeHandler = (); } parameter_types! { diff --git a/pallets/vtoken-minting/src/mock.rs b/pallets/vtoken-minting/src/mock.rs index 6665527c9..179e380c3 100644 --- a/pallets/vtoken-minting/src/mock.rs +++ b/pallets/vtoken-minting/src/mock.rs @@ -362,6 +362,7 @@ impl bifrost_slp::Config for Runtime { type ParachainStaking = (); type XcmTransfer = XTokens; type MaxLengthLimit = MaxLengthLimit; + type XcmWeightAndFeeHandler = (); } parameter_types! { diff --git a/pallets/vtoken-voting/src/lib.rs b/pallets/vtoken-voting/src/lib.rs index 0e9835054..5e0446e42 100644 --- a/pallets/vtoken-voting/src/lib.rs +++ b/pallets/vtoken-voting/src/lib.rs @@ -45,7 +45,8 @@ use frame_support::{ use frame_system::pallet_prelude::{BlockNumberFor, *}; use node_primitives::{ currency::{VDOT, VKSM}, - CurrencyId, + traits::XcmDestWeightAndFeeHandler, + CurrencyId, XcmInterfaceOperation, }; use orml_traits::{MultiCurrency, MultiLockableCurrency}; pub use pallet::*; @@ -104,7 +105,7 @@ pub mod pallet { Success = MultiLocation, >; - type XcmDestWeightAndFee: XcmDestWeightAndFeeHandler; + type XcmDestWeightAndFee: XcmDestWeightAndFeeHandler>; type DerivativeAccount: DerivativeAccountHandler; @@ -398,8 +399,9 @@ pub mod pallet { // send XCM message let vote_call = as ConvictionVotingCall>::vote(poll_index, new_vote); let notify_call = Call::::notify_vote { query_id: 0, response: Default::default() }; - let (weight, extra_fee) = T::XcmDestWeightAndFee::get_vote( + let (weight, extra_fee) = T::XcmDestWeightAndFee::get_operation_weight_and_fee( CurrencyId::to_token(&vtoken).map_err(|_| Error::::NoData)?, + XcmInterfaceOperation::VoteVtoken, ) .ok_or(Error::::NoData)?; Self::send_xcm_with_notify( @@ -464,8 +466,9 @@ pub mod pallet { }; let remove_vote_call = as ConvictionVotingCall>::remove_vote(None, poll_index); - let (weight, extra_fee) = T::XcmDestWeightAndFee::get_remove_vote( + let (weight, extra_fee) = T::XcmDestWeightAndFee::get_operation_weight_and_fee( CurrencyId::to_token(&vtoken).map_err(|_| Error::::NoData)?, + XcmInterfaceOperation::VoteRemoveDelegatorVote, ) .ok_or(Error::::NoData)?; Self::send_xcm_with_notify( diff --git a/pallets/vtoken-voting/src/mock.rs b/pallets/vtoken-voting/src/mock.rs index cef7c8516..25c41b2b3 100644 --- a/pallets/vtoken-voting/src/mock.rs +++ b/pallets/vtoken-voting/src/mock.rs @@ -19,10 +19,7 @@ // Ensure we're `no_std` when compiling for Wasm. use crate as vtoken_voting; -use crate::{ - traits::{DerivativeAccountHandler, XcmDestWeightAndFeeHandler}, - BalanceOf, DerivativeIndex, -}; +use crate::{traits::DerivativeAccountHandler, BalanceOf, DerivativeIndex, DispatchResult}; use cumulus_primitives_core::ParaId; use frame_support::{ ord_parameter_types, @@ -33,7 +30,8 @@ use frame_support::{ use frame_system::{EnsureRoot, EnsureSignedBy}; use node_primitives::{ currency::{KSM, VBNC, VKSM}, - CurrencyId, DoNothingRouter, TokenSymbol, + traits::XcmDestWeightAndFeeHandler, + CurrencyId, DoNothingRouter, TokenSymbol, XcmInterfaceOperation, }; use pallet_xcm::EnsureResponse; use sp_core::H256; @@ -41,7 +39,7 @@ use sp_runtime::{ testing::Header, traits::{BlakeTwo256, BlockNumberProvider, ConstU32, IdentityLookup}, }; -use xcm::{prelude::*, v3::Weight as XcmWeight}; +use xcm::prelude::*; use xcm_builder::FixedWeightBounds; use xcm_executor::XcmExecutor; @@ -239,13 +237,20 @@ impl Get for ParachainId { } pub struct XcmDestWeightAndFee; -impl XcmDestWeightAndFeeHandler for XcmDestWeightAndFee { - fn get_vote(_token: CurrencyId) -> Option<(XcmWeight, BalanceOf)> { +impl XcmDestWeightAndFeeHandler> for XcmDestWeightAndFee { + fn get_operation_weight_and_fee( + _token: CurrencyId, + _operation: XcmInterfaceOperation, + ) -> Option<(Weight, Balance)> { Some((Weight::from_parts(4000000000, 100000), 4000000000u32.into())) } - fn get_remove_vote(_token: CurrencyId) -> Option<(XcmWeight, BalanceOf)> { - Some((Weight::from_parts(4000000000, 100000), 4000000000u32.into())) + fn set_xcm_dest_weight_and_fee( + _currency_id: CurrencyId, + _operation: XcmInterfaceOperation, + _weight_and_fee: Option<(Weight, Balance)>, + ) -> DispatchResult { + Ok(()) } } diff --git a/pallets/vtoken-voting/src/traits.rs b/pallets/vtoken-voting/src/traits.rs index 5f1e88544..d1cab95fd 100644 --- a/pallets/vtoken-voting/src/traits.rs +++ b/pallets/vtoken-voting/src/traits.rs @@ -1,11 +1,5 @@ use crate::{BalanceOf, Config, CurrencyIdOf, DerivativeIndex}; -use xcm::v3::{MultiLocation, Weight as XcmWeight}; - -pub trait XcmDestWeightAndFeeHandler { - fn get_vote(token: CurrencyIdOf) -> Option<(XcmWeight, BalanceOf)>; - - fn get_remove_vote(token: CurrencyIdOf) -> Option<(XcmWeight, BalanceOf)>; -} +use xcm::v3::MultiLocation; pub trait DerivativeAccountHandler { fn check_derivative_index_exists( diff --git a/pallets/xcm-interface/Cargo.toml b/pallets/xcm-interface/Cargo.toml index d38943554..a4cac5ae3 100644 --- a/pallets/xcm-interface/Cargo.toml +++ b/pallets/xcm-interface/Cargo.toml @@ -5,19 +5,24 @@ authors = ["Ron yang"] edition = "2021" [dependencies] -codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false, features = ["derive"] } -scale-info = { version = "2.3.1", default-features = false, features = ["derive"] } -frame-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.42", default-features = false, optional = true} +codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false, features = [ + "derive", +] } +scale-info = { version = "2.3.1", default-features = false, features = [ + "derive", +] } +frame-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.42", default-features = false, optional = true } frame-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.42", default-features = false } frame-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.42", default-features = false } sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.42", default-features = false } -sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.42", default-features = false } -sp-std = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.42", default-features = false } -sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.42", default-features = false } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.42", default-features = false } +sp-std = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.42", default-features = false } +sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.42", default-features = false } pallet-xcm = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.42", default-features = false } xcm = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.42", default-features = false } cumulus-primitives-core = { git = "https://github.com/paritytech/cumulus", branch = "polkadot-v0.9.42", default-features = false } orml-traits = { version = "0.4.1-dev", default-features = false } +node-primitives = { path = "../../node/primitives", default-features = false } [dev-dependencies] sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.42" } @@ -40,6 +45,7 @@ std = [ "xcm/std", "orml-traits/std", "cumulus-primitives-core/std", + "node-primitives/std", ] runtime-benchmarks = [ "frame-benchmarking", diff --git a/pallets/xcm-interface/src/lib.rs b/pallets/xcm-interface/src/lib.rs index 1629f099a..b395deb49 100644 --- a/pallets/xcm-interface/src/lib.rs +++ b/pallets/xcm-interface/src/lib.rs @@ -21,6 +21,7 @@ pub mod calls; pub mod traits; pub use calls::*; +use node_primitives::{traits::XcmDestWeightAndFeeHandler, XcmInterfaceOperation}; use orml_traits::MultiCurrency; pub use pallet::*; pub use traits::{ChainId, MessageId, Nonce, SalpHelper}; @@ -59,11 +60,7 @@ pub mod pallet { use frame_support::pallet_prelude::*; use frame_system::pallet_prelude::*; use orml_traits::{currency::TransferAll, MultiCurrency, MultiReservableCurrency}; - use scale_info::TypeInfo; - use sp_runtime::{ - traits::{Convert, Zero}, - DispatchError, - }; + use sp_runtime::{traits::Convert, DispatchError}; use sp_std::{convert::From, prelude::*, vec, vec::Vec}; use xcm::{ v3::{prelude::*, ExecuteXcm, Parent}, @@ -73,12 +70,6 @@ pub mod pallet { use super::*; use crate::traits::*; - #[derive(Encode, Decode, Eq, PartialEq, Copy, Clone, RuntimeDebug, TypeInfo)] - pub enum XcmInterfaceOperation { - UmpContributeTransact, - StatemineTransfer, - } - #[pallet::config] pub trait Config: frame_system::Config + pallet_xcm::Config { type RuntimeEvent: From> + IsType<::RuntimeEvent>; @@ -114,18 +105,6 @@ pub mod pallet { #[pallet::constant] type RelayNetwork: Get; - #[pallet::constant] - type StatemineTransferFee: Get>; - - #[pallet::constant] - type StatemineTransferWeight: Get; - - #[pallet::constant] - type ContributionFee: Get>; - - #[pallet::constant] - type ContributionWeight: Get; - #[pallet::constant] type ParachainId: Get; @@ -138,28 +117,44 @@ pub mod pallet { FeeConvertFailed, XcmExecutionFailed, XcmSendFailed, + OperationWeightAndFeeNotExist, } #[pallet::event] #[pallet::generate_deposit(pub(crate) fn deposit_event)] pub enum Event { - /// Xcm dest weight has been updated. \[xcm_operation, new_xcm_dest_weight\] - XcmDestWeightUpdated(XcmInterfaceOperation, Weight), - /// Xcm dest weight has been updated. \[xcm_operation, new_xcm_dest_weight\] - XcmFeeUpdated(XcmInterfaceOperation, BalanceOf), + XcmDestWeightAndFeeUpdated(XcmInterfaceOperation, CurrencyIdOf, Weight, BalanceOf), TransferredStatemineMultiAsset(AccountIdOf, BalanceOf), } + /// The current storage version, we set to 2 our new version(after migrate stroage + /// XcmWeightAndFee from SLP module). + #[allow(unused)] + const STORAGE_VERSION: StorageVersion = StorageVersion::new(2); + + // DEPRECATED: This storage is deprecated, we use XcmWeightAndFee instead. + #[pallet::storage] + #[pallet::getter(fn xcm_weight_and_fee)] + pub type XcmDestWeightAndFee = + StorageMap<_, Twox64Concat, XcmInterfaceOperation, (Weight, BalanceOf), OptionQuery>; + /// The dest weight limit and fee for execution XCM msg sent by XcmInterface. Must be /// sufficient, otherwise the execution of XCM msg on relaychain will fail. /// - /// XcmDestWeightAndFee: map: XcmInterfaceOperation => (Weight, Balance) + /// XcmWeightAndFee: map: XcmInterfaceOperation => (Weight, Balance) #[pallet::storage] #[pallet::getter(fn xcm_dest_weight_and_fee)] - pub type XcmDestWeightAndFee = - StorageMap<_, Twox64Concat, XcmInterfaceOperation, (Weight, BalanceOf), OptionQuery>; - - /// Tracker for the next nonce index + pub type XcmWeightAndFee = StorageDoubleMap< + _, + Blake2_128Concat, + CurrencyIdOf, + Blake2_128Concat, + XcmInterfaceOperation, + (Weight, BalanceOf), + OptionQuery, + >; + + // Tracker for the next nonce index #[pallet::storage] #[pallet::getter(fn current_nonce)] pub(super) type CurrentNonce = @@ -182,29 +177,23 @@ pub mod pallet { #[pallet::weight({16_690_000})] pub fn update_xcm_dest_weight_and_fee( origin: OriginFor, - updates: Vec<(XcmInterfaceOperation, Option, Option>)>, + updates: Vec<(CurrencyIdOf, XcmInterfaceOperation, Weight, BalanceOf)>, ) -> DispatchResult { T::UpdateOrigin::ensure_origin(origin)?; - for (operation, weight_change, fee_change) in updates { - XcmDestWeightAndFee::::mutate_exists(operation, |info| { - if let Some(new_weight) = weight_change { - match info.as_mut() { - Some(info) => info.0 = new_weight, - None => *info = Some((new_weight, Zero::zero())), - } - Self::deposit_event(Event::::XcmDestWeightUpdated( - operation, new_weight, - )); - } - if let Some(new_fee) = fee_change { - match info.as_mut() { - Some(info) => info.1 = new_fee, - None => *info = Some((Zero::zero(), new_fee)), - } - Self::deposit_event(Event::::XcmFeeUpdated(operation, new_fee)); - } - }); + for (currency_id, operation, weight_change, fee_change) in updates { + Self::set_xcm_dest_weight_and_fee( + currency_id, + operation, + Some((weight_change, fee_change)), + )?; + + Self::deposit_event(Event::::XcmDestWeightAndFeeUpdated( + operation, + currency_id, + weight_change, + fee_change, + )); } Ok(()) @@ -227,9 +216,12 @@ pub mod pallet { let amount_u128 = TryInto::::try_into(amount).map_err(|_| Error::::FeeConvertFailed)?; - let (dest_weight, xcm_fee) = - Self::xcm_dest_weight_and_fee(XcmInterfaceOperation::StatemineTransfer) - .unwrap_or((T::StatemineTransferWeight::get(), T::StatemineTransferFee::get())); + let (dest_weight, xcm_fee) = Self::xcm_dest_weight_and_fee( + T::RelaychainCurrencyId::get(), + XcmInterfaceOperation::StatemineTransfer, + ) + .ok_or(Error::::OperationWeightAndFeeNotExist)?; + let xcm_fee_u128 = TryInto::::try_into(xcm_fee).map_err(|_| Error::::FeeConvertFailed)?; @@ -287,9 +279,11 @@ pub mod pallet { ) -> Result { // Construct contribute call data let contribute_call = Self::build_ump_crowdloan_contribute(index, amount); - let (dest_weight, xcm_fee) = - Self::xcm_dest_weight_and_fee(XcmInterfaceOperation::UmpContributeTransact) - .unwrap_or((T::ContributionWeight::get(), T::ContributionFee::get())); + let (dest_weight, xcm_fee) = Self::xcm_dest_weight_and_fee( + T::RelaychainCurrencyId::get(), + XcmInterfaceOperation::UmpContributeTransact, + ) + .ok_or(Error::::OperationWeightAndFeeNotExist)?; // Construct confirm_contribute_call let confirm_contribute_call = T::SalpHelper::confirm_contribute_call(); @@ -313,6 +307,29 @@ pub mod pallet { } } + impl XcmDestWeightAndFeeHandler, BalanceOf> for Pallet { + fn get_operation_weight_and_fee( + token: CurrencyIdOf, + operation: XcmInterfaceOperation, + ) -> Option<(Weight, BalanceOf)> { + Self::xcm_dest_weight_and_fee(token, operation) + } + + fn set_xcm_dest_weight_and_fee( + currency_id: CurrencyIdOf, + operation: XcmInterfaceOperation, + weight_and_fee: Option<(Weight, BalanceOf)>, + ) -> DispatchResult { + // If param weight_and_fee is a none, it will delete the storage. Otherwise, revise the + // storage to the new value if exists, or insert a new record if not exists before. + XcmWeightAndFee::::mutate_exists(currency_id, &operation, |wt_n_f| { + *wt_n_f = weight_and_fee; + }); + + Ok(()) + } + } + impl Pallet { pub(crate) fn transact_id(data: &[u8]) -> MessageId { return sp_io::hashing::blake2_256(data); diff --git a/runtime/bifrost-kusama/src/lib.rs b/runtime/bifrost-kusama/src/lib.rs index ebde181df..3eae12927 100644 --- a/runtime/bifrost-kusama/src/lib.rs +++ b/runtime/bifrost-kusama/src/lib.rs @@ -26,9 +26,10 @@ #[cfg(feature = "std")] include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); -use core::convert::TryInto; - +pub mod migration; use bifrost_slp::{Ledger, QueryResponseManager}; +use core::convert::TryInto; +use frame_support::pallet_prelude::StorageVersion; // A few exports that help ease life for downstream crates. pub use frame_support::{ construct_runtime, match_types, parameter_types, @@ -66,13 +67,11 @@ use sp_std::{marker::PhantomData, prelude::*}; use sp_version::NativeVersion; use sp_version::RuntimeVersion; use static_assertions::const_assert; - /// Constant values used within the runtime. pub mod constants; pub mod weights; use bifrost_asset_registry::AssetIdMaps; -#[allow(unused_imports)] -use bifrost_flexible_fee::misc_fees::{ExtraFeeMatcher, MiscFeeHandler, NameGetter}; + pub use bifrost_runtime_common::{ cent, constants::time::*, dollar, micro, milli, millicent, prod_or_test, AuraId, CouncilCollective, EnsureRootOrAllTechnicalCommittee, MoreThanHalfCouncil, @@ -90,10 +89,13 @@ use frame_support::{ use frame_system::{EnsureRoot, EnsureSigned}; use hex_literal::hex; pub use node_primitives::{ - traits::{CheckSubAccount, FarmingInfo, VtokenMintingInterface, VtokenMintingOperator}, + traits::{ + CheckSubAccount, FarmingInfo, FeeGetter, VtokenMintingInterface, VtokenMintingOperator, + XcmDestWeightAndFeeHandler, + }, AccountId, Amount, AssetIds, Balance, BlockNumber, CurrencyId, CurrencyIdMapping, - DistributionId, ExtraFeeName, Moment, Nonce, ParaId, PoolId, RpcContributionStatus, TimeUnit, - TokenSymbol, + DistributionId, ExtraFeeInfo, ExtraFeeName, Moment, Nonce, ParaId, PoolId, + RpcContributionStatus, TimeUnit, TokenSymbol, }; // zenlink imports use zenlink_protocol::{ @@ -108,16 +110,13 @@ use governance::{custom_origins, CoreAdmin, TechAdmin}; // xcm config mod xcm_config; -use bifrost_vtoken_voting::{ - traits::{DerivativeAccountHandler, XcmDestWeightAndFeeHandler}, - DerivativeIndex, -}; +use bifrost_vtoken_voting::{traits::DerivativeAccountHandler, DerivativeIndex}; use pallet_xcm::{EnsureResponse, QueryStatus}; use xcm::v3::prelude::*; pub use xcm_config::{ parachains, AccountId32Aliases, BifrostCurrencyIdConvert, BifrostTreasuryAccount, ExistentialDeposits, MultiCurrency, SelfParaChainId, Sibling, SiblingParachainConvertsVia, - StatemineTransferFee, UmpTransactFee, XcmConfig, XcmRouter, + XcmConfig, XcmRouter, }; use xcm_executor::XcmExecutor; @@ -1092,87 +1091,54 @@ impl pallet_vesting::Config for Runtime { // Bifrost modules start -// Aggregate name getter to get fee names if the call needs to pay extra fees. -// If any call need to pay extra fees, it should be added as an item here. -// Used together with AggregateExtraFeeFilter below. -pub struct FeeNameGetter; -impl NameGetter for FeeNameGetter { - fn get_name(c: &RuntimeCall) -> ExtraFeeName { +pub struct ExtraFeeMatcher; +impl FeeGetter for ExtraFeeMatcher { + fn get_fee_info(c: &RuntimeCall) -> ExtraFeeInfo { match *c { - RuntimeCall::Salp(bifrost_salp::Call::contribute { .. }) => - ExtraFeeName::SalpContribute, - RuntimeCall::XcmInterface(xcm_interface::Call::transfer_statemine_assets { - .. - }) => ExtraFeeName::StatemineTransfer, - _ => ExtraFeeName::NoExtraFee, - } - } -} - -// Aggregate filter to filter if the call needs to pay extra fees -// If any call need to pay extra fees, it should be added as an item here. -pub struct AggregateExtraFeeFilter; -impl Contains for AggregateExtraFeeFilter { - fn contains(c: &RuntimeCall) -> bool { - match *c { - RuntimeCall::Salp(bifrost_salp::Call::contribute { .. }) => true, + RuntimeCall::Salp(bifrost_salp::Call::contribute { .. }) => ExtraFeeInfo { + extra_fee_name: ExtraFeeName::SalpContribute, + extra_fee_currency: RelayCurrencyId::get(), + }, RuntimeCall::XcmInterface(xcm_interface::Call::transfer_statemine_assets { .. - }) => true, - _ => false, - } - } -} - -pub struct ContributeFeeFilter; -impl Contains for ContributeFeeFilter { - fn contains(c: &RuntimeCall) -> bool { - match *c { - RuntimeCall::Salp(bifrost_salp::Call::contribute { .. }) => true, - _ => false, - } - } -} - -pub struct StatemineTransferFeeFilter; -impl Contains for StatemineTransferFeeFilter { - fn contains(c: &RuntimeCall) -> bool { - match *c { - RuntimeCall::XcmInterface(xcm_interface::Call::transfer_statemine_assets { + }) => ExtraFeeInfo { + extra_fee_name: ExtraFeeName::StatemineTransfer, + extra_fee_currency: RelayCurrencyId::get(), + }, + RuntimeCall::VtokenVoting(bifrost_vtoken_voting::Call::vote { vtoken, .. }) => + ExtraFeeInfo { + extra_fee_name: ExtraFeeName::VoteVtoken, + extra_fee_currency: vtoken, + }, + RuntimeCall::VtokenVoting(bifrost_vtoken_voting::Call::remove_delegator_vote { + vtoken, .. - }) => true, - _ => false, + }) => ExtraFeeInfo { + extra_fee_name: ExtraFeeName::VoteRemoveDelegatorVote, + extra_fee_currency: vtoken, + }, + _ => ExtraFeeInfo::default(), } } } parameter_types! { - pub const AltFeeCurrencyExchangeRate: (u32, u32) = (1, 100); - pub UmpContributeFee: Balance = UmpTransactFee::get(); pub MaxFeeCurrencyOrderListLen: u32 = 50; } -pub type MiscFeeHandlers = ( - MiscFeeHandler, - MiscFeeHandler, -); - impl bifrost_flexible_fee::Config for Runtime { type Currency = Balances; type DexOperator = ZenlinkProtocol; type RuntimeEvent = RuntimeEvent; type MultiCurrency = Currencies; type TreasuryAccount = BifrostTreasuryAccount; - type NativeCurrencyId = NativeCurrencyId; - type AlternativeFeeCurrencyId = RelayCurrencyId; - type AltFeeCurrencyExchangeRate = AltFeeCurrencyExchangeRate; type MaxFeeCurrencyOrderListLen = MaxFeeCurrencyOrderListLen; type OnUnbalanced = Treasury; type WeightInfo = bifrost_flexible_fee::weights::BifrostWeight; - type ExtraFeeMatcher = ExtraFeeMatcher; - type MiscFeeHandler = MiscFeeHandlers; + type ExtraFeeMatcher = ExtraFeeMatcher; type ParachainId = ParachainInfo; type ControlOrigin = EitherOfDiverse; + type XcmWeightAndFeeHandler = XcmInterface; } parameter_types! { @@ -1419,6 +1385,7 @@ impl bifrost_slp::Config for Runtime { type ParachainStaking = ParachainStaking; type XcmTransfer = XTokens; type MaxLengthLimit = MaxLengthLimit; + type XcmWeightAndFeeHandler = XcmInterface; } impl bifrost_vstoken_conversion::Config for Runtime { @@ -1514,17 +1481,6 @@ parameter_types! { pub const QueryTimeout: BlockNumber = 100; } -pub struct XcmDestWeightAndFee; -impl XcmDestWeightAndFeeHandler for XcmDestWeightAndFee { - fn get_vote(token: CurrencyId) -> Option<(xcm::v3::Weight, Balance)> { - Slp::xcm_dest_weight_and_fee(token, bifrost_slp::XcmOperation::Vote) - } - - fn get_remove_vote(token: CurrencyId) -> Option<(xcm::v3::Weight, Balance)> { - Slp::xcm_dest_weight_and_fee(token, bifrost_slp::XcmOperation::RemoveVote) - } -} - pub struct DerivativeAccount; impl DerivativeAccountHandler for DerivativeAccount { fn check_derivative_index_exists(token: CurrencyId, derivative_index: DerivativeIndex) -> bool { @@ -1559,7 +1515,7 @@ impl bifrost_vtoken_voting::Config for Runtime { type MultiCurrency = Currencies; type ControlOrigin = EitherOfDiverse; type ResponseOrigin = EnsureResponse; - type XcmDestWeightAndFee = XcmDestWeightAndFee; + type XcmDestWeightAndFee = XcmInterface; type DerivativeAccount = DerivativeAccount; type RelaychainBlockNumberProvider = RelaychainDataProvider; type ParachainId = SelfParaChainId; @@ -1988,6 +1944,7 @@ pub type Executive = frame_executive::Executive< frame_system::ChainContext, Runtime, AllPalletsWithSystem, + migration::XcmInterfaceMigration, >; #[cfg(feature = "runtime-benchmarks")] @@ -2140,8 +2097,11 @@ impl_runtime_apis! { } impl bifrost_flexible_fee_rpc_runtime_api::FlexibleFeeRuntimeApi for Runtime { - fn get_fee_token_and_amount(who: AccountId, fee: Balance) -> (CurrencyId, Balance) { - let rs = FlexibleFee::cal_fee_token_and_amount(&who, fee); + fn get_fee_token_and_amount(who: AccountId, fee: Balance,utx: ::Extrinsic) -> (CurrencyId, Balance) { + let call = utx.function; + + let rs = FlexibleFee::cal_fee_token_and_amount(&who, fee, &call); + match rs { Ok(val) => val, _ => (CurrencyId::Native(TokenSymbol::BNC), Zero::zero()), diff --git a/runtime/bifrost-kusama/src/migration.rs b/runtime/bifrost-kusama/src/migration.rs new file mode 100644 index 000000000..9a1221b89 --- /dev/null +++ b/runtime/bifrost-kusama/src/migration.rs @@ -0,0 +1,126 @@ +use super::*; +use crate::sp_api_hidden_includes_construct_runtime::hidden_include::dispatch::GetStorageVersion; +#[allow(unused_imports)] +use frame_support::ensure; +use frame_support::traits::OnRuntimeUpgrade; +use node_primitives::traits::XcmDestWeightAndFeeHandler; + +const LOG_TARGET: &str = "XCM-INTERFACE::migration"; + +pub struct XcmInterfaceMigration; +impl OnRuntimeUpgrade for XcmInterfaceMigration { + fn on_runtime_upgrade() -> frame_support::weights::Weight { + // Check the storage version + let onchain_version = XcmInterface::on_chain_storage_version(); + if onchain_version < 2 { + // Transform storage values + // We transform the storage values from the old into the new format. + log::info!( + target: LOG_TARGET, + "Start to migrate XcmInterface storage XcmDestWeightAndFee..." + ); + + let count1 = bifrost_slp::XcmDestWeightAndFee::::iter().count(); + + // 先将Xcm_interface的XcmDestWeightAndFee的值从旧的存储中取出来, + // 然后设置到新的XcmWeightAndFee存储中,新增一个currency_id作为主key + xcm_interface::XcmDestWeightAndFee::::iter().for_each(|(key, value)| { + log::info!( + target: LOG_TARGET, + "Migrated to doublemap for {:?}, {:?}...", + key, + value + ); + let _ = XcmInterface::set_xcm_dest_weight_and_fee( + RelayCurrencyId::get(), + key, + Some(value), + ); + }); + + // get value from the old SLP XcmDestWeightAndFee storage and set it to the XcmInterface + // storage + let count2 = bifrost_slp::XcmDestWeightAndFee::::iter().count(); + + // iterrate the old SLP XcmDestWeightAndFee storage + bifrost_slp::XcmDestWeightAndFee::::iter().for_each(|(key1, key2, value)| { + log::info!( + target: LOG_TARGET, + "Migrated to XcmInterface XcmWeightAndFee for {:?}, {:?}, {:?}...", + key1, + key2, + value + ); + // set the value to the new XcmInterface storage + let _ = XcmInterface::set_xcm_dest_weight_and_fee(key1, key2, Some(value)); + // delete the old SLP XcmDestWeightAndFee storage + bifrost_slp::XcmDestWeightAndFee::::remove(key1, key2); + }); + + // delete the old Xcm_interface XcmDestWeightAndFee storage + xcm_interface::XcmDestWeightAndFee::::iter().for_each(|(key, _value)| { + xcm_interface::XcmDestWeightAndFee::::remove(key); + }); + + // Update the storage version + StorageVersion::new(2).put::>(); + + let count = count1 + count2; + // Return the consumed weight + Weight::from( + ::DbWeight::get() + .reads_writes(count as u64 + 1, count as u64 + 1), + ) + } else { + // We don't do anything here. + Weight::zero() + } + } + + #[cfg(feature = "try-runtime")] + fn pre_upgrade() -> Result, &'static str> { + let xcm_interface_xcm_dest_weight_and_fee_cnt = + xcm_interface::XcmDestWeightAndFee::::iter().count(); + // print out the pre-migrate storage count + log::info!( + target: LOG_TARGET, + "XcmInterface XcmDestWeightAndFee pre-migrate storage count: {:?}", + xcm_interface_xcm_dest_weight_and_fee_cnt + ); + + let slp_xcm_dest_weight_and_fee_cnt = + bifrost_slp::XcmDestWeightAndFee::::iter().count(); + log::info!( + target: LOG_TARGET, + "Slp XcmDestWeightAndFee pre-migrate storage count: {:?}", + slp_xcm_dest_weight_and_fee_cnt + ); + + let cnt = + (xcm_interface_xcm_dest_weight_and_fee_cnt + slp_xcm_dest_weight_and_fee_cnt) as u32; + + Ok(cnt.encode()) + } + + #[cfg(feature = "try-runtime")] + fn post_upgrade(cnt: Vec) -> Result<(), &'static str> { + let old_xcm_interface_xcm_weight_and_fee_cnt: u32 = Decode::decode(&mut cnt.as_slice()) + .expect("the state parameter should be something that was generated by pre_upgrade"); + + let new_xcm_interface_xcm_weight_and_fee_cnt = + xcm_interface::XcmWeightAndFee::::iter().count(); + // print out the post-migrate storage count + log::info!( + target: LOG_TARGET, + "XcmInterface XcmWeightAndFee post-migrate storage count: {:?}", + new_xcm_interface_xcm_weight_and_fee_cnt + ); + ensure!( + new_xcm_interface_xcm_weight_and_fee_cnt as u32 == + old_xcm_interface_xcm_weight_and_fee_cnt, + "XcmInterface XcmWeightAndFee post-migrate storage count not match" + ); + + Ok(()) + } +} diff --git a/runtime/bifrost-kusama/src/xcm_config.rs b/runtime/bifrost-kusama/src/xcm_config.rs index 32f8a0f5e..7da032d83 100644 --- a/runtime/bifrost-kusama/src/xcm_config.rs +++ b/runtime/bifrost-kusama/src/xcm_config.rs @@ -894,10 +894,7 @@ impl orml_xcm::Config for Runtime { parameter_types! { pub ParachainAccount: AccountId = ParachainInfo::get().into_account_truncating(); - pub ContributionWeight: Weight = Weight::from_parts(milli::(RelayCurrencyId::get()) as u64 , 1000_000u64); - pub UmpTransactFee: Balance = prod_or_test!(milli::(RelayCurrencyId::get()),milli::(RelayCurrencyId::get()) * 100); - pub StatemineTransferFee: Balance = milli::(RelayCurrencyId::get()) * 4; - pub StatemineTransferWeight: Weight = Weight::from_parts(4 * milli::(RelayCurrencyId::get()) as u64, 0); + } impl xcm_interface::Config for Runtime { @@ -909,10 +906,6 @@ impl xcm_interface::Config for Runtime { type ParachainSovereignAccount = ParachainAccount; type XcmExecutor = XcmExecutor; type AccountIdToMultiLocation = BifrostAccountIdToMultiLocation; - type StatemineTransferWeight = StatemineTransferWeight; - type StatemineTransferFee = StatemineTransferFee; - type ContributionWeight = ContributionWeight; - type ContributionFee = UmpTransactFee; type SalpHelper = Salp; type ParachainId = SelfParaChainId; type CallBackTimeOut = ConstU32<10>; diff --git a/runtime/bifrost-polkadot/src/lib.rs b/runtime/bifrost-polkadot/src/lib.rs index 7fd1f0d4e..8b022d026 100644 --- a/runtime/bifrost-polkadot/src/lib.rs +++ b/runtime/bifrost-polkadot/src/lib.rs @@ -26,9 +26,10 @@ #[cfg(feature = "std")] include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); -use core::convert::TryInto; - +pub mod migration; use bifrost_slp::{Ledger, QueryResponseManager}; +use core::convert::TryInto; +use frame_support::pallet_prelude::StorageVersion; // A few exports that help ease life for downstream crates. use cumulus_pallet_parachain_system::{RelayNumberStrictlyIncreases, RelaychainDataProvider}; pub use frame_support::{ @@ -71,7 +72,6 @@ use sp_version::RuntimeVersion; pub mod constants; pub mod weights; use bifrost_asset_registry::{AssetIdMaps, FixedRateOfAsset}; -use bifrost_flexible_fee::misc_fees::{ExtraFeeMatcher, MiscFeeHandler, NameGetter}; use bifrost_runtime_common::{ constants::time::*, dollar, micro, milli, prod_or_test, AuraId, CouncilCollective, EnsureRootOrAllTechnicalCommittee, MoreThanHalfCouncil, SlowAdjustingFeeUpdate, @@ -90,31 +90,30 @@ use frame_support::{ use frame_system::{EnsureRoot, EnsureSigned}; use hex_literal::hex; pub use node_primitives::{ - traits::{CheckSubAccount, FarmingInfo, VtokenMintingInterface, VtokenMintingOperator}, + traits::{ + CheckSubAccount, FarmingInfo, FeeGetter, VtokenMintingInterface, VtokenMintingOperator, + XcmDestWeightAndFeeHandler, + }, AccountId, Amount, AssetIds, Balance, BlockNumber, CurrencyId, CurrencyIdMapping, - DistributionId, ExtraFeeName, Moment, Nonce, ParaId, PoolId, RpcContributionStatus, TimeUnit, - TokenSymbol, DOT_TOKEN_ID, GLMR_TOKEN_ID, + DistributionId, ExtraFeeInfo, ExtraFeeName, Moment, Nonce, ParaId, PoolId, + RpcContributionStatus, TimeUnit, TokenSymbol, DOT_TOKEN_ID, GLMR_TOKEN_ID, }; // zenlink imports +use bifrost_salp::remove_storage::RemoveUnusedQueryIdContributionInfo; use zenlink_protocol::{ AssetBalance, AssetId as ZenlinkAssetId, LocalAssetHandler, MultiAssetsHandler, PairInfo, PairLpGenerate, ZenlinkMultiAssets, }; - // xcm config mod xcm_config; -use bifrost_salp::remove_storage::RemoveUnusedQueryIdContributionInfo; -use bifrost_vtoken_voting::{ - traits::{DerivativeAccountHandler, XcmDestWeightAndFeeHandler}, - DerivativeIndex, -}; +use bifrost_vtoken_voting::{traits::DerivativeAccountHandler, DerivativeIndex}; use orml_traits::{currency::MutationHooks, location::RelativeReserveProvider}; use pallet_xcm::{EnsureResponse, QueryStatus}; use static_assertions::const_assert; use xcm::v3::prelude::*; use xcm_config::{ parachains, BifrostCurrencyIdConvert, BifrostTreasuryAccount, MultiCurrency, SelfParaChainId, - StatemineTransferFee, UmpTransactFee, XcmConfig, XcmRouter, + XcmConfig, XcmRouter, }; use xcm_executor::XcmExecutor; @@ -950,87 +949,54 @@ impl pallet_vesting::Config for Runtime { // Bifrost modules start -// Aggregate name getter to get fee names if the call needs to pay extra fees. -// If any call need to pay extra fees, it should be added as an item here. -// Used together with AggregateExtraFeeFilter below. -pub struct FeeNameGetter; -impl NameGetter for FeeNameGetter { - fn get_name(c: &RuntimeCall) -> ExtraFeeName { +pub struct ExtraFeeMatcher; +impl FeeGetter for ExtraFeeMatcher { + fn get_fee_info(c: &RuntimeCall) -> ExtraFeeInfo { match *c { - RuntimeCall::Salp(bifrost_salp::Call::contribute { .. }) => - ExtraFeeName::SalpContribute, - RuntimeCall::XcmInterface(xcm_interface::Call::transfer_statemine_assets { - .. - }) => ExtraFeeName::StatemineTransfer, - _ => ExtraFeeName::NoExtraFee, - } - } -} - -// Aggregate filter to filter if the call needs to pay extra fees -// If any call need to pay extra fees, it should be added as an item here. -pub struct AggregateExtraFeeFilter; -impl Contains for AggregateExtraFeeFilter { - fn contains(c: &RuntimeCall) -> bool { - match *c { - RuntimeCall::Salp(bifrost_salp::Call::contribute { .. }) => true, + RuntimeCall::Salp(bifrost_salp::Call::contribute { .. }) => ExtraFeeInfo { + extra_fee_name: ExtraFeeName::SalpContribute, + extra_fee_currency: RelayCurrencyId::get(), + }, RuntimeCall::XcmInterface(xcm_interface::Call::transfer_statemine_assets { .. - }) => true, - _ => false, - } - } -} - -pub struct ContributeFeeFilter; -impl Contains for ContributeFeeFilter { - fn contains(c: &RuntimeCall) -> bool { - match *c { - RuntimeCall::Salp(bifrost_salp::Call::contribute { .. }) => true, - _ => false, - } - } -} - -pub struct StatemineTransferFeeFilter; -impl Contains for StatemineTransferFeeFilter { - fn contains(c: &RuntimeCall) -> bool { - match *c { - RuntimeCall::XcmInterface(xcm_interface::Call::transfer_statemine_assets { + }) => ExtraFeeInfo { + extra_fee_name: ExtraFeeName::StatemineTransfer, + extra_fee_currency: RelayCurrencyId::get(), + }, + RuntimeCall::VtokenVoting(bifrost_vtoken_voting::Call::vote { vtoken, .. }) => + ExtraFeeInfo { + extra_fee_name: ExtraFeeName::VoteVtoken, + extra_fee_currency: vtoken, + }, + RuntimeCall::VtokenVoting(bifrost_vtoken_voting::Call::remove_delegator_vote { + vtoken, .. - }) => true, - _ => false, + }) => ExtraFeeInfo { + extra_fee_name: ExtraFeeName::VoteRemoveDelegatorVote, + extra_fee_currency: vtoken, + }, + _ => ExtraFeeInfo::default(), } } } parameter_types! { - pub const AltFeeCurrencyExchangeRate: (u32, u32) = (1, 100); - pub UmpContributeFee: Balance = UmpTransactFee::get(); pub MaxFeeCurrencyOrderListLen: u32 = 50; } -pub type MiscFeeHandlers = ( - MiscFeeHandler, - MiscFeeHandler, -); - impl bifrost_flexible_fee::Config for Runtime { type Currency = Balances; type DexOperator = ZenlinkProtocol; type RuntimeEvent = RuntimeEvent; type MultiCurrency = Currencies; type TreasuryAccount = BifrostTreasuryAccount; - type NativeCurrencyId = NativeCurrencyId; - type AlternativeFeeCurrencyId = RelayCurrencyId; - type AltFeeCurrencyExchangeRate = AltFeeCurrencyExchangeRate; type MaxFeeCurrencyOrderListLen = MaxFeeCurrencyOrderListLen; type OnUnbalanced = Treasury; type WeightInfo = bifrost_flexible_fee::weights::BifrostWeight; - type ExtraFeeMatcher = ExtraFeeMatcher; - type MiscFeeHandler = MiscFeeHandlers; + type ExtraFeeMatcher = ExtraFeeMatcher; type ParachainId = ParachainInfo; type ControlOrigin = EitherOfDiverse; + type XcmWeightAndFeeHandler = XcmInterface; } parameter_types! { @@ -1249,6 +1215,7 @@ impl bifrost_slp::Config for Runtime { type ParachainStaking = (); type XcmTransfer = XTokens; type MaxLengthLimit = MaxLengthLimit; + type XcmWeightAndFeeHandler = XcmInterface; } parameter_types! { @@ -1362,17 +1329,6 @@ parameter_types! { pub const QueryTimeout: BlockNumber = 100; } -pub struct XcmDestWeightAndFee; -impl XcmDestWeightAndFeeHandler for XcmDestWeightAndFee { - fn get_vote(token: CurrencyId) -> Option<(xcm::v3::Weight, Balance)> { - Slp::xcm_dest_weight_and_fee(token, bifrost_slp::XcmOperation::Vote) - } - - fn get_remove_vote(token: CurrencyId) -> Option<(xcm::v3::Weight, Balance)> { - Slp::xcm_dest_weight_and_fee(token, bifrost_slp::XcmOperation::RemoveVote) - } -} - pub struct DerivativeAccount; impl DerivativeAccountHandler for DerivativeAccount { fn check_derivative_index_exists(token: CurrencyId, derivative_index: DerivativeIndex) -> bool { @@ -1407,7 +1363,7 @@ impl bifrost_vtoken_voting::Config for Runtime { type MultiCurrency = Currencies; type ControlOrigin = EitherOfDiverse; type ResponseOrigin = EnsureResponse; - type XcmDestWeightAndFee = XcmDestWeightAndFee; + type XcmDestWeightAndFee = XcmInterface; type DerivativeAccount = DerivativeAccount; type RelaychainBlockNumberProvider = RelaychainDataProvider; type ParachainId = SelfParaChainId; @@ -1755,7 +1711,7 @@ pub type Executive = frame_executive::Executive< frame_system::ChainContext, Runtime, AllPalletsWithSystem, - RemoveUnusedQueryIdContributionInfo, + (RemoveUnusedQueryIdContributionInfo, migration::XcmInterfaceMigration), >; #[cfg(feature = "runtime-benchmarks")] @@ -1897,8 +1853,10 @@ impl_runtime_apis! { } impl bifrost_flexible_fee_rpc_runtime_api::FlexibleFeeRuntimeApi for Runtime { - fn get_fee_token_and_amount(who: AccountId, fee: Balance) -> (CurrencyId, Balance) { - let rs = FlexibleFee::cal_fee_token_and_amount(&who, fee); + fn get_fee_token_and_amount(who: AccountId, fee: Balance, utx: ::Extrinsic) -> (CurrencyId, Balance) { + let call = utx.function; + let rs = FlexibleFee::cal_fee_token_and_amount(&who, fee, &call); + match rs { Ok(val) => val, _ => (CurrencyId::Native(TokenSymbol::BNC), Zero::zero()), diff --git a/runtime/bifrost-polkadot/src/migration.rs b/runtime/bifrost-polkadot/src/migration.rs new file mode 100644 index 000000000..b4ac12144 --- /dev/null +++ b/runtime/bifrost-polkadot/src/migration.rs @@ -0,0 +1,128 @@ +use super::*; +use crate::sp_api_hidden_includes_construct_runtime::hidden_include::dispatch::GetStorageVersion; +#[allow(unused_imports)] +use frame_support::ensure; +use frame_support::traits::OnRuntimeUpgrade; +use node_primitives::traits::XcmDestWeightAndFeeHandler; + +const LOG_TARGET: &str = "XCM-INTERFACE::migration"; + +pub struct XcmInterfaceMigration; +impl OnRuntimeUpgrade for XcmInterfaceMigration { + fn on_runtime_upgrade() -> frame_support::weights::Weight { + // Check the storage version + let onchain_version = XcmInterface::on_chain_storage_version(); + if onchain_version < 2 { + // Transform storage values + // We transform the storage values from the old into the new format. + log::info!( + target: LOG_TARGET, + "Start to migrate XcmInterface storage XcmDestWeightAndFee..." + ); + + let count1 = bifrost_slp::XcmDestWeightAndFee::::iter().count(); + + // 先将Xcm_interface的XcmDestWeightAndFee的值从旧的存储中取出来, + // 然后设置到新的XcmWeightAndFee存储中,新增一个currency_id作为主key + xcm_interface::XcmDestWeightAndFee::::iter().for_each(|(key, value)| { + log::info!( + target: LOG_TARGET, + "Migrated to doublemap for {:?}, {:?}...", + key, + value + ); + + let _ = XcmInterface::set_xcm_dest_weight_and_fee( + RelayCurrencyId::get(), + key, + Some(value), + ); + }); + + // get value from the old SLP XcmDestWeightAndFee storage and set it to the XcmInterface + // storage + let count2 = bifrost_slp::XcmDestWeightAndFee::::iter().count(); + + // iterrate the old SLP XcmDestWeightAndFee storage + bifrost_slp::XcmDestWeightAndFee::::iter().for_each(|(key1, key2, value)| { + log::info!( + target: LOG_TARGET, + "Migrated to XcmInterface XcmWeightAndFee for {:?}, {:?}, {:?}...", + key1, + key2, + value + ); + // set the value to the new XcmInterface storage + let _ = XcmInterface::set_xcm_dest_weight_and_fee(key1, key2, Some(value)); + + // delete the old SLP XcmDestWeightAndFee storage + bifrost_slp::XcmDestWeightAndFee::::remove(key1, key2); + }); + + // delete the old Xcm_interface XcmDestWeightAndFee storage + xcm_interface::XcmDestWeightAndFee::::iter().for_each(|(key, _value)| { + xcm_interface::XcmDestWeightAndFee::::remove(key); + }); + + // Update the storage version + StorageVersion::new(2).put::>(); + + let count = count1 + count2; + // Return the consumed weight + Weight::from( + ::DbWeight::get() + .reads_writes(count as u64 + 1, count as u64 + 1), + ) + } else { + // We don't do anything here. + Weight::zero() + } + } + + #[cfg(feature = "try-runtime")] + fn pre_upgrade() -> Result, &'static str> { + let xcm_interface_xcm_dest_weight_and_fee_cnt = + xcm_interface::XcmDestWeightAndFee::::iter().count(); + // print out the pre-migrate storage count + log::info!( + target: LOG_TARGET, + "XcmInterface XcmDestWeightAndFee pre-migrate storage count: {:?}", + xcm_interface_xcm_dest_weight_and_fee_cnt + ); + + let slp_xcm_dest_weight_and_fee_cnt = + bifrost_slp::XcmDestWeightAndFee::::iter().count(); + log::info!( + target: LOG_TARGET, + "Slp XcmDestWeightAndFee pre-migrate storage count: {:?}", + slp_xcm_dest_weight_and_fee_cnt + ); + + let cnt = + (xcm_interface_xcm_dest_weight_and_fee_cnt + slp_xcm_dest_weight_and_fee_cnt) as u32; + + Ok(cnt.encode()) + } + + #[cfg(feature = "try-runtime")] + fn post_upgrade(cnt: Vec) -> Result<(), &'static str> { + let old_xcm_interface_xcm_weight_and_fee_cnt: u32 = Decode::decode(&mut cnt.as_slice()) + .expect("the state parameter should be something that was generated by pre_upgrade"); + + let new_xcm_interface_xcm_weight_and_fee_cnt = + xcm_interface::XcmWeightAndFee::::iter().count(); + // print out the post-migrate storage count + log::info!( + target: LOG_TARGET, + "XcmInterface XcmWeightAndFee post-migrate storage count: {:?}", + new_xcm_interface_xcm_weight_and_fee_cnt + ); + ensure!( + new_xcm_interface_xcm_weight_and_fee_cnt as u32 == + old_xcm_interface_xcm_weight_and_fee_cnt, + "XcmInterface XcmWeightAndFee post-migrate storage count not match" + ); + + Ok(()) + } +} diff --git a/runtime/bifrost-polkadot/src/xcm_config.rs b/runtime/bifrost-polkadot/src/xcm_config.rs index 7cfb5ac78..29be0e6e2 100644 --- a/runtime/bifrost-polkadot/src/xcm_config.rs +++ b/runtime/bifrost-polkadot/src/xcm_config.rs @@ -714,10 +714,6 @@ impl orml_xcm::Config for Runtime { parameter_types! { pub ParachainAccount: AccountId = ParachainInfo::get().into_account_truncating(); - pub ContributionWeight: Weight = Weight::from_parts(100 * milli::(RelayCurrencyId::get()) as u64,1000_000u64); - pub UmpTransactFee: Balance = milli::(RelayCurrencyId::get()) * 100; - pub StatemineTransferFee: Balance = milli::(RelayCurrencyId::get()) * 400; - pub StatemineTransferWeight:Weight = Weight::from_parts(400 * milli::(RelayCurrencyId::get()) as u64, 0); } impl xcm_interface::Config for Runtime { @@ -729,10 +725,6 @@ impl xcm_interface::Config for Runtime { type ParachainSovereignAccount = ParachainAccount; type XcmExecutor = XcmExecutor; type AccountIdToMultiLocation = BifrostAccountIdToMultiLocation; - type StatemineTransferWeight = StatemineTransferWeight; - type StatemineTransferFee = StatemineTransferFee; - type ContributionWeight = ContributionWeight; - type ContributionFee = UmpTransactFee; type SalpHelper = Salp; type ParachainId = SelfParaChainId; type CallBackTimeOut = ConstU32<10>; From 174717bfbb5eb501debc561dde9a8e2334456e05 Mon Sep 17 00:00:00 2001 From: yooml Date: Fri, 8 Sep 2023 09:36:10 +0800 Subject: [PATCH 4/9] =?UTF-8?q?fix:=20=F0=9F=90=9B=20decision=5Fdeposit=20?= =?UTF-8?q?(#1033)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- runtime/bifrost-kusama/src/governance/tracks.rs | 16 ++++++++-------- .../bifrost-polkadot/src/governance/tracks.rs | 16 ++++++++-------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/runtime/bifrost-kusama/src/governance/tracks.rs b/runtime/bifrost-kusama/src/governance/tracks.rs index 05f3541b9..e4b7bcb64 100644 --- a/runtime/bifrost-kusama/src/governance/tracks.rs +++ b/runtime/bifrost-kusama/src/governance/tracks.rs @@ -39,7 +39,7 @@ const TRACKS_DATA: [(u16, pallet_referenda::TrackInfo); 8] // For Root origin this should generally be just one. max_deciding: 1, // Amount that must be placed on deposit before a decision can be made. - decision_deposit: 5_000 * BNCS, + decision_deposit: 50_000 * BNCS, // Amount of time this must be submitted for before a decision can be made. prepare_period: 2 * HOURS, // Amount of time that a decision may take to be approved prior to cancellation. @@ -61,7 +61,7 @@ const TRACKS_DATA: [(u16, pallet_referenda::TrackInfo); 8] pallet_referenda::TrackInfo { name: "whitelisted_caller", max_deciding: 100, - decision_deposit: 500 * BNCS, + decision_deposit: 5_000 * BNCS, prepare_period: 15 * MINUTES, decision_period: 14 * DAYS, confirm_period: 10 * MINUTES, @@ -81,7 +81,7 @@ const TRACKS_DATA: [(u16, pallet_referenda::TrackInfo); 8] pallet_referenda::TrackInfo { name: "fellowship_admin", max_deciding: 10, - decision_deposit: 250 * BNCS, + decision_deposit: 2_500 * BNCS, prepare_period: 2 * HOURS, decision_period: 14 * DAYS, confirm_period: 3 * HOURS, @@ -95,7 +95,7 @@ const TRACKS_DATA: [(u16, pallet_referenda::TrackInfo); 8] pallet_referenda::TrackInfo { name: "referendum_canceller", max_deciding: 1_000, - decision_deposit: 500 * BNCS, + decision_deposit: 5_000 * BNCS, prepare_period: 2 * HOURS, decision_period: 7 * DAYS, confirm_period: 3 * HOURS, @@ -109,7 +109,7 @@ const TRACKS_DATA: [(u16, pallet_referenda::TrackInfo); 8] pallet_referenda::TrackInfo { name: "referendum_killer", max_deciding: 1_000, - decision_deposit: 2_500 * BNCS, + decision_deposit: 25_000 * BNCS, prepare_period: 2 * HOURS, decision_period: 14 * DAYS, confirm_period: 3 * HOURS, @@ -123,7 +123,7 @@ const TRACKS_DATA: [(u16, pallet_referenda::TrackInfo); 8] pallet_referenda::TrackInfo { name: "validator_election", max_deciding: 10, - decision_deposit: 250 * BNCS, + decision_deposit: 2_500 * BNCS, prepare_period: 2 * HOURS, decision_period: 14 * DAYS, confirm_period: 3 * HOURS, @@ -137,7 +137,7 @@ const TRACKS_DATA: [(u16, pallet_referenda::TrackInfo); 8] pallet_referenda::TrackInfo { name: "system_staking_admin", max_deciding: 10, - decision_deposit: 1_000 * BNCS, + decision_deposit: 10_000 * BNCS, prepare_period: 2 * HOURS, decision_period: 14 * DAYS, confirm_period: 3 * HOURS, @@ -151,7 +151,7 @@ const TRACKS_DATA: [(u16, pallet_referenda::TrackInfo); 8] pallet_referenda::TrackInfo { name: "salp_admin", max_deciding: 10, - decision_deposit: 250 * BNCS, + decision_deposit: 2_500 * BNCS, prepare_period: 15 * MINUTES, decision_period: 14 * DAYS, confirm_period: 1 * HOURS, diff --git a/runtime/bifrost-polkadot/src/governance/tracks.rs b/runtime/bifrost-polkadot/src/governance/tracks.rs index 05f3541b9..e4b7bcb64 100644 --- a/runtime/bifrost-polkadot/src/governance/tracks.rs +++ b/runtime/bifrost-polkadot/src/governance/tracks.rs @@ -39,7 +39,7 @@ const TRACKS_DATA: [(u16, pallet_referenda::TrackInfo); 8] // For Root origin this should generally be just one. max_deciding: 1, // Amount that must be placed on deposit before a decision can be made. - decision_deposit: 5_000 * BNCS, + decision_deposit: 50_000 * BNCS, // Amount of time this must be submitted for before a decision can be made. prepare_period: 2 * HOURS, // Amount of time that a decision may take to be approved prior to cancellation. @@ -61,7 +61,7 @@ const TRACKS_DATA: [(u16, pallet_referenda::TrackInfo); 8] pallet_referenda::TrackInfo { name: "whitelisted_caller", max_deciding: 100, - decision_deposit: 500 * BNCS, + decision_deposit: 5_000 * BNCS, prepare_period: 15 * MINUTES, decision_period: 14 * DAYS, confirm_period: 10 * MINUTES, @@ -81,7 +81,7 @@ const TRACKS_DATA: [(u16, pallet_referenda::TrackInfo); 8] pallet_referenda::TrackInfo { name: "fellowship_admin", max_deciding: 10, - decision_deposit: 250 * BNCS, + decision_deposit: 2_500 * BNCS, prepare_period: 2 * HOURS, decision_period: 14 * DAYS, confirm_period: 3 * HOURS, @@ -95,7 +95,7 @@ const TRACKS_DATA: [(u16, pallet_referenda::TrackInfo); 8] pallet_referenda::TrackInfo { name: "referendum_canceller", max_deciding: 1_000, - decision_deposit: 500 * BNCS, + decision_deposit: 5_000 * BNCS, prepare_period: 2 * HOURS, decision_period: 7 * DAYS, confirm_period: 3 * HOURS, @@ -109,7 +109,7 @@ const TRACKS_DATA: [(u16, pallet_referenda::TrackInfo); 8] pallet_referenda::TrackInfo { name: "referendum_killer", max_deciding: 1_000, - decision_deposit: 2_500 * BNCS, + decision_deposit: 25_000 * BNCS, prepare_period: 2 * HOURS, decision_period: 14 * DAYS, confirm_period: 3 * HOURS, @@ -123,7 +123,7 @@ const TRACKS_DATA: [(u16, pallet_referenda::TrackInfo); 8] pallet_referenda::TrackInfo { name: "validator_election", max_deciding: 10, - decision_deposit: 250 * BNCS, + decision_deposit: 2_500 * BNCS, prepare_period: 2 * HOURS, decision_period: 14 * DAYS, confirm_period: 3 * HOURS, @@ -137,7 +137,7 @@ const TRACKS_DATA: [(u16, pallet_referenda::TrackInfo); 8] pallet_referenda::TrackInfo { name: "system_staking_admin", max_deciding: 10, - decision_deposit: 1_000 * BNCS, + decision_deposit: 10_000 * BNCS, prepare_period: 2 * HOURS, decision_period: 14 * DAYS, confirm_period: 3 * HOURS, @@ -151,7 +151,7 @@ const TRACKS_DATA: [(u16, pallet_referenda::TrackInfo); 8] pallet_referenda::TrackInfo { name: "salp_admin", max_deciding: 10, - decision_deposit: 250 * BNCS, + decision_deposit: 2_500 * BNCS, prepare_period: 15 * MINUTES, decision_period: 14 * DAYS, confirm_period: 1 * HOURS, From 307cf70049b0d94a0366eb2845b5a6f43b2b7c0e Mon Sep 17 00:00:00 2001 From: Edwin Date: Fri, 8 Sep 2023 12:51:39 +0800 Subject: [PATCH 5/9] Benchmarking: vtoken-voting (#1034) * Fix * Add trait `DerivativeAccountHandler` * Impl `DerivativeAccountHandler` * Fix benchmark * Update DerivativeAccountHandler implement * Fix * Fix benchmark * Fix benchmark * Fix benchmark `on_initialize` * Update weights.rs * Update release.yml * Fix weight * Fix XCM weight * More tests * Fix * Fix --- .github/workflows/release.yml | 2 +- Cargo.lock | 3 +- .../src/kusama_cross_chain_transact.rs | 13 +- .../bifrost-kusama/src/vtoken_voting.rs | 4 +- node/primitives/Cargo.toml | 1 + node/primitives/src/lib.rs | 2 + node/primitives/src/traits.rs | 27 +- pallets/slp/Cargo.toml | 1 + pallets/slp/src/lib.rs | 77 ++- pallets/vtoken-voting/Cargo.toml | 7 +- pallets/vtoken-voting/src/benchmarking.rs | 299 ++++++++++- pallets/vtoken-voting/src/lib.rs | 48 +- pallets/vtoken-voting/src/mock.rs | 8 +- pallets/vtoken-voting/src/tests.rs | 91 +++- pallets/vtoken-voting/src/traits.rs | 19 - pallets/vtoken-voting/src/weights.rs | 483 +++++++++++++----- runtime/bifrost-kusama/src/lib.rs | 35 +- runtime/bifrost-polkadot/src/lib.rs | 35 +- 18 files changed, 892 insertions(+), 263 deletions(-) delete mode 100644 pallets/vtoken-voting/src/traits.rs diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 0455a10b4..3a88ae70b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -93,7 +93,7 @@ jobs: ${{ github.workspace }}/artifacts/bifrost_polkadot_runtime.compact.compressed.wasm - uses: 8398a7/action-slack@v3 - if: failure() + if: always() with: status: ${{ job.status }} fields: repo,author,eventName,workflow,ref,commit diff --git a/Cargo.lock b/Cargo.lock index c59217f2b..e5a4927f4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1640,9 +1640,10 @@ dependencies = [ name = "bifrost-vtoken-voting" version = "0.8.0" dependencies = [ + "assert_matches", "bifrost-currencies", + "bifrost-slp", "cumulus-primitives-core", - "env_logger 0.10.0", "frame-benchmarking", "frame-support", "frame-system", diff --git a/integration-tests/bifrost-kusama/src/kusama_cross_chain_transact.rs b/integration-tests/bifrost-kusama/src/kusama_cross_chain_transact.rs index 1c9047b56..064828546 100644 --- a/integration-tests/bifrost-kusama/src/kusama_cross_chain_transact.rs +++ b/integration-tests/bifrost-kusama/src/kusama_cross_chain_transact.rs @@ -67,9 +67,7 @@ fn relaychain_transact_works() { }); Bifrost::execute_with(|| { - // QueryStatus::Pending { responder: V3(MultiLocation { parents: 1, interior: Here }), - // maybe_match_querier: Some(V3(MultiLocation { parents: 0, interior: Here })), - // maybe_notify: Some((0, 7)), timeout: 100 } let query_id = + let notify_vote_call_weight = notify_vote_call.get_dispatch_info().weight; let query_id = pallet_xcm::Pallet::::new_notify_query( MultiLocation::parent(), notify_vote_call, @@ -77,23 +75,20 @@ fn relaychain_transact_works() { Here, ); - // QueryResponse { query_id: 0, response: DispatchResult(Success), max_weight: Weight { - // ref_time: 4000000000, proof_size: 0 }, querier: Some(MultiLocation { parents: 0, - // interior: Here }) } let asset: MultiAsset = - MultiAsset { id: Concrete(MultiLocation::here()), fun: Fungible(4000000000) }; + MultiAsset { id: Concrete(MultiLocation::here()), fun: Fungible(517318631) }; let msg = Xcm(vec![ WithdrawAsset(asset.clone().into()), BuyExecution { fees: asset, weight_limit: Unlimited }, Transact { origin_kind: OriginKind::SovereignAccount, - require_weight_at_most: Weight::from_parts(4000000000, 100000), + require_weight_at_most: Weight::from_parts(961496000, 83866), call: vote_call.encode().into(), }, ReportTransactStatus(QueryResponseInfo { destination: MultiLocation::from(X1(Parachain(2001))), query_id, - max_weight: Weight::from_parts(3000000, 0), + max_weight: notify_vote_call_weight, }), RefundSurplus, DepositAsset { diff --git a/integration-tests/bifrost-kusama/src/vtoken_voting.rs b/integration-tests/bifrost-kusama/src/vtoken_voting.rs index 878bf57ff..63b45c705 100644 --- a/integration-tests/bifrost-kusama/src/vtoken_voting.rs +++ b/integration-tests/bifrost-kusama/src/vtoken_voting.rs @@ -63,7 +63,7 @@ fn vote_works() { RuntimeOrigin::root(), MultiAddress::Id(ALICE.into()), VKSM, - 10_000_000_000_000u64.into(), + u64::MAX.into(), Zero::zero(), )); let token = CurrencyId::to_token(&vtoken).unwrap(); @@ -86,7 +86,7 @@ fn vote_works() { delegator_active_staking_maximum: 0u32.into(), validators_reward_maximum: 0u32, delegation_amount_minimum: 0u32.into(), - delegators_maximum: 10u16, + delegators_maximum: u16::MAX, validators_maximum: 0u16, }) )); diff --git a/node/primitives/Cargo.toml b/node/primitives/Cargo.toml index 47447d30b..dd44acaaf 100644 --- a/node/primitives/Cargo.toml +++ b/node/primitives/Cargo.toml @@ -43,3 +43,4 @@ with-bifrost-runtime = [ with-bifrost-kusama-runtime = [] with-bifrost-polkadot-runtime = [] with-all-runtime = ["with-bifrost-runtime"] +runtime-benchmarks = [] \ No newline at end of file diff --git a/node/primitives/src/lib.rs b/node/primitives/src/lib.rs index f74a23b72..702e71796 100644 --- a/node/primitives/src/lib.rs +++ b/node/primitives/src/lib.rs @@ -136,6 +136,8 @@ pub type TrieIndex = u32; /// Distribution Id pub type DistributionId = u32; +pub type DerivativeIndex = u16; + #[derive( Encode, Decode, Eq, PartialEq, Copy, Clone, RuntimeDebug, PartialOrd, Ord, scale_info::TypeInfo, )] diff --git a/node/primitives/src/traits.rs b/node/primitives/src/traits.rs index 00b2dafd6..6d1a6c292 100644 --- a/node/primitives/src/traits.rs +++ b/node/primitives/src/traits.rs @@ -21,8 +21,8 @@ #![allow(clippy::unnecessary_cast)] use crate::{ - AssetIds, ExtraFeeInfo, LeasePeriod, ParaId, PoolId, RedeemType, TokenId, TokenSymbol, - XcmInterfaceOperation, + AssetIds, DerivativeIndex, ExtraFeeInfo, LeasePeriod, ParaId, PoolId, RedeemType, TokenId, + TokenSymbol, XcmInterfaceOperation, }; use codec::{Decode, Encode, FullCodec}; use frame_support::{ @@ -463,3 +463,26 @@ where pub trait FeeGetter { fn get_fee_info(call: &RuntimeCall) -> ExtraFeeInfo; } + +pub trait DerivativeAccountHandler { + fn check_derivative_index_exists(token: CurrencyId, derivative_index: DerivativeIndex) -> bool; + + fn get_multilocation( + token: CurrencyId, + derivative_index: DerivativeIndex, + ) -> Option; + + fn get_stake_info( + token: CurrencyId, + derivative_index: DerivativeIndex, + ) -> Option<(Balance, Balance)>; + + #[cfg(feature = "runtime-benchmarks")] + fn init_minimums_and_maximums(token: CurrencyId); + + #[cfg(feature = "runtime-benchmarks")] + fn new_delegator_ledger(token: CurrencyId, who: xcm::v3::MultiLocation); + + #[cfg(feature = "runtime-benchmarks")] + fn add_delegator(token: CurrencyId, index: DerivativeIndex, who: xcm::v3::MultiLocation); +} diff --git a/pallets/slp/Cargo.toml b/pallets/slp/Cargo.toml index 04a433740..3a259dd69 100644 --- a/pallets/slp/Cargo.toml +++ b/pallets/slp/Cargo.toml @@ -81,5 +81,6 @@ runtime-benchmarks = [ "frame-system/runtime-benchmarks", "pallet-xcm/runtime-benchmarks", "xcm-builder/runtime-benchmarks", + "node-primitives/runtime-benchmarks", ] try-runtime = [ "frame-support/try-runtime" ] diff --git a/pallets/slp/src/lib.rs b/pallets/slp/src/lib.rs index ee207f01a..e70888a7c 100644 --- a/pallets/slp/src/lib.rs +++ b/pallets/slp/src/lib.rs @@ -32,7 +32,7 @@ pub use crate::{ Junctions::X1, }; use cumulus_primitives_core::{relay_chain::HashT, ParaId}; -use frame_support::{pallet_prelude::*, weights::Weight}; +use frame_support::{pallet_prelude::*, traits::Contains, weights::Weight}; use frame_system::{ pallet_prelude::{BlockNumberFor, OriginFor}, RawOrigin, @@ -40,8 +40,8 @@ use frame_system::{ use node_primitives::{ currency::{BNC, KSM, MOVR, PHA}, traits::XcmDestWeightAndFeeHandler, - CurrencyId, CurrencyIdExt, SlpOperator, TimeUnit, VtokenMintingOperator, - XcmInterfaceOperation as XcmOperation, ASTR, DOT, FIL, GLMR, + CurrencyId, CurrencyIdExt, DerivativeAccountHandler, DerivativeIndex, SlpOperator, TimeUnit, + VtokenMintingOperator, XcmInterfaceOperation as XcmOperation, ASTR, DOT, FIL, GLMR, }; use orml_traits::MultiCurrency; use parachain_staking::ParachainStakingInterface; @@ -2383,3 +2383,74 @@ pub mod pallet { } } } + +pub struct DerivativeAccountProvider(PhantomData<(T, F)>); + +impl>> + DerivativeAccountHandler, BalanceOf> for DerivativeAccountProvider +{ + fn check_derivative_index_exists( + token: CurrencyIdOf, + derivative_index: DerivativeIndex, + ) -> bool { + Pallet::::get_delegator_multilocation_by_index(token, derivative_index).is_some() + } + + fn get_multilocation( + token: CurrencyIdOf, + derivative_index: DerivativeIndex, + ) -> Option { + Pallet::::get_delegator_multilocation_by_index(token, derivative_index) + } + + fn get_stake_info( + token: CurrencyIdOf, + derivative_index: DerivativeIndex, + ) -> Option<(BalanceOf, BalanceOf)> { + Self::get_multilocation(token, derivative_index).and_then(|location| { + Pallet::::get_delegator_ledger(token, location).and_then(|ledger| match ledger { + Ledger::Substrate(l) if F::contains(&token) => Some((l.total, l.active)), + _ => None, + }) + }) + } + + #[cfg(feature = "runtime-benchmarks")] + fn init_minimums_and_maximums(currency_id: CurrencyIdOf) { + MinimumsAndMaximums::::insert( + currency_id, + MinimumsMaximums { + delegator_bonded_minimum: 0u32.into(), + bond_extra_minimum: 0u32.into(), + unbond_minimum: 0u32.into(), + rebond_minimum: 0u32.into(), + unbond_record_maximum: 0u32, + validators_back_maximum: 0u32, + delegator_active_staking_maximum: 0u32.into(), + validators_reward_maximum: 0u32, + delegation_amount_minimum: 0u32.into(), + delegators_maximum: u16::MAX, + validators_maximum: 0u16, + }, + ); + } + + #[cfg(feature = "runtime-benchmarks")] + fn new_delegator_ledger(currency_id: CurrencyIdOf, who: MultiLocation) { + DelegatorLedgers::::insert( + currency_id, + &who, + Ledger::Substrate(SubstrateLedger { + account: Parent.into(), + total: u32::MAX.into(), + active: u32::MAX.into(), + unlocking: vec![], + }), + ); + } + + #[cfg(feature = "runtime-benchmarks")] + fn add_delegator(currency_id: CurrencyIdOf, index: DerivativeIndex, who: MultiLocation) { + Pallet::::inner_add_delegator(index, &who, currency_id).unwrap(); + } +} diff --git a/pallets/vtoken-voting/Cargo.toml b/pallets/vtoken-voting/Cargo.toml index 70a142695..b1e7ca04c 100644 --- a/pallets/vtoken-voting/Cargo.toml +++ b/pallets/vtoken-voting/Cargo.toml @@ -8,6 +8,7 @@ edition = "2021" targets = ["x86_64-unknown-linux-gnu"] [dependencies] +assert_matches = "1.3.0" codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false, features = [ "derive", ] } @@ -27,13 +28,12 @@ sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0 sp-std = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.42", default-features = false } sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.42", default-features = false } xcm = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.42", default-features = false } +bifrost-slp = { path = "../slp", default-features = false } [dev-dependencies] -env_logger = "0.10.0" orml-tokens = "0.4.1-dev" bifrost-currencies = { workspace = true } pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.42"} -pallet-xcm = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.42" } sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.42" } xcm-executor = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.42" } xcm-builder = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.42" } @@ -54,6 +54,7 @@ std = [ "sp-io/std", "sp-runtime/std", "xcm/std", + "bifrost-slp/std", ] kusama = [] polkadot = [] @@ -61,5 +62,7 @@ runtime-benchmarks = [ "frame-benchmarking/runtime-benchmarks", "pallet-conviction-voting/runtime-benchmarks", "pallet-xcm/runtime-benchmarks", + "xcm-builder/runtime-benchmarks", + "bifrost-slp/runtime-benchmarks", ] try-runtime = ["frame-support/try-runtime"] diff --git a/pallets/vtoken-voting/src/benchmarking.rs b/pallets/vtoken-voting/src/benchmarking.rs index 475161618..2aecac291 100644 --- a/pallets/vtoken-voting/src/benchmarking.rs +++ b/pallets/vtoken-voting/src/benchmarking.rs @@ -17,10 +17,20 @@ // along with this program. If not, see . use crate::*; +use assert_matches::assert_matches; use frame_benchmarking::v2::*; use frame_system::RawOrigin; -use node_primitives::currency::VKSM; +use node_primitives::{currency::VKSM, XcmInterfaceOperation as XcmOperation}; use pallet_conviction_voting::{Conviction, Vote}; +use sp_runtime::traits::Bounded; + +const SEED: u32 = 0; + +fn funded_account(name: &'static str, index: u32) -> AccountIdOf { + let caller = account(name, index, SEED); + T::MultiCurrency::deposit(VKSM, &caller, BalanceOf::::max_value()).unwrap(); + caller +} fn account_vote(b: BalanceOf) -> AccountVote> { let v = Vote { aye: true, conviction: Conviction::Locked1x }; @@ -28,30 +38,128 @@ fn account_vote(b: BalanceOf) -> AccountVote> { AccountVote::Standard { vote: v, balance: b } } -#[benchmarks] +fn init_vote(vtoken: CurrencyIdOf) -> Result<(), BenchmarkError> { + let derivative_index = 0; + let token = CurrencyId::to_token(&vtoken).unwrap(); + T::XcmDestWeightAndFee::set_xcm_dest_weight_and_fee( + token, + XcmOperation::VoteVtoken, + Some((Weight::from_parts(4000000000, 100000), 4000000000u32.into())), + )?; + T::DerivativeAccount::init_minimums_and_maximums(token); + T::DerivativeAccount::add_delegator(token, derivative_index, Parent.into()); + T::DerivativeAccount::new_delegator_ledger(token, Parent.into()); + Pallet::::set_undeciding_timeout(RawOrigin::Root.into(), vtoken, Zero::zero())?; + Pallet::::set_delegator_role( + RawOrigin::Root.into(), + vtoken, + derivative_index, + VoteRole::Standard { aye: true, conviction: Conviction::Locked1x }, + )?; + + Ok(()) +} + +#[benchmarks(where T::MaxVotes: core::fmt::Debug)] mod benchmarks { use super::*; #[benchmark] - fn vote() -> Result<(), BenchmarkError> { - let caller = whitelisted_caller(); - let origin = RawOrigin::Signed(caller); + fn vote_new() -> Result<(), BenchmarkError> { + let caller = funded_account::("caller", 0); + whitelist_account!(caller); let vtoken = VKSM; let poll_index = 0u32; - let account_vote = account_vote::(100u32.into()); + let vote = account_vote::(100u32.into()); + let control_origin = + T::ControlOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; + + init_vote::(vtoken)?; + let r = T::MaxVotes::get() - 1; + let response = Response::DispatchResult(MaybeErrorCode::Success); + for (i, index) in (0..T::MaxVotes::get()).collect::>().iter().skip(1).enumerate() { + Pallet::::on_initialize(Zero::zero()); + Pallet::::vote(RawOrigin::Signed(caller.clone()).into(), vtoken, *index, vote)?; + Pallet::::notify_vote( + control_origin.clone() as ::RuntimeOrigin, + i as QueryId, + response.clone(), + )?; + } + let votes = match VotingFor::::get(&caller) { + Voting::Casting(Casting { votes, .. }) => votes, + _ => return Err("Votes are not direct".into()), + }; + assert_eq!(votes.len(), r as usize, "Votes were not recorded."); + + #[extrinsic_call] + Pallet::::vote(RawOrigin::Signed(caller.clone()), vtoken, poll_index, vote); + + assert_matches!( + VotingFor::::get(&caller), + Voting::Casting(Casting { votes, .. }) if votes.len() == (r + 1) as usize + ); + + Ok(()) + } + + #[benchmark] + fn vote_existing() -> Result<(), BenchmarkError> { + let caller = funded_account::("caller", 0); + whitelist_account!(caller); + let vtoken = VKSM; + let old_vote = account_vote::(100u32.into()); + let control_origin = + T::ControlOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; + + init_vote::(vtoken)?; + let r = 50; + let response = Response::DispatchResult(MaybeErrorCode::Success); + for index in (0..r).collect::>().iter() { + Pallet::::vote(RawOrigin::Signed(caller.clone()).into(), vtoken, *index, old_vote)?; + Pallet::::notify_vote( + control_origin.clone() as ::RuntimeOrigin, + *index as QueryId, + response.clone(), + )?; + } + let votes = match VotingFor::::get(&caller) { + Voting::Casting(Casting { votes, .. }) => votes, + _ => return Err("Votes are not direct".into()), + }; + assert_eq!(votes.len(), r as usize, "Votes were not recorded."); + let poll_index = 1u32; + let new_vote = account_vote::(200u32.into()); #[extrinsic_call] - vote(origin, vtoken, poll_index, account_vote); + Pallet::::vote(RawOrigin::Signed(caller.clone()), vtoken, poll_index, new_vote); + + assert_matches!( + VotingFor::::get(&caller), + Voting::Casting(Casting { votes, .. }) if votes.len() == r as usize + ); Ok(()) } #[benchmark] pub fn unlock() -> Result<(), BenchmarkError> { - let caller = whitelisted_caller(); + let caller = funded_account::("caller", 0); + whitelist_account!(caller); let origin = RawOrigin::Signed(caller); let vtoken = VKSM; let poll_index = 0u32; + let vote = account_vote::(100u32.into()); + + init_vote::(vtoken)?; + Pallet::::vote(origin.clone().into(), vtoken, poll_index, vote)?; + Pallet::::set_referendum_status( + RawOrigin::Root.into(), + vtoken, + poll_index, + ReferendumInfo::Completed(0u32.into()), + )?; + Pallet::::set_vote_locking_period(RawOrigin::Root.into(), vtoken, 0u32.into())?; #[extrinsic_call] _(origin, vtoken, poll_index); @@ -59,6 +167,181 @@ mod benchmarks { Ok(()) } + #[benchmark] + pub fn remove_delegator_vote() -> Result<(), BenchmarkError> { + let caller = funded_account::("caller", 0); + whitelist_account!(caller); + let origin = RawOrigin::Signed(caller); + let vtoken = VKSM; + let poll_index = 0u32; + let vote = account_vote::(100u32.into()); + let derivative_index = 0u16; + + init_vote::(vtoken)?; + Pallet::::vote(origin.clone().into(), vtoken, poll_index, vote)?; + Pallet::::set_referendum_status( + RawOrigin::Root.into(), + vtoken, + poll_index, + ReferendumInfo::Completed(0u32.into()), + )?; + Pallet::::set_vote_locking_period(RawOrigin::Root.into(), vtoken, 0u32.into())?; + let token = CurrencyId::to_token(&vtoken).unwrap(); + T::XcmDestWeightAndFee::set_xcm_dest_weight_and_fee( + token, + XcmOperation::VoteRemoveDelegatorVote, + Some((Weight::from_parts(4000000000, 100000), 4000000000u32.into())), + )?; + + #[extrinsic_call] + _(origin, vtoken, poll_index, derivative_index); + + Ok(()) + } + + #[benchmark] + pub fn kill_referendum() -> Result<(), BenchmarkError> { + let origin = + T::ControlOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; + let vtoken = VKSM; + let poll_index = 0u32; + let vote = account_vote::(100u32.into()); + + init_vote::(vtoken)?; + let caller = funded_account::("caller", 0); + whitelist_account!(caller); + let origin_caller = RawOrigin::Signed(caller); + Pallet::::vote(origin_caller.into(), vtoken, poll_index, vote)?; + Pallet::::set_referendum_status( + RawOrigin::Root.into(), + vtoken, + poll_index, + ReferendumInfo::Completed(0u32.into()), + )?; + + #[extrinsic_call] + _(origin as ::RuntimeOrigin, vtoken, poll_index); + + Ok(()) + } + + #[benchmark] + pub fn set_delegator_role() -> Result<(), BenchmarkError> { + let origin = + T::ControlOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; + let vtoken = VKSM; + let derivative_index = 10; + let vote_role = VoteRole::SplitAbstain; + + init_vote::(vtoken)?; + T::DerivativeAccount::add_delegator( + CurrencyId::to_token(&vtoken).unwrap(), + derivative_index, + Parent.into(), + ); + + #[extrinsic_call] + _( + origin as ::RuntimeOrigin, + vtoken, + derivative_index, + vote_role, + ); + + Ok(()) + } + + #[benchmark] + pub fn set_referendum_status() -> Result<(), BenchmarkError> { + let origin = + T::ControlOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; + let vtoken = VKSM; + let poll_index = 0u32; + let info = ReferendumInfo::Completed(>::block_number()); + + init_vote::(vtoken)?; + let caller = funded_account::("caller", 0); + whitelist_account!(caller); + let origin_caller = RawOrigin::Signed(caller); + let vote = account_vote::(100u32.into()); + Pallet::::vote(origin_caller.into(), vtoken, poll_index, vote)?; + + #[extrinsic_call] + _(origin as ::RuntimeOrigin, vtoken, poll_index, info); + + Ok(()) + } + + #[benchmark] + pub fn set_undeciding_timeout() -> Result<(), BenchmarkError> { + let origin = + T::ControlOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; + let vtoken = VKSM; + let vote_locking_period = 100u32.into(); + + #[extrinsic_call] + _(origin as ::RuntimeOrigin, vtoken, vote_locking_period); + + Ok(()) + } + + #[benchmark] + pub fn set_vote_locking_period() -> Result<(), BenchmarkError> { + let origin = + T::ControlOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; + let vtoken = VKSM; + let undeciding_timeout = 100u32.into(); + + #[extrinsic_call] + _(origin as ::RuntimeOrigin, vtoken, undeciding_timeout); + + Ok(()) + } + + #[benchmark] + pub fn notify_vote() -> Result<(), BenchmarkError> { + let origin = + T::ResponseOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; + let vtoken = VKSM; + let poll_index = 0u32; + let query_id = 1u64; + let response = Response::DispatchResult(MaybeErrorCode::Success); + + init_vote::(vtoken)?; + let caller = funded_account::("caller", 0); + whitelist_account!(caller); + let origin_caller = RawOrigin::Signed(caller); + let vote = account_vote::(100u32.into()); + Pallet::::vote(origin_caller.into(), vtoken, poll_index, vote)?; + + #[extrinsic_call] + _(origin as ::RuntimeOrigin, query_id, response); + + Ok(()) + } + + #[benchmark] + pub fn notify_remove_delegator_vote() -> Result<(), BenchmarkError> { + let origin = + T::ResponseOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; + let vtoken = VKSM; + let poll_index = 0u32; + let query_id = 1u64; + let response = Response::DispatchResult(MaybeErrorCode::Success); + + init_vote::(vtoken)?; + let caller = funded_account::("caller", 0); + whitelist_account!(caller); + let origin_caller = RawOrigin::Signed(caller); + let vote = account_vote::(100u32.into()); + Pallet::::vote(origin_caller.into(), vtoken, poll_index, vote)?; + + #[extrinsic_call] + _(origin as ::RuntimeOrigin, query_id, response); + + Ok(()) + } + // This line generates test cases for benchmarking, and could be run by: // `cargo test -p pallet-example-basic --all-features`, you will see one line per case: // `test benchmarking::bench_sort_vector ... ok` diff --git a/pallets/vtoken-voting/src/lib.rs b/pallets/vtoken-voting/src/lib.rs index 5e0446e42..5f352eb59 100644 --- a/pallets/vtoken-voting/src/lib.rs +++ b/pallets/vtoken-voting/src/lib.rs @@ -28,7 +28,6 @@ mod mock; mod tests; mod call; -pub mod traits; mod vote; pub mod weights; @@ -39,14 +38,15 @@ pub use crate::{ }; use cumulus_primitives_core::{ParaId, QueryId, Response}; use frame_support::{ + dispatch::GetDispatchInfo, pallet_prelude::*, traits::{Get, LockIdentifier}, }; use frame_system::pallet_prelude::{BlockNumberFor, *}; use node_primitives::{ currency::{VDOT, VKSM}, - traits::XcmDestWeightAndFeeHandler, - CurrencyId, XcmInterfaceOperation, + traits::{DerivativeAccountHandler, XcmDestWeightAndFeeHandler}, + CurrencyId, DerivativeIndex, XcmInterfaceOperation, }; use orml_traits::{MultiCurrency, MultiLockableCurrency}; pub use pallet::*; @@ -56,14 +56,11 @@ use sp_runtime::{ ArithmeticError, }; use sp_std::prelude::*; -pub use traits::*; use weights::WeightInfo; use xcm::v3::{prelude::*, Weight as XcmWeight}; const CONVICTION_VOTING_ID: LockIdentifier = *b"vtvoting"; -pub type DerivativeIndex = u16; - type PollIndex = u32; pub type AccountIdOf = ::AccountId; @@ -94,7 +91,9 @@ pub mod pallet { type RuntimeOrigin: IsType<::RuntimeOrigin> + Into::RuntimeOrigin>>; - type RuntimeCall: IsType<::RuntimeCall> + From>; + type RuntimeCall: IsType<::RuntimeCall> + + From> + + GetDispatchInfo; type MultiCurrency: MultiLockableCurrency, CurrencyId = CurrencyId>; @@ -105,9 +104,9 @@ pub mod pallet { Success = MultiLocation, >; - type XcmDestWeightAndFee: XcmDestWeightAndFeeHandler>; + type XcmDestWeightAndFee: XcmDestWeightAndFeeHandler, BalanceOf>; - type DerivativeAccount: DerivativeAccountHandler; + type DerivativeAccount: DerivativeAccountHandler, BalanceOf>; type RelaychainBlockNumberProvider: BlockNumberProvider>; @@ -331,9 +330,12 @@ pub mod pallet { #[pallet::hooks] impl Hooks> for Pallet { fn on_initialize(_: BlockNumberFor) -> Weight { + let mut weight = T::DbWeight::get().reads(1); let relay_current_block_number = T::RelaychainBlockNumberProvider::current_block_number(); - ReferendumTimeout::::get(relay_current_block_number).iter().for_each( + + weight += T::DbWeight::get().reads(1); + ReferendumTimeout::::take(relay_current_block_number).iter().for_each( |(vtoken, poll_index)| { ReferendumInfoFor::::mutate( vtoken, @@ -341,21 +343,25 @@ pub mod pallet { |maybe_info| match maybe_info { Some(info) => if let ReferendumInfo::Ongoing(_) = info { - *info = ReferendumInfo::Completed(relay_current_block_number); + *info = ReferendumInfo::Completed( + relay_current_block_number.into(), + ); }, None => {}, }, ); + weight += T::DbWeight::get().reads_writes(1, 1); }, ); - Zero::zero() + + weight } } #[pallet::call] impl Pallet { #[pallet::call_index(0)] - #[pallet::weight(::WeightInfo::vote())] + #[pallet::weight(::WeightInfo::vote_new().max(::WeightInfo::vote_existing()))] pub fn vote( origin: OriginFor, vtoken: CurrencyIdOf, @@ -872,16 +878,18 @@ pub mod pallet { derivative_index: DerivativeIndex, call: RelayCall, notify_call: Call, - weight: XcmWeight, + transact_weight: XcmWeight, extra_fee: BalanceOf, f: impl FnOnce(QueryId) -> (), ) -> DispatchResult { let responder = MultiLocation::parent(); let now = frame_system::Pallet::::block_number(); let timeout = now.saturating_add(T::QueryTimeout::get()); + let notify_runtime_call = ::RuntimeCall::from(notify_call); + let notify_call_weight = notify_runtime_call.get_dispatch_info().weight; let query_id = pallet_xcm::Pallet::::new_notify_query( responder, - ::RuntimeCall::from(notify_call), + notify_runtime_call, timeout, Here, ); @@ -891,7 +899,8 @@ pub mod pallet { as UtilityCall>>::as_derivative(derivative_index, call) .encode(), extra_fee, - weight, + transact_weight, + notify_call_weight, query_id, )?; @@ -904,7 +913,8 @@ pub mod pallet { fn construct_xcm_message( call: Vec, extra_fee: BalanceOf, - weight: XcmWeight, + transact_weight: XcmWeight, + notify_call_weight: XcmWeight, query_id: QueryId, ) -> Result, Error> { let para_id = T::ParachainId::get().into(); @@ -917,13 +927,13 @@ pub mod pallet { BuyExecution { fees: asset, weight_limit: Unlimited }, Transact { origin_kind: OriginKind::SovereignAccount, - require_weight_at_most: weight, + require_weight_at_most: transact_weight, call: call.into(), }, ReportTransactStatus(QueryResponseInfo { destination: MultiLocation::from(X1(Parachain(para_id))), query_id, - max_weight: weight, + max_weight: notify_call_weight, }), RefundSurplus, DepositAsset { diff --git a/pallets/vtoken-voting/src/mock.rs b/pallets/vtoken-voting/src/mock.rs index 25c41b2b3..a83c0f3eb 100644 --- a/pallets/vtoken-voting/src/mock.rs +++ b/pallets/vtoken-voting/src/mock.rs @@ -19,7 +19,7 @@ // Ensure we're `no_std` when compiling for Wasm. use crate as vtoken_voting; -use crate::{traits::DerivativeAccountHandler, BalanceOf, DerivativeIndex, DispatchResult}; +use crate::{BalanceOf, DerivativeAccountHandler, DerivativeIndex, DispatchResult}; use cumulus_primitives_core::ParaId; use frame_support::{ ord_parameter_types, @@ -255,7 +255,7 @@ impl XcmDestWeightAndFeeHandler> for XcmDestWeigh } pub struct DerivativeAccount; -impl DerivativeAccountHandler for DerivativeAccount { +impl DerivativeAccountHandler for DerivativeAccount { fn check_derivative_index_exists( _token: CurrencyId, _derivative_index: DerivativeIndex, @@ -275,7 +275,7 @@ impl DerivativeAccountHandler for DerivativeAccount { derivative_index: DerivativeIndex, ) -> Option<(Balance, Balance)> { Self::get_multilocation(token, derivative_index) - .and_then(|_location| Some((100u32.into(), 100u32.into()))) + .and_then(|_location| Some((u32::MAX.into(), u32::MAX.into()))) } } @@ -309,7 +309,7 @@ impl vtoken_voting::Config for Runtime { type XcmDestWeightAndFee = XcmDestWeightAndFee; type DerivativeAccount = DerivativeAccount; type RelaychainBlockNumberProvider = RelaychainDataProvider; - type MaxVotes = ConstU32<3>; + type MaxVotes = ConstU32<256>; type ParachainId = ParachainId; type QueryTimeout = QueryTimeout; type WeightInfo = (); diff --git a/pallets/vtoken-voting/src/tests.rs b/pallets/vtoken-voting/src/tests.rs index 109e81998..acd4cac82 100644 --- a/pallets/vtoken-voting/src/tests.rs +++ b/pallets/vtoken-voting/src/tests.rs @@ -55,10 +55,6 @@ fn tally(vtoken: CurrencyId, poll_index: u32) -> TallyOf { .tally } -fn class(_vtoken: CurrencyId, poll_index: u32) -> PollIndex { - poll_index -} - fn usable_balance(vtoken: CurrencyId, who: &AccountId) -> Balance { Tokens::reducible_balance(vtoken, who, Expendable, Polite) } @@ -130,7 +126,7 @@ fn basic_voting_works() { assert_ok!(VtokenVoting::try_remove_vote(&ALICE, vtoken, poll_index, UnvoteScope::Any)); assert_eq!(tally(vtoken, poll_index), Tally::from_parts(0, 0, 0)); - assert_ok!(VtokenVoting::update_lock(&ALICE, vtoken, &class(vtoken, poll_index))); + assert_ok!(VtokenVoting::update_lock(&ALICE, vtoken, &poll_index)); assert_eq!(usable_balance(vtoken, &ALICE), 10); }); } @@ -168,7 +164,7 @@ fn split_voting_works() { assert_ok!(VtokenVoting::try_remove_vote(&ALICE, vtoken, poll_index, UnvoteScope::Any)); assert_eq!(tally(vtoken, poll_index), Tally::from_parts(0, 0, 0)); - assert_ok!(VtokenVoting::update_lock(&ALICE, vtoken, &class(vtoken, poll_index))); + assert_ok!(VtokenVoting::update_lock(&ALICE, vtoken, &poll_index)); assert_eq!(usable_balance(vtoken, &ALICE), 10); }); } @@ -224,10 +220,10 @@ fn abstain_voting_works() { assert_ok!(VtokenVoting::try_remove_vote(&BOB, vtoken, poll_index, UnvoteScope::Any)); assert_eq!(tally(vtoken, poll_index), Tally::from_parts(0, 0, 0)); - assert_ok!(VtokenVoting::update_lock(&ALICE, vtoken, &class(vtoken, poll_index))); + assert_ok!(VtokenVoting::update_lock(&ALICE, vtoken, &poll_index)); assert_eq!(usable_balance(vtoken, &ALICE), 10); - assert_ok!(VtokenVoting::update_lock(&BOB, vtoken, &class(vtoken, poll_index))); + assert_ok!(VtokenVoting::update_lock(&BOB, vtoken, &poll_index)); assert_eq!(usable_balance(vtoken, &BOB), 20); }); } @@ -275,7 +271,7 @@ fn voting_balance_gets_locked() { assert_ok!(VtokenVoting::try_remove_vote(&ALICE, vtoken, poll_index, UnvoteScope::Any)); assert_eq!(tally(vtoken, poll_index), Tally::from_parts(0, 0, 0)); - assert_ok!(VtokenVoting::update_lock(&ALICE, vtoken, &class(vtoken, poll_index))); + assert_ok!(VtokenVoting::update_lock(&ALICE, vtoken, &poll_index)); assert_eq!(usable_balance(vtoken, &ALICE), 10); }); } @@ -291,7 +287,6 @@ fn successful_but_zero_conviction_vote_balance_can_be_unlocked() { assert_ok!(VtokenVoting::vote(RuntimeOrigin::signed(BOB), vtoken, poll_index, nay(20, 0))); assert_ok!(VtokenVoting::notify_vote(origin_response(), 1, response_success())); - let c = class(vtoken, poll_index); assert_ok!(VtokenVoting::set_referendum_status( RuntimeOrigin::signed(CONTROLLER), vtoken, @@ -299,7 +294,7 @@ fn successful_but_zero_conviction_vote_balance_can_be_unlocked() { ReferendumInfoOf::::Completed(3), )); assert_ok!(VtokenVoting::try_remove_vote(&BOB, vtoken, poll_index, UnvoteScope::Any)); - assert_ok!(VtokenVoting::update_lock(&BOB, vtoken, &c)); + assert_ok!(VtokenVoting::update_lock(&BOB, vtoken, &poll_index)); assert_eq!(usable_balance(vtoken, &BOB), 20); }); } @@ -315,7 +310,6 @@ fn unsuccessful_conviction_vote_balance_can_be_unlocked() { assert_ok!(VtokenVoting::vote(RuntimeOrigin::signed(BOB), vtoken, poll_index, nay(20, 0))); assert_ok!(VtokenVoting::notify_vote(origin_response(), 1, response_success())); - let c = class(vtoken, poll_index); assert_ok!(VtokenVoting::set_referendum_status( RuntimeOrigin::signed(CONTROLLER), vtoken, @@ -323,7 +317,7 @@ fn unsuccessful_conviction_vote_balance_can_be_unlocked() { ReferendumInfoOf::::Completed(3), )); assert_ok!(VtokenVoting::try_remove_vote(&ALICE, vtoken, poll_index, UnvoteScope::Any)); - assert_ok!(VtokenVoting::update_lock(&ALICE, vtoken, &c)); + assert_ok!(VtokenVoting::update_lock(&ALICE, vtoken, &poll_index)); assert_eq!(usable_balance(vtoken, &ALICE), 10); }); } @@ -343,7 +337,6 @@ fn successful_conviction_vote_balance_stays_locked_for_correct_time() { )); assert_ok!(VtokenVoting::notify_vote(origin_response(), i - 1, response_success())); } - let c = class(vtoken, poll_index); assert_ok!(VtokenVoting::set_referendum_status( RuntimeOrigin::signed(CONTROLLER), vtoken, @@ -354,7 +347,7 @@ fn successful_conviction_vote_balance_stays_locked_for_correct_time() { assert_ok!(VtokenVoting::try_remove_vote(&i, vtoken, poll_index, UnvoteScope::Any)); } for i in 1..=5 { - assert_ok!(VtokenVoting::update_lock(&i, vtoken, &c)); + assert_ok!(VtokenVoting::update_lock(&i, vtoken, &poll_index)); assert_eq!(usable_balance(vtoken, &i), 10 * i as u128); } }); @@ -429,11 +422,16 @@ fn errors_with_vote_works() { Error::::InsufficientFunds ); - assert_ok!(VtokenVoting::vote(RuntimeOrigin::signed(1), vtoken, 0, aye(10, 0))); - assert_ok!(VtokenVoting::vote(RuntimeOrigin::signed(1), vtoken, 1, aye(10, 0))); - assert_ok!(VtokenVoting::vote(RuntimeOrigin::signed(1), vtoken, 2, aye(10, 0))); + for poll_index in 0..256 { + assert_ok!(VtokenVoting::vote( + RuntimeOrigin::signed(1), + vtoken, + poll_index, + aye(10, 0) + )); + } assert_noop!( - VtokenVoting::vote(RuntimeOrigin::signed(1), vtoken, 3, aye(10, 0)), + VtokenVoting::vote(RuntimeOrigin::signed(1), vtoken, 256, aye(10, 0)), Error::::MaxVotesReached ); }); @@ -678,6 +676,61 @@ fn notify_vote_success_works() { }); } +#[test] +fn notify_vote_success_max_works() { + new_test_ext().execute_with(|| { + let vtoken = VKSM; + + for poll_index in 0..256 { + RelaychainDataProvider::set_block_number(1); + + assert_ok!(VtokenVoting::vote( + RuntimeOrigin::signed(ALICE), + vtoken, + poll_index, + aye(2, 5) + )); + assert_ok!(VtokenVoting::notify_vote( + origin_response(), + poll_index as QueryId, + response_success() + )); + + RelaychainDataProvider::set_block_number( + 1 + UndecidingTimeout::::get(vtoken).unwrap(), + ); + VtokenVoting::on_initialize(Zero::zero()); + } + }); +} + +#[test] +fn notify_vote_success_exceed_max_fail() { + new_test_ext().execute_with(|| { + let vtoken = VKSM; + + for poll_index in 0..50 { + assert_ok!(VtokenVoting::vote( + RuntimeOrigin::signed(ALICE), + vtoken, + poll_index, + aye(2, 5) + )); + assert_ok!(VtokenVoting::notify_vote( + origin_response(), + poll_index as QueryId, + response_success() + ),); + } + let poll_index = 50; + assert_ok!(VtokenVoting::vote(RuntimeOrigin::signed(ALICE), vtoken, poll_index, aye(2, 5))); + assert_noop!( + VtokenVoting::notify_vote(origin_response(), poll_index as QueryId, response_success()), + Error::::TooMany + ); + }); +} + #[test] fn notify_vote_fail_works() { new_test_ext().execute_with(|| { diff --git a/pallets/vtoken-voting/src/traits.rs b/pallets/vtoken-voting/src/traits.rs deleted file mode 100644 index d1cab95fd..000000000 --- a/pallets/vtoken-voting/src/traits.rs +++ /dev/null @@ -1,19 +0,0 @@ -use crate::{BalanceOf, Config, CurrencyIdOf, DerivativeIndex}; -use xcm::v3::MultiLocation; - -pub trait DerivativeAccountHandler { - fn check_derivative_index_exists( - token: CurrencyIdOf, - derivative_index: DerivativeIndex, - ) -> bool; - - fn get_multilocation( - token: CurrencyIdOf, - derivative_index: DerivativeIndex, - ) -> Option; - - fn get_stake_info( - token: CurrencyIdOf, - derivative_index: DerivativeIndex, - ) -> Option<(BalanceOf, BalanceOf)>; -} diff --git a/pallets/vtoken-voting/src/weights.rs b/pallets/vtoken-voting/src/weights.rs index 3773adc49..84719d0c2 100644 --- a/pallets/vtoken-voting/src/weights.rs +++ b/pallets/vtoken-voting/src/weights.rs @@ -25,7 +25,7 @@ //! Autogenerated weights for bifrost_vtoken_voting //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-08-02, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2023-09-07, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` //! HOSTNAME: `EdwindeMBP`, CPU: `` //! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("bifrost-kusama-local"), DB CACHE: 1024 @@ -55,199 +55,446 @@ use core::marker::PhantomData; /// Weight functions needed for bifrost_vtoken_voting. pub trait WeightInfo { - fn vote() -> Weight; + fn vote_new() -> Weight; + fn vote_existing() -> Weight; fn unlock() -> Weight; - fn update_referendum_status() -> Weight; fn remove_delegator_vote() -> Weight; + fn kill_referendum() -> Weight; fn set_delegator_role() -> Weight; fn set_referendum_status() -> Weight; - fn set_vote_locking_period() -> Weight; fn set_undeciding_timeout() -> Weight; - fn kill_referendum() -> Weight; + fn set_vote_locking_period() -> Weight; fn notify_vote() -> Weight; - fn notify_update_referendum_status() -> Weight; fn notify_remove_delegator_vote() -> Weight; } /// Weights for bifrost_vtoken_voting using the Bifrost node and recommended hardware. pub struct BifrostWeight(PhantomData); impl WeightInfo for BifrostWeight { - fn vote() -> Weight { + /// Storage: VtokenVoting UndecidingTimeout (r:1 w:0) + /// Proof: VtokenVoting UndecidingTimeout (max_values: None, max_size: Some(26), added: 2501, mode: MaxEncodedLen) + /// Storage: VtokenVoting DelegatorVote (r:2 w:1) + /// Proof: VtokenVoting DelegatorVote (max_values: None, max_size: Some(81), added: 2556, mode: MaxEncodedLen) + /// Storage: Slp DelegatorsIndex2Multilocation (r:1 w:0) + /// Proof Skipped: Slp DelegatorsIndex2Multilocation (max_values: None, max_size: None, mode: Measured) + /// Storage: Slp DelegatorLedgers (r:1 w:0) + /// Proof Skipped: Slp DelegatorLedgers (max_values: None, max_size: None, mode: Measured) + /// Storage: VtokenVoting PendingVotingInfo (r:1 w:1) + /// Proof: VtokenVoting PendingVotingInfo (max_values: None, max_size: Some(117), added: 2592, mode: MaxEncodedLen) + /// Storage: VtokenVoting ReferendumInfoFor (r:1 w:1) + /// Proof: VtokenVoting ReferendumInfoFor (max_values: None, max_size: Some(88), added: 2563, mode: MaxEncodedLen) + /// Storage: Tokens Accounts (r:1 w:1) + /// Proof: Tokens Accounts (max_values: None, max_size: Some(118), added: 2593, mode: MaxEncodedLen) + /// Storage: VtokenVoting VotingFor (r:1 w:1) + /// Proof: VtokenVoting VotingFor (max_values: None, max_size: Some(13663), added: 16138, mode: MaxEncodedLen) + /// Storage: VtokenVoting ClassLocksFor (r:1 w:1) + /// Proof: VtokenVoting ClassLocksFor (max_values: None, max_size: Some(5162), added: 7637, mode: MaxEncodedLen) + /// Storage: Tokens Locks (r:1 w:1) + /// Proof: Tokens Locks (max_values: None, max_size: Some(1271), added: 3746, mode: MaxEncodedLen) + /// Storage: AssetRegistry CurrencyMetadatas (r:1 w:0) + /// Proof Skipped: AssetRegistry CurrencyMetadatas (max_values: None, max_size: None, mode: Measured) + /// Storage: XcmInterface XcmWeightAndFee (r:1 w:0) + /// Proof Skipped: XcmInterface XcmWeightAndFee (max_values: None, max_size: None, mode: Measured) + /// Storage: PolkadotXcm QueryCounter (r:1 w:1) + /// Proof Skipped: PolkadotXcm QueryCounter (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParachainInfo ParachainId (r:1 w:0) + /// Proof: ParachainInfo ParachainId (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: VtokenVoting PendingReferendumInfo (r:0 w:1) + /// Proof: VtokenVoting PendingReferendumInfo (max_values: None, max_size: Some(34), added: 2509, mode: MaxEncodedLen) + /// Storage: PolkadotXcm Queries (r:0 w:1) + /// Proof Skipped: PolkadotXcm Queries (max_values: None, max_size: None, mode: Measured) + fn vote_new() -> Weight { // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 7_000_000 picoseconds. - Weight::from_parts(7_000_000, 0) + // Measured: `14411` + // Estimated: `17876` + // Minimum execution time: 128_000_000 picoseconds. + Weight::from_parts(133_000_000, 17876) + .saturating_add(T::DbWeight::get().reads(15_u64)) + .saturating_add(T::DbWeight::get().writes(10_u64)) } - fn unlock() -> Weight { + /// Storage: VtokenVoting UndecidingTimeout (r:1 w:0) + /// Proof: VtokenVoting UndecidingTimeout (max_values: None, max_size: Some(26), added: 2501, mode: MaxEncodedLen) + /// Storage: VtokenVoting DelegatorVote (r:2 w:1) + /// Proof: VtokenVoting DelegatorVote (max_values: None, max_size: Some(81), added: 2556, mode: MaxEncodedLen) + /// Storage: Slp DelegatorsIndex2Multilocation (r:1 w:0) + /// Proof Skipped: Slp DelegatorsIndex2Multilocation (max_values: None, max_size: None, mode: Measured) + /// Storage: Slp DelegatorLedgers (r:1 w:0) + /// Proof Skipped: Slp DelegatorLedgers (max_values: None, max_size: None, mode: Measured) + /// Storage: VtokenVoting PendingVotingInfo (r:1 w:1) + /// Proof: VtokenVoting PendingVotingInfo (max_values: None, max_size: Some(117), added: 2592, mode: MaxEncodedLen) + /// Storage: VtokenVoting ReferendumInfoFor (r:1 w:1) + /// Proof: VtokenVoting ReferendumInfoFor (max_values: None, max_size: Some(88), added: 2563, mode: MaxEncodedLen) + /// Storage: Tokens Accounts (r:1 w:1) + /// Proof: Tokens Accounts (max_values: None, max_size: Some(118), added: 2593, mode: MaxEncodedLen) + /// Storage: VtokenVoting VotingFor (r:1 w:1) + /// Proof: VtokenVoting VotingFor (max_values: None, max_size: Some(13663), added: 16138, mode: MaxEncodedLen) + /// Storage: VtokenVoting ClassLocksFor (r:1 w:1) + /// Proof: VtokenVoting ClassLocksFor (max_values: None, max_size: Some(5162), added: 7637, mode: MaxEncodedLen) + /// Storage: Tokens Locks (r:1 w:1) + /// Proof: Tokens Locks (max_values: None, max_size: Some(1271), added: 3746, mode: MaxEncodedLen) + /// Storage: AssetRegistry CurrencyMetadatas (r:1 w:0) + /// Proof Skipped: AssetRegistry CurrencyMetadatas (max_values: None, max_size: None, mode: Measured) + /// Storage: XcmInterface XcmWeightAndFee (r:1 w:0) + /// Proof Skipped: XcmInterface XcmWeightAndFee (max_values: None, max_size: None, mode: Measured) + /// Storage: PolkadotXcm QueryCounter (r:1 w:1) + /// Proof Skipped: PolkadotXcm QueryCounter (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParachainInfo ParachainId (r:1 w:0) + /// Proof: ParachainInfo ParachainId (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: PolkadotXcm Queries (r:0 w:1) + /// Proof Skipped: PolkadotXcm Queries (max_values: None, max_size: None, mode: Measured) + fn vote_existing() -> Weight { // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 7_000_000 picoseconds. - Weight::from_parts(7_000_000, 0) + // Measured: `14786` + // Estimated: `18251` + // Minimum execution time: 133_000_000 picoseconds. + Weight::from_parts(135_000_000, 18251) + .saturating_add(T::DbWeight::get().reads(15_u64)) + .saturating_add(T::DbWeight::get().writes(9_u64)) } - fn update_referendum_status() -> Weight { + /// Storage: VtokenVoting ReferendumInfoFor (r:1 w:0) + /// Proof: VtokenVoting ReferendumInfoFor (max_values: None, max_size: Some(88), added: 2563, mode: MaxEncodedLen) + /// Storage: VtokenVoting VoteLockingPeriod (r:1 w:0) + /// Proof: VtokenVoting VoteLockingPeriod (max_values: None, max_size: Some(26), added: 2501, mode: MaxEncodedLen) + /// Storage: ParachainSystem ValidationData (r:1 w:0) + /// Proof Skipped: ParachainSystem ValidationData (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: VtokenVoting VotingFor (r:1 w:1) + /// Proof: VtokenVoting VotingFor (max_values: None, max_size: Some(13663), added: 16138, mode: MaxEncodedLen) + /// Storage: VtokenVoting ClassLocksFor (r:1 w:1) + /// Proof: VtokenVoting ClassLocksFor (max_values: None, max_size: Some(5162), added: 7637, mode: MaxEncodedLen) + /// Storage: Tokens Locks (r:1 w:1) + /// Proof: Tokens Locks (max_values: None, max_size: Some(1271), added: 3746, mode: MaxEncodedLen) + /// Storage: Tokens Accounts (r:1 w:1) + /// Proof: Tokens Accounts (max_values: None, max_size: Some(118), added: 2593, mode: MaxEncodedLen) + /// Storage: AssetRegistry CurrencyMetadatas (r:1 w:0) + /// Proof Skipped: AssetRegistry CurrencyMetadatas (max_values: None, max_size: None, mode: Measured) + fn unlock() -> Weight { // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 7_000_000 picoseconds. - Weight::from_parts(8_000_000, 0) + // Measured: `2032` + // Estimated: `17128` + // Minimum execution time: 65_000_000 picoseconds. + Weight::from_parts(67_000_000, 17128) + .saturating_add(T::DbWeight::get().reads(8_u64)) + .saturating_add(T::DbWeight::get().writes(4_u64)) } + /// Storage: VtokenVoting ReferendumInfoFor (r:1 w:0) + /// Proof: VtokenVoting ReferendumInfoFor (max_values: None, max_size: Some(88), added: 2563, mode: MaxEncodedLen) + /// Storage: VtokenVoting VoteLockingPeriod (r:1 w:0) + /// Proof: VtokenVoting VoteLockingPeriod (max_values: None, max_size: Some(26), added: 2501, mode: MaxEncodedLen) + /// Storage: ParachainSystem ValidationData (r:1 w:0) + /// Proof Skipped: ParachainSystem ValidationData (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: VtokenVoting DelegatorVote (r:1 w:0) + /// Proof: VtokenVoting DelegatorVote (max_values: None, max_size: Some(81), added: 2556, mode: MaxEncodedLen) + /// Storage: XcmInterface XcmWeightAndFee (r:1 w:0) + /// Proof Skipped: XcmInterface XcmWeightAndFee (max_values: None, max_size: None, mode: Measured) + /// Storage: PolkadotXcm QueryCounter (r:1 w:1) + /// Proof Skipped: PolkadotXcm QueryCounter (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParachainInfo ParachainId (r:1 w:0) + /// Proof: ParachainInfo ParachainId (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: VtokenVoting PendingRemoveDelegatorVote (r:0 w:1) + /// Proof: VtokenVoting PendingRemoveDelegatorVote (max_values: None, max_size: Some(36), added: 2511, mode: MaxEncodedLen) + /// Storage: PolkadotXcm Queries (r:0 w:1) + /// Proof Skipped: PolkadotXcm Queries (max_values: None, max_size: None, mode: Measured) fn remove_delegator_vote() -> Weight { // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 7_000_000 picoseconds. - Weight::from_parts(7_000_000, 0) + // Measured: `965` + // Estimated: `4430` + // Minimum execution time: 40_000_000 picoseconds. + Weight::from_parts(41_000_000, 4430) + .saturating_add(T::DbWeight::get().reads(7_u64)) + .saturating_add(T::DbWeight::get().writes(3_u64)) } - fn set_delegator_role() -> Weight { + /// Storage: VtokenVoting ReferendumInfoFor (r:1 w:1) + /// Proof: VtokenVoting ReferendumInfoFor (max_values: None, max_size: Some(88), added: 2563, mode: MaxEncodedLen) + /// Storage: ParachainSystem ValidationData (r:1 w:0) + /// Proof Skipped: ParachainSystem ValidationData (max_values: Some(1), max_size: None, mode: Measured) + fn kill_referendum() -> Weight { // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 6_000_000 picoseconds. - Weight::from_parts(7_000_000, 0) + // Measured: `370` + // Estimated: `3553` + // Minimum execution time: 16_000_000 picoseconds. + Weight::from_parts(17_000_000, 3553) + .saturating_add(T::DbWeight::get().reads(2_u64)) + .saturating_add(T::DbWeight::get().writes(1_u64)) } - fn set_referendum_status() -> Weight { + /// Storage: Slp DelegatorsIndex2Multilocation (r:1 w:0) + /// Proof Skipped: Slp DelegatorsIndex2Multilocation (max_values: None, max_size: None, mode: Measured) + /// Storage: VtokenVoting DelegatorVote (r:1 w:1) + /// Proof: VtokenVoting DelegatorVote (max_values: None, max_size: Some(81), added: 2556, mode: MaxEncodedLen) + fn set_delegator_role() -> Weight { // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 7_000_000 picoseconds. - Weight::from_parts(7_000_000, 0) + // Measured: `372` + // Estimated: `3837` + // Minimum execution time: 18_000_000 picoseconds. + Weight::from_parts(19_000_000, 3837) + .saturating_add(T::DbWeight::get().reads(2_u64)) + .saturating_add(T::DbWeight::get().writes(1_u64)) } - fn set_vote_locking_period() -> Weight { + /// Storage: VtokenVoting ReferendumInfoFor (r:1 w:1) + /// Proof: VtokenVoting ReferendumInfoFor (max_values: None, max_size: Some(88), added: 2563, mode: MaxEncodedLen) + fn set_referendum_status() -> Weight { // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 6_000_000 picoseconds. - Weight::from_parts(7_000_000, 0) + // Measured: `321` + // Estimated: `3553` + // Minimum execution time: 13_000_000 picoseconds. + Weight::from_parts(14_000_000, 3553) + .saturating_add(T::DbWeight::get().reads(1_u64)) + .saturating_add(T::DbWeight::get().writes(1_u64)) } + /// Storage: VtokenVoting UndecidingTimeout (r:0 w:1) + /// Proof: VtokenVoting UndecidingTimeout (max_values: None, max_size: Some(26), added: 2501, mode: MaxEncodedLen) fn set_undeciding_timeout() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 6_000_000 picoseconds. - Weight::from_parts(7_000_000, 0) + // Minimum execution time: 7_000_000 picoseconds. + Weight::from_parts(8_000_000, 0) + .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: VtokenVoting ReferendumInfos (r:0 w:1) - /// Proof: VtokenVoting ReferendumInfos (max_values: None, max_size: Some(56), added: 2531, mode: MaxEncodedLen) - fn kill_referendum() -> Weight { + /// Storage: VtokenVoting VoteLockingPeriod (r:0 w:1) + /// Proof: VtokenVoting VoteLockingPeriod (max_values: None, max_size: Some(26), added: 2501, mode: MaxEncodedLen) + fn set_vote_locking_period() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 8_000_000 picoseconds. - Weight::from_parts(9_000_000, 0) + // Minimum execution time: 7_000_000 picoseconds. + Weight::from_parts(8_000_000, 0) .saturating_add(T::DbWeight::get().writes(1_u64)) } + /// Storage: VtokenVoting PendingVotingInfo (r:1 w:0) + /// Proof: VtokenVoting PendingVotingInfo (max_values: None, max_size: Some(117), added: 2592, mode: MaxEncodedLen) + /// Storage: VtokenVoting PendingReferendumInfo (r:1 w:0) + /// Proof: VtokenVoting PendingReferendumInfo (max_values: None, max_size: Some(34), added: 2509, mode: MaxEncodedLen) fn notify_vote() -> Weight { // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 2_000_000 picoseconds. - Weight::from_parts(3_000_000, 0) - } - fn notify_update_referendum_status() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 2_000_000 picoseconds. - Weight::from_parts(3_000_000, 0) + // Measured: `361` + // Estimated: `3582` + // Minimum execution time: 15_000_000 picoseconds. + Weight::from_parts(16_000_000, 3582) + .saturating_add(T::DbWeight::get().reads(2_u64)) } + /// Storage: VtokenVoting PendingRemoveDelegatorVote (r:1 w:0) + /// Proof: VtokenVoting PendingRemoveDelegatorVote (max_values: None, max_size: Some(36), added: 2511, mode: MaxEncodedLen) fn notify_remove_delegator_vote() -> Weight { // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 2_000_000 picoseconds. - Weight::from_parts(3_000_000, 0) + // Measured: `329` + // Estimated: `3501` + // Minimum execution time: 12_000_000 picoseconds. + Weight::from_parts(13_000_000, 3501) + .saturating_add(T::DbWeight::get().reads(1_u64)) } } // For backwards compatibility and tests impl WeightInfo for () { - fn vote() -> Weight { + /// Storage: VtokenVoting UndecidingTimeout (r:1 w:0) + /// Proof: VtokenVoting UndecidingTimeout (max_values: None, max_size: Some(26), added: 2501, mode: MaxEncodedLen) + /// Storage: VtokenVoting DelegatorVote (r:2 w:1) + /// Proof: VtokenVoting DelegatorVote (max_values: None, max_size: Some(81), added: 2556, mode: MaxEncodedLen) + /// Storage: Slp DelegatorsIndex2Multilocation (r:1 w:0) + /// Proof Skipped: Slp DelegatorsIndex2Multilocation (max_values: None, max_size: None, mode: Measured) + /// Storage: Slp DelegatorLedgers (r:1 w:0) + /// Proof Skipped: Slp DelegatorLedgers (max_values: None, max_size: None, mode: Measured) + /// Storage: VtokenVoting PendingVotingInfo (r:1 w:1) + /// Proof: VtokenVoting PendingVotingInfo (max_values: None, max_size: Some(117), added: 2592, mode: MaxEncodedLen) + /// Storage: VtokenVoting ReferendumInfoFor (r:1 w:1) + /// Proof: VtokenVoting ReferendumInfoFor (max_values: None, max_size: Some(88), added: 2563, mode: MaxEncodedLen) + /// Storage: Tokens Accounts (r:1 w:1) + /// Proof: Tokens Accounts (max_values: None, max_size: Some(118), added: 2593, mode: MaxEncodedLen) + /// Storage: VtokenVoting VotingFor (r:1 w:1) + /// Proof: VtokenVoting VotingFor (max_values: None, max_size: Some(13663), added: 16138, mode: MaxEncodedLen) + /// Storage: VtokenVoting ClassLocksFor (r:1 w:1) + /// Proof: VtokenVoting ClassLocksFor (max_values: None, max_size: Some(5162), added: 7637, mode: MaxEncodedLen) + /// Storage: Tokens Locks (r:1 w:1) + /// Proof: Tokens Locks (max_values: None, max_size: Some(1271), added: 3746, mode: MaxEncodedLen) + /// Storage: AssetRegistry CurrencyMetadatas (r:1 w:0) + /// Proof Skipped: AssetRegistry CurrencyMetadatas (max_values: None, max_size: None, mode: Measured) + /// Storage: XcmInterface XcmWeightAndFee (r:1 w:0) + /// Proof Skipped: XcmInterface XcmWeightAndFee (max_values: None, max_size: None, mode: Measured) + /// Storage: PolkadotXcm QueryCounter (r:1 w:1) + /// Proof Skipped: PolkadotXcm QueryCounter (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParachainInfo ParachainId (r:1 w:0) + /// Proof: ParachainInfo ParachainId (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: VtokenVoting PendingReferendumInfo (r:0 w:1) + /// Proof: VtokenVoting PendingReferendumInfo (max_values: None, max_size: Some(34), added: 2509, mode: MaxEncodedLen) + /// Storage: PolkadotXcm Queries (r:0 w:1) + /// Proof Skipped: PolkadotXcm Queries (max_values: None, max_size: None, mode: Measured) + fn vote_new() -> Weight { // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 7_000_000 picoseconds. - Weight::from_parts(7_000_000, 0) + // Measured: `14411` + // Estimated: `17876` + // Minimum execution time: 128_000_000 picoseconds. + Weight::from_parts(133_000_000, 17876) + .saturating_add(RocksDbWeight::get().reads(15_u64)) + .saturating_add(RocksDbWeight::get().writes(10_u64)) } - fn unlock() -> Weight { + /// Storage: VtokenVoting UndecidingTimeout (r:1 w:0) + /// Proof: VtokenVoting UndecidingTimeout (max_values: None, max_size: Some(26), added: 2501, mode: MaxEncodedLen) + /// Storage: VtokenVoting DelegatorVote (r:2 w:1) + /// Proof: VtokenVoting DelegatorVote (max_values: None, max_size: Some(81), added: 2556, mode: MaxEncodedLen) + /// Storage: Slp DelegatorsIndex2Multilocation (r:1 w:0) + /// Proof Skipped: Slp DelegatorsIndex2Multilocation (max_values: None, max_size: None, mode: Measured) + /// Storage: Slp DelegatorLedgers (r:1 w:0) + /// Proof Skipped: Slp DelegatorLedgers (max_values: None, max_size: None, mode: Measured) + /// Storage: VtokenVoting PendingVotingInfo (r:1 w:1) + /// Proof: VtokenVoting PendingVotingInfo (max_values: None, max_size: Some(117), added: 2592, mode: MaxEncodedLen) + /// Storage: VtokenVoting ReferendumInfoFor (r:1 w:1) + /// Proof: VtokenVoting ReferendumInfoFor (max_values: None, max_size: Some(88), added: 2563, mode: MaxEncodedLen) + /// Storage: Tokens Accounts (r:1 w:1) + /// Proof: Tokens Accounts (max_values: None, max_size: Some(118), added: 2593, mode: MaxEncodedLen) + /// Storage: VtokenVoting VotingFor (r:1 w:1) + /// Proof: VtokenVoting VotingFor (max_values: None, max_size: Some(13663), added: 16138, mode: MaxEncodedLen) + /// Storage: VtokenVoting ClassLocksFor (r:1 w:1) + /// Proof: VtokenVoting ClassLocksFor (max_values: None, max_size: Some(5162), added: 7637, mode: MaxEncodedLen) + /// Storage: Tokens Locks (r:1 w:1) + /// Proof: Tokens Locks (max_values: None, max_size: Some(1271), added: 3746, mode: MaxEncodedLen) + /// Storage: AssetRegistry CurrencyMetadatas (r:1 w:0) + /// Proof Skipped: AssetRegistry CurrencyMetadatas (max_values: None, max_size: None, mode: Measured) + /// Storage: XcmInterface XcmWeightAndFee (r:1 w:0) + /// Proof Skipped: XcmInterface XcmWeightAndFee (max_values: None, max_size: None, mode: Measured) + /// Storage: PolkadotXcm QueryCounter (r:1 w:1) + /// Proof Skipped: PolkadotXcm QueryCounter (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParachainInfo ParachainId (r:1 w:0) + /// Proof: ParachainInfo ParachainId (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: PolkadotXcm Queries (r:0 w:1) + /// Proof Skipped: PolkadotXcm Queries (max_values: None, max_size: None, mode: Measured) + fn vote_existing() -> Weight { // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 7_000_000 picoseconds. - Weight::from_parts(7_000_000, 0) + // Measured: `14786` + // Estimated: `18251` + // Minimum execution time: 133_000_000 picoseconds. + Weight::from_parts(135_000_000, 18251) + .saturating_add(RocksDbWeight::get().reads(15_u64)) + .saturating_add(RocksDbWeight::get().writes(9_u64)) } - fn update_referendum_status() -> Weight { + /// Storage: VtokenVoting ReferendumInfoFor (r:1 w:0) + /// Proof: VtokenVoting ReferendumInfoFor (max_values: None, max_size: Some(88), added: 2563, mode: MaxEncodedLen) + /// Storage: VtokenVoting VoteLockingPeriod (r:1 w:0) + /// Proof: VtokenVoting VoteLockingPeriod (max_values: None, max_size: Some(26), added: 2501, mode: MaxEncodedLen) + /// Storage: ParachainSystem ValidationData (r:1 w:0) + /// Proof Skipped: ParachainSystem ValidationData (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: VtokenVoting VotingFor (r:1 w:1) + /// Proof: VtokenVoting VotingFor (max_values: None, max_size: Some(13663), added: 16138, mode: MaxEncodedLen) + /// Storage: VtokenVoting ClassLocksFor (r:1 w:1) + /// Proof: VtokenVoting ClassLocksFor (max_values: None, max_size: Some(5162), added: 7637, mode: MaxEncodedLen) + /// Storage: Tokens Locks (r:1 w:1) + /// Proof: Tokens Locks (max_values: None, max_size: Some(1271), added: 3746, mode: MaxEncodedLen) + /// Storage: Tokens Accounts (r:1 w:1) + /// Proof: Tokens Accounts (max_values: None, max_size: Some(118), added: 2593, mode: MaxEncodedLen) + /// Storage: AssetRegistry CurrencyMetadatas (r:1 w:0) + /// Proof Skipped: AssetRegistry CurrencyMetadatas (max_values: None, max_size: None, mode: Measured) + fn unlock() -> Weight { // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 7_000_000 picoseconds. - Weight::from_parts(8_000_000, 0) + // Measured: `2032` + // Estimated: `17128` + // Minimum execution time: 65_000_000 picoseconds. + Weight::from_parts(67_000_000, 17128) + .saturating_add(RocksDbWeight::get().reads(8_u64)) + .saturating_add(RocksDbWeight::get().writes(4_u64)) } + /// Storage: VtokenVoting ReferendumInfoFor (r:1 w:0) + /// Proof: VtokenVoting ReferendumInfoFor (max_values: None, max_size: Some(88), added: 2563, mode: MaxEncodedLen) + /// Storage: VtokenVoting VoteLockingPeriod (r:1 w:0) + /// Proof: VtokenVoting VoteLockingPeriod (max_values: None, max_size: Some(26), added: 2501, mode: MaxEncodedLen) + /// Storage: ParachainSystem ValidationData (r:1 w:0) + /// Proof Skipped: ParachainSystem ValidationData (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: VtokenVoting DelegatorVote (r:1 w:0) + /// Proof: VtokenVoting DelegatorVote (max_values: None, max_size: Some(81), added: 2556, mode: MaxEncodedLen) + /// Storage: XcmInterface XcmWeightAndFee (r:1 w:0) + /// Proof Skipped: XcmInterface XcmWeightAndFee (max_values: None, max_size: None, mode: Measured) + /// Storage: PolkadotXcm QueryCounter (r:1 w:1) + /// Proof Skipped: PolkadotXcm QueryCounter (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParachainInfo ParachainId (r:1 w:0) + /// Proof: ParachainInfo ParachainId (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: VtokenVoting PendingRemoveDelegatorVote (r:0 w:1) + /// Proof: VtokenVoting PendingRemoveDelegatorVote (max_values: None, max_size: Some(36), added: 2511, mode: MaxEncodedLen) + /// Storage: PolkadotXcm Queries (r:0 w:1) + /// Proof Skipped: PolkadotXcm Queries (max_values: None, max_size: None, mode: Measured) fn remove_delegator_vote() -> Weight { // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 7_000_000 picoseconds. - Weight::from_parts(7_000_000, 0) + // Measured: `965` + // Estimated: `4430` + // Minimum execution time: 40_000_000 picoseconds. + Weight::from_parts(41_000_000, 4430) + .saturating_add(RocksDbWeight::get().reads(7_u64)) + .saturating_add(RocksDbWeight::get().writes(3_u64)) } - fn set_delegator_role() -> Weight { + /// Storage: VtokenVoting ReferendumInfoFor (r:1 w:1) + /// Proof: VtokenVoting ReferendumInfoFor (max_values: None, max_size: Some(88), added: 2563, mode: MaxEncodedLen) + /// Storage: ParachainSystem ValidationData (r:1 w:0) + /// Proof Skipped: ParachainSystem ValidationData (max_values: Some(1), max_size: None, mode: Measured) + fn kill_referendum() -> Weight { // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 6_000_000 picoseconds. - Weight::from_parts(7_000_000, 0) + // Measured: `370` + // Estimated: `3553` + // Minimum execution time: 16_000_000 picoseconds. + Weight::from_parts(17_000_000, 3553) + .saturating_add(RocksDbWeight::get().reads(2_u64)) + .saturating_add(RocksDbWeight::get().writes(1_u64)) } - fn set_referendum_status() -> Weight { + /// Storage: Slp DelegatorsIndex2Multilocation (r:1 w:0) + /// Proof Skipped: Slp DelegatorsIndex2Multilocation (max_values: None, max_size: None, mode: Measured) + /// Storage: VtokenVoting DelegatorVote (r:1 w:1) + /// Proof: VtokenVoting DelegatorVote (max_values: None, max_size: Some(81), added: 2556, mode: MaxEncodedLen) + fn set_delegator_role() -> Weight { // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 7_000_000 picoseconds. - Weight::from_parts(7_000_000, 0) + // Measured: `372` + // Estimated: `3837` + // Minimum execution time: 18_000_000 picoseconds. + Weight::from_parts(19_000_000, 3837) + .saturating_add(RocksDbWeight::get().reads(2_u64)) + .saturating_add(RocksDbWeight::get().writes(1_u64)) } - fn set_vote_locking_period() -> Weight { + /// Storage: VtokenVoting ReferendumInfoFor (r:1 w:1) + /// Proof: VtokenVoting ReferendumInfoFor (max_values: None, max_size: Some(88), added: 2563, mode: MaxEncodedLen) + fn set_referendum_status() -> Weight { // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 6_000_000 picoseconds. - Weight::from_parts(7_000_000, 0) + // Measured: `321` + // Estimated: `3553` + // Minimum execution time: 13_000_000 picoseconds. + Weight::from_parts(14_000_000, 3553) + .saturating_add(RocksDbWeight::get().reads(1_u64)) + .saturating_add(RocksDbWeight::get().writes(1_u64)) } + /// Storage: VtokenVoting UndecidingTimeout (r:0 w:1) + /// Proof: VtokenVoting UndecidingTimeout (max_values: None, max_size: Some(26), added: 2501, mode: MaxEncodedLen) fn set_undeciding_timeout() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 6_000_000 picoseconds. - Weight::from_parts(7_000_000, 0) + // Minimum execution time: 7_000_000 picoseconds. + Weight::from_parts(8_000_000, 0) + .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: VtokenVoting ReferendumInfos (r:0 w:1) - /// Proof: VtokenVoting ReferendumInfos (max_values: None, max_size: Some(56), added: 2531, mode: MaxEncodedLen) - fn kill_referendum() -> Weight { + /// Storage: VtokenVoting VoteLockingPeriod (r:0 w:1) + /// Proof: VtokenVoting VoteLockingPeriod (max_values: None, max_size: Some(26), added: 2501, mode: MaxEncodedLen) + fn set_vote_locking_period() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 8_000_000 picoseconds. - Weight::from_parts(9_000_000, 0) + // Minimum execution time: 7_000_000 picoseconds. + Weight::from_parts(8_000_000, 0) .saturating_add(RocksDbWeight::get().writes(1_u64)) } + /// Storage: VtokenVoting PendingVotingInfo (r:1 w:0) + /// Proof: VtokenVoting PendingVotingInfo (max_values: None, max_size: Some(117), added: 2592, mode: MaxEncodedLen) + /// Storage: VtokenVoting PendingReferendumInfo (r:1 w:0) + /// Proof: VtokenVoting PendingReferendumInfo (max_values: None, max_size: Some(34), added: 2509, mode: MaxEncodedLen) fn notify_vote() -> Weight { // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 2_000_000 picoseconds. - Weight::from_parts(3_000_000, 0) - } - fn notify_update_referendum_status() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 2_000_000 picoseconds. - Weight::from_parts(3_000_000, 0) + // Measured: `361` + // Estimated: `3582` + // Minimum execution time: 15_000_000 picoseconds. + Weight::from_parts(16_000_000, 3582) + .saturating_add(RocksDbWeight::get().reads(2_u64)) } + /// Storage: VtokenVoting PendingRemoveDelegatorVote (r:1 w:0) + /// Proof: VtokenVoting PendingRemoveDelegatorVote (max_values: None, max_size: Some(36), added: 2511, mode: MaxEncodedLen) fn notify_remove_delegator_vote() -> Weight { // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 2_000_000 picoseconds. - Weight::from_parts(3_000_000, 0) + // Measured: `329` + // Estimated: `3501` + // Minimum execution time: 12_000_000 picoseconds. + Weight::from_parts(13_000_000, 3501) + .saturating_add(RocksDbWeight::get().reads(1_u64)) } } diff --git a/runtime/bifrost-kusama/src/lib.rs b/runtime/bifrost-kusama/src/lib.rs index 3eae12927..1661562eb 100644 --- a/runtime/bifrost-kusama/src/lib.rs +++ b/runtime/bifrost-kusama/src/lib.rs @@ -27,7 +27,7 @@ include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); pub mod migration; -use bifrost_slp::{Ledger, QueryResponseManager}; +use bifrost_slp::{DerivativeAccountProvider, QueryResponseManager}; use core::convert::TryInto; use frame_support::pallet_prelude::StorageVersion; // A few exports that help ease life for downstream crates. @@ -110,7 +110,6 @@ use governance::{custom_origins, CoreAdmin, TechAdmin}; // xcm config mod xcm_config; -use bifrost_vtoken_voting::{traits::DerivativeAccountHandler, DerivativeIndex}; use pallet_xcm::{EnsureResponse, QueryStatus}; use xcm::v3::prelude::*; pub use xcm_config::{ @@ -1481,30 +1480,10 @@ parameter_types! { pub const QueryTimeout: BlockNumber = 100; } -pub struct DerivativeAccount; -impl DerivativeAccountHandler for DerivativeAccount { - fn check_derivative_index_exists(token: CurrencyId, derivative_index: DerivativeIndex) -> bool { - Slp::get_delegator_multilocation_by_index(token, derivative_index).is_some() - } - - fn get_multilocation( - token: CurrencyId, - derivative_index: DerivativeIndex, - ) -> Option { - Slp::get_delegator_multilocation_by_index(token, derivative_index) - } - - fn get_stake_info( - token: CurrencyId, - derivative_index: DerivativeIndex, - ) -> Option<(Balance, Balance)> { - Self::get_multilocation(token, derivative_index).and_then(|location| { - Slp::get_delegator_ledger(token, location).and_then(|ledger| match ledger { - Ledger::Substrate(l) if token == CurrencyId::Token(TokenSymbol::KSM) => - Some((l.total, l.active)), - _ => None, - }) - }) +pub struct DerivativeAccountTokenFilter; +impl Contains for DerivativeAccountTokenFilter { + fn contains(token: &CurrencyId) -> bool { + *token == RelayCurrencyId::get() } } @@ -1516,10 +1495,10 @@ impl bifrost_vtoken_voting::Config for Runtime { type ControlOrigin = EitherOfDiverse; type ResponseOrigin = EnsureResponse; type XcmDestWeightAndFee = XcmInterface; - type DerivativeAccount = DerivativeAccount; + type DerivativeAccount = DerivativeAccountProvider; type RelaychainBlockNumberProvider = RelaychainDataProvider; type ParachainId = SelfParaChainId; - type MaxVotes = ConstU32<512>; + type MaxVotes = ConstU32<256>; type QueryTimeout = QueryTimeout; type WeightInfo = bifrost_vtoken_voting::weights::BifrostWeight; } diff --git a/runtime/bifrost-polkadot/src/lib.rs b/runtime/bifrost-polkadot/src/lib.rs index 8b022d026..829616d70 100644 --- a/runtime/bifrost-polkadot/src/lib.rs +++ b/runtime/bifrost-polkadot/src/lib.rs @@ -27,7 +27,7 @@ include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); pub mod migration; -use bifrost_slp::{Ledger, QueryResponseManager}; +use bifrost_slp::{DerivativeAccountProvider, QueryResponseManager}; use core::convert::TryInto; use frame_support::pallet_prelude::StorageVersion; // A few exports that help ease life for downstream crates. @@ -106,7 +106,6 @@ use zenlink_protocol::{ }; // xcm config mod xcm_config; -use bifrost_vtoken_voting::{traits::DerivativeAccountHandler, DerivativeIndex}; use orml_traits::{currency::MutationHooks, location::RelativeReserveProvider}; use pallet_xcm::{EnsureResponse, QueryStatus}; use static_assertions::const_assert; @@ -1329,30 +1328,10 @@ parameter_types! { pub const QueryTimeout: BlockNumber = 100; } -pub struct DerivativeAccount; -impl DerivativeAccountHandler for DerivativeAccount { - fn check_derivative_index_exists(token: CurrencyId, derivative_index: DerivativeIndex) -> bool { - Slp::get_delegator_multilocation_by_index(token, derivative_index).is_some() - } - - fn get_multilocation( - token: CurrencyId, - derivative_index: DerivativeIndex, - ) -> Option { - Slp::get_delegator_multilocation_by_index(token, derivative_index) - } - - fn get_stake_info( - token: CurrencyId, - derivative_index: DerivativeIndex, - ) -> Option<(Balance, Balance)> { - Self::get_multilocation(token, derivative_index).and_then(|location| { - Slp::get_delegator_ledger(token, location).and_then(|ledger| match ledger { - Ledger::Substrate(l) if token == CurrencyId::Token(TokenSymbol::KSM) => - Some((l.total, l.active)), - _ => None, - }) - }) +pub struct DerivativeAccountTokenFilter; +impl Contains for DerivativeAccountTokenFilter { + fn contains(token: &CurrencyId) -> bool { + *token == RelayCurrencyId::get() } } @@ -1364,10 +1343,10 @@ impl bifrost_vtoken_voting::Config for Runtime { type ControlOrigin = EitherOfDiverse; type ResponseOrigin = EnsureResponse; type XcmDestWeightAndFee = XcmInterface; - type DerivativeAccount = DerivativeAccount; + type DerivativeAccount = DerivativeAccountProvider; type RelaychainBlockNumberProvider = RelaychainDataProvider; type ParachainId = SelfParaChainId; - type MaxVotes = ConstU32<512>; + type MaxVotes = ConstU32<256>; type QueryTimeout = QueryTimeout; type WeightInfo = bifrost_vtoken_voting::weights::BifrostWeight; } From b8dc6c28df2b88defc294991e3b955073db6f216 Mon Sep 17 00:00:00 2001 From: Edwin Date: Fri, 8 Sep 2023 16:35:34 +0800 Subject: [PATCH 6/9] Fix token convert (#1035) --- node/primitives/src/currency.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/node/primitives/src/currency.rs b/node/primitives/src/currency.rs index bcf514204..b00df4b00 100644 --- a/node/primitives/src/currency.rs +++ b/node/primitives/src/currency.rs @@ -410,6 +410,7 @@ impl CurrencyId { pub fn to_token(&self) -> Result { match self { Self::VToken(symbol) => Ok(Self::Token(*symbol)), + Self::VToken2(id) => Ok(Self::Token2(*id)), _ => Err(()), } } @@ -417,6 +418,7 @@ impl CurrencyId { pub fn to_vtoken(&self) -> Result { match self { Self::Token(symbol) => Ok(Self::VToken(*symbol)), + Self::Token2(id) => Ok(Self::VToken2(*id)), _ => Err(()), } } @@ -424,6 +426,7 @@ impl CurrencyId { pub fn to_vstoken(&self) -> Result { match self { Self::Token(symbol) => Ok(Self::VSToken(*symbol)), + Self::Token2(id) => Ok(Self::VSToken2(*id)), _ => Err(()), } } From 04a50db93ba54581dc4d90850ef2d926078d08ad Mon Sep 17 00:00:00 2001 From: Edwin Date: Sat, 9 Sep 2023 20:46:58 +0800 Subject: [PATCH 7/9] Fix vtoken-voting test (#1036) * Fix integration tests * More tests * More tests --- Cargo.lock | 1 - .../bifrost-kusama/src/vtoken_voting.rs | 57 ++++++++++++++- pallets/vtoken-voting/Cargo.toml | 4 +- pallets/vtoken-voting/src/tests.rs | 72 ++++++++++++++++++- 4 files changed, 124 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e5a4927f4..e005e23e4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1642,7 +1642,6 @@ version = "0.8.0" dependencies = [ "assert_matches", "bifrost-currencies", - "bifrost-slp", "cumulus-primitives-core", "frame-benchmarking", "frame-support", diff --git a/integration-tests/bifrost-kusama/src/vtoken_voting.rs b/integration-tests/bifrost-kusama/src/vtoken_voting.rs index 63b45c705..62c353ac8 100644 --- a/integration-tests/bifrost-kusama/src/vtoken_voting.rs +++ b/integration-tests/bifrost-kusama/src/vtoken_voting.rs @@ -32,6 +32,8 @@ use xcm_emulator::TestExt; #[test] fn vote_works() { + env_logger::init(); + sp_io::TestExternalities::default().execute_with(|| { let vtoken = VKSM; let poll_index = 0; @@ -73,6 +75,12 @@ fn vote_works() { XcmOperation::VoteVtoken, Some((Weight::from_parts(4000000000, 100000), 4000000000u32.into())), )); + assert_ok!(Slp::set_xcm_dest_weight_and_fee( + RuntimeOrigin::root(), + token, + XcmOperation::VoteRemoveDelegatorVote, + Some((Weight::from_parts(4000000000, 100000), 4000000000u32.into())), + )); assert_ok!(Slp::set_minimums_and_maximums( RuntimeOrigin::root(), token, @@ -114,6 +122,7 @@ fn vote_works() { 5, VoteRole::Standard { aye: true, conviction: Conviction::Locked5x }, )); + assert_ok!(VtokenVoting::set_vote_locking_period(RuntimeOrigin::root(), vtoken, 0)); assert_ok!(VtokenVoting::set_undeciding_timeout(RuntimeOrigin::root(), vtoken, 100)); assert_ok!(VtokenVoting::vote( @@ -139,7 +148,7 @@ fn vote_works() { KusamaNet::execute_with(|| { use kusama_runtime::System; - System::events().iter().for_each(|r| println!("KusamaNet >>> {:?}", r.event)); + System::events().iter().for_each(|r| log::debug!("KusamaNet >>> {:?}", r.event)); assert!(System::events().iter().any(|r| matches!( r.event, kusama_runtime::RuntimeEvent::Ump( @@ -150,9 +159,9 @@ fn vote_works() { }); Bifrost::execute_with(|| { - use bifrost_kusama_runtime::{RuntimeEvent, System}; + use bifrost_kusama_runtime::{RuntimeEvent, System, VtokenVoting}; - System::events().iter().for_each(|r| println!("Bifrost >>> {:?}", r.event)); + System::events().iter().for_each(|r| log::debug!("Bifrost >>> {:?}", r.event)); assert!(System::events().iter().any(|r| matches!( r.event, RuntimeEvent::VtokenVoting(bifrost_vtoken_voting::Event::VoteNotified { @@ -161,6 +170,48 @@ fn vote_works() { success: true, }) ))); + assert_ok!(VtokenVoting::set_referendum_status( + RuntimeOrigin::root(), + VKSM, + 0, + bifrost_vtoken_voting::ReferendumInfoOf::::Completed(1), + )); + assert_ok!(VtokenVoting::remove_delegator_vote( + RuntimeOrigin::signed(ALICE.into()), + VKSM, + 0, + 5, + )); + System::reset_events(); + }); + + KusamaNet::execute_with(|| { + use kusama_runtime::System; + + System::events().iter().for_each(|r| log::debug!("KusamaNet >>> {:?}", r.event)); + assert!(System::events().iter().any(|r| matches!( + r.event, + kusama_runtime::RuntimeEvent::Ump( + polkadot_runtime_parachains::ump::Event::ExecutedUpward(..) + ) + ))); + System::reset_events(); + }); + + Bifrost::execute_with(|| { + use bifrost_kusama_runtime::{RuntimeEvent, System}; + + System::events().iter().for_each(|r| log::debug!("Bifrost >>> {:?}", r.event)); + assert!(System::events().iter().any(|r| matches!( + r.event, + RuntimeEvent::VtokenVoting( + bifrost_vtoken_voting::Event::DelegatorVoteRemovedNotified { + vtoken: VKSM, + poll_index: 0, + success: true, + } + ) + ))); System::reset_events(); }); }); diff --git a/pallets/vtoken-voting/Cargo.toml b/pallets/vtoken-voting/Cargo.toml index b1e7ca04c..1881e7d05 100644 --- a/pallets/vtoken-voting/Cargo.toml +++ b/pallets/vtoken-voting/Cargo.toml @@ -28,7 +28,6 @@ sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0 sp-std = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.42", default-features = false } sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.42", default-features = false } xcm = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.42", default-features = false } -bifrost-slp = { path = "../slp", default-features = false } [dev-dependencies] orml-tokens = "0.4.1-dev" @@ -54,15 +53,14 @@ std = [ "sp-io/std", "sp-runtime/std", "xcm/std", - "bifrost-slp/std", ] kusama = [] polkadot = [] runtime-benchmarks = [ "frame-benchmarking/runtime-benchmarks", + "node-primitives/runtime-benchmarks", "pallet-conviction-voting/runtime-benchmarks", "pallet-xcm/runtime-benchmarks", "xcm-builder/runtime-benchmarks", - "bifrost-slp/runtime-benchmarks", ] try-runtime = ["frame-support/try-runtime"] diff --git a/pallets/vtoken-voting/src/tests.rs b/pallets/vtoken-voting/src/tests.rs index acd4cac82..8d66039e4 100644 --- a/pallets/vtoken-voting/src/tests.rs +++ b/pallets/vtoken-voting/src/tests.rs @@ -644,8 +644,17 @@ fn notify_vote_success_works() { let vtoken = VKSM; let query_id = 0; let response = response_success(); + let derivative_index = 5; assert_ok!(VtokenVoting::vote(RuntimeOrigin::signed(ALICE), vtoken, poll_index, aye(2, 5))); + assert_eq!( + ReferendumInfoFor::::get(vtoken, poll_index), + Some(ReferendumInfo::Ongoing(ReferendumStatus { + submitted: None, + tally: TallyOf::::from_parts(10, 0, 2), + })) + ); + assert_eq!(DelegatorVote::::get(vtoken, derivative_index), Some(aye(2, 5))); assert_eq!(tally(vtoken, poll_index), Tally::from_parts(10, 0, 2)); System::assert_last_event(RuntimeEvent::VtokenVoting(Event::Voted { who: ALICE, @@ -655,6 +664,14 @@ fn notify_vote_success_works() { })); assert_ok!(VtokenVoting::notify_vote(origin_response(), query_id, response.clone())); + assert_eq!( + ReferendumInfoFor::::get(vtoken, poll_index), + Some(ReferendumInfo::Ongoing(ReferendumStatus { + submitted: Some(1), + tally: TallyOf::::from_parts(10, 0, 2), + })) + ); + assert_eq!(DelegatorVote::::get(vtoken, derivative_index), Some(aye(2, 5))); System::assert_has_event(RuntimeEvent::VtokenVoting(Event::VoteNotified { vtoken, poll_index, @@ -720,7 +737,7 @@ fn notify_vote_success_exceed_max_fail() { origin_response(), poll_index as QueryId, response_success() - ),); + )); } let poll_index = 50; assert_ok!(VtokenVoting::vote(RuntimeOrigin::signed(ALICE), vtoken, poll_index, aye(2, 5))); @@ -738,8 +755,17 @@ fn notify_vote_fail_works() { let vtoken = VKSM; let query_id = 0; let response = response_fail(); + let derivative_index = 5; assert_ok!(VtokenVoting::vote(RuntimeOrigin::signed(ALICE), vtoken, poll_index, aye(2, 5))); + assert_eq!( + ReferendumInfoFor::::get(vtoken, poll_index), + Some(ReferendumInfo::Ongoing(ReferendumStatus { + submitted: None, + tally: TallyOf::::from_parts(10, 0, 2), + })) + ); + assert_eq!(DelegatorVote::::get(vtoken, derivative_index), Some(aye(2, 5))); assert_eq!(tally(vtoken, poll_index), Tally::from_parts(10, 0, 2)); System::assert_last_event(RuntimeEvent::VtokenVoting(Event::Voted { who: ALICE, @@ -749,6 +775,8 @@ fn notify_vote_fail_works() { })); assert_ok!(VtokenVoting::notify_vote(origin_response(), query_id, response.clone())); + assert_eq!(ReferendumInfoFor::::get(vtoken, poll_index), None); + assert_eq!(DelegatorVote::::get(vtoken, derivative_index), Some(aye(0, 5))); System::assert_has_event(RuntimeEvent::VtokenVoting(Event::VoteNotified { vtoken, poll_index, @@ -783,10 +811,11 @@ fn notify_remove_delegator_vote_success_works() { let poll_index = 3; let vtoken = VKSM; let mut query_id = 0; - let derivative_index = 3; + let derivative_index = 5; let response = response_success(); assert_ok!(VtokenVoting::vote(RuntimeOrigin::signed(ALICE), vtoken, poll_index, aye(2, 5))); + assert_eq!(DelegatorVote::::get(vtoken, derivative_index), Some(aye(2, 5))); assert_eq!(tally(vtoken, poll_index), Tally::from_parts(10, 0, 2)); System::assert_last_event(RuntimeEvent::VtokenVoting(Event::Voted { who: ALICE, @@ -815,6 +844,7 @@ fn notify_remove_delegator_vote_success_works() { poll_index, derivative_index, )); + assert_eq!(DelegatorVote::::get(vtoken, derivative_index), Some(aye(2, 5))); query_id = 1; assert_ok!(VtokenVoting::notify_remove_delegator_vote( @@ -822,6 +852,7 @@ fn notify_remove_delegator_vote_success_works() { query_id, response.clone() )); + assert_eq!(DelegatorVote::::get(vtoken, derivative_index), Some(aye(0, 5))); System::assert_has_event(RuntimeEvent::VtokenVoting(Event::DelegatorVoteRemovedNotified { vtoken, poll_index, @@ -841,7 +872,7 @@ fn notify_remove_delegator_vote_fail_works() { let poll_index = 3; let vtoken = VKSM; let mut query_id = 0; - let derivative_index = 3; + let derivative_index = 5; let response = response_fail(); assert_ok!(VtokenVoting::vote(RuntimeOrigin::signed(ALICE), vtoken, poll_index, aye(2, 5))); @@ -873,6 +904,7 @@ fn notify_remove_delegator_vote_fail_works() { poll_index, derivative_index, )); + assert_eq!(DelegatorVote::::get(vtoken, derivative_index), Some(aye(2, 5))); query_id = 1; assert_ok!(VtokenVoting::notify_remove_delegator_vote( @@ -880,6 +912,7 @@ fn notify_remove_delegator_vote_fail_works() { query_id, response.clone() )); + assert_eq!(DelegatorVote::::get(vtoken, derivative_index), Some(aye(2, 5))); System::assert_last_event(RuntimeEvent::VtokenVoting(Event::ResponseReceived { responder: Parent.into(), query_id, @@ -906,3 +939,36 @@ fn notify_remove_delegator_vote_with_no_data_works() { })); }); } + +#[test] +fn on_initialize_works() { + new_test_ext().execute_with(|| { + let vtoken = VKSM; + RelaychainDataProvider::set_block_number(1); + for (query_id, poll_index) in (0..50).collect::>().iter().enumerate() { + assert_ok!(VtokenVoting::vote( + RuntimeOrigin::signed(ALICE), + vtoken, + *poll_index, + aye(2, 5) + )); + assert_ok!(VtokenVoting::notify_vote( + origin_response(), + query_id as QueryId, + response_success() + )); + } + + RelaychainDataProvider::set_block_number( + 1 + UndecidingTimeout::::get(vtoken).unwrap(), + ); + VtokenVoting::on_initialize(Zero::zero()); + + for poll_index in 0..50 { + assert_eq!( + ReferendumInfoFor::::get(vtoken, poll_index), + Some(ReferendumInfo::Completed(101)) + ); + } + }); +} From 5bccf08ff4df1e1b7cd87ef3b9656e5a2eacfe66 Mon Sep 17 00:00:00 2001 From: Edwin Date: Sun, 10 Sep 2023 18:49:14 +0800 Subject: [PATCH 8/9] Fix weight (#1038) --- pallets/vtoken-voting/src/lib.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/pallets/vtoken-voting/src/lib.rs b/pallets/vtoken-voting/src/lib.rs index 5f352eb59..1cd449e21 100644 --- a/pallets/vtoken-voting/src/lib.rs +++ b/pallets/vtoken-voting/src/lib.rs @@ -361,7 +361,10 @@ pub mod pallet { #[pallet::call] impl Pallet { #[pallet::call_index(0)] - #[pallet::weight(::WeightInfo::vote_new().max(::WeightInfo::vote_existing()))] + #[pallet::weight( + ::WeightInfo::vote_new().max(::WeightInfo::vote_existing()) + + ::WeightInfo::notify_vote() + )] pub fn vote( origin: OriginFor, vtoken: CurrencyIdOf, @@ -454,7 +457,10 @@ pub mod pallet { } #[pallet::call_index(2)] - #[pallet::weight(::WeightInfo::remove_delegator_vote())] + #[pallet::weight( + ::WeightInfo::remove_delegator_vote() + + ::WeightInfo::notify_remove_delegator_vote() + )] pub fn remove_delegator_vote( origin: OriginFor, vtoken: CurrencyIdOf, From 0323af5910a8aa5dbd08098c1f59903903206adc Mon Sep 17 00:00:00 2001 From: Herry Ho <45537372+herryho@users.noreply.github.com> Date: Mon, 11 Sep 2023 11:27:26 +0800 Subject: [PATCH 9/9] Flexible fee tests (#1037) * add flexible fee unit tests * fix tests * change operation name * fixes * fixes --- integration-tests/bifrost-kusama/src/slp.rs | 130 ++-- .../bifrost-kusama/src/vtoken_voting.rs | 10 +- node/primitives/src/lib.rs | 4 +- pallets/flexible-fee/src/lib.rs | 18 +- pallets/flexible-fee/src/mock.rs | 7 + pallets/flexible-fee/src/tests.rs | 168 +++++- pallets/slp/src/benchmarking.rs | 561 +----------------- pallets/slp/src/lib.rs | 34 -- pallets/slp/src/mocks/mock.rs | 25 +- pallets/slp/src/mocks/mock_kusama.rs | 29 +- pallets/slp/src/tests/kusama_tests.rs | 30 +- pallets/slp/src/tests/moonriver_tests.rs | 36 +- .../slp/src/tests/parachain_staking_tests.rs | 84 --- pallets/slp/src/tests/phala_tests.rs | 15 +- pallets/vtoken-voting/src/benchmarking.rs | 4 +- pallets/vtoken-voting/src/lib.rs | 4 +- 16 files changed, 335 insertions(+), 824 deletions(-) diff --git a/integration-tests/bifrost-kusama/src/slp.rs b/integration-tests/bifrost-kusama/src/slp.rs index f4d697187..7cc32b8bd 100644 --- a/integration-tests/bifrost-kusama/src/slp.rs +++ b/integration-tests/bifrost-kusama/src/slp.rs @@ -251,75 +251,85 @@ fn slp_setup() { )); // Register Operation weight and fee - assert_ok!(Slp::set_xcm_dest_weight_and_fee( - RuntimeOrigin::root(), - RelayCurrencyId::get(), - XcmOperation::TransferTo, - Some((Weight::from_parts(10000000000, 1000000), 10_000_000_000)), - )); + assert_ok!( + ::XcmWeightAndFeeHandler::set_xcm_dest_weight_and_fee( + RelayCurrencyId::get(), + XcmOperation::TransferTo, + Some((Weight::from_parts(10000000000, 1000000), 10_000_000_000)), + ) + ); - assert_ok!(Slp::set_xcm_dest_weight_and_fee( - RuntimeOrigin::root(), - RelayCurrencyId::get(), - XcmOperation::Bond, - Some((Weight::from_parts(10000000000, 1000000), 10_000_000_000)), - )); + assert_ok!( + ::XcmWeightAndFeeHandler::set_xcm_dest_weight_and_fee( + RelayCurrencyId::get(), + XcmOperation::Bond, + Some((Weight::from_parts(10000000000, 1000000), 10_000_000_000)), + ) + ); - assert_ok!(Slp::set_xcm_dest_weight_and_fee( - RuntimeOrigin::root(), - RelayCurrencyId::get(), - XcmOperation::BondExtra, - Some((Weight::from_parts(10000000000, 1000000), 10_000_000_000)), - )); + assert_ok!( + ::XcmWeightAndFeeHandler::set_xcm_dest_weight_and_fee( + RelayCurrencyId::get(), + XcmOperation::BondExtra, + Some((Weight::from_parts(10000000000, 1000000), 10_000_000_000)), + ) + ); - assert_ok!(Slp::set_xcm_dest_weight_and_fee( - RuntimeOrigin::root(), - RelayCurrencyId::get(), - XcmOperation::Unbond, - Some((Weight::from_parts(10000000000, 1000000), 10_000_000_000)), - )); + assert_ok!( + ::XcmWeightAndFeeHandler::set_xcm_dest_weight_and_fee( + RelayCurrencyId::get(), + XcmOperation::Unbond, + Some((Weight::from_parts(10000000000, 1000000), 10_000_000_000)), + ) + ); - assert_ok!(Slp::set_xcm_dest_weight_and_fee( - RuntimeOrigin::root(), - RelayCurrencyId::get(), - XcmOperation::Rebond, - Some((Weight::from_parts(10000000000, 1000000), 10_000_000_000)), - )); + assert_ok!( + ::XcmWeightAndFeeHandler::set_xcm_dest_weight_and_fee( + RelayCurrencyId::get(), + XcmOperation::Rebond, + Some((Weight::from_parts(10000000000, 1000000), 10_000_000_000)), + ) + ); - assert_ok!(Slp::set_xcm_dest_weight_and_fee( - RuntimeOrigin::root(), - RelayCurrencyId::get(), - XcmOperation::Delegate, - Some((Weight::from_parts(10000000000, 1000000), 10_000_000_000)), - )); + assert_ok!( + ::XcmWeightAndFeeHandler::set_xcm_dest_weight_and_fee( + RelayCurrencyId::get(), + XcmOperation::Delegate, + Some((Weight::from_parts(10000000000, 1000000), 10_000_000_000)), + ) + ); - assert_ok!(Slp::set_xcm_dest_weight_and_fee( - RuntimeOrigin::root(), - RelayCurrencyId::get(), - XcmOperation::Payout, - Some((Weight::from_parts(10000000000, 1000000), 10_000_000_000)), - )); + assert_ok!( + ::XcmWeightAndFeeHandler::set_xcm_dest_weight_and_fee( + RelayCurrencyId::get(), + XcmOperation::Payout, + Some((Weight::from_parts(10000000000, 1000000), 10_000_000_000)), + ) + ); - assert_ok!(Slp::set_xcm_dest_weight_and_fee( - RuntimeOrigin::root(), - RelayCurrencyId::get(), - XcmOperation::Liquidize, - Some((Weight::from_parts(10000000000, 1000000), 10_000_000_000)), - )); + assert_ok!( + ::XcmWeightAndFeeHandler::set_xcm_dest_weight_and_fee( + RelayCurrencyId::get(), + XcmOperation::Liquidize, + Some((Weight::from_parts(10000000000, 1000000), 10_000_000_000)), + ) + ); - assert_ok!(Slp::set_xcm_dest_weight_and_fee( - RuntimeOrigin::root(), - RelayCurrencyId::get(), - XcmOperation::Chill, - Some((Weight::from_parts(10000000000, 1000000), 10_000_000_000)), - )); + assert_ok!( + ::XcmWeightAndFeeHandler::set_xcm_dest_weight_and_fee( + RelayCurrencyId::get(), + XcmOperation::Chill, + Some((Weight::from_parts(10000000000, 1000000), 10_000_000_000)), + ) + ); - assert_ok!(Slp::set_xcm_dest_weight_and_fee( - RuntimeOrigin::root(), - RelayCurrencyId::get(), - XcmOperation::TransferBack, - Some((Weight::from_parts(10000000000, 1000000), 10_000_000_000)), - )); + assert_ok!( + ::XcmWeightAndFeeHandler::set_xcm_dest_weight_and_fee( + RelayCurrencyId::get(), + XcmOperation::TransferBack, + Some((Weight::from_parts(10000000000, 1000000), 10_000_000_000)), + ) + ); // initialize two delegators assert_ok!(Slp::initialize_delegator(RuntimeOrigin::root(), RelayCurrencyId::get(), None)); diff --git a/integration-tests/bifrost-kusama/src/vtoken_voting.rs b/integration-tests/bifrost-kusama/src/vtoken_voting.rs index 62c353ac8..9995926cd 100644 --- a/integration-tests/bifrost-kusama/src/vtoken_voting.rs +++ b/integration-tests/bifrost-kusama/src/vtoken_voting.rs @@ -69,16 +69,14 @@ fn vote_works() { Zero::zero(), )); let token = CurrencyId::to_token(&vtoken).unwrap(); - assert_ok!(Slp::set_xcm_dest_weight_and_fee( - RuntimeOrigin::root(), + assert_ok!(XcmInterface::set_xcm_dest_weight_and_fee( token, - XcmOperation::VoteVtoken, + XcmOperation::Vote, Some((Weight::from_parts(4000000000, 100000), 4000000000u32.into())), )); - assert_ok!(Slp::set_xcm_dest_weight_and_fee( - RuntimeOrigin::root(), + assert_ok!(XcmInterface::set_xcm_dest_weight_and_fee( token, - XcmOperation::VoteRemoveDelegatorVote, + XcmOperation::RemoveVote, Some((Weight::from_parts(4000000000, 100000), 4000000000u32.into())), )); assert_ok!(Slp::set_minimums_and_maximums( diff --git a/node/primitives/src/lib.rs b/node/primitives/src/lib.rs index 702e71796..387260c44 100644 --- a/node/primitives/src/lib.rs +++ b/node/primitives/src/lib.rs @@ -265,8 +265,8 @@ pub enum XcmInterfaceOperation { ExecuteLeave, ConvertAsset, // VtokenVoting operations - VoteVtoken, - VoteRemoveDelegatorVote, + Vote, + RemoveVote, Any, } diff --git a/pallets/flexible-fee/src/lib.rs b/pallets/flexible-fee/src/lib.rs index 1a43f2aa4..567d37fa7 100644 --- a/pallets/flexible-fee/src/lib.rs +++ b/pallets/flexible-fee/src/lib.rs @@ -282,7 +282,7 @@ impl Pallet { .extra_fee_currency .to_token() .map_err(|_| Error::::ConversionError)?; - (fee_currency, XcmInterfaceOperation::VoteVtoken) + (fee_currency, XcmInterfaceOperation::Vote) }, ExtraFeeName::VoteRemoveDelegatorVote => { // We define error code 77 for conversion failure error @@ -290,7 +290,7 @@ impl Pallet { .extra_fee_currency .to_token() .map_err(|_| Error::::ConversionError)?; - (fee_currency, XcmInterfaceOperation::VoteRemoveDelegatorVote) + (fee_currency, XcmInterfaceOperation::RemoveVote) }, ExtraFeeName::NoExtraFee => (fee_info.extra_fee_currency, XcmInterfaceOperation::Any), @@ -319,6 +319,13 @@ impl Pallet { return Ok((total_fee, Zero::zero(), Zero::zero(), path)); } } + + fn get_currency_asset_id(currency_id: CurrencyIdOf) -> Result> { + let asset_id: AssetId = + AssetId::try_convert_from(currency_id, T::ParachainId::get().into()) + .map_err(|_| Error::::ConversionError)?; + Ok(asset_id) + } } /// Default implementation for a Currency and an OnUnbalanced handler. @@ -486,11 +493,4 @@ impl Pallet { } Ok(None) } - - fn get_currency_asset_id(currency_id: CurrencyIdOf) -> Result> { - let asset_id: AssetId = - AssetId::try_convert_from(currency_id, T::ParachainId::get().into()) - .map_err(|_| Error::::ConversionError)?; - Ok(asset_id) - } } diff --git a/pallets/flexible-fee/src/mock.rs b/pallets/flexible-fee/src/mock.rs index d51ff1ba5..a153ae3f8 100644 --- a/pallets/flexible-fee/src/mock.rs +++ b/pallets/flexible-fee/src/mock.rs @@ -20,6 +20,7 @@ use super::*; use crate::{self as flexible_fee, tests::CHARLIE}; +use balances::Call as BalancesCall; use bifrost_asset_registry::AssetIdMaps; use cumulus_primitives_core::ParaId as Pid; #[cfg(feature = "runtime-benchmarks")] @@ -82,6 +83,12 @@ frame_support::construct_runtime!( } ); +pub(crate) const BALANCE_TRANSFER_CALL: ::RuntimeCall = + RuntimeCall::Balances(BalancesCall::transfer_allow_death { dest: ALICE, value: 69 }); + +pub(crate) const SALP_CONTRIBUTE_CALL: ::RuntimeCall = + RuntimeCall::Salp(bifrost_salp::Call::contribute { index: 2001, value: 1_000_000_000_000 }); + impl bifrost_asset_registry::Config for Test { type RuntimeEvent = RuntimeEvent; type Currency = Balances; diff --git a/pallets/flexible-fee/src/tests.rs b/pallets/flexible-fee/src/tests.rs index dcfd09cfd..b83ada465 100644 --- a/pallets/flexible-fee/src/tests.rs +++ b/pallets/flexible-fee/src/tests.rs @@ -253,9 +253,6 @@ fn inner_get_user_fee_charge_order_list_should_work() { }); } -// Three tests below are ignored due to some bugs of zenlink. Tests will be reopened after the bugs -// fixed. - #[test] fn ensure_can_charge_fee_should_work() { new_test_ext().execute_with(|| { @@ -278,22 +275,21 @@ fn ensure_can_charge_fee_should_work() { asset_order_list_vec.clone() )); - // Set bob order as [4,3,2,1]. Alice and Charlie will use the default order of [0..11]] - let _ = FlexibleFee::set_user_default_fee_currency( - origin_signed_bob.clone(), - Some(CURRENCY_ID_0), - ); - + // Alice's default fee currency is Asset 1 let _ = FlexibleFee::set_user_default_fee_currency( RuntimeOrigin::signed(ALICE), Some(CURRENCY_ID_1), ); + // Bob's default fee currency is Asset 0 let _ = FlexibleFee::set_user_default_fee_currency( - RuntimeOrigin::signed(CHARLIE), - Some(CURRENCY_ID_2), + origin_signed_bob.clone(), + Some(CURRENCY_ID_0), ); + // Alice originally should have 50 Asset 0 and 200 Asset 1 + // Now that 50 < 100, so Alice should be deducted some amount from Asset 1 and get 100 Asset + // 0 assert_ok!(FlexibleFee::ensure_can_charge_fee( &ALICE, 100, @@ -301,23 +297,140 @@ fn ensure_can_charge_fee_should_work() { )); // Alice should be deducted 100 from Asset 1 since Asset 0 doesn't have enough balance. - // asset1 : 200-100=100 asset0: 50+100 = 150 + // asset1 : 200-112=88 asset0: 50+100 = 150 assert_eq!(Currencies::total_balance(CURRENCY_ID_0, &ALICE), 150); assert_eq!(Currencies::total_balance(CURRENCY_ID_1, &ALICE), 88); + // Currency 0 is the native currency. assert_eq!(::Currency::free_balance(&ALICE), 150); - // Bob + // Bob originally should have 100 Asset 0 and 200 Asset 1 assert_ok!(FlexibleFee::ensure_can_charge_fee( &BOB, 100, WithdrawReasons::TRANSACTION_PAYMENT, )); assert_eq!(::Currency::free_balance(&BOB), 100); // no exitential deposit requirement. 100 is enough + // Bob should be deducted 100 from Asset 0 since Asset 0 has enough balance. + // Currency 1 should not be affected. assert_eq!(Currencies::total_balance(CURRENCY_ID_1, &BOB), 200); }); } +#[test] +fn find_out_fee_currency_and_amount_should_work() { + new_test_ext().execute_with(|| { + basic_setup(); + + // set universal fee currency order list + let asset_order_list_vec: BoundedVec< + CurrencyId, + ::MaxFeeCurrencyOrderListLen, + > = BoundedVec::try_from(vec![ + CURRENCY_ID_4, + CURRENCY_ID_3, + CURRENCY_ID_2, + CURRENCY_ID_1, + CURRENCY_ID_0, + ]) + .unwrap(); + assert_ok!(FlexibleFee::set_universal_fee_currency_order_list( + RuntimeOrigin::root(), + asset_order_list_vec.clone() + )); + + // charlie originally has 200 currency 0(Native currency) + let (fee_token, amount_in, amount_out) = + FlexibleFee::find_out_fee_currency_and_amount(&CHARLIE, 88).unwrap().unwrap(); + assert_eq!(fee_token, CURRENCY_ID_0); + assert_eq!(amount_in, 88); + assert_eq!(amount_out, 88); + + // alice originally should have 50 Asset 0. Should use Currency 4 to pay fee. + let (fee_token, amount_in, amount_out) = + FlexibleFee::find_out_fee_currency_and_amount(&ALICE, 88).unwrap().unwrap(); + assert_eq!(fee_token, CURRENCY_ID_4); + assert_eq!(amount_in, 97); + assert_eq!(amount_out, 88); + }); +} + +#[test] +fn get_extrinsic_and_extra_fee_total_should_work() { + new_test_ext().execute_with(|| { + basic_setup(); + + let native_asset_id = FlexibleFee::get_currency_asset_id(CURRENCY_ID_0).unwrap(); + let asset_id = FlexibleFee::get_currency_asset_id(CURRENCY_ID_4).unwrap(); + + // call with no extra fee + let path_vec = vec![native_asset_id, native_asset_id]; + let (total_fee, extra_bnc_fee, fee_value, path) = + FlexibleFee::get_extrinsic_and_extra_fee_total(&BALANCE_TRANSFER_CALL, 88).unwrap(); + assert_eq!(total_fee, 88); + assert_eq!(extra_bnc_fee, 0); + assert_eq!(fee_value, 0); + assert_eq!(path, path_vec); + + // call with extra fee + let path_vec = vec![native_asset_id, asset_id]; + let (total_fee, extra_bnc_fee, fee_value, path) = + FlexibleFee::get_extrinsic_and_extra_fee_total(&SALP_CONTRIBUTE_CALL, 88).unwrap(); + assert_eq!(total_fee, 200); + assert_eq!(extra_bnc_fee, 112); + assert_eq!(fee_value, 100); + assert_eq!(path, path_vec); + }); +} + +#[test] +fn cal_fee_token_and_amount_should_work() { + new_test_ext().execute_with(|| { + basic_setup(); + + // set universal fee currency order list + let asset_order_list_vec: BoundedVec< + CurrencyId, + ::MaxFeeCurrencyOrderListLen, + > = BoundedVec::try_from(vec![ + CURRENCY_ID_4, + CURRENCY_ID_3, + CURRENCY_ID_2, + CURRENCY_ID_1, + CURRENCY_ID_0, + ]) + .unwrap(); + assert_ok!(FlexibleFee::set_universal_fee_currency_order_list( + RuntimeOrigin::root(), + asset_order_list_vec.clone() + )); + + // use default asset_order_list_vec + let (currency_id, amount_in) = + FlexibleFee::cal_fee_token_and_amount(&ALICE, 20, &BALANCE_TRANSFER_CALL).unwrap(); + assert_eq!(currency_id, CURRENCY_ID_4); + assert_eq!(amount_in, 21); + + // set alice's default fee currency to be CURRENCY_ID_0 + assert_ok!(FlexibleFee::set_user_default_fee_currency( + RuntimeOrigin::signed(ALICE), + Some(CURRENCY_ID_0), + )); + + // alice has enough balance of CURRENCY_ID_0, so should use CURRENCY_ID_0 to pay fee + let (currency_id, amount_in) = + FlexibleFee::cal_fee_token_and_amount(&ALICE, 20, &BALANCE_TRANSFER_CALL).unwrap(); + assert_eq!(currency_id, CURRENCY_ID_0); + assert_eq!(amount_in, 20); + + // alice originally only have 50 CURRENCY_ID_0. Should use Currency 4 to pay fee. + let (currency_id, amount_in) = + FlexibleFee::cal_fee_token_and_amount(&ALICE, 88, &SALP_CONTRIBUTE_CALL).unwrap(); + assert_eq!(currency_id, CURRENCY_ID_4); + assert_eq!(amount_in, 251); + }); +} + #[test] fn withdraw_fee_should_work() { new_test_ext().execute_with(|| { @@ -382,20 +495,16 @@ fn deduct_salp_fee_should_work() { new_test_ext().execute_with(|| { basic_setup(); - // prepare call variable - let para_id = 2001; - let value = 1_000_000_000_000; - - let call = RuntimeCall::Salp(bifrost_salp::Call::contribute { index: para_id, value }); - // prepare info variable let extra = (); - let xt = TestXt::new(call.clone(), Some((0u64, extra))); + let xt = TestXt::new(SALP_CONTRIBUTE_CALL.clone(), Some((0u64, extra))); let info = xt.get_dispatch_info(); - // 99 inclusion fee and a tip of 8 - assert_ok!(FlexibleFee::withdraw_fee(&CHARLIE, &call, &info, 80, 8)); + // 80 inclusion fee and a tip of 8 + assert_ok!(FlexibleFee::withdraw_fee(&CHARLIE, &SALP_CONTRIBUTE_CALL, &info, 80, 8)); + // originally Charlie has 200 currency 0(Native currency) + // 200 - 88 = 112. extra fee cost 104. 112 - 104 = 8 assert_eq!(::Currency::free_balance(&CHARLIE), 8); // Other currencies should not be affected @@ -417,3 +526,18 @@ fn deduct_salp_fee_should_work() { ); }); } + +#[test] +fn get_currency_asset_id_should_work() { + new_test_ext().execute_with(|| { + // BNC + let asset_id = FlexibleFee::get_currency_asset_id(CURRENCY_ID_0).unwrap(); + let bnc_asset_id = AssetId { chain_id: 2001, asset_type: 0, asset_index: 0 }; + assert_eq!(asset_id, bnc_asset_id); + + // KSM + let asset_id = FlexibleFee::get_currency_asset_id(CURRENCY_ID_4).unwrap(); + let ksm_asset_id = AssetId { chain_id: 2001, asset_type: 2, asset_index: 516 }; + assert_eq!(asset_id, ksm_asset_id); + }); +} diff --git a/pallets/slp/src/benchmarking.rs b/pallets/slp/src/benchmarking.rs index c44867ea0..7f4f60c94 100644 --- a/pallets/slp/src/benchmarking.rs +++ b/pallets/slp/src/benchmarking.rs @@ -19,7 +19,7 @@ // Ensure we're `no_std` when compiling for Wasm. #![cfg(feature = "runtime-benchmarks")] -use frame_benchmarking::{account, benchmarks, v1::BenchmarkError, whitelisted_caller}; +use frame_benchmarking::{benchmarks, v1::BenchmarkError, whitelisted_caller}; use frame_support::{assert_ok, dispatch::UnfilteredDispatchable}; use frame_system::RawOrigin; use node_primitives::TokenSymbol; @@ -131,15 +131,13 @@ fn kusama_setup< Some((treasury_location, BalanceOf::::unique_saturated_from(1_000_000_000_000u128))), )); - assert_ok!(Slp::::set_xcm_dest_weight_and_fee( - origin.clone(), + assert_ok!(::XcmWeightAndFeeHandler::set_xcm_dest_weight_and_fee( KSM, XcmOperation::Bond, Some((Weight::from_parts(0, u64::MAX), BalanceOf::::unique_saturated_from(0u128))), )); - assert_ok!(Slp::::set_xcm_dest_weight_and_fee( - origin.clone(), + assert_ok!(::XcmWeightAndFeeHandler::set_xcm_dest_weight_and_fee( KSM, XcmOperation::BondExtra, Some(( @@ -148,8 +146,7 @@ fn kusama_setup< )), )); - assert_ok!(Slp::::set_xcm_dest_weight_and_fee( - origin.clone(), + assert_ok!(::XcmWeightAndFeeHandler::set_xcm_dest_weight_and_fee( KSM, XcmOperation::Unbond, Some(( @@ -158,8 +155,7 @@ fn kusama_setup< )), )); - assert_ok!(Slp::::set_xcm_dest_weight_and_fee( - origin.clone(), + assert_ok!(::XcmWeightAndFeeHandler::set_xcm_dest_weight_and_fee( KSM, XcmOperation::Chill, Some(( @@ -168,8 +164,7 @@ fn kusama_setup< )), )); - assert_ok!(Slp::::set_xcm_dest_weight_and_fee( - origin.clone(), + assert_ok!(::XcmWeightAndFeeHandler::set_xcm_dest_weight_and_fee( KSM, XcmOperation::Rebond, Some(( @@ -178,8 +173,7 @@ fn kusama_setup< )), )); - assert_ok!(Slp::::set_xcm_dest_weight_and_fee( - origin.clone(), + assert_ok!(::XcmWeightAndFeeHandler::set_xcm_dest_weight_and_fee( KSM, XcmOperation::Undelegate, Some(( @@ -188,8 +182,7 @@ fn kusama_setup< )), )); - assert_ok!(Slp::::set_xcm_dest_weight_and_fee( - origin.clone(), + assert_ok!(::XcmWeightAndFeeHandler::set_xcm_dest_weight_and_fee( KSM, XcmOperation::Delegate, Some(( @@ -198,8 +191,7 @@ fn kusama_setup< )), )); - assert_ok!(Slp::::set_xcm_dest_weight_and_fee( - origin.clone(), + assert_ok!(::XcmWeightAndFeeHandler::set_xcm_dest_weight_and_fee( KSM, XcmOperation::Payout, Some(( @@ -208,8 +200,7 @@ fn kusama_setup< )), )); - assert_ok!(Slp::::set_xcm_dest_weight_and_fee( - origin.clone(), + assert_ok!(::XcmWeightAndFeeHandler::set_xcm_dest_weight_and_fee( KSM, XcmOperation::CancelLeave, Some(( @@ -218,8 +209,7 @@ fn kusama_setup< )), )); - assert_ok!(Slp::::set_xcm_dest_weight_and_fee( - origin.clone(), + assert_ok!(::XcmWeightAndFeeHandler::set_xcm_dest_weight_and_fee( KSM, XcmOperation::Liquidize, Some(( @@ -228,8 +218,7 @@ fn kusama_setup< )), )); - assert_ok!(Slp::::set_xcm_dest_weight_and_fee( - origin.clone(), + assert_ok!(::XcmWeightAndFeeHandler::set_xcm_dest_weight_and_fee( KSM, XcmOperation::ExecuteLeave, Some(( @@ -238,8 +227,7 @@ fn kusama_setup< )), )); - assert_ok!(Slp::::set_xcm_dest_weight_and_fee( - origin.clone(), + assert_ok!(::XcmWeightAndFeeHandler::set_xcm_dest_weight_and_fee( KSM, XcmOperation::TransferBack, Some(( @@ -248,8 +236,7 @@ fn kusama_setup< )), )); - assert_ok!(Slp::::set_xcm_dest_weight_and_fee( - origin.clone(), + assert_ok!(::XcmWeightAndFeeHandler::set_xcm_dest_weight_and_fee( KSM, XcmOperation::XtokensTransferBack, Some(( @@ -258,8 +245,7 @@ fn kusama_setup< )), )); - assert_ok!(Slp::::set_xcm_dest_weight_and_fee( - origin.clone(), + assert_ok!(::XcmWeightAndFeeHandler::set_xcm_dest_weight_and_fee( KSM, XcmOperation::TransferTo, Some(( @@ -508,8 +494,7 @@ benchmarks! { assert_ok!(Slp::::set_operate_origin(origin.clone(), KSM, Some(who.clone()))); assert_ok!(Slp::::add_delegator(origin.clone(), KSM, 1u16,Box::new(subaccount_0_location.clone()))); - assert_ok!(Slp::::set_xcm_dest_weight_and_fee( - origin.clone(), + assert_ok!(::XcmWeightAndFeeHandler::set_xcm_dest_weight_and_fee( KSM, XcmOperation::TransferBack, Some((Weight::from_parts(20_000_000_000, u64::MAX), BalanceOf::::unique_saturated_from(10_000_000_000u128))), @@ -656,508 +641,6 @@ benchmarks! { }; }: {call.dispatch_bypass_filter(RawOrigin::Signed(who.clone()).into())?} - set_xcm_dest_weight_and_fee { - let origin = ::ControlOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; - let call = Call::::set_xcm_dest_weight_and_fee { - currency_id:KSM, - operation:XcmOperation::Bond, - weight_and_fee:Some((Weight::from_parts(5_000_000_000, u64::MAX), BalanceOf::::unique_saturated_from(5_000_000_000u128))) - }; - }: {call.dispatch_bypass_filter(origin)?} - verify { - assert_eq!(Slp::::xcm_dest_weight_and_fee(KSM,XcmOperation::Bond),Some((Weight::from_parts(5_000_000_000, u64::MAX),BalanceOf::::unique_saturated_from(5_000_000_000u128) ))); - } - - set_operate_origin { - let origin = ::ControlOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; - let who: T::AccountId = whitelisted_caller(); - let call = Call::::set_operate_origin { - currency_id:KSM, - who:Some(who.clone()) - }; - }: {call.dispatch_bypass_filter(origin)?} - verify { - assert_eq!(Slp::::get_operate_origin(KSM),Some(who.clone())); - } - - set_fee_source { - let origin = ::ControlOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; - let who: T::AccountId = whitelisted_caller(); - let who_32 = Pallet::::account_id_to_account_32(who).unwrap(); - let who_location = Pallet::::account_32_to_local_location(who_32).unwrap(); - let call = Call::::set_fee_source { - currency_id:KSM, - who_and_fee:Some((who_location.clone(),BalanceOf::::unique_saturated_from(5_000_000_000u128))) - }; - }: {call.dispatch_bypass_filter(origin)?} - verify { - assert_eq!(Slp::::get_fee_source(KSM),Some((who_location.clone(),BalanceOf::::unique_saturated_from(5_000_000_000u128)))); - } - - add_delegator { - kusama_setup::()?; - let origin = ::ControlOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; - let who: T::AccountId = whitelisted_caller(); - - let subaccount_0_32: [u8; 32] = Pallet::::account_id_to_account_32(who).unwrap(); - let subaccount_0_location: MultiLocation = - Pallet::::account_32_to_parent_location(subaccount_0_32).unwrap(); - - let call = Call::::add_delegator { - currency_id:KSM, - index:2u16, - who:Box::new(subaccount_0_location.clone()), - }; - }: {call.dispatch_bypass_filter(origin)?} - - remove_delegator { - let origin = ::ControlOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; - let who: T::AccountId = whitelisted_caller(); - let subaccount_0_32: [u8; 32] = Pallet::::account_id_to_account_32(who.clone()).unwrap(); - let subaccount_0_location: MultiLocation = - Pallet::::account_32_to_parent_location(subaccount_0_32).unwrap(); - let who2: T::AccountId = whitelisted_caller(); - let validator_0_account_id_20: [u8; 32] = Pallet::::account_id_to_account_32(who2.clone()).unwrap(); - let validator_0_location: MultiLocation = - Pallet::::account_32_to_parent_location(validator_0_account_id_20).unwrap(); - kusama_setup::()?; - assert_ok!(Slp::::add_delegator(origin.clone(), KSM, 1u16,Box::new(subaccount_0_location.clone()))); - assert_ok!(Slp::::add_validator(origin.clone(), KSM,Box::new(validator_0_location.clone()))); - - assert_ok!(Slp::::bond( - RawOrigin::Signed(who.clone()).into(), - KSM, - Box::new(subaccount_0_location.clone()), - BalanceOf::::unique_saturated_from(5_000_000_000_000_000_000u128), - Some(validator_0_location.clone()), - )); - - let call = Call::::remove_delegator { - currency_id:KSM, - who:Box::new(subaccount_0_location.clone()), - }; - }: {call.dispatch_bypass_filter(origin)?} - - set_validators_by_delegator { - let origin = ::ControlOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; - let who: T::AccountId = whitelisted_caller(); - let subaccount_0_32: [u8; 32] = Pallet::::account_id_to_account_32(who.clone()).unwrap(); - let subaccount_0_location: MultiLocation = - Pallet::::account_32_to_parent_location(subaccount_0_32).unwrap(); - let who2: T::AccountId = whitelisted_caller(); - let validator_0_account_id_20: [u8; 32] = Pallet::::account_id_to_account_32(who2.clone()).unwrap(); - let validator_0_location: MultiLocation = - Pallet::::account_32_to_parent_location(validator_0_account_id_20).unwrap(); - kusama_setup::()?; - assert_ok!(Slp::::add_delegator(origin.clone(), KSM, 1u16,Box::new(subaccount_0_location.clone()))); - assert_ok!(Slp::::add_validator(origin.clone(), KSM,Box::new(validator_0_location.clone()))); - - assert_ok!(Slp::::bond( - RawOrigin::Signed(who.clone()).into(), - KSM, - Box::new(subaccount_0_location.clone()), - BalanceOf::::unique_saturated_from(5_000_000_000_000_000_000u128), - Some(validator_0_location.clone()), - )); - let call = Call::::set_validators_by_delegator { - currency_id:KSM, - who:Box::new(subaccount_0_location.clone()), - validators:vec![validator_0_location.clone()] - }; - }: {call.dispatch_bypass_filter(origin)?} - - set_delegator_ledger { - let origin = ::ControlOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; - let who: T::AccountId = whitelisted_caller(); - let subaccount_0_32: [u8; 32] = Pallet::::account_id_to_account_32(who).unwrap(); - - let subaccount_0_location: MultiLocation = - Pallet::::account_32_to_parent_location(subaccount_0_32).unwrap(); - kusama_setup::()?; - let sb_ledger = SubstrateLedger { - account: subaccount_0_location.clone(), - total: BalanceOf::::unique_saturated_from(10_000_000_000_000u128), - active: BalanceOf::::unique_saturated_from(10_000_000_000_000u128), - unlocking: vec![], - }; - let ledger = Ledger::Substrate(sb_ledger); - - let call = Call::::set_delegator_ledger { - currency_id:KSM, - who:Box::new(subaccount_0_location.clone()), - ledger:Box::new(Some(ledger)) - }; - }: {call.dispatch_bypass_filter(origin)?} - - add_validator { - kusama_setup::()?; - let origin = ::ControlOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; - let who: T::AccountId = whitelisted_caller(); - let subaccount_0_32: [u8; 32] = Pallet::::account_id_to_account_32(who).unwrap(); - - let subaccount_0_location: MultiLocation = - Pallet::::account_32_to_parent_location(subaccount_0_32).unwrap(); - - let call = Call::::add_validator { - currency_id:KSM, - who:Box::new(subaccount_0_location.clone()), - }; - }: {call.dispatch_bypass_filter(origin)?} - - remove_validator { - kusama_setup::()?; - let origin = ::ControlOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; - let who: T::AccountId = whitelisted_caller(); - let subaccount_0_32: [u8; 32] = Pallet::::account_id_to_account_32(who).unwrap(); - - let subaccount_0_location: MultiLocation = - Pallet::::account_32_to_parent_location(subaccount_0_32).unwrap(); - - assert_ok!(Slp::::add_validator(origin.clone(),KSM,Box::new(subaccount_0_location.clone()))); - - let call = Call::::remove_validator { - currency_id:KSM, - who:Box::new(subaccount_0_location.clone()), - }; - }: {call.dispatch_bypass_filter(origin)?} - - reset_validators { - kusama_setup::()?; - let origin = ::ControlOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; - let who: T::AccountId = whitelisted_caller(); - let subaccount_0_32: [u8; 32] = Pallet::::account_id_to_account_32(who).unwrap(); - - let subaccount_0_location: MultiLocation = - Pallet::::account_32_to_parent_location(subaccount_0_32).unwrap(); - - let call = Call::::reset_validators { - currency_id:KSM, - validator_list:vec![subaccount_0_location], - }; - }: {call.dispatch_bypass_filter(origin)?} - - set_validator_boost_list { - kusama_setup::()?; - let origin = ::ControlOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; - let who: T::AccountId = whitelisted_caller(); - let subaccount_0_32: [u8; 32] = Pallet::::account_id_to_account_32(who).unwrap(); - - let subaccount_0_location: MultiLocation = - Pallet::::account_32_to_parent_location(subaccount_0_32).unwrap(); - - let call = Call::::set_validator_boost_list { - currency_id:KSM, - validator_list:vec![subaccount_0_location], - }; - }: {call.dispatch_bypass_filter(origin)?} - - convert_asset { - kusama_setup::()?; - let origin = ::ControlOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; - let who: T::AccountId = whitelisted_caller(); - let subaccount_0_32: [u8; 32] = Pallet::::account_id_to_account_32(who).unwrap(); - - let subaccount_0_location: MultiLocation = - Pallet::::account_32_to_parent_location(subaccount_0_32).unwrap(); - - let call = Call::::convert_asset { - currency_id:KSM, - who:Box::new(subaccount_0_location.clone()), - amount: BalanceOf::::unique_saturated_from(10_000_000_000_000u128), - if_from_currency: true - }; - }: {call.dispatch_bypass_filter(origin)?} - - add_to_validator_boost_list { - kusama_setup::()?; - let origin = ::ControlOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; - let who: T::AccountId = whitelisted_caller(); - let subaccount_0_32: [u8; 32] = Pallet::::account_id_to_account_32(who).unwrap(); - - let subaccount_0_location: MultiLocation = - Pallet::::account_32_to_parent_location(subaccount_0_32).unwrap(); - - let call = Call::::add_to_validator_boost_list { - currency_id:KSM, - who:Box::new(subaccount_0_location.clone()), - }; - }: {call.dispatch_bypass_filter(origin)?} - - remove_from_validator_boot_list { - kusama_setup::()?; - let origin = ::ControlOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; - let who: T::AccountId = whitelisted_caller(); - let subaccount_0_32: [u8; 32] = Pallet::::account_id_to_account_32(who).unwrap(); - - let subaccount_0_location: MultiLocation = - Pallet::::account_32_to_parent_location(subaccount_0_32).unwrap(); - - assert_ok!(Slp::::add_to_validator_boost_list(origin.clone(),KSM,Box::new(subaccount_0_location.clone()))); - - let call = Call::::remove_from_validator_boot_list { - currency_id:KSM, - who:Box::new(subaccount_0_location.clone()), - }; - }: {call.dispatch_bypass_filter(origin)?} - - - set_minimums_and_maximums { - let origin = ::ControlOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; - - let mins_and_maxs = MinimumsMaximums { - delegator_bonded_minimum: BalanceOf::::unique_saturated_from(100_000_000_000u128), - - bond_extra_minimum: BalanceOf::::unique_saturated_from(100_000_000_000u128), - unbond_minimum: BalanceOf::::unique_saturated_from(100_000_000_000u128), - rebond_minimum: BalanceOf::::unique_saturated_from(100_000_000_000u128), - unbond_record_maximum: 1u32, - validators_back_maximum: 100u32, - delegator_active_staking_maximum: BalanceOf::::unique_saturated_from(200_000_000_000_000_000_000u128), - validators_reward_maximum: 300u32, - delegation_amount_minimum: BalanceOf::::unique_saturated_from(500_000_000u128), - delegators_maximum: 0, - validators_maximum: 0 - }; - let call = Call::::set_minimums_and_maximums { - currency_id:KSM, - constraints:Some(mins_and_maxs) - }; - }: {call.dispatch_bypass_filter(origin)?} - - set_currency_delays { - let origin = ::ControlOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; - let delay = - Delays { unlock_delay: TimeUnit::Round(24), leave_delegators_delay: TimeUnit::Round(24) }; - - let call = Call::::set_currency_delays { - currency_id:KSM, - maybe_delays:Some(delay) - }; - }: {call.dispatch_bypass_filter(origin)?} - - set_hosting_fees { - let origin = ::ControlOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; - let treasury_32: [u8; 32] = - hex_literal::hex!["6d6f646c62662f74727372790000000000000000000000000000000000000000"]; - let pct = Permill::from_percent(20); - let treasury_location = MultiLocation { - parents: 0, - interior: X1(AccountId32 { network: None, id: treasury_32 }), - }; - let call = Call::::set_hosting_fees { - currency_id:KSM, - maybe_fee_set:Some((pct, treasury_location)) - }; - }: {call.dispatch_bypass_filter(origin)?} - - set_currency_tune_exchange_rate_limit { - let origin = ::ControlOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; - let pct_100 = Permill::from_percent(100); - let call = Call::::set_currency_tune_exchange_rate_limit { - currency_id:KSM, - maybe_tune_exchange_rate_limit:Some((1, pct_100)) - }; - }: {call.dispatch_bypass_filter(origin)?} - - set_ongoing_time_unit_update_interval { - let origin = ::ControlOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; - - let call = Call::::set_ongoing_time_unit_update_interval { - currency_id:KSM, - maybe_interval:Some(BlockNumberFor::::from(100u32)) - }; - }: {call.dispatch_bypass_filter(origin)?} - verify { - assert_eq!(Slp::::get_ongoing_time_unit_update_interval(KSM),Some(BlockNumberFor::::from(100u32))); - } - - add_supplement_fee_account_to_whitelist { - let origin = ::ControlOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; - let exit_account_id_32: [u8; 32] = - hex_literal::hex!["6d6f646c62662f76746f75740000000000000000000000000000000000000000"] - .into(); - let exit_account_location = MultiLocation { - parents: 0, - interior: X1(Junction::AccountId32 { network: None, id: exit_account_id_32 }), - }; - - let call = Call::::add_supplement_fee_account_to_whitelist { - currency_id:KSM, - who:Box::new(exit_account_location.clone()), - }; - }: {call.dispatch_bypass_filter(origin)?} - - remove_supplement_fee_account_from_whitelist { - let origin = ::ControlOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; - let exit_account_id_32: [u8; 32] = - hex_literal::hex!["6d6f646c62662f76746f75740000000000000000000000000000000000000000"] - .into(); - let exit_account_location = MultiLocation { - parents: 0, - interior: X1(Junction::AccountId32 { network: None, id: exit_account_id_32 }), - }; - assert_ok!(Slp::::add_supplement_fee_account_to_whitelist(origin.clone(), KSM, Box::new(exit_account_location.clone()))); - let call = Call::::remove_supplement_fee_account_from_whitelist { - currency_id:KSM, - who:Box::new(exit_account_location.clone()), - }; - }: {call.dispatch_bypass_filter(origin)?} - - unbond { - let origin = ::ControlOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; - let who: T::AccountId = whitelisted_caller(); - let subaccount_0_32: [u8; 32] = Pallet::::account_id_to_account_32(who.clone()).unwrap(); - let subaccount_0_location: MultiLocation = - Pallet::::account_32_to_parent_location(subaccount_0_32).unwrap(); - let validator_0_account_id_20: [u8; 20] = - hex_literal::hex!["3Cd0A705a2DC65e5b1E1205896BaA2be8A07c6e0"].into(); - let validator_0_location = MultiLocation { - parents: 1, - interior: X2( - Parachain(2023), - AccountKey20 { network: None, key: validator_0_account_id_20 }, - ), - }; - kusama_setup::()?; - assert_ok!(Slp::::add_delegator(origin.clone(), KSM, 1u16,Box::new(subaccount_0_location.clone()))); - assert_ok!(Slp::::bond( - RawOrigin::Signed(who.clone()).into(), - KSM, - Box::new(subaccount_0_location.clone()), - BalanceOf::::unique_saturated_from(5_000_000_000_000_000_000u128), - Some(validator_0_location.clone()), - )); - - let call = Call::::unbond { - currency_id:KSM, - who:Box::new(subaccount_0_location.clone()), - validator:None, - amount:BalanceOf::::unique_saturated_from(0u128), - }; - }: {call.dispatch_bypass_filter(RawOrigin::Signed(who.clone()).into())?} - - unbond_all { - let origin = ::ControlOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; - let who: T::AccountId = whitelisted_caller(); - let subaccount_0_32: [u8; 32] = Pallet::::account_id_to_account_32(who.clone()).unwrap(); - let subaccount_0_location: MultiLocation = - Pallet::::account_32_to_parent_location(subaccount_0_32).unwrap(); - let validator_0_account_id_20: [u8; 20] = - hex_literal::hex!["3Cd0A705a2DC65e5b1E1205896BaA2be8A07c6e0"].into(); - let validator_0_location = MultiLocation { - parents: 1, - interior: X2( - Parachain(2023), - AccountKey20 { network: None, key: validator_0_account_id_20 }, - ), - }; - kusama_setup::()?; - assert_ok!(Slp::::add_delegator(origin.clone(), KSM, 1u16,Box::new(subaccount_0_location.clone()))); - assert_ok!(Slp::::bond( - RawOrigin::Signed(who.clone()).into(), - KSM, - Box::new(subaccount_0_location.clone()), - BalanceOf::::unique_saturated_from(5_000_000_000_000_000_000u128), - Some(validator_0_location.clone()), - )); - - let call = Call::::unbond_all { - currency_id:KSM, - who:Box::new(subaccount_0_location.clone()), - }; - }: {call.dispatch_bypass_filter(RawOrigin::Signed(who.clone()).into())?} - - undelegate { - let origin = ::ControlOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; - let who: T::AccountId = whitelisted_caller(); - let subaccount_0_32: [u8; 32] = Pallet::::account_id_to_account_32(who.clone()).unwrap(); - let subaccount_0_location: MultiLocation = - Pallet::::account_32_to_parent_location(subaccount_0_32).unwrap(); - - let validator_0_account: T::AccountId = account("validator0",0,1); - let validator_0_32: [u8; 32] = Pallet::::account_id_to_account_32(validator_0_account.clone()).unwrap(); - let validator_0_location: MultiLocation = - Pallet::::account_32_to_parent_location(validator_0_32).unwrap(); - - let validator_1_account: T::AccountId = account("validator1",0,1); - let validator_1_32: [u8; 32] = Pallet::::account_id_to_account_32(validator_1_account.clone()).unwrap(); - let validator_1_location: MultiLocation = - Pallet::::account_32_to_parent_location(validator_1_32).unwrap(); - - kusama_setup::()?; - - assert_ok!(Slp::::add_delegator(origin.clone(), KSM, 1u16,Box::new(subaccount_0_location.clone()))); - assert_ok!(Slp::::add_validator(origin.clone(), KSM,Box::new(validator_0_location.clone()))); - assert_ok!(Slp::::add_validator(origin.clone(), KSM,Box::new(validator_1_location.clone()))); - - let sb_ledger = SubstrateLedger { - account: subaccount_0_location.clone(), - total: BalanceOf::::unique_saturated_from(1000_000_000_000u128), - active: BalanceOf::::unique_saturated_from(500_000_000_000u128), - unlocking: vec![], - }; - let ledger = Ledger::Substrate(sb_ledger); - DelegatorLedgers::::insert(KSM, subaccount_0_location.clone(), ledger); - - assert_ok!(Slp::::set_validators_by_delegator ( - origin.clone(), - KSM, - Box::new(subaccount_0_location.clone()), - vec![validator_0_location.clone(),validator_1_location.clone()] - )); - - let call = Call::::undelegate { - currency_id:KSM, - who:Box::new(subaccount_0_location.clone()), - targets:vec![validator_0_location.clone()], - }; - }: {call.dispatch_bypass_filter(RawOrigin::Signed(who.clone()).into())?} - - transfer_to { - kusama_setup::()?; - let origin = ::ControlOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; - let who: T::AccountId = whitelisted_caller(); - - let subaccount_0_32: [u8; 32] = Pallet::::account_id_to_account_32(who.clone()).unwrap(); - - let subaccount_0_location: MultiLocation = - Pallet::::account_32_to_parent_location(subaccount_0_32).unwrap(); - - let entrance_account: T::AccountId = T::EntranceAccount::get().into_account_truncating(); - - assert_ok!(orml_tokens::Pallet::::set_balance( - RawOrigin::Root.into(), - lookup_of_account::(entrance_account.clone()), - KSM, - ::Balance::unique_saturated_from(1_000_000_000_000_000_000u128), - ::Balance::unique_saturated_from(0u128) - )); - - assert_eq!(orml_tokens::Pallet::::total_balance(KSM, &entrance_account), - ::Balance::unique_saturated_from(1_000_000_000_000_000_000u128) - ); - - - let entrance_account_32 = Slp::::account_id_to_account_32(entrance_account.clone()).unwrap(); - let entrance_account_location: MultiLocation = - Slp::::account_32_to_local_location(entrance_account_32).unwrap(); - - assert_ok!(Slp::::set_operate_origin(origin.clone(), KSM, Some(who.clone()))); - assert_ok!(Slp::::add_delegator(origin.clone(), KSM, 1u16,Box::new(subaccount_0_location.clone()))); - assert_ok!(Slp::::set_xcm_dest_weight_and_fee( - origin.clone(), - KSM, - XcmOperation::TransferTo, - Some((Weight::from_parts(20_000_000_000, u64::MAX), BalanceOf::::unique_saturated_from(10_000_000_000u128))), - )); - let call = Call::::transfer_to { - currency_id:KSM, - from:Box::new(entrance_account_location.clone()), - to:Box::new(subaccount_0_location.clone()), - amount: BalanceOf::::unique_saturated_from(10_000_000_000u128) - }; - }: {call.dispatch_bypass_filter(RawOrigin::Signed(who.clone()).into())?} - chill { kusama_setup::()?; let origin = ::ControlOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; @@ -1189,8 +672,7 @@ benchmarks! { assert_ok!(Slp::::set_operate_origin(origin.clone(), KSM, Some(who.clone()))); assert_ok!(Slp::::add_delegator(origin.clone(), KSM, 1u16,Box::new(subaccount_0_location.clone()))); - assert_ok!(Slp::::set_xcm_dest_weight_and_fee( - origin.clone(), + assert_ok!(::XcmWeightAndFeeHandler::set_xcm_dest_weight_and_fee( KSM, XcmOperation::Chill, Some((Weight::from_parts(20_000_000_000, u64::MAX), BalanceOf::::unique_saturated_from(10_000_000_000u128))), @@ -1253,8 +735,7 @@ benchmarks! { assert_ok!(Slp::::set_operate_origin(origin.clone(), KSM, Some(who.clone()))); assert_ok!(Slp::::add_delegator(origin.clone(), KSM, 1u16,Box::new(subaccount_0_location.clone()))); - assert_ok!(Slp::::set_xcm_dest_weight_and_fee( - origin.clone(), + assert_ok!(::XcmWeightAndFeeHandler::set_xcm_dest_weight_and_fee( KSM, XcmOperation::TransferTo, Some((Weight::from_parts(20_000_000_000, u64::MAX), BalanceOf::::unique_saturated_from(10_000_000_000u128))), @@ -1330,8 +811,7 @@ benchmarks! { assert_ok!(Slp::::set_operate_origin(origin.clone(), KSM, Some(who.clone()))); assert_ok!(Slp::::add_delegator(origin.clone(), KSM, 1u16,Box::new(subaccount_0_location.clone()))); assert_ok!(Slp::::add_validator(origin.clone(), KSM,Box::new(validator_0_location.clone()))); - assert_ok!(Slp::::set_xcm_dest_weight_and_fee( - origin.clone(), + assert_ok!(::XcmWeightAndFeeHandler::set_xcm_dest_weight_and_fee( KSM, XcmOperation::TransferTo, Some((Weight::from_parts(20_000_000_000, u64::MAX), BalanceOf::::unique_saturated_from(10_000_000_000u128))), @@ -1412,8 +892,7 @@ benchmarks! { assert_ok!(Slp::::set_operate_origin(origin.clone(), KSM, Some(who.clone()))); assert_ok!(Slp::::add_delegator(origin.clone(), KSM, 1u16,Box::new(subaccount_0_location.clone()))); assert_ok!(Slp::::add_validator(origin.clone(), KSM,Box::new(validator_0_location.clone()))); - assert_ok!(Slp::::set_xcm_dest_weight_and_fee( - origin.clone(), + assert_ok!(::XcmWeightAndFeeHandler::set_xcm_dest_weight_and_fee( KSM, XcmOperation::TransferTo, Some((Weight::from_parts(20_000_000_000, u64::MAX), BalanceOf::::unique_saturated_from(10_000_000_000u128))), diff --git a/pallets/slp/src/lib.rs b/pallets/slp/src/lib.rs index e70888a7c..0dcd605d8 100644 --- a/pallets/slp/src/lib.rs +++ b/pallets/slp/src/lib.rs @@ -420,11 +420,6 @@ pub mod pallet { validators_list: Vec, delegator_id: MultiLocation, }, - XcmDestWeightAndFeeSet { - currency_id: CurrencyId, - operation: XcmOperation, - weight_and_fee: Option<(XcmWeight, BalanceOf)>, - }, OperateOriginSet { currency_id: CurrencyId, operator: Option>, @@ -1541,35 +1536,6 @@ pub mod pallet { /// ***************************** /// ****** Storage Setters ****** /// ***************************** - #[pallet::call_index(21)] - #[pallet::weight(T::WeightInfo::set_xcm_dest_weight_and_fee())] - pub fn set_xcm_dest_weight_and_fee( - origin: OriginFor, - currency_id: CurrencyId, - operation: XcmOperation, - weight_and_fee: Option<(XcmWeight, BalanceOf)>, - ) -> DispatchResult { - // Check the validity of origin - T::ControlOrigin::ensure_origin(origin)?; - - // If param weight_and_fee is a none, it will delete the storage. Otherwise, revise the - // storage to the new value if exists, or insert a new record if not exists before. - T::XcmWeightAndFeeHandler::set_xcm_dest_weight_and_fee( - currency_id, - operation, - weight_and_fee, - )?; - - // Deposit event. - Pallet::::deposit_event(Event::XcmDestWeightAndFeeSet { - currency_id, - operation, - weight_and_fee, - }); - - Ok(()) - } - /// Update storage OperateOrigins. #[pallet::call_index(22)] #[pallet::weight(T::WeightInfo::set_operate_origin())] diff --git a/pallets/slp/src/mocks/mock.rs b/pallets/slp/src/mocks/mock.rs index 73d4a53a7..64c33c9a5 100644 --- a/pallets/slp/src/mocks/mock.rs +++ b/pallets/slp/src/mocks/mock.rs @@ -21,7 +21,7 @@ #![cfg(test)] use crate as bifrost_slp; -use crate::{Config, QueryResponseManager}; +use crate::{Config, DispatchResult, QueryResponseManager, XcmDestWeightAndFeeHandler}; use bifrost_asset_registry::AssetIdMaps; use codec::{Decode, Encode}; pub use cumulus_primitives_core::ParaId; @@ -38,7 +38,7 @@ use hex_literal::hex; use node_primitives::currency::VKSM; use node_primitives::{ currency::{BNC, KSM}, - Amount, Balance, CurrencyId, SlpxOperator, TokenSymbol, + Amount, Balance, CurrencyId, SlpxOperator, TokenSymbol, XcmInterfaceOperation, }; use orml_traits::{location::RelativeReserveProvider, parameter_type_with_key}; use sp_core::{bounded::BoundedVec, hashing::blake2_256, ConstU32, H256}; @@ -469,7 +469,26 @@ impl Config for Runtime { type ParachainStaking = ParachainStaking; type XcmTransfer = XTokens; type MaxLengthLimit = MaxLengthLimit; - type XcmWeightAndFeeHandler = (); + type XcmWeightAndFeeHandler = XcmDestWeightAndFee; +} + +pub struct XcmDestWeightAndFee; +impl XcmDestWeightAndFeeHandler for XcmDestWeightAndFee { + fn get_operation_weight_and_fee( + _token: CurrencyId, + _operation: XcmInterfaceOperation, + ) -> Option<(Weight, Balance)> { + // Some((Weight::from_parts(100, 100), 100u32.into())) + Some((20_000_000_000.into(), 10_000_000_000)) + } + + fn set_xcm_dest_weight_and_fee( + _currency_id: CurrencyId, + _operation: XcmInterfaceOperation, + _weight_and_fee: Option<(Weight, Balance)>, + ) -> DispatchResult { + Ok(()) + } } parameter_types! { diff --git a/pallets/slp/src/mocks/mock_kusama.rs b/pallets/slp/src/mocks/mock_kusama.rs index ad5a8f8e9..a6958b7c6 100644 --- a/pallets/slp/src/mocks/mock_kusama.rs +++ b/pallets/slp/src/mocks/mock_kusama.rs @@ -22,6 +22,8 @@ use bifrost_asset_registry::AssetIdMaps; // use parachain_staking::ParachainStakingInterface; +use crate as bifrost_slp; +use crate::{Config, DispatchResult, QueryResponseManager}; use codec::{Decode, Encode}; pub use cumulus_primitives_core::ParaId; use frame_support::{ @@ -35,7 +37,8 @@ use frame_system::{EnsureRoot, EnsureSignedBy}; use hex_literal::hex; use node_primitives::{ currency::{BNC, KSM, VKSM}, - Amount, Balance, CurrencyId, SlpxOperator, TokenSymbol, + Amount, Balance, CurrencyId, SlpxOperator, TokenSymbol, XcmDestWeightAndFeeHandler, + XcmInterfaceOperation, }; use orml_traits::{location::RelativeReserveProvider, parameter_type_with_key}; use sp_core::{bounded::BoundedVec, hashing::blake2_256, ConstU32, H256}; @@ -49,9 +52,6 @@ use xcm::v3::{prelude::*, Weight}; use xcm_builder::FixedWeightBounds; use xcm_executor::XcmExecutor; -use crate as bifrost_slp; -use crate::{Config, QueryResponseManager}; - pub type AccountId = AccountId32; pub type Block = frame_system::mocking::MockBlock; pub type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; @@ -484,7 +484,26 @@ impl Config for Runtime { type ParachainStaking = ParachainStaking; type XcmTransfer = XTokens; type MaxLengthLimit = MaxLengthLimit; - type XcmWeightAndFeeHandler = (); + type XcmWeightAndFeeHandler = XcmDestWeightAndFee; +} + +pub struct XcmDestWeightAndFee; +impl XcmDestWeightAndFeeHandler for XcmDestWeightAndFee { + fn get_operation_weight_and_fee( + _token: CurrencyId, + _operation: XcmInterfaceOperation, + ) -> Option<(Weight, Balance)> { + // Some((Weight::from_parts(100, 100), 100u32.into())) + Some((20_000_000_000.into(), 10_000_000_000)) + } + + fn set_xcm_dest_weight_and_fee( + _currency_id: CurrencyId, + _operation: XcmInterfaceOperation, + _weight_and_fee: Option<(Weight, Balance)>, + ) -> DispatchResult { + Ok(()) + } } parameter_types! { diff --git a/pallets/slp/src/tests/kusama_tests.rs b/pallets/slp/src/tests/kusama_tests.rs index 2defb4f2f..ead045798 100644 --- a/pallets/slp/src/tests/kusama_tests.rs +++ b/pallets/slp/src/tests/kusama_tests.rs @@ -603,71 +603,61 @@ fn register_subaccount_index_0() { )); // Register Operation weight and fee - assert_ok!(Slp::set_xcm_dest_weight_and_fee( - RuntimeOrigin::signed(ALICE), + assert_ok!(::XcmWeightAndFeeHandler::set_xcm_dest_weight_and_fee( DOT, XcmOperation::TransferTo, Some((20_000_000_000.into(), 10_000_000_000)), )); - assert_ok!(Slp::set_xcm_dest_weight_and_fee( - RuntimeOrigin::signed(ALICE), + assert_ok!(::XcmWeightAndFeeHandler::set_xcm_dest_weight_and_fee( DOT, XcmOperation::Bond, Some((20_000_000_000.into(), 10_000_000_000)), )); - assert_ok!(Slp::set_xcm_dest_weight_and_fee( - RuntimeOrigin::signed(ALICE), + assert_ok!(::XcmWeightAndFeeHandler::set_xcm_dest_weight_and_fee( DOT, XcmOperation::BondExtra, Some((20_000_000_000.into(), 10_000_000_000)), )); - assert_ok!(Slp::set_xcm_dest_weight_and_fee( - RuntimeOrigin::signed(ALICE), + assert_ok!(::XcmWeightAndFeeHandler::set_xcm_dest_weight_and_fee( DOT, XcmOperation::Unbond, Some((20_000_000_000.into(), 10_000_000_000)), )); - assert_ok!(Slp::set_xcm_dest_weight_and_fee( - RuntimeOrigin::signed(ALICE), + assert_ok!(::XcmWeightAndFeeHandler::set_xcm_dest_weight_and_fee( DOT, XcmOperation::Rebond, Some((20_000_000_000.into(), 10_000_000_000)), )); - assert_ok!(Slp::set_xcm_dest_weight_and_fee( - RuntimeOrigin::signed(ALICE), + assert_ok!(::XcmWeightAndFeeHandler::set_xcm_dest_weight_and_fee( DOT, XcmOperation::Delegate, Some((20_000_000_000.into(), 10_000_000_000)), )); - assert_ok!(Slp::set_xcm_dest_weight_and_fee( - RuntimeOrigin::signed(ALICE), + assert_ok!(::XcmWeightAndFeeHandler::set_xcm_dest_weight_and_fee( DOT, XcmOperation::Payout, Some((20_000_000_000.into(), 10_000_000_000)), )); - assert_ok!(Slp::set_xcm_dest_weight_and_fee( - RuntimeOrigin::signed(ALICE), + assert_ok!(::XcmWeightAndFeeHandler::set_xcm_dest_weight_and_fee( DOT, XcmOperation::Liquidize, Some((20_000_000_000.into(), 10_000_000_000)), )); - assert_ok!(Slp::set_xcm_dest_weight_and_fee( - RuntimeOrigin::signed(ALICE), + assert_ok!(::XcmWeightAndFeeHandler::set_xcm_dest_weight_and_fee( DOT, XcmOperation::Chill, Some((20_000_000_000.into(), 10_000_000_000)), )); - assert_ok!(Slp::set_xcm_dest_weight_and_fee( - RuntimeOrigin::signed(ALICE), + assert_ok!(::XcmWeightAndFeeHandler::set_xcm_dest_weight_and_fee( DOT, XcmOperation::TransferBack, Some((20_000_000_000.into(), 10_000_000_000)), diff --git a/pallets/slp/src/tests/moonriver_tests.rs b/pallets/slp/src/tests/moonriver_tests.rs index 04c3d3b57..feea5daea 100644 --- a/pallets/slp/src/tests/moonriver_tests.rs +++ b/pallets/slp/src/tests/moonriver_tests.rs @@ -188,85 +188,73 @@ fn moonriver_setup() { Some((treasury_location, 1_000_000_000_000)), )); - assert_ok!(Slp::set_xcm_dest_weight_and_fee( - RuntimeOrigin::signed(ALICE), + assert_ok!(::XcmWeightAndFeeHandler::set_xcm_dest_weight_and_fee( MOVR, XcmOperation::Bond, Some((20_000_000_000.into(), 10_000_000_000)), )); - assert_ok!(Slp::set_xcm_dest_weight_and_fee( - RuntimeOrigin::signed(ALICE), + assert_ok!(::XcmWeightAndFeeHandler::set_xcm_dest_weight_and_fee( MOVR, XcmOperation::BondExtra, Some((20_000_000_000.into(), 10_000_000_000)), )); - assert_ok!(Slp::set_xcm_dest_weight_and_fee( - RuntimeOrigin::signed(ALICE), + assert_ok!(::XcmWeightAndFeeHandler::set_xcm_dest_weight_and_fee( MOVR, XcmOperation::Unbond, Some((20_000_000_000.into(), 10_000_000_000)), )); - assert_ok!(Slp::set_xcm_dest_weight_and_fee( - RuntimeOrigin::signed(ALICE), + assert_ok!(::XcmWeightAndFeeHandler::set_xcm_dest_weight_and_fee( MOVR, XcmOperation::Chill, Some((20_000_000_000.into(), 10_000_000_000)), )); - assert_ok!(Slp::set_xcm_dest_weight_and_fee( - RuntimeOrigin::signed(ALICE), + assert_ok!(::XcmWeightAndFeeHandler::set_xcm_dest_weight_and_fee( MOVR, XcmOperation::Rebond, Some((20_000_000_000.into(), 10_000_000_000)), )); - assert_ok!(Slp::set_xcm_dest_weight_and_fee( - RuntimeOrigin::signed(ALICE), + assert_ok!(::XcmWeightAndFeeHandler::set_xcm_dest_weight_and_fee( MOVR, XcmOperation::Undelegate, Some((20_000_000_000.into(), 10_000_000_000)), )); - assert_ok!(Slp::set_xcm_dest_weight_and_fee( - RuntimeOrigin::signed(ALICE), + assert_ok!(::XcmWeightAndFeeHandler::set_xcm_dest_weight_and_fee( MOVR, XcmOperation::CancelLeave, Some((20_000_000_000.into(), 10_000_000_000)), )); - assert_ok!(Slp::set_xcm_dest_weight_and_fee( - RuntimeOrigin::signed(ALICE), + assert_ok!(::XcmWeightAndFeeHandler::set_xcm_dest_weight_and_fee( MOVR, XcmOperation::Liquidize, Some((20_000_000_000.into(), 10_000_000_000)), )); - assert_ok!(Slp::set_xcm_dest_weight_and_fee( - RuntimeOrigin::signed(ALICE), + assert_ok!(::XcmWeightAndFeeHandler::set_xcm_dest_weight_and_fee( MOVR, XcmOperation::ExecuteLeave, Some((20_000_000_000.into(), 10_000_000_000)), )); - assert_ok!(Slp::set_xcm_dest_weight_and_fee( - RuntimeOrigin::signed(ALICE), + assert_ok!(::XcmWeightAndFeeHandler::set_xcm_dest_weight_and_fee( MOVR, XcmOperation::TransferBack, Some((20_000_000_000.into(), 10_000_000_000)), )); - assert_ok!(Slp::set_xcm_dest_weight_and_fee( - RuntimeOrigin::signed(ALICE), + assert_ok!(::XcmWeightAndFeeHandler::set_xcm_dest_weight_and_fee( MOVR, XcmOperation::XtokensTransferBack, Some((20_000_000_000.into(), 10_000_000_000)), )); - assert_ok!(Slp::set_xcm_dest_weight_and_fee( - RuntimeOrigin::signed(ALICE), + assert_ok!(::XcmWeightAndFeeHandler::set_xcm_dest_weight_and_fee( MOVR, XcmOperation::TransferTo, Some((20_000_000_000.into(), 10_000_000_000)), diff --git a/pallets/slp/src/tests/parachain_staking_tests.rs b/pallets/slp/src/tests/parachain_staking_tests.rs index 48805e886..2073577b4 100644 --- a/pallets/slp/src/tests/parachain_staking_tests.rs +++ b/pallets/slp/src/tests/parachain_staking_tests.rs @@ -135,90 +135,6 @@ fn parachain_staking_setup() { Some((treasury_location, 1_000_000_000_000)), )); - // assert_ok!(Slp::set_xcm_dest_weight_and_fee( - // RuntimeOrigin::signed(ALICE), - // BNC, - // XcmOperation::Bond, - // Some((20_000_000_000, 10_000_000_000)), - // )); - - // assert_ok!(Slp::set_xcm_dest_weight_and_fee( - // RuntimeOrigin::signed(ALICE), - // BNC, - // XcmOperation::BondExtra, - // Some((20_000_000_000, 10_000_000_000)), - // )); - - // assert_ok!(Slp::set_xcm_dest_weight_and_fee( - // RuntimeOrigin::signed(ALICE), - // BNC, - // XcmOperation::Unbond, - // Some((20_000_000_000, 10_000_000_000)), - // )); - - // assert_ok!(Slp::set_xcm_dest_weight_and_fee( - // RuntimeOrigin::signed(ALICE), - // BNC, - // XcmOperation::Chill, - // Some((20_000_000_000, 10_000_000_000)), - // )); - - // assert_ok!(Slp::set_xcm_dest_weight_and_fee( - // RuntimeOrigin::signed(ALICE), - // BNC, - // XcmOperation::Rebond, - // Some((20_000_000_000, 10_000_000_000)), - // )); - - // assert_ok!(Slp::set_xcm_dest_weight_and_fee( - // RuntimeOrigin::signed(ALICE), - // BNC, - // XcmOperation::Undelegate, - // Some((20_000_000_000, 10_000_000_000)), - // )); - - // assert_ok!(Slp::set_xcm_dest_weight_and_fee( - // RuntimeOrigin::signed(ALICE), - // BNC, - // XcmOperation::CancelLeave, - // Some((20_000_000_000, 10_000_000_000)), - // )); - - // assert_ok!(Slp::set_xcm_dest_weight_and_fee( - // RuntimeOrigin::signed(ALICE), - // BNC, - // XcmOperation::Liquidize, - // Some((20_000_000_000, 10_000_000_000)), - // )); - - // assert_ok!(Slp::set_xcm_dest_weight_and_fee( - // RuntimeOrigin::signed(ALICE), - // BNC, - // XcmOperation::ExecuteLeave, - // Some((20_000_000_000, 10_000_000_000)), - // )); - - // assert_ok!(Slp::set_xcm_dest_weight_and_fee( - // RuntimeOrigin::signed(ALICE), - // BNC, - // XcmOperation::TransferBack, - // Some((20_000_000_000, 10_000_000_000)), - // )); - - // assert_ok!(Slp::set_xcm_dest_weight_and_fee( - // RuntimeOrigin::signed(ALICE), - // BNC, - // XcmOperation::XtokensTransferBack, - // Some((20_000_000_000, 10_000_000_000)), - // )); - - // assert_ok!(Slp::set_xcm_dest_weight_and_fee( - // RuntimeOrigin::signed(ALICE), - // BNC, - // XcmOperation::TransferTo, - // Some((20_000_000_000, 10_000_000_000)), - // )); - // Set delegator ledger assert_ok!(Slp::add_validator( RuntimeOrigin::signed(ALICE), diff --git a/pallets/slp/src/tests/phala_tests.rs b/pallets/slp/src/tests/phala_tests.rs index c4de19d81..807cebdc7 100644 --- a/pallets/slp/src/tests/phala_tests.rs +++ b/pallets/slp/src/tests/phala_tests.rs @@ -329,36 +329,31 @@ fn phala_xcm_setup() { Some((treasury_location, 1_000_000_000_000)), )); - assert_ok!(Slp::set_xcm_dest_weight_and_fee( - RuntimeOrigin::signed(ALICE), + assert_ok!(::XcmWeightAndFeeHandler::set_xcm_dest_weight_and_fee( PHA, XcmOperation::Bond, Some((20_000_000_000.into(), 10_000_000_000)), )); - assert_ok!(Slp::set_xcm_dest_weight_and_fee( - RuntimeOrigin::signed(ALICE), + assert_ok!(::XcmWeightAndFeeHandler::set_xcm_dest_weight_and_fee( PHA, XcmOperation::Unbond, Some((20_000_000_000.into(), 10_000_000_000)), )); - assert_ok!(Slp::set_xcm_dest_weight_and_fee( - RuntimeOrigin::signed(ALICE), + assert_ok!(::XcmWeightAndFeeHandler::set_xcm_dest_weight_and_fee( PHA, XcmOperation::TransferBack, Some((20_000_000_000.into(), 10_000_000_000)), )); - assert_ok!(Slp::set_xcm_dest_weight_and_fee( - RuntimeOrigin::signed(ALICE), + assert_ok!(::XcmWeightAndFeeHandler::set_xcm_dest_weight_and_fee( PHA, XcmOperation::TransferTo, Some((20_000_000_000.into(), 10_000_000_000)), )); - assert_ok!(Slp::set_xcm_dest_weight_and_fee( - RuntimeOrigin::signed(ALICE), + assert_ok!(::XcmWeightAndFeeHandler::set_xcm_dest_weight_and_fee( PHA, XcmOperation::ConvertAsset, Some((20_000_000_000.into(), 10_000_000_000)), diff --git a/pallets/vtoken-voting/src/benchmarking.rs b/pallets/vtoken-voting/src/benchmarking.rs index 2aecac291..68e4dae5f 100644 --- a/pallets/vtoken-voting/src/benchmarking.rs +++ b/pallets/vtoken-voting/src/benchmarking.rs @@ -43,7 +43,7 @@ fn init_vote(vtoken: CurrencyIdOf) -> Result<(), BenchmarkError> { let token = CurrencyId::to_token(&vtoken).unwrap(); T::XcmDestWeightAndFee::set_xcm_dest_weight_and_fee( token, - XcmOperation::VoteVtoken, + XcmOperation::Vote, Some((Weight::from_parts(4000000000, 100000), 4000000000u32.into())), )?; T::DerivativeAccount::init_minimums_and_maximums(token); @@ -189,7 +189,7 @@ mod benchmarks { let token = CurrencyId::to_token(&vtoken).unwrap(); T::XcmDestWeightAndFee::set_xcm_dest_weight_and_fee( token, - XcmOperation::VoteRemoveDelegatorVote, + XcmOperation::RemoveVote, Some((Weight::from_parts(4000000000, 100000), 4000000000u32.into())), )?; diff --git a/pallets/vtoken-voting/src/lib.rs b/pallets/vtoken-voting/src/lib.rs index 1cd449e21..f0fe7b252 100644 --- a/pallets/vtoken-voting/src/lib.rs +++ b/pallets/vtoken-voting/src/lib.rs @@ -410,7 +410,7 @@ pub mod pallet { let notify_call = Call::::notify_vote { query_id: 0, response: Default::default() }; let (weight, extra_fee) = T::XcmDestWeightAndFee::get_operation_weight_and_fee( CurrencyId::to_token(&vtoken).map_err(|_| Error::::NoData)?, - XcmInterfaceOperation::VoteVtoken, + XcmInterfaceOperation::Vote, ) .ok_or(Error::::NoData)?; Self::send_xcm_with_notify( @@ -480,7 +480,7 @@ pub mod pallet { as ConvictionVotingCall>::remove_vote(None, poll_index); let (weight, extra_fee) = T::XcmDestWeightAndFee::get_operation_weight_and_fee( CurrencyId::to_token(&vtoken).map_err(|_| Error::::NoData)?, - XcmInterfaceOperation::VoteRemoveDelegatorVote, + XcmInterfaceOperation::RemoveVote, ) .ok_or(Error::::NoData)?; Self::send_xcm_with_notify(