From b1cca59932579d9f06570040c83943f49f150ee7 Mon Sep 17 00:00:00 2001 From: Edwin Wang Date: Wed, 10 Jan 2024 18:40:25 +0800 Subject: [PATCH 1/8] Bifrost v0.9.92 --- Cargo.lock | 2 +- node/cli/Cargo.toml | 2 +- runtime/bifrost-kusama/src/lib.rs | 2 +- runtime/bifrost-polkadot/src/lib.rs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 12dafafbe..823af14f6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -917,7 +917,7 @@ dependencies = [ [[package]] name = "bifrost-cli" -version = "0.9.90" +version = "0.9.92" dependencies = [ "bifrost-primitives", "bifrost-service", diff --git a/node/cli/Cargo.toml b/node/cli/Cargo.toml index e2f9192e3..1ae1c3033 100644 --- a/node/cli/Cargo.toml +++ b/node/cli/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "bifrost-cli" -version = "0.9.90" +version = "0.9.92" 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 457f9836d..9e55a6556 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: 990, + spec_version: 992, 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 dc8b8b343..40a9ca5f7 100644 --- a/runtime/bifrost-polkadot/src/lib.rs +++ b/runtime/bifrost-polkadot/src/lib.rs @@ -132,7 +132,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: 990, + spec_version: 992, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 1, From 4e604b11084ae57fe66d2d9e433e48e357ef4db4 Mon Sep 17 00:00:00 2001 From: yooml Date: Sun, 14 Jan 2024 20:44:23 +0800 Subject: [PATCH 2/8] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20prod=5For=5Ffast=20(?= =?UTF-8?q?#1144)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 🎸 prod_or_fast * fix: 🐛 default-features --- Cargo.lock | 2 ++ Cargo.toml | 1 + runtime/bifrost-kusama/Cargo.toml | 1 + runtime/bifrost-kusama/src/lib.rs | 17 +++++++++-------- runtime/bifrost-polkadot/Cargo.toml | 1 + runtime/bifrost-polkadot/src/lib.rs | 7 ++++--- runtime/common/src/lib.rs | 18 ------------------ 7 files changed, 18 insertions(+), 29 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 823af14f6..938014972 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1259,6 +1259,7 @@ dependencies = [ "parity-scale-codec", "polkadot-parachain-primitives", "polkadot-primitives", + "polkadot-runtime-common", "scale-info", "smallvec", "sp-api", @@ -1427,6 +1428,7 @@ dependencies = [ "parity-scale-codec", "polkadot-parachain-primitives", "polkadot-primitives", + "polkadot-runtime-common", "scale-info", "smallvec", "sp-api", diff --git a/Cargo.toml b/Cargo.toml index 418f5a419..ea27da7c4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -228,6 +228,7 @@ kusama-runtime = { package = "staging-kusama-runtime", git = "https kusama-runtime-constants = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.1.0" } polkadot-cli = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.1.0" } polkadot-runtime = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.1.0" } +polkadot-runtime-common = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.1.0", default-features = false } polkadot-runtime-constants = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.1.0" } polkadot-runtime-parachains = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.1.0" } polkadot-service = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.1.0" } diff --git a/runtime/bifrost-kusama/Cargo.toml b/runtime/bifrost-kusama/Cargo.toml index 8340f6e9e..12291eb84 100644 --- a/runtime/bifrost-kusama/Cargo.toml +++ b/runtime/bifrost-kusama/Cargo.toml @@ -80,6 +80,7 @@ parachain-info = { workspace = true } pallet-xcm = { workspace = true } polkadot-parachain-primitives = { workspace = true } polkadot-primitives = { workspace = true } +polkadot-runtime-common = { workspace = true } xcm = { workspace = true } xcm-builder = { workspace = true } xcm-executor = { workspace = true } diff --git a/runtime/bifrost-kusama/src/lib.rs b/runtime/bifrost-kusama/src/lib.rs index 8db5649ff..4b43d5ed2 100644 --- a/runtime/bifrost-kusama/src/lib.rs +++ b/runtime/bifrost-kusama/src/lib.rs @@ -79,9 +79,9 @@ pub use bifrost_primitives::{ Ratio, RpcContributionStatus, Shortfall, TimeUnit, TokenSymbol, }; pub use bifrost_runtime_common::{ - cent, constants::time::*, dollar, micro, milli, millicent, prod_or_test, AuraId, - CouncilCollective, EnsureRootOrAllTechnicalCommittee, MoreThanHalfCouncil, - SlowAdjustingFeeUpdate, TechnicalCollective, + cent, constants::time::*, dollar, micro, milli, millicent, AuraId, CouncilCollective, + EnsureRootOrAllTechnicalCommittee, MoreThanHalfCouncil, SlowAdjustingFeeUpdate, + TechnicalCollective, }; use bifrost_slp::QueryId; use constants::currency::*; @@ -95,6 +95,7 @@ use frame_system::{EnsureRoot, EnsureRootWithSuccess, EnsureSigned}; use hex_literal::hex; use orml_oracle::{DataFeeder, DataProvider, DataProviderExtended}; use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; +use polkadot_runtime_common::prod_or_fast; // zenlink imports use zenlink_protocol::{ @@ -976,7 +977,7 @@ parameter_types! { /// Minimum round length is 2 minutes (10 * 12 second block times) pub const MinBlocksPerRound: u32 = 10; /// Blocks per round - pub const DefaultBlocksPerRound: u32 = prod_or_test!(2 * HOURS, 10); + pub const DefaultBlocksPerRound: u32 = prod_or_fast!(2 * HOURS, 10); /// Rounds before the collator leaving the candidates request can be executed pub const LeaveCandidatesDelay: u32 = 84; /// Rounds before the candidate bond increase/decrease can be executed @@ -990,7 +991,7 @@ parameter_types! { /// Rounds before the reward is paid pub const RewardPaymentDelay: u32 = 2; /// Minimum collators selected per round, default at genesis and minimum forever after - pub const MinSelectedCandidates: u32 = prod_or_test!(16,6); + pub const MinSelectedCandidates: u32 = prod_or_fast!(16,6); /// Maximum top delegations per candidate pub const MaxTopDelegationsPerCandidate: u32 = 300; /// Maximum bottom delegations per candidate @@ -1008,7 +1009,7 @@ parameter_types! { /// Minimum stake required to be reserved to be a delegator pub MinDelegatorStk: u128 = 50 * BNCS; pub AllowInflation: bool = false; - pub ToMigrateInvulnables: Vec = prod_or_test!(vec![ + pub ToMigrateInvulnables: Vec = prod_or_fast!(vec![ hex!["8cf80f0bafcd0a3d80ca61cb688e4400e275b39d3411b4299b47e712e9dab809"].into(), hex!["40ac4effe39181731a8feb8a8ee0780e177bdd0d752b09c8fd71047e67189022"].into(), hex!["624d6a004c72a1abcf93131e185515ebe1410e43a301fe1f25d20d8da345376e"].into(), @@ -1426,7 +1427,7 @@ impl bifrost_farming::Config for Runtime { } parameter_types! { - pub const BlocksPerRound: u32 = prod_or_test!(1500, 50); + pub const BlocksPerRound: u32 = prod_or_fast!(1500, 50); pub const MaxTokenLen: u32 = 500; pub const MaxFarmingPoolIdLen: u32 = 100; } @@ -1786,7 +1787,7 @@ impl leverage_staking::Config for Runtime { } parameter_types! { - pub const ClearingDuration: u32 = 7 * DAYS; + pub const ClearingDuration: u32 = prod_or_fast!(7 * DAYS, 10 * MINUTES); pub const NameLengthLimit: u32 = 20; pub BifrostCommissionReceiver: AccountId = TreasuryPalletId::get().into_account_truncating(); } diff --git a/runtime/bifrost-polkadot/Cargo.toml b/runtime/bifrost-polkadot/Cargo.toml index 680f70952..18f2c4b17 100644 --- a/runtime/bifrost-polkadot/Cargo.toml +++ b/runtime/bifrost-polkadot/Cargo.toml @@ -80,6 +80,7 @@ parachain-info = { workspace = true } pallet-xcm = { workspace = true } polkadot-parachain-primitives = { workspace = true } polkadot-primitives = { workspace = true } +polkadot-runtime-common = { workspace = true } xcm = { workspace = true } xcm-builder = { workspace = true } xcm-executor = { workspace = true } diff --git a/runtime/bifrost-polkadot/src/lib.rs b/runtime/bifrost-polkadot/src/lib.rs index b5695627f..43d430a0c 100644 --- a/runtime/bifrost-polkadot/src/lib.rs +++ b/runtime/bifrost-polkadot/src/lib.rs @@ -78,7 +78,7 @@ pub use bifrost_primitives::{ GLMR_TOKEN_ID, }; use bifrost_runtime_common::{ - constants::time::*, dollar, micro, milli, prod_or_test, AuraId, CouncilCollective, + constants::time::*, dollar, micro, milli, AuraId, CouncilCollective, EnsureRootOrAllTechnicalCommittee, MoreThanHalfCouncil, SlowAdjustingFeeUpdate, TechnicalCollective, }; @@ -103,6 +103,7 @@ use zenlink_protocol::{ pub mod xcm_config; use orml_traits::{currency::MutationHooks, location::RelativeReserveProvider}; use pallet_xcm::{EnsureResponse, QueryStatus}; +use polkadot_runtime_common::prod_or_fast; use static_assertions::const_assert; use xcm::v3::prelude::*; use xcm_config::{ @@ -1258,7 +1259,7 @@ impl bifrost_farming::Config for Runtime { } parameter_types! { - pub const BlocksPerRound: u32 = prod_or_test!(1500, 50); + pub const BlocksPerRound: u32 = prod_or_fast!(1500, 50); pub const MaxTokenLen: u32 = 500; pub const MaxFarmingPoolIdLen: u32 = 100; } @@ -1594,7 +1595,7 @@ impl leverage_staking::Config for Runtime { } parameter_types! { - pub const ClearingDuration: u32 = 7 * DAYS; + pub const ClearingDuration: u32 = prod_or_fast!(7 * DAYS, 10 * MINUTES); pub const NameLengthLimit: u32 = 20; pub BifrostCommissionReceiver: AccountId = TreasuryPalletId::get().into_account_truncating(); } diff --git a/runtime/common/src/lib.rs b/runtime/common/src/lib.rs index 3f4b184e2..3d5ed2397 100644 --- a/runtime/common/src/lib.rs +++ b/runtime/common/src/lib.rs @@ -132,21 +132,3 @@ impl BlockNumberProvider .unwrap_or_default() } } - -#[macro_export] -macro_rules! prod_or_test { - ($prod:expr, $test:expr) => { - if cfg!(feature = "fast-runtime") { - $test - } else { - $prod - } - }; - ($prod:expr, $test:expr, $env:expr) => { - if cfg!(feature = "fast-runtime") { - core::option_env!($env).map(|s| s.parse().ok()).flatten().unwrap_or($test) - } else { - $prod - } - }; -} From 2803aaaf72e06b82f6299b3a09354befa8d0e8d6 Mon Sep 17 00:00:00 2001 From: Edwin Date: Sun, 14 Jan 2024 20:28:00 -0600 Subject: [PATCH 3/8] Fix DelegatorVotes removal (#1147) * Fix DelegatorVotes removal * Fix --- pallets/vtoken-voting/src/lib.rs | 4 +- pallets/vtoken-voting/src/mock.rs | 19 ++- pallets/vtoken-voting/src/tests.rs | 183 +++++++++++++++++++++++++++-- 3 files changed, 189 insertions(+), 17 deletions(-) diff --git a/pallets/vtoken-voting/src/lib.rs b/pallets/vtoken-voting/src/lib.rs index 2da8c53a2..b515e5bae 100644 --- a/pallets/vtoken-voting/src/lib.rs +++ b/pallets/vtoken-voting/src/lib.rs @@ -721,7 +721,7 @@ pub mod pallet { if !VoteDelegatorFor::::contains_key((&who, vtoken, poll_index)) { VoteDelegatorFor::::insert((&who, vtoken, poll_index), derivative_index); } - let _ = DelegatorVotes::::clear(u32::MAX, None); + DelegatorVotes::::remove(vtoken, poll_index); DelegatorVotes::::try_mutate( vtoken, poll_index, @@ -796,7 +796,7 @@ pub mod pallet { { let success = Response::DispatchResult(MaybeErrorCode::Success) == response; if success { - let _ = DelegatorVotes::::clear(u32::MAX, None); + DelegatorVotes::::remove(vtoken, poll_index); } PendingRemoveDelegatorVote::::remove(query_id); Self::deposit_event(Event::::DelegatorVoteRemovedNotified { diff --git a/pallets/vtoken-voting/src/mock.rs b/pallets/vtoken-voting/src/mock.rs index d924363f3..9d0106b7e 100644 --- a/pallets/vtoken-voting/src/mock.rs +++ b/pallets/vtoken-voting/src/mock.rs @@ -308,15 +308,30 @@ impl BlockNumberProvider for RelaychainDataProvider { } } +parameter_types! { + pub static VTokenSupply: Balance = u64::MAX.into(); + pub static TokenSupply: Balance = u64::MAX.into(); +} + pub struct SimpleVTokenSupplyProvider; +impl SimpleVTokenSupplyProvider { + pub fn set_vtoken_supply(supply: Balance) { + VTokenSupply::set(supply); + } + + pub fn set_token_supply(supply: Balance) { + TokenSupply::set(supply); + } +} + impl VTokenSupplyProvider for SimpleVTokenSupplyProvider { fn get_vtoken_supply(_: CurrencyId) -> Option { - Some(u64::MAX.into()) + Some(VTokenSupply::get()) } fn get_token_supply(_: CurrencyId) -> Option { - Some(u64::MAX.into()) + Some(TokenSupply::get()) } } diff --git a/pallets/vtoken-voting/src/tests.rs b/pallets/vtoken-voting/src/tests.rs index 1d70ea26d..789f38e34 100644 --- a/pallets/vtoken-voting/src/tests.rs +++ b/pallets/vtoken-voting/src/tests.rs @@ -1046,6 +1046,115 @@ fn compute_delegator_total_vote_works() { assert_eq!(VtokenVoting::compute_delegator_total_vote(vtoken, nay(2, 4)), Ok(nay(80, 0))); assert_eq!(VtokenVoting::compute_delegator_total_vote(vtoken, nay(2, 5)), Ok(nay(100, 0))); assert_eq!(VtokenVoting::compute_delegator_total_vote(vtoken, nay(2, 6)), Ok(nay(120, 0))); + + SimpleVTokenSupplyProvider::set_token_supply(10_000_000); + assert_eq!(VtokenVoting::vote_cap(vtoken), Ok(1_000_000)); + assert_eq!( + VtokenVoting::compute_delegator_total_vote(vtoken, aye(1_000_000, 0)), + Ok(aye(1_000_000, 0)) + ); + for i in 1..=6_u8 { + assert_eq!( + VtokenVoting::compute_delegator_total_vote( + vtoken, + aye(10_000_000 * i as Balance, 0) + ), + Ok(aye(1_000_000, i)) + ); + } + + assert_eq!( + VtokenVoting::compute_delegator_total_vote(vtoken, aye(100_000, 1)), + Ok(aye(1_000_000, 0)) + ); + for i in 1..=6_u8 { + assert_eq!( + VtokenVoting::compute_delegator_total_vote( + vtoken, + aye(1_000_000 * i as Balance, 1) + ), + Ok(aye(1_000_000, i)) + ); + } + assert_noop!( + VtokenVoting::compute_delegator_total_vote(vtoken, aye(6_000_006, 1)), + Error::::InsufficientFunds + ); + + assert_eq!( + VtokenVoting::compute_delegator_total_vote(vtoken, aye(50_000, 2)), + Ok(aye(1_000_000, 0)) + ); + for i in 1..=6_u8 { + assert_eq!( + VtokenVoting::compute_delegator_total_vote(vtoken, aye(500_000 * i as Balance, 2)), + Ok(aye(1_000_000, i)) + ); + } + assert_noop!( + VtokenVoting::compute_delegator_total_vote(vtoken, aye(3_000_003, 2)), + Error::::InsufficientFunds + ); + + assert_eq!( + VtokenVoting::compute_delegator_total_vote(vtoken, aye(33_333, 3)), + Ok(aye(999_990, 0)) + ); + for i in 1..=6_u8 { + assert_eq!( + VtokenVoting::compute_delegator_total_vote(vtoken, aye(333_333 * i as Balance, 3)), + Ok(aye(999_999, i)) + ); + } + assert_noop!( + VtokenVoting::compute_delegator_total_vote(vtoken, aye(2_000_002, 3)), + Error::::InsufficientFunds + ); + + assert_eq!( + VtokenVoting::compute_delegator_total_vote(vtoken, aye(25_000, 4)), + Ok(aye(1_000_000, 0)) + ); + for i in 1..=6_u8 { + assert_eq!( + VtokenVoting::compute_delegator_total_vote(vtoken, aye(250_000 * i as Balance, 4)), + Ok(aye(1_000_000, i)) + ); + } + assert_noop!( + VtokenVoting::compute_delegator_total_vote(vtoken, aye(1_500_002, 4)), + Error::::InsufficientFunds + ); + + assert_eq!( + VtokenVoting::compute_delegator_total_vote(vtoken, aye(20_000, 5)), + Ok(aye(1_000_000, 0)) + ); + for i in 1..=6_u8 { + assert_eq!( + VtokenVoting::compute_delegator_total_vote(vtoken, aye(200_000 * i as Balance, 5)), + Ok(aye(1_000_000, i)) + ); + } + assert_noop!( + VtokenVoting::compute_delegator_total_vote(vtoken, aye(1_200_002, 5)), + Error::::InsufficientFunds + ); + + assert_eq!( + VtokenVoting::compute_delegator_total_vote(vtoken, aye(16_666, 6)), + Ok(aye(999_960, 0)) + ); + for i in 1..=6_u8 { + assert_eq!( + VtokenVoting::compute_delegator_total_vote(vtoken, aye(166_666 * i as Balance, 6)), + Ok(aye(999_996, i)) + ); + } + assert_noop!( + VtokenVoting::compute_delegator_total_vote(vtoken, aye(1_000_001, 6)), + Error::::InsufficientFunds + ); }); } @@ -1063,19 +1172,67 @@ fn allocate_delegator_votes_works() { new_test_ext().execute_with(|| { let vtoken = VKSM; let poll_index = 3; - let vote = aye(5e9 as Balance, 2); - let delegator_votes = VtokenVoting::allocate_delegator_votes(vtoken, poll_index, vote); - assert_eq!(delegator_votes, Ok(vec![(0, aye(4294967295, 2)), (1, aye(705032705, 2))])); - assert_eq!( - delegator_votes.unwrap().into_iter().map(|(_derivative_index, vote)| vote).fold( - aye(0, 2), - |mut acc, vote| { - let _ = acc.checked_add(vote); - acc - }, - ), - vote - ); + for conviction in 0..=6 { + let vote = aye(5e9 as Balance, conviction); + let delegator_votes = VtokenVoting::allocate_delegator_votes(vtoken, poll_index, vote); + assert_eq!( + delegator_votes, + Ok(vec![(0, aye(4294967295, conviction)), (1, aye(705032705, conviction))]) + ); + assert_eq!( + delegator_votes.unwrap().into_iter().map(|(_derivative_index, vote)| vote).fold( + aye(0, conviction), + |mut acc, vote| { + let _ = acc.checked_add(vote); + acc + }, + ), + vote + ); + } + + for conviction in 0..=6 { + let vote = aye(3e10 as Balance, conviction); + let delegator_votes = VtokenVoting::allocate_delegator_votes(vtoken, poll_index, vote); + assert_eq!( + delegator_votes, + Ok(vec![ + (0, aye(4294967295, conviction)), + (1, aye(4294967295, conviction)), + (2, aye(4294967295, conviction)), + (3, aye(4294967295, conviction)), + (4, aye(4294967295, conviction)), + (5, aye(4294967295, conviction)), + (10, aye(4230196230, conviction)) + ]) + ); + assert_eq!( + delegator_votes.unwrap().into_iter().map(|(_derivative_index, vote)| vote).fold( + aye(0, conviction), + |mut acc, vote| { + let _ = acc.checked_add(vote); + acc + }, + ), + vote + ); + } }); } + +#[test] +fn tally_convert_works() { + assert_eq!( + TallyOf::::from_parts(10, 9, 0).account_vote(Conviction::Locked1x), + aye(1, 1) + ); + assert_eq!( + TallyOf::::from_parts(10, 11, 0).account_vote(Conviction::Locked1x), + nay(1, 1) + ); + assert_eq!( + TallyOf::::from_parts(10, 10, 0).account_vote(Conviction::Locked1x), + aye(0, 1) + ); +} From 062fd8683031aa9a14f4b439e39b6790c070da33 Mon Sep 17 00:00:00 2001 From: herryho Date: Wed, 17 Jan 2024 00:28:40 +0800 Subject: [PATCH 4/8] fix-vtoken-channel-shares-creation --- pallets/channel-commission/src/lib.rs | 3 +++ pallets/channel-commission/src/tests.rs | 23 +++++++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/pallets/channel-commission/src/lib.rs b/pallets/channel-commission/src/lib.rs index 08b120469..054d55692 100644 --- a/pallets/channel-commission/src/lib.rs +++ b/pallets/channel-commission/src/lib.rs @@ -332,6 +332,9 @@ pub mod pallet { vtoken, DEFAULT_COMMISSION_RATE, ); + + // for each vtoken, add the 0 share to ChannelVtokenShares storage + ChannelVtokenShares::::insert(channel_id, vtoken, Permill::zero()); }); Self::deposit_event(Event::ChannelRegistered { diff --git a/pallets/channel-commission/src/tests.rs b/pallets/channel-commission/src/tests.rs index 4b1bc3304..5fd889bf3 100644 --- a/pallets/channel-commission/src/tests.rs +++ b/pallets/channel-commission/src/tests.rs @@ -69,6 +69,20 @@ fn set_commission_tokens_should_work() { #[test] fn register_channel_should_work() { ExtBuilder::default().one_hundred_for_alice_n_bob().build().execute_with(|| { + // set commission tokens: VKSM -> KSM + assert_ok!(ChannelCommission::set_commission_tokens( + RuntimeOrigin::signed(ALICE), + VKSM, + KSM, + )); + + // set commission tokens: VBNC -> BNC + assert_ok!(ChannelCommission::set_commission_tokens( + RuntimeOrigin::signed(ALICE), + VBNC, + BNC, + )); + assert_ok!(ChannelCommission::register_channel( RuntimeOrigin::signed(ALICE), CHANNEL_A_NAME.to_vec(), @@ -83,6 +97,15 @@ fn register_channel_should_work() { // next channel id has been increased assert_eq!(ChannelNextId::::get(), 1); + + // ChannelCommissionTokenRates have been set for Channel A in both VKSM and VBNC + assert_eq!(ChannelCommissionTokenRates::::get(0, VKSM), DEFAULT_COMMISSION_RATE); + assert_eq!(ChannelCommissionTokenRates::::get(0, VBNC), DEFAULT_COMMISSION_RATE); + + // ChannelVtokenShares has been initialized for Channel A in both VKSM and VBNC + assert_eq!(ChannelVtokenShares::::get(0, VKSM), Permill::from_percent(0)); + + assert_eq!(ChannelVtokenShares::::get(0, VBNC), Permill::from_percent(0)); }); } From df7fa050cf4d71b5ad4fa9daaf107d8570392609 Mon Sep 17 00:00:00 2001 From: herryho Date: Thu, 18 Jan 2024 16:56:18 +0800 Subject: [PATCH 5/8] fixes --- .../channel-commission/src/benchmarking.rs | 17 +++ pallets/channel-commission/src/lib.rs | 59 ++++++++++ pallets/channel-commission/src/tests.rs | 102 +++++++++++++++++- pallets/channel-commission/src/weights.rs | 11 ++ 4 files changed, 188 insertions(+), 1 deletion(-) diff --git a/pallets/channel-commission/src/benchmarking.rs b/pallets/channel-commission/src/benchmarking.rs index 329b3866f..5c6e2d404 100644 --- a/pallets/channel-commission/src/benchmarking.rs +++ b/pallets/channel-commission/src/benchmarking.rs @@ -188,6 +188,23 @@ benchmarks! { let block_num =BlockNumberFor::::from(101u32); }: {ChannelCommission::::on_initialize(block_num);} + set_channel_vtoken_shares { + let origin = T::ControlOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; + let vtoken_set = CurrencyId::VToken2(0); + let shares = Permill::from_percent(1); + let channel_id = 0; + + // assume we have 60 channels at most + let x in 1 .. 60; + let channel_name = b"Bifrost".to_vec(); + let receiver = whitelisted_caller(); + + // register channels + for i in 0 .. x { + assert_ok!(register_channel(origin.clone(), channel_name.clone(), receiver.clone())); + } + + }: _(origin.clone(), channel_id, vtoken_set, shares) impl_benchmark_test_suite!(ChannelCommission,crate::mock::ExtBuilder::default().build(),crate::mock::Runtime); } diff --git a/pallets/channel-commission/src/lib.rs b/pallets/channel-commission/src/lib.rs index 054d55692..826a6a446 100644 --- a/pallets/channel-commission/src/lib.rs +++ b/pallets/channel-commission/src/lib.rs @@ -469,6 +469,11 @@ pub mod pallet { // set the commission token CommissionTokens::::insert(vtoken, commission_token); + // set VtokenIssuanceSnapshots for the vtoken + let issuance = T::MultiCurrency::total_issuance(vtoken); + let zero_balance: BalanceOf = Zero::zero(); + VtokenIssuanceSnapshots::::insert(vtoken, (zero_balance, issuance)); + Self::deposit_event(Event::CommissionTokenSet { vtoken, commission_token: Some(commission_token), @@ -485,6 +490,60 @@ pub mod pallet { Self::settle_channel_commission(channel_id)?; Ok(()) } + + #[pallet::call_index(6)] + #[pallet::weight(T::WeightInfo::set_channel_vtoken_shares(Channels::::iter().count() as u32))] + pub fn set_channel_vtoken_shares( + origin: OriginFor, + channel_id: ChannelId, + vtoken: CurrencyId, + shares: Permill, + ) -> DispatchResult { + T::ControlOrigin::ensure_origin(origin)?; + + // check if the channel exists + ensure!(Channels::::contains_key(channel_id), Error::::ChannelNotExist); + + // check if the vtoken exists + ensure!( + CommissionTokens::::contains_key(vtoken), + Error::::VtokenNotConfiguredForCommission + ); + + // 将所有渠道的这个vtoken的share加起来,但当前渠道的share不用storage里的,用传入的值 + // 如果加起来的share大于1,报错 + // 获取所有的channel_id + let channel_ids: Vec = Channels::::iter_keys().collect(); + // 对于每一个channel_id,获取这个channel_id的这个vtoken的share, + // 如果channel_id是当前channel_id,用传入的值 + let mut total_shares = Permill::zero(); + for id in channel_ids { + let share = if id == channel_id { + shares + } else { + ChannelVtokenShares::::get(id, vtoken) + }; + + let total_shares_op = total_shares.checked_add(&share); + + if let Some(total_shares_new) = total_shares_op { + total_shares = total_shares_new + } else { + Err(Error::::InvalidCommissionRate)? + }; + } + + // update the channel vtoken share + ChannelVtokenShares::::insert(channel_id, vtoken, shares); + + Self::deposit_event(Event::ChannelVtokenSharesUpdated { + channel_id, + vtoken, + share: shares, + }); + + Ok(()) + } } } diff --git a/pallets/channel-commission/src/tests.rs b/pallets/channel-commission/src/tests.rs index 5fd889bf3..b8b9f8b8c 100644 --- a/pallets/channel-commission/src/tests.rs +++ b/pallets/channel-commission/src/tests.rs @@ -20,7 +20,7 @@ use crate::{mock::*, *}; use bifrost_primitives::{currency::KSM, BNC, VBNC, VKSM}; -use frame_support::assert_ok; +use frame_support::{assert_noop, assert_ok}; use sp_runtime::AccountId32; const CHANNEL_A_NAME: &[u8] = b"channel_a"; @@ -482,3 +482,103 @@ fn channel_commission_distribution_with_net_mint_negative_should_work() { assert_eq!(bifrost_commission_balance_after, 100 - 6); }); } + +#[test] +fn set_channel_vtoken_shares_should_work() { + ExtBuilder::default().one_hundred_for_alice_n_bob().build().execute_with(|| { + setup(); + + // assure Channel A has no 0 percent in ChannelVtokenShares in VKSM + assert_eq!(ChannelVtokenShares::::get(0, VKSM), Permill::from_percent(0)); + + // set channel A's vtoken share in VKSM to 50% + assert_ok!(ChannelCommission::set_channel_vtoken_shares( + RuntimeOrigin::signed(ALICE), + 0, + VKSM, + Permill::from_percent(50), + )); + + assert_eq!(ChannelVtokenShares::::get(0, VKSM), Permill::from_percent(50)); + + // set channel B's vtoken share in VKSM to 90%, it should fail because the sum of all shares + // should be less than or equal to 100% + assert_noop!( + ChannelCommission::set_channel_vtoken_shares( + RuntimeOrigin::signed(ALICE), + 1, + VKSM, + Permill::from_percent(90), + ), + Error::::InvalidCommissionRate + ); + + // set channel B's vtoken share in VKSM to 30%, it should be ok now + assert_ok!(ChannelCommission::set_channel_vtoken_shares( + RuntimeOrigin::signed(ALICE), + 1, + VKSM, + Permill::from_percent(30), + )); + + assert_eq!(ChannelVtokenShares::::get(1, VKSM), Permill::from_percent(30)); + }); +} + +// register a new channel base on some existing channels, and mint some tokens to see whether the +// shares of existing channels are updated correctly.s +#[test] +fn register_a_new_channel_and_mint_should_update_shares_and_get_claimable_tokens() { + ExtBuilder::default().one_hundred_for_alice_n_bob().build().execute_with(|| { + let commission_account: AccountId = + ::CommissionPalletId::get().into_account_truncating(); + + // set the block number to 35 + System::set_block_number(35); + + // we have registered channel A and channel B for 0 shares for VKSM + setup(); + + // VtokenIssuanceSnapshots, set VKSM old total issuance to 10000. newly minted + // VKSM is 1000 + VtokenIssuanceSnapshots::::insert(VKSM, (9000, 10000)); + + // PeriodVtokenTotalMint + PeriodVtokenTotalMint::::insert(VKSM, (10000, 2000)); + + // PeriodVtokenTotalRedeem + PeriodVtokenTotalRedeem::::insert(VKSM, (0, 1000)); + + // PeriodChannelVtokenMint. Channel A mint 1000 VKSM, Channel B mint 1000 VKSM. + PeriodChannelVtokenMint::::insert(0, VKSM, (2000, 500)); + PeriodChannelVtokenMint::::insert(1, VKSM, (2000, 100)); + + // set vksm token issuance to 11000 + let _ = Currencies::update_balance( + RuntimeOrigin::root(), + commission_account.clone(), + VKSM, + 11000, + ); + + // set ksm token issuance to 11000 + let _ = Currencies::update_balance( + RuntimeOrigin::root(), + commission_account.clone(), + KSM, + 11000, + ); + + // set block number to 100 + run_to_block(100); + run_to_block(101); + + let channel_a_new_net_mint: u32 = 500 * 1000 / 2000; + + let channel_a_new_percentage = + Permill::from_rational_with_rounding(channel_a_new_net_mint, 11000u32, Rounding::Down) + .unwrap(); + // check channel A vtoken share after being cleared + assert_eq!(ChannelVtokenShares::::get(0, VKSM), channel_a_new_percentage); + }); +} diff --git a/pallets/channel-commission/src/weights.rs b/pallets/channel-commission/src/weights.rs index 39ffe56f9..50ccb7e04 100644 --- a/pallets/channel-commission/src/weights.rs +++ b/pallets/channel-commission/src/weights.rs @@ -60,6 +60,7 @@ pub trait WeightInfo { fn set_commission_tokens() -> Weight; fn claim_commissions() -> Weight; fn on_initialize(x: u32, ) -> Weight; + fn set_channel_vtoken_shares(x: u32,) -> Weight; } // For backwards compatibility and tests @@ -169,4 +170,14 @@ impl WeightInfo for () { .saturating_add(Weight::from_parts(58_153, 0).saturating_mul(x.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) } + + fn set_channel_vtoken_shares(x: u32, ) -> Weight { + Weight::from_parts(43_239_575, 3597) + .saturating_add(Weight::from_parts(5_355_920, 0).saturating_mul(x.into())) + .saturating_add(RocksDbWeight::get().reads(2_u64)) + .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(x.into()))) + .saturating_add(RocksDbWeight::get().writes(2_u64)) + .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(x.into()))) + .saturating_add(Weight::from_parts(0, 2499).saturating_mul(x.into())) + } } From 8b6473d2ab091175dd723c756eb7ad0d336734ac Mon Sep 17 00:00:00 2001 From: herryho Date: Thu, 18 Jan 2024 18:37:44 +0800 Subject: [PATCH 6/8] fix weights --- .../src/weights/bifrost_channel_commission.rs | 10 ++++++++++ .../src/weights/bifrost_channel_commission.rs | 10 ++++++++++ 2 files changed, 20 insertions(+) diff --git a/runtime/bifrost-kusama/src/weights/bifrost_channel_commission.rs b/runtime/bifrost-kusama/src/weights/bifrost_channel_commission.rs index 806993dbb..91c99f39d 100644 --- a/runtime/bifrost-kusama/src/weights/bifrost_channel_commission.rs +++ b/runtime/bifrost-kusama/src/weights/bifrost_channel_commission.rs @@ -159,4 +159,14 @@ impl bifrost_channel_commission::WeightInfo for Bifrost .saturating_add(Weight::from_parts(69_114, 0).saturating_mul(x.into())) .saturating_add(T::DbWeight::get().reads(1)) } + + fn set_channel_vtoken_shares(x: u32, ) -> Weight { + Weight::from_parts(43_239_575, 3597) + .saturating_add(Weight::from_parts(5_355_920, 0).saturating_mul(x.into())) + .saturating_add(T::DbWeight::get().reads(2_u64)) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(x.into()))) + .saturating_add(T::DbWeight::get().writes(2_u64)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(x.into()))) + .saturating_add(Weight::from_parts(0, 2499).saturating_mul(x.into())) + } } diff --git a/runtime/bifrost-polkadot/src/weights/bifrost_channel_commission.rs b/runtime/bifrost-polkadot/src/weights/bifrost_channel_commission.rs index 02184c97e..4e25a05fa 100644 --- a/runtime/bifrost-polkadot/src/weights/bifrost_channel_commission.rs +++ b/runtime/bifrost-polkadot/src/weights/bifrost_channel_commission.rs @@ -162,4 +162,14 @@ impl bifrost_channel_commission::WeightInfo for Bifrost .saturating_add(Weight::from_parts(220_865, 0).saturating_mul(x.into())) .saturating_add(T::DbWeight::get().reads(1)) } + + fn set_channel_vtoken_shares(x: u32, ) -> Weight { + Weight::from_parts(43_239_575, 3597) + .saturating_add(Weight::from_parts(5_355_920, 0).saturating_mul(x.into())) + .saturating_add(T::DbWeight::get().reads(2_u64)) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(x.into()))) + .saturating_add(T::DbWeight::get().writes(2_u64)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(x.into()))) + .saturating_add(Weight::from_parts(0, 2499).saturating_mul(x.into())) + } } From 3adf152fbe3190984d263be50a113ffe2bcba05b Mon Sep 17 00:00:00 2001 From: herryho Date: Thu, 18 Jan 2024 20:32:38 +0800 Subject: [PATCH 7/8] fix check-all --- pallets/channel-commission/src/benchmarking.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pallets/channel-commission/src/benchmarking.rs b/pallets/channel-commission/src/benchmarking.rs index 5c6e2d404..05761ddde 100644 --- a/pallets/channel-commission/src/benchmarking.rs +++ b/pallets/channel-commission/src/benchmarking.rs @@ -197,11 +197,11 @@ benchmarks! { // assume we have 60 channels at most let x in 1 .. 60; let channel_name = b"Bifrost".to_vec(); - let receiver = whitelisted_caller(); + let receiver: T::AccountId = whitelisted_caller(); // register channels for i in 0 .. x { - assert_ok!(register_channel(origin.clone(), channel_name.clone(), receiver.clone())); + assert_ok!(ChannelCommission::::register_channel(origin.clone(), channel_name.clone(), receiver.clone())); } }: _(origin.clone(), channel_id, vtoken_set, shares) From 50ab49cce8d79ab3b280edde3e6fe9a9af09a478 Mon Sep 17 00:00:00 2001 From: herryho Date: Mon, 29 Jan 2024 21:16:17 +0800 Subject: [PATCH 8/8] fix benchmark --- pallets/channel-commission/src/benchmarking.rs | 6 ++++++ pallets/channel-commission/src/lib.rs | 12 +++++++----- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/pallets/channel-commission/src/benchmarking.rs b/pallets/channel-commission/src/benchmarking.rs index 05761ddde..1930af0f9 100644 --- a/pallets/channel-commission/src/benchmarking.rs +++ b/pallets/channel-commission/src/benchmarking.rs @@ -199,6 +199,12 @@ benchmarks! { let channel_name = b"Bifrost".to_vec(); let receiver: T::AccountId = whitelisted_caller(); + // set_commission_tokens + assert_ok!(ChannelCommission::::set_commission_tokens( + origin.clone(), + vtoken_set, CurrencyId::Token2(0) + )); + // register channels for i in 0 .. x { assert_ok!(ChannelCommission::::register_channel(origin.clone(), channel_name.clone(), receiver.clone())); diff --git a/pallets/channel-commission/src/lib.rs b/pallets/channel-commission/src/lib.rs index 826a6a446..dbd9b3299 100644 --- a/pallets/channel-commission/src/lib.rs +++ b/pallets/channel-commission/src/lib.rs @@ -510,12 +510,11 @@ pub mod pallet { Error::::VtokenNotConfiguredForCommission ); - // 将所有渠道的这个vtoken的share加起来,但当前渠道的share不用storage里的,用传入的值 - // 如果加起来的share大于1,报错 - // 获取所有的channel_id + // get all channel_ids let channel_ids: Vec = Channels::::iter_keys().collect(); - // 对于每一个channel_id,获取这个channel_id的这个vtoken的share, - // 如果channel_id是当前channel_id,用传入的值 + // for each channel_id,get its vtoken share for the particular vtoken from the storage + // if channel_id equals the passed in channel_id, we use the passed in share instead of + // the storage one let mut total_shares = Permill::zero(); for id in channel_ids { let share = if id == channel_id { @@ -524,6 +523,9 @@ pub mod pallet { ChannelVtokenShares::::get(id, vtoken) }; + // add up all the vtoken shares of all channels for this particular vtoken, + // but use the passed in share for the passed in channel_id + // if the sum of all shares is greater than 1, throw an error let total_shares_op = total_shares.checked_add(&share); if let Some(total_shares_new) = total_shares_op {