Skip to content

Conversation

@yrong
Copy link
Contributor

@yrong yrong commented May 16, 2025

No description provided.

@yrong yrong changed the title Migrate ForeignToNativeId to XCM V5 Snowbridge: Migrate ForeignToNativeId to XCM V5 May 16, 2025
@yrong
Copy link
Contributor Author

yrong commented May 16, 2025

Just added some tests in a182c17 to demonstrate the following:

  • PNA TokenId generated in V4 is exactly the same as in V5.
  • Location encoded in V4 can be correctly decoded in V5.

Does this mean the migration might not even be nessessary?

@yrong
Copy link
Contributor Author

yrong commented May 16, 2025

Migration test

try-runtime --runtime ./target/release/wbuild/bridge-hub-polkadot-runtime/bridge_hub_polkadot_runtime.wasm on-runtime-upgrade --blocktime 6000 --checks=pre-and-post --disable-spec-version-check --disable-mbm-checks live --uri wss://polkadot-bridge-hub-rpc.polkadot.io

[2025-05-19T02:11:14Z INFO  bridge_hub_polkadot_runtime::bridge_to_ethereum_config::migration] Number of PNAs: 24
[2025-05-19T02:11:14Z INFO  bridge_hub_polkadot_runtime::bridge_to_ethereum_config::migration] PNA migration Location { parents: 1, interior: X2([GlobalConsensus(Polkadot), Parachain(2008)]) } from v4 to v5
[2025-05-19T02:11:14Z INFO  bridge_hub_polkadot_runtime::bridge_to_ethereum_config::migration] PNA migration Location { parents: 1, interior: X1([GlobalConsensus(Polkadot)]) } from v4 to v5
...
[2025-05-19T02:11:14Z INFO  bridge_hub_polkadot_runtime::bridge_to_ethereum_config::migration] PNA migration finished!

@yrong
Copy link
Contributor Author

yrong commented May 27, 2025

@acatangiu Which release do you think we should include this migration? As I mentioned earlier in this comment, the V4-encoded location can be decoded in V5, which makes this PR technically unnessessary.

However, I’d still prefer to merge it just for consistency and to avoid confusion.

@acatangiu
Copy link
Contributor

acatangiu commented May 27, 2025

@acatangiu Which release do you think we should include this migration? As I mentioned earlier in this comment, the V4-encoded location can be decoded in V5, which makes this PR technically unnessessary.

However, I’d still prefer to merge it just for consistency and to avoid confusion.

hmm, I don't understand the question really, this is a runtime migration defined at the runtime level, so not part of any crates released in Polkadot-SDK - nothing to backport

ideally same should be done for Westend and Paseo, on their repos

@yrong
Copy link
Contributor Author

yrong commented May 27, 2025

hmm, I don't understand the question really, this is a runtime migration defined at the runtime level, so not part of any crates released in Polkadot-SDK - nothing to backport

Sorry for the confusion - It's not a backport. I'm just curious has version 1.5.1 been released? Is that the first release to enable XCM V5 on BH? Do we want to include this migration in it?

ideally same should be done for Westend and Paseo, on their repos

We already did that on Westend. Paseo is not actively maintained at the moment.

@acatangiu
Copy link
Contributor

Sorry for the confusion - It's not a backport. I'm just curious has version 1.5.1 been released? Is that the first release to enable XCM V5 on BH? Do we want to include this migration in it?

yes, 1.5.1 is released and live on system chains including BH (spec version is 1005001)

Do we want to include this migration in it?

we should get this migration in master so that it's included with next release

@github-actions github-actions bot requested a review from acatangiu June 6, 2025 04:35
@github-actions
Copy link

github-actions bot commented Jun 6, 2025

Review required! Latest push from author must always be reviewed

@yrong yrong force-pushed the migration-token-id-to-xcm-v5 branch from c459e39 to f8f1d26 Compare July 1, 2025 02:18
@yrong
Copy link
Contributor Author

yrong commented Jul 1, 2025

@bkontur @franciscoaguirre Thanks for the review.

Why is this migration even needed?

Yeah, it's techniquelly not required, as I mentioned in #730 (comment) - it's actually a no-op operation.

I would just add RemoveStorage migration for removing NativeToForeignId storage, which is removed with stable2503 and nothing else.

Nice catch. I've made changes accordingly and tested with try-runtime-cli. The logs show the RemoveStorage migration running as expected.

[2025-07-01T01:17:56Z INFO  bridge_hub_polkadot_runtime::bridge_to_ethereum_config::migration] Number of PNAs: 24
[2025-07-01T01:17:56Z INFO  bridge_hub_polkadot_runtime::bridge_to_ethereum_config::migration] RemoveNativeToForeignId finished!

