Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
3 changes: 3 additions & 0 deletions Cargo.lock

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

10 changes: 8 additions & 2 deletions container-chains/runtime-templates/simple/src/migrations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ use {
},
pallet_migrations::{GetMigrations, Migration},
runtime_common::migrations::{
PolkadotXcmMigrationFixVersion, XcmpQueueMigrationFixVersion, XcmpQueueMigrationV3,
XcmpQueueMigrationV4,
ForeignAssetCreatorMigration, PolkadotXcmMigrationFixVersion, XcmpQueueMigrationFixVersion,
XcmpQueueMigrationV3, XcmpQueueMigrationV4,
},
sp_std::{marker::PhantomData, prelude::*},
};
Expand Down Expand Up @@ -71,6 +71,9 @@ where
Runtime: cumulus_pallet_xcmp_queue::Config,
Runtime: pallet_xcm_executor_utils::Config,
Runtime: pallet_xcm::Config,
Runtime: pallet_foreign_asset_creator::Config,
<Runtime as pallet_foreign_asset_creator::Config>::ForeignAsset:
TryFrom<staging_xcm::v3::MultiLocation>,
{
fn get_migrations() -> Vec<Box<dyn Migration>> {
let migrate_polkadot_xcm_v1 =
Expand All @@ -82,13 +85,16 @@ where
let migrate_xcm_executor_utils_v4 =
pallet_xcm_executor_utils::migrations::MigrateToV1::<Runtime>(Default::default());
let migrate_pallet_xcm_v4 = MigrateToLatestXcmVersion::<Runtime>(Default::default());
let foreign_asset_creator_migration =
ForeignAssetCreatorMigration::<Runtime>(Default::default());
vec![
Box::new(migrate_polkadot_xcm_v1),
Box::new(migrate_xcmp_queue_v2),
Box::new(migrate_xcmp_queue_v3),
Box::new(migrate_xcmp_queue_v4),
Box::new(migrate_xcm_executor_utils_v4),
Box::new(migrate_pallet_xcm_v4),
Box::new(foreign_asset_creator_migration),
]
}
}
8 changes: 8 additions & 0 deletions runtime/common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,14 @@ workspace = true

[dependencies]
hex-literal = { workspace = true }
log = { workspace = true }
parity-scale-codec = { workspace = true, features = [ "derive" ] }
scale-info = { workspace = true, features = [ "derive" ] }

# Own
pallet-configuration = { workspace = true }
pallet-data-preservers = { workspace = true }
pallet-foreign-asset-creator = { workspace = true }
pallet-invulnerables = { workspace = true }
pallet-pooled-staking = { workspace = true }
pallet-registrar = { workspace = true }
Expand All @@ -41,6 +43,7 @@ cumulus-pallet-xcmp-queue = { workspace = true }

# Polkadot
pallet-xcm = { workspace = true }
staging-xcm = { workspace = true }

