Skip to content

Commit

Permalink
Add multisig migration
Browse files Browse the repository at this point in the history
Signed-off-by: Oliver Tale-Yazdi <[email protected]>
  • Loading branch information
ggwpez committed Jan 9, 2025
1 parent dde9960 commit 24248d9
Show file tree
Hide file tree
Showing 14 changed files with 506 additions and 117 deletions.
4 changes: 4 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,7 @@ sp-offchain = { version = "34.0.0", default-features = false }
sp-runtime = { version = "39.0.1", default-features = false }
sp-session = { version = "36.0.0", default-features = false }
sp-staking = { version = "36.0.0", default-features = false }
sp-state-machine = { version = "0.43.0", default-features = false }
sp-std = { version = "14.0.0", default-features = false }
sp-storage = { version = "21.0.0", default-features = false }
sp-tracing = { version = "17.0.1", default-features = false }
Expand Down
1 change: 1 addition & 0 deletions integration-tests/ahm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,4 @@ sp-runtime = { workspace = true, default-features = true }
sp-storage = { workspace = true, default-features = true }
sp-tracing = { workspace = true, default-features = true }
tokio = { features = ["full", "macros"], workspace = true }
sp-state-machine = { workspace = true, default-features = true }
17 changes: 17 additions & 0 deletions integration-tests/ahm/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,11 @@
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.

use asset_hub_polkadot_runtime::Block as AssetHubBlock;
use cumulus_primitives_core::{AggregateMessageOrigin, InboundDownwardMessage};
use frame_support::traits::EnqueueMessage;
use polkadot_runtime::Block as PolkadotBlock;
use remote_externalities::{Builder, Mode, OfflineConfig, RemoteExternalities};
use sp_runtime::BoundedVec;

const LOG_RC: &str = "runtime::relay";
const LOG_AH: &str = "runtime::asset-hub";
Expand Down Expand Up @@ -73,3 +76,17 @@ pub fn next_block_ah() {
frame_system::Pallet::<polkadot_runtime::Runtime>::reset_events();
<asset_hub_polkadot_runtime::AhMigrator as frame_support::traits::OnInitialize<_>>::on_initialize(now + 1);
}

/// Enqueue DMP messages on the parachain side.
///
/// This bypasses `set_validation_data` and `enqueue_inbound_downward_messages` by just directly
/// enqueuing them.
pub fn enqueue_dmp(msgs: Vec<InboundDownwardMessage>) {
for msg in msgs {
let bounded_msg: BoundedVec<u8, _> = msg.msg.try_into().expect("DMP message too big");
asset_hub_polkadot_runtime::MessageQueue::enqueue_message(
bounded_msg.as_bounded_slice(),
AggregateMessageOrigin::Parent,
);
}
}
35 changes: 10 additions & 25 deletions integration-tests/ahm/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,10 @@
use cumulus_primitives_core::{AggregateMessageOrigin, ParaId};
use frame_support::{pallet_prelude::*, traits::*, weights::WeightMeter};
use pallet_rc_migrator::RcMigrationStage;
use pallet_rc_migrator::{MigrationStage, RcMigrationStage};
use polkadot_primitives::InboundDownwardMessage;
use polkadot_runtime::RcMigrator;
use sp_core::H256;
use sp_io::TestExternalities;
use sp_storage::StateVersion;
use std::cell::OnceCell;
use remote_externalities::RemoteExternalities;
use tokio::sync::mpsc::channel;

use asset_hub_polkadot_runtime::{Block as AssetHubBlock, Runtime as AssetHub};
use polkadot_runtime::{Block as PolkadotBlock, Runtime as Polkadot};
Expand All @@ -61,13 +58,15 @@ async fn account_migration_works() {

let new_dmps =
runtime_parachains::dmp::DownwardMessageQueues::<Polkadot>::take(para_id);
if new_dmps.is_empty() && !dmps.is_empty() {
break;
}
dmps.extend(new_dmps);
}

