From 798229c61137f4f063c9a059e03b9259a8ac24b6 Mon Sep 17 00:00:00 2001 From: Alistair Singh Date: Fri, 24 Jan 2025 13:27:38 +0200 Subject: [PATCH] factor test --- .../src/tests/snowbridge.rs | 281 ++++-------------- 1 file changed, 66 insertions(+), 215 deletions(-) diff --git a/integration-tests/emulated/tests/bridges/bridge-hub-polkadot/src/tests/snowbridge.rs b/integration-tests/emulated/tests/bridges/bridge-hub-polkadot/src/tests/snowbridge.rs index 4f0eb45d26..30fd0e1d6f 100644 --- a/integration-tests/emulated/tests/bridges/bridge-hub-polkadot/src/tests/snowbridge.rs +++ b/integration-tests/emulated/tests/bridges/bridge-hub-polkadot/src/tests/snowbridge.rs @@ -461,9 +461,12 @@ fn send_weth_from_ethereum_to_asset_hub() { }); } -/// Tests sending ether from Ethereum to Asset Hub and back to Ethereum -#[test] -fn send_eth_asset_from_asset_hub_to_ethereum() { +// Performs a round trip tansfer of a token, asseting success. +fn send_token_from_ethereum_to_asset_hub_and_back_works( + token_address: H160, + amount: u128, + asset_location: Location, +) { let assethub_sovereign = BridgeHubPolkadot::sovereign_account_id_of( BridgeHubPolkadot::sibling_location_of(AssetHubPolkadot::para_id()), ); @@ -477,40 +480,35 @@ fn send_eth_asset_from_asset_hub_to_ethereum() { (ethereum_sovereign_account(), INITIAL_FUND), ]); - let ether_location: Location = (Parent, Parent, EthereumNetwork::get()).into(); - - // Register Ether as foreign asset on AH. + // Set base transfer fee to Ethereum on AH. AssetHubPolkadot::execute_with(|| { - type RuntimeEvent = ::RuntimeEvent; type RuntimeOrigin = ::RuntimeOrigin; - // Set base transfer fee to Ethereum on AH. assert_ok!(::System::set_storage( - ::RuntimeOrigin::root(), - vec![(BridgeHubEthereumBaseFee::key().to_vec(), AH_BASE_FEE.encode())], - )); - - // Register Ether - assert_ok!(::ForeignAssets::force_create( RuntimeOrigin::root(), - ether_location.clone(), - ethereum_sovereign_account().into(), - true, - MIN_ETHER_BALANCE, + vec![(BridgeHubEthereumBaseFee::key().to_vec(), AH_BASE_FEE.encode())], )); - - assert_expected_events!( - AssetHubPolkadot, - vec![ - RuntimeEvent::ForeignAssets(pallet_assets::Event::ForceCreated { .. }) => {}, - ] - ); }); - // Send Ether from Bridge Hub (simulates received Command from Ethereum) + // Send Token from Bridge Hub (simulates received Command from Ethereum) BridgeHubPolkadot::execute_with(|| { type RuntimeEvent = ::RuntimeEvent; + assert_ok!( + ::EthereumSystem::set_pricing_parameters( + ::RuntimeOrigin::root(), + PricingParametersOf:: { + exchange_rate: FixedU128::from_rational(1, 75), + fee_per_gas: gwei(20), + rewards: Rewards { + local: (UNITS / 100), // 0.01 DOT + remote: meth(1), + }, + multiplier: FixedU128::from_rational(1, 1), + } + ) + ); + assert_ok!(::System::set_storage( ::RuntimeOrigin::root(), vec![(EthereumGatewayAddress::key().to_vec(), H160(GATEWAY_ADDRESS).encode())], @@ -521,11 +519,11 @@ fn send_eth_asset_from_asset_hub_to_ethereum() { let message = VersionedMessage::V1(MessageV1 { chain_id: CHAIN_ID, command: Command::SendToken { - token: ETHER_TOKEN_ADDRESS.into(), + token: token_address, destination: Destination::AccountId32 { id: AssetHubPolkadotReceiver::get().into(), }, - amount: MIN_ETHER_BALANCE + TOKEN_AMOUNT, + amount, fee: XCM_FEE, }, }); @@ -543,7 +541,7 @@ fn send_eth_asset_from_asset_hub_to_ethereum() { ); }); - // Receive Ether on Asset Hub. + // Receive Token on Asset Hub. AssetHubPolkadot::execute_with(|| { type RuntimeEvent = ::RuntimeEvent; @@ -551,7 +549,9 @@ fn send_eth_asset_from_asset_hub_to_ethereum() { assert_expected_events!( AssetHubPolkadot, vec![ - RuntimeEvent::ForeignAssets(pallet_assets::Event::Issued { .. }) => {}, + RuntimeEvent::ForeignAssets(pallet_assets::Event::Issued { asset_id, .. }) => { + asset_id: *asset_id == asset_location, + }, ] ); }); @@ -560,11 +560,11 @@ fn send_eth_asset_from_asset_hub_to_ethereum() { <::Balances as frame_support::traits::fungible::Inspect<_>>::balance(&RelayTreasuryPalletAccount::get()) }); - // Send Ether from Asset Hub back to Ethereum. + // Send Token from Asset Hub back to Ethereum. AssetHubPolkadot::execute_with(|| { type RuntimeOrigin = ::RuntimeOrigin; - let assets = vec![Asset { id: AssetId(ether_location), fun: Fungible(TOKEN_AMOUNT) }]; + let assets = vec![Asset { id: AssetId(asset_location), fun: Fungible(amount) }]; let versioned_assets = VersionedAssets::from(Assets::from(assets)); let destination = VersionedLocation::from(Location::new( @@ -581,7 +581,7 @@ fn send_eth_asset_from_asset_hub_to_ethereum() { ::Balances::free_balance( AssetHubPolkadotReceiver::get(), ); - // Send the Ether back to Ethereum + // Send the Token back to Ethereum assert_ok!( ::PolkadotXcm::limited_reserve_transfer_assets( RuntimeOrigin::signed(AssetHubPolkadotReceiver::get()), @@ -602,7 +602,7 @@ fn send_eth_asset_from_asset_hub_to_ethereum() { assert!(free_balance_diff > AH_BASE_FEE); }); - // Check that message with Ether was queued on the BridgeHub + // Check that message with Token was queued on the BridgeHub BridgeHubPolkadot::execute_with(|| { type RuntimeEvent = ::RuntimeEvent; // check the outbound queue @@ -622,8 +622,8 @@ fn send_eth_asset_from_asset_hub_to_ethereum() { assert!( events.iter().any(|event| matches!( event, - RuntimeEvent::Balances(pallet_balances::Event::Minted { who, amount }) - if *who == RelayTreasuryPalletAccount::get() && *amount == local_fee + RuntimeEvent::Balances(pallet_balances::Event::Minted { who, amount: fee_minted }) + if *who == RelayTreasuryPalletAccount::get() && *fee_minted == local_fee )), "Snowbridge sovereign takes local fee." ); @@ -639,199 +639,50 @@ fn send_eth_asset_from_asset_hub_to_ethereum() { }); } -/// Tests the full cycle of token transfers: -/// - registering a token on AssetHub -/// - sending a token to AssetHub -/// - returning the token to Ethereum +/// Tests sending Ether from Ethereum to Asset Hub and back to Ethereum #[test] -fn send_weth_asset_from_asset_hub_to_ethereum() { - let assethub_sovereign = BridgeHubPolkadot::sovereign_account_id_of(Location::new( - 1, - [Parachain(AssetHubPolkadot::para_id().into())], - )); - - BridgeHubPolkadot::fund_accounts(vec![ - (assethub_sovereign.clone(), INITIAL_FUND), - (RelayTreasuryPalletAccount::get(), INITIAL_FUND), - ]); - AssetHubPolkadot::fund_accounts(vec![ - (AssetHubPolkadotReceiver::get(), INITIAL_FUND), - (ethereum_sovereign_account(), INITIAL_FUND), - ]); - - // Set base transfer fee to Ethereum on AH. - AssetHubPolkadot::execute_with(|| { - assert_ok!(::System::set_storage( - ::RuntimeOrigin::root(), - vec![(BridgeHubEthereumBaseFee::key().to_vec(), AH_BASE_FEE.encode())], - )); - }); - - BridgeHubPolkadot::execute_with(|| { - type RuntimeEvent = ::RuntimeEvent; - - assert_ok!( - ::EthereumSystem::set_pricing_parameters( - ::RuntimeOrigin::root(), - PricingParametersOf:: { - exchange_rate: FixedU128::from_rational(1, 75), - fee_per_gas: gwei(20), - rewards: Rewards { - local: (UNITS / 100), // 0.01 DOT - remote: meth(1), - }, - multiplier: FixedU128::from_rational(1, 1), - } - ) - ); - - assert_ok!(::System::set_storage( - ::RuntimeOrigin::root(), - vec![(EthereumGatewayAddress::key().to_vec(), H160(GATEWAY_ADDRESS).encode())], - )); - - let message_id: H256 = [1; 32].into(); - let message = VersionedMessage::V1(MessageV1 { - chain_id: CHAIN_ID, - command: Command::RegisterToken { token: WETH.into(), fee: XCM_FEE }, - }); - // Convert the message to XCM - let (xcm, _) = EthereumInboundQueue::do_convert(message_id, message).unwrap(); - // Send the XCM - let _ = EthereumInboundQueue::send_xcm(xcm, AssetHubPolkadot::para_id()).unwrap(); - - // Check that the register token message was sent using xcm - assert_expected_events!( - BridgeHubPolkadot, - vec![ - RuntimeEvent::XcmpQueue(cumulus_pallet_xcmp_queue::Event::XcmpMessageSent { .. }) => {}, - ] - ); - - // Construct SendToken message and sent to inbound queue - let message = VersionedMessage::V1(MessageV1 { - chain_id: CHAIN_ID, - command: Command::SendToken { - token: WETH.into(), - destination: Destination::AccountId32 { - id: AssetHubPolkadotReceiver::get().into(), - }, - amount: TOKEN_AMOUNT, - fee: XCM_FEE, - }, - }); - // Convert the message to XCM - let (xcm, _) = EthereumInboundQueue::do_convert(message_id, message).unwrap(); - // Send the XCM - let _ = EthereumInboundQueue::send_xcm(xcm, AssetHubPolkadot::para_id()).unwrap(); - - // Check that the send token message was sent using xcm - assert_expected_events!( - BridgeHubPolkadot, - vec![ - RuntimeEvent::XcmpQueue(cumulus_pallet_xcmp_queue::Event::XcmpMessageSent { .. }) => {}, - ] - ); - }); - - // check treasury account balance on BH before - let treasury_account_before = BridgeHubPolkadot::execute_with(|| { - <::Balances as frame_support::traits::fungible::Inspect<_>>::balance(&RelayTreasuryPalletAccount::get()) - }); +fn send_eth_asset_from_asset_hub_to_ethereum() { + let ether_location: Location = (Parent, Parent, EthereumNetwork::get()).into(); + // Register Ether as foreign asset on AH. AssetHubPolkadot::execute_with(|| { type RuntimeEvent = ::RuntimeEvent; type RuntimeOrigin = ::RuntimeOrigin; - // Check that AssetHub has issued the foreign asset - assert_expected_events!( - AssetHubPolkadot, - vec![ - RuntimeEvent::ForeignAssets(pallet_assets::Event::Issued { .. }) => {}, - ] - ); - let assets = vec![Asset { - id: AssetId(Location::new( - 2, - [ - GlobalConsensus(Ethereum { chain_id: CHAIN_ID }), - AccountKey20 { network: None, key: WETH }, - ], - )), - fun: Fungible(TOKEN_AMOUNT), - }]; - let versioned_assets = VersionedAssets::from(Assets::from(assets)); - - let destination = VersionedLocation::from(Location::new( - 2, - [GlobalConsensus(Ethereum { chain_id: CHAIN_ID })], - )); - - let beneficiary = VersionedLocation::from(Location::new( - 0, - [AccountKey20 { network: None, key: ETHEREUM_DESTINATION_ADDRESS }], + assert_ok!(::ForeignAssets::force_create( + RuntimeOrigin::root(), + ether_location.clone(), + ethereum_sovereign_account().into(), + true, + MIN_ETHER_BALANCE, )); - let free_balance_before = - ::Balances::free_balance( - AssetHubPolkadotReceiver::get(), - ); - // Send the Weth back to Ethereum - assert_ok!( - ::PolkadotXcm::limited_reserve_transfer_assets( - RuntimeOrigin::signed(AssetHubPolkadotReceiver::get()), - Box::new(destination), - Box::new(beneficiary), - Box::new(versioned_assets), - 0, - Unlimited, - ) - ); - - let free_balance_after = - ::Balances::free_balance( - AssetHubPolkadotReceiver::get(), - ); - // Assert at least DefaultBridgeHubEthereumBaseFee charged from the sender - let free_balance_diff = free_balance_before - free_balance_after; - assert!(free_balance_diff > AH_BASE_FEE); - }); - - BridgeHubPolkadot::execute_with(|| { - type RuntimeEvent = ::RuntimeEvent; - // Check that the transfer token back to Ethereum message was queue in the Ethereum - // Outbound Queue assert_expected_events!( - BridgeHubPolkadot, + AssetHubPolkadot, vec![ - RuntimeEvent::EthereumOutboundQueue(snowbridge_pallet_outbound_queue::Event::MessageQueued {..}) => {}, + RuntimeEvent::ForeignAssets(pallet_assets::Event::ForceCreated { .. }) => {}, ] ); + }); - // check treasury account balance on BH after (should receive some fees) - let treasury_account_after = <::Balances as frame_support::traits::fungible::Inspect<_>>::balance(&RelayTreasuryPalletAccount::get()); - let local_fee = treasury_account_after - treasury_account_before; + // Perform a roundtrip transfer of Ether + send_token_from_ethereum_to_asset_hub_and_back_works( + ETHER_TOKEN_ADDRESS.into(), + MIN_ETHER_BALANCE + TOKEN_AMOUNT, + ether_location, + ); +} - let events = BridgeHubPolkadot::events(); - // Check that the local fee was credited to the Snowbridge sovereign account - assert!( - events.iter().any(|event| matches!( - event, - RuntimeEvent::Balances(pallet_balances::Event::Minted { who, amount }) - if *who == RelayTreasuryPalletAccount::get() && *amount == local_fee - )), - "Snowbridge sovereign takes local fee." - ); - // Check that the remote delivery fee was credited to the AssetHub sovereign account - assert!( - events.iter().any(|event| matches!( - event, - RuntimeEvent::Balances(pallet_balances::Event::Minted { who, .. }) - if *who == assethub_sovereign, - )), - "AssetHub sovereign takes remote fee." - ); - }); +/// Tests the full cycle of token transfers: +/// - registering a token on AssetHub +/// - sending a token to AssetHub +/// - returning the token to Ethereum +#[test] +fn send_weth_asset_from_asset_hub_to_ethereum() { + let weth_location: Location = + (Parent, Parent, EthereumNetwork::get(), AccountKey20 { network: None, key: WETH }).into(); + // Perform a roundtrip transfer of WETH + send_token_from_ethereum_to_asset_hub_and_back_works(WETH.into(), TOKEN_AMOUNT, weth_location); } #[test]