mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-30 17:31:03 +00:00
cumulus: add asset-hub-rococo runtime based on asset-hub-kusama and add asset-bridging support to it (#1215)
This commit adds Rococo Asset Hub dedicated runtime so we can test new features here, before merging them in Kusama Asset Hub. Also adds one such feature: asset transfer over bridge (Rococo AssetHub <> Wococo AssetHub) - clone `asset-hub-kusama-runtime` -> `asset-hub-rococo-runtime` - make it use Rococo primitives, names, assets, constants, etc - add asset-transfer-over-bridge support to Rococo AssetHub <> Wococo AssetHub Fixes #1128 --------- Co-authored-by: Branislav Kontur <bkontur@gmail.com> Co-authored-by: joe petrowski <25483142+joepetrowski@users.noreply.github.com> Co-authored-by: Francisco Aguirre <franciscoaguirreperez@gmail.com>
This commit is contained in:
@@ -16,7 +16,6 @@
|
||||
|
||||
//! Module contains predefined test-case scenarios for `Runtime` with bridging capabilities.
|
||||
|
||||
use assert_matches::assert_matches;
|
||||
use bp_messages::{
|
||||
target_chain::{DispatchMessage, DispatchMessageData, MessageDispatch, SourceHeaderChain},
|
||||
LaneId, MessageKey, OutboundLaneData, Weight,
|
||||
@@ -47,10 +46,16 @@ use parachains_runtimes_test_utils::{
|
||||
};
|
||||
use sp_core::H256;
|
||||
use sp_keyring::AccountKeyring::*;
|
||||
use sp_runtime::{traits::Header as HeaderT, AccountId32};
|
||||
use sp_runtime::{
|
||||
traits::{Header as HeaderT, Zero},
|
||||
AccountId32,
|
||||
};
|
||||
use xcm::latest::prelude::*;
|
||||
use xcm_builder::DispatchBlobError;
|
||||
use xcm_executor::XcmExecutor;
|
||||
use xcm_executor::{
|
||||
traits::{TransactAsset, WeightBounds},
|
||||
XcmExecutor,
|
||||
};
|
||||
|
||||
// Re-export test_case from assets
|
||||
pub use asset_test_utils::include_teleports_for_native_asset_works;
|
||||
@@ -137,6 +142,9 @@ pub fn handle_export_message_from_system_parachain_to_outbound_queue_works<
|
||||
>,
|
||||
export_message_instruction: fn() -> Instruction<XcmConfig::RuntimeCall>,
|
||||
expected_lane_id: LaneId,
|
||||
existential_deposit: Option<MultiAsset>,
|
||||
maybe_paid_export_message: Option<MultiAsset>,
|
||||
prepare_configuration: impl Fn(),
|
||||
) where
|
||||
Runtime: frame_system::Config
|
||||
+ pallet_balances::Config
|
||||
@@ -161,6 +169,8 @@ pub fn handle_export_message_from_system_parachain_to_outbound_queue_works<
|
||||
.with_tracing()
|
||||
.build()
|
||||
.execute_with(|| {
|
||||
prepare_configuration();
|
||||
|
||||
// check queue before
|
||||
assert_eq!(
|
||||
pallet_bridge_messages::OutboundLanes::<Runtime, MessagesPalletInstance>::try_get(
|
||||
@@ -170,10 +180,35 @@ pub fn handle_export_message_from_system_parachain_to_outbound_queue_works<
|
||||
);
|
||||
|
||||
// prepare `ExportMessage`
|
||||
let xcm = Xcm(vec![
|
||||
UnpaidExecution { weight_limit: Unlimited, check_origin: None },
|
||||
export_message_instruction(),
|
||||
]);
|
||||
let xcm = if let Some(fee) = maybe_paid_export_message {
|
||||
// deposit ED to origin (if needed)
|
||||
if let Some(ed) = existential_deposit {
|
||||
XcmConfig::AssetTransactor::deposit_asset(
|
||||
&ed,
|
||||
&sibling_parachain_location,
|
||||
&XcmContext::with_message_id([0; 32]),
|
||||
)
|
||||
.expect("deposited ed");
|
||||
}
|
||||
// deposit fee to origin
|
||||
XcmConfig::AssetTransactor::deposit_asset(
|
||||
&fee,
|
||||
&sibling_parachain_location,
|
||||
&XcmContext::with_message_id([0; 32]),
|
||||
)
|
||||
.expect("deposited fee");
|
||||
|
||||
Xcm(vec![
|
||||
WithdrawAsset(MultiAssets::from(vec![fee.clone()])),
|
||||
BuyExecution { fees: fee, weight_limit: Unlimited },
|
||||
export_message_instruction(),
|
||||
])
|
||||
} else {
|
||||
Xcm(vec![
|
||||
UnpaidExecution { weight_limit: Unlimited, check_origin: None },
|
||||
export_message_instruction(),
|
||||
])
|
||||
};
|
||||
|
||||
// execute XCM
|
||||
let hash = xcm.using_encoded(sp_io::hashing::blake2_256);
|
||||
@@ -231,6 +266,7 @@ pub fn message_dispatch_routing_works<
|
||||
dyn Fn(Vec<u8>) -> Option<cumulus_pallet_xcmp_queue::Event<Runtime>>,
|
||||
>,
|
||||
expected_lane_id: LaneId,
|
||||
prepare_configuration: impl Fn(),
|
||||
) where
|
||||
Runtime: frame_system::Config
|
||||
+ pallet_balances::Config
|
||||
@@ -249,6 +285,7 @@ pub fn message_dispatch_routing_works<
|
||||
XcmConfig: xcm_executor::Config,
|
||||
MessagesPalletInstance: 'static,
|
||||
ValidatorIdOf<Runtime>: From<AccountIdOf<Runtime>>,
|
||||
<Runtime as frame_system::Config>::AccountId: From<AccountId32>,
|
||||
HrmpChannelOpener: frame_support::inherent::ProvideInherent<
|
||||
Call = cumulus_pallet_parachain_system::Call<Runtime>,
|
||||
>,
|
||||
@@ -267,12 +304,14 @@ pub fn message_dispatch_routing_works<
|
||||
.with_tracing()
|
||||
.build()
|
||||
.execute_with(|| {
|
||||
prepare_configuration();
|
||||
|
||||
let mut alice = [0u8; 32];
|
||||
alice[0] = 1;
|
||||
|
||||
let included_head = RuntimeHelper::<Runtime, AllPalletsWithoutSystem>::run_to_block(
|
||||
2,
|
||||
AccountId::from(alice),
|
||||
AccountId::from(alice).into(),
|
||||
);
|
||||
// 1. this message is sent from other global consensus with destination of this Runtime relay chain (UMP)
|
||||
let bridging_message =
|
||||
@@ -343,6 +382,7 @@ pub fn relayed_incoming_message_works<Runtime, AllPalletsWithoutSystem, XcmConfi
|
||||
sibling_parachain_id: u32,
|
||||
local_relay_chain_id: NetworkId,
|
||||
lane_id: LaneId,
|
||||
prepare_configuration: impl Fn(),
|
||||
) where
|
||||
Runtime: frame_system::Config
|
||||
+ pallet_balances::Config
|
||||
@@ -374,11 +414,11 @@ pub fn relayed_incoming_message_works<Runtime, AllPalletsWithoutSystem, XcmConfi
|
||||
ParaHash: From<<<Runtime as pallet_bridge_grandpa::Config<GPI>>::BridgedChain as bp_runtime::Chain>::Hash>,
|
||||
<Runtime as frame_system::Config>::AccountId:
|
||||
Into<<<Runtime as frame_system::Config>::RuntimeOrigin as OriginTrait>::AccountId>,
|
||||
<Runtime as frame_system::Config>::AccountId: From<AccountId32>,
|
||||
AccountIdOf<Runtime>: From<sp_core::sr25519::Public>,
|
||||
<Runtime as pallet_bridge_messages::Config<MPI>>::InboundRelayer: From<AccountId32>,
|
||||
{
|
||||
assert_ne!(runtime_para_id, sibling_parachain_id);
|
||||
assert_ne!(runtime_para_id, bridged_para_id);
|
||||
|
||||
ExtBuilder::<Runtime>::default()
|
||||
.with_collators(collator_session_key.collators())
|
||||
@@ -388,12 +428,14 @@ pub fn relayed_incoming_message_works<Runtime, AllPalletsWithoutSystem, XcmConfi
|
||||
.with_tracing()
|
||||
.build()
|
||||
.execute_with(|| {
|
||||
prepare_configuration();
|
||||
|
||||
let mut alice = [0u8; 32];
|
||||
alice[0] = 1;
|
||||
|
||||
let included_head = RuntimeHelper::<Runtime, AllPalletsWithoutSystem>::run_to_block(
|
||||
2,
|
||||
AccountId::from(alice),
|
||||
AccountId::from(alice).into(),
|
||||
);
|
||||
mock_open_hrmp_channel::<Runtime, HrmpChannelOpener>(
|
||||
runtime_para_id.into(),
|
||||
@@ -528,15 +570,24 @@ pub fn relayed_incoming_message_works<Runtime, AllPalletsWithoutSystem, XcmConfi
|
||||
.last_delivered_nonce(),
|
||||
1,
|
||||
);
|
||||
|
||||
// verify relayed bridged XCM message is dispatched to destination sibling para
|
||||
let dispatched = RuntimeHelper::<cumulus_pallet_xcmp_queue::Pallet<Runtime>>::take_xcm(
|
||||
sibling_parachain_id.into(),
|
||||
)
|
||||
.unwrap();
|
||||
let mut dispatched = xcm::latest::Xcm::<()>::try_from(dispatched).unwrap();
|
||||
// We use `WithUniqueTopic`, so expect a trailing `SetTopic`.
|
||||
assert_matches!(dispatched.0.pop(), Some(SetTopic(..)));
|
||||
assert_eq!(dispatched, expected_dispatch);
|
||||
// verify contains original message
|
||||
let dispatched = xcm::latest::Xcm::<()>::try_from(dispatched).unwrap();
|
||||
let mut dispatched_clone = dispatched.clone();
|
||||
for (idx, expected_instr) in expected_dispatch.0.iter().enumerate() {
|
||||
assert_eq!(expected_instr, &dispatched.0[idx]);
|
||||
assert_eq!(expected_instr, &dispatched_clone.0.remove(0));
|
||||
}
|
||||
match dispatched_clone.0.len() {
|
||||
0 => (),
|
||||
1 => assert!(matches!(dispatched_clone.0[0], SetTopic(_))),
|
||||
count => assert!(false, "Unexpected messages count: {:?}", count),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -557,6 +608,7 @@ pub fn complex_relay_extrinsic_works<Runtime, AllPalletsWithoutSystem, XcmConfig
|
||||
sp_keyring::AccountKeyring,
|
||||
pallet_utility::Call::<Runtime>
|
||||
) -> sp_runtime::DispatchOutcome,
|
||||
prepare_configuration: impl Fn(),
|
||||
) where
|
||||
Runtime: frame_system::Config
|
||||
+ pallet_balances::Config
|
||||
@@ -591,6 +643,7 @@ pub fn complex_relay_extrinsic_works<Runtime, AllPalletsWithoutSystem, XcmConfig
|
||||
<Runtime as frame_system::Config>::AccountId:
|
||||
Into<<<Runtime as frame_system::Config>::RuntimeOrigin as OriginTrait>::AccountId>,
|
||||
AccountIdOf<Runtime>: From<sp_core::sr25519::Public>,
|
||||
<Runtime as frame_system::Config>::AccountId: From<AccountId32>,
|
||||
<Runtime as pallet_bridge_messages::Config<MPI>>::InboundRelayer: From<AccountId32>,
|
||||
<Runtime as pallet_utility::Config>::RuntimeCall:
|
||||
From<pallet_bridge_grandpa::Call<Runtime, GPI>>
|
||||
@@ -598,7 +651,6 @@ pub fn complex_relay_extrinsic_works<Runtime, AllPalletsWithoutSystem, XcmConfig
|
||||
+ From<pallet_bridge_messages::Call<Runtime, MPI>>
|
||||
{
|
||||
assert_ne!(runtime_para_id, sibling_parachain_id);
|
||||
assert_ne!(runtime_para_id, bridged_para_id);
|
||||
|
||||
// Relayer account at local/this BH.
|
||||
let relayer_at_target = Bob;
|
||||
@@ -617,12 +669,14 @@ pub fn complex_relay_extrinsic_works<Runtime, AllPalletsWithoutSystem, XcmConfig
|
||||
.with_tracing()
|
||||
.build()
|
||||
.execute_with(|| {
|
||||
prepare_configuration();
|
||||
|
||||
let mut alice = [0u8; 32];
|
||||
alice[0] = 1;
|
||||
|
||||
let included_head = RuntimeHelper::<Runtime, AllPalletsWithoutSystem>::run_to_block(
|
||||
2,
|
||||
AccountId::from(alice),
|
||||
AccountId::from(alice).into(),
|
||||
);
|
||||
let zero: BlockNumberFor<Runtime> = 0u32.into();
|
||||
let genesis_hash = frame_system::Pallet::<Runtime>::block_hash(zero);
|
||||
@@ -678,7 +732,7 @@ pub fn complex_relay_extrinsic_works<Runtime, AllPalletsWithoutSystem, XcmConfig
|
||||
message_proof,
|
||||
) = test_data::make_complex_relayer_proofs::<BridgedHeader<Runtime, GPI>, MB, ()>(
|
||||
lane_id,
|
||||
xcm.into(),
|
||||
xcm.clone().into(),
|
||||
message_nonce,
|
||||
message_destination,
|
||||
para_header_number,
|
||||
@@ -769,18 +823,133 @@ pub fn complex_relay_extrinsic_works<Runtime, AllPalletsWithoutSystem, XcmConfig
|
||||
msg_proofs_rewards_account
|
||||
)
|
||||
.is_some());
|
||||
|
||||
// verify relayed bridged XCM message is dispatched to destination sibling para
|
||||
let dispatched = RuntimeHelper::<cumulus_pallet_xcmp_queue::Pallet<Runtime>>::take_xcm(
|
||||
sibling_parachain_id.into(),
|
||||
)
|
||||
.unwrap();
|
||||
let mut dispatched = xcm::latest::Xcm::<()>::try_from(dispatched).unwrap();
|
||||
// We use `WithUniqueTopic`, so expect a trailing `SetTopic`.
|
||||
assert_matches!(dispatched.0.pop(), Some(SetTopic(..)));
|
||||
assert_eq!(dispatched, expected_dispatch);
|
||||
// verify contains original message
|
||||
let dispatched = xcm::latest::Xcm::<()>::try_from(dispatched).unwrap();
|
||||
let mut dispatched_clone = dispatched.clone();
|
||||
for (idx, expected_instr) in expected_dispatch.0.iter().enumerate() {
|
||||
assert_eq!(expected_instr, &dispatched.0[idx]);
|
||||
assert_eq!(expected_instr, &dispatched_clone.0.remove(0));
|
||||
}
|
||||
match dispatched_clone.0.len() {
|
||||
0 => (),
|
||||
1 => assert!(matches!(dispatched_clone.0[0], SetTopic(_))),
|
||||
count => assert!(false, "Unexpected messages count: {:?}", count),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Estimates fee for paid `ExportMessage` processing.
|
||||
pub fn can_calculate_weight_for_paid_export_message_with_reserve_transfer<
|
||||
Runtime,
|
||||
XcmConfig,
|
||||
WeightToFee,
|
||||
>() -> u128
|
||||
where
|
||||
Runtime: frame_system::Config + pallet_balances::Config,
|
||||
XcmConfig: xcm_executor::Config,
|
||||
WeightToFee: frame_support::weights::WeightToFee<Balance = BalanceOf<Runtime>>,
|
||||
<WeightToFee as frame_support::weights::WeightToFee>::Balance: From<u128> + Into<u128>,
|
||||
{
|
||||
// data here are not relevant for weighing
|
||||
let mut xcm = Xcm(vec![
|
||||
WithdrawAsset(MultiAssets::from(vec![MultiAsset {
|
||||
id: Concrete(MultiLocation { parents: 1, interior: Here }),
|
||||
fun: Fungible(34333299),
|
||||
}])),
|
||||
BuyExecution {
|
||||
fees: MultiAsset {
|
||||
id: Concrete(MultiLocation { parents: 1, interior: Here }),
|
||||
fun: Fungible(34333299),
|
||||
},
|
||||
weight_limit: Unlimited,
|
||||
},
|
||||
ExportMessage {
|
||||
network: Polkadot,
|
||||
destination: X1(Parachain(1000)),
|
||||
xcm: Xcm(vec![
|
||||
ReserveAssetDeposited(MultiAssets::from(vec![MultiAsset {
|
||||
id: Concrete(MultiLocation {
|
||||
parents: 2,
|
||||
interior: X1(GlobalConsensus(Kusama)),
|
||||
}),
|
||||
fun: Fungible(1000000000000),
|
||||
}])),
|
||||
ClearOrigin,
|
||||
BuyExecution {
|
||||
fees: MultiAsset {
|
||||
id: Concrete(MultiLocation {
|
||||
parents: 2,
|
||||
interior: X1(GlobalConsensus(Kusama)),
|
||||
}),
|
||||
fun: Fungible(1000000000000),
|
||||
},
|
||||
weight_limit: Unlimited,
|
||||
},
|
||||
DepositAsset {
|
||||
assets: Wild(AllCounted(1)),
|
||||
beneficiary: MultiLocation {
|
||||
parents: 0,
|
||||
interior: X1(xcm::latest::prelude::AccountId32 {
|
||||
network: None,
|
||||
id: [
|
||||
212, 53, 147, 199, 21, 253, 211, 28, 97, 20, 26, 189, 4, 169, 159,
|
||||
214, 130, 44, 133, 88, 133, 76, 205, 227, 154, 86, 132, 231, 165,
|
||||
109, 162, 125,
|
||||
],
|
||||
}),
|
||||
},
|
||||
},
|
||||
SetTopic([
|
||||
116, 82, 194, 132, 171, 114, 217, 165, 23, 37, 161, 177, 165, 179, 247, 114,
|
||||
137, 101, 147, 70, 28, 157, 168, 32, 154, 63, 74, 228, 152, 180, 5, 63,
|
||||
]),
|
||||
]),
|
||||
},
|
||||
RefundSurplus,
|
||||
DepositAsset {
|
||||
assets: Wild(All),
|
||||
beneficiary: MultiLocation { parents: 1, interior: X1(Parachain(1000)) },
|
||||
},
|
||||
SetTopic([
|
||||
36, 224, 250, 165, 82, 195, 67, 110, 160, 170, 140, 87, 217, 62, 201, 164, 42, 98, 219,
|
||||
157, 124, 105, 248, 25, 131, 218, 199, 36, 109, 173, 100, 122,
|
||||
]),
|
||||
]);
|
||||
|
||||
// get weight
|
||||
let weight = XcmConfig::Weigher::weight(&mut xcm);
|
||||
assert_ok!(weight);
|
||||
let weight = weight.unwrap();
|
||||
// check if sane
|
||||
let max_expected = Runtime::BlockWeights::get().max_block / 10;
|
||||
assert!(
|
||||
weight.all_lte(max_expected),
|
||||
"calculated weight: {:?}, max_expected: {:?}",
|
||||
weight,
|
||||
max_expected
|
||||
);
|
||||
|
||||
// check fee, should not be 0
|
||||
let estimated_fee = WeightToFee::weight_to_fee(&weight);
|
||||
assert!(estimated_fee > BalanceOf::<Runtime>::zero());
|
||||
|
||||
sp_tracing::try_init_simple();
|
||||
log::error!(
|
||||
target: "bridges::estimate",
|
||||
"Estimate fee: {:?} for `ExportMessage` for runtime: {:?}",
|
||||
estimated_fee,
|
||||
Runtime::Version::get(),
|
||||
);
|
||||
|
||||
estimated_fee.into()
|
||||
}
|
||||
|
||||
pub mod test_data {
|
||||
use super::*;
|
||||
use bp_header_chain::justification::GrandpaJustification;
|
||||
@@ -928,7 +1097,7 @@ pub mod test_data {
|
||||
);
|
||||
|
||||
/// Simulates `HaulBlobExporter` and all its wrapping and captures generated plain bytes,
|
||||
/// which are transfered over bridge.
|
||||
/// which are transferred over bridge.
|
||||
pub(crate) fn simulate_message_exporter_on_bridged_chain<
|
||||
SourceNetwork: Get<NetworkId>,
|
||||
DestinationNetwork: Get<NetworkId>,
|
||||
|
||||
Reference in New Issue
Block a user