sp-core = { workspace = true }
sp-runtime = { workspace = true }
Expand All @@ -59,9 +62,11 @@ std = [
"frame-support/std",
"frame-system/std",
"frame-try-runtime?/std",
"log/std",
"pallet-balances/std",
"pallet-configuration/std",
"pallet-data-preservers/std",
"pallet-foreign-asset-creator/std",
"pallet-invulnerables/std",
"pallet-migrations/std",
"pallet-pooled-staking/std",
Expand All @@ -74,6 +79,7 @@ std = [
"sp-core/std",
"sp-runtime/std",
"sp-std/std",
"staging-xcm/std",
]

runtime-benchmarks = [
Expand All @@ -84,6 +90,7 @@ runtime-benchmarks = [
"pallet-balances/runtime-benchmarks",
"pallet-configuration/runtime-benchmarks",
"pallet-data-preservers/runtime-benchmarks",
"pallet-foreign-asset-creator/runtime-benchmarks",
"pallet-invulnerables/runtime-benchmarks",
"pallet-migrations/runtime-benchmarks",
"pallet-pooled-staking/runtime-benchmarks",
Expand All @@ -102,6 +109,7 @@ try-runtime = [
"pallet-balances/try-runtime",
"pallet-configuration/try-runtime",
"pallet-data-preservers/try-runtime",
"pallet-foreign-asset-creator/try-runtime",
"pallet-invulnerables/try-runtime",
"pallet-migrations/try-runtime",
"pallet-pooled-staking/try-runtime",
Expand Down
89 changes: 89 additions & 0 deletions runtime/common/src/migrations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,19 @@

#[cfg(feature = "try-runtime")]
use frame_support::ensure;
use frame_support::migration::storage_key_iter;

use {
cumulus_primitives_core::ParaId,
frame_support::{
pallet_prelude::GetStorageVersion,
traits::{OnRuntimeUpgrade, PalletInfoAccess, StorageVersion},
weights::Weight,
StoragePrefixedMap,
},
pallet_configuration::{weights::WeightInfo as _, HostConfiguration},
pallet_foreign_asset_creator::AssetId,
pallet_foreign_asset_creator::{AssetIdToForeignAsset, ForeignAssetToAssetId},
pallet_migrations::{GetMigrations, Migration},
sp_core::Get,
sp_std::{collections::btree_set::BTreeSet, marker::PhantomData, prelude::*},
Expand Down Expand Up @@ -516,6 +520,9 @@ where
Runtime: pallet_xcm::Config,
<Runtime as pallet_balances::Config>::RuntimeHoldReason:
From<pallet_pooled_staking::HoldReason>,
Runtime: pallet_foreign_asset_creator::Config,
<Runtime as pallet_foreign_asset_creator::Config>::ForeignAsset:
TryFrom<staging_xcm::v3::MultiLocation>,
{
fn get_migrations() -> Vec<Box<dyn Migration>> {
// let migrate_invulnerables = MigrateInvulnerables::<Runtime>(Default::default());
Expand All @@ -540,6 +547,8 @@ where
RegistrarParaManagerMigration::<Runtime>(Default::default());

let migrate_pallet_xcm_v4 = MigrateToLatestXcmVersion::<Runtime>(Default::default());
let foreign_asset_creator_migration =
ForeignAssetCreatorMigration::<Runtime>(Default::default());

vec![
// Applied in runtime 200
Expand All @@ -564,6 +573,86 @@ where
Box::new(migrate_registrar_pending_verification),
Box::new(migrate_registrar_manager),
Box::new(migrate_pallet_xcm_v4),
Box::new(foreign_asset_creator_migration),
]
}
}

pub struct ForeignAssetCreatorMigration<Runtime>(pub PhantomData<Runtime>);

impl<Runtime> Migration for ForeignAssetCreatorMigration<Runtime>
where
Runtime: pallet_foreign_asset_creator::Config,
<Runtime as pallet_foreign_asset_creator::Config>::ForeignAsset:
TryFrom<staging_xcm::v3::MultiLocation>,
{
fn friendly_name(&self) -> &str {
"TM_ForeignAssetCreatorMigration"
}

fn migrate(&self, _available_weight: Weight) -> Weight {
use frame_support::pallet_prelude::*;

use staging_xcm::v3::MultiLocation as OldLocation;

let pallet_prefix = AssetIdToForeignAsset::<Runtime>::pallet_prefix();
let asset_id_to_foreign_asset_storage_prefix =
AssetIdToForeignAsset::<Runtime>::storage_prefix();
let foreign_asset_to_asset_id_prefix = ForeignAssetToAssetId::<Runtime>::storage_prefix();

// Data required to migrate ForeignAsset values
// Read all the data into memory.
let asset_id_to_foreign_asset_data: Vec<_> =
storage_key_iter::<AssetId<Runtime>, OldLocation, Blake2_128Concat>(
pallet_prefix,
asset_id_to_foreign_asset_storage_prefix,
)
.drain()
.collect();

// Data required to migrate ForeignAsset keys
let foreign_asset_to_asset_id_data: Vec<_> =
storage_key_iter::<OldLocation, AssetId<Runtime>, Blake2_128Concat>(
pallet_prefix,
foreign_asset_to_asset_id_prefix,
)
.drain()
.collect();

let migrated_count = asset_id_to_foreign_asset_data
.len()
.saturating_add(foreign_asset_to_asset_id_data.len());

log::info!("Migrating {:?} elements", migrated_count);

// Write to the new storage with removed and added fields
for (asset_id, old_location) in asset_id_to_foreign_asset_data {
if let Ok(new_location) = Runtime::ForeignAsset::try_from(old_location) {
AssetIdToForeignAsset::<Runtime>::insert(asset_id, new_location);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

YOu can probably do both migrations here and not iterate twice

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm. But, that would mean I am assuming the semantics of these two storage items in runtime.

} else {
log::warn!("Location could not be converted safely to xcmV4")
}
}

for (old_location, asset_id) in foreign_asset_to_asset_id_data {
if let Ok(new_location) = Runtime::ForeignAsset::try_from(old_location) {
ForeignAssetToAssetId::<Runtime>::insert(new_location, asset_id);
} else {
log::warn!("Location could not be converted safely to xcmV4")
}
}

// One db read and one db write per element, plus the on-chain storage
Runtime::DbWeight::get().reads_writes(migrated_count as u64, 2 * migrated_count as u64)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see, 1 write when using drain, and another write when using insert...

}

#[cfg(feature = "try-runtime")]
fn pre_upgrade(&self) -> Result<Vec<u8>, DispatchError> {
Ok(vec![])
}

#[cfg(feature = "try-runtime")]
fn post_upgrade(&self, _state: Vec<u8>) -> Result<(), DispatchError> {
Ok(())
}
}
99 changes: 99 additions & 0 deletions runtime/dancebox/tests/integration_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,17 @@

#![cfg(test)]

use dancebox_runtime::xcm_config::ForeignAssetsInstance;
use frame_support::migration::put_storage_value;
use frame_support::storage::generator::StorageMap;
use frame_support::Hashable;
use pallet_foreign_asset_creator::{AssetIdToForeignAsset, ForeignAssetToAssetId};
use runtime_common::migrations::ForeignAssetCreatorMigration;
use staging_xcm::v3::{
Junction as V3Junction, Junctions as V3Junctions, MultiLocation as V3MultiLocation,
NetworkId as V3NetworkId,
};
use std::marker::PhantomData;
use {
common::*,
cumulus_primitives_core::ParaId,
Expand Down Expand Up @@ -5581,6 +5592,94 @@ fn test_migration_services_collator_assignment_payment() {
});
}

#[test]
fn test_migration_foreign_asset_creator() {
ExtBuilder::default().build().execute_with(|| {
// Sample pairs of asset id with v3 location
let (asset_id1, location_1) = (
<Runtime as pallet_assets::Config<ForeignAssetsInstance>>::AssetId::from(13u16),
V3MultiLocation::new(
1,
V3Junctions::X2(
V3Junction::PalletInstance(1),
V3Junction::AccountIndex64 {
network: Some(V3NetworkId::BitcoinCore),
index: 5,
},
),
),
);

let (asset_id2, location_2) = (
<Runtime as pallet_assets::Config<ForeignAssetsInstance>>::AssetId::from(14u16),
V3MultiLocation::new(
1,
V3Junctions::X2(
V3Junction::PalletInstance(2),
V3Junction::AccountIndex64 {
network: Some(V3NetworkId::Kusama),
index: 10,
},
),
),
);

put_storage_value(
AssetIdToForeignAsset::<Runtime>::pallet_prefix(),
AssetIdToForeignAsset::<Runtime>::storage_prefix(),
&asset_id1.blake2_128_concat(),
location_1,
);
put_storage_value(
AssetIdToForeignAsset::<Runtime>::pallet_prefix(),
AssetIdToForeignAsset::<Runtime>::storage_prefix(),
&asset_id2.blake2_128_concat(),
location_2,
);

put_storage_value(
ForeignAssetToAssetId::<Runtime>::pallet_prefix(),
ForeignAssetToAssetId::<Runtime>::storage_prefix(),
&location_1.blake2_128_concat(),
asset_id1,
);
put_storage_value(
ForeignAssetToAssetId::<Runtime>::pallet_prefix(),
ForeignAssetToAssetId::<Runtime>::storage_prefix(),
&location_2.blake2_128_concat(),
asset_id2,
);

// Let's run the migration now
let foreign_asset_creator_migration: ForeignAssetCreatorMigration<Runtime> =
ForeignAssetCreatorMigration(PhantomData);
let weight_consumed = foreign_asset_creator_migration.migrate(Default::default());
assert_eq!(
weight_consumed,
<Runtime as frame_system::Config>::DbWeight::get().reads_writes(1 * 4, 2 * 4)
);

// Let's check if everything is migrated properly
assert_eq!(
AssetIdToForeignAsset::<Runtime>::get(asset_id1),
Some(Location::try_from(location_1).unwrap())
);
assert_eq!(
AssetIdToForeignAsset::<Runtime>::get(asset_id2),
Some(Location::try_from(location_2).unwrap())
);

assert_eq!(
ForeignAssetToAssetId::<Runtime>::get(Location::try_from(location_1).unwrap()),
Some(asset_id1)
);
assert_eq!(
ForeignAssetToAssetId::<Runtime>::get(Location::try_from(location_2).unwrap()),
Some(asset_id2)
);
});
}

#[test]
fn test_max_collators_uses_pending_value() {
// Start with max_collators = 100, and collators_per_container = 2
Expand Down