dmps
if RcMigrationStage::<Polkadot>::get() ==
pallet_rc_migrator::MigrationStage::MultisigMigrationDone
{
log::info!("Multisig migration done");
break dmps;
}
}
});
rc.commit_all().unwrap();
log::info!("Num of RC->AH DMP messages: {}", dmp_messages.len());
Expand Down Expand Up @@ -95,17 +94,3 @@ async fn account_migration_works() {
// some overweight ones.
});
}

/// Enqueue DMP messages on the parachain side.
///
/// This bypasses `set_validation_data` and `enqueue_inbound_downward_messages` by just directly
/// enqueuing them.
fn enqueue_dmp(msgs: Vec<InboundDownwardMessage>) {
for msg in msgs {
let bounded_msg: BoundedVec<u8, _> = msg.msg.try_into().expect("DMP message too big");
asset_hub_polkadot_runtime::MessageQueue::enqueue_message(
bounded_msg.as_bounded_slice(),
AggregateMessageOrigin::Parent,
);
}
}
5 changes: 5 additions & 0 deletions pallets/ah-migrator/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ frame-support = { workspace = true }
frame-system = { workspace = true }
log = { workspace = true }
pallet-balances = { workspace = true }
pallet-multisig = { workspace = true }
pallet-nomination-pools = { workspace = true }
pallet-preimage = { workspace = true }
pallet-rc-migrator = { workspace = true }
Expand All @@ -29,6 +30,7 @@ sp-core = { workspace = true }
sp-io = { workspace = true }
sp-runtime = { workspace = true }
sp-std = { workspace = true }
hex-literal = { workspace = true }

