Skip to content

Commit

Permalink
shit works now
Browse files Browse the repository at this point in the history
Signed-off-by: Oliver Tale-Yazdi <[email protected]>
  • Loading branch information
ggwpez committed Feb 13, 2025
1 parent 31ca5cd commit 4384e58
Show file tree
Hide file tree
Showing 5 changed files with 195 additions and 18 deletions.
3 changes: 3 additions & 0 deletions integration-tests/ahm/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ use super::mock::*;

#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn account_migration_works() {
std::env::set_var("SNAP_RC", "/Users/vados/Documents/work/runtimes/polkadot.snap");
std::env::set_var("SNAP_AH", "/Users/vados/Documents/work/runtimes/ah-polkadot.snap");
std::env::set_var("START_STAGE", "crowdloan");
let Some((mut rc, mut ah)) = load_externalities().await else { return };
let para_id = ParaId::from(1000);

Expand Down
79 changes: 77 additions & 2 deletions pallets/ah-migrator/src/crowdloan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,88 @@

use crate::*;
use frame_support::traits::tokens::Preservation;
use polkadot_runtime_common::crowdloan as pallet_crowdloan;
use pallet_rc_migrator::crowdloan::RcCrowdloanMessage;

impl<T: Config> Pallet<T> {
pub fn do_receive_crowdloan_messages(
messages: Vec<RcCrowdloanMessageOf<T>>,
) -> Result<(), Error<T>> {
todo!()
let (mut good, mut bad) = (0, 0);
Self::deposit_event(Event::BatchReceived {
pallet: PalletEventName::Crowdloan,
count: messages.len() as u32,
});
log::info!(target: LOG_TARGET, "Received {} crowdloan messages", messages.len());

for message in messages {
match Self::do_process_crowdloan_message(message) {
Ok(()) => good += 1,
Err(e) => {
bad += 1;
log::error!(target: LOG_TARGET, "Error while integrating crowdloan message: {:?}", e);
},
}
}

Self::deposit_event(Event::BatchProcessed {
pallet: PalletEventName::Crowdloan,
count_good: good,
count_bad: bad,
});

Ok(())
}

pub fn do_process_crowdloan_message(message: RcCrowdloanMessageOf<T>) -> Result<(), Error<T>> {
match message {
RcCrowdloanMessage::LeaseReserve { unreserve_block, account, para_id, amount } => {
log::info!(target: LOG_TARGET, "Integrating lease reserve for para_id: {:?}, account: {:?}, amount: {:?}, unreserve_block: {:?}", &para_id, &account, &amount, &unreserve_block);
defensive_assert!(!RcLeaseReserve::<T>::contains_key((
unreserve_block,
&account,
para_id
)));

RcLeaseReserve::<T>::insert((unreserve_block, account, para_id), amount);
},
RcCrowdloanMessage::CrowdloanContribution {
withdraw_block,
contributor,
para_id,
amount,
crowdloan_account,
} => {
log::info!(target: LOG_TARGET, "Integrating crowdloan contribution for para_id: {:?}, contributor: {:?}, amount: {:?}, crowdloan_account: {:?}, withdraw_block: {:?}", &para_id, &contributor, &amount, &crowdloan_account, &withdraw_block);
defensive_assert!(!RcCrowdloanContribution::<T>::contains_key((
withdraw_block,
&contributor,
para_id
)));

RcCrowdloanContribution::<T>::insert(
(withdraw_block, contributor, para_id),
(crowdloan_account, amount),
);
},
RcCrowdloanMessage::CrowdloanDeposit {
unreserve_block,
para_id,
fund_index,
amount,
depositor,
} => {
log::info!(target: LOG_TARGET, "Integrating crowdloan deposit for para_id: {:?}, fund_index: {:?}, amount: {:?}, depositor: {:?}", &para_id, &fund_index, &amount, &depositor);
defensive_assert!(!RcCrowdloanContribution::<T>::contains_key((
unreserve_block,
&depositor,
para_id
)));

RcCrowdloanReserve::<T>::insert((unreserve_block, depositor, para_id), amount);
},
}

Ok(())
}
}

Expand Down
22 changes: 21 additions & 1 deletion pallets/ah-migrator/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ pub mod vesting;

pub use pallet::*;
pub use pallet_rc_migrator::types::ZeroWeightOr;
use polkadot_runtime_common::crowdloan as pallet_crowdloan;

