Skip to content

Commit

Permalink
Storage Migrations
Browse files Browse the repository at this point in the history
  • Loading branch information
JuaniRios committed Feb 17, 2025
1 parent 3f334d5 commit c4858c3
Show file tree
Hide file tree
Showing 19 changed files with 472 additions and 268 deletions.
7 changes: 4 additions & 3 deletions integration-tests/src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
5 changes: 1 addition & 4 deletions integration-tests/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<PolkadotNet>;
pub type PolimecNet = Polimec<PolkadotNet>;
Expand Down
Empty file.
1 change: 0 additions & 1 deletion pallets/funding/src/functions/1_application.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ impl<T: Config> Pallet<T> {
},
usd_bid_on_oversubscription: None,
funding_end_block: None,
migration_type: None,
};

let bucket: BucketOf<T> = Self::create_bucket_from_metadata(project_metadata)?;
Expand Down
5 changes: 1 addition & 4 deletions pallets/funding/src/functions/5_settlement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,6 @@ impl<T: Config> Pallet<T> {
Self::create_migration(
project_id,
&evaluation.evaluator,
evaluation.id,
ParticipationType::Evaluation,
ct_rewarded,
duration,
Expand Down Expand Up @@ -203,7 +202,6 @@ impl<T: Config> Pallet<T> {
Self::create_migration(
project_id,
&bid.bidder,
bid.id,
ParticipationType::Bid,
final_ct_amount,
ct_vesting_duration,
Expand Down Expand Up @@ -410,7 +408,6 @@ impl<T: Config> Pallet<T> {
pub fn create_migration(
project_id: ProjectId,
origin: &AccountIdOf<T>,
id: u32,
participation_type: ParticipationType,
ct_amount: Balance,
vesting_time: BlockNumberFor<T>,
Expand All @@ -424,7 +421,7 @@ impl<T: Config> Pallet<T> {
}

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::<T>::BadMath)?;
let migration_info: MigrationInfo = (ct_amount, vesting_time).into();
let migration = Migration::new(migration_origin, migration_info);
Expand Down
4 changes: 1 addition & 3 deletions pallets/funding/src/functions/6_ct_migration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,10 @@ use super::*;
impl<T: Config> Pallet<T> {
#[transactional]
pub fn do_start_offchain_migration(project_id: ProjectId, caller: AccountIdOf<T>) -> DispatchResultWithPostInfo {
let mut project_details = ProjectsDetails::<T>::get(project_id).ok_or(Error::<T>::ProjectDetailsNotFound)?;
let project_details = ProjectsDetails::<T>::get(project_id).ok_or(Error::<T>::ProjectDetailsNotFound)?;

ensure!(project_details.issuer_account == caller, Error::<T>::NotIssuer);

project_details.migration_type = Some(MigrationType::Offchain);

Self::transition_project(
project_id,
project_details,
Expand Down
81 changes: 2 additions & 79 deletions pallets/funding/src/functions/misc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -236,70 +236,6 @@ impl<T: Config> Pallet<T> {
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::<MigrationInfo>::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<T>) -> bool {
// Evaluations::<T>::iter_prefix_values((project_id, user.clone())).next().is_none() &&
// Bids::<T>::iter_prefix_values((project_id, user.clone())).next().is_none()
// }

pub fn construct_migration_xcm_message(
migrations: WeakBoundedVec<Migration, ConstU32<10_000>>,
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,
Expand All @@ -309,22 +245,9 @@ impl<T: Config> Pallet<T> {
let (current_status, migrations) =
UserMigrations::<T>::get((project_id, user.clone())).ok_or(Error::<T>::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::<T>::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::<T>::MigrationAlreadyConfirmed);

_ => return Err(Error::<T>::NotAllowed.into()),
};
UnmigratedCounter::<T>::mutate(project_id, |counter| *counter = counter.saturating_sub(1));
UserMigrations::<T>::insert((project_id, user), (status, migrations));
ProjectsDetails::<T>::insert(project_id, project_details);

Expand Down
2 changes: 0 additions & 2 deletions pallets/funding/src/functions/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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"]
Expand Down
35 changes: 18 additions & 17 deletions pallets/funding/src/instantiator/chain_interactions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -540,7 +539,6 @@ impl<
project_id,
account,
amount,
evaluation.id,
ParticipationType::Evaluation,
evaluation.receiving_account,
is_successful,
Expand Down Expand Up @@ -586,7 +584,6 @@ impl<
project_id,
bid.bidder,
bid_ct_amount,
bid.id,
ParticipationType::Bid,
bid.receiving_account,
is_successful,
Expand All @@ -599,7 +596,6 @@ impl<
project_id: ProjectId,
account: AccountIdOf<T>,
amount: Balance,
id: u32,
participation_type: ParticipationType,
receiving_account: Junction,
should_exist: bool,
Expand All @@ -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(
Expand Down
13 changes: 13 additions & 0 deletions pallets/funding/src/instantiator/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),+) => {
Expand Down
10 changes: 4 additions & 6 deletions pallets/funding/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -173,7 +173,6 @@ pub mod pallet {
pub trait Config:
frame_system::Config<Nonce = u32>
+ pallet_balances::Config<Balance = Balance>
+ pallet_xcm::Config
+ pallet_linear_release::Config<Balance = Balance, RuntimeHoldReason = RuntimeHoldReasonOf<Self>>
+ pallet_proxy_bonding::Config<
RuntimeHoldReason = RuntimeHoldReasonOf<Self>,
Expand Down Expand Up @@ -307,9 +306,6 @@ pub mod pallet {
#[pallet::constant]
type RequiredMaxMessageSize: Get<u32>;

/// The runtime enum constructed by the construct_runtime macro
type RuntimeCall: Parameter + IsType<<Self as pallet_xcm::Config>::RuntimeCall> + From<Call<Self>>;

/// The event enum constructed by the construct_runtime macro
type RuntimeEvent: From<Event<Self>>
+ TryInto<Event<Self>>
Expand Down Expand Up @@ -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]
Expand Down Expand Up @@ -954,4 +952,4 @@ pub mod pallet {
weight_consumed
}
}
}
}
1 change: 0 additions & 1 deletion pallets/funding/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Loading

0 comments on commit c4858c3

Please sign in to comment.