[features]
default = ["std"]
Expand All @@ -54,6 +56,7 @@ std = [
"sp-io/std",
"sp-runtime/std",
"sp-std/std",
"pallet-multisig/std"
]
runtime-benchmarks = [
"frame-benchmarking/runtime-benchmarks",
Expand All @@ -69,6 +72,7 @@ runtime-benchmarks = [
"polkadot-runtime-common/runtime-benchmarks",
"runtime-parachains/runtime-benchmarks",
"sp-runtime/runtime-benchmarks",
"pallet-multisig/runtime-benchmarks"
]
try-runtime = [
"frame-support/try-runtime",
Expand All @@ -82,4 +86,5 @@ try-runtime = [
"polkadot-runtime-common/try-runtime",
"runtime-parachains/try-runtime",
"sp-runtime/try-runtime",
"pallet-multisig/try-runtime"
]
52 changes: 41 additions & 11 deletions pallets/ah-migrator/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#![cfg_attr(not(feature = "std"), no_std)]

pub mod multisig;
pub mod types;
pub use pallet::*;

Expand All @@ -44,7 +45,7 @@ use frame_support::{
};
use frame_system::pallet_prelude::*;
use pallet_balances::{AccountData, Reasons as LockReasons};
use pallet_rc_migrator::accounts::Account as RcAccount;
use pallet_rc_migrator::{accounts::Account as RcAccount, multisig::*};
use sp_application_crypto::Ss58Codec;
use sp_runtime::{traits::Convert, AccountId32};
use sp_std::prelude::*;
Expand All @@ -62,6 +63,7 @@ pub mod pallet {
pub trait Config:
frame_system::Config<AccountData = AccountData<u128>, AccountId = AccountId32>
+ pallet_balances::Config<Balance = u128>
+ pallet_multisig::Config
{
/// The overarching event type.
type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;
Expand Down Expand Up @@ -91,10 +93,21 @@ pub mod pallet {
}

#[pallet::event]
//#[pallet::generate_deposit(pub(crate) fn deposit_event)]
#[pallet::generate_deposit(pub(crate) fn deposit_event)]
pub enum Event<T: Config> {
/// TODO
TODO,
/// We received a batch of multisigs that we are going to integrate.
MultisigBatchReceived {
/// How many multisigs are in the batch.
count: u32,
},
MultisigBatchProcessed {
/// How many multisigs were successfully integrated.
count_good: u32,
/// How many multisigs failed to integrate.
count_bad: u32,
},
}

#[pallet::pallet]
Expand All @@ -109,7 +122,6 @@ pub mod pallet {
///
/// The accounts that sent with `pallet_rc_migrator::Pallet::migrate_accounts` function.
#[pallet::call_index(0)]
#[pallet::weight({1})]
pub fn receive_accounts(
origin: OriginFor<T>,
accounts: Vec<RcAccount<T::AccountId, T::Balance, T::RcHoldReason, T::RcFreezeReason>>,
Expand All @@ -121,13 +133,28 @@ pub mod pallet {

Ok(())
}

/// Receive multisigs from the Relay Chain.
///
/// This will be called from an XCM `Transact` inside a DMP from the relay chain. The
/// multisigs were prepared by
/// `pallet_rc_migrator::multisig::MultisigMigrator::migrate_many`.
#[pallet::call_index(1)]
pub fn receive_multisigs(
origin: OriginFor<T>,
accounts: Vec<RcMultisigOf<T>>,
) -> DispatchResult {
ensure_root(origin)?;

Self::do_receive_multisigs(accounts).map_err(Into::into)
}
}

impl<T: Config> Pallet<T> {
fn do_receive_accounts(
accounts: Vec<RcAccount<T::AccountId, T::Balance, T::RcHoldReason, T::RcFreezeReason>>,
) -> Result<(), Error<T>> {
log::debug!(target: LOG_TARGET, "Integrating {} accounts", accounts.len());
log::info!(target: LOG_TARGET, "Integrating {} accounts", accounts.len());

for account in accounts {
let _: Result<(), ()> = with_transaction_opaque_err::<(), (), _>(|| {
Expand All @@ -148,7 +175,7 @@ pub mod pallet {
) -> Result<(), Error<T>> {
let who = account.who;
let total_balance = account.free + account.reserved;
let minted = match T::Currency::mint_into(&who, total_balance) {
let minted = match <T as pallet::Config>::Currency::mint_into(&who, total_balance) {
Ok(minted) => minted,
Err(e) => {
log::error!(target: LOG_TARGET, "Failed to mint into account {}: {:?}", who.to_ss58check(), e);
Expand All @@ -158,21 +185,24 @@ pub mod pallet {
debug_assert!(minted == total_balance);

for hold in account.holds {
if let Err(e) =
T::Currency::hold(&T::RcToAhHoldReason::convert(hold.id), &who, hold.amount)
{
if let Err(e) = <T as pallet::Config>::Currency::hold(
&T::RcToAhHoldReason::convert(hold.id),
&who,
hold.amount,
) {
log::error!(target: LOG_TARGET, "Failed to hold into account {}: {:?}", who.to_ss58check(), e);
return Err(Error::<T>::TODO);
}
}

if let Err(e) = T::Currency::reserve(&who, account.unnamed_reserve) {
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);
}

for freeze in account.freezes {
if let Err(e) = T::Currency::set_freeze(
if let Err(e) = <T as pallet::Config>::Currency::set_freeze(
&T::RcToAhFreezeReason::convert(freeze.id),
&who,
freeze.amount,
Expand All @@ -183,7 +213,7 @@ pub mod pallet {
}

for lock in account.locks {
T::Currency::set_lock(
<T as pallet::Config>::Currency::set_lock(
lock.id,
&who,
lock.amount,
Expand Down
54 changes: 54 additions & 0 deletions pallets/ah-migrator/src/multisig.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
use crate::{types::*, *};
use hex_literal::hex;

/// These multisigs have historical issues where the deposit is missing for the creator.
const KNOWN_BAD_MULTISIGS: &[AccountId32] = &[
AccountId32::new(hex!("e64d5c0de81b9c960c1dd900ad2a5d9d91c8a683e60dd1308e6bc7f80ea3b25f")),
AccountId32::new(hex!("d55ec415b6703ddf7bec9d5c02a0b642f1f5bd068c6b3c50c2145544046f1491")),
AccountId32::new(hex!("c2ff4f84b7fcee1fb04b4a97800e72321a4bc9939d456ad48d971127fc661c48")),
AccountId32::new(hex!("0a8933d3f2164648399cc48cb8bb8c915abb94a2164c40ad6b48cee005f1cb6e")),
AccountId32::new(hex!("ebe3cd53e580c4cd88acec1c952585b50a44a9b697d375ff648fee582ae39d38")),
AccountId32::new(hex!("e64d5c0de81b9c960c1dd900ad2a5d9d91c8a683e60dd1308e6bc7f80ea3b25f")),
AccountId32::new(hex!("caafae0aaa6333fcf4dc193146945fe8e4da74aa6c16d481eef0ca35b8279d73")),
AccountId32::new(hex!("d429458e57ba6e9b21688441ff292c7cf82700550446b061a6c5dec306e1ef05")),
];

impl<T: Config> Pallet<T> {
pub fn do_receive_multisigs(multisigs: Vec<RcMultisigOf<T>>) -> Result<(), Error<T>> {
Self::deposit_event(Event::MultisigBatchReceived { count: multisigs.len() as u32 });
let (mut count_good, mut count_bad) = (0, 0);
log::info!(target: LOG_TARGET, "Integrating {} multisigs", multisigs.len());

for multisig in multisigs {
match Self::do_receive_multisig(multisig) {
Ok(()) => count_good += 1,
Err(e) => {
count_bad += 1;
log::error!(target: LOG_TARGET, "Error while integrating multisig: {:?}", e);
},
}
}
Self::deposit_event(Event::MultisigBatchProcessed { count_good, count_bad });

Ok(())
}

pub fn do_receive_multisig(multisig: RcMultisigOf<T>) -> Result<(), Error<T>> {
log::debug!(target: LOG_TARGET, "Integrating multisig {}, {:?}", multisig.creator.to_ss58check(), multisig.deposit);

let missing = <T as pallet_multisig::Config>::Currency::unreserve(
&multisig.creator,
multisig.deposit,
);
if missing != Default::default() {
if KNOWN_BAD_MULTISIGS.contains(&multisig.creator) {
log::warn!(target: LOG_TARGET, "Failed to unreserve deposit for known bad multisig {}, missing: {:?}", multisig.creator.to_ss58check(), missing);

log::warn!("{:?}", frame_system::Account::<T>::get(&multisig.creator));
} else {
log::error!(target: LOG_TARGET, "Failed to unreserve deposit for multisig {} missing {:?}, details: {:?}", multisig.creator.to_ss58check(), missing, multisig.details);
}
}
Ok(())
}
}
7 changes: 4 additions & 3 deletions pallets/rc-migrator/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,16 @@ codec = { workspace = true, features = ["max-encoded-len"] }
scale-info = { workspace = true, features = ["derive"] }
serde = { features = ["derive"], optional = true, workspace = true }
log = { workspace = true }

frame-benchmarking = { workspace = true, optional = true }
frame-support = { workspace = true }
frame-system = { workspace = true }
sp-core = { workspace = true }
sp-runtime = { workspace = true }
sp-std = { workspace = true }
sp-io = { workspace = true }

pallet-balances = { workspace = true }
pallet-staking = { workspace = true }

pallet-multisig = { workspace = true }
polkadot-runtime-common = { workspace = true }
runtime-parachains = { workspace = true }
polkadot-parachain-primitives = { workspace = true }
Expand All @@ -50,6 +48,7 @@ std = [
"sp-runtime/std",
"sp-std/std",
"xcm/std",
"pallet-multisig/std"
]
runtime-benchmarks = [
"frame-benchmarking/runtime-benchmarks",
Expand All @@ -61,6 +60,7 @@ runtime-benchmarks = [
"polkadot-runtime-common/runtime-benchmarks",
"runtime-parachains/runtime-benchmarks",
"sp-runtime/runtime-benchmarks",
"pallet-multisig/runtime-benchmarks"
]
try-runtime = [
"frame-support/try-runtime",
Expand All @@ -70,4 +70,5 @@ try-runtime = [
"polkadot-runtime-common/try-runtime",
"runtime-parachains/try-runtime",
"sp-runtime/try-runtime",
"pallet-multisig/try-runtime"
]
Loading

0 comments on commit 24248d9

Please sign in to comment.