From c4858c3bbeda5f1611b4fa22f847acd451813d1c Mon Sep 17 00:00:00 2001 From: Juan Ignacio Rios Date: Wed, 12 Feb 2025 13:16:11 +0100 Subject: [PATCH] Storage Migrations --- integration-tests/src/constants.rs | 7 +- integration-tests/src/lib.rs | 5 +- integration-tests/src/tests/ct_migration.rs | 0 .../funding/src/functions/1_application.rs | 1 - pallets/funding/src/functions/5_settlement.rs | 5 +- .../funding/src/functions/6_ct_migration.rs | 4 +- pallets/funding/src/functions/misc.rs | 81 +--- pallets/funding/src/functions/mod.rs | 2 - .../src/instantiator/chain_interactions.rs | 35 +- pallets/funding/src/instantiator/macros.rs | 13 + pallets/funding/src/lib.rs | 10 +- pallets/funding/src/mock.rs | 1 - pallets/funding/src/storage_migrations.rs | 347 +++++++++++++++++- pallets/funding/src/tests/2_evaluation.rs | 1 - pallets/funding/src/tests/3_auction.rs | 149 ++++---- pallets/funding/src/tests/5_settlement.rs | 5 +- pallets/funding/src/types.rs | 57 +-- polimec-common/common/src/lib.rs | 9 +- runtimes/polimec/src/lib.rs | 8 +- 19 files changed, 472 insertions(+), 268 deletions(-) delete mode 100644 integration-tests/src/tests/ct_migration.rs diff --git a/integration-tests/src/constants.rs b/integration-tests/src/constants.rs index 79cf19cf6..c2d87a7c8 100644 --- a/integration-tests/src/constants.rs +++ b/integration-tests/src/constants.rs @@ -358,9 +358,10 @@ pub mod polimec { let usdc_asset_id = AcceptedFundingAsset::USDC.id(); let weth_asset_id = AcceptedFundingAsset::WETH.id(); - let mut funded_accounts = vec![ - (PolimecNet::sovereign_account_id_of((Parent, xcm::prelude::Parachain(1000)).into()), INITIAL_DEPOSIT), - ]; + let mut funded_accounts = vec![( + PolimecNet::sovereign_account_id_of((Parent, xcm::prelude::Parachain(1000)).into()), + INITIAL_DEPOSIT, + )]; let alice_account = PolimecNet::account_id_of(accounts::ALICE); let bob_account: AccountId = PolimecNet::account_id_of(accounts::BOB); let charlie_account: AccountId = PolimecNet::account_id_of(accounts::CHARLIE); diff --git a/integration-tests/src/lib.rs b/integration-tests/src/lib.rs index fe3b2cb3d..3b33ca82e 100644 --- a/integration-tests/src/lib.rs +++ b/integration-tests/src/lib.rs @@ -83,10 +83,7 @@ decl_test_networks! { /// Shortcuts to reduce boilerplate on runtime types pub mod shortcuts { - use super::{ - Chain, Polimec, PolimecParaPallet, PolkadotNet, PolkadotRelay as Polkadot, - PolkadotRelayRelayPallet, - }; + use super::{Chain, Polimec, PolimecParaPallet, PolkadotNet, PolkadotRelay as Polkadot, PolkadotRelayRelayPallet}; pub type PolkaNet = Polkadot; pub type PolimecNet = Polimec; diff --git a/integration-tests/src/tests/ct_migration.rs b/integration-tests/src/tests/ct_migration.rs deleted file mode 100644 index e69de29bb..000000000 diff --git a/pallets/funding/src/functions/1_application.rs b/pallets/funding/src/functions/1_application.rs index ca75f6b38..ac7e0d138 100644 --- a/pallets/funding/src/functions/1_application.rs +++ b/pallets/funding/src/functions/1_application.rs @@ -45,7 +45,6 @@ impl Pallet { }, usd_bid_on_oversubscription: None, funding_end_block: None, - migration_type: None, }; let bucket: BucketOf = Self::create_bucket_from_metadata(project_metadata)?; diff --git a/pallets/funding/src/functions/5_settlement.rs b/pallets/funding/src/functions/5_settlement.rs index a2dfd5e75..dd7db5a5b 100644 --- a/pallets/funding/src/functions/5_settlement.rs +++ b/pallets/funding/src/functions/5_settlement.rs @@ -134,7 +134,6 @@ impl Pallet { Self::create_migration( project_id, &evaluation.evaluator, - evaluation.id, ParticipationType::Evaluation, ct_rewarded, duration, @@ -203,7 +202,6 @@ impl Pallet { Self::create_migration( project_id, &bid.bidder, - bid.id, ParticipationType::Bid, final_ct_amount, ct_vesting_duration, @@ -410,7 +408,6 @@ impl Pallet { pub fn create_migration( project_id: ProjectId, origin: &AccountIdOf, - id: u32, participation_type: ParticipationType, ct_amount: Balance, vesting_time: BlockNumberFor, @@ -424,7 +421,7 @@ impl Pallet { } let mut user_migrations = user_migrations.to_vec(); - let migration_origin = MigrationOrigin { user: receiving_account, id, participation_type }; + let migration_origin = MigrationOrigin { user: receiving_account, participation_type }; let vesting_time: u64 = vesting_time.try_into().map_err(|_| Error::::BadMath)?; let migration_info: MigrationInfo = (ct_amount, vesting_time).into(); let migration = Migration::new(migration_origin, migration_info); diff --git a/pallets/funding/src/functions/6_ct_migration.rs b/pallets/funding/src/functions/6_ct_migration.rs index 07a2a5918..0de47d703 100644 --- a/pallets/funding/src/functions/6_ct_migration.rs +++ b/pallets/funding/src/functions/6_ct_migration.rs @@ -4,12 +4,10 @@ use super::*; impl Pallet { #[transactional] pub fn do_start_offchain_migration(project_id: ProjectId, caller: AccountIdOf) -> DispatchResultWithPostInfo { - let mut project_details = ProjectsDetails::::get(project_id).ok_or(Error::::ProjectDetailsNotFound)?; + let project_details = ProjectsDetails::::get(project_id).ok_or(Error::::ProjectDetailsNotFound)?; ensure!(project_details.issuer_account == caller, Error::::NotIssuer); - project_details.migration_type = Some(MigrationType::Offchain); - Self::transition_project( project_id, project_details, diff --git a/pallets/funding/src/functions/misc.rs b/pallets/funding/src/functions/misc.rs index e92568c9a..cb6742091 100644 --- a/pallets/funding/src/functions/misc.rs +++ b/pallets/funding/src/functions/misc.rs @@ -236,70 +236,6 @@ impl Pallet { Ok((liquidity_pools_reward_pot, long_term_holder_reward_pot)) } - pub fn migrations_per_xcm_message_allowed() -> u32 { - const MAX_WEIGHT: Weight = Weight::from_parts(20_000_000_000, 1_000_000); - - let one_migration_bytes = (0u128, 0u64).encode().len() as u32; - - // our encoded call starts with pallet index 51, and call index 0 - let mut encoded_call = vec![51u8, 0]; - let encoded_first_param = [0u8; 32].encode(); - let encoded_second_param = Vec::::new().encode(); - // we append the encoded parameters, with our migrations vec being empty for now - encoded_call.extend_from_slice(encoded_first_param.as_slice()); - encoded_call.extend_from_slice(encoded_second_param.as_slice()); - - let base_xcm_message: Xcm<()> = Xcm(vec![ - UnpaidExecution { weight_limit: WeightLimit::Unlimited, check_origin: None }, - Transact { origin_kind: OriginKind::Native, require_weight_at_most: MAX_WEIGHT, call: encoded_call.into() }, - ReportTransactStatus(QueryResponseInfo { - destination: Parachain(3344).into(), - query_id: 0, - max_weight: MAX_WEIGHT, - }), - ]); - let xcm_size = base_xcm_message.encode().len(); - - let available_bytes_for_migration_per_message = - T::RequiredMaxMessageSize::get().saturating_sub(xcm_size as u32); - - available_bytes_for_migration_per_message.saturating_div(one_migration_bytes) - } - - // /// Check if the user has no participations (left) in the project. - // pub fn user_has_no_participations(project_id: ProjectId, user: AccountIdOf) -> bool { - // Evaluations::::iter_prefix_values((project_id, user.clone())).next().is_none() && - // Bids::::iter_prefix_values((project_id, user.clone())).next().is_none() - // } - - pub fn construct_migration_xcm_message( - migrations: WeakBoundedVec>, - query_id: QueryId, - pallet_index: PalletIndex, - ) -> Xcm<()> { - // TODO: adjust this as benchmarks for polimec-receiver are written - const MAX_WEIGHT: Weight = Weight::from_parts(10_000, 0); - const MAX_RESPONSE_WEIGHT: Weight = Weight::from_parts(700_000_000, 50_000); - let migrations_item = Migrations::from(migrations.to_vec()); - - // First byte is the pallet index, second byte is the call index - let mut encoded_call = vec![pallet_index, 0]; - - // migrations_item can contain a Maximum of MaxParticipationsPerUser migrations which - // is 48. So we know that there is an upper limit to this encoded call, namely 48 * - // Migration encode size. - encoded_call.extend_from_slice(migrations_item.encode().as_slice()); - Xcm(vec![ - UnpaidExecution { weight_limit: WeightLimit::Unlimited, check_origin: None }, - Transact { origin_kind: OriginKind::Native, require_weight_at_most: MAX_WEIGHT, call: encoded_call.into() }, - ReportTransactStatus(QueryResponseInfo { - destination: ParentThen(Parachain(POLIMEC_PARA_ID).into()).into(), - query_id, - max_weight: MAX_RESPONSE_WEIGHT, - }), - ]) - } - pub fn change_migration_status( project_id: ProjectId, user: T::AccountId, @@ -309,22 +245,9 @@ impl Pallet { let (current_status, migrations) = UserMigrations::::get((project_id, user.clone())).ok_or(Error::::NoMigrationsFound)?; - let status = match status { - MigrationStatus::Sent(_) - if matches!(current_status, MigrationStatus::NotStarted | MigrationStatus::Failed) => - status, - MigrationStatus::Confirmed - if matches!(project_details.migration_type, Some(MigrationType::Offchain)) || - (matches!(project_details.migration_type, Some(MigrationType::Pallet(_))) && - matches!(current_status, MigrationStatus::Sent(_))) => - { - UnmigratedCounter::::mutate(project_id, |counter| *counter = counter.saturating_sub(1)); - status - }, - MigrationStatus::Failed if matches!(current_status, MigrationStatus::Sent(_)) => status, + ensure!(current_status == MigrationStatus::NotStarted, Error::::MigrationAlreadyConfirmed); - _ => return Err(Error::::NotAllowed.into()), - }; + UnmigratedCounter::::mutate(project_id, |counter| *counter = counter.saturating_sub(1)); UserMigrations::::insert((project_id, user), (status, migrations)); ProjectsDetails::::insert(project_id, project_details); diff --git a/pallets/funding/src/functions/mod.rs b/pallets/funding/src/functions/mod.rs index 5caf55a2a..18b3e3086 100644 --- a/pallets/funding/src/functions/mod.rs +++ b/pallets/funding/src/functions/mod.rs @@ -19,13 +19,11 @@ use frame_support::{ use frame_system::pallet_prelude::BlockNumberFor; use polimec_common::{ credentials::{Did, InvestorType}, - migration_types::{MigrationInfo, Migrations}, USD_DECIMALS, }; use sp_arithmetic::{traits::Zero, Percent, Perquintill}; use sp_runtime::traits::Convert; -const POLIMEC_PARA_ID: u32 = 3344u32; #[path = "1_application.rs"] mod application; #[path = "3_auction.rs"] diff --git a/pallets/funding/src/instantiator/chain_interactions.rs b/pallets/funding/src/instantiator/chain_interactions.rs index aff823e96..45fb7ba1f 100644 --- a/pallets/funding/src/instantiator/chain_interactions.rs +++ b/pallets/funding/src/instantiator/chain_interactions.rs @@ -280,7 +280,6 @@ impl< }, usd_bid_on_oversubscription: None, funding_end_block: None, - migration_type: None, }; assert_eq!(metadata, expected_metadata); assert_eq!(details, expected_details); @@ -540,7 +539,6 @@ impl< project_id, account, amount, - evaluation.id, ParticipationType::Evaluation, evaluation.receiving_account, is_successful, @@ -586,7 +584,6 @@ impl< project_id, bid.bidder, bid_ct_amount, - bid.id, ParticipationType::Bid, bid.receiving_account, is_successful, @@ -599,7 +596,6 @@ impl< project_id: ProjectId, account: AccountIdOf, amount: Balance, - id: u32, participation_type: ParticipationType, receiving_account: Junction, should_exist: bool, @@ -610,19 +606,24 @@ impl< assert!(!should_exist); return; }; - let expected_migration_origin = MigrationOrigin { user: receiving_account, id, participation_type }; - - let Some(migration) = - user_migrations.into_iter().find(|migration| migration.origin == expected_migration_origin) - else { - assert!(!should_exist); - return; - }; - assert_close_enough!( - migration.info.contribution_token_amount, - amount, - Perquintill::from_rational(999u64, 1000u64) - ); + let expected_migration_origin = MigrationOrigin { user: receiving_account, participation_type }; + + let is_migration_found = user_migrations + .into_iter() + .find(|migration| { + migration.origin == expected_migration_origin && + is_close_enough!( + migration.info.contribution_token_amount, + amount, + Perquintill::from_rational(999u64, 1000u64) + ) + }) + .is_some(); + if should_exist { + assert!(is_migration_found, "Migration not found for user {:?}", account); + } else { + assert!(!is_migration_found, "Migration found for user {:?}", account); + } } pub fn create_new_project( diff --git a/pallets/funding/src/instantiator/macros.rs b/pallets/funding/src/instantiator/macros.rs index 8c385c058..fdce086bd 100644 --- a/pallets/funding/src/instantiator/macros.rs +++ b/pallets/funding/src/instantiator/macros.rs @@ -40,6 +40,19 @@ macro_rules! assert_close_enough { }; } +#[macro_export] +macro_rules! is_close_enough { + ($real:expr, $desired:expr, $min_percentage:expr) => { + { + if $real <= $desired { + Perquintill::from_rational($real, $desired) >= $min_percentage + } else { + Perquintill::from_rational($desired, $real) >= $min_percentage + } + } + }; +} + #[macro_export] macro_rules! find_event { ($runtime:ty, $pattern:pat, $($field_name:ident == $field_value:expr),+) => { diff --git a/pallets/funding/src/lib.rs b/pallets/funding/src/lib.rs index 9428818f4..c2d7e904a 100644 --- a/pallets/funding/src/lib.rs +++ b/pallets/funding/src/lib.rs @@ -91,7 +91,7 @@ use sp_arithmetic::traits::{One, Saturating}; use sp_runtime::{traits::AccountIdConversion, FixedPointNumber, FixedU128}; use sp_std::prelude::*; pub use types::*; -use xcm::v4::{prelude::*}; +use xcm::v4::prelude::*; pub mod functions; pub mod storage_migrations; @@ -173,7 +173,6 @@ pub mod pallet { pub trait Config: frame_system::Config + pallet_balances::Config - + pallet_xcm::Config + pallet_linear_release::Config> + pallet_proxy_bonding::Config< RuntimeHoldReason = RuntimeHoldReasonOf, @@ -307,9 +306,6 @@ pub mod pallet { #[pallet::constant] type RequiredMaxMessageSize: Get; - /// The runtime enum constructed by the construct_runtime macro - type RuntimeCall: Parameter + IsType<::RuntimeCall> + From>; - /// The event enum constructed by the construct_runtime macro type RuntimeEvent: From> + TryInto> @@ -654,6 +650,8 @@ pub mod pallet { SettlementNotComplete, /// Tried to mark a project's CT migration as finished but there are still migrations to be confirmed MigrationsStillPending, + /// Tried to confirm an already confirmed user CT migration + MigrationAlreadyConfirmed, } #[pallet::call] @@ -954,4 +952,4 @@ pub mod pallet { weight_consumed } } -} \ No newline at end of file +} diff --git a/pallets/funding/src/mock.rs b/pallets/funding/src/mock.rs index 61a52bf4b..3c1284544 100644 --- a/pallets/funding/src/mock.rs +++ b/pallets/funding/src/mock.rs @@ -428,7 +428,6 @@ impl Config for TestRuntime { type RemainderRoundDuration = RemainderRoundDuration; type RequiredMaxCapacity = RequiredMaxCapacity; type RequiredMaxMessageSize = RequiredMaxMessageSize; - type RuntimeCall = RuntimeCall; type RuntimeEvent = RuntimeEvent; type RuntimeHoldReason = RuntimeHoldReason; type RuntimeOrigin = RuntimeOrigin; diff --git a/pallets/funding/src/storage_migrations.rs b/pallets/funding/src/storage_migrations.rs index 1c060b9ef..231b28d37 100644 --- a/pallets/funding/src/storage_migrations.rs +++ b/pallets/funding/src/storage_migrations.rs @@ -1,7 +1,350 @@ //! A module that is responsible for migration of storage. -use frame_support::traits::StorageVersion; +use crate::{ + AccountIdOf, BiddingTicketSizes, Config, CurrencyMetadata, FixedPointNumber, ParticipantsAccountType, PriceOf, + ProjectMetadataOf, StringLimitOf, +}; +use core::marker::PhantomData; +use frame_support::traits::{StorageVersion, UncheckedOnRuntimeUpgrade}; +use polimec_common::{assets::AcceptedFundingAsset, credentials::Cid}; +use scale_info::TypeInfo; +use serde::{Deserialize, Serialize}; +use sp_core::{ConstU32, Decode, Encode, Get, MaxEncodedLen, RuntimeDebug}; +use sp_runtime::{BoundedVec, Percent}; extern crate alloc; +use alloc::vec::Vec; +use polimec_common::migration_types::{MigrationInfo, ParticipationType}; +use xcm::v4::Location; /// The current storage version -pub const STORAGE_VERSION: StorageVersion = StorageVersion::new(7); +pub const STORAGE_VERSION: StorageVersion = StorageVersion::new(6); pub const LOG: &str = "runtime::funding::migration"; + +pub mod v5_storage_items { + + #[derive(Clone, Copy, Encode, Decode, Eq, PartialEq, RuntimeDebug, TypeInfo, MaxEncodedLen)] + pub enum CheckOutcome { + AwaitingResponse, + Passed(Option), + Failed, + } + use super::*; + use crate::{Balance, BlockNumberPair, FundingOutcome, Pallet, ProjectId, TicketSize}; + use frame_support::{pallet_prelude::NMapKey, storage_alias, Blake2_128Concat}; + use polimec_common::migration_types::MigrationStatus; + use polkadot_parachain_primitives::primitives::Id as ParaId; + use xcm::v4::QueryId; + + #[derive(Clone, Copy, Encode, Decode, Eq, PartialEq, RuntimeDebug, TypeInfo, MaxEncodedLen)] + pub struct HRMPChannelStatus { + pub project_to_polimec: ChannelStatus, + pub polimec_to_project: ChannelStatus, + } + + #[derive(Clone, Copy, Encode, Decode, Eq, PartialEq, RuntimeDebug, TypeInfo, MaxEncodedLen)] + pub enum ChannelStatus { + Closed, + Open, + AwaitingAcceptance, + } + pub type PalletIndex = u8; + + #[derive(Clone, Copy, Encode, Decode, Eq, PartialEq, RuntimeDebug, TypeInfo, MaxEncodedLen)] + pub struct PalletMigrationReadinessCheck { + pub holding_check: (QueryId, CheckOutcome), + pub pallet_check: (QueryId, CheckOutcome), + } + impl PalletMigrationReadinessCheck { + pub fn is_ready(&self) -> bool { + self.holding_check.1 == CheckOutcome::Passed(None) && + matches!(self.pallet_check.1, CheckOutcome::Passed(Some(_))) + } + } + #[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, MaxEncodedLen, TypeInfo)] + pub struct PalletMigrationInfo { + /// ParaId of project + pub parachain_id: ParaId, + /// HRMP Channel status + pub hrmp_channel_status: HRMPChannelStatus, + /// Migration readiness check + pub migration_readiness_check: Option, + } + #[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, MaxEncodedLen, TypeInfo)] + pub enum MigrationType { + Offchain, + Pallet(PalletMigrationInfo), + } + + #[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, MaxEncodedLen, TypeInfo)] + pub enum OldProjectStatus { + Application, + EvaluationRound, + AuctionRound, + CommunityRound(BlockNumber), + FundingFailed, + FundingSuccessful, + SettlementStarted(FundingOutcome), + SettlementFinished(FundingOutcome), + CTMigrationStarted, + CTMigrationFinished, + } + #[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, MaxEncodedLen, TypeInfo)] + pub struct OldProjectDetails { + pub issuer_account: AccountId, + pub issuer_did: Did, + /// Whether the project is frozen, so no `metadata` changes are allowed. + pub is_frozen: bool, + /// The price in USD per token decided after the Auction Round + pub weighted_average_price: Option, + /// The current status of the project + pub status: OldProjectStatus, + /// When the different project phases start and end + pub round_duration: BlockNumberPair, + /// Fundraising target amount in USD (6 decimals) + pub fundraising_target_usd: Balance, + /// The amount of Contribution Tokens that have not yet been sold + pub remaining_contribution_tokens: Balance, + /// Funding reached amount in USD (6 decimals) + pub funding_amount_reached_usd: Balance, + /// Information about the total amount bonded, and the outcome in regards to reward/slash/nothing + pub evaluation_round_info: EvaluationRoundInfo, + /// If the auction was oversubscribed, how much USD was raised across all winning bids + pub usd_bid_on_oversubscription: Option, + /// When the Funding Round ends + pub funding_end_block: Option, + pub migration_type: Option, + } + + #[derive( + Clone, Copy, Encode, Decode, Eq, PartialEq, RuntimeDebug, MaxEncodedLen, TypeInfo, Serialize, Deserialize, + )] + pub struct OldBiddingTicketSizes { + pub professional: TicketSize, + pub institutional: TicketSize, + pub phantom: PhantomData<(Price, Balance)>, + } + #[derive( + Clone, Copy, Encode, Decode, Eq, PartialEq, RuntimeDebug, MaxEncodedLen, TypeInfo, Serialize, Deserialize, + )] + pub struct OldContributingTicketSizes { + pub retail: TicketSize, + pub professional: TicketSize, + pub institutional: TicketSize, + pub phantom: PhantomData<(Price, Balance)>, + } + + #[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, MaxEncodedLen, TypeInfo, Serialize, Deserialize)] + pub struct OldProjectMetadata { + /// Token Metadata + pub token_information: CurrencyMetadata, + /// Mainnet Token Max Supply + pub mainnet_token_max_supply: Balance, + /// Total allocation of Contribution Tokens available for the Funding Round. + pub total_allocation_size: Balance, + /// Percentage of the total allocation of Contribution Tokens available for the Auction Round + pub auction_round_allocation_percentage: Percent, + /// The minimum price per token in USD, decimal-aware. See [`calculate_decimals_aware_price()`](crate::traits::ProvideAssetPrice::calculate_decimals_aware_price) for more information. + pub minimum_price: Price, + /// Maximum and minimum ticket sizes for auction round + pub bidding_ticket_sizes: OldBiddingTicketSizes, + pub contributing_ticket_sizes: OldContributingTicketSizes, + /// Participation currencies (e.g stablecoin, DOT, KSM) + /// e.g. https://github.com/paritytech/substrate/blob/427fd09bcb193c1e79dec85b1e207c718b686c35/frame/uniques/src/types.rs#L110 + /// For now is easier to handle the case where only just one Currency is accepted + pub participation_currencies: + BoundedVec>, + pub funding_destination_account: AccountId, + /// Additional metadata + pub policy_ipfs_cid: Option, + } + + #[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, TypeInfo, MaxEncodedLen)] + pub struct OldMigrationOrigin { + pub user: Location, + pub id: u32, + pub participation_type: OldParticipationType, + } + impl PartialOrd for OldMigrationOrigin { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } + } + impl Ord for OldMigrationOrigin { + fn cmp(&self, other: &Self) -> core::cmp::Ordering { + if self.participation_type == other.participation_type { + self.id.cmp(&other.id) + } else { + self.participation_type.cmp(&other.participation_type) + } + } + } + + #[derive(Clone, Copy, Encode, Decode, Eq, PartialEq, Ord, PartialOrd, RuntimeDebug, TypeInfo, MaxEncodedLen)] + pub enum OldParticipationType { + Evaluation, + Bid, + Contribution, + } + #[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, TypeInfo, MaxEncodedLen)] + pub struct OldMigration { + pub origin: OldMigrationOrigin, + pub info: MigrationInfo, + } + pub const MAX_PARTICIPATIONS_PER_USER: u32 = 16 + 16 + 16; + + #[storage_alias] + pub type UserMigrations = StorageNMap< + Pallet, + (NMapKey, NMapKey>), + (MigrationStatus, BoundedVec>), + >; +} + +pub mod v6 { + use super::*; + use crate::{ + storage_migrations::v5_storage_items::{OldMigration, OldProjectStatus, MAX_PARTICIPATIONS_PER_USER}, + EvaluationRoundInfo, ProjectDetailsOf, ProjectStatus, TicketSize, + }; + use frame_system::pallet_prelude::BlockNumberFor; + use polimec_common::{ + credentials::Did, + migration_types::{Migration, MigrationOrigin, MigrationStatus}, + USD_UNIT, + }; + use sp_runtime::{WeakBoundedVec}; + + type OldProjectMetadataOf = super::v5_storage_items::OldProjectMetadata< + BoundedVec>, + ::Balance, + PriceOf, + AccountIdOf, + Cid, + >; + + type OldProjectDetailsOf = super::v5_storage_items::OldProjectDetails< + AccountIdOf, + Did, + BlockNumberFor, + PriceOf, + EvaluationRoundInfo, + >; + + pub struct UncheckedMigrationToV6(PhantomData); + impl UncheckedOnRuntimeUpgrade for UncheckedMigrationToV6 { + fn on_runtime_upgrade() -> frame_support::weights::Weight { + let mut items = 0; + log::info!("Starting migration to V5"); + let translate_project_metadata = |_key, item: OldProjectMetadataOf| -> Option> { + items += 1; + + let new_bidding_ticket_sizes = BiddingTicketSizes { + professional: item.bidding_ticket_sizes.professional, + institutional: item.bidding_ticket_sizes.institutional, + retail: TicketSize { usd_minimum_per_participation: 10 * USD_UNIT, usd_maximum_per_did: None }, + phantom: Default::default(), + }; + + Some(ProjectMetadataOf:: { + token_information: item.token_information, + mainnet_token_max_supply: item.mainnet_token_max_supply, + total_allocation_size: item.total_allocation_size, + minimum_price: item.minimum_price, + bidding_ticket_sizes: new_bidding_ticket_sizes, + participation_currencies: item.participation_currencies, + funding_destination_account: item.funding_destination_account, + policy_ipfs_cid: item.policy_ipfs_cid, + participants_account_type: ParticipantsAccountType::Polkadot, + }) + }; + crate::ProjectsMetadata::::translate(translate_project_metadata); + + let translate_project_details = |_key, item: OldProjectDetailsOf| -> Option> { + items += 1; + Some(ProjectDetailsOf:: { + issuer_account: item.issuer_account, + issuer_did: item.issuer_did, + is_frozen: item.is_frozen, + status: match item.status { + OldProjectStatus::Application => ProjectStatus::Application, + OldProjectStatus::EvaluationRound => ProjectStatus::EvaluationRound, + OldProjectStatus::AuctionRound => ProjectStatus::AuctionRound, + OldProjectStatus::FundingFailed => ProjectStatus::FundingFailed, + OldProjectStatus::FundingSuccessful => ProjectStatus::FundingSuccessful, + OldProjectStatus::SettlementStarted(outcome) => ProjectStatus::SettlementStarted(outcome), + OldProjectStatus::SettlementFinished(outcome) => ProjectStatus::SettlementFinished(outcome), + OldProjectStatus::CTMigrationStarted => ProjectStatus::CTMigrationStarted, + OldProjectStatus::CTMigrationFinished => ProjectStatus::CTMigrationFinished, + _ => { + log::warn!("Unsupported project status: {:?}", item.status); + return None; + }, + }, + round_duration: item.round_duration, + fundraising_target_usd: item.fundraising_target_usd, + remaining_contribution_tokens: item.remaining_contribution_tokens, + funding_amount_reached_usd: item.funding_amount_reached_usd, + evaluation_round_info: item.evaluation_round_info, + usd_bid_on_oversubscription: item.usd_bid_on_oversubscription, + funding_end_block: item.funding_end_block, + }) + }; + crate::ProjectsDetails::::translate(translate_project_details); + + let mut translate_migration = + |(status, migrations): ( + MigrationStatus, + BoundedVec>, + )| + -> Option<(MigrationStatus, WeakBoundedVec>)> { + let old_migrations = migrations.to_vec(); + let mut new_migrations = Vec::new(); + + for mut old_migration in old_migrations { + items += 1; + let origin_junction = old_migration.origin.user.interior.take_first().unwrap(); + let new_origin = MigrationOrigin { + user: origin_junction, + participation_type: match old_migration.origin.participation_type { + v5_storage_items::OldParticipationType::Evaluation => ParticipationType::Evaluation, + v5_storage_items::OldParticipationType::Bid => ParticipationType::Bid, + v5_storage_items::OldParticipationType::Contribution => ParticipationType::Bid, + }, + }; + new_migrations.push(Migration { origin: new_origin, info: old_migration.info }); + } + let new_migrations = new_migrations.try_into().ok()?; + Some((status, new_migrations)) + }; + + let old_migration_keys = v5_storage_items::UserMigrations::::iter(); + + for ((project_id, account), (status, migrations)) in old_migration_keys { + log::info!("Read one old migration"); + v5_storage_items::UserMigrations::::remove((project_id, account.clone())); + log::info!("Removed one old migration"); + let maybe_new_migrations = translate_migration((status, migrations)); + if let Some(new_migrations) = maybe_new_migrations { + crate::UserMigrations::::insert((project_id, account.clone()), new_migrations); + log::info!("Inserted a new migration"); + } else { + log::error!( + "Failed to migrate UserMigrations for project_id: {:?}, account: {:?}", + project_id, + account + ); + } + } + + log::info!("Migration to V5 completed. Migrated {} items", items); + T::DbWeight::get().reads_writes(items, items) + } + } + + pub type MigrationToV6 = frame_support::migrations::VersionedMigration< + 5, + 6, + UncheckedMigrationToV6, + crate::Pallet, + ::DbWeight, + >; +} diff --git a/pallets/funding/src/tests/2_evaluation.rs b/pallets/funding/src/tests/2_evaluation.rs index a92c1bfe3..1d3e557a0 100644 --- a/pallets/funding/src/tests/2_evaluation.rs +++ b/pallets/funding/src/tests/2_evaluation.rs @@ -288,7 +288,6 @@ mod start_evaluation_extrinsic { }, usd_bid_on_oversubscription: None, funding_end_block: None, - migration_type: None, }; assert_ok!(inst.execute(|| PolimecFunding::start_evaluation( RuntimeOrigin::signed(issuer), diff --git a/pallets/funding/src/tests/3_auction.rs b/pallets/funding/src/tests/3_auction.rs index 0fca04feb..d5fc1d5ba 100644 --- a/pallets/funding/src/tests/3_auction.rs +++ b/pallets/funding/src/tests/3_auction.rs @@ -202,52 +202,51 @@ mod round_flow { inst.mint_necessary_tokens_for_bids(project_id, bids.clone()); inst.bid_for_users(project_id, bids.clone()).unwrap(); - // Check full rejection of one bid by another - let last_bid_amount = bids[9].amount; - let oversubscribed_bid = - BidParams::::from((BIDDER_1, Retail, last_bid_amount, Classic(1u8), USDT)); - inst.mint_necessary_tokens_for_bids(project_id, vec![oversubscribed_bid.clone()]); - inst.bid_for_users(project_id, vec![oversubscribed_bid.clone()]).unwrap(); - assert_eq!(inst.execute(|| CTAmountOversubscribed::::get(project_id)), last_bid_amount); - inst.advance_time(1); - let rejected_bid = inst.execute(|| Bids::::get(project_id, 9)).unwrap(); - assert_eq!(inst.execute(|| CTAmountOversubscribed::::get(project_id)), Zero::zero()); - assert_eq!(rejected_bid.status, BidStatus::Rejected); - let yet_unknown_bid = inst.execute(|| Bids::::get(project_id, 8)).unwrap(); - assert_eq!(yet_unknown_bid.status, BidStatus::YetUnknown); - - // Check multiple bid rejections by one bid - let multiple_bids_amount = bids[8].amount + bids[7].amount + bids[6].amount; - let multiple_bids = - BidParams::::from((BIDDER_1, Retail, multiple_bids_amount, Classic(1u8), USDT)); - inst.mint_necessary_tokens_for_bids(project_id, vec![multiple_bids.clone()]); - inst.bid_for_users(project_id, vec![multiple_bids.clone()]).unwrap(); - assert_eq!(inst.execute(|| CTAmountOversubscribed::::get(project_id)), multiple_bids_amount); - inst.advance_time(1); - let rejected_bid_1 = inst.execute(|| Bids::::get(project_id, 8)).unwrap(); - let rejected_bid_2 = inst.execute(|| Bids::::get(project_id, 7)).unwrap(); - let rejected_bid_3 = inst.execute(|| Bids::::get(project_id, 6)).unwrap(); - assert_eq!(inst.execute(|| CTAmountOversubscribed::::get(project_id)), Zero::zero()); - assert_eq!(rejected_bid_1.status, BidStatus::Rejected); - assert_eq!(rejected_bid_2.status, BidStatus::Rejected); - assert_eq!(rejected_bid_3.status, BidStatus::Rejected); - let yet_unknown_bid = inst.execute(|| Bids::::get(project_id, 5)).unwrap(); - assert_eq!(yet_unknown_bid.status, BidStatus::YetUnknown); - - // Check partial rejection of one bid by another - let partial_bid_amount = last_bid_amount / 2; - let partial_bid = - BidParams::::from((BIDDER_1, Retail, partial_bid_amount, Classic(1u8), USDT)); - inst.mint_necessary_tokens_for_bids(project_id, vec![partial_bid.clone()]); - inst.bid_for_users(project_id, vec![partial_bid.clone()]).unwrap(); - assert_eq!(inst.execute(|| CTAmountOversubscribed::::get(project_id)), partial_bid_amount); - inst.advance_time(1); - let rejected_bid = inst.execute(|| Bids::::get(project_id, 5)).unwrap(); - assert_eq!(inst.execute(|| CTAmountOversubscribed::::get(project_id)), Zero::zero()); - assert_eq!(rejected_bid.status, BidStatus::PartiallyAccepted(last_bid_amount - partial_bid_amount)); - let yet_unknown_bid = inst.execute(|| Bids::::get(project_id, 4)).unwrap(); - assert_eq!(yet_unknown_bid.status, BidStatus::YetUnknown); - } + // Check full rejection of one bid by another + let last_bid_amount = bids[9].amount; + let oversubscribed_bid = + BidParams::::from((BIDDER_1, Retail, last_bid_amount, Classic(1u8), USDT)); + inst.mint_necessary_tokens_for_bids(project_id, vec![oversubscribed_bid.clone()]); + inst.bid_for_users(project_id, vec![oversubscribed_bid.clone()]).unwrap(); + assert_eq!(inst.execute(|| CTAmountOversubscribed::::get(project_id)), last_bid_amount); + inst.advance_time(1); + let rejected_bid = inst.execute(|| Bids::::get(project_id, 9)).unwrap(); + assert_eq!(inst.execute(|| CTAmountOversubscribed::::get(project_id)), Zero::zero()); + assert_eq!(rejected_bid.status, BidStatus::Rejected); + let yet_unknown_bid = inst.execute(|| Bids::::get(project_id, 8)).unwrap(); + assert_eq!(yet_unknown_bid.status, BidStatus::YetUnknown); + + // Check multiple bid rejections by one bid + let multiple_bids_amount = bids[8].amount + bids[7].amount + bids[6].amount; + let multiple_bids = + BidParams::::from((BIDDER_1, Retail, multiple_bids_amount, Classic(1u8), USDT)); + inst.mint_necessary_tokens_for_bids(project_id, vec![multiple_bids.clone()]); + inst.bid_for_users(project_id, vec![multiple_bids.clone()]).unwrap(); + assert_eq!(inst.execute(|| CTAmountOversubscribed::::get(project_id)), multiple_bids_amount); + inst.advance_time(1); + let rejected_bid_1 = inst.execute(|| Bids::::get(project_id, 8)).unwrap(); + let rejected_bid_2 = inst.execute(|| Bids::::get(project_id, 7)).unwrap(); + let rejected_bid_3 = inst.execute(|| Bids::::get(project_id, 6)).unwrap(); + assert_eq!(inst.execute(|| CTAmountOversubscribed::::get(project_id)), Zero::zero()); + assert_eq!(rejected_bid_1.status, BidStatus::Rejected); + assert_eq!(rejected_bid_2.status, BidStatus::Rejected); + assert_eq!(rejected_bid_3.status, BidStatus::Rejected); + let yet_unknown_bid = inst.execute(|| Bids::::get(project_id, 5)).unwrap(); + assert_eq!(yet_unknown_bid.status, BidStatus::YetUnknown); + + // Check partial rejection of one bid by another + let partial_bid_amount = last_bid_amount / 2; + let partial_bid = BidParams::::from((BIDDER_1, Retail, partial_bid_amount, Classic(1u8), USDT)); + inst.mint_necessary_tokens_for_bids(project_id, vec![partial_bid.clone()]); + inst.bid_for_users(project_id, vec![partial_bid.clone()]).unwrap(); + assert_eq!(inst.execute(|| CTAmountOversubscribed::::get(project_id)), partial_bid_amount); + inst.advance_time(1); + let rejected_bid = inst.execute(|| Bids::::get(project_id, 5)).unwrap(); + assert_eq!(inst.execute(|| CTAmountOversubscribed::::get(project_id)), Zero::zero()); + assert_eq!(rejected_bid.status, BidStatus::PartiallyAccepted(last_bid_amount - partial_bid_amount)); + let yet_unknown_bid = inst.execute(|| Bids::::get(project_id, 4)).unwrap(); + assert_eq!(yet_unknown_bid.status, BidStatus::YetUnknown); + } #[test] fn on_idle_clears_multiple_oversubscribed_projects() { @@ -296,16 +295,16 @@ mod round_flow { assert_eq!(inst.execute(|| CTAmountOversubscribed::::get(project_id_1)), Zero::zero()); assert_eq!(inst.execute(|| CTAmountOversubscribed::::get(project_id_2)), Zero::zero()); - // Verify bid statuses for both projects - let rejected_bid_1 = inst.execute(|| Bids::::get(project_id_1, 4)).unwrap(); - let rejected_bid_2 = inst.execute(|| Bids::::get(project_id_2, 9)).unwrap(); - assert_eq!(rejected_bid_1.status, BidStatus::Rejected); - assert_eq!(rejected_bid_2.status, BidStatus::Rejected); + // Verify bid statuses for both projects + let rejected_bid_1 = inst.execute(|| Bids::::get(project_id_1, 4)).unwrap(); + let rejected_bid_2 = inst.execute(|| Bids::::get(project_id_2, 9)).unwrap(); + assert_eq!(rejected_bid_1.status, BidStatus::Rejected); + assert_eq!(rejected_bid_2.status, BidStatus::Rejected); - let yet_unknown_bid_1 = inst.execute(|| Bids::::get(project_id_1, 3)).unwrap(); - let yet_unknown_bid_2 = inst.execute(|| Bids::::get(project_id_2, 8)).unwrap(); - assert_eq!(yet_unknown_bid_1.status, BidStatus::YetUnknown); - assert_eq!(yet_unknown_bid_2.status, BidStatus::YetUnknown); + let yet_unknown_bid_1 = inst.execute(|| Bids::::get(project_id_1, 3)).unwrap(); + let yet_unknown_bid_2 = inst.execute(|| Bids::::get(project_id_2, 8)).unwrap(); + assert_eq!(yet_unknown_bid_1.status, BidStatus::YetUnknown); + assert_eq!(yet_unknown_bid_2.status, BidStatus::YetUnknown); inst.go_to_next_state(project_id_1); inst.go_to_next_state(project_id_2); @@ -1892,13 +1891,11 @@ mod end_auction_extrinsic { assert!(matches!(inst.go_to_next_state(project_id), ProjectStatus::FundingSuccessful)); - let bidder_5_rejected_bid = inst.execute(|| Bids::::get(project_id, 2)).unwrap(); - let _bidder_5_accepted_bid = inst.execute(|| Bids::::get(project_id, 3)).unwrap(); - let bidder_5_plmc_pre_balance = inst.get_free_plmc_balance_for(bidder_5_rejected_bid.bidder); - let bidder_5_funding_asset_pre_balance = inst.get_free_funding_asset_balance_for( - bidder_5_rejected_bid.funding_asset.id(), - bidder_5_rejected_bid.bidder, - ); + let bidder_5_rejected_bid = inst.execute(|| Bids::::get(project_id, 2)).unwrap(); + let _bidder_5_accepted_bid = inst.execute(|| Bids::::get(project_id, 3)).unwrap(); + let bidder_5_plmc_pre_balance = inst.get_free_plmc_balance_for(bidder_5_rejected_bid.bidder); + let bidder_5_funding_asset_pre_balance = inst + .get_free_funding_asset_balance_for(bidder_5_rejected_bid.funding_asset.id(), bidder_5_rejected_bid.bidder); assert!(matches!(inst.go_to_next_state(project_id), ProjectStatus::SettlementStarted(FundingOutcome::Success))); inst.settle_project(project_id, true); @@ -1933,12 +1930,12 @@ mod end_auction_extrinsic { let bidder_5_returned_funding_asset = returned_funding_assets.iter().find(|x| x.account == BIDDER_5).unwrap().asset_amount; - assert!(inst.execute(|| Bids::::get(project_id, 2)).is_none()); - assert_eq!(bidder_5_plmc_post_balance, bidder_5_plmc_pre_balance + bidder_5_returned_plmc); - assert_eq!( - bidder_5_funding_asset_post_balance, - bidder_5_funding_asset_pre_balance + bidder_5_returned_funding_asset - ); + assert!(inst.execute(|| Bids::::get(project_id, 2)).is_none()); + assert_eq!(bidder_5_plmc_post_balance, bidder_5_plmc_pre_balance + bidder_5_returned_plmc); + assert_eq!( + bidder_5_funding_asset_post_balance, + bidder_5_funding_asset_pre_balance + bidder_5_returned_funding_asset + ); inst.do_free_plmc_assertions(expected_free_plmc); inst.do_reserved_plmc_assertions(expected_reserved_plmc, HoldReason::Participation.into()); @@ -1989,10 +1986,10 @@ mod end_auction_extrinsic { let pre_first_refund_bidder_funding_asset_balance = inst.get_free_funding_asset_balance_for(first_bid_to_refund.asset.id(), first_bid_to_refund.bidder); - let first_bid = inst.execute(|| Bids::::get(project_id, 9)).unwrap(); - assert!(matches!(first_bid.status, BidStatus::Rejected)); - let second_bid = inst.execute(|| Bids::::get(project_id, 8)).unwrap(); - assert!(matches!(second_bid.status, BidStatus::PartiallyAccepted(_))); + let first_bid = inst.execute(|| Bids::::get(project_id, 9)).unwrap(); + assert!(matches!(first_bid.status, BidStatus::Rejected)); + let second_bid = inst.execute(|| Bids::::get(project_id, 8)).unwrap(); + assert!(matches!(second_bid.status, BidStatus::PartiallyAccepted(_))); inst.execute(|| { assert_ok!(Pallet::::do_settle_bid(project_id, 9)); @@ -2023,10 +2020,10 @@ mod end_auction_extrinsic { let pre_second_refund_bidder_funding_asset_balance = inst.get_free_funding_asset_balance_for(second_bid_to_refund.asset.id(), second_bid_to_refund.bidder); - let second_bid = inst.execute(|| Bids::::get(project_id, 8)).unwrap(); - assert!(matches!(second_bid.status, BidStatus::Rejected)); - let third_bid = inst.execute(|| Bids::::get(project_id, 7)).unwrap(); - assert!(matches!(third_bid.status, BidStatus::PartiallyAccepted(_))); + let second_bid = inst.execute(|| Bids::::get(project_id, 8)).unwrap(); + assert!(matches!(second_bid.status, BidStatus::Rejected)); + let third_bid = inst.execute(|| Bids::::get(project_id, 7)).unwrap(); + assert!(matches!(third_bid.status, BidStatus::PartiallyAccepted(_))); inst.execute(|| { assert_ok!(Pallet::::do_settle_bid(project_id, 8)); diff --git a/pallets/funding/src/tests/5_settlement.rs b/pallets/funding/src/tests/5_settlement.rs index fefe8ec0a..4ed893766 100644 --- a/pallets/funding/src/tests/5_settlement.rs +++ b/pallets/funding/src/tests/5_settlement.rs @@ -331,7 +331,7 @@ mod settle_evaluation_extrinsic { let evals = vec![(EVALUATOR_1, EVAL_1_REWARD), (EVALUATOR_2, EVAL_2_REWARD), (EVALUATOR_3, EVAL_3_REWARD)]; - for (index, (evaluator, expected_reward)) in evals.into_iter().enumerate() { + for (_index, (evaluator, expected_reward)) in evals.into_iter().enumerate() { let evaluation_locked_plmc = inst.get_reserved_plmc_balance_for(evaluator, HoldReason::Evaluation.into()); let free_plmc = inst.get_free_plmc_balance_for(evaluator); @@ -349,7 +349,6 @@ mod settle_evaluation_extrinsic { project_id, evaluator, expected_reward, - index as u32, ParticipationType::Evaluation, polkadot_junction!(evaluator), true, @@ -559,7 +558,6 @@ mod settle_bid_extrinsic { project_id, BIDDER_1, auction_allocation - 2000 * CT_UNIT, - 0, ParticipationType::Bid, polkadot_junction!(BIDDER_1), true, @@ -638,7 +636,6 @@ mod settle_bid_extrinsic { project_id, BIDDER_1, auction_allocation / 2, - 0, ParticipationType::Bid, polkadot_junction!(BIDDER_1), true, diff --git a/pallets/funding/src/types.rs b/pallets/funding/src/types.rs index 523b26978..6512198c0 100644 --- a/pallets/funding/src/types.rs +++ b/pallets/funding/src/types.rs @@ -26,7 +26,6 @@ use frame_system::pallet_prelude::BlockNumberFor; pub use inner::*; use parachains_common::DAYS; use polimec_common::USD_DECIMALS; -use polkadot_parachain_primitives::primitives::Id as ParaId; use serde::{Deserialize, Serialize}; use sp_arithmetic::{traits::Saturating, FixedPointNumber, FixedU128}; use sp_runtime::traits::{Convert, One}; @@ -270,22 +269,6 @@ pub mod storage { Institutional(Bound), } - #[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, MaxEncodedLen, TypeInfo)] - pub enum MigrationType { - Offchain, - Pallet(PalletMigrationInfo), - } - - #[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, MaxEncodedLen, TypeInfo)] - pub struct PalletMigrationInfo { - /// ParaId of project - pub parachain_id: ParaId, - /// HRMP Channel status - pub hrmp_channel_status: HRMPChannelStatus, - /// Migration readiness check - pub migration_readiness_check: Option, - } - #[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, MaxEncodedLen, TypeInfo)] pub struct ProjectDetails { pub issuer_account: AccountId, @@ -308,7 +291,6 @@ pub mod storage { pub usd_bid_on_oversubscription: Option, /// When the Funding Round ends pub funding_end_block: Option, - pub migration_type: Option, } /// Tells on_initialize what to do with the project #[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, TypeInfo, MaxEncodedLen)] @@ -494,7 +476,7 @@ pub mod inner { #[allow(clippy::wildcard_imports)] use super::*; use crate::Balance; - use xcm::v4::{Junction, QueryId}; + use xcm::v4::Junction; pub enum MetadataError { /// The minimum price per token is too low. @@ -708,43 +690,6 @@ pub mod inner { RejectFunding, } - #[derive(Clone, Copy, Encode, Decode, Eq, PartialEq, RuntimeDebug, TypeInfo, MaxEncodedLen)] - pub struct PalletMigrationReadinessCheck { - pub holding_check: (QueryId, CheckOutcome), - pub pallet_check: (QueryId, CheckOutcome), - } - - impl PalletMigrationReadinessCheck { - pub fn is_ready(&self) -> bool { - self.holding_check.1 == CheckOutcome::Passed(None) && - matches!(self.pallet_check.1, CheckOutcome::Passed(Some(_))) - } - } - - pub type PalletIndex = u8; - #[derive(Clone, Copy, Encode, Decode, Eq, PartialEq, RuntimeDebug, TypeInfo, MaxEncodedLen)] - pub enum CheckOutcome { - AwaitingResponse, - Passed(Option), - Failed, - } - - #[derive(Clone, Copy, Encode, Decode, Eq, PartialEq, RuntimeDebug, TypeInfo, MaxEncodedLen)] - pub struct HRMPChannelStatus { - pub project_to_polimec: ChannelStatus, - pub polimec_to_project: ChannelStatus, - } - - #[derive(Clone, Copy, Encode, Decode, Eq, PartialEq, RuntimeDebug, TypeInfo, MaxEncodedLen)] - pub enum ChannelStatus { - /// hrmp channel is closed. - Closed, - /// hrmp channel is open. - Open, - /// request for a hrmp channel was sent to the relay. Waiting for response. - AwaitingAcceptance, - } - #[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, TypeInfo, MaxEncodedLen)] pub struct ProjectMigrationOrigins { pub project_id: ProjectId, diff --git a/polimec-common/common/src/lib.rs b/polimec-common/common/src/lib.rs index 6df43fd0c..00b79c8c2 100644 --- a/polimec-common/common/src/lib.rs +++ b/polimec-common/common/src/lib.rs @@ -113,7 +113,6 @@ pub mod migration_types { #[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, TypeInfo, MaxEncodedLen)] pub struct MigrationOrigin { pub user: Junction, - pub id: u32, pub participation_type: ParticipationType, } impl PartialOrd for MigrationOrigin { @@ -123,10 +122,10 @@ pub mod migration_types { } impl Ord for MigrationOrigin { fn cmp(&self, other: &Self) -> core::cmp::Ordering { - if self.participation_type == other.participation_type { - self.id.cmp(&other.id) - } else { + if self.user == other.user { self.participation_type.cmp(&other.participation_type) + } else { + self.user.cmp(&other.user) } } } @@ -151,9 +150,7 @@ pub mod migration_types { #[derive(Clone, Encode, Decode, Eq, PartialEq, Ord, PartialOrd, RuntimeDebug, TypeInfo, MaxEncodedLen)] pub enum MigrationStatus { NotStarted, - Sent(QueryId), Confirmed, - Failed, } #[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, TypeInfo, MaxEncodedLen)] diff --git a/runtimes/polimec/src/lib.rs b/runtimes/polimec/src/lib.rs index 189302a7a..2a35961b6 100644 --- a/runtimes/polimec/src/lib.rs +++ b/runtimes/polimec/src/lib.rs @@ -170,7 +170,7 @@ pub type Migrations = migrations::Unreleased; /// The runtime migrations per release. #[allow(missing_docs)] pub mod migrations { - use crate::parameter_types; + use crate::{parameter_types, Runtime}; parameter_types! { pub const RandomPalletName: &'static str = "Random"; @@ -178,7 +178,10 @@ pub mod migrations { /// Unreleased migrations. Add new ones here: #[allow(unused_parens)] - pub type Unreleased = (); + pub type Unreleased = ( + super::custom_migrations::asset_id_migration::FromOldAssetIdMigration, + pallet_funding::storage_migrations::v6::MigrationToV6, + ); } /// Executive: handles dispatch to the various modules. @@ -1085,7 +1088,6 @@ impl pallet_funding::Config for Runtime { type RemainderRoundDuration = RemainderRoundDuration; type RequiredMaxCapacity = RequiredMaxCapacity; type RequiredMaxMessageSize = RequiredMaxMessageSize; - type RuntimeCall = RuntimeCall; type RuntimeEvent = RuntimeEvent; type RuntimeHoldReason = RuntimeHoldReason; type RuntimeOrigin = RuntimeOrigin;