Skip to content
This repository has been archived by the owner on Oct 22, 2024. It is now read-only.

Adds emulated test comments #97

Merged
merged 3 commits into from
Jan 16, 2024
Merged
Changes from 1 commit
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
Original file line number Diff line number Diff line change
Expand Up @@ -48,17 +48,19 @@ pub enum SnowbridgeControl {
Control(ControlCall),
}

/// Create an agent on Ethereum. An agent is a representation of an entity in the Polkadot
/// ecosystem (like a parachain) on Ethereum.
claravanstaden marked this conversation as resolved.
Show resolved Hide resolved
#[test]
fn create_agent() {
let origin_para: u32 = 1001;

// Fund AssetHub sovereign account so that it can pay execution fees.
BridgeHubRococo::fund_para_sovereign(origin_para.into(), INITIAL_FUND);

let sudo_origin = <Rococo as Chain>::RuntimeOrigin::root();
let destination = Rococo::child_location_of(BridgeHubRococo::para_id()).into();

let create_agent_call = SnowbridgeControl::Control(ControlCall::CreateAgent {});

// Create Agent XCM call
let remote_xcm = VersionedXcm::from(Xcm(vec![
UnpaidExecution { weight_limit: Unlimited, check_origin: None },
DescendOrigin(X1(Parachain(origin_para))),
Expand All @@ -69,7 +71,7 @@ fn create_agent() {
},
]));

//Rococo Global Consensus
// Rococo Global Consensus
// Send XCM message from Relay Chain to Bridge Hub source Parachain
Rococo::execute_with(|| {
assert_ok!(<Rococo as RococoPallet>::XcmPallet::send(
Expand All @@ -79,7 +81,7 @@ fn create_agent() {
));

type RuntimeEvent = <Rococo as Chain>::RuntimeEvent;

// Check that the Transact message was sent
assert_expected_events!(
Rococo,
vec![
Expand All @@ -90,7 +92,7 @@ fn create_agent() {

BridgeHubRococo::execute_with(|| {
type RuntimeEvent = <BridgeHubRococo as Chain>::RuntimeEvent;

// Check that the Agent was created
claravanstaden marked this conversation as resolved.
Show resolved Hide resolved
assert_expected_events!(
BridgeHubRococo,
vec![
Expand All @@ -102,18 +104,19 @@ fn create_agent() {
});
}

/// Create a channel for an agent. A channel is like a lane, specifically used by one agent.
claravanstaden marked this conversation as resolved.
Show resolved Hide resolved
#[test]
fn create_channel() {
let origin_para: u32 = 1001;

// Fund AssetHub sovereign account so that it can pay execution fees.
claravanstaden marked this conversation as resolved.
Show resolved Hide resolved
BridgeHubRococo::fund_para_sovereign(origin_para.into(), INITIAL_FUND);

let sudo_origin = <Rococo as Chain>::RuntimeOrigin::root();
let destination: VersionedMultiLocation =
Rococo::child_location_of(BridgeHubRococo::para_id()).into();

let create_agent_call = SnowbridgeControl::Control(ControlCall::CreateAgent {});

// Create Channel XCM call
claravanstaden marked this conversation as resolved.
Show resolved Hide resolved
let create_agent_xcm = VersionedXcm::from(Xcm(vec![
UnpaidExecution { weight_limit: Unlimited, check_origin: None },
DescendOrigin(X1(Parachain(origin_para))),
Expand All @@ -137,7 +140,7 @@ fn create_channel() {
},
]));

//Rococo Global Consensus
// Rococo Global Consensus
// Send XCM message from Relay Chain to Bridge Hub source Parachain
Rococo::execute_with(|| {
assert_ok!(<Rococo as RococoPallet>::XcmPallet::send(
Expand Down Expand Up @@ -165,6 +168,7 @@ fn create_channel() {
BridgeHubRococo::execute_with(|| {
type RuntimeEvent = <BridgeHubRococo as Chain>::RuntimeEvent;

// Check that the Channel was created
assert_expected_events!(
BridgeHubRococo,
vec![
Expand All @@ -176,11 +180,13 @@ fn create_channel() {
});
}

/// Tests the registering of a token as an asset on AssetHub.
#[test]
fn register_weth_token_from_ethereum_to_asset_hub() {
// Fund AssetHub sovereign account so that it can pay execution fees.
BridgeHubRococo::fund_para_sovereign(AssetHubRococo::para_id().into(), INITIAL_FUND);

let message_id_: H256 = [1; 32].into();
let message_id: H256 = [1; 32].into();

BridgeHubRococo::execute_with(|| {
type RuntimeEvent = <BridgeHubRococo as Chain>::RuntimeEvent;
Expand All @@ -190,7 +196,7 @@ fn register_weth_token_from_ethereum_to_asset_hub() {
chain_id: CHAIN_ID,
command: Command::RegisterToken { token: WETH.into(), fee: XCM_FEE },
});
let (xcm, fee) = EthereumInboundQueue::do_convert(message_id_, message).unwrap();
let (xcm, fee) = EthereumInboundQueue::do_convert(message_id, message).unwrap();

assert_ok!(EthereumInboundQueue::burn_fees(AssetHubRococo::para_id().into(), fee));

Expand All @@ -216,32 +222,38 @@ fn register_weth_token_from_ethereum_to_asset_hub() {
});
}

/// Tests sending a token to a 3rd party parachain, called PenPal. The token reserve is
/// still located on AssetHub.
#[test]
fn send_token_from_ethereum_to_penpal() {
let asset_hub_sovereign = BridgeHubRococo::sovereign_account_id_of(MultiLocation {
parents: 1,
interior: X1(Parachain(AssetHubRococo::para_id().into())),
});
// Fund AssetHub sovereign account so it can pay execution fees for the asset transfer
BridgeHubRococo::fund_accounts(vec![(asset_hub_sovereign.clone(), INITIAL_FUND)]);

// Fund PenPal sender and receiver
PenpalA::fund_accounts(vec![
(PenpalAReceiver::get(), INITIAL_FUND),
(PenpalASender::get(), INITIAL_FUND),
(PenpalAReceiver::get(), INITIAL_FUND), // for receiving the sent asset on PenPal
(PenpalASender::get(), INITIAL_FUND), // for creating the asset on PenPal
]);

// The Weth asset location, identified by the contract address on Ethereum
let weth_asset_location: MultiLocation =
(Parent, Parent, EthereumNetwork::get(), AccountKey20 { network: None, key: WETH }).into();
// Converts the Weth asset location into an asset ID
let weth_asset_id = weth_asset_location.into();

let origin_location = (Parent, Parent, EthereumNetwork::get()).into();

// Fund ethereum sovereign in asset hub
// Fund ethereum sovereign on AssetHub
let ethereum_sovereign: AccountId =
GlobalConsensusEthereumConvertsFor::<AccountId>::convert_location(&origin_location)
.unwrap();
AssetHubRococo::fund_accounts(vec![(ethereum_sovereign.clone(), INITIAL_FUND)]);

// Create asset on assethub.
// Create asset on AssetHub, since that is where the asset reserve is located (u
AssetHubRococo::execute_with(|| {
assert_ok!(<AssetHubRococo as AssetHubRococoPallet>::ForeignAssets::create(
pallet_xcm::Origin::Xcm(origin_location).into(),
Expand All @@ -255,7 +267,7 @@ fn send_token_from_ethereum_to_penpal() {
));
});

// Create asset on penpal.
// Create asset on the Penpal parachain.
PenpalA::execute_with(|| {
assert_ok!(<PenpalA as PenpalAPallet>::ForeignAssets::create(
<PenpalA as Chain>::RuntimeOrigin::signed(PenpalASender::get()),
Expand All @@ -267,12 +279,13 @@ fn send_token_from_ethereum_to_penpal() {
assert!(<PenpalA as PenpalAPallet>::ForeignAssets::asset_exists(weth_asset_id));
});

let message_id_: H256 = [1; 32].into();
let message_id: H256 = [1; 32].into();

BridgeHubRococo::execute_with(|| {
type RuntimeEvent = <BridgeHubRococo as Chain>::RuntimeEvent;
type EthereumInboundQueue =
<BridgeHubRococo as BridgeHubRococoPallet>::EthereumInboundQueue;
// Construct SendToken message
let message = VersionedMessage::V1(MessageV1 {
chain_id: CHAIN_ID,
command: Command::SendToken {
Expand All @@ -286,7 +299,9 @@ fn send_token_from_ethereum_to_penpal() {
fee: XCM_FEE,
},
});
let (xcm, _) = EthereumInboundQueue::do_convert(message_id_, message).unwrap();
// Convert the message to XCM
let (xcm, _) = EthereumInboundQueue::do_convert(message_id, message).unwrap();
// Send the XCM
let _ = EthereumInboundQueue::send_xcm(xcm, AssetHubRococo::para_id().into()).unwrap();

assert_expected_events!(
Expand All @@ -299,7 +314,7 @@ fn send_token_from_ethereum_to_penpal() {

AssetHubRococo::execute_with(|| {
type RuntimeEvent = <AssetHubRococo as Chain>::RuntimeEvent;

// Check that the assets were issued on AssetHub
assert_expected_events!(
AssetHubRococo,
vec![
Expand All @@ -311,7 +326,7 @@ fn send_token_from_ethereum_to_penpal() {

PenpalA::execute_with(|| {
type RuntimeEvent = <PenpalA as Chain>::RuntimeEvent;

// Check that the assets were issued on PenPal
assert_expected_events!(
PenpalA,
vec![
Expand All @@ -321,25 +336,32 @@ fn send_token_from_ethereum_to_penpal() {
});
}

/// Tests the registering of a token as an asset on AssetHub, and then subsequently sending
/// a token from Ethereum to AssetHub.
#[test]
fn send_token_from_ethereum_to_asset_hub() {
BridgeHubRococo::fund_para_sovereign(AssetHubRococo::para_id().into(), INITIAL_FUND);

// Fund ethereum sovereign in asset hub
// Fund ethereum sovereign on AssetHub
AssetHubRococo::fund_accounts(vec![(AssetHubRococoReceiver::get(), INITIAL_FUND)]);

let message_id_: H256 = [1; 32].into();
let message_id: H256 = [1; 32].into();

BridgeHubRococo::execute_with(|| {
type RuntimeEvent = <BridgeHubRococo as Chain>::RuntimeEvent;
type EthereumInboundQueue =
<BridgeHubRococo as BridgeHubRococoPallet>::EthereumInboundQueue;
// Construct RegisterToken message
let message = VersionedMessage::V1(MessageV1 {
chain_id: CHAIN_ID,
command: Command::RegisterToken { token: WETH.into(), fee: XCM_FEE },
});
let (xcm, _) = EthereumInboundQueue::do_convert(message_id_, message).unwrap();
// Convert the message to XCM
let (xcm, _) = EthereumInboundQueue::do_convert(message_id, message).unwrap();
// Send the XCM
let _ = EthereumInboundQueue::send_xcm(xcm, AssetHubRococo::para_id().into()).unwrap();

// Construct SendToken message
let message = VersionedMessage::V1(MessageV1 {
chain_id: CHAIN_ID,
command: Command::SendToken {
Expand All @@ -349,9 +371,12 @@ fn send_token_from_ethereum_to_asset_hub() {
fee: XCM_FEE,
},
});
let (xcm, _) = EthereumInboundQueue::do_convert(message_id_, message).unwrap();
// Convert the message to XCM
let (xcm, _) = EthereumInboundQueue::do_convert(message_id, message).unwrap();
// Send the XCM
let _ = EthereumInboundQueue::send_xcm(xcm, AssetHubRococo::para_id().into()).unwrap();

// Check that the message was sent
assert_expected_events!(
BridgeHubRococo,
vec![
Expand All @@ -363,6 +388,7 @@ fn send_token_from_ethereum_to_asset_hub() {
AssetHubRococo::execute_with(|| {
type RuntimeEvent = <AssetHubRococo as Chain>::RuntimeEvent;

// Check that the token was received and issued as a foreign asset on AssetHub
assert_expected_events!(
AssetHubRococo,
vec![
Expand All @@ -372,6 +398,10 @@ fn send_token_from_ethereum_to_asset_hub() {
});
}

/// 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() {
use asset_hub_rococo_runtime::xcm_config::bridging::to_ethereum::DefaultBridgeHubEthereumBaseFee;
Expand All @@ -394,19 +424,32 @@ fn send_weth_asset_from_asset_hub_to_ethereum() {
AssetHubRococo::fund_accounts(vec![(AssetHubRococoReceiver::get(), INITIAL_FUND)]);

const WETH_AMOUNT: u128 = 1_000_000_000;
let message_id_: H256 = [1; 32].into();
let message_id_register_token: H256 = [1; 32].into();
let message_id_send_token: H256 = [2; 32].into();

BridgeHubRococo::execute_with(|| {
type RuntimeEvent = <BridgeHubRococo as Chain>::RuntimeEvent;
type EthereumInboundQueue =
<BridgeHubRococo as BridgeHubRococoPallet>::EthereumInboundQueue;

// Register ERC-20 token on AssetHub
let message = VersionedMessage::V1(MessageV1 {
chain_id: CHAIN_ID,
command: Command::RegisterToken { token: WETH.into(), fee: XCM_FEE },
});
let (xcm, _) = EthereumInboundQueue::do_convert(message_id_, message).unwrap();
// Converts the versioned message to XCM
let (xcm, _) = EthereumInboundQueue::do_convert(message_id_register_token, message).unwrap();
let _ = EthereumInboundQueue::send_xcm(xcm, AssetHubRococo::para_id().into()).unwrap();

// Check that the register token message was sent using xcm
assert_expected_events!(
BridgeHubRococo,
vec![
RuntimeEvent::XcmpQueue(cumulus_pallet_xcmp_queue::Event::XcmpMessageSent { .. }) => {},
]
);

// Send ERC-20 token to AssetHub
let message = VersionedMessage::V1(MessageV1 {
chain_id: CHAIN_ID,
command: Command::SendToken {
Expand All @@ -416,9 +459,11 @@ fn send_weth_asset_from_asset_hub_to_ethereum() {
fee: XCM_FEE,
},
});
let (xcm, _) = EthereumInboundQueue::do_convert(message_id_, message).unwrap();
// Converts the versioned message to XCM
let (xcm, _) = EthereumInboundQueue::do_convert(message_id_send_token, message).unwrap();
let _ = EthereumInboundQueue::send_xcm(xcm, AssetHubRococo::para_id().into()).unwrap();

// Check that the send token message was sent using xcm
assert_expected_events!(
BridgeHubRococo,
vec![
Expand All @@ -431,6 +476,7 @@ fn send_weth_asset_from_asset_hub_to_ethereum() {
type RuntimeEvent = <AssetHubRococo as Chain>::RuntimeEvent;
type RuntimeOrigin = <AssetHubRococo as Chain>::RuntimeOrigin;

// Check that AssetHub has issued the foreign asset
assert_expected_events!(
AssetHubRococo,
vec![
Expand Down Expand Up @@ -462,6 +508,7 @@ fn send_weth_asset_from_asset_hub_to_ethereum() {
let free_balance_before = <AssetHubRococo as AssetHubRococoPallet>::Balances::free_balance(
AssetHubRococoReceiver::get(),
);
// Send the Weth back to Ethereum
<AssetHubRococo as AssetHubRococoPallet>::PolkadotXcm::reserve_transfer_assets(
RuntimeOrigin::signed(AssetHubRococoReceiver::get()),
Box::new(destination),
Expand All @@ -473,21 +520,23 @@ fn send_weth_asset_from_asset_hub_to_ethereum() {
let free_balance_after = <AssetHubRococo as AssetHubRococoPallet>::Balances::free_balance(
AssetHubRococoReceiver::get(),
);
// assert at least DefaultBridgeHubEthereumBaseFee charged from the sender
// Assert at least DefaultBridgeHubEthereumBaseFee charged from the sender
let free_balance_diff = free_balance_before - free_balance_after;
assert!(free_balance_diff > DefaultBridgeHubEthereumBaseFee::get());
});

BridgeHubRococo::execute_with(|| {
type RuntimeEvent = <BridgeHubRococo as Chain>::RuntimeEvent;

// Check that the transfer token back to Ethereum message was queue in the Ethereum
// Outbound Queue
assert_expected_events!(
BridgeHubRococo,
vec![
RuntimeEvent::EthereumOutboundQueue(snowbridge_pallet_outbound_queue::Event::MessageQueued {..}) => {},
]
);
let events = BridgeHubRococo::events();
// Check that the local fee was credited to the Snowbridge sovereign account
assert!(
events.iter().any(|event| matches!(
event,
Expand All @@ -496,6 +545,7 @@ fn send_weth_asset_from_asset_hub_to_ethereum() {
)),
"Snowbridge sovereign takes local fee."
);
// Check that the remote fee was credited to the AssetHub sovereign account
assert!(
events.iter().any(|event| matches!(
event,
Expand Down
Loading