From 5b92bd0689d3a05237f673736a87f50450d7503f Mon Sep 17 00:00:00 2001 From: claravanstaden Date: Mon, 4 Nov 2024 16:24:36 +0200 Subject: [PATCH] xcm decoding --- Cargo.lock | 1 + .../pallets/inbound-queue-v2/Cargo.toml | 1 + .../pallets/inbound-queue-v2/src/test.rs | 111 +++++++++++++++++- 3 files changed, 111 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 80b763792b44..e0fc00e3c524 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -21325,6 +21325,7 @@ dependencies = [ "frame-benchmarking", "frame-support", "frame-system", + "hex", "hex-literal", "log", "pallet-balances", diff --git a/bridges/snowbridge/pallets/inbound-queue-v2/Cargo.toml b/bridges/snowbridge/pallets/inbound-queue-v2/Cargo.toml index d212b18d2d54..4d589b86e142 100644 --- a/bridges/snowbridge/pallets/inbound-queue-v2/Cargo.toml +++ b/bridges/snowbridge/pallets/inbound-queue-v2/Cargo.toml @@ -45,6 +45,7 @@ frame-benchmarking = { workspace = true, default-features = true } sp-keyring = { workspace = true, default-features = true } snowbridge-pallet-ethereum-client = { workspace = true, default-features = true } hex-literal = { workspace = true, default-features = true } +hex = { workspace = true, default-features = true } [features] default = ["std"] diff --git a/bridges/snowbridge/pallets/inbound-queue-v2/src/test.rs b/bridges/snowbridge/pallets/inbound-queue-v2/src/test.rs index 5420db36fb47..d195c21f85a2 100644 --- a/bridges/snowbridge/pallets/inbound-queue-v2/src/test.rs +++ b/bridges/snowbridge/pallets/inbound-queue-v2/src/test.rs @@ -9,7 +9,12 @@ use sp_keyring::AccountKeyring as Keyring; use sp_runtime::DispatchError; use crate::{mock::*, Error, Event as InboundQueueEvent}; -use snowbridge_router_primitives::inbound::v2::Asset; +use snowbridge_router_primitives::inbound::v2::Asset as InboundAsset; +use sp_core::H256; +use xcm::opaque::latest::prelude::ClearOrigin; +use xcm::opaque::latest::Asset; +use xcm::opaque::latest::prelude::ReceiveTeleportedAsset; +use codec::DecodeLimit; #[test] fn test_submit_happy_path() { @@ -158,7 +163,7 @@ fn test_send_native_erc20_token_payload() { assert_eq!(expected_origin, inbound_message.origin); assert_eq!(1, inbound_message.assets.len()); - if let Asset::NativeTokenERC20 { token_id, value } = &inbound_message.assets[0] { + if let InboundAsset::NativeTokenERC20 { token_id, value } = &inbound_message.assets[0] { assert_eq!(expected_token_id, *token_id); assert_eq!(expected_value, *value); } else { @@ -168,3 +173,105 @@ fn test_send_native_erc20_token_payload() { assert_eq!(expected_claimer, inbound_message.claimer); }); } + +#[test] +fn test_send_foreign_erc20_token_payload() { + new_tester().execute_with(|| { + let payload = hex!("29e3b139f4393adda86303fcdaa35f60bb7092bf040197874824853fb4ad04794ccfd1cc8d2a7463839cfcbc6a315a1045c60ab85f400000b2d3595bf00600000000000000000000").to_vec(); + let message = MessageV2::decode(&mut payload.as_ref()); + assert_ok!(message.clone()); + + let inbound_message = message.unwrap(); + + let expected_origin: H160 = hex!("29e3b139f4393adda86303fcdaa35f60bb7092bf").into(); + let expected_token_id: H256 = hex!("97874824853fb4ad04794ccfd1cc8d2a7463839cfcbc6a315a1045c60ab85f40").into(); + let expected_value = 500000000000000000u128; + let expected_xcm: Vec = vec![]; + let expected_claimer: Option> = None; + + assert_eq!(expected_origin, inbound_message.origin); + assert_eq!(1, inbound_message.assets.len()); + if let InboundAsset::ForeignTokenERC20 { token_id, value } = &inbound_message.assets[0] { + assert_eq!(expected_token_id, *token_id); + assert_eq!(expected_value, *value); + } else { + panic!("Expected ForeignTokenERC20 asset"); + } + assert_eq!(expected_xcm, inbound_message.xcm); + assert_eq!(expected_claimer, inbound_message.claimer); + }); +} + +#[test] +fn test_inbound_message_with_xcm() { + new_tester().execute_with(|| { + let payload = hex!("29e3b139f4393adda86303fcdaa35f60bb7092bf040197874824853fb4ad04794ccfd1cc8d2a7463839cfcbc6a315a1045c60ab85f400000b2d3595bf00600000000000000000c0508020401000002286bee0a00").to_vec(); + let message = MessageV2::decode(&mut payload.as_ref()); + assert_ok!(message.clone()); + + let inbound_message = message.unwrap(); + + let expected_origin: H160 = hex!("29e3b139f4393adda86303fcdaa35f60bb7092bf").into(); + let expected_token_id: H256 = hex!("97874824853fb4ad04794ccfd1cc8d2a7463839cfcbc6a315a1045c60ab85f40").into(); + let expected_value = 500000000000000000u128; + let expected_xcm: Vec = vec![]; + let expected_claimer: Option> = None; + + assert_eq!(expected_origin, inbound_message.origin); + assert_eq!(1, inbound_message.assets.len()); + if let InboundAsset::ForeignTokenERC20 { token_id, value } = &inbound_message.assets[0] { + assert_eq!(expected_token_id, *token_id); + assert_eq!(expected_value, *value); + } else { + panic!("Expected ForeignTokenERC20 asset"); + } + assert_eq!(expected_xcm, inbound_message.xcm); + assert_eq!(expected_claimer, inbound_message.claimer); + }); +} + +#[test] +fn encode_xcm() { + new_tester().execute_with(|| { + let total_fee_asset: Asset = (Location::parent(), 1_000_000_000).into(); + + let mut instructions: Xcm<()> = vec![ + ReceiveTeleportedAsset(total_fee_asset.into()), + ClearOrigin, + ].into(); + + let versioned_xcm_message = VersionedXcm::V5(instructions.clone()); + + let xcm_bytes = VersionedXcm::encode(&versioned_xcm_message); + let hex_string = hex::encode(xcm_bytes.clone()); + + println!("xcm hex: {}", hex_string); + + let versioned_xcm = VersionedXcm::<()>::decode_with_depth_limit( + MAX_XCM_DECODE_DEPTH, + &mut xcm_bytes.as_ref(), + ); + + assert_ok!(versioned_xcm.clone()); + + // Check if decoding was successful + let decoded_instructions = match versioned_xcm.unwrap() { + VersionedXcm::V5(decoded) => decoded, + _ => { + panic!("unexpected xcm version found") + } + }; + + let mut original_instructions = instructions.into_iter(); + let mut decoded_instructions = decoded_instructions.into_iter(); + + let original_first = original_instructions.next().take(); + let decoded_first = decoded_instructions.next().take(); + assert_eq!(original_first, decoded_first, "First instruction (ReceiveTeleportedAsset) does not match."); + + let original_second = original_instructions.next().take(); + let decoded_second = decoded_instructions.next().take(); + assert_eq!(original_second, decoded_second, "Second instruction (ClearOrigin) does not match."); + }); +} +