@yrong yrong changed the title Snowbridge: Migrate ForeignToNativeId to XCM V5 Snowbridge: Remove snowbridge-pallet-system::NativeToForeignId Jul 1, 2025
@yrong yrong requested a review from bkontur July 1, 2025 04:41
bridge_to_kusama_config::XcmOverBridgeHubKusamaInstance,
>,
snowbridge_pallet_system::migration::FeePerGasMigrationV0ToV1<Runtime>,
bridge_to_ethereum_config::migration::RemoveNativeToForeignId<Runtime>,
Copy link
Contributor

Choose a reason for hiding this comment

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

@yrong this PR should really contain just adding one migration and nothing else :), for example:

Suggested change
bridge_to_ethereum_config::migration::RemoveNativeToForeignId<Runtime>,
frame_support::migrations::RemoveStorage<
"EthereumSystem", // <- define as &str param_type
"NativeToForeignId", // <- define as &str param_type
RocksDbWeight,
>,

for example check in polkadot-sdk:

frame_support::migrations::RemoveStorage<
		BridgeWestendMessagesPalletName,
		OutboundLanesCongestedSignalsKey,
		RocksDbWeight,
>

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@bkontur The tests added in this PR are meant to ensure that the PNA transfer don't break in future XCM releases (e.g. XCM V6). The reason is that the tokenID - the key of ForeignToNativeId storage to identify the PNA - was generated from XCM V4 and has already been finalized and stored on Ethereum side.

So we can't allow it to change. The test will fail if there is any compatalibity issue in a future release, so I prefer to keep it as a safeguard.

Meanwhile, I've simplified the migration and made some cleaned things up as you suggested in 1ffb3a0.

@yrong
Copy link
Contributor Author

yrong commented Jul 1, 2025

The logs show the RemoveStorage migration running as expected.

[2025-07-01T09:04:40Z INFO  frame_support::migrations] Found `EthereumSystem` `NativeToForeignId` keys pre-removal 👀
[2025-07-01T09:04:40Z INFO  frame_support::migrations] Removed `24` `EthereumSystem` `NativeToForeignId` keys 🧹
[2025-07-01T09:04:40Z INFO  frame_support::migrations] No `EthereumSystem` `NativeToForeignId` keys found post-removal 🎉

}

