mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-07-08 17:07:21 +00:00
Replicate e2e integration test as emulated (#2958)
* Allow functions to work over both parachains and relay chains * additional references * import * backup * refactoring para and relay traits * use runtime crates to build types * decouple ProcessMessage * decouple ProcessMessage 2 * dmp and xcmp handlers decouple * backup * refactor done * common int values working * added global ext with mutex * works for two mutex * single mutex and remove condvar * global test ext done * failing moving test_ext because relay block num * relay_block_number issue fixed * backup * Test working with assertions * assertions get Test as arg * DispatchArgs as generic * clean up * backup * teleports for asset-hub-kusama done * improve assert_expected_events macro * rename Test generics * check assertions for tuples * test assertions redone * reserve_transfer_assets done * send transact done * hrmp test for paras * hrmp channels test done * hrmp channels test done 2 * before modifying test dispatch * reserve tests done & Test dispatch fixed * reserve transfer local asset * force_create_and_mint_asset * force create and mint done * tests done * fix imports in common * common events refactored * add option to events attributes * asset-hub-polkadot tests done * asset-hub-westend half done * relay chain events move to common * remove failing send tests for asset-hub-westend * added events to bridge-hub-rococo * added events to collectives-polkadot * cargo clean up * fix asset-hub-westend tests * ".git/.scripts/commands/fmt/fmt.sh" * fix clippy * ".git/.scripts/commands/fmt/fmt.sh" * Removed unnecessary deps * Extracted some commonality for Kusama/Polkadot (which will be reused also for BridgeHubs) (#2971) * Extracted some commonality for Kusama/Polkadot (which will be reused also for BridgeHubs) * AssetHubRococo should better use AssetHubKusama runtime * add fund_account --------- Co-authored-by: NachoPal <ignacio.palacios.santos@gmail.com> * address comments * rename event assertion helpers * clean comments * address comments 2 * ".git/.scripts/commands/fmt/fmt.sh" --------- Co-authored-by: Giles Cope <gilescope@gmail.com> Co-authored-by: command-bot <> Co-authored-by: Branislav Kontur <bkontur@gmail.com>
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
use super::{BridgeHubRococo, BridgeHubWococo};
|
||||
// pub use paste;
|
||||
use bp_messages::{
|
||||
target_chain::{DispatchMessage, DispatchMessageData, MessageDispatch},
|
||||
LaneId, MessageKey, OutboundLaneData,
|
||||
@@ -8,7 +9,7 @@ use codec::Decode;
|
||||
pub use cumulus_primitives_core::{DmpMessageHandler, XcmpMessageHandler};
|
||||
use pallet_bridge_messages::{Config, Instance1, Instance2, OutboundLanes, Pallet};
|
||||
use sp_core::Get;
|
||||
use xcm_emulator::{BridgeMessage, BridgeMessageDispatchError, BridgeMessageHandler, Parachain};
|
||||
use xcm_emulator::{BridgeMessage, BridgeMessageDispatchError, BridgeMessageHandler, Chain};
|
||||
|
||||
pub struct BridgeHubMessageHandler<S, T, I> {
|
||||
_marker: std::marker::PhantomData<(S, T, I)>,
|
||||
@@ -28,12 +29,12 @@ impl From<u32> for LaneIdWrapper {
|
||||
}
|
||||
}
|
||||
|
||||
type BridgeHubRococoRuntime = <BridgeHubRococo as Parachain>::Runtime;
|
||||
type BridgeHubWococoRuntime = <BridgeHubWococo as Parachain>::Runtime;
|
||||
type BridgeHubRococoRuntime = <BridgeHubRococo as Chain>::Runtime;
|
||||
type BridgeHubWococoRuntime = <BridgeHubWococo as Chain>::Runtime;
|
||||
|
||||
// TODO: uncomment when https://github.com/paritytech/cumulus/pull/2528 is merged
|
||||
// type BridgeHubPolkadotRuntime = <BridgeHubPolkadot as Parachain>::Runtime;
|
||||
// type BridgeHubKusamaRuntime = <BridgeHubKusama as Parachain>::Runtime;
|
||||
// type BridgeHubPolkadotRuntime = <BridgeHubPolkadot as Chain>::Runtime;
|
||||
// type BridgeHubKusamaRuntime = <BridgeHubKusama as Chain>::Runtime;
|
||||
|
||||
pub type RococoWococoMessageHandler =
|
||||
BridgeHubMessageHandler<BridgeHubRococoRuntime, BridgeHubWococoRuntime, Instance2>;
|
||||
@@ -124,3 +125,473 @@ where
|
||||
OutboundLanes::<S, Instance1>::insert(LaneIdWrapper::from(lane_id).0, new_data);
|
||||
}
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! impl_accounts_helpers_for_relay_chain {
|
||||
( $chain:ident ) => {
|
||||
$crate::paste::paste! {
|
||||
impl $chain {
|
||||
/// Fund a set of accounts with a balance
|
||||
pub fn fund_accounts(accounts: Vec<(AccountId, Balance)>) {
|
||||
Self::execute_with(|| {
|
||||
for account in accounts {
|
||||
assert_ok!(<Self as [<$chain Pallet>]>::Balances::force_set_balance(
|
||||
<Self as Chain>::RuntimeOrigin::root(),
|
||||
account.0.into(),
|
||||
account.1,
|
||||
));
|
||||
}
|
||||
});
|
||||
}
|
||||
/// Fund a sovereign account based on its Parachain Id
|
||||
pub fn fund_para_sovereign(amount: Balance, para_id: ParaId) -> sp_runtime::AccountId32 {
|
||||
let sovereign_account = Self::sovereign_account_id_of_child_para(para_id);
|
||||
Self::fund_accounts(vec![(sovereign_account.clone(), amount)]);
|
||||
sovereign_account
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! impl_assert_events_helpers_for_relay_chain {
|
||||
( $chain:ident ) => {
|
||||
$crate::paste::paste! {
|
||||
type [<$chain RuntimeEvent>] = <$chain as Chain>::RuntimeEvent;
|
||||
|
||||
impl $chain {
|
||||
/// Asserts a dispatchable is completely executed and XCM sent
|
||||
pub fn assert_xcm_pallet_attempted_complete(expected_weight: Option<Weight>) {
|
||||
assert_expected_events!(
|
||||
Self,
|
||||
vec![
|
||||
[<$chain RuntimeEvent>]::XcmPallet(
|
||||
pallet_xcm::Event::Attempted { outcome: Outcome::Complete(weight) }
|
||||
) => {
|
||||
weight: weight_within_threshold(
|
||||
(REF_TIME_THRESHOLD, PROOF_SIZE_THRESHOLD),
|
||||
expected_weight.unwrap_or(*weight),
|
||||
*weight
|
||||
),
|
||||
},
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/// Asserts a dispatchable is incompletely executed and XCM sent
|
||||
pub fn assert_xcm_pallet_attempted_incomplete(
|
||||
expected_weight: Option<Weight>,
|
||||
expected_error: Option<Error>,
|
||||
) {
|
||||
assert_expected_events!(
|
||||
Self,
|
||||
vec![
|
||||
// Dispatchable is properly executed and XCM message sent
|
||||
[<$chain RuntimeEvent>]::XcmPallet(
|
||||
pallet_xcm::Event::Attempted { outcome: Outcome::Incomplete(weight, error) }
|
||||
) => {
|
||||
weight: weight_within_threshold(
|
||||
(REF_TIME_THRESHOLD, PROOF_SIZE_THRESHOLD),
|
||||
expected_weight.unwrap_or(*weight),
|
||||
*weight
|
||||
),
|
||||
error: *error == expected_error.unwrap_or(*error),
|
||||
},
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/// Asserts a XCM message is sent
|
||||
pub fn assert_xcm_pallet_sent() {
|
||||
assert_expected_events!(
|
||||
Self,
|
||||
vec![
|
||||
[<$chain RuntimeEvent>]::XcmPallet(pallet_xcm::Event::Sent { .. }) => {},
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/// Asserts a XCM from System Parachain is succesfully received and proccessed
|
||||
pub fn assert_ump_queue_processed(
|
||||
expected_success: bool,
|
||||
expected_id: Option<ParaId>,
|
||||
expected_weight: Option<Weight>,
|
||||
) {
|
||||
assert_expected_events!(
|
||||
Self,
|
||||
vec![
|
||||
// XCM is succesfully received and proccessed
|
||||
[<$chain RuntimeEvent>]::MessageQueue(pallet_message_queue::Event::Processed {
|
||||
origin: AggregateMessageOrigin::Ump(UmpQueueId::Para(id)),
|
||||
weight_used,
|
||||
success,
|
||||
..
|
||||
}) => {
|
||||
id: *id == expected_id.unwrap_or(*id),
|
||||
weight_used: weight_within_threshold(
|
||||
(REF_TIME_THRESHOLD, PROOF_SIZE_THRESHOLD),
|
||||
expected_weight.unwrap_or(*weight_used),
|
||||
*weight_used
|
||||
),
|
||||
success: *success == expected_success,
|
||||
},
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! impl_hrmp_channels_helpers_for_relay_chain {
|
||||
( $chain:ident ) => {
|
||||
$crate::paste::paste! {
|
||||
impl $chain {
|
||||
/// Init open channel request with another Parachain
|
||||
pub fn init_open_channel_call(
|
||||
recipient_para_id: ParaId,
|
||||
max_capacity: u32,
|
||||
max_message_size: u32,
|
||||
) -> DoubleEncoded<()> {
|
||||
<Self as Chain>::RuntimeCall::Hrmp(polkadot_runtime_parachains::hrmp::Call::<
|
||||
<Self as Chain>::Runtime,
|
||||
>::hrmp_init_open_channel {
|
||||
recipient: recipient_para_id,
|
||||
proposed_max_capacity: max_capacity,
|
||||
proposed_max_message_size: max_message_size,
|
||||
})
|
||||
.encode()
|
||||
.into()
|
||||
}
|
||||
/// Recipient Parachain accept the open request from another Parachain
|
||||
pub fn accept_open_channel_call(sender_para_id: ParaId) -> DoubleEncoded<()> {
|
||||
<Self as Chain>::RuntimeCall::Hrmp(polkadot_runtime_parachains::hrmp::Call::<
|
||||
<Self as Chain>::Runtime,
|
||||
>::hrmp_accept_open_channel {
|
||||
sender: sender_para_id,
|
||||
})
|
||||
.encode()
|
||||
.into()
|
||||
}
|
||||
|
||||
/// A root origin force to open a channel between two Parachains
|
||||
pub fn force_process_hrmp_open(sender: ParaId, recipient: ParaId) {
|
||||
Self::execute_with(|| {
|
||||
let relay_root_origin = <Self as Chain>::RuntimeOrigin::root();
|
||||
|
||||
// Force process HRMP open channel requests without waiting for the next session
|
||||
assert_ok!(<Self as [<$chain Pallet>]>::Hrmp::force_process_hrmp_open(
|
||||
relay_root_origin,
|
||||
0
|
||||
));
|
||||
|
||||
let channel_id = HrmpChannelId { sender, recipient };
|
||||
|
||||
let hrmp_channel_exist = polkadot_runtime_parachains::hrmp::HrmpChannels::<
|
||||
<Self as Chain>::Runtime,
|
||||
>::contains_key(&channel_id);
|
||||
|
||||
// Check the HRMP channel has been successfully registrered
|
||||
assert!(hrmp_channel_exist)
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! impl_accounts_helpers_for_parachain {
|
||||
( $chain:ident ) => {
|
||||
$crate::paste::paste! {
|
||||
impl $chain {
|
||||
/// Fund a set of accounts with a balance
|
||||
pub fn fund_accounts(accounts: Vec<(AccountId, Balance)>) {
|
||||
Self::execute_with(|| {
|
||||
for account in accounts {
|
||||
assert_ok!(<Self as [<$chain Pallet>]>::Balances::force_set_balance(
|
||||
<Self as Chain>::RuntimeOrigin::root(),
|
||||
account.0.into(),
|
||||
account.1,
|
||||
));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! impl_assert_events_helpers_for_parachain {
|
||||
( $chain:ident ) => {
|
||||
$crate::paste::paste! {
|
||||
type [<$chain RuntimeEvent>] = <$chain as Chain>::RuntimeEvent;
|
||||
|
||||
impl $chain {
|
||||
/// Asserts a dispatchable is completely executed and XCM sent
|
||||
pub fn assert_xcm_pallet_attempted_complete(expected_weight: Option<Weight>) {
|
||||
assert_expected_events!(
|
||||
Self,
|
||||
vec![
|
||||
[<$chain RuntimeEvent>]::PolkadotXcm(
|
||||
pallet_xcm::Event::Attempted { outcome: Outcome::Complete(weight) }
|
||||
) => {
|
||||
weight: weight_within_threshold(
|
||||
(REF_TIME_THRESHOLD, PROOF_SIZE_THRESHOLD),
|
||||
expected_weight.unwrap_or(*weight),
|
||||
*weight
|
||||
),
|
||||
},
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/// Asserts a dispatchable is incompletely executed and XCM sent
|
||||
pub fn assert_xcm_pallet_attempted_incomplete(
|
||||
expected_weight: Option<Weight>,
|
||||
expected_error: Option<Error>,
|
||||
) {
|
||||
assert_expected_events!(
|
||||
Self,
|
||||
vec![
|
||||
// Dispatchable is properly executed and XCM message sent
|
||||
[<$chain RuntimeEvent>]::PolkadotXcm(
|
||||
pallet_xcm::Event::Attempted { outcome: Outcome::Incomplete(weight, error) }
|
||||
) => {
|
||||
weight: weight_within_threshold(
|
||||
(REF_TIME_THRESHOLD, PROOF_SIZE_THRESHOLD),
|
||||
expected_weight.unwrap_or(*weight),
|
||||
*weight
|
||||
),
|
||||
error: *error == expected_error.unwrap_or(*error),
|
||||
},
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/// Asserts a dispatchable throws and error when trying to be sent
|
||||
pub fn assert_xcm_pallet_attempted_error(expected_error: Option<Error>) {
|
||||
assert_expected_events!(
|
||||
Self,
|
||||
vec![
|
||||
// Execution fails in the origin with `Barrier`
|
||||
[<$chain RuntimeEvent>]::PolkadotXcm(
|
||||
pallet_xcm::Event::Attempted { outcome: Outcome::Error(error) }
|
||||
) => {
|
||||
error: *error == expected_error.unwrap_or(*error),
|
||||
},
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/// Asserts a XCM message is sent
|
||||
pub fn assert_xcm_pallet_sent() {
|
||||
assert_expected_events!(
|
||||
Self,
|
||||
vec![
|
||||
[<$chain RuntimeEvent>]::PolkadotXcm(pallet_xcm::Event::Sent { .. }) => {},
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/// Asserts a XCM message is sent to Relay Chain
|
||||
pub fn assert_parachain_system_ump_sent() {
|
||||
assert_expected_events!(
|
||||
Self,
|
||||
vec![
|
||||
[<$chain RuntimeEvent>]::ParachainSystem(
|
||||
cumulus_pallet_parachain_system::Event::UpwardMessageSent { .. }
|
||||
) => {},
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/// Asserts a XCM from Relay Chain is completely executed
|
||||
pub fn assert_dmp_queue_complete(expected_weight: Option<Weight>) {
|
||||
assert_expected_events!(
|
||||
Self,
|
||||
vec![
|
||||
[<$chain RuntimeEvent>]::DmpQueue(cumulus_pallet_dmp_queue::Event::ExecutedDownward {
|
||||
outcome: Outcome::Complete(weight), ..
|
||||
}) => {
|
||||
weight: weight_within_threshold(
|
||||
(REF_TIME_THRESHOLD, PROOF_SIZE_THRESHOLD),
|
||||
expected_weight.unwrap_or(*weight),
|
||||
*weight
|
||||
),
|
||||
},
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/// Asserts a XCM from Relay Chain is incompletely executed
|
||||
pub fn assert_dmp_queue_incomplete(
|
||||
expected_weight: Option<Weight>,
|
||||
expected_error: Option<Error>,
|
||||
) {
|
||||
assert_expected_events!(
|
||||
Self,
|
||||
vec![
|
||||
[<$chain RuntimeEvent>]::DmpQueue(cumulus_pallet_dmp_queue::Event::ExecutedDownward {
|
||||
outcome: Outcome::Incomplete(weight, error), ..
|
||||
}) => {
|
||||
weight: weight_within_threshold(
|
||||
(REF_TIME_THRESHOLD, PROOF_SIZE_THRESHOLD),
|
||||
expected_weight.unwrap_or(*weight),
|
||||
*weight
|
||||
),
|
||||
error: *error == expected_error.unwrap_or(*error),
|
||||
},
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/// Asserts a XCM from another Parachain is completely executed
|
||||
pub fn assert_xcmp_queue_success(expected_weight: Option<Weight>) {
|
||||
assert_expected_events!(
|
||||
Self,
|
||||
vec![
|
||||
[<$chain RuntimeEvent>]::XcmpQueue(
|
||||
cumulus_pallet_xcmp_queue::Event::Success { weight, .. }
|
||||
) => {
|
||||
weight: weight_within_threshold(
|
||||
(REF_TIME_THRESHOLD, PROOF_SIZE_THRESHOLD),
|
||||
expected_weight.unwrap_or(*weight),
|
||||
*weight
|
||||
),
|
||||
},
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! impl_assets_helpers_for_parachain {
|
||||
( $chain:ident, $relay_chain:ident ) => {
|
||||
$crate::paste::paste! {
|
||||
impl $chain {
|
||||
/// Returns the encoded call for `force_create` from the assets pallet
|
||||
pub fn force_create_asset_call(
|
||||
asset_id: u32,
|
||||
owner: AccountId,
|
||||
is_sufficient: bool,
|
||||
min_balance: Balance,
|
||||
) -> DoubleEncoded<()> {
|
||||
<Self as Chain>::RuntimeCall::Assets(pallet_assets::Call::<
|
||||
<Self as Chain>::Runtime,
|
||||
Instance1,
|
||||
>::force_create {
|
||||
id: asset_id.into(),
|
||||
owner: owner.into(),
|
||||
is_sufficient,
|
||||
min_balance,
|
||||
})
|
||||
.encode()
|
||||
.into()
|
||||
}
|
||||
|
||||
/// Returns a `VersionedXcm` for `force_create` from the assets pallet
|
||||
pub fn force_create_asset_xcm(
|
||||
origin_kind: OriginKind,
|
||||
asset_id: u32,
|
||||
owner: AccountId,
|
||||
is_sufficient: bool,
|
||||
min_balance: Balance,
|
||||
) -> VersionedXcm<()> {
|
||||
let call = Self::force_create_asset_call(asset_id, owner, is_sufficient, min_balance);
|
||||
xcm_transact_unpaid_execution(call, origin_kind)
|
||||
}
|
||||
|
||||
/// Mint assets making use of the assets pallet
|
||||
pub fn mint_asset(
|
||||
signed_origin: <Self as Chain>::RuntimeOrigin,
|
||||
id: u32,
|
||||
beneficiary: AccountId,
|
||||
amount_to_mint: u128,
|
||||
) {
|
||||
Self::execute_with(|| {
|
||||
assert_ok!(<Self as [<$chain Pallet>]>::Assets::mint(
|
||||
signed_origin,
|
||||
id.into(),
|
||||
beneficiary.clone().into(),
|
||||
amount_to_mint
|
||||
));
|
||||
|
||||
type RuntimeEvent = <$chain as Chain>::RuntimeEvent;
|
||||
|
||||
assert_expected_events!(
|
||||
Self,
|
||||
vec![
|
||||
RuntimeEvent::Assets(pallet_assets::Event::Issued { asset_id, owner, amount }) => {
|
||||
asset_id: *asset_id == id,
|
||||
owner: *owner == beneficiary.clone().into(),
|
||||
amount: *amount == amount_to_mint,
|
||||
},
|
||||
]
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
/// Force create and mint assets making use of the assets pallet
|
||||
pub fn force_create_and_mint_asset(
|
||||
id: u32,
|
||||
min_balance: u128,
|
||||
is_sufficient: bool,
|
||||
asset_owner: AccountId,
|
||||
amount_to_mint: u128,
|
||||
) {
|
||||
// Init values for Relay Chain
|
||||
let root_origin = <$relay_chain as Chain>::RuntimeOrigin::root();
|
||||
let destination = <$relay_chain>::child_location_of(<$chain>::para_id());
|
||||
let xcm = Self::force_create_asset_xcm(
|
||||
OriginKind::Superuser,
|
||||
id,
|
||||
asset_owner.clone(),
|
||||
is_sufficient,
|
||||
min_balance,
|
||||
);
|
||||
|
||||
<$relay_chain>::execute_with(|| {
|
||||
assert_ok!(<$relay_chain as [<$relay_chain Pallet>]>::XcmPallet::send(
|
||||
root_origin,
|
||||
bx!(destination.into()),
|
||||
bx!(xcm),
|
||||
));
|
||||
|
||||
<$relay_chain>::assert_xcm_pallet_sent();
|
||||
});
|
||||
|
||||
Self::execute_with(|| {
|
||||
Self::assert_dmp_queue_complete(Some(Weight::from_parts(1_019_445_000, 200_000)));
|
||||
|
||||
type RuntimeEvent = <$chain as Chain>::RuntimeEvent;
|
||||
|
||||
assert_expected_events!(
|
||||
Self,
|
||||
vec![
|
||||
// Asset has been created
|
||||
RuntimeEvent::Assets(pallet_assets::Event::ForceCreated { asset_id, owner }) => {
|
||||
asset_id: *asset_id == id,
|
||||
owner: *owner == asset_owner.clone(),
|
||||
},
|
||||
]
|
||||
);
|
||||
|
||||
assert!(<Self as [<$chain Pallet>]>::Assets::asset_exists(id.into()));
|
||||
});
|
||||
|
||||
let signed_origin = <Self as Chain>::RuntimeOrigin::signed(asset_owner.clone());
|
||||
|
||||
// Mint asset for System Parachain's sender
|
||||
Self::mint_asset(signed_origin, id, asset_owner, amount_to_mint);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user