mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-31 06:21:02 +00:00
Snowbridge: Synchronize from Snowfork repository (#3761)
This PR includes the following 2 improvements: ## Ethereum Client Author: @yrong ### Original Upstream PRs - https://github.com/Snowfork/polkadot-sdk/pull/123 - https://github.com/Snowfork/polkadot-sdk/pull/125 ### Description The Ethereum client syncs beacon headers as they are finalized, and imports every execution header. When a message is received, it is verified against the import execution header. This is unnecessary, since the execution header can be sent with the message as proof. The recent Deneb Ethereum upgrade made it easier to locate the relevant beacon header from an execution header, and so this improvement was made possible. This resolves a concern @svyatonik had in our initial Rococo PR: https://github.com/paritytech/polkadot-sdk/pull/2522#discussion_r1431270691 ## Inbound Queue Author: @yrong ### Original Upstream PR - https://github.com/Snowfork/polkadot-sdk/pull/118 ### Description When the AH sovereign account (who pays relayer rewards) is depleted, the inbound message will not fail. The relayer just will not receive rewards. Both these changes were done by @yrong, many thanks. ❤️ --------- Co-authored-by: claravanstaden <Cats 4 life!> Co-authored-by: Ron <yrong1997@gmail.com> Co-authored-by: Vincent Geddes <vincent@snowfork.com> Co-authored-by: Svyatoslav Nikolsky <svyatonik@gmail.com>
This commit is contained in:
+80
-68
@@ -20,17 +20,17 @@ use frame_support::pallet_prelude::TypeInfo;
|
||||
use hex_literal::hex;
|
||||
use rococo_system_emulated_network::penpal_emulated_chain::CustomizableAssetFromSystemAssetHub;
|
||||
use rococo_westend_system_emulated_network::BridgeHubRococoParaSender as BridgeHubRococoSender;
|
||||
use snowbridge_core::outbound::OperatingMode;
|
||||
use snowbridge_core::{inbound::InboundQueueFixture, outbound::OperatingMode};
|
||||
use snowbridge_pallet_inbound_queue_fixtures::{
|
||||
register_token::make_register_token_message,
|
||||
register_token_with_insufficient_fee::make_register_token_with_insufficient_fee_message,
|
||||
send_token::make_send_token_message, send_token_to_penpal::make_send_token_to_penpal_message,
|
||||
InboundQueueFixture,
|
||||
register_token::make_register_token_message, send_token::make_send_token_message,
|
||||
send_token_to_penpal::make_send_token_to_penpal_message,
|
||||
};
|
||||
use snowbridge_pallet_system;
|
||||
use snowbridge_router_primitives::inbound::GlobalConsensusEthereumConvertsFor;
|
||||
use snowbridge_router_primitives::inbound::{
|
||||
Command, GlobalConsensusEthereumConvertsFor, MessageV1, VersionedMessage,
|
||||
};
|
||||
use sp_core::H256;
|
||||
use sp_runtime::{ArithmeticError::Underflow, DispatchError::Arithmetic};
|
||||
use sp_runtime::{DispatchError::Token, TokenError::FundsUnavailable};
|
||||
use testnet_parachains_constants::rococo::snowbridge::EthereumNetwork;
|
||||
|
||||
const INITIAL_FUND: u128 = 5_000_000_000 * ROCOCO_ED;
|
||||
@@ -39,6 +39,7 @@ const TREASURY_ACCOUNT: [u8; 32] =
|
||||
hex!("6d6f646c70792f74727372790000000000000000000000000000000000000000");
|
||||
const WETH: [u8; 20] = hex!("87d1f7fdfEe7f651FaBc8bFCB6E086C278b77A7d");
|
||||
const ETHEREUM_DESTINATION_ADDRESS: [u8; 20] = hex!("44a57ee2f2FCcb85FDa2B0B18EBD0D8D2333700e");
|
||||
const INSUFFICIENT_XCM_FEE: u128 = 1000;
|
||||
|
||||
#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)]
|
||||
pub enum ControlCall {
|
||||
@@ -56,13 +57,11 @@ pub enum SnowbridgeControl {
|
||||
}
|
||||
|
||||
pub fn send_inbound_message(fixture: InboundQueueFixture) -> DispatchResult {
|
||||
EthereumBeaconClient::store_execution_header(
|
||||
fixture.message.proof.block_hash,
|
||||
fixture.execution_header,
|
||||
0,
|
||||
H256::default(),
|
||||
);
|
||||
|
||||
EthereumBeaconClient::store_finalized_header(
|
||||
fixture.finalized_header,
|
||||
fixture.block_roots_root,
|
||||
)
|
||||
.unwrap();
|
||||
EthereumInboundQueue::submit(
|
||||
RuntimeOrigin::signed(BridgeHubRococoSender::get()),
|
||||
fixture.message,
|
||||
@@ -237,6 +236,46 @@ fn register_weth_token_from_ethereum_to_asset_hub() {
|
||||
});
|
||||
}
|
||||
|
||||
/// 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 on AssetHub
|
||||
AssetHubRococo::fund_accounts(vec![(AssetHubRococoReceiver::get(), INITIAL_FUND)]);
|
||||
|
||||
BridgeHubRococo::execute_with(|| {
|
||||
type RuntimeEvent = <BridgeHubRococo as Chain>::RuntimeEvent;
|
||||
|
||||
// Construct RegisterToken message and sent to inbound queue
|
||||
send_inbound_message(make_register_token_message()).unwrap();
|
||||
|
||||
// Construct SendToken message and sent to inbound queue
|
||||
send_inbound_message(make_send_token_message()).unwrap();
|
||||
|
||||
// Check that the message was sent
|
||||
assert_expected_events!(
|
||||
BridgeHubRococo,
|
||||
vec![
|
||||
RuntimeEvent::XcmpQueue(cumulus_pallet_xcmp_queue::Event::XcmpMessageSent { .. }) => {},
|
||||
]
|
||||
);
|
||||
});
|
||||
|
||||
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![
|
||||
RuntimeEvent::ForeignAssets(pallet_assets::Event::Issued { .. }) => {},
|
||||
]
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
/// Tests sending a token to a 3rd party parachain, called PenPal. The token reserve is
|
||||
/// still located on AssetHub.
|
||||
#[test]
|
||||
@@ -296,6 +335,10 @@ fn send_token_from_ethereum_to_penpal() {
|
||||
// Construct RegisterToken message and sent to inbound queue
|
||||
send_inbound_message(make_register_token_message()).unwrap();
|
||||
|
||||
// Construct SendToken message to AssetHub(only for increase the nonce as the same order in
|
||||
// smoke test)
|
||||
send_inbound_message(make_send_token_message()).unwrap();
|
||||
|
||||
// Construct SendToken message and sent to inbound queue
|
||||
send_inbound_message(make_send_token_to_penpal_message()).unwrap();
|
||||
|
||||
@@ -331,46 +374,6 @@ 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 on AssetHub
|
||||
AssetHubRococo::fund_accounts(vec![(AssetHubRococoReceiver::get(), INITIAL_FUND)]);
|
||||
|
||||
BridgeHubRococo::execute_with(|| {
|
||||
type RuntimeEvent = <BridgeHubRococo as Chain>::RuntimeEvent;
|
||||
|
||||
// Construct RegisterToken message and sent to inbound queue
|
||||
send_inbound_message(make_register_token_message()).unwrap();
|
||||
|
||||
// Construct SendToken message and sent to inbound queue
|
||||
send_inbound_message(make_send_token_message()).unwrap();
|
||||
|
||||
// Check that the message was sent
|
||||
assert_expected_events!(
|
||||
BridgeHubRococo,
|
||||
vec![
|
||||
RuntimeEvent::XcmpQueue(cumulus_pallet_xcmp_queue::Event::XcmpMessageSent { .. }) => {},
|
||||
]
|
||||
);
|
||||
});
|
||||
|
||||
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![
|
||||
RuntimeEvent::ForeignAssets(pallet_assets::Event::Issued { .. }) => {},
|
||||
]
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
/// Tests the full cycle of token transfers:
|
||||
/// - registering a token on AssetHub
|
||||
/// - sending a token to AssetHub
|
||||
@@ -507,16 +510,35 @@ fn send_weth_asset_from_asset_hub_to_ethereum() {
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn send_token_from_ethereum_to_asset_hub_fail_for_insufficient_fund() {
|
||||
// Insufficient fund
|
||||
BridgeHubRococo::fund_para_sovereign(AssetHubRococo::para_id().into(), 1_000);
|
||||
|
||||
BridgeHubRococo::execute_with(|| {
|
||||
assert_err!(send_inbound_message(make_register_token_message()), Token(FundsUnavailable));
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn register_weth_token_in_asset_hub_fail_for_insufficient_fee() {
|
||||
BridgeHubRococo::fund_para_sovereign(AssetHubRococo::para_id().into(), INITIAL_FUND);
|
||||
|
||||
BridgeHubRococo::execute_with(|| {
|
||||
type RuntimeEvent = <BridgeHubRococo as Chain>::RuntimeEvent;
|
||||
|
||||
// Construct RegisterToken message and sent to inbound queue
|
||||
let message = make_register_token_with_insufficient_fee_message();
|
||||
send_inbound_message(message).unwrap();
|
||||
type EthereumInboundQueue =
|
||||
<BridgeHubRococo as BridgeHubRococoPallet>::EthereumInboundQueue;
|
||||
let message_id: H256 = [0; 32].into();
|
||||
let message = VersionedMessage::V1(MessageV1 {
|
||||
chain_id: CHAIN_ID,
|
||||
command: Command::RegisterToken {
|
||||
token: WETH.into(),
|
||||
// Insufficient fee which should trigger the trap
|
||||
fee: INSUFFICIENT_XCM_FEE,
|
||||
},
|
||||
});
|
||||
let (xcm, _) = EthereumInboundQueue::do_convert(message_id, message).unwrap();
|
||||
let _ = EthereumInboundQueue::send_xcm(xcm, AssetHubRococo::para_id().into()).unwrap();
|
||||
|
||||
assert_expected_events!(
|
||||
BridgeHubRococo,
|
||||
@@ -537,13 +559,3 @@ fn register_weth_token_in_asset_hub_fail_for_insufficient_fee() {
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn send_token_from_ethereum_to_asset_hub_fail_for_insufficient_fund() {
|
||||
// Insufficient fund
|
||||
BridgeHubRococo::fund_para_sovereign(AssetHubRococo::para_id().into(), 1_000);
|
||||
|
||||
BridgeHubRococo::execute_with(|| {
|
||||
assert_err!(send_inbound_message(make_register_token_message()), Arithmetic(Underflow));
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user