diff --git a/Cargo.lock b/Cargo.lock index fe18931d7..65d11db94 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1047,6 +1047,7 @@ dependencies = [ "frame-benchmarking", "frame-support", "frame-system", + "manta-primitives", "pallet-balances", "pallet-timestamp", "parity-scale-codec", @@ -4985,6 +4986,7 @@ dependencies = [ "frame-support", "frame-system", "log", + "manta-primitives", "nimbus-primitives", "pallet-aura", "pallet-authorship", @@ -9063,6 +9065,7 @@ dependencies = [ name = "runtime-common" version = "3.4.0" dependencies = [ + "calamari-runtime", "cumulus-pallet-dmp-queue", "cumulus-pallet-parachain-system", "cumulus-pallet-xcm", diff --git a/node/src/chain_specs/calamari.rs b/node/src/chain_specs/calamari.rs index 4e7d1a46f..295b971e7 100644 --- a/node/src/chain_specs/calamari.rs +++ b/node/src/chain_specs/calamari.rs @@ -173,10 +173,15 @@ fn calamari_dev_genesis( candidates: invulnerables .iter() .cloned() - .map(|(account, _)| (account, 4_000_000 * KMA)) // TODO: Change to use constant from primitives + .map(|(account, _)| { + ( + account, + calamari_runtime::staking::NORMAL_COLLATOR_MINIMUM_STAKE, + ) + }) .collect(), delegations, - inflation_config: calamari_runtime::currency::inflation_config::< + inflation_config: calamari_runtime::staking::inflation_config::< calamari_runtime::Runtime, >(), }, diff --git a/pallets/asset-manager/src/mock.rs b/pallets/asset-manager/src/mock.rs index 73403f98e..29aa302ec 100644 --- a/pallets/asset-manager/src/mock.rs +++ b/pallets/asset-manager/src/mock.rs @@ -31,13 +31,10 @@ use manta_primitives::{ ConcreteFungibleLedger, }, constants::{ASSET_MANAGER_PALLET_ID, ASSET_STRING_LIMIT}, - types::{AccountId, AssetId, Balance}, + types::{AccountId, AssetId, Balance, BlockNumber, Header}, }; use sp_core::{H160, H256}; -use sp_runtime::{ - testing::Header, - traits::{BlakeTwo256, IdentityLookup}, -}; +use sp_runtime::traits::{BlakeTwo256, IdentityLookup}; use sp_std::marker::PhantomData; use xcm::{ prelude::{Parachain, X1}, @@ -47,7 +44,7 @@ use xcm::{ parameter_types! { pub const BlockHashCount: u64 = 250; - pub const SS58Prefix: u8 = 78; + pub const SS58Prefix: u8 = manta_primitives::constants::CALAMARI_SS58PREFIX; } impl system::Config for Runtime { @@ -58,14 +55,14 @@ impl system::Config for Runtime { type Origin = Origin; type Call = Call; type Index = u64; - type BlockNumber = u64; + type BlockNumber = BlockNumber; type Hash = H256; type Hashing = BlakeTwo256; type AccountId = AccountId; type Lookup = IdentityLookup; type Header = Header; type Event = Event; - type BlockHashCount = BlockHashCount; + type BlockHashCount = ConstU32<250>; type Version = (); type PalletInfo = PalletInfo; type AccountData = pallet_balances::AccountData; diff --git a/pallets/collator-selection/Cargo.toml b/pallets/collator-selection/Cargo.toml index 258a73c80..f049f9903 100644 --- a/pallets/collator-selection/Cargo.toml +++ b/pallets/collator-selection/Cargo.toml @@ -31,6 +31,7 @@ sp-staking = { git = 'https://github.com/paritytech/substrate.git', default-feat sp-std = { git = 'https://github.com/paritytech/substrate.git', default-features = false, branch = "polkadot-v0.9.26" } [dev-dependencies] +manta-primitives = { path = "../../primitives/manta" } pallet-aura = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.26" } pallet-balances = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.26" } pallet-timestamp = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.26" } diff --git a/pallets/collator-selection/src/mock.rs b/pallets/collator-selection/src/mock.rs index 64cd30477..31768ca50 100644 --- a/pallets/collator-selection/src/mock.rs +++ b/pallets/collator-selection/src/mock.rs @@ -23,12 +23,12 @@ use frame_support::{ }, PalletId, }; - use frame_system::EnsureSignedBy; +use manta_primitives::types::{BlockNumber, Header}; use sp_arithmetic::Percent; use sp_core::H256; use sp_runtime::{ - testing::{Header, UintAuthorityId}, + testing::UintAuthorityId, traits::{BlakeTwo256, IdentityLookup, OpaqueKeys}, RuntimeAppPublic, }; @@ -61,14 +61,14 @@ impl frame_system::Config for Test { type Origin = Origin; type Call = Call; type Index = u64; - type BlockNumber = u64; + type BlockNumber = BlockNumber; type Hash = H256; type Hashing = BlakeTwo256; type AccountId = u64; type Lookup = IdentityLookup; type Header = Header; type Event = Event; - type BlockHashCount = ConstU64<250>; + type BlockHashCount = ConstU32<250>; type Version = (); type PalletInfo = PalletInfo; type AccountData = pallet_balances::AccountData; @@ -147,7 +147,7 @@ impl pallet_session::SessionHandler for TestSessionHandler { SessionHandlerCollators::set(keys.iter().map(|(a, _)| *a).collect::>()) } fn on_new_session(_: bool, keys: &[(u64, Ks)], _: &[(u64, Ks)]) { - SessionChangeBlock::set(System::block_number()); + SessionChangeBlock::set(System::block_number() as u64); SessionHandlerCollators::set(keys.iter().map(|(a, _)| *a).collect::>()) } fn on_before_session_ending() {} @@ -155,8 +155,8 @@ impl pallet_session::SessionHandler for TestSessionHandler { } parameter_types! { - pub const Offset: u64 = 0; - pub const Period: u64 = 10; + pub const Offset: BlockNumber = 0; + pub const Period: BlockNumber = 10; } impl pallet_session::Config for Test { @@ -251,9 +251,9 @@ pub fn new_test_ext() -> sp_io::TestExternalities { t.into() } -pub fn initialize_to_block(n: u64) { +pub fn initialize_to_block(n: BlockNumber) { for i in System::block_number() + 1..=n { System::set_block_number(i); - >::on_initialize(i); + >::on_initialize(i); } } diff --git a/pallets/manta-pay/src/mock.rs b/pallets/manta-pay/src/mock.rs index 4580d02cf..764d403fb 100644 --- a/pallets/manta-pay/src/mock.rs +++ b/pallets/manta-pay/src/mock.rs @@ -27,11 +27,10 @@ use manta_primitives::{ ConcreteFungibleLedger, }, constants::{ASSET_MANAGER_PALLET_ID, MANTA_PAY_PALLET_ID}, - types::{AssetId, Balance}, + types::{AssetId, Balance, BlockNumber, Header}, }; use sp_core::H256; use sp_runtime::{ - testing::Header, traits::{BlakeTwo256, IdentityLookup}, AccountId32, }; @@ -58,11 +57,9 @@ frame_support::construct_runtime!( } ); -type BlockNumber = u64; - parameter_types! { pub const BlockHashCount: BlockNumber = 250; - pub const SS58Prefix: u8 = 42; + pub const SS58Prefix: u8 = manta_primitives::constants::CALAMARI_SS58PREFIX; } impl frame_system::Config for Test { diff --git a/pallets/parachain-staking/src/mock.rs b/pallets/parachain-staking/src/mock.rs index 76f88f3d4..d79168221 100644 --- a/pallets/parachain-staking/src/mock.rs +++ b/pallets/parachain-staking/src/mock.rs @@ -24,17 +24,16 @@ use frame_support::{ traits::{Everything, GenesisBuild, LockIdentifier, OnFinalize, OnInitialize}, weights::Weight, }; +use manta_primitives::types::{BlockNumber, Header}; use sp_core::H256; use sp_io; use sp_runtime::{ - testing::Header, traits::{BlakeTwo256, IdentityLookup}, Perbill, Percent, }; pub type AccountId = u64; pub type Balance = u128; -pub type BlockNumber = u64; type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; type Block = frame_system::mocking::MockBlock; @@ -57,11 +56,11 @@ construct_runtime!( ); parameter_types! { - pub const BlockHashCount: u64 = 250; + pub const BlockHashCount: BlockNumber = 250; pub const MaximumBlockWeight: Weight = 1024; pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::one(); - pub const SS58Prefix: u8 = 42; + pub const SS58Prefix: u8 = manta_primitives::constants::CALAMARI_SS58PREFIX; } impl frame_system::Config for Test { type BaseCallFilter = Everything; @@ -212,7 +211,7 @@ impl pallet_session::SessionHandler for TestSessionHandler { SessionHandlerCollators::set(keys.iter().map(|(a, _)| *a).collect::>()) } fn on_new_session(_: bool, keys: &[(u64, Ks)], _: &[(u64, Ks)]) { - SessionChangeBlock::set(System::block_number()); + SessionChangeBlock::set(System::block_number() as u64); SessionHandlerCollators::set(keys.iter().map(|(a, _)| *a).collect::>()) } fn on_before_session_ending() {} @@ -233,8 +232,8 @@ impl From for MockSessionKeys { } parameter_types! { - pub const Offset: u64 = 0; - pub const Period: u64 = 10; + pub const Offset: BlockNumber = 0; + pub const Period: BlockNumber = 10; } impl pallet_session::Config for Test { type Event = Event; @@ -340,7 +339,7 @@ impl ExtBuilder { } /// Rolls forward one block. Returns the new block number. -pub(crate) fn roll_one_block() -> u64 { +pub(crate) fn roll_one_block() -> u32 { Balances::on_finalize(System::block_number()); System::on_finalize(System::block_number()); System::set_block_number(System::block_number() + 1); @@ -351,7 +350,7 @@ pub(crate) fn roll_one_block() -> u64 { } /// Rolls to the desired block. Returns the number of blocks played. -pub(crate) fn roll_to(n: u64) -> u64 { +pub(crate) fn roll_to(n: u32) -> u32 { let mut num_blocks = 0; let mut block = System::block_number(); while block < n { @@ -364,15 +363,15 @@ pub(crate) fn roll_to(n: u64) -> u64 { /// Rolls block-by-block to the beginning of the specified round. /// This will complete the block in which the round change occurs. /// Returns the number of blocks played. -pub(crate) fn roll_to_round_begin(round: u64) -> u64 { - let block = (round - 1) * DefaultBlocksPerRound::get() as u64; +pub(crate) fn roll_to_round_begin(round: u32) -> u32 { + let block = (round - 1) * DefaultBlocksPerRound::get(); roll_to(block) } /// Rolls block-by-block to the end of the specified round. /// The block following will be the one in which the specified round change occurs. -pub(crate) fn roll_to_round_end(round: u64) -> u64 { - let block = round * DefaultBlocksPerRound::get() as u64 - 1; +pub(crate) fn roll_to_round_end(round: u32) -> u32 { + let block = round * DefaultBlocksPerRound::get() - 1; roll_to(block) } diff --git a/pallets/parachain-staking/src/tests.rs b/pallets/parachain-staking/src/tests.rs index 100ea5f65..e8d0dc2cb 100644 --- a/pallets/parachain-staking/src/tests.rs +++ b/pallets/parachain-staking/src/tests.rs @@ -7376,11 +7376,11 @@ fn deferred_payment_steady_state_event_flow() { .build() .execute_with(|| { // convenience to set the round points consistently - let set_round_points = |round: u64| { - set_author(round as u32, 1, 1); - set_author(round as u32, 2, 1); - set_author(round as u32, 3, 1); - set_author(round as u32, 4, 1); + let set_round_points = |round: u32| { + set_author(round, 1, 1); + set_author(round, 2, 1); + set_author(round, 3, 1); + set_author(round, 4, 1); }; // grab initial issuance -- we will reset it before round issuance is calculated so that @@ -7400,8 +7400,8 @@ fn deferred_payment_steady_state_event_flow() { }; // fn to roll through the first RewardPaymentDelay rounds. returns new round index - let roll_through_initial_rounds = |mut round: u64| -> u64 { - while round < crate::mock::RewardPaymentDelay::get() as u64 + 1 { + let roll_through_initial_rounds = |mut round: u32| -> u32 { + while round < crate::mock::RewardPaymentDelay::get() + 1 { set_round_points(round); roll_to_round_end(round); @@ -7415,7 +7415,7 @@ fn deferred_payment_steady_state_event_flow() { // roll through a "steady state" round and make all of our assertions // returns new round index - let roll_through_steady_state_round = |round: u64| -> u64 { + let roll_through_steady_state_round = |round: u32| -> u32 { let num_rounds_rolled = roll_to_round_begin(round); assert_eq!( num_rounds_rolled, 1, @@ -7424,28 +7424,28 @@ fn deferred_payment_steady_state_event_flow() { let expected = vec![ Event::CollatorChosen { - round: round as u32, + round, collator_account: 1, total_exposed_amount: 400, }, Event::CollatorChosen { - round: round as u32, + round, collator_account: 2, total_exposed_amount: 400, }, Event::CollatorChosen { - round: round as u32, + round, collator_account: 3, total_exposed_amount: 400, }, Event::CollatorChosen { - round: round as u32, + round, collator_account: 4, total_exposed_amount: 400, }, Event::NewRound { starting_block: (round - 1) * 5, - round: round as u32, + round, selected_collators_number: 4, total_balance: 1600, }, diff --git a/pallets/tx-pause/src/mock.rs b/pallets/tx-pause/src/mock.rs index 31570e9b5..7c4b1718f 100644 --- a/pallets/tx-pause/src/mock.rs +++ b/pallets/tx-pause/src/mock.rs @@ -22,15 +22,12 @@ #![cfg(test)] use super::*; -use frame_support::{ - construct_runtime, ord_parameter_types, parameter_types, - traits::{ConstU32, ConstU64}, -}; +use frame_support::{construct_runtime, ord_parameter_types, parameter_types, traits::ConstU32}; use frame_system::EnsureRoot; -use manta_primitives::types::Balance; +use manta_primitives::types::{Balance, BlockNumber, Header}; use sp_core::H256; -use sp_runtime::{testing::Header, traits::IdentityLookup}; +use sp_runtime::traits::{BlakeTwo256, IdentityLookup}; pub type AccountId = u128; pub const ALICE: AccountId = 1; @@ -50,15 +47,15 @@ impl Contains for BaseFilter { impl frame_system::Config for Runtime { type Origin = Origin; type Index = u64; - type BlockNumber = u64; + type BlockNumber = BlockNumber; type Call = Call; type Hash = H256; - type Hashing = ::sp_runtime::traits::BlakeTwo256; + type Hashing = BlakeTwo256; type AccountId = AccountId; type Lookup = IdentityLookup; type Header = Header; type Event = Event; - type BlockHashCount = ConstU64<250>; + type BlockHashCount = ConstU32<250>; type BlockWeights = (); type BlockLength = (); type Version = (); diff --git a/pallets/vesting/Cargo.toml b/pallets/vesting/Cargo.toml index ae84276ef..771fdae3b 100644 --- a/pallets/vesting/Cargo.toml +++ b/pallets/vesting/Cargo.toml @@ -21,6 +21,7 @@ sp-std = { git = 'https://github.com/paritytech/substrate.git', default-features [dev-dependencies] chrono = "0.4" +manta-primitives = { path = "../../primitives/manta" } pallet-balances = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.26" } pallet-timestamp = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.26" } sp-core = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.26" } diff --git a/pallets/vesting/src/mock.rs b/pallets/vesting/src/mock.rs index d27787fa6..2d5c1fc1d 100644 --- a/pallets/vesting/src/mock.rs +++ b/pallets/vesting/src/mock.rs @@ -14,24 +14,17 @@ // You should have received a copy of the GNU General Public License // along with Manta. If not, see . -use frame_support::{ - parameter_types, - traits::{ConstU32, ConstU64}, -}; -use sp_core::H256; -use sp_runtime::{ - testing::Header, - traits::{BlakeTwo256, IdentityLookup}, -}; - use super::*; use crate as calamari_vesting; +use frame_support::{parameter_types, traits::ConstU32}; +use manta_primitives::types::{BlockNumber, Header}; +use sp_core::H256; +use sp_runtime::traits::{BlakeTwo256, IdentityLookup}; type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; type Block = frame_system::mocking::MockBlock; pub type AccountId = u128; -pub type BlockNumber = u64; pub type Balance = u128; pub const ALICE: AccountId = 1; @@ -59,7 +52,7 @@ impl frame_system::Config for Test { type AccountData = pallet_balances::AccountData; type AccountId = AccountId; type BaseCallFilter = frame_support::traits::Everything; - type BlockHashCount = ConstU64<250>; + type BlockHashCount = ConstU32<250>; type BlockLength = (); type BlockNumber = BlockNumber; type BlockWeights = (); @@ -157,6 +150,6 @@ impl ExtBuilder { } } -pub(crate) fn run_to_block(n: u64) { +pub(crate) fn run_to_block(n: BlockNumber) { System::set_block_number(n); } diff --git a/primitives/manta/src/constants.rs b/primitives/manta/src/constants.rs index aea128842..881c06e1c 100644 --- a/primitives/manta/src/constants.rs +++ b/primitives/manta/src/constants.rs @@ -60,8 +60,3 @@ pub const MANTA_PAY_PALLET_ID: PalletId = PalletId(*b"mantapay"); /// Default Asset Existential Deposit: Should only be used in TEST pub const DEFAULT_ASSET_ED: Balance = 1; - -pub mod calamari_staking { - // TODO - // pub const MinCollatorStake: u32 = 4_000_000; -} diff --git a/runtime/calamari/Cargo.toml b/runtime/calamari/Cargo.toml index 9281bc98e..500ec4f6a 100644 --- a/runtime/calamari/Cargo.toml +++ b/runtime/calamari/Cargo.toml @@ -109,6 +109,46 @@ substrate-wasm-builder = { git = 'https://github.com/paritytech/substrate.git', reqwest = { version = "0.11", features = ["blocking"] } serde_json = "1.0" +# 3rd dependencies +codec = { package = "parity-scale-codec", version = "3.1.2" } +scale-info = { version = "2.1.2", features = ["derive"] } + +# Substrate dependencies +frame-system = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.26" } +pallet-assets = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.26" } +pallet-balances = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.26" } +pallet-utility = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.26" } +sp-core = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.26" } +sp-io = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.26" } +sp-std = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.26" } + +# Polkadot dependencies +pallet-xcm = { git = 'https://github.com/paritytech/polkadot.git', branch = "release-v0.9.26" } +polkadot-core-primitives = { git = 'https://github.com/paritytech/polkadot.git', branch = "release-v0.9.26" } +polkadot-parachain = { git = 'https://github.com/paritytech/polkadot.git', branch = "release-v0.9.26" } +polkadot-runtime-parachains = { git = 'https://github.com/paritytech/polkadot.git', branch = "release-v0.9.26" } +xcm = { git = 'https://github.com/paritytech/polkadot.git', branch = "release-v0.9.26" } +xcm-builder = { git = 'https://github.com/paritytech/polkadot.git', branch = "release-v0.9.26" } +xcm-executor = { git = 'https://github.com/paritytech/polkadot.git', branch = "release-v0.9.26" } +xcm-simulator = { git = 'https://github.com/paritytech/polkadot.git', branch = "release-v0.9.26" } + +# Cumulus dependencies +cumulus-pallet-dmp-queue = { git = 'https://github.com/paritytech/cumulus.git', branch = "polkadot-v0.9.26" } +cumulus-pallet-parachain-system = { git = 'https://github.com/paritytech/cumulus.git', branch = "polkadot-v0.9.26" } +cumulus-pallet-xcm = { git = 'https://github.com/paritytech/cumulus.git', branch = "polkadot-v0.9.26" } +cumulus-pallet-xcmp-queue = { git = 'https://github.com/paritytech/cumulus.git', branch = "polkadot-v0.9.26" } +cumulus-primitives-parachain-inherent = { git = "https://github.com/paritytech/cumulus.git", branch = "polkadot-v0.9.26" } +cumulus-test-relay-sproof-builder = { git = "https://github.com/paritytech/cumulus.git", branch = "polkadot-v0.9.26" } +parachain-info = { git = 'https://github.com/paritytech/cumulus.git', branch = "polkadot-v0.9.26" } + +# Orml dependencies +orml-traits = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "polkadot-v0.9.26" } +orml-xtokens = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "polkadot-v0.9.26" } + +# Self dependencies +pallet-asset-manager = { path = '../../pallets/asset-manager' } + + [features] default = ['std'] runtime-benchmarks = [ diff --git a/runtime/calamari/src/currency.rs b/runtime/calamari/src/currency.rs index 32451537f..b4f37b69c 100644 --- a/runtime/calamari/src/currency.rs +++ b/runtime/calamari/src/currency.rs @@ -25,39 +25,3 @@ pub const uKMA: Balance = KMA / 1_000_000; // 6 decimal, micro-MA pub const fn deposit(items: u32, bytes: u32) -> Balance { items as Balance * 15 * mKMA + (bytes as Balance) * 6 * mKMA // TODO: revisit the storage cost here } - -use pallet_parachain_staking::{BalanceOf, InflationInfo}; -pub fn inflation_config( -) -> InflationInfo> { - use pallet_parachain_staking::inflation::Range; - use sp_arithmetic::Perbill; - use sp_runtime::{traits::UniqueSaturatedInto, PerThing}; - - fn to_round_inflation(annual: Range) -> Range { - use pallet_parachain_staking::inflation::{ - perbill_annual_to_perbill_round, BLOCKS_PER_YEAR, - }; - perbill_annual_to_perbill_round( - annual, - // rounds per year - BLOCKS_PER_YEAR / crate::DefaultBlocksPerRound::get(), - ) - } - let annual = Range { - min: Perbill::from_rational_with_rounding(5u32, 200u32, sp_arithmetic::Rounding::Down) - .expect("constant denom is not 0. qed"), // = 2.5% - ideal: Perbill::from_percent(3), - max: Perbill::from_percent(3), - }; - InflationInfo::> { - // staking expectations **per round** - expect: Range { - min: (170_000 * KMA).unique_saturated_into(), - ideal: (205_479 * KMA).unique_saturated_into(), // annual inflation / number of rounds - max: (210_000 * KMA).unique_saturated_into(), - }, - // annual inflation - annual, - round: to_round_inflation(annual), - } -} diff --git a/runtime/calamari/src/lib.rs b/runtime/calamari/src/lib.rs index e34efb8b6..efd7577d1 100644 --- a/runtime/calamari/src/lib.rs +++ b/runtime/calamari/src/lib.rs @@ -76,6 +76,7 @@ pub mod fee; pub mod impls; pub mod migrations; mod nimbus_session_adapter; +pub mod staking; pub mod xcm_config; use currency::*; @@ -115,7 +116,7 @@ pub mod opaque { } // Weights used in the runtime. -mod weights; +pub mod weights; #[sp_version::runtime_version] pub const VERSION: RuntimeVersion = RuntimeVersion { @@ -568,8 +569,8 @@ parameter_types! { pub const DefaultCollatorCommission: Perbill = Perbill::from_percent(10); /// Default percent of inflation set aside for parachain bond every round pub const DefaultParachainBondReservePercent: Percent = Percent::zero(); - pub DefaultBlocksPerRound: BlockNumber = prod_or_fast!(6 * HOURS ,15,"CALAMARI_DEFAULTBLOCKSPERROUND"); - pub LeaveDelayRounds: BlockNumber = prod_or_fast!(28 ,1 ,"CALAMARI_LEAVEDELAYROUNDS"); // == 7 * DAYS / 6 * HOURS + pub DefaultBlocksPerRound: BlockNumber = prod_or_fast!(6 * HOURS,15,"CALAMARI_DEFAULTBLOCKSPERROUND"); + pub LeaveDelayRounds: BlockNumber = prod_or_fast!(28,1,"CALAMARI_LEAVEDELAYROUNDS"); // == 7 * DAYS / 6 * HOURS } impl pallet_parachain_staking::Config for Runtime { type Event = Event; @@ -603,12 +604,11 @@ impl pallet_parachain_staking::Config for Runtime { type DefaultCollatorCommission = DefaultCollatorCommission; type DefaultParachainBondReservePercent = DefaultParachainBondReservePercent; /// Minimum stake on a collator to be considered for block production - // WHITELIST: Temporarily 400k to accomodate whitelisted collators - type MinCollatorStk = ConstU128<{ 400_000 * KMA }>; + type MinCollatorStk = ConstU128<{ crate::staking::MIN_BOND_TO_BE_CONSIDERED_COLLATOR }>; /// Minimum stake the collator runner must bond to register as collator candidate - type MinCandidateStk = ConstU128<{ 4_000_000 * KMA }>; + type MinCandidateStk = ConstU128<{ crate::staking::NORMAL_COLLATOR_MINIMUM_STAKE }>; /// WHITELIST: Minimum stake required for *a whitelisted* account to be a collator candidate - type MinWhitelistCandidateStk = ConstU128<{ 400_000 * KMA }>; + type MinWhitelistCandidateStk = ConstU128<{ crate::staking::EARLY_COLLATOR_MINIMUM_STAKE }>; /// Smallest amount that can be delegated type MinDelegation = ConstU128<{ 5_000 * KMA }>; /// Minimum stake required to be reserved to be a delegator diff --git a/runtime/calamari/src/migrations/staking.rs b/runtime/calamari/src/migrations/staking.rs index 41237bed1..63362a17f 100644 --- a/runtime/calamari/src/migrations/staking.rs +++ b/runtime/calamari/src/migrations/staking.rs @@ -109,7 +109,7 @@ where pallet_parachain_staking::Pallet::::initialize_pallet( current_block, invulnerables, - crate::currency::inflation_config::(), + crate::staking::inflation_config::(), ) .unwrap_or_else(|err| { log::error!( diff --git a/runtime/calamari/src/staking.rs b/runtime/calamari/src/staking.rs new file mode 100644 index 000000000..b543a3f8c --- /dev/null +++ b/runtime/calamari/src/staking.rs @@ -0,0 +1,57 @@ +// Copyright 2020-2022 Manta Network. +// This file is part of Manta. +// +// Manta 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. +// +// Manta 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 Manta. If not, see . + +use crate::{currency::KMA, Balance}; +use pallet_parachain_staking::{BalanceOf, InflationInfo}; + +pub const NORMAL_COLLATOR_MINIMUM_STAKE: Balance = 4_000_000 * KMA; +pub const EARLY_COLLATOR_MINIMUM_STAKE: Balance = 400_000 * KMA; +pub const MIN_BOND_TO_BE_CONSIDERED_COLLATOR: Balance = EARLY_COLLATOR_MINIMUM_STAKE; + +pub fn inflation_config( +) -> InflationInfo> { + use pallet_parachain_staking::inflation::Range; + use sp_arithmetic::Perbill; + use sp_runtime::{traits::UniqueSaturatedInto, PerThing}; + + fn to_round_inflation(annual: Range) -> Range { + use pallet_parachain_staking::inflation::{ + perbill_annual_to_perbill_round, BLOCKS_PER_YEAR, + }; + perbill_annual_to_perbill_round( + annual, + // rounds per year + BLOCKS_PER_YEAR / crate::DefaultBlocksPerRound::get(), + ) + } + let annual = Range { + min: Perbill::from_rational_with_rounding(5u32, 200u32, sp_arithmetic::Rounding::Down) + .expect("constant denom is not 0. qed"), // = 2.5% + ideal: Perbill::from_percent(3), + max: Perbill::from_percent(3), + }; + InflationInfo::> { + // staking expectations **per round** + expect: Range { + min: (170_000 * KMA).unique_saturated_into(), + ideal: (205_479 * KMA).unique_saturated_into(), // annual inflation / number of rounds + max: (210_000 * KMA).unique_saturated_into(), + }, + // annual inflation + annual, + round: to_round_inflation(annual), + } +} diff --git a/runtime/calamari/tests/integration_tests.rs b/runtime/calamari/tests/integration_tests.rs index 3ce218f9c..cd84dc9ae 100644 --- a/runtime/calamari/tests/integration_tests.rs +++ b/runtime/calamari/tests/integration_tests.rs @@ -18,8 +18,8 @@ #![allow(clippy::identity_op)] // keep e.g. 1 * DAYS for legibility -mod common; -use common::{info_from_weight, last_event, mock::*, root_origin, INITIAL_BALANCE}; +mod integrations_mock; +use integrations_mock::{info_from_weight, last_event, mock::*, root_origin, INITIAL_BALANCE}; pub use calamari_runtime::{ assets_config::{CalamariAssetConfig, CalamariConcreteFungibleLedger}, diff --git a/runtime/calamari/tests/common/mock.rs b/runtime/calamari/tests/integrations_mock/mock.rs similarity index 99% rename from runtime/calamari/tests/common/mock.rs rename to runtime/calamari/tests/integrations_mock/mock.rs index f01263c92..5fab306a8 100644 --- a/runtime/calamari/tests/common/mock.rs +++ b/runtime/calamari/tests/integrations_mock/mock.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Manta. If not, see . -use crate::common::*; +use crate::integrations_mock::*; use calamari_runtime::opaque::SessionKeys; pub use calamari_runtime::{ diff --git a/runtime/calamari/tests/common/mod.rs b/runtime/calamari/tests/integrations_mock/mod.rs similarity index 100% rename from runtime/calamari/tests/common/mod.rs rename to runtime/calamari/tests/integrations_mock/mod.rs diff --git a/runtime/common/tests/xcm_mock/mod.rs b/runtime/calamari/tests/xcm_mock/mod.rs similarity index 100% rename from runtime/common/tests/xcm_mock/mod.rs rename to runtime/calamari/tests/xcm_mock/mod.rs diff --git a/runtime/common/tests/xcm_mock/parachain.rs b/runtime/calamari/tests/xcm_mock/parachain.rs similarity index 97% rename from runtime/common/tests/xcm_mock/parachain.rs rename to runtime/calamari/tests/xcm_mock/parachain.rs index 94d0cb9c3..8b7c41397 100644 --- a/runtime/common/tests/xcm_mock/parachain.rs +++ b/runtime/calamari/tests/xcm_mock/parachain.rs @@ -30,8 +30,7 @@ use frame_system::EnsureRoot; use scale_info::TypeInfo; use sp_core::{H160, H256}; use sp_runtime::{ - testing::Header, - traits::{Hash, IdentityLookup}, + traits::{BlakeTwo256, Hash, IdentityLookup}, AccountId32, }; use sp_std::prelude::*; @@ -42,7 +41,7 @@ use manta_primitives::{ AssetStorageMetadata, ConcreteFungibleLedger, }, constants::{ASSET_MANAGER_PALLET_ID, CALAMARI_DECIMAL}, - types::AssetId, + types::{AssetId, BlockNumber, Header}, xcm::{FirstAssetTrader, IsNativeConcrete, MultiAssetAdapter, MultiNativeAsset}, }; use pallet_xcm::XcmPassthrough; @@ -54,26 +53,27 @@ use xcm::{latest::prelude::*, Version as XcmVersion, VersionedMultiLocation, Ver use xcm_builder::{ AccountId32Aliases, AllowKnownQueryResponses, AllowSubscriptionsFrom, AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom, ConvertedConcreteAssetId, - EnsureXcmOrigin, FixedRateOfFungible, FixedWeightBounds, LocationInverter, ParentIsPreset, + EnsureXcmOrigin, FixedRateOfFungible, LocationInverter, ParentIsPreset, SiblingParachainAsNative, SiblingParachainConvertsVia, SignedAccountId32AsNative, - SovereignSignedViaLocation, TakeWeightCredit, + SovereignSignedViaLocation, TakeWeightCredit, WeightInfoBounds, }; use xcm_executor::{traits::JustTry, Config, XcmExecutor}; use xcm_simulator::{DmpMessageHandlerT, Get, TestExt, XcmpMessageHandlerT}; + pub type AccountId = AccountId32; pub type Balance = u128; parameter_types! { - pub const BlockHashCount: u64 = 250; + pub const BlockHashCount: BlockNumber = 250; } impl frame_system::Config for Runtime { type Origin = Origin; type Call = Call; type Index = u64; - type BlockNumber = u64; + type BlockNumber = BlockNumber; type Hash = H256; - type Hashing = ::sp_runtime::traits::BlakeTwo256; + type Hashing = BlakeTwo256; type AccountId = AccountId; type Lookup = IdentityLookup; type Header = Header; @@ -270,7 +270,11 @@ impl Config for XcmExecutorConfig { type IsTeleporter = (); type LocationInverter = LocationInverter; type Barrier = Barrier; - type Weigher = FixedWeightBounds; + type Weigher = WeightInfoBounds< + calamari_runtime::weights::xcm::CalamariXcmWeight, + Call, + MaxInstructions, + >; // Trader is the means to purchasing weight credit for XCM execution. // We define two traders: // The first one will charge parachain's native currency, who's `MultiLocation` @@ -471,7 +475,11 @@ impl pallet_xcm::Config for Runtime { // Do not allow teleports type XcmTeleportFilter = Nothing; type XcmReserveTransferFilter = Nothing; - type Weigher = FixedWeightBounds; + type Weigher = WeightInfoBounds< + calamari_runtime::weights::xcm::CalamariXcmWeight, + Call, + MaxInstructions, + >; type LocationInverter = LocationInverter; type Origin = Origin; type Call = Call; @@ -611,7 +619,11 @@ impl orml_xtokens::Config for Runtime { CurrencyIdtoMultiLocation>; type XcmExecutor = XcmExecutor; type SelfLocation = SelfReserve; - type Weigher = xcm_builder::FixedWeightBounds; + type Weigher = WeightInfoBounds< + calamari_runtime::weights::xcm::CalamariXcmWeight, + Call, + MaxInstructions, + >; type BaseXcmWeight = BaseXcmWeight; type LocationInverter = LocationInverter; type MaxAssetsForTransfer = MaxAssetsForTransfer; @@ -660,7 +672,7 @@ pub(crate) fn on_runtime_upgrade() { PolkadotXcm::on_runtime_upgrade(); } -pub(crate) fn para_roll_to(n: u64) { +pub(crate) fn para_roll_to(n: u32) { while System::block_number() < n { PolkadotXcm::on_finalize(System::block_number()); Balances::on_finalize(System::block_number()); diff --git a/runtime/common/tests/xcm_mock/relay_chain.rs b/runtime/calamari/tests/xcm_mock/relay_chain.rs similarity index 96% rename from runtime/common/tests/xcm_mock/relay_chain.rs rename to runtime/calamari/tests/xcm_mock/relay_chain.rs index 36ce77e83..a053175f6 100644 --- a/runtime/common/tests/xcm_mock/relay_chain.rs +++ b/runtime/calamari/tests/xcm_mock/relay_chain.rs @@ -22,8 +22,12 @@ use frame_support::{ weights::Weight, }; use sp_core::H256; -use sp_runtime::{testing::Header, traits::IdentityLookup, AccountId32}; +use sp_runtime::{ + traits::{BlakeTwo256, IdentityLookup}, + AccountId32, +}; +use manta_primitives::types::{BlockNumber, Header}; use polkadot_parachain::primitives::Id as ParaId; use polkadot_runtime_parachains::{configuration, origin, shared, ump}; use xcm::latest::prelude::*; @@ -36,20 +40,21 @@ use xcm_builder::{ TakeWeightCredit, }; use xcm_executor::{Config, XcmExecutor}; + pub type AccountId = AccountId32; pub type Balance = u128; parameter_types! { - pub const BlockHashCount: u64 = 250; + pub const BlockHashCount: BlockNumber = 250; } impl frame_system::Config for Runtime { type Origin = Origin; type Call = Call; type Index = u64; - type BlockNumber = u64; + type BlockNumber = BlockNumber; type Hash = H256; - type Hashing = ::sp_runtime::traits::BlakeTwo256; + type Hashing = BlakeTwo256; type AccountId = AccountId; type Lookup = IdentityLookup; type Header = Header; @@ -221,7 +226,7 @@ pub(crate) fn relay_events() -> Vec { } use frame_support::traits::{OnFinalize, OnInitialize}; -pub(crate) fn relay_roll_to(n: u64) { +pub(crate) fn relay_roll_to(n: BlockNumber) { while System::block_number() < n { XcmPallet::on_finalize(System::block_number()); Balances::on_finalize(System::block_number()); diff --git a/runtime/common/tests/xcm_tests.rs b/runtime/calamari/tests/xcm_tests.rs similarity index 73% rename from runtime/common/tests/xcm_tests.rs rename to runtime/calamari/tests/xcm_tests.rs index 541542f42..550da35af 100644 --- a/runtime/common/tests/xcm_tests.rs +++ b/runtime/calamari/tests/xcm_tests.rs @@ -21,12 +21,10 @@ mod xcm_mock; use codec::Encode; -use frame_support::{ - assert_err, assert_noop, assert_ok, weights::constants::WEIGHT_PER_SECOND, WeakBoundedVec, -}; +use frame_support::{assert_err, assert_noop, assert_ok, weights::constants::WEIGHT_PER_SECOND}; use manta_primitives::assets::AssetLocation; use xcm::{latest::prelude::*, v2::Response, VersionedMultiLocation, WrapVersion}; -use xcm_executor::traits::{Convert, WeightBounds}; +use xcm_executor::traits::WeightBounds; use xcm_mock::{parachain::PALLET_ASSET_INDEX, *}; use xcm_simulator::TestExt; @@ -47,7 +45,7 @@ fn calculate_fee(units_per_seconds: u128, weight: u64) -> u128 { units_per_seconds * (weight as u128) / (WEIGHT_PER_SECOND as u128) } -fn weight_of_four_xcm_instructions_on_para() -> u64 { +fn self_reserve_xtokens_weight_on_receiver() -> u64 { let mut msg = Xcm(vec![ ReserveAssetDeposited(MultiAssets::from(vec![MultiAsset { id: Concrete(MultiLocation { @@ -86,6 +84,45 @@ fn weight_of_four_xcm_instructions_on_para() -> u64 { ::Weigher::weight(&mut msg).unwrap() } +fn non_self_reserve_xtokens_weight_on_receiver() -> u64 { + let mut msg = Xcm(vec![ + WithdrawAsset(MultiAssets::from(vec![MultiAsset { + id: Concrete(MultiLocation { + parents: 1, + interior: X1(Parachain(1)), + }), + fun: Fungible(10000000000000), + }])), + ClearOrigin, + BuyExecution { + fees: MultiAsset { + id: Concrete(MultiLocation { + parents: 1, + interior: X1(Parachain(1)), + }), + fun: Fungible(10000000000000), + }, + weight_limit: Limited(3999999999), + }, + DepositAsset { + assets: Wild(All), + max_assets: 1, + beneficiary: MultiLocation { + parents: 0, + interior: X1(AccountId32 { + network: Any, + id: [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, + ], + }), + }, + }, + ]); + + ::Weigher::weight(&mut msg).unwrap() +} + // Helper function for forming buy execution message fn buy_execution(fees: impl Into) -> Instruction { BuyExecution { @@ -314,7 +351,7 @@ fn send_para_a_native_asset_to_para_b() { let para_b_source_location = create_asset_location(1, PARA_B_ID); let amount = INITIAL_BALANCE; - let weight = weight_of_four_xcm_instructions_on_para(); + let weight = self_reserve_xtokens_weight_on_receiver(); let para_a_asset_metadata = create_asset_metadata("ParaAToken", "ParaA", 18, 1, None, false, false); @@ -437,7 +474,7 @@ fn send_para_a_native_asset_to_para_b_barriers_should_work() { }; // AllowTopLevelPaidExecutionFrom should fail because weight is not enough - let weight = weight_of_four_xcm_instructions_on_para() - 1; + let weight = self_reserve_xtokens_weight_on_receiver() - 1; ParaA::execute_with(|| { assert_ok!(parachain::XTokens::transfer( parachain::Origin::signed(ALICE), @@ -481,7 +518,7 @@ fn send_insufficient_asset_from_para_a_to_para_b() { let amount = 8888888u128; let units_per_second_at_b = 1_250_000u128; - let dest_weight = weight_of_four_xcm_instructions_on_para(); + let dest_weight = self_reserve_xtokens_weight_on_receiver(); let fee_at_b = calculate_fee(units_per_second_at_b, dest_weight); let para_a_asset_metadata = @@ -648,7 +685,7 @@ fn send_para_a_native_asset_to_para_b_must_fail_cases() { }; // High amount should fail on the sender side - let weight = weight_of_four_xcm_instructions_on_para() * 100_000_000; + let weight = self_reserve_xtokens_weight_on_receiver() * 100_000_000; ParaA::execute_with(|| { assert_err!( parachain::XTokens::transfer( @@ -722,7 +759,7 @@ fn register_insufficient_with_zero_min_balance_should_fail() { #[test] fn send_para_a_custom_asset_to_para_b() { let amount = 321; - let weight_at_most = weight_of_four_xcm_instructions_on_para(); + let weight_at_most = self_reserve_xtokens_weight_on_receiver(); let para_a_source_location = create_asset_location(1, PARA_A_ID); let para_a_doge_location = AssetLocation(VersionedMultiLocation::V1(MultiLocation::new( @@ -825,7 +862,7 @@ fn send_para_a_native_asset_para_b_and_then_send_back() { let para_b_source_location = create_asset_location(1, PARA_B_ID); let amount = 5000000u128; - let weight = weight_of_four_xcm_instructions_on_para(); + let weight = non_self_reserve_xtokens_weight_on_receiver(); let fee_on_b_when_send_back = calculate_fee(ParaTokenPerSecond::get().1, weight); assert!(fee_on_b_when_send_back < amount); @@ -932,7 +969,7 @@ fn send_para_a_native_asset_from_para_b_to_para_c() { let para_c_source_location = create_asset_location(1, PARA_C_ID); let amount = 8888888u128; - let weight = weight_of_four_xcm_instructions_on_para(); + let weight = non_self_reserve_xtokens_weight_on_receiver(); let fee_at_reserve = calculate_fee(ParaTokenPerSecond::get().1, weight); assert!(amount >= fee_at_reserve * 2_u128); @@ -1124,7 +1161,7 @@ fn send_para_a_asset_to_para_b_with_trader_and_fee() { let amount = 222u128; let units_per_second = 1_250_000u128; - let dest_weight = weight_of_four_xcm_instructions_on_para(); + let dest_weight = self_reserve_xtokens_weight_on_receiver(); let fee = calculate_fee(units_per_second, dest_weight); let para_a_asset_metadata = @@ -1199,9 +1236,10 @@ fn send_para_a_asset_from_para_b_to_para_c_with_trader() { let mut amount = 8888888u128; let units_per_second = 1_250_000u128; - let dest_weight = weight_of_four_xcm_instructions_on_para(); - let fee_at_b = calculate_fee(units_per_second, dest_weight); - let fee_at_a = calculate_fee(ParaTokenPerSecond::get().1, dest_weight); + let dest_weight2 = self_reserve_xtokens_weight_on_receiver(); + let dest_weight1 = non_self_reserve_xtokens_weight_on_receiver(); + let fee_at_b = calculate_fee(units_per_second, dest_weight2); + let fee_at_a = calculate_fee(ParaTokenPerSecond::get().1, dest_weight1); let para_a_asset_metadata = create_asset_metadata("ParaAToken", "ParaA", 18, 1, None, false, true); @@ -1274,7 +1312,8 @@ fn send_para_a_asset_from_para_b_to_para_c_with_trader() { parachain::CurrencyId::MantaCurrency(a_asset_id_on_a), amount, Box::new(VersionedMultiLocation::V1(alice_on_b.clone())), - dest_weight + // dest_weight + 4_000_000_000 )); assert_eq!( parachain::Balances::free_balance(&ALICE), @@ -1307,7 +1346,8 @@ fn send_para_a_asset_from_para_b_to_para_c_with_trader() { parachain::CurrencyId::MantaCurrency(a_asset_id_on_b), amount, Box::new(VersionedMultiLocation::V1(alice_on_c)), - dest_weight + // dest_weight + 4_000_000_000 )); assert_eq!(parachain::Assets::balance(a_asset_id_on_b, &ALICE), 0); }); @@ -2066,7 +2106,7 @@ fn test_automatic_versioning_on_runtime_upgrade_with_para_b() { parachain::CurrencyId::MantaCurrency(a_asset_id_on_a), 100, Box::new(VersionedMultiLocation::V1(dest)), - weight_of_four_xcm_instructions_on_para() + self_reserve_xtokens_weight_on_receiver() )); // free execution, full amount received assert_eq!( @@ -2307,737 +2347,3 @@ fn filtered_multilocation_should_not_work() { )); }); } - -#[test] -fn less_than_min_xcm_fee_should_not_work() { - MockNet::reset(); - - let para_a_source_location = create_asset_location(1, PARA_A_ID); - let para_b_source_location = AssetLocation(VersionedMultiLocation::V1(MultiLocation::new( - 1, - X2( - Parachain(PARA_B_ID), - GeneralKey(WeakBoundedVec::force_from(b"ParaBToken".to_vec(), None)), - ), - ))); - let para_b_as_reserve_chain = create_asset_location(1, PARA_B_ID); - - let para_a_asset_metadata = - create_asset_metadata("ParaAToken", "ParaA", 18, 1, None, false, true); - let para_b_asset_metadata = - create_asset_metadata("ParaBToken", "ParaB", 18, 1, None, false, true); - - let relay_source_location = AssetLocation(VersionedMultiLocation::V1(MultiLocation::parent())); - let relay_asset_metadata = create_asset_metadata("Kusama", "KSM", 12, 1, None, false, true); - - let _ = register_assets_on_parachain::( - ¶_a_source_location, - ¶_a_asset_metadata, - Some(0u128), - None, - ); - let relay_asset_id_on_a = register_assets_on_parachain::( - &relay_source_location, - &relay_asset_metadata, - Some(0u128), - None, - ); - let b_asset_id_on_a = register_assets_on_parachain::( - ¶_b_source_location, - ¶_b_asset_metadata, - Some(0u128), - None, - ); - - let _ = register_assets_on_parachain::( - ¶_b_source_location, - ¶_b_asset_metadata, - Some(0u128), - None, - ); - let _ = register_assets_on_parachain::( - ¶_a_source_location, - ¶_a_asset_metadata, - Some(0u128), - None, - ); - let _ = register_assets_on_parachain::( - &relay_source_location, - &relay_asset_metadata, - Some(0u128), - None, - ); - - // Initialize some tokens for alice - assert_ok!(ParaA::execute_with(|| { - parachain::Assets::mint( - parachain::Origin::signed(parachain::AssetManager::account_id()), - b_asset_id_on_a, - ALICE, - 1000, - ) - })); - assert_ok!(ParaA::execute_with(|| { - parachain::Assets::mint( - parachain::Origin::signed(parachain::AssetManager::account_id()), - relay_asset_id_on_a, - ALICE, - 1000, - ) - })); - - let dest = MultiLocation { - parents: 1, - interior: X2( - Parachain(2), - AccountId32 { - network: NetworkId::Any, - id: ALICE.into(), - }, - ), - }; - - let amount = 450; - let fee_amount: u128 = 200; - // Minimum xcm execution fee paid on destination chain. - // Current only support `ToReserve` with relay-chain asset as fee. other case - // like `NonReserve` or `SelfReserve` with relay-chain fee is not support. - // And our `MaxAssetsForTransfer` for xtokens is 1, - // so `transfer_multicurrencies` is not supported on calamari. - // If min-xcm-fee is not set, no one can pay xcm fee(MinXcmFeeNotDefined). - ParaA::execute_with(|| { - assert_noop!( - parachain::XTokens::transfer_multicurrencies( - Some(ALICE).into(), - vec![ - ( - parachain::CurrencyId::MantaCurrency(b_asset_id_on_a), - amount - ), - ( - parachain::CurrencyId::MantaCurrency(relay_asset_id_on_a), - fee_amount - ) - ], - 1, - Box::new(VersionedMultiLocation::V1(dest.clone())), - 40, - ), - orml_xtokens::Error::::MinXcmFeeNotDefined - ); - }); - - // set min xcm fee on ParaA - let min_xcm_fee = 40; - ParaA::execute_with(|| { - assert_ok!(AssetManager::set_min_xcm_fee( - parachain::Origin::root(), - para_b_as_reserve_chain, - min_xcm_fee, - )); - }); - - // fee is bigger than min-xcm-fee should work(39 < 40). - ParaA::execute_with(|| { - assert_noop!( - parachain::XTokens::transfer_multicurrencies( - Some(ALICE).into(), - vec![ - ( - parachain::CurrencyId::MantaCurrency(b_asset_id_on_a), - amount - ), - ( - parachain::CurrencyId::MantaCurrency(relay_asset_id_on_a), - 39 - ) - ], - 1, - Box::new(VersionedMultiLocation::V1(dest.clone())), - 40, - ), - orml_xtokens::Error::::FeeNotEnough - ); - }); - - // fee is bigger than min-xcm-fee should work - ParaA::execute_with(|| { - assert_ok!(parachain::XTokens::transfer_multicurrencies( - Some(ALICE).into(), - vec![ - ( - parachain::CurrencyId::MantaCurrency(b_asset_id_on_a), - amount - ), - ( - parachain::CurrencyId::MantaCurrency(relay_asset_id_on_a), - fee_amount - ) - ], - 1, - Box::new(VersionedMultiLocation::V1(dest.clone())), - 40, - )); - }); -} - -#[test] -fn transfer_multicurrencies_should_work_scenarios() { - MockNet::reset(); - - let para_a_id = 1; - let para_b_id = 2; - let para_a_source_location = AssetLocation(VersionedMultiLocation::V1(MultiLocation::new( - 1, - X1(Parachain(para_a_id)), - ))); - let para_b_source_location = AssetLocation(VersionedMultiLocation::V1(MultiLocation::new( - 1, - X1(Parachain(para_b_id)), - ))); - let units_per_sec = 0; - - let para_a_asset_metadata = - create_asset_metadata("ParaAToken", "ParaA", 18, 1, None, false, true); - let para_b_asset_metadata = - create_asset_metadata("ParaBToken", "ParaB", 18, 1, None, false, true); - - let relay_source_location = AssetLocation(VersionedMultiLocation::V1(MultiLocation::parent())); - let relay_asset_metadata = create_asset_metadata("Kusama", "KSM", 12, 1, None, false, true); - - let _ = register_assets_on_parachain::( - ¶_a_source_location, - ¶_a_asset_metadata, - Some(units_per_sec), - None, - ); - let relay_asset_id_on_a = register_assets_on_parachain::( - &relay_source_location, - &relay_asset_metadata, - Some(units_per_sec), - None, - ); - let b_asset_id_on_a = register_assets_on_parachain::( - ¶_b_source_location, - ¶_b_asset_metadata, - Some(units_per_sec), - None, - ); - - let b_asset_id_on_b = register_assets_on_parachain::( - ¶_b_source_location, - ¶_b_asset_metadata, - Some(units_per_sec), - None, - ); - let _ = register_assets_on_parachain::( - ¶_a_source_location, - ¶_a_asset_metadata, - Some(units_per_sec), - None, - ); - let relay_asset_id_on_b = register_assets_on_parachain::( - &relay_source_location, - &relay_asset_metadata, - Some(units_per_sec), - None, - ); - - let relay_asset_amount_minted_on_a = 10000000; - // Initialize some relay chain tokens for alice - assert_ok!(ParaA::execute_with(|| { - parachain::Assets::mint( - parachain::Origin::signed(parachain::AssetManager::account_id()), - relay_asset_id_on_a, - ALICE, - relay_asset_amount_minted_on_a, - ) - })); - - let dest = MultiLocation { - parents: 1, - interior: X2( - Parachain(para_a_id), - AccountId32 { - network: NetworkId::Any, - id: ALICE.into(), - }, - ), - }; - - // Send some ParaB tokens from Alice on B to Alice on A - let amount_to_a = 10000000; - let weight = weight_of_four_xcm_instructions_on_para(); - ParaB::execute_with(|| { - assert_ok!(parachain::XTokens::transfer( - Some(ALICE).into(), - parachain::CurrencyId::MantaCurrency(b_asset_id_on_b), - amount_to_a, - Box::new(VersionedMultiLocation::V1(dest.clone())), - weight, - )); - }); - - let dest = MultiLocation { - parents: 1, - interior: X2( - Parachain(para_b_id), - AccountId32 { - network: NetworkId::Any, - id: ALICE.into(), - }, - ), - }; - - let amount_back_to_b = 100; - let fee_amount: u128 = 50; - let min_xcm_fee = 10; - // Send some ParaB tokens from Alice on A back to Alice on B - ParaA::execute_with(|| { - assert_ok!(AssetManager::set_min_xcm_fee( - parachain::Origin::root(), - para_b_source_location, - min_xcm_fee, - )); - - assert_ok!(parachain::XTokens::transfer_multicurrencies( - Some(ALICE).into(), - vec![ - ( - parachain::CurrencyId::MantaCurrency(b_asset_id_on_a), - amount_back_to_b - ), - ( - parachain::CurrencyId::MantaCurrency(relay_asset_id_on_a), - fee_amount - ) - ], - 1, - Box::new(VersionedMultiLocation::V1(dest.clone())), - weight, - )); - - assert_eq!( - parachain::Assets::balance(relay_asset_id_on_a, &ALICE), - relay_asset_amount_minted_on_a - fee_amount - ); - assert_eq!( - // Notice that total supply between the two chains is: - // `(relay_asset_amount_minted_on_a - fee_amount) + (fee_amount - min_xcm_fee)` - // `relay_asset_amount_minted_on_a - fee_amount` is still on ParaA - // `fee_amount - min_xcm_fee` is on ParaB. (min_xcm_fee is subtracted in the ORML code) - // The total comes out to `relay_asset_amount_minted_on_a - min_xcm_fee`, meaning one `min_xcm_fee` is destroyed - // This is a design choice by ORML to make these kinds of transfers possible. - // Practically some of tokens held as reserve on the reserve chain, will become unwithdrawable. - parachain::Assets::total_supply(relay_asset_id_on_a), - relay_asset_amount_minted_on_a - fee_amount - ); - - assert_eq!( - parachain::Assets::balance(b_asset_id_on_a, &ALICE), - amount_to_a - amount_back_to_b - ); - }); - - Relay::execute_with(|| { - let para_a_sovereign_on_relay = para_account_id(1); - let para_b_sovereign_on_relay = para_account_id(2); - assert_eq!( - relay_chain::Balances::free_balance(¶_a_sovereign_on_relay), - INITIAL_BALANCE - (fee_amount - min_xcm_fee) - ); - assert_eq!( - relay_chain::Balances::free_balance(¶_b_sovereign_on_relay), - // 0 because transfer_multicurrencies uses a Teleport for this case - 0 - ); - }); - - ParaB::execute_with(|| { - assert_eq!( - parachain::Balances::free_balance(&ALICE), - // because transfer_multicurrencies uses a Teleport for this case - // we no longer expect the amount_back_to_b to be in the sovereign account - INITIAL_BALANCE - amount_to_a - ); - - // Parachain A sovereign account on Parachain B should receive: 0 - // because transfer_multicurrencies uses Teleport in this case - let para_a_sovereign_on_para_b = parachain::LocationToAccountId::convert_ref( - MultiLocation::new(1, X1(Parachain(para_a_id))), - ) - .unwrap(); - assert_eq!( - parachain::Assets::balance(relay_asset_id_on_b, ¶_a_sovereign_on_para_b), - 0 - ); - - assert_eq!( - // min_xcm_fee will be just enough to pay for execution so - // no change from BuyExecution will be deposited in Alice's account. - parachain::Assets::balance(relay_asset_id_on_b, &ALICE), - 0 - ); - assert_eq!( - parachain::Assets::total_supply(relay_asset_id_on_b), - // Since all of the fee is used the total supply should be 0 - 0 - ); - }); -} - -/// Checks only must-fail cases related to transfer_multicurrencies -/// First part is for testing cases on the sender side. -/// Second part is for testing cases on the receiver side. -#[test] -fn transfer_multicurrencies_should_fail_scenarios() { - MockNet::reset(); - - let para_a_id = 1; - let para_b_id = 2; - let para_c_id = 3; - let para_a_source_location = create_asset_location(1, para_a_id); - let para_b_source_location = create_asset_location(1, para_b_id); - let para_c_source_location = create_asset_location(1, para_c_id); - - let para_a_asset_metadata = - create_asset_metadata("ParaAToken", "ParaA", 18, 1, None, false, true); - let para_b_asset_metadata = - create_asset_metadata("ParaBToken", "ParaB", 18, 1, None, false, true); - let para_c_asset_metadata = - create_asset_metadata("ParaCToken", "ParaC", 18, 1, None, false, true); - - let relay_source_location = AssetLocation(VersionedMultiLocation::V1(MultiLocation::parent())); - let relay_asset_metadata = create_asset_metadata("Kusama", "KSM", 12, 1, None, false, true); - let units_per_sec = 0; - - let a_asset_id_on_a = register_assets_on_parachain::( - ¶_a_source_location, - ¶_a_asset_metadata, - Some(units_per_sec), - None, - ); - let relay_asset_id_on_a = register_assets_on_parachain::( - &relay_source_location, - &relay_asset_metadata, - Some(units_per_sec), - None, - ); - let b_asset_id_on_a = register_assets_on_parachain::( - ¶_b_source_location, - ¶_b_asset_metadata, - Some(units_per_sec), - None, - ); - let c_asset_id_on_a = register_assets_on_parachain::( - ¶_c_source_location, - ¶_c_asset_metadata, - Some(units_per_sec), - None, - ); - - let b_asset_id_on_b = register_assets_on_parachain::( - ¶_b_source_location, - ¶_b_asset_metadata, - Some(units_per_sec), - None, - ); - let _ = register_assets_on_parachain::( - ¶_a_source_location, - ¶_a_asset_metadata, - Some(units_per_sec), - None, - ); - let relay_asset_id_on_b = register_assets_on_parachain::( - &relay_source_location, - &relay_asset_metadata, - Some(units_per_sec), - None, - ); - - let c_asset_id_on_c = register_assets_on_parachain::( - ¶_c_source_location, - ¶_c_asset_metadata, - Some(units_per_sec), - None, - ); - let _ = register_assets_on_parachain::( - ¶_a_source_location, - ¶_a_asset_metadata, - Some(units_per_sec), - None, - ); - let _ = register_assets_on_parachain::( - &relay_source_location, - &relay_asset_metadata, - Some(units_per_sec), - None, - ); - - let amount = 1000; - let weight = weight_of_four_xcm_instructions_on_para(); - assert_ok!(ParaA::execute_with(|| { - parachain::Assets::mint( - parachain::Origin::signed(parachain::AssetManager::account_id()), - relay_asset_id_on_a, - ALICE, - amount, - ) - })); - - let dest = MultiLocation { - parents: 1, - interior: X2( - Parachain(para_a_id), - AccountId32 { - network: NetworkId::Any, - id: ALICE.into(), - }, - ), - }; - ParaC::execute_with(|| { - assert_ok!(parachain::XTokens::transfer( - Some(ALICE).into(), - parachain::CurrencyId::MantaCurrency(c_asset_id_on_c), - amount, - Box::new(VersionedMultiLocation::V1(dest.clone())), - weight, - )); - }); - ParaB::execute_with(|| { - assert_ok!(parachain::XTokens::transfer( - Some(ALICE).into(), - parachain::CurrencyId::MantaCurrency(b_asset_id_on_b), - amount, - Box::new(VersionedMultiLocation::V1(dest)), - weight, - )); - }); - - let dest = MultiLocation { - parents: 1, - interior: X2( - Parachain(para_b_id), - AccountId32 { - network: NetworkId::Any, - id: ALICE.into(), - }, - ), - }; - - // Sender Side Tests: - - let fee_amount: u128 = 50; - let min_xcm_fee = 10; - ParaA::execute_with(|| { - assert_ok!(AssetManager::set_min_xcm_fee( - parachain::Origin::root(), - para_b_source_location.clone(), - min_xcm_fee, - )); - assert_ok!(AssetManager::set_min_xcm_fee( - parachain::Origin::root(), - para_c_source_location, - min_xcm_fee, - )); - - assert_err!( - parachain::XTokens::transfer_multicurrencies( - Some(ALICE).into(), - vec![ - ( - parachain::CurrencyId::MantaCurrency(b_asset_id_on_a), - amount - ), - ( - parachain::CurrencyId::MantaCurrency(c_asset_id_on_a), - fee_amount - ), - ( - parachain::CurrencyId::MantaCurrency(relay_asset_id_on_a), - fee_amount - ) - ], - 2, - Box::new(VersionedMultiLocation::V1(dest.clone())), - weight, - ), - // Assets and fee must have the same reserve - orml_xtokens::Error::::DistinctReserveForAssetAndFee - ); - - assert_err!( - parachain::XTokens::transfer_multicurrencies( - Some(ALICE).into(), - vec![ - ( - parachain::CurrencyId::MantaCurrency(b_asset_id_on_a), - amount - ), - ( - parachain::CurrencyId::MantaCurrency(relay_asset_id_on_a), - fee_amount - ), - ( - parachain::CurrencyId::MantaCurrency(c_asset_id_on_a), - fee_amount - ), - ( - parachain::CurrencyId::MantaCurrency(a_asset_id_on_a), - fee_amount - ) - ], - 2, - Box::new(VersionedMultiLocation::V1(dest.clone())), - weight, - ), - // MaxAssetsForTransfer is set to 3 in the mock - orml_xtokens::Error::::TooManyAssetsBeingSent - ); - - assert_err!( - parachain::XTokens::transfer_multicurrencies( - Some(ALICE).into(), - vec![ - ( - parachain::CurrencyId::MantaCurrency(b_asset_id_on_a), - amount - ), - ( - parachain::CurrencyId::MantaCurrency(relay_asset_id_on_a), - fee_amount - ) - ], - 2, - Box::new(VersionedMultiLocation::V1(dest.clone())), - weight, - ), - orml_xtokens::Error::::AssetIndexNonExistent - ); - - assert_err!( - parachain::XTokens::transfer_multicurrencies( - Some(ALICE).into(), - vec![ - ( - parachain::CurrencyId::MantaCurrency(b_asset_id_on_a), - amount - ), - (parachain::CurrencyId::MantaCurrency(relay_asset_id_on_a), 0) - ], - 1, - Box::new(VersionedMultiLocation::V1(dest.clone())), - weight, - ), - // 0 fees should not work - orml_xtokens::Error::::ZeroAmount - ); - - assert_err!( - parachain::XTokens::transfer_multicurrencies( - Some(ALICE).into(), - vec![ - (parachain::CurrencyId::MantaCurrency(b_asset_id_on_a), 0), - ( - parachain::CurrencyId::MantaCurrency(relay_asset_id_on_a), - fee_amount - ) - ], - 1, - Box::new(VersionedMultiLocation::V1(dest.clone())), - weight, - ), - // 0 assets should not work - orml_xtokens::Error::::ZeroAmount - ); - }); - - // Receiver Side Tests: - - let amount_back_to_b = 100; - let fee_amount: u128 = 50; - let min_xcm_fee = 40; - // Setup to succeed on the sender side, but fail on the receiver side due to not enough fees. - ParaA::execute_with(|| { - assert_ok!(AssetManager::set_min_xcm_fee( - parachain::Origin::root(), - para_b_source_location, - min_xcm_fee, - )); - - assert_eq!(parachain::Assets::balance(b_asset_id_on_a, &ALICE), amount); - assert_eq!( - parachain::Assets::balance(relay_asset_id_on_a, &ALICE), - amount - ); - - assert_ok!(parachain::XTokens::transfer_multicurrencies( - Some(ALICE).into(), - vec![ - ( - parachain::CurrencyId::MantaCurrency(b_asset_id_on_a), - amount_back_to_b - ), - ( - parachain::CurrencyId::MantaCurrency(relay_asset_id_on_a), - fee_amount - ) - ], - 1, - Box::new(VersionedMultiLocation::V1(dest.clone())), - weight, - )); - - assert_eq!( - parachain::Assets::balance(relay_asset_id_on_a, &ALICE), - amount - fee_amount - ); - - assert_eq!( - parachain::Assets::balance(b_asset_id_on_a, &ALICE), - amount - amount_back_to_b - ); - }); - - Relay::execute_with(|| { - let para_a_sovereign_on_relay = para_account_id(1); - let para_b_sovereign_on_relay = para_account_id(2); - assert_eq!( - relay_chain::Balances::free_balance(¶_a_sovereign_on_relay), - INITIAL_BALANCE - (fee_amount - min_xcm_fee) - ); - assert_eq!( - relay_chain::Balances::free_balance(¶_b_sovereign_on_relay), - // 0 because transfer_multicurrencies uses a Teleport for this case - 0 - ); - }); - - ParaB::execute_with(|| { - // Parachain A sovereign account on Parachain B should receive: 0 - // because transfer_multicurrencies uses Teleport in this case - let para_a_sovereign_on_para_b = parachain::LocationToAccountId::convert_ref( - MultiLocation::new(1, X1(Parachain(para_a_id))), - ) - .unwrap(); - assert_eq!( - parachain::Assets::balance(relay_asset_id_on_b, ¶_a_sovereign_on_para_b), - 0 - ); - - assert_eq!( - // The BuyExecution failed so no change to deposit in Alice's account. - parachain::Assets::balance(relay_asset_id_on_b, &ALICE), - 0 - ); - // Since BuyExecution failed so no change to deposit in Alice's account - // the total_supply will remain 0. - assert_eq!(parachain::Assets::total_supply(relay_asset_id_on_b), 0); - - assert_eq!( - parachain::Balances::free_balance(&ALICE), - // Did not receive amount_back_to_b, because there was not enough of the relay fee - INITIAL_BALANCE - amount - ); - }); -} diff --git a/runtime/common/Cargo.toml b/runtime/common/Cargo.toml index 2d3c6971a..0876f0992 100644 --- a/runtime/common/Cargo.toml +++ b/runtime/common/Cargo.toml @@ -18,44 +18,7 @@ sp-std = { git = 'https://github.com/paritytech/substrate.git', branch = "polkad manta-primitives = { path = '../../primitives/manta', default-features = false } [dev-dependencies] -# 3rd dependencies -codec = { package = "parity-scale-codec", version = "3.1.2" } -scale-info = { version = "2.1.2", features = ["derive"] } - -# Substrate dependencies -frame-system = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.26" } -pallet-assets = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.26" } -pallet-balances = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.26" } -pallet-utility = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.26" } -sp-core = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.26" } sp-io = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.26" } -sp-std = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.26" } - -# Polkadot dependencies -pallet-xcm = { git = 'https://github.com/paritytech/polkadot.git', branch = "release-v0.9.26" } -polkadot-core-primitives = { git = 'https://github.com/paritytech/polkadot.git', branch = "release-v0.9.26" } -polkadot-parachain = { git = 'https://github.com/paritytech/polkadot.git', branch = "release-v0.9.26" } -polkadot-runtime-parachains = { git = 'https://github.com/paritytech/polkadot.git', branch = "release-v0.9.26" } -xcm = { git = 'https://github.com/paritytech/polkadot.git', branch = "release-v0.9.26" } -xcm-builder = { git = 'https://github.com/paritytech/polkadot.git', branch = "release-v0.9.26" } -xcm-executor = { git = 'https://github.com/paritytech/polkadot.git', branch = "release-v0.9.26" } -xcm-simulator = { git = 'https://github.com/paritytech/polkadot.git', branch = "release-v0.9.26" } - -# Cumulus dependencies -cumulus-pallet-dmp-queue = { git = 'https://github.com/paritytech/cumulus.git', branch = "polkadot-v0.9.26" } -cumulus-pallet-parachain-system = { git = 'https://github.com/paritytech/cumulus.git', branch = "polkadot-v0.9.26" } -cumulus-pallet-xcm = { git = 'https://github.com/paritytech/cumulus.git', branch = "polkadot-v0.9.26" } -cumulus-pallet-xcmp-queue = { git = 'https://github.com/paritytech/cumulus.git', branch = "polkadot-v0.9.26" } -cumulus-primitives-parachain-inherent = { git = "https://github.com/paritytech/cumulus.git", branch = "polkadot-v0.9.26" } -cumulus-test-relay-sproof-builder = { git = "https://github.com/paritytech/cumulus.git", branch = "polkadot-v0.9.26" } -parachain-info = { git = 'https://github.com/paritytech/cumulus.git', branch = "polkadot-v0.9.26" } - -# Orml dependencies -orml-traits = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "polkadot-v0.9.26" } -orml-xtokens = { git = "https://github.com/manta-network/open-runtime-module-library.git", branch = "polkadot-v0.9.26" } - -# Self dependencies -pallet-asset-manager = { path = '../../pallets/asset-manager' } [features] default = ["std"]