Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[AHM] Improve accounts migration #550

Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion integration-tests/ahm/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,14 +59,16 @@ async fn account_migration_works() {
dmps.extend(new_dmps);

if RcMigrationStage::<Polkadot>::get() ==
pallet_rc_migrator::MigrationStage::ProxyMigrationDone
pallet_rc_migrator::MigrationStage::MigrationDone
{
log::info!("Migration done");
break dmps;
}
}
});
rc.commit_all().unwrap();
// TODO: for some reason this prints some small value (2947), but logs on XCM send and receive
// show more iteration.
log::info!("Num of RC->AH DMP messages: {}", dmp_messages.len());

// Inject the DMP messages into the Asset Hub
Expand Down
33 changes: 23 additions & 10 deletions pallets/ah-migrator/src/account.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,30 @@ impl<T: Config> Pallet<T> {
) -> Result<(), Error<T>> {
log::info!(target: LOG_TARGET, "Integrating {} accounts", accounts.len());

Self::deposit_event(Event::<T>::AccountBatchReceived { count: accounts.len() as u32 });
let (mut count_good, mut count_bad) = (0, 0);

for account in accounts {
let _: Result<(), ()> = with_transaction_opaque_err::<(), (), _>(|| {
match Self::do_receive_account(account) {
let res = with_transaction_opaque_err::<(), RcAccountFor<T>, _>(|| {
match Self::do_receive_account(account.clone()) {
Ok(()) => TransactionOutcome::Commit(Ok(())),
Err(_) => TransactionOutcome::Rollback(Ok(())),
Err(_) => TransactionOutcome::Rollback(Err(account)),
}
})
.expect("Always returning Ok; qed");
}

if let Err(account) = res {
// unlikely to happen cause we dry run migration, but we keep it for completeness.
count_bad += 1;
let who = account.who.clone();
log::error!(target: LOG_TARGET, "Saving the failed account data: {:?}", who.to_ss58check());
RcAccounts::<T>::insert(&who, account);
} else {
count_good += 1;
}
}
count_good = count_good - count_bad;
Self::deposit_event(Event::<T>::AccountBatchProcessed { count_good, count_bad });
Ok(())
}

Expand All @@ -48,7 +62,7 @@ impl<T: Config> Pallet<T> {
Ok(minted) => minted,
Err(e) => {
log::error!(target: LOG_TARGET, "Failed to mint into account {}: {:?}", who.to_ss58check(), e);
return Err(Error::<T>::TODO);
return Err(Error::<T>::FailedToProcessAccount);
},
};
debug_assert!(minted == total_balance);
Expand All @@ -60,13 +74,13 @@ impl<T: Config> Pallet<T> {
hold.amount,
) {
log::error!(target: LOG_TARGET, "Failed to hold into account {}: {:?}", who.to_ss58check(), e);
return Err(Error::<T>::TODO);
return Err(Error::<T>::FailedToProcessAccount);
}
}

if let Err(e) = <T as pallet::Config>::Currency::reserve(&who, account.unnamed_reserve) {
log::error!(target: LOG_TARGET, "Failed to reserve into account {}: {:?}", who.to_ss58check(), e);
return Err(Error::<T>::TODO);
return Err(Error::<T>::FailedToProcessAccount);
}

for freeze in account.freezes {
Expand All @@ -76,7 +90,7 @@ impl<T: Config> Pallet<T> {
freeze.amount,
) {
log::error!(target: LOG_TARGET, "Failed to freeze into account {}: {:?}", who.to_ss58check(), e);
return Err(Error::<T>::TODO);
return Err(Error::<T>::FailedToProcessAccount);
}
}

Expand All @@ -100,14 +114,13 @@ impl<T: Config> Pallet<T> {
for _ in 0..account.consumers {
if let Err(e) = frame_system::Pallet::<T>::inc_consumers(&who) {
log::error!(target: LOG_TARGET, "Failed to inc consumers for account {}: {:?}", who.to_ss58check(), e);
return Err(Error::<T>::TODO);
return Err(Error::<T>::FailedToProcessAccount);
}
}
for _ in 0..account.providers {
frame_system::Pallet::<T>::inc_providers(&who);
}

// TODO: publish event
Ok(())
}
}
35 changes: 31 additions & 4 deletions pallets/ah-migrator/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,13 @@ use sp_std::prelude::*;
/// The log target of this pallet.
pub const LOG_TARGET: &str = "runtime::ah-migrator";

type RcAccountFor<T> = RcAccount<
<T as frame_system::Config>::AccountId,
<T as pallet_balances::Config>::Balance,
<T as Config>::RcHoldReason,
<T as Config>::RcFreezeReason,
>;

#[frame_support::pallet(dev_mode)]
pub mod pallet {
use super::*;
Expand Down Expand Up @@ -102,17 +109,38 @@ pub mod pallet {
type RcToProxyDelay: TryConvert<BlockNumberFor<Self>, BlockNumberFor<Self>>;
}

/// RC accounts that failed to migrate when were received on the Asset Hub.
///
/// This is unlikely to happen, since we dry run the migration, but we keep it for completeness.
#[pallet::storage]
pub type RcAccounts<T: Config> =
StorageMap<_, Twox64Concat, T::AccountId, RcAccountFor<T>, OptionQuery>;

#[pallet::error]
pub enum Error<T> {
/// TODO
/// The error that should to be replaced by something meaningful.
TODO,
/// Failed to process an account data from RC.
FailedToProcessAccount,
}

#[pallet::event]
#[pallet::generate_deposit(pub(crate) fn deposit_event)]
pub enum Event<T: Config> {
/// TODO
/// The event that should to be replaced by something meaningful.
TODO,
/// We received a batch of accounts that we are going to integrate.
AccountBatchReceived {
/// How many accounts are in the batch.
count: u32,
},
/// We processed a batch of accounts that we received.
AccountBatchProcessed {
/// How many accounts were successfully integrated.
count_good: u32,
/// How many accounts failed to integrate.
count_bad: u32,
},
/// We received a batch of multisigs that we are going to integrate.
MultisigBatchReceived {
/// How many multisigs are in the batch.
Expand Down Expand Up @@ -164,12 +192,11 @@ pub mod pallet {
#[pallet::call_index(0)]
pub fn receive_accounts(
origin: OriginFor<T>,
accounts: Vec<RcAccount<T::AccountId, T::Balance, T::RcHoldReason, T::RcFreezeReason>>,
accounts: Vec<RcAccountFor<T>>,
) -> DispatchResult {
ensure_root(origin)?;

Self::do_receive_accounts(accounts)?;
// TODO: publish event

Ok(())
}
Expand Down
Loading
Loading