#[test]
fn check_token_id_on_chain_derived_from_xcm_v4_is_same_as_value_derived_from_xcm_v5() {
Copy link
Contributor

Choose a reason for hiding this comment

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

@yrong can you add here please some description and/or what to do when this test starts to fail?

Suggested change
fn check_token_id_on_chain_derived_from_xcm_v4_is_same_as_value_derived_from_xcm_v5() {
fn check_compatibility_for_token_id_stored_on_ethereum() {

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Comment on lines 535 to 621
#[test]
fn check_location_encode_in_xcm_v4_can_be_decoded_by_xcm_v5() {
use xcm::v4::prelude::{
GeneralIndex as GeneralIndexV4, GeneralKey as GeneralKeyV4,
GlobalConsensus as GlobalConsensusV4, Kusama as KusamaV4, Location as LocationV4,
PalletInstance as PalletInstanceV4, Parachain as ParachainV4, Polkadot as PolkadotV4,
};
pub struct LocationEncodeDecodeTestCase {
pub v4: LocationV4,
pub latest: Location,
}
let test_cases = vec![
// DOT
LocationEncodeDecodeTestCase {
v4: LocationV4::new(1, GlobalConsensusV4(PolkadotV4)),
latest: Location::new(1, GlobalConsensus(Polkadot)),
},
// KSM
LocationEncodeDecodeTestCase {
v4: LocationV4::new(1, GlobalConsensusV4(KusamaV4)),
latest: Location::new(1, GlobalConsensus(Kusama)),
},
// PINK
LocationEncodeDecodeTestCase {
v4: LocationV4::new(
1,
[
GlobalConsensusV4(PolkadotV4),
ParachainV4(1000),
PalletInstanceV4(50),
GeneralIndexV4(23),
],
),
latest: Location::new(
1,
[GlobalConsensus(Polkadot), Parachain(1000), PalletInstance(50), GeneralIndex(23)],
),
},
// TEER
LocationEncodeDecodeTestCase {
v4: LocationV4::new(1, [GlobalConsensusV4(PolkadotV4), ParachainV4(2039)]),
latest: Location::new(1, [GlobalConsensus(Polkadot), Parachain(2039)]),
},
// Hydration
LocationEncodeDecodeTestCase {
v4: LocationV4::new(
1,
[GlobalConsensusV4(PolkadotV4), ParachainV4(2034), GeneralIndexV4(0)],
),
latest: Location::new(1, [GlobalConsensus(Polkadot), Parachain(2034), GeneralIndex(0)]),
},
// Voucher DOT
LocationEncodeDecodeTestCase {
v4: LocationV4::new(
1,
[
GlobalConsensusV4(PolkadotV4),
ParachainV4(2030),
GeneralKeyV4 {
length: 2,
data: hex!(
"0900000000000000000000000000000000000000000000000000000000000000"
),
},
],
),
latest: Location::new(
1,
[
GlobalConsensus(Polkadot),
Parachain(2030),
GeneralKey {
length: 2,
data: hex!(
"0900000000000000000000000000000000000000000000000000000000000000"
),
},
],
),
},
];
for tc in test_cases.iter() {
let location: Location = Decode::decode(&mut tc.v4.encode().as_slice())
.expect("Stored data should decode to V5 format correctly");
assert_eq!(location, tc.latest);
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

@yrong I think we can remove this test

Suggested change
#[test]
fn check_location_encode_in_xcm_v4_can_be_decoded_by_xcm_v5() {
use xcm::v4::prelude::{
GeneralIndex as GeneralIndexV4, GeneralKey as GeneralKeyV4,
GlobalConsensus as GlobalConsensusV4, Kusama as KusamaV4, Location as LocationV4,
PalletInstance as PalletInstanceV4, Parachain as ParachainV4, Polkadot as PolkadotV4,
};
pub struct LocationEncodeDecodeTestCase {
pub v4: LocationV4,
pub latest: Location,
}
let test_cases = vec![
// DOT
LocationEncodeDecodeTestCase {
v4: LocationV4::new(1, GlobalConsensusV4(PolkadotV4)),
latest: Location::new(1, GlobalConsensus(Polkadot)),
},
// KSM
LocationEncodeDecodeTestCase {
v4: LocationV4::new(1, GlobalConsensusV4(KusamaV4)),
latest: Location::new(1, GlobalConsensus(Kusama)),
},
// PINK
LocationEncodeDecodeTestCase {
v4: LocationV4::new(
1,
[
GlobalConsensusV4(PolkadotV4),
ParachainV4(1000),
PalletInstanceV4(50),
GeneralIndexV4(23),
],
),
latest: Location::new(
1,
[GlobalConsensus(Polkadot), Parachain(1000), PalletInstance(50), GeneralIndex(23)],
),
},
// TEER
LocationEncodeDecodeTestCase {
v4: LocationV4::new(1, [GlobalConsensusV4(PolkadotV4), ParachainV4(2039)]),
latest: Location::new(1, [GlobalConsensus(Polkadot), Parachain(2039)]),
},
// Hydration
LocationEncodeDecodeTestCase {
v4: LocationV4::new(
1,
[GlobalConsensusV4(PolkadotV4), ParachainV4(2034), GeneralIndexV4(0)],
),
latest: Location::new(1, [GlobalConsensus(Polkadot), Parachain(2034), GeneralIndex(0)]),
},
// Voucher DOT
LocationEncodeDecodeTestCase {
v4: LocationV4::new(
1,
[
GlobalConsensusV4(PolkadotV4),
ParachainV4(2030),
GeneralKeyV4 {
length: 2,
data: hex!(
"0900000000000000000000000000000000000000000000000000000000000000"
),
},
],
),
latest: Location::new(
1,
[
GlobalConsensus(Polkadot),
Parachain(2030),
GeneralKey {
length: 2,
data: hex!(
"0900000000000000000000000000000000000000000000000000000000000000"
),
},
],
),
},
];
for tc in test_cases.iter() {
let location: Location = Decode::decode(&mut tc.v4.encode().as_slice())
.expect("Stored data should decode to V5 format correctly");
assert_eq!(location, tc.latest);
}
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

IMHO, this test is also useful, so I'd prefer to keep it. I've added comments in
055f9ee for more details.

Copy link
Contributor

Choose a reason for hiding this comment

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

IMHO, this test is also useful, so I'd prefer to keep it.

Well, this test does not test anything special for Snowbridge or specific onchain stuff like the test before, it just tests "some" compatibility for XCMv4 vs XCMv5 - which should better go directly to the polkadot-sdk/xcm/src/v5 module and not here.

We basically agreed here that XCMv4 vs XCMv5 are compatible, so really this test is not needed here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Make sense. Removed in e051c64

@acatangiu
Copy link
Contributor

/merge

@fellowship-merge-bot fellowship-merge-bot bot enabled auto-merge (squash) July 2, 2025 12:34
@fellowship-merge-bot
Copy link
Contributor

Enabled auto-merge in Pull Request

Available commands
  • /merge: Enables auto-merge for Pull Request
  • /merge cancel: Cancels auto-merge for Pull Request
  • /merge help: Shows this menu

For more information see the documentation

@acatangiu
Copy link
Contributor

@pandres95 can you please review this too? 🙏

@fellowship-merge-bot fellowship-merge-bot bot merged commit d41d01f into polkadot-fellows:main Jul 3, 2025
79 of 82 checks passed
@github-project-automation github-project-automation bot moved this from In Progress to Done in Runtime releases Jul 3, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

7 participants