diff --git a/.github/workflows/try-runtime.yml b/.github/workflows/try-runtime.yml deleted file mode 100644 index d0f066cfb..000000000 --- a/.github/workflows/try-runtime.yml +++ /dev/null @@ -1,54 +0,0 @@ -name: Try Runtime - -# Controls when the action will run. -on: - # Triggers the workflow on push or pull request events but only for the master branch - push: - branches: [master] - pull_request: - branches: [master] - - # Allows you to run this workflow manually from the Actions tab - workflow_dispatch: - -# A workflow run is made up of one or more jobs that can run sequentially or in parallel -jobs: - check: - if: github.repository == 'parallel-finance/parallel' - name: Auto Try Runtime Upgrade - runs-on: ${{ matrix.os }} - strategy: - matrix: - os: [ubuntu-latest] - rust: [nightly-2021-11-07] - - # Steps represent a sequence of tasks that will be executed as part of the job - steps: - # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - - name: Checkout Repository - uses: actions/checkout@v2 - with: - submodules: true - - - name: Install Rust toolchain ${{ matrix.rust }} - uses: actions-rs/toolchain@v1 - with: - profile: minimal - toolchain: ${{ matrix.rust }} - components: rustfmt, clippy - override: true - - - name: Install wasm32-unknown-unknown for ${{ matrix.rust }} - uses: actions-rs/toolchain@v1 - with: - toolchain: ${{ matrix.rust }} - target: wasm32-unknown-unknown - override: true - - - name: Create snapshot - run: | - make BLOCK_AT=0x05928f1bff29327eab9b0ec65b3a23437d141520ce1bd3205e4f963d8a455efd URL=wss://testnet-rpc.parallel.fi CHAIN=vanilla-dev snapshot - - - name: Try runtime upgrade - run: | - make CHAIN=vanilla-dev try-runtime-upgrade diff --git a/launch/index.ts b/launch/index.ts index 2d0490ffe..0eaace9ea 100644 --- a/launch/index.ts +++ b/launch/index.ts @@ -120,6 +120,7 @@ async function para() { const keyring = new Keyring({ type: 'sr25519', ss58Format: 110 }) const signer = keyring.addFromUri('//Dave') const call = [] + const height = await chainHeight(api) for (const { name, symbol, assetId, decimal, marketOption, balances } of config.assets) { console.log(`Create ${name}(${symbol}) asset, ptokenId is ${marketOption.ptokenId}`) @@ -132,8 +133,8 @@ async function para() { call.push(...balances.map(([account, amount]) => api.tx.assets.mint(assetId, account, amount))) } - for (const { paraId, image, chain, ctokenId, pending } of config.crowdloans) { - call.push(api.tx.sudo.sudo(api.tx.crowdloans.createVault(paraId, ctokenId, 'XCM'))) + for (const { paraId, image, chain, ctokenId, cap, duration, pending } of config.crowdloans) { + call.push(api.tx.sudo.sudo(api.tx.crowdloans.createVault(paraId, ctokenId, 'XCM', cap, height + duration))) if (!pending) { call.push(api.tx.sudo.sudo(api.tx.crowdloans.open(paraId))) } diff --git a/pallets/crowdloans/src/benchmarking.rs b/pallets/crowdloans/src/benchmarking.rs index 183f04946..ade5aa44e 100644 --- a/pallets/crowdloans/src/benchmarking.rs +++ b/pallets/crowdloans/src/benchmarking.rs @@ -30,6 +30,9 @@ const XCM_WEIGHT: XcmWeightMisc = XcmWeightMisc { const CONTRIBUTE_AMOUNT: u128 = 20000000000000u128; const INITIAL_RESERVES: u128 = 1000000000000000u128; const INITIAL_AMOUNT: u128 = 1000000000000000u128; +const LARGE_CAP: u128 = 1_000_000_000_000_000u128; +const CAP: u128 = 1_000_000_000_000_000u128; +const END_BLOCK: u32 = 1_000_000_000u32; fn assert_last_event(generic_event: ::Event) { frame_system::Pallet::::assert_last_event(generic_event.into()); @@ -92,24 +95,46 @@ benchmarks! { create_vault { let ctoken = 8; let caller: T::AccountId = whitelisted_caller(); - let crowdloan = ParaId::from(1334); + let crowdloan = ParaId::from(1334u32); + initial_set_up::(caller, ctoken); }: _( SystemOrigin::Root, crowdloan, ctoken, - ContributionStrategy::XCM + ContributionStrategy::XCM, + CAP, + END_BLOCK ) verify { assert_last_event::(Event::::VaultCreated(crowdloan, ctoken).into()) } + update_vault { + let ctoken = 8; + let crowdloan = ParaId::from(1334u32); + let caller: T::AccountId = whitelisted_caller(); + initial_set_up::(caller, ctoken); + // create vault before update + assert_ok!(Crowdloans::::create_vault(SystemOrigin::Root.into(), crowdloan, ctoken, ContributionStrategy::XCM, CAP, END_BLOCK)); + }: _( + SystemOrigin::Root, + crowdloan, + Some(1_000_000_000_001), + Some(1_000_000_001u32), + Some(ContributionStrategy::XCM) + ) + verify { + assert_last_event::(Event::::VaultUpdated(crowdloan).into()) + } + contribute { let ctoken = 9; let caller: T::AccountId = whitelisted_caller(); - let crowdloan = ParaId::from(1335); + let crowdloan = ParaId::from(1335u32); + initial_set_up::(caller.clone(), ctoken); - assert_ok!(Crowdloans::::create_vault(SystemOrigin::Root.into(), crowdloan, ctoken, ContributionStrategy::XCM)); + assert_ok!(Crowdloans::::create_vault(SystemOrigin::Root.into(), crowdloan, ctoken, ContributionStrategy::XCM, CAP, END_BLOCK)); assert_ok!(Crowdloans::::open(SystemOrigin::Root.into(), crowdloan)); }: _( SystemOrigin::Signed(caller.clone()), @@ -124,9 +149,10 @@ benchmarks! { open { let ctoken = 10; let caller: T::AccountId = whitelisted_caller(); - let crowdloan = ParaId::from(1336); + let crowdloan = ParaId::from(1336u32); + initial_set_up::(caller, ctoken); - assert_ok!(Crowdloans::::create_vault(SystemOrigin::Root.into(), crowdloan, ctoken, ContributionStrategy::XCM)); + assert_ok!(Crowdloans::::create_vault(SystemOrigin::Root.into(), crowdloan, ctoken, ContributionStrategy::XCM, CAP, END_BLOCK)); }: _( SystemOrigin::Root, crowdloan @@ -138,9 +164,10 @@ benchmarks! { close { let ctoken = 11; let caller: T::AccountId = whitelisted_caller(); - let crowdloan = ParaId::from(1337); + let crowdloan = ParaId::from(1337u32); + initial_set_up::(caller, ctoken); - assert_ok!(Crowdloans::::create_vault(SystemOrigin::Root.into(), crowdloan, ctoken, ContributionStrategy::XCM)); + assert_ok!(Crowdloans::::create_vault(SystemOrigin::Root.into(), crowdloan, ctoken, ContributionStrategy::XCM, CAP, END_BLOCK)); assert_ok!(Crowdloans::::open(SystemOrigin::Root.into(), crowdloan)); }: _( SystemOrigin::Root, @@ -153,9 +180,10 @@ benchmarks! { set_vrfs { let ctoken = 12; let caller: T::AccountId = whitelisted_caller(); - let crowdloan = ParaId::from(1338); + let crowdloan = ParaId::from(1338u32); + initial_set_up::(caller, ctoken); - assert_ok!(Crowdloans::::create_vault(SystemOrigin::Root.into(), crowdloan, ctoken, ContributionStrategy::XCM)); + assert_ok!(Crowdloans::::create_vault(SystemOrigin::Root.into(), crowdloan, ctoken, ContributionStrategy::XCM, CAP, END_BLOCK)); }: _( SystemOrigin::Root, vec![ParaId::from(1336u32), ParaId::from(1337u32)] @@ -168,9 +196,10 @@ benchmarks! { reopen { let ctoken = 13; let caller: T::AccountId = whitelisted_caller(); - let crowdloan = ParaId::from(1339); + let crowdloan = ParaId::from(1339u32); + initial_set_up::(caller, ctoken); - assert_ok!(Crowdloans::::create_vault(SystemOrigin::Root.into(), crowdloan, ctoken, ContributionStrategy::XCM)); + assert_ok!(Crowdloans::::create_vault(SystemOrigin::Root.into(), crowdloan, ctoken, ContributionStrategy::XCM, CAP, END_BLOCK)); assert_ok!(Crowdloans::::open(SystemOrigin::Root.into(), crowdloan)); assert_ok!(Crowdloans::::close(SystemOrigin::Root.into(), crowdloan)); }: _( @@ -184,9 +213,10 @@ benchmarks! { auction_failed { let ctoken = 14; let caller: T::AccountId = whitelisted_caller(); - let crowdloan = ParaId::from(1340); + let crowdloan = ParaId::from(1340u32); + initial_set_up::(caller.clone(), ctoken); - assert_ok!(Crowdloans::::create_vault(SystemOrigin::Root.into(), crowdloan, ctoken, ContributionStrategy::XCM)); + assert_ok!(Crowdloans::::create_vault(SystemOrigin::Root.into(), crowdloan, ctoken, ContributionStrategy::XCM, LARGE_CAP, END_BLOCK)); assert_ok!(Crowdloans::::open(SystemOrigin::Root.into(), crowdloan)); assert_ok!(Crowdloans::::contribute(SystemOrigin::Signed(caller).into(), crowdloan, CONTRIBUTE_AMOUNT, Vec::new())); assert_ok!(Crowdloans::::close(SystemOrigin::Root.into(), crowdloan)); @@ -202,9 +232,10 @@ benchmarks! { claim_refund { let ctoken = 15; let caller: T::AccountId = whitelisted_caller(); - let crowdloan = ParaId::from(1341); + let crowdloan = ParaId::from(1341u32); + initial_set_up::(caller.clone(), ctoken); - assert_ok!(Crowdloans::::create_vault(SystemOrigin::Root.into(), crowdloan, ctoken, ContributionStrategy::XCM)); + assert_ok!(Crowdloans::::create_vault(SystemOrigin::Root.into(), crowdloan, ctoken, ContributionStrategy::XCM, LARGE_CAP, END_BLOCK)); assert_ok!(Crowdloans::::open(SystemOrigin::Root.into(), crowdloan)); assert_ok!(Crowdloans::::contribute(SystemOrigin::Signed(caller.clone()).into(), crowdloan, CONTRIBUTE_AMOUNT, Vec::new())); assert_ok!(Crowdloans::::notification_received( @@ -231,9 +262,10 @@ benchmarks! { slot_expired { let ctoken = 16; let caller: T::AccountId = whitelisted_caller(); - let crowdloan = ParaId::from(1342); + let crowdloan = ParaId::from(1342u32); + initial_set_up::(caller.clone(), ctoken); - assert_ok!(Crowdloans::::create_vault(SystemOrigin::Root.into(), crowdloan, ctoken, ContributionStrategy::XCM)); + assert_ok!(Crowdloans::::create_vault(SystemOrigin::Root.into(), crowdloan, ctoken, ContributionStrategy::XCM, LARGE_CAP, END_BLOCK)); assert_ok!(Crowdloans::::open(SystemOrigin::Root.into(), crowdloan)); assert_ok!(Crowdloans::::contribute(SystemOrigin::Signed(caller).into(), crowdloan, CONTRIBUTE_AMOUNT, Vec::new())); assert_ok!(Crowdloans::::close(SystemOrigin::Root.into(), crowdloan)); @@ -248,9 +280,10 @@ benchmarks! { migrate_pending { let ctoken = 17; let caller: T::AccountId = whitelisted_caller(); - let crowdloan = ParaId::from(1343); + let crowdloan = ParaId::from(1343u32); + initial_set_up::(caller.clone(), ctoken); - assert_ok!(Crowdloans::::create_vault(SystemOrigin::Root.into(), crowdloan, ctoken, ContributionStrategy::XCM)); + assert_ok!(Crowdloans::::create_vault(SystemOrigin::Root.into(), crowdloan, ctoken, ContributionStrategy::XCM, LARGE_CAP, END_BLOCK)); for _ in 0..10 { assert_ok!(Crowdloans::::contribute(SystemOrigin::Signed(caller.clone()).into(), crowdloan, CONTRIBUTE_AMOUNT, Vec::new())); } @@ -265,9 +298,10 @@ benchmarks! { notification_received { let ctoken = 18; let caller: T::AccountId = whitelisted_caller(); - let crowdloan = ParaId::from(1344); + let crowdloan = ParaId::from(1344u32); + initial_set_up::(caller.clone(), ctoken); - assert_ok!(Crowdloans::::create_vault(SystemOrigin::Root.into(), crowdloan, ctoken, ContributionStrategy::XCM)); + assert_ok!(Crowdloans::::create_vault(SystemOrigin::Root.into(), crowdloan, ctoken, ContributionStrategy::XCM, LARGE_CAP, END_BLOCK)); assert_ok!(Crowdloans::::open(SystemOrigin::Root.into(), crowdloan)); assert_ok!(Crowdloans::::contribute(SystemOrigin::Signed(caller).into(), crowdloan, CONTRIBUTE_AMOUNT, Vec::new())); }: _( diff --git a/pallets/crowdloans/src/lib.rs b/pallets/crowdloans/src/lib.rs index 6c98d945f..47f00b258 100644 --- a/pallets/crowdloans/src/lib.rs +++ b/pallets/crowdloans/src/lib.rs @@ -50,9 +50,9 @@ pub mod pallet { }; use frame_system::{ensure_signed, pallet_prelude::OriginFor}; use pallet_xcm::ensure_response; - use primitives::{ump::*, Balance, CurrencyId, ParaId, TrieIndex}; + use primitives::{ump::*, Balance, BlockNumber, CurrencyId, ParaId, TrieIndex}; use sp_runtime::{ - traits::{AccountIdConversion, Convert, Hash, Zero}, + traits::{AccountIdConversion, BlockNumberProvider, Convert, Hash, Zero}, ArithmeticError, DispatchError, }; use sp_std::{boxed::Box, convert::TryInto, vec::Vec}; @@ -127,6 +127,9 @@ pub mod pallet { /// The origin which can create vault type CreateVaultOrigin: EnsureOrigin<::Origin>; + /// The origin which can update vault + type UpdateVaultOrigin: EnsureOrigin<::Origin>; + /// The origin which can close/reopen vault type OpenCloseOrigin: EnsureOrigin<::Origin>; @@ -139,6 +142,11 @@ pub mod pallet { /// Weight information type WeightInfo: WeightInfo; + /// The relay's BlockNumber provider + type RelayChainBlockNumberProvider: BlockNumberProvider< + BlockNumber = primitives::BlockNumber, + >; + /// To expose XCM helper functions type XCM: XcmHelper, AssetIdOf, Self::AccountId>; } @@ -148,6 +156,8 @@ pub mod pallet { pub enum Event { /// New vault was created VaultCreated(ParaId, AssetIdOf), + /// Existing vault was updated + VaultUpdated(ParaId), /// User is contributing amount to vault VaultContributing(ParaId, T::AccountId, BalanceOf, Vec), /// Vault was opened @@ -194,6 +204,10 @@ pub mod pallet { ParaIdAlreadyTaken, /// No contributions allowed during the VRF delay VrfDelayInProgress, + /// Attempted contribution violates contribution cap + ExceededCap, + /// Current relay block is greater then vault end block + ExceededEndBlock, /// Exceeded maximum vrfs ExceededMaxVrfs, /// Pending contribution must be killed before entering `Contributing` vault phase @@ -238,6 +252,8 @@ pub mod pallet { crowdloan: ParaId, ctoken: AssetIdOf, contribution_strategy: ContributionStrategy, + #[pallet::compact] cap: BalanceOf, + end_block: BlockNumber, ) -> DispatchResult { T::CreateVaultOrigin::ensure_origin(origin)?; @@ -247,6 +263,7 @@ pub mod pallet { Error::::CTokenAlreadyTaken ); + // users shouldn't be able to create a new vault if the previous one is not finished if let Some(vault) = Self::current_vault(crowdloan) { if vault.phase != VaultPhase::Failed && vault.phase != VaultPhase::Expired { return Err(DispatchError::from(Error::::ParaIdAlreadyTaken)); @@ -259,21 +276,33 @@ pub mod pallet { Error::::CrowdloanAlreadyExists ); + ensure!( + T::RelayChainBlockNumberProvider::current_block_number() <= end_block, + Error::::ExceededEndBlock + ); + let trie_index = Self::next_trie_index(); let next_trie_index = trie_index.checked_add(1).ok_or(ArithmeticError::Overflow)?; - let new_vault = Vault::new(next_index, ctoken, contribution_strategy, trie_index); + let new_vault = Vault::new( + next_index, + ctoken, + contribution_strategy, + cap, + end_block, + trie_index, + ); log::trace!( target: "crowdloans::create_vault", - "ctoken_issuance: {:?}, next_index: {:?}, trie_index: {:?}, ctoken: {:?}", + "ctoken_issuance: {:?}, next_index: {:?}, trie_index: {:?}, ctoken: {:?}, trie_index: {:?}", ctoken_issuance, next_index, trie_index, ctoken, + trie_index, ); NextTrieIndex::::put(next_trie_index); - Vaults::::insert(crowdloan, next_index, new_vault); CTokensRegistry::::insert(ctoken, (crowdloan, next_index)); BatchIndexes::::insert(crowdloan, next_index); @@ -283,6 +312,42 @@ pub mod pallet { Ok(()) } + /// Update an exisiting vault via a governance decision + #[pallet::weight(::WeightInfo::update_vault())] + #[transactional] + pub fn update_vault( + origin: OriginFor, + crowdloan: ParaId, + cap: Option>, + end_block: Option, + contribution_strategy: Option, + ) -> DispatchResult { + T::UpdateVaultOrigin::ensure_origin(origin)?; + + let mut vault = Self::current_vault(crowdloan).ok_or(Error::::VaultDoesNotExist)?; + + if let Some(cap) = cap { + vault.cap = cap; + } + + if let Some(end_block) = end_block { + ensure!( + T::RelayChainBlockNumberProvider::current_block_number() <= end_block, + Error::::ExceededEndBlock + ); + + vault.end_block = end_block; + } + + if let Some(contribution_strategy) = contribution_strategy { + vault.contribution_strategy = contribution_strategy; + } + + Self::deposit_event(Event::::VaultUpdated(crowdloan)); + + Ok(()) + } + /// Mark the associated vault as ready for real contributions on the relaychain #[pallet::weight(::WeightInfo::open())] #[transactional] @@ -323,6 +388,11 @@ pub mod pallet { let mut vault = Self::current_vault(crowdloan).ok_or(Error::::VaultDoesNotExist)?; + ensure!( + T::RelayChainBlockNumberProvider::current_block_number() <= vault.end_block, + Error::::ExceededEndBlock + ); + ensure!( vault.phase == VaultPhase::Contributing || vault.phase == VaultPhase::Pending, Error::::IncorrectVaultPhase @@ -346,13 +416,10 @@ pub mod pallet { true, )?; - log::trace!( - target: "crowdloans::contribute", - "who: {:?}, crowdloan: {:?}, amount: {:?}", - &who, - &crowdloan, - &amount, - ); + let total_contribution = Self::cap(&vault, amount)?; + + // throw if new value overflows cap + ensure!(total_contribution <= vault.cap, Error::::ExceededCap); if vault.phase == VaultPhase::Contributing && !Self::has_vrfs() { Self::do_contribute(&who, crowdloan, amount)?; @@ -362,6 +429,14 @@ pub mod pallet { Vaults::::insert(crowdloan, vault.id, vault); + log::trace!( + target: "crowdloans::contribute", + "who: {:?}, crowdloan: {:?}, amount: {:?}", + &who, + &crowdloan, + &amount, + ); + Self::deposit_event(Event::::VaultContributing( crowdloan, who, @@ -518,8 +593,9 @@ pub mod pallet { let vault = Self::current_vault(crowdloan).ok_or(Error::::VaultDoesNotExist)?; let contributions = Self::contribution_iterator(vault.trie_index, true); - let mut migrated_count = 0u32; + let mut migrated_count: u32 = 0u32; let mut all_migrated = true; + for (who, (amount, _)) in contributions { if migrated_count >= T::MigrateKeysLimit::get() { all_migrated = false; @@ -612,6 +688,14 @@ pub mod pallet { Self::current_index(crowdloan).and_then(|index| Self::vaults(crowdloan, index)) } + fn cap(vault: &Vault, amount: BalanceOf) -> Result, ArithmeticError> { + vault + .contributed + .checked_add(vault.pending) + .and_then(|sum| sum.checked_add(amount)) + .ok_or(ArithmeticError::Overflow) + } + fn notify_placeholder() -> ::Call { ::Call::from(Call::::notification_received { query_id: Default::default(), diff --git a/pallets/crowdloans/src/mock.rs b/pallets/crowdloans/src/mock.rs index ed6a5c35b..639396b2e 100644 --- a/pallets/crowdloans/src/mock.rs +++ b/pallets/crowdloans/src/mock.rs @@ -14,7 +14,9 @@ use primitives::{currency::MultiCurrencyAdapter, tokens::*, Balance, ParaId}; use sp_core::H256; use sp_runtime::{ testing::Header, - traits::{AccountIdConversion, AccountIdLookup, BlakeTwo256, Convert, Zero}, + traits::{ + AccountIdConversion, AccountIdLookup, BlakeTwo256, BlockNumberProvider, Convert, Zero, + }, AccountId32, MultiAddress::Id, }; @@ -34,6 +36,21 @@ pub type AccountId = AccountId32; pub type CurrencyId = u32; pub use kusama_runtime; +pub struct RelayChainBlockNumberProvider(sp_std::marker::PhantomData); + +impl BlockNumberProvider + for RelayChainBlockNumberProvider +{ + type BlockNumber = primitives::BlockNumber; + + fn current_block_number() -> Self::BlockNumber { + cumulus_pallet_parachain_system::Pallet::::validation_data() + .map(|d| d.relay_parent_number) + .unwrap_or_default() + .into() + } +} + parameter_types! { pub const ReservedXcmpWeight: Weight = WEIGHT_PER_SECOND / 4; pub const ReservedDmpWeight: Weight = WEIGHT_PER_SECOND / 4; @@ -319,6 +336,9 @@ parameter_types! { pub type CreateVaultOrigin = EnsureOneOf, EnsureSignedBy>; +pub type UpdateVaultOrigin = + EnsureOneOf, EnsureSignedBy>; + pub type VrfOrigin = EnsureOneOf, EnsureSignedBy>; @@ -347,12 +367,14 @@ impl crate::Config for Test { type UpdateOrigin = EnsureRoot; type MigrateOrigin = EnsureRoot; type CreateVaultOrigin = CreateVaultOrigin; + type UpdateVaultOrigin = UpdateVaultOrigin; type VrfOrigin = VrfOrigin; type OpenCloseOrigin = OpenCloseOrigin; type AuctionFailedOrigin = AuctionFailedOrigin; type SlotExpiredOrigin = SlotExpiredOrigin; type WeightInfo = (); type XCM = XcmHelper; + type RelayChainBlockNumberProvider = RelayChainBlockNumberProvider; } parameter_types! { diff --git a/pallets/crowdloans/src/tests.rs b/pallets/crowdloans/src/tests.rs index 55161a120..2eb7a3200 100644 --- a/pallets/crowdloans/src/tests.rs +++ b/pallets/crowdloans/src/tests.rs @@ -4,7 +4,7 @@ use crate::mock::*; use frame_support::{assert_noop, assert_ok}; use frame_system::RawOrigin; use pallet_xcm_helper::{XcmFees, XcmWeight}; -use primitives::{ump::*, ParaId}; +use primitives::{ump::*, BlockNumber, ParaId}; use sp_runtime::{ traits::{One, UniqueSaturatedInto, Zero}, MultiAddress::Id, @@ -15,9 +15,10 @@ pub const VAULT_ID: u32 = 0; #[test] fn create_new_vault_should_work() { new_test_ext().execute_with(|| { - let crowdloan = ParaId::from(1337); + let crowdloan = ParaId::from(1337u32); let ctoken = 10; - + let cap = 1_000_000_000_000; + let end_block = BlockNumber::from(1_000_000_000u32); let contribution_strategy = ContributionStrategy::XCM; // create the ctoken asset @@ -34,6 +35,8 @@ fn create_new_vault_should_work() { crowdloan, // crowdloan ctoken, // ctoken contribution_strategy, // contribution_strategy + cap, // cap + end_block // end_block )); let just_created_vault = Crowdloans::vaults(crowdloan, VAULT_ID).unwrap(); @@ -46,7 +49,9 @@ fn create_new_vault_should_work() { contributed: Zero::zero(), pending: Zero::zero(), contribution_strategy, - trie_index: Zero::zero(), + cap, + end_block, + trie_index: Zero::zero() } ); }); @@ -55,8 +60,10 @@ fn create_new_vault_should_work() { #[test] fn create_new_vault_should_not_work_if_vault_is_already_created() { new_test_ext().execute_with(|| { - let crowdloan = ParaId::from(1337); + let crowdloan = ParaId::from(1337u32); let ctoken = 10; + let cap = 1_000_000_000_000; + let end_block = BlockNumber::from(1_000_000_000u32); assert_ok!(Assets::force_create( RawOrigin::Root.into(), @@ -80,6 +87,8 @@ fn create_new_vault_should_not_work_if_vault_is_already_created() { crowdloan, // crowdloan ctoken, // ctoken ContributionStrategy::XCM, // contribution_strategy + cap, // cap + end_block // end_block ), Error::::CTokenAlreadyTaken ); @@ -89,9 +98,10 @@ fn create_new_vault_should_not_work_if_vault_is_already_created() { #[test] fn create_new_vault_should_not_work_if_crowdloan_already_exists() { new_test_ext().execute_with(|| { - let crowdloan = ParaId::from(1337); + let crowdloan = ParaId::from(1337u32); let ctoken = 10; - + let cap = 1_000_000_000_000; + let end_block = BlockNumber::from(1_000_000_000u32); let contribution_strategy = ContributionStrategy::XCM; // create the ctoken asset @@ -108,6 +118,8 @@ fn create_new_vault_should_not_work_if_crowdloan_already_exists() { crowdloan, // crowdloan ctoken, // ctoken contribution_strategy, // contribution_strategy + cap, // cap + end_block // end_block )); assert_noop!( @@ -116,6 +128,8 @@ fn create_new_vault_should_not_work_if_crowdloan_already_exists() { crowdloan, // crowdloan ctoken, // ctoken contribution_strategy, // contribution_strategy + cap, // cap + end_block // end_block ), Error::::CTokenAlreadyTaken ); @@ -125,10 +139,11 @@ fn create_new_vault_should_not_work_if_crowdloan_already_exists() { #[test] fn set_vrfs_should_work() { new_test_ext().execute_with(|| { - let crowdloan = ParaId::from(1337); + let crowdloan = ParaId::from(1337u32); let ctoken = 10; let amount = 1_000; - + let cap = 1_000_000_000_000; + let end_block = BlockNumber::from(1_000_000_000u32); let contribution_strategy = ContributionStrategy::XCM; // create the ctoken asset @@ -146,6 +161,8 @@ fn set_vrfs_should_work() { crowdloan, // crowdloan ctoken, // ctoken contribution_strategy, // contribution_strategy + cap, // cap + end_block // end_block )); // do open @@ -175,10 +192,11 @@ fn set_vrfs_should_work() { #[test] fn contribute_should_work() { new_test_ext().execute_with(|| { - let crowdloan = ParaId::from(1337); + let crowdloan = ParaId::from(1337u32); let ctoken = 10; let amount = 1_000; - + let cap = 1_000_000_000_000; + let end_block = BlockNumber::from(1_000_000_000u32); let contribution_strategy = ContributionStrategy::XCM; // create the ctoken asset @@ -196,6 +214,8 @@ fn contribute_should_work() { crowdloan, // crowdloan ctoken, // ctoken contribution_strategy, // contribution_strategy + cap, // cap + end_block // end_block )); // do open @@ -233,10 +253,11 @@ fn contribute_should_work() { #[test] fn contribute_should_fail_insufficent_funds() { new_test_ext().execute_with(|| { - let crowdloan = ParaId::from(1337); + let crowdloan = ParaId::from(1337u32); let ctoken = 10; let amount = 1_000; - + let cap = 1_000_000_000_000; + let end_block = BlockNumber::from(1_000_000_000u32); let contribution_strategy = ContributionStrategy::XCM; // create the ctoken asset @@ -254,6 +275,8 @@ fn contribute_should_fail_insufficent_funds() { crowdloan, // crowdloan ctoken, // ctoken contribution_strategy, // contribution_strategy + cap, // cap + end_block // end_block )); // do contribute @@ -272,9 +295,10 @@ fn contribute_should_fail_insufficent_funds() { #[test] fn close_should_work() { new_test_ext().execute_with(|| { - let crowdloan = ParaId::from(1337); + let crowdloan = ParaId::from(1337u32); let ctoken = 10; - + let cap = 1_000_000_000_000; + let end_block = BlockNumber::from(1_000_000_000u32); let contribution_strategy = ContributionStrategy::XCM; // create a vault to contribute to @@ -283,6 +307,8 @@ fn close_should_work() { crowdloan, // crowdloan ctoken, // ctoken contribution_strategy, // contribution_strategy + cap, // cap + end_block // end_block )); // do open @@ -306,9 +332,10 @@ fn close_should_work() { #[test] fn reopen_should_work() { new_test_ext().execute_with(|| { - let crowdloan = ParaId::from(1337); + let crowdloan = ParaId::from(1337u32); let ctoken = 10; - + let cap = 1_000_000_000_000; + let end_block = BlockNumber::from(1_000_000_000u32); let contribution_strategy = ContributionStrategy::XCM; // create a vault to contribute to @@ -317,6 +344,8 @@ fn reopen_should_work() { crowdloan, // crowdloan ctoken, // ctoken contribution_strategy, // contribution_strategy + cap, // cap + end_block // end_block )); // do open @@ -346,35 +375,38 @@ fn reopen_should_work() { #[test] fn auction_failed_should_work() { new_test_ext().execute_with(|| { - let crowdloan = 1337; + let crowdloan = ParaId::from(1337u32); let ctoken = 10; - + let cap = 1_000_000_000_000; + let end_block = BlockNumber::from(1_000_000_000u32); let contribution_strategy = ContributionStrategy::XCM; // create a vault to contribute to assert_ok!(Crowdloans::create_vault( frame_system::RawOrigin::Root.into(), // origin - ParaId::from(crowdloan), // crowdloan + crowdloan, // crowdloan ctoken, // ctoken contribution_strategy, // contribution_strategy + cap, // cap + end_block // end_block )); // do open assert_ok!(Crowdloans::open( frame_system::RawOrigin::Root.into(), // origin - ParaId::from(crowdloan), // crowdloan + crowdloan, // crowdloan )); // do close assert_ok!(Crowdloans::close( frame_system::RawOrigin::Root.into(), // origin - ParaId::from(crowdloan), // crowdloan + crowdloan, // crowdloan )); // set to failed assert_ok!(Crowdloans::auction_failed( frame_system::RawOrigin::Root.into(), // origin - ParaId::from(crowdloan), // crowdloan + crowdloan, // crowdloan )); Crowdloans::notification_received( @@ -385,7 +417,7 @@ fn auction_failed_should_work() { .unwrap(); // check that we're in the right phase - let vault = Crowdloans::vaults(ParaId::from(crowdloan), VAULT_ID).unwrap(); + let vault = Crowdloans::vaults(crowdloan, VAULT_ID).unwrap(); assert_eq!(vault.phase, VaultPhase::Failed) }); } @@ -393,10 +425,11 @@ fn auction_failed_should_work() { #[test] fn claim_refund_should_work() { new_test_ext().execute_with(|| { - let crowdloan = 1337u32; + let crowdloan = ParaId::from(1337u32); let ctoken = 10u32; let amount = 1_000u128; - + let cap = 1_000_000_000_000; + let end_block = BlockNumber::from(1_000_000_000u32); let contribution_strategy = ContributionStrategy::XCM; // create the ctoken asset @@ -411,22 +444,24 @@ fn claim_refund_should_work() { // create a vault to contribute to assert_ok!(Crowdloans::create_vault( frame_system::RawOrigin::Root.into(), // origin - ParaId::from(crowdloan), // crowdloan + crowdloan, // crowdloan ctoken, // ctoken contribution_strategy, // contribution_strategy + cap, // cap + end_block // end_block )); // do open assert_ok!(Crowdloans::open( frame_system::RawOrigin::Root.into(), // origin - ParaId::from(crowdloan), // crowdloan + crowdloan, // crowdloan )); // do contribute assert_ok!(Crowdloans::contribute( - Origin::signed(ALICE), // origin - ParaId::from(crowdloan), // crowdloan - amount, // amount + Origin::signed(ALICE), // origin + crowdloan, // crowdloan + amount, // amount Vec::new() )); @@ -440,13 +475,13 @@ fn claim_refund_should_work() { // do close assert_ok!(Crowdloans::close( frame_system::RawOrigin::Root.into(), // origin - ParaId::from(crowdloan), // crowdloan + crowdloan, // crowdloan )); // set to failed assert_ok!(Crowdloans::auction_failed( frame_system::RawOrigin::Root.into(), // origin - ParaId::from(crowdloan), // crowdloan + crowdloan, // crowdloan )); Crowdloans::notification_received( @@ -464,7 +499,7 @@ fn claim_refund_should_work() { )); // check that we're in the right phase - let vault = Crowdloans::vaults(ParaId::from(crowdloan), VAULT_ID).unwrap(); + let vault = Crowdloans::vaults(crowdloan, VAULT_ID).unwrap(); // vault should be in a state we allow assert!( vault.phase == VaultPhase::Failed || vault.phase == VaultPhase::Expired, @@ -476,34 +511,37 @@ fn claim_refund_should_work() { #[test] fn slot_expired_should_work() { new_test_ext().execute_with(|| { - let crowdloan = 1337; + let crowdloan = ParaId::from(1337u32); let ctoken = 10; - + let cap = 1_000_000_000_000; + let end_block = BlockNumber::from(1_000_000_000u32); let contribution_strategy = ContributionStrategy::XCM; // create a vault to contribute to assert_ok!(Crowdloans::create_vault( frame_system::RawOrigin::Root.into(), // origin - ParaId::from(crowdloan), // crowdloan + crowdloan, // crowdloan ctoken, // ctoken contribution_strategy, // contribution_strategy + cap, // cap + end_block // end_block )); // do open assert_ok!(Crowdloans::open( frame_system::RawOrigin::Root.into(), // origin - ParaId::from(crowdloan), // crowdloan + crowdloan, // crowdloan )); // do close assert_ok!(Crowdloans::close( frame_system::RawOrigin::Root.into(), // origin - ParaId::from(crowdloan), // crowdloan + crowdloan, // crowdloan )); assert_ok!(Crowdloans::slot_expired( frame_system::RawOrigin::Root.into(), // origin - ParaId::from(crowdloan), // crowdloan + crowdloan, // crowdloan )); Crowdloans::notification_received( @@ -514,7 +552,7 @@ fn slot_expired_should_work() { .unwrap(); // check that we're in the right phase - let vault = Crowdloans::vaults(ParaId::from(crowdloan), VAULT_ID).unwrap(); + let vault = Crowdloans::vaults(crowdloan, VAULT_ID).unwrap(); assert_eq!(vault.phase, VaultPhase::Expired) }); } diff --git a/pallets/crowdloans/src/types.rs b/pallets/crowdloans/src/types.rs index 5455a0b5e..c3e763d6b 100644 --- a/pallets/crowdloans/src/types.rs +++ b/pallets/crowdloans/src/types.rs @@ -21,7 +21,7 @@ use codec::{Decode, Encode}; use scale_info::TypeInfo; use sp_runtime::{traits::Zero, RuntimeDebug}; -use primitives::{ParaId, TrieIndex}; +use primitives::{BlockNumber, ParaId, TrieIndex}; #[derive(PartialEq, Eq, Copy, Clone, Encode, Decode, RuntimeDebug, TypeInfo)] pub enum VaultPhase { @@ -59,6 +59,10 @@ pub struct Vault { pub pending: BalanceOf, /// How we contribute coins to the crowdloan pub contribution_strategy: ContributionStrategy, + /// parallel enforced limit + pub cap: BalanceOf, + /// block that vault ends + pub end_block: BlockNumber, /// child storage trie index where we store all contributions pub trie_index: TrieIndex, } @@ -69,6 +73,8 @@ impl Vault { id: u32, ctoken: AssetIdOf, contribution_strategy: ContributionStrategy, + cap: BalanceOf, + end_block: BlockNumber, trie_index: TrieIndex, ) -> Self { Self { @@ -78,6 +84,8 @@ impl Vault { contributed: Zero::zero(), pending: Zero::zero(), contribution_strategy, + cap, + end_block, trie_index, } } diff --git a/pallets/crowdloans/src/weights.rs b/pallets/crowdloans/src/weights.rs index f4b6b392a..8d1373bc3 100644 --- a/pallets/crowdloans/src/weights.rs +++ b/pallets/crowdloans/src/weights.rs @@ -18,22 +18,22 @@ //! Autogenerated weights for pallet_crowdloans //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2021-12-15, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2021-12-16, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` //! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("vanilla-dev"), DB CACHE: 128 // Executed Command: // target/release/parallel // benchmark // --chain=vanilla-dev -// --execution=wasm -// --wasm-execution=compiled -// --pallet=pallet-crowdloans -// --extrinsic=* // --steps=50 // --repeat=20 +// --pallet=pallet_crowdloans +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled // --heap-pages=4096 -// --template=./.maintain/frame-weight-template.hbs // --output=./pallets/crowdloans/src/weights.rs +// --template=./.maintain/frame-weight-template.hbs #![allow(unused_parens)] @@ -49,6 +49,7 @@ use sp_std::marker::PhantomData; /// Weight functions needed for pallet_crowdloans. pub trait WeightInfo { fn create_vault() -> Weight; + fn update_vault() -> Weight; fn contribute() -> Weight; fn open() -> Weight; fn close() -> Weight; @@ -67,67 +68,71 @@ pub trait WeightInfo { pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { fn create_vault() -> Weight { - (70_000_000 as Weight) - .saturating_add(T::DbWeight::get().reads(5 as Weight)) + (84_160_000 as Weight) + .saturating_add(T::DbWeight::get().reads(6 as Weight)) .saturating_add(T::DbWeight::get().writes(4 as Weight)) } + fn update_vault() -> Weight { + (51_078_000 as Weight) + .saturating_add(T::DbWeight::get().reads(3 as Weight)) + } fn contribute() -> Weight { - (309_000_000 as Weight) - .saturating_add(T::DbWeight::get().reads(18 as Weight)) + (440_404_000 as Weight) + .saturating_add(T::DbWeight::get().reads(19 as Weight)) .saturating_add(T::DbWeight::get().writes(12 as Weight)) } fn open() -> Weight { - (71_000_000 as Weight) + (183_468_000 as Weight) .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn close() -> Weight { - (43_000_000 as Weight) + (54_108_000 as Weight) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn set_vrfs() -> Weight { - (35_000_000 as Weight) + (44_661_000 as Weight) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn reopen() -> Weight { - (42_000_000 as Weight) + (53_330_000 as Weight) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn auction_failed() -> Weight { - (176_000_000 as Weight) + (230_637_000 as Weight) .saturating_add(T::DbWeight::get().reads(13 as Weight)) .saturating_add(T::DbWeight::get().writes(8 as Weight)) } fn claim_refund() -> Weight { - (179_000_000 as Weight) + (206_190_000 as Weight) .saturating_add(T::DbWeight::get().reads(7 as Weight)) .saturating_add(T::DbWeight::get().writes(5 as Weight)) } fn slot_expired() -> Weight { - (176_000_000 as Weight) + (232_475_000 as Weight) .saturating_add(T::DbWeight::get().reads(13 as Weight)) .saturating_add(T::DbWeight::get().writes(8 as Weight)) } fn migrate_pending() -> Weight { - (203_000_000 as Weight) + (293_922_000 as Weight) .saturating_add(T::DbWeight::get().reads(15 as Weight)) .saturating_add(T::DbWeight::get().writes(7 as Weight)) } fn notification_received() -> Weight { - (208_000_000 as Weight) + (254_408_000 as Weight) .saturating_add(T::DbWeight::get().reads(10 as Weight)) .saturating_add(T::DbWeight::get().writes(9 as Weight)) } fn update_xcm_fees() -> Weight { - (31_000_000 as Weight) + (35_436_000 as Weight) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn update_xcm_weight() -> Weight { - (33_000_000 as Weight) + (38_151_000 as Weight) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } @@ -136,67 +141,71 @@ impl WeightInfo for SubstrateWeight { // For backwards compatibility and tests impl WeightInfo for () { fn create_vault() -> Weight { - (70_000_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(5 as Weight)) + (84_160_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(6 as Weight)) .saturating_add(RocksDbWeight::get().writes(4 as Weight)) } + fn update_vault() -> Weight { + (51_078_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(3 as Weight)) + } fn contribute() -> Weight { - (309_000_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(18 as Weight)) + (440_404_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(19 as Weight)) .saturating_add(RocksDbWeight::get().writes(12 as Weight)) } fn open() -> Weight { - (71_000_000 as Weight) + (183_468_000 as Weight) .saturating_add(RocksDbWeight::get().reads(3 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn close() -> Weight { - (43_000_000 as Weight) + (54_108_000 as Weight) .saturating_add(RocksDbWeight::get().reads(2 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn set_vrfs() -> Weight { - (35_000_000 as Weight) + (44_661_000 as Weight) .saturating_add(RocksDbWeight::get().reads(1 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn reopen() -> Weight { - (42_000_000 as Weight) + (53_330_000 as Weight) .saturating_add(RocksDbWeight::get().reads(2 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn auction_failed() -> Weight { - (176_000_000 as Weight) + (230_637_000 as Weight) .saturating_add(RocksDbWeight::get().reads(13 as Weight)) .saturating_add(RocksDbWeight::get().writes(8 as Weight)) } fn claim_refund() -> Weight { - (179_000_000 as Weight) + (206_190_000 as Weight) .saturating_add(RocksDbWeight::get().reads(7 as Weight)) .saturating_add(RocksDbWeight::get().writes(5 as Weight)) } fn slot_expired() -> Weight { - (176_000_000 as Weight) + (232_475_000 as Weight) .saturating_add(RocksDbWeight::get().reads(13 as Weight)) .saturating_add(RocksDbWeight::get().writes(8 as Weight)) } fn migrate_pending() -> Weight { - (203_000_000 as Weight) + (293_922_000 as Weight) .saturating_add(RocksDbWeight::get().reads(15 as Weight)) .saturating_add(RocksDbWeight::get().writes(7 as Weight)) } fn notification_received() -> Weight { - (208_000_000 as Weight) + (254_408_000 as Weight) .saturating_add(RocksDbWeight::get().reads(10 as Weight)) .saturating_add(RocksDbWeight::get().writes(9 as Weight)) } fn update_xcm_fees() -> Weight { - (31_000_000 as Weight) + (35_436_000 as Weight) .saturating_add(RocksDbWeight::get().reads(1 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn update_xcm_weight() -> Weight { - (33_000_000 as Weight) + (38_151_000 as Weight) .saturating_add(RocksDbWeight::get().reads(1 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } diff --git a/runtime/heiko/src/lib.rs b/runtime/heiko/src/lib.rs index 2c6100144..6c087aaba 100644 --- a/runtime/heiko/src/lib.rs +++ b/runtime/heiko/src/lib.rs @@ -42,7 +42,8 @@ use sp_core::{ use sp_runtime::{ create_runtime_str, generic, impl_opaque_keys, traits::{ - self, AccountIdConversion, AccountIdLookup, BlakeTwo256, Block as BlockT, Convert, Zero, + self, AccountIdConversion, AccountIdLookup, BlakeTwo256, Block as BlockT, + BlockNumberProvider, Convert, Zero, }, transaction_validity::{TransactionSource, TransactionValidity}, ApplyExtrinsicResult, DispatchError, KeyTypeId, Perbill, Permill, RuntimeDebug, @@ -1332,6 +1333,20 @@ parameter_types! { pub RefundLocation: AccountId = Utility::derivative_account_id(ParachainInfo::parachain_id().into_account(), u16::MAX); } +pub struct RelayChainBlockNumberProvider(sp_std::marker::PhantomData); + +impl BlockNumberProvider + for RelayChainBlockNumberProvider +{ + type BlockNumber = primitives::BlockNumber; + + fn current_block_number() -> Self::BlockNumber { + cumulus_pallet_parachain_system::Pallet::::validation_data() + .map(|d| d.relay_parent_number) + .unwrap_or_default() + } +} + impl pallet_crowdloans::Config for Runtime { type Event = Event; type Origin = Origin; @@ -1349,11 +1364,13 @@ impl pallet_crowdloans::Config for Runtime { type MigrateOrigin = EnsureRootOrMoreThanHalfGeneralCouncil; type VrfOrigin = EnsureRootOrMoreThanHalfGeneralCouncil; type CreateVaultOrigin = EnsureRootOrMoreThanHalfGeneralCouncil; + type UpdateVaultOrigin = EnsureRootOrMoreThanHalfGeneralCouncil; type OpenCloseOrigin = EnsureRootOrMoreThanHalfGeneralCouncil; type AuctionFailedOrigin = EnsureRootOrMoreThanHalfGeneralCouncil; type SlotExpiredOrigin = EnsureRootOrMoreThanHalfGeneralCouncil; type WeightInfo = pallet_crowdloans::weights::SubstrateWeight; type XCM = XcmHelper; + type RelayChainBlockNumberProvider = RelayChainBlockNumberProvider; } parameter_types! { diff --git a/runtime/parallel/src/lib.rs b/runtime/parallel/src/lib.rs index 42ee2ae68..16a80e535 100644 --- a/runtime/parallel/src/lib.rs +++ b/runtime/parallel/src/lib.rs @@ -44,7 +44,8 @@ use sp_core::{ use sp_runtime::{ create_runtime_str, generic, impl_opaque_keys, traits::{ - self, AccountIdConversion, AccountIdLookup, BlakeTwo256, Block as BlockT, Convert, Zero, + self, AccountIdConversion, AccountIdLookup, BlakeTwo256, Block as BlockT, + BlockNumberProvider, Convert, Zero, }, transaction_validity::{TransactionSource, TransactionValidity}, ApplyExtrinsicResult, DispatchError, KeyTypeId, Perbill, Permill, RuntimeDebug, @@ -1325,6 +1326,20 @@ parameter_types! { pub RefundLocation: AccountId = Utility::derivative_account_id(ParachainInfo::parachain_id().into_account(), u16::MAX); } +pub struct RelayChainBlockNumberProvider(sp_std::marker::PhantomData); + +impl BlockNumberProvider + for RelayChainBlockNumberProvider +{ + type BlockNumber = primitives::BlockNumber; + + fn current_block_number() -> Self::BlockNumber { + cumulus_pallet_parachain_system::Pallet::::validation_data() + .map(|d| d.relay_parent_number) + .unwrap_or_default() + } +} + impl pallet_crowdloans::Config for Runtime { type Event = Event; type Origin = Origin; @@ -1342,11 +1357,13 @@ impl pallet_crowdloans::Config for Runtime { type MigrateOrigin = EnsureRootOrMoreThanHalfGeneralCouncil; type VrfOrigin = EnsureRootOrMoreThanHalfGeneralCouncil; type CreateVaultOrigin = EnsureRootOrMoreThanHalfGeneralCouncil; + type UpdateVaultOrigin = EnsureRootOrMoreThanHalfGeneralCouncil; type OpenCloseOrigin = EnsureRootOrMoreThanHalfGeneralCouncil; type AuctionFailedOrigin = EnsureRootOrMoreThanHalfGeneralCouncil; type SlotExpiredOrigin = EnsureRootOrMoreThanHalfGeneralCouncil; type WeightInfo = pallet_crowdloans::weights::SubstrateWeight; type XCM = XcmHelper; + type RelayChainBlockNumberProvider = RelayChainBlockNumberProvider; } parameter_types! { diff --git a/runtime/vanilla/src/lib.rs b/runtime/vanilla/src/lib.rs index d3f05153d..6b79c82dd 100644 --- a/runtime/vanilla/src/lib.rs +++ b/runtime/vanilla/src/lib.rs @@ -57,7 +57,8 @@ use sp_core::{ use sp_runtime::{ create_runtime_str, generic, impl_opaque_keys, traits::{ - self, AccountIdConversion, AccountIdLookup, BlakeTwo256, Block as BlockT, Convert, Zero, + self, AccountIdConversion, AccountIdLookup, BlakeTwo256, Block as BlockT, + BlockNumberProvider, Convert, Zero, }, transaction_validity::{TransactionSource, TransactionValidity}, ApplyExtrinsicResult, DispatchError, KeyTypeId, Perbill, Permill, RuntimeDebug, @@ -1359,6 +1360,20 @@ parameter_types! { pub RefundLocation: AccountId = Utility::derivative_account_id(ParachainInfo::parachain_id().into_account(), u16::MAX); } +pub struct RelayChainBlockNumberProvider(sp_std::marker::PhantomData); + +impl BlockNumberProvider + for RelayChainBlockNumberProvider +{ + type BlockNumber = primitives::BlockNumber; + + fn current_block_number() -> Self::BlockNumber { + cumulus_pallet_parachain_system::Pallet::::validation_data() + .map(|d| d.relay_parent_number) + .unwrap_or_default() + } +} + impl pallet_crowdloans::Config for Runtime { type Event = Event; type Origin = Origin; @@ -1376,11 +1391,13 @@ impl pallet_crowdloans::Config for Runtime { type MigrateOrigin = EnsureRootOrMoreThanHalfGeneralCouncil; type VrfOrigin = EnsureRootOrMoreThanHalfGeneralCouncil; type CreateVaultOrigin = EnsureRootOrMoreThanHalfGeneralCouncil; + type UpdateVaultOrigin = EnsureRootOrMoreThanHalfGeneralCouncil; type OpenCloseOrigin = EnsureRootOrMoreThanHalfGeneralCouncil; type AuctionFailedOrigin = EnsureRootOrMoreThanHalfGeneralCouncil; type SlotExpiredOrigin = EnsureRootOrMoreThanHalfGeneralCouncil; type WeightInfo = pallet_crowdloans::weights::SubstrateWeight; type XCM = XcmHelper; + type RelayChainBlockNumberProvider = RelayChainBlockNumberProvider; } parameter_types! {