use cumulus_primitives_core::ParaId;
use frame_support::{
Expand Down Expand Up @@ -105,6 +104,7 @@ type RcAccountFor<T> = RcAccount<
pub enum PalletEventName {
Indices,
FastUnstake,
Crowdloan,
BagsList,
Vesting,
Bounties,
Expand Down Expand Up @@ -239,6 +239,26 @@ pub mod pallet {
OptionQuery,
>;

/// The reserve that was taken to create a crowdloan.
///
/// This is normally 500 DOT and can be refunded as last step after all
/// `RcCrowdloanContribution`s of this loan have been withdrawn.
///
/// Keys:
/// - Block number after which this can be unreserved
/// -
#[pallet::storage]
pub type RcCrowdloanReserve<T: Config> = StorageNMap<
_,
(
NMapKey<Twox64Concat, BlockNumberFor<T>>,
NMapKey<Twox64Concat, T::AccountId>,
NMapKey<Twox64Concat, ParaId>,
),
BalanceOf<T>,
OptionQuery,
>;

#[pallet::error]
pub enum Error<T> {
/// The error that should to be replaced by something meaningful.
Expand Down
102 changes: 88 additions & 14 deletions pallets/rc-migrator/src/crowdloan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,27 @@ pub struct CrowdloanMigrator<T> {
#[derive(Encode, Decode, MaxEncodedLen, TypeInfo, RuntimeDebug, Clone, PartialEq, Eq)]
pub enum RcCrowdloanMessage<BlockNumber, AccountId, Balance> {
LeaseReserve {
block: BlockNumber,
/// The block number at which this deposit can be unreserved.
unreserve_block: BlockNumber,
account: AccountId,
para_id: ParaId,
amount: Balance,
},
CrowdloanContribution {
block: BlockNumber,
/// The block number at which this contribution can be withdrawn.
withdraw_block: BlockNumber,
contributor: AccountId,
para_id: ParaId,
amount: Balance,
crowdloan_account: AccountId,
},
CrowdloanDeposit {
unreserve_block: BlockNumber,
depositor: AccountId,
para_id: ParaId,
fund_index: u32,
amount: Balance,
},
}

pub type RcCrowdloanMessageOf<T> =
Expand All @@ -48,11 +57,17 @@ pub type RcCrowdloanMessageOf<T> =
pub enum CrowdloanStage {
LeaseReserve { last_key: Option<ParaId> },
CrowdloanContribution { last_key: Option<ParaId> },
CrowdloanDeposit,
Finished,
}

impl<T: Config> PalletMigration for CrowdloanMigrator<T>
where crate::BalanceOf<T>: From<<<T as polkadot_runtime_common::slots::Config>::Currency as frame_support::traits::Currency<sp_runtime::AccountId32>>::Balance> {
where
crate::BalanceOf<T>:
From<<<T as polkadot_runtime_common::slots::Config>::Currency as frame_support::traits::Currency<sp_runtime::AccountId32>>::Balance>,
crate::BalanceOf<T>:
From<<<<T as polkadot_runtime_common::crowdloan::Config>::Auctioneer as polkadot_runtime_common::traits::Auctioneer<<<<T as frame_system::Config>::Block as sp_runtime::traits::Block>::Header as sp_runtime::traits::Header>::Number>>::Currency as frame_support::traits::Currency<sp_runtime::AccountId32>>::Balance>,
{
type Key = CrowdloanStage;
type Error = Error<T>;

Expand All @@ -68,11 +83,13 @@ where crate::BalanceOf<T>: From<<<T as polkadot_runtime_common::slots::Config>::
.try_consume(<T as frame_system::Config>::DbWeight::get().reads_writes(1, 1))
.is_err()
{
if messages.is_empty() {
/*if messages.is_empty() {
return Err(Error::OutOfWeight);
} else {
break;
}
}*/
log::warn!("Out of weight, stop. num messages: {}", messages.len());
break;
}

if messages.len() > 10_000 {
Expand All @@ -89,39 +106,96 @@ where crate::BalanceOf<T>: From<<<T as polkadot_runtime_common::slots::Config>::

match iter.next() {
Some((para_id, leases)) => {
pallet_slots::Leases::<T>::remove(&para_id);

let Some(last_lease) = leases.last() else {
// This seems to be fine, but i don't know how it happens, see https://github.com/paritytech/polkadot-sdk/blob/db3ff60b5af2a9017cb968a4727835f3d00340f0/polkadot/runtime/common/src/slots/mod.rs#L108-L109
log::warn!(target: LOG_TARGET, "Empty leases for para_id: {:?}", para_id);
inner_key = CrowdloanStage::LeaseReserve { last_key: Some(para_id) };
continue;
};

let Some((lease_acc, _)) = last_lease else {
defensive!("Last lease cannot be None");
inner_key = CrowdloanStage::LeaseReserve { last_key: Some(para_id) };
continue;
};

// NOTE: Max instead of sum, see https://github.com/paritytech/polkadot-sdk/blob/db3ff60b5af2a9017cb968a4727835f3d00340f0/polkadot/runtime/common/src/slots/mod.rs#L102-L103
let amount = leases.iter().flatten().map(|(_acc, amount)| amount).max().cloned().unwrap_or_default().into();
let amount: crate::BalanceOf<T> = leases.iter().flatten().map(|(_acc, amount)| amount).max().cloned().unwrap_or_default().into();

if amount == 0 {
// fucking stupid ParaId type
if amount == 0u32.into() {
defensive_assert!(para_id < ParaId::from(2000), "Must be system chain");
inner_key = CrowdloanStage::LeaseReserve { last_key: Some(para_id) };
continue;
}

let unlock_block = num_leases_to_ending_block::<T>(leases.len() as u32);
let unreserve_block = num_leases_to_ending_block::<T>(leases.len() as u32);

log::warn!(target: LOG_TARGET, "Migrating out lease reserve for para_id: {:?}, account: {:?}, amount: {:?}, unlock_block: {:?}", &para_id, &lease_acc, &amount, &unlock_block);
messages.push(RcCrowdloanMessage::LeaseReserve { block: unlock_block, account: lease_acc.clone(), para_id, amount });
log::warn!(target: LOG_TARGET, "Migrating out lease reserve for para_id: {:?}, account: {:?}, amount: {:?}, unreserve_block: {:?}", &para_id, &lease_acc, &amount, &unreserve_block);
messages.push(RcCrowdloanMessage::LeaseReserve { unreserve_block, account: lease_acc.clone(), para_id, amount });
CrowdloanStage::LeaseReserve { last_key: Some(para_id) }
},
None => CrowdloanStage::CrowdloanContribution { last_key: None },
}
},
CrowdloanStage::CrowdloanContribution { last_key } => {
todo!()
let mut funds_iter = match last_key.clone() {
Some(last_key) => pallet_crowdloan::Funds::<T>::iter_from_key(last_key),
None => pallet_crowdloan::Funds::<T>::iter(),
};

let (para_id, fund) = match funds_iter.next() {
Some((para_id, fund)) => (para_id, fund),
None => {
inner_key = CrowdloanStage::CrowdloanDeposit;
continue;
},
};

let mut contributions_iter = pallet_crowdloan::Pallet::<T>::contribution_iterator(fund.fund_index);

match contributions_iter.next() {
Some((contributor, (amount, memo))) => {
// Dont really care about memos, but we can add them, if needed.
if !memo.is_empty() {
log::warn!(target: LOG_TARGET, "Discarding crowdloan memo of length: {}", &memo.len());
}

let leases = pallet_slots::Leases::<T>::get(para_id);
if leases.is_empty() {
defensive!("Leases should not be empty if there is a fund");
}

let crowdloan_account = pallet_crowdloan::Pallet::<T>::fund_account_id(fund.fund_index);

let withdraw_block = num_leases_to_ending_block::<T>(leases.len() as u32);
log::warn!(target: LOG_TARGET, "Migrating out crowdloan contribution for para_id: {:?}, contributor: {:?}, amount: {:?}, withdraw_block: {:?}", &para_id, &contributor, &amount, &withdraw_block);
pallet_crowdloan::Pallet::<T>::contribution_kill(fund.fund_index, &contributor);
messages.push(RcCrowdloanMessage::CrowdloanContribution { withdraw_block, contributor, para_id, amount: amount.into(), crowdloan_account });

inner_key // does not change since we deleted the contribution
},
None => {
CrowdloanStage::CrowdloanContribution { last_key: Some(para_id) }
},
}
},
CrowdloanStage::CrowdloanDeposit => {
match pallet_crowdloan::Funds::<T>::iter().next() {
Some((para_id, fund)) => {
pallet_crowdloan::Funds::<T>::take(para_id);

let leases = pallet_slots::Leases::<T>::get(para_id);
if leases.is_empty() {
defensive!("Leases should not be empty if there is a fund");
}
let unreserve_block = num_leases_to_ending_block::<T>(leases.len() as u32);

log::warn!(target: LOG_TARGET, "Migrating out crowdloan deposit for para_id: {:?}, fund_index: {:?}, amount: {:?}, depositor: {:?}", &para_id, &fund.fund_index, &fund.deposit, &fund.depositor);
messages.push(RcCrowdloanMessage::CrowdloanDeposit { unreserve_block, para_id, fund_index: fund.fund_index, amount: fund.deposit.into(), depositor: fund.depositor });
CrowdloanStage::CrowdloanDeposit
},
None => CrowdloanStage::Finished,
}
},
CrowdloanStage::Finished => {
break;
Expand Down
7 changes: 6 additions & 1 deletion pallets/rc-migrator/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -413,7 +413,12 @@ pub mod pallet {

#[pallet::hooks]
impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T>
where crate::BalanceOf<T>: From<<<T as polkadot_runtime_common::slots::Config>::Currency as frame_support::traits::Currency<sp_runtime::AccountId32>>::Balance>{
where
crate::BalanceOf<T>:
From<<<T as polkadot_runtime_common::slots::Config>::Currency as frame_support::traits::Currency<sp_runtime::AccountId32>>::Balance>,
crate::BalanceOf<T>:
From<<<<T as polkadot_runtime_common::crowdloan::Config>::Auctioneer as polkadot_runtime_common::traits::Auctioneer<<<<T as frame_system::Config>::Block as sp_runtime::traits::Block>::Header as sp_runtime::traits::Header>::Number>>::Currency as frame_support::traits::Currency<sp_runtime::AccountId32>>::Balance>,
{
fn on_initialize(_: BlockNumberFor<T>) -> Weight {
let mut weight_counter = WeightMeter::with_limit(T::MaxRcWeight::get());
let stage = RcMigrationStage::<T>::get();
Expand Down

0 comments on commit 4384e58

Please sign in to comment.