mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-17 18:21:02 +00:00
Bridge: make some headers submissions free (#4102)
supersedes https://github.com/paritytech/parity-bridges-common/pull/2873 Draft because of couple of TODOs: - [x] fix remaining TODOs; - [x] double check that all changes from https://github.com/paritytech/parity-bridges-common/pull/2873 are correctly ported; - [x] create a separate PR (on top of that one or a follow up?) for https://github.com/paritytech/polkadot-sdk/tree/sv-try-new-bridge-fees; - [x] fix compilation issues (haven't checked, but there should be many). --------- Co-authored-by: Adrian Catangiu <adrian@parity.io>
This commit is contained in:
committed by
GitHub
parent
4f3d43a0c4
commit
a633e954f3
@@ -22,6 +22,7 @@ scale-info = { version = "2.11.1", default-features = false, features = [
|
||||
"derive",
|
||||
] }
|
||||
serde = { optional = true, features = ["derive"], workspace = true, default-features = true }
|
||||
tuplex = { version = "0.1", default-features = false }
|
||||
|
||||
# Substrate
|
||||
frame-benchmarking = { path = "../../../../../substrate/frame/benchmarking", default-features = false, optional = true }
|
||||
@@ -218,6 +219,7 @@ std = [
|
||||
"sp-version/std",
|
||||
"substrate-wasm-builder",
|
||||
"testnet-parachains-constants/std",
|
||||
"tuplex/std",
|
||||
"xcm-builder/std",
|
||||
"xcm-executor/std",
|
||||
"xcm/std",
|
||||
|
||||
+4
-2
@@ -49,7 +49,8 @@ pub type BridgeGrandpaWestendInstance = pallet_bridge_grandpa::Instance3;
|
||||
impl pallet_bridge_grandpa::Config<BridgeGrandpaWestendInstance> for Runtime {
|
||||
type RuntimeEvent = RuntimeEvent;
|
||||
type BridgedChain = bp_westend::Westend;
|
||||
type MaxFreeMandatoryHeadersPerBlock = ConstU32<4>;
|
||||
type MaxFreeHeadersPerBlock = ConstU32<4>;
|
||||
type FreeHeadersInterval = ConstU32<5>;
|
||||
type HeadersToKeep = RelayChainHeadersToKeep;
|
||||
type WeightInfo = weights::pallet_bridge_grandpa::WeightInfo<Runtime>;
|
||||
}
|
||||
@@ -89,7 +90,8 @@ pub type BridgeGrandpaRococoBulletinInstance = pallet_bridge_grandpa::Instance4;
|
||||
impl pallet_bridge_grandpa::Config<BridgeGrandpaRococoBulletinInstance> for Runtime {
|
||||
type RuntimeEvent = RuntimeEvent;
|
||||
type BridgedChain = bp_polkadot_bulletin::PolkadotBulletin;
|
||||
type MaxFreeMandatoryHeadersPerBlock = ConstU32<4>;
|
||||
type MaxFreeHeadersPerBlock = ConstU32<4>;
|
||||
type FreeHeadersInterval = ConstU32<5>;
|
||||
type HeadersToKeep = RelayChainHeadersToKeep;
|
||||
// Technically this is incorrect - we have two pallet instances and ideally we shall
|
||||
// benchmark every instance separately. But the benchmarking engine has a flaw - it
|
||||
|
||||
+18
-9
@@ -20,17 +20,15 @@
|
||||
//! are reusing Polkadot Bulletin chain primitives everywhere here.
|
||||
|
||||
use crate::{
|
||||
bridge_common_config::{BridgeGrandpaRococoBulletinInstance, BridgeHubRococo},
|
||||
weights,
|
||||
xcm_config::UniversalLocation,
|
||||
AccountId, BridgeRococoBulletinGrandpa, BridgeRococoBulletinMessages, PolkadotXcm, Runtime,
|
||||
RuntimeEvent, XcmOverRococoBulletin, XcmRouter,
|
||||
bridge_common_config::BridgeHubRococo, weights, xcm_config::UniversalLocation, AccountId,
|
||||
BridgeRococoBulletinGrandpa, BridgeRococoBulletinMessages, PolkadotXcm, Runtime, RuntimeEvent,
|
||||
XcmOverRococoBulletin, XcmRouter,
|
||||
};
|
||||
use bp_messages::LaneId;
|
||||
use bp_runtime::Chain;
|
||||
use bridge_runtime_common::{
|
||||
extensions::refund_relayer_extension::{
|
||||
ActualFeeRefund, RefundBridgedGrandpaMessages, RefundSignedExtensionAdapter,
|
||||
ActualFeeRefund, RefundBridgedMessages, RefundSignedExtensionAdapter,
|
||||
RefundableMessagesLane,
|
||||
},
|
||||
messages,
|
||||
@@ -83,6 +81,9 @@ parameter_types! {
|
||||
pub const RococoPeopleToRococoBulletinMessagesLane: bp_messages::LaneId
|
||||
= XCM_LANE_FOR_ROCOCO_PEOPLE_TO_ROCOCO_BULLETIN;
|
||||
|
||||
// see the `FEE_BOOST_PER_RELAY_HEADER` constant get the meaning of this value
|
||||
pub PriorityBoostPerRelayHeader: u64 = 58_014_163_614_163;
|
||||
|
||||
/// Priority boost that the registered relayer receives for every additional message in the message
|
||||
/// delivery transaction.
|
||||
///
|
||||
@@ -169,9 +170,8 @@ impl messages::BridgedChainWithMessages for RococoBulletin {}
|
||||
/// Signed extension that refunds relayers that are delivering messages from the Rococo Bulletin
|
||||
/// chain.
|
||||
pub type OnBridgeHubRococoRefundRococoBulletinMessages = RefundSignedExtensionAdapter<
|
||||
RefundBridgedGrandpaMessages<
|
||||
RefundBridgedMessages<
|
||||
Runtime,
|
||||
BridgeGrandpaRococoBulletinInstance,
|
||||
RefundableMessagesLane<
|
||||
WithRococoBulletinMessagesInstance,
|
||||
RococoPeopleToRococoBulletinMessagesLane,
|
||||
@@ -244,6 +244,9 @@ mod tests {
|
||||
/// operational costs and a faster bridge), so this value should be significant.
|
||||
const FEE_BOOST_PER_MESSAGE: Balance = 2 * rococo::currency::UNITS;
|
||||
|
||||
// see `FEE_BOOST_PER_MESSAGE` comment
|
||||
const FEE_BOOST_PER_RELAY_HEADER: Balance = 2 * rococo::currency::UNITS;
|
||||
|
||||
#[test]
|
||||
fn ensure_bridge_hub_rococo_message_lane_weights_are_correct() {
|
||||
check_message_lane_weights::<
|
||||
@@ -273,7 +276,13 @@ mod tests {
|
||||
// Bulletin chain - it has the same (almost) runtime for Polkadot Bulletin and Rococo
|
||||
// Bulletin, so we have to adhere Polkadot names here
|
||||
|
||||
bridge_runtime_common::extensions::priority_calculator::ensure_priority_boost_is_sane::<
|
||||
bridge_runtime_common::extensions::priority_calculator::per_relay_header::ensure_priority_boost_is_sane::<
|
||||
Runtime,
|
||||
BridgeGrandpaRococoBulletinInstance,
|
||||
PriorityBoostPerRelayHeader,
|
||||
>(FEE_BOOST_PER_RELAY_HEADER);
|
||||
|
||||
bridge_runtime_common::extensions::priority_calculator::per_message::ensure_priority_boost_is_sane::<
|
||||
Runtime,
|
||||
WithRococoBulletinMessagesInstance,
|
||||
PriorityBoostPerMessage,
|
||||
|
||||
+26
-8
@@ -29,8 +29,8 @@ use bp_messages::LaneId;
|
||||
use bp_runtime::Chain;
|
||||
use bridge_runtime_common::{
|
||||
extensions::refund_relayer_extension::{
|
||||
ActualFeeRefund, RefundBridgedParachainMessages, RefundSignedExtensionAdapter,
|
||||
RefundableMessagesLane, RefundableParachain,
|
||||
ActualFeeRefund, RefundBridgedMessages, RefundSignedExtensionAdapter,
|
||||
RefundableMessagesLane,
|
||||
},
|
||||
messages,
|
||||
messages::{
|
||||
@@ -65,6 +65,10 @@ parameter_types! {
|
||||
2,
|
||||
[GlobalConsensus(WestendGlobalConsensusNetwork::get())]
|
||||
);
|
||||
// see the `FEE_BOOST_PER_RELAY_HEADER` constant get the meaning of this value
|
||||
pub PriorityBoostPerRelayHeader: u64 = 32_007_814_407_814;
|
||||
// see the `FEE_BOOST_PER_PARACHAIN_HEADER` constant get the meaning of this value
|
||||
pub PriorityBoostPerParachainHeader: u64 = 1_396_340_903_540_903;
|
||||
// see the `FEE_BOOST_PER_MESSAGE` constant to get the meaning of this value
|
||||
pub PriorityBoostPerMessage: u64 = 182_044_444_444_444;
|
||||
|
||||
@@ -174,12 +178,8 @@ impl messages::BridgedChainWithMessages for BridgeHubWestend {}
|
||||
|
||||
/// Signed extension that refunds relayers that are delivering messages from the Westend parachain.
|
||||
pub type OnBridgeHubRococoRefundBridgeHubWestendMessages = RefundSignedExtensionAdapter<
|
||||
RefundBridgedParachainMessages<
|
||||
RefundBridgedMessages<
|
||||
Runtime,
|
||||
RefundableParachain<
|
||||
BridgeParachainWestendInstance,
|
||||
bp_bridge_hub_westend::BridgeHubWestend,
|
||||
>,
|
||||
RefundableMessagesLane<
|
||||
WithBridgeHubWestendMessagesInstance,
|
||||
AssetHubRococoToAssetHubWestendMessagesLane,
|
||||
@@ -246,6 +246,7 @@ mod tests {
|
||||
use crate::bridge_common_config::BridgeGrandpaWestendInstance;
|
||||
use bridge_runtime_common::{
|
||||
assert_complete_bridge_types,
|
||||
extensions::refund_relayer_extension::RefundableParachain,
|
||||
integrity::{
|
||||
assert_complete_bridge_constants, check_message_lane_weights,
|
||||
AssertBridgeMessagesPalletConstants, AssertBridgePalletNames, AssertChainConstants,
|
||||
@@ -266,6 +267,11 @@ mod tests {
|
||||
/// operational costs and a faster bridge), so this value should be significant.
|
||||
const FEE_BOOST_PER_MESSAGE: Balance = 2 * rococo::currency::UNITS;
|
||||
|
||||
// see `FEE_BOOST_PER_MESSAGE` comment
|
||||
const FEE_BOOST_PER_RELAY_HEADER: Balance = 2 * rococo::currency::UNITS;
|
||||
// see `FEE_BOOST_PER_MESSAGE` comment
|
||||
const FEE_BOOST_PER_PARACHAIN_HEADER: Balance = 2 * rococo::currency::UNITS;
|
||||
|
||||
#[test]
|
||||
fn ensure_bridge_hub_rococo_message_lane_weights_are_correct() {
|
||||
check_message_lane_weights::<
|
||||
@@ -318,7 +324,19 @@ mod tests {
|
||||
},
|
||||
});
|
||||
|
||||
bridge_runtime_common::extensions::priority_calculator::ensure_priority_boost_is_sane::<
|
||||
bridge_runtime_common::extensions::priority_calculator::per_relay_header::ensure_priority_boost_is_sane::<
|
||||
Runtime,
|
||||
BridgeGrandpaWestendInstance,
|
||||
PriorityBoostPerRelayHeader,
|
||||
>(FEE_BOOST_PER_RELAY_HEADER);
|
||||
|
||||
bridge_runtime_common::extensions::priority_calculator::per_parachain_header::ensure_priority_boost_is_sane::<
|
||||
Runtime,
|
||||
RefundableParachain<WithBridgeHubWestendMessagesInstance, BridgeHubWestend>,
|
||||
PriorityBoostPerParachainHeader,
|
||||
>(FEE_BOOST_PER_PARACHAIN_HEADER);
|
||||
|
||||
bridge_runtime_common::extensions::priority_calculator::per_message::ensure_priority_boost_is_sane::<
|
||||
Runtime,
|
||||
WithBridgeHubWestendMessagesInstance,
|
||||
PriorityBoostPerMessage,
|
||||
|
||||
@@ -35,6 +35,12 @@ pub mod bridge_to_westend_config;
|
||||
mod weights;
|
||||
pub mod xcm_config;
|
||||
|
||||
use bridge_runtime_common::extensions::{
|
||||
check_obsolete_extension::{
|
||||
CheckAndBoostBridgeGrandpaTransactions, CheckAndBoostBridgeParachainsTransactions,
|
||||
},
|
||||
refund_relayer_extension::RefundableParachain,
|
||||
};
|
||||
use cumulus_pallet_parachain_system::RelayNumberMonotonicallyIncreases;
|
||||
use snowbridge_beacon_primitives::{Fork, ForkVersions};
|
||||
use snowbridge_core::{
|
||||
@@ -63,7 +69,7 @@ use frame_support::{
|
||||
dispatch::DispatchClass,
|
||||
genesis_builder_helper::{build_state, get_preset},
|
||||
parameter_types,
|
||||
traits::{ConstBool, ConstU32, ConstU64, ConstU8, TransformOrigin},
|
||||
traits::{ConstBool, ConstU32, ConstU64, ConstU8, Get, TransformOrigin},
|
||||
weights::{ConstantMultiplier, Weight},
|
||||
PalletId,
|
||||
};
|
||||
@@ -740,10 +746,28 @@ pub type XcmOverRococoBulletin = XcmOverPolkadotBulletin;
|
||||
bridge_runtime_common::generate_bridge_reject_obsolete_headers_and_messages! {
|
||||
RuntimeCall, AccountId,
|
||||
// Grandpa
|
||||
BridgeWestendGrandpa,
|
||||
BridgeRococoBulletinGrandpa,
|
||||
CheckAndBoostBridgeGrandpaTransactions<
|
||||
Runtime,
|
||||
bridge_common_config::BridgeGrandpaWestendInstance,
|
||||
bridge_to_westend_config::PriorityBoostPerRelayHeader,
|
||||
xcm_config::TreasuryAccount,
|
||||
>,
|
||||
CheckAndBoostBridgeGrandpaTransactions<
|
||||
Runtime,
|
||||
bridge_common_config::BridgeGrandpaRococoBulletinInstance,
|
||||
bridge_to_bulletin_config::PriorityBoostPerRelayHeader,
|
||||
xcm_config::TreasuryAccount,
|
||||
>,
|
||||
// Parachains
|
||||
BridgeWestendParachains,
|
||||
CheckAndBoostBridgeParachainsTransactions<
|
||||
Runtime,
|
||||
RefundableParachain<
|
||||
bridge_common_config::BridgeParachainWestendInstance,
|
||||
bp_bridge_hub_westend::BridgeHubWestend,
|
||||
>,
|
||||
bridge_to_westend_config::PriorityBoostPerParachainHeader,
|
||||
xcm_config::TreasuryAccount,
|
||||
>,
|
||||
// Messages
|
||||
BridgeWestendMessages,
|
||||
BridgeRococoBulletinMessages
|
||||
@@ -938,6 +962,11 @@ impl_runtime_apis! {
|
||||
fn best_finalized() -> Option<HeaderId<bp_westend::Hash, bp_westend::BlockNumber>> {
|
||||
BridgeWestendGrandpa::best_finalized()
|
||||
}
|
||||
fn free_headers_interval() -> Option<bp_westend::BlockNumber> {
|
||||
<Runtime as pallet_bridge_grandpa::Config<
|
||||
bridge_common_config::BridgeGrandpaWestendInstance
|
||||
>>::FreeHeadersInterval::get()
|
||||
}
|
||||
fn synced_headers_grandpa_info(
|
||||
) -> Vec<bp_header_chain::StoredHeaderGrandpaInfo<bp_westend::Header>> {
|
||||
BridgeWestendGrandpa::synced_headers_grandpa_info()
|
||||
@@ -950,6 +979,10 @@ impl_runtime_apis! {
|
||||
bp_bridge_hub_westend::BridgeHubWestend
|
||||
>().unwrap_or(None)
|
||||
}
|
||||
fn free_headers_interval() -> Option<bp_bridge_hub_westend::BlockNumber> {
|
||||
// "free interval" is not currently used for parachains
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
// This is exposed by BridgeHubRococo
|
||||
@@ -984,6 +1017,12 @@ impl_runtime_apis! {
|
||||
BridgePolkadotBulletinGrandpa::best_finalized()
|
||||
}
|
||||
|
||||
fn free_headers_interval() -> Option<bp_polkadot_bulletin::BlockNumber> {
|
||||
<Runtime as pallet_bridge_grandpa::Config<
|
||||
bridge_common_config::BridgeGrandpaRococoBulletinInstance
|
||||
>>::FreeHeadersInterval::get()
|
||||
}
|
||||
|
||||
fn synced_headers_grandpa_info(
|
||||
) -> Vec<bp_header_chain::StoredHeaderGrandpaInfo<bp_polkadot_bulletin::Header>> {
|
||||
BridgePolkadotBulletinGrandpa::synced_headers_grandpa_info()
|
||||
|
||||
@@ -17,8 +17,10 @@
|
||||
|
||||
//! Expose the auto generated weight files.
|
||||
|
||||
use ::pallet_bridge_grandpa::WeightInfoExt as GrandpaWeightInfoExt;
|
||||
use ::pallet_bridge_messages::WeightInfoExt as MessagesWeightInfoExt;
|
||||
use ::pallet_bridge_parachains::WeightInfoExt as ParachainsWeightInfoExt;
|
||||
use ::pallet_bridge_relayers::WeightInfo as _;
|
||||
|
||||
pub mod block_weights;
|
||||
pub mod cumulus_pallet_parachain_system;
|
||||
@@ -56,6 +58,16 @@ use frame_support::weights::Weight;
|
||||
// import trait from dependency module
|
||||
use ::pallet_bridge_relayers::WeightInfoExt as _;
|
||||
|
||||
impl GrandpaWeightInfoExt for pallet_bridge_grandpa::WeightInfo<crate::Runtime> {
|
||||
fn submit_finality_proof_overhead_from_runtime() -> Weight {
|
||||
// our signed extension:
|
||||
// 1) checks whether relayer registration is active from validate/pre_dispatch;
|
||||
// 2) may slash and deregister relayer from post_dispatch
|
||||
// (2) includes (1), so (2) is the worst case
|
||||
pallet_bridge_relayers::WeightInfo::<Runtime>::slash_and_deregister()
|
||||
}
|
||||
}
|
||||
|
||||
impl MessagesWeightInfoExt
|
||||
for pallet_bridge_messages_rococo_to_rococo_bulletin::WeightInfo<crate::Runtime>
|
||||
{
|
||||
@@ -94,4 +106,12 @@ impl ParachainsWeightInfoExt for pallet_bridge_parachains::WeightInfo<crate::Run
|
||||
fn expected_extra_storage_proof_size() -> u32 {
|
||||
bp_bridge_hub_westend::EXTRA_STORAGE_PROOF_SIZE
|
||||
}
|
||||
|
||||
fn submit_parachain_heads_overhead_from_runtime() -> Weight {
|
||||
// our signed extension:
|
||||
// 1) checks whether relayer registration is active from validate/pre_dispatch;
|
||||
// 2) may slash and deregister relayer from post_dispatch
|
||||
// (2) includes (1), so (2) is the worst case
|
||||
pallet_bridge_relayers::WeightInfo::<Runtime>::slash_and_deregister()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,11 +80,10 @@ fn construct_and_apply_extrinsic(
|
||||
r.unwrap()
|
||||
}
|
||||
|
||||
fn construct_and_estimate_extrinsic_fee(batch: pallet_utility::Call<Runtime>) -> Balance {
|
||||
let batch_call = RuntimeCall::Utility(batch);
|
||||
let batch_info = batch_call.get_dispatch_info();
|
||||
let xt = construct_extrinsic(Alice, batch_call);
|
||||
TransactionPayment::compute_fee(xt.encoded_size() as _, &batch_info, 0)
|
||||
fn construct_and_estimate_extrinsic_fee(call: RuntimeCall) -> Balance {
|
||||
let info = call.get_dispatch_info();
|
||||
let xt = construct_extrinsic(Alice, call);
|
||||
TransactionPayment::compute_fee(xt.encoded_size() as _, &info, 0)
|
||||
}
|
||||
|
||||
fn collator_session_keys() -> bridge_hub_test_utils::CollatorSessionKeys<Runtime> {
|
||||
@@ -376,20 +375,20 @@ mod bridge_hub_westend_tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn complex_relay_extrinsic_works() {
|
||||
// for Westend
|
||||
from_parachain::complex_relay_extrinsic_works::<RuntimeTestsAdapter>(
|
||||
fn free_relay_extrinsic_works() {
|
||||
// from Westend
|
||||
from_parachain::free_relay_extrinsic_works::<RuntimeTestsAdapter>(
|
||||
collator_session_keys(),
|
||||
slot_durations(),
|
||||
bp_bridge_hub_rococo::BRIDGE_HUB_ROCOCO_PARACHAIN_ID,
|
||||
bp_bridge_hub_westend::BRIDGE_HUB_WESTEND_PARACHAIN_ID,
|
||||
SIBLING_PARACHAIN_ID,
|
||||
BridgeHubWestendChainId::get(),
|
||||
SIBLING_PARACHAIN_ID,
|
||||
Rococo,
|
||||
XCM_LANE_FOR_ASSET_HUB_ROCOCO_TO_ASSET_HUB_WESTEND,
|
||||
|| (),
|
||||
construct_and_apply_extrinsic,
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -414,12 +413,12 @@ mod bridge_hub_westend_tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn can_calculate_fee_for_complex_message_delivery_transaction() {
|
||||
fn can_calculate_fee_for_standalone_message_delivery_transaction() {
|
||||
bridge_hub_test_utils::check_sane_fees_values(
|
||||
"bp_bridge_hub_rococo::BridgeHubRococoBaseDeliveryFeeInRocs",
|
||||
bp_bridge_hub_rococo::BridgeHubRococoBaseDeliveryFeeInRocs::get(),
|
||||
|| {
|
||||
from_parachain::can_calculate_fee_for_complex_message_delivery_transaction::<
|
||||
from_parachain::can_calculate_fee_for_standalone_message_delivery_transaction::<
|
||||
RuntimeTestsAdapter,
|
||||
>(collator_session_keys(), construct_and_estimate_extrinsic_fee)
|
||||
},
|
||||
@@ -433,12 +432,12 @@ mod bridge_hub_westend_tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn can_calculate_fee_for_complex_message_confirmation_transaction() {
|
||||
fn can_calculate_fee_for_standalone_message_confirmation_transaction() {
|
||||
bridge_hub_test_utils::check_sane_fees_values(
|
||||
"bp_bridge_hub_rococo::BridgeHubRococoBaseConfirmationFeeInRocs",
|
||||
bp_bridge_hub_rococo::BridgeHubRococoBaseConfirmationFeeInRocs::get(),
|
||||
|| {
|
||||
from_parachain::can_calculate_fee_for_complex_message_confirmation_transaction::<
|
||||
from_parachain::can_calculate_fee_for_standalone_message_confirmation_transaction::<
|
||||
RuntimeTestsAdapter,
|
||||
>(collator_session_keys(), construct_and_estimate_extrinsic_fee)
|
||||
},
|
||||
@@ -581,28 +580,28 @@ mod bridge_hub_bulletin_tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn complex_relay_extrinsic_works() {
|
||||
// for Bulletin
|
||||
from_grandpa_chain::complex_relay_extrinsic_works::<RuntimeTestsAdapter>(
|
||||
fn free_relay_extrinsic_works() {
|
||||
// from Bulletin
|
||||
from_grandpa_chain::free_relay_extrinsic_works::<RuntimeTestsAdapter>(
|
||||
collator_session_keys(),
|
||||
slot_durations(),
|
||||
bp_bridge_hub_rococo::BRIDGE_HUB_ROCOCO_PARACHAIN_ID,
|
||||
SIBLING_PARACHAIN_ID,
|
||||
RococoBulletinChainId::get(),
|
||||
SIBLING_PARACHAIN_ID,
|
||||
Rococo,
|
||||
XCM_LANE_FOR_ROCOCO_PEOPLE_TO_ROCOCO_BULLETIN,
|
||||
|| (),
|
||||
construct_and_apply_extrinsic,
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn can_calculate_fee_for_complex_message_delivery_transaction() {
|
||||
pub fn can_calculate_fee_for_standalone_message_delivery_transaction() {
|
||||
bridge_hub_test_utils::check_sane_fees_values(
|
||||
"bp_bridge_hub_rococo::BridgeHubRococoBaseDeliveryFeeInRocs",
|
||||
bp_bridge_hub_rococo::BridgeHubRococoBaseDeliveryFeeInRocs::get(),
|
||||
|| {
|
||||
from_grandpa_chain::can_calculate_fee_for_complex_message_delivery_transaction::<
|
||||
from_grandpa_chain::can_calculate_fee_for_standalone_message_delivery_transaction::<
|
||||
RuntimeTestsAdapter,
|
||||
>(collator_session_keys(), construct_and_estimate_extrinsic_fee)
|
||||
},
|
||||
@@ -617,12 +616,12 @@ mod bridge_hub_bulletin_tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn can_calculate_fee_for_complex_message_confirmation_transaction() {
|
||||
pub fn can_calculate_fee_for_standalone_message_confirmation_transaction() {
|
||||
bridge_hub_test_utils::check_sane_fees_values(
|
||||
"bp_bridge_hub_rococo::BridgeHubRococoBaseConfirmationFeeInRocs",
|
||||
bp_bridge_hub_rococo::BridgeHubRococoBaseConfirmationFeeInRocs::get(),
|
||||
|| {
|
||||
from_grandpa_chain::can_calculate_fee_for_complex_message_confirmation_transaction::<
|
||||
from_grandpa_chain::can_calculate_fee_for_standalone_message_confirmation_transaction::<
|
||||
RuntimeTestsAdapter,
|
||||
>(collator_session_keys(), construct_and_estimate_extrinsic_fee)
|
||||
},
|
||||
|
||||
@@ -18,6 +18,7 @@ hex-literal = { version = "0.4.1" }
|
||||
log = { workspace = true }
|
||||
scale-info = { version = "2.11.1", default-features = false, features = ["derive"] }
|
||||
serde = { optional = true, features = ["derive"], workspace = true, default-features = true }
|
||||
tuplex = { version = "0.1", default-features = false }
|
||||
|
||||
# Substrate
|
||||
frame-benchmarking = { path = "../../../../../substrate/frame/benchmarking", default-features = false, optional = true }
|
||||
@@ -180,6 +181,7 @@ std = [
|
||||
"sp-version/std",
|
||||
"substrate-wasm-builder",
|
||||
"testnet-parachains-constants/std",
|
||||
"tuplex/std",
|
||||
"westend-runtime-constants/std",
|
||||
"xcm-builder/std",
|
||||
"xcm-executor/std",
|
||||
|
||||
+28
-6
@@ -26,8 +26,8 @@ use bp_parachains::SingleParaStoredHeaderDataBuilder;
|
||||
use bp_runtime::Chain;
|
||||
use bridge_runtime_common::{
|
||||
extensions::refund_relayer_extension::{
|
||||
ActualFeeRefund, RefundBridgedParachainMessages, RefundSignedExtensionAdapter,
|
||||
RefundableMessagesLane, RefundableParachain,
|
||||
ActualFeeRefund, RefundBridgedMessages, RefundSignedExtensionAdapter,
|
||||
RefundableMessagesLane,
|
||||
},
|
||||
messages,
|
||||
messages::{
|
||||
@@ -70,6 +70,10 @@ parameter_types! {
|
||||
2,
|
||||
[GlobalConsensus(RococoGlobalConsensusNetwork::get())]
|
||||
);
|
||||
// see the `FEE_BOOST_PER_RELAY_HEADER` constant get the meaning of this value
|
||||
pub PriorityBoostPerRelayHeader: u64 = 32_007_814_407_814;
|
||||
// see the `FEE_BOOST_PER_PARACHAIN_HEADER` constant get the meaning of this value
|
||||
pub PriorityBoostPerParachainHeader: u64 = 1_396_340_903_540_903;
|
||||
// see the `FEE_BOOST_PER_MESSAGE` constant to get the meaning of this value
|
||||
pub PriorityBoostPerMessage: u64 = 182_044_444_444_444;
|
||||
|
||||
@@ -191,9 +195,8 @@ impl ThisChainWithMessages for BridgeHubWestend {
|
||||
|
||||
/// Signed extension that refunds relayers that are delivering messages from the Rococo parachain.
|
||||
pub type OnBridgeHubWestendRefundBridgeHubRococoMessages = RefundSignedExtensionAdapter<
|
||||
RefundBridgedParachainMessages<
|
||||
RefundBridgedMessages<
|
||||
Runtime,
|
||||
RefundableParachain<BridgeParachainRococoInstance, bp_bridge_hub_rococo::BridgeHubRococo>,
|
||||
RefundableMessagesLane<
|
||||
WithBridgeHubRococoMessagesInstance,
|
||||
AssetHubWestendToAssetHubRococoMessagesLane,
|
||||
@@ -210,7 +213,8 @@ pub type BridgeGrandpaRococoInstance = pallet_bridge_grandpa::Instance1;
|
||||
impl pallet_bridge_grandpa::Config<BridgeGrandpaRococoInstance> for Runtime {
|
||||
type RuntimeEvent = RuntimeEvent;
|
||||
type BridgedChain = bp_rococo::Rococo;
|
||||
type MaxFreeMandatoryHeadersPerBlock = ConstU32<4>;
|
||||
type MaxFreeHeadersPerBlock = ConstU32<4>;
|
||||
type FreeHeadersInterval = ConstU32<5>;
|
||||
type HeadersToKeep = RelayChainHeadersToKeep;
|
||||
type WeightInfo = weights::pallet_bridge_grandpa::WeightInfo<Runtime>;
|
||||
}
|
||||
@@ -281,6 +285,7 @@ mod tests {
|
||||
use super::*;
|
||||
use bridge_runtime_common::{
|
||||
assert_complete_bridge_types,
|
||||
extensions::refund_relayer_extension::RefundableParachain,
|
||||
integrity::{
|
||||
assert_complete_bridge_constants, check_message_lane_weights,
|
||||
AssertBridgeMessagesPalletConstants, AssertBridgePalletNames, AssertChainConstants,
|
||||
@@ -301,6 +306,11 @@ mod tests {
|
||||
/// operational costs and a faster bridge), so this value should be significant.
|
||||
const FEE_BOOST_PER_MESSAGE: Balance = 2 * westend::currency::UNITS;
|
||||
|
||||
// see `FEE_BOOST_PER_MESSAGE` comment
|
||||
const FEE_BOOST_PER_RELAY_HEADER: Balance = 2 * westend::currency::UNITS;
|
||||
// see `FEE_BOOST_PER_MESSAGE` comment
|
||||
const FEE_BOOST_PER_PARACHAIN_HEADER: Balance = 2 * westend::currency::UNITS;
|
||||
|
||||
#[test]
|
||||
fn ensure_bridge_hub_westend_message_lane_weights_are_correct() {
|
||||
check_message_lane_weights::<
|
||||
@@ -352,7 +362,19 @@ mod tests {
|
||||
},
|
||||
});
|
||||
|
||||
bridge_runtime_common::extensions::priority_calculator::ensure_priority_boost_is_sane::<
|
||||
bridge_runtime_common::extensions::priority_calculator::per_relay_header::ensure_priority_boost_is_sane::<
|
||||
Runtime,
|
||||
BridgeGrandpaRococoInstance,
|
||||
PriorityBoostPerRelayHeader,
|
||||
>(FEE_BOOST_PER_RELAY_HEADER);
|
||||
|
||||
bridge_runtime_common::extensions::priority_calculator::per_parachain_header::ensure_priority_boost_is_sane::<
|
||||
Runtime,
|
||||
RefundableParachain<WithBridgeHubRococoMessagesInstance, BridgeHubRococo>,
|
||||
PriorityBoostPerParachainHeader,
|
||||
>(FEE_BOOST_PER_PARACHAIN_HEADER);
|
||||
|
||||
bridge_runtime_common::extensions::priority_calculator::per_message::ensure_priority_boost_is_sane::<
|
||||
Runtime,
|
||||
WithBridgeHubRococoMessagesInstance,
|
||||
PriorityBoostPerMessage,
|
||||
|
||||
@@ -32,6 +32,12 @@ pub mod bridge_to_rococo_config;
|
||||
mod weights;
|
||||
pub mod xcm_config;
|
||||
|
||||
use bridge_runtime_common::extensions::{
|
||||
check_obsolete_extension::{
|
||||
CheckAndBoostBridgeGrandpaTransactions, CheckAndBoostBridgeParachainsTransactions,
|
||||
},
|
||||
refund_relayer_extension::RefundableParachain,
|
||||
};
|
||||
use cumulus_pallet_parachain_system::RelayNumberMonotonicallyIncreases;
|
||||
use cumulus_primitives_core::ParaId;
|
||||
use sp_api::impl_runtime_apis;
|
||||
@@ -57,7 +63,7 @@ use frame_support::{
|
||||
dispatch::DispatchClass,
|
||||
genesis_builder_helper::{build_state, get_preset},
|
||||
parameter_types,
|
||||
traits::{ConstBool, ConstU32, ConstU64, ConstU8, TransformOrigin},
|
||||
traits::{ConstBool, ConstU32, ConstU64, ConstU8, Get, TransformOrigin},
|
||||
weights::{ConstantMultiplier, Weight},
|
||||
PalletId,
|
||||
};
|
||||
@@ -502,9 +508,22 @@ construct_runtime!(
|
||||
bridge_runtime_common::generate_bridge_reject_obsolete_headers_and_messages! {
|
||||
RuntimeCall, AccountId,
|
||||
// Grandpa
|
||||
BridgeRococoGrandpa,
|
||||
CheckAndBoostBridgeGrandpaTransactions<
|
||||
Runtime,
|
||||
bridge_to_rococo_config::BridgeGrandpaRococoInstance,
|
||||
bridge_to_rococo_config::PriorityBoostPerRelayHeader,
|
||||
xcm_config::TreasuryAccount,
|
||||
>,
|
||||
// Parachains
|
||||
BridgeRococoParachains,
|
||||
CheckAndBoostBridgeParachainsTransactions<
|
||||
Runtime,
|
||||
RefundableParachain<
|
||||
bridge_to_rococo_config::BridgeParachainRococoInstance,
|
||||
bp_bridge_hub_rococo::BridgeHubRococo,
|
||||
>,
|
||||
bridge_to_rococo_config::PriorityBoostPerParachainHeader,
|
||||
xcm_config::TreasuryAccount,
|
||||
>,
|
||||
// Messages
|
||||
BridgeRococoMessages
|
||||
}
|
||||
@@ -692,6 +711,11 @@ impl_runtime_apis! {
|
||||
fn best_finalized() -> Option<HeaderId<bp_rococo::Hash, bp_rococo::BlockNumber>> {
|
||||
BridgeRococoGrandpa::best_finalized()
|
||||
}
|
||||
fn free_headers_interval() -> Option<bp_rococo::BlockNumber> {
|
||||
<Runtime as pallet_bridge_grandpa::Config<
|
||||
bridge_to_rococo_config::BridgeGrandpaRococoInstance
|
||||
>>::FreeHeadersInterval::get()
|
||||
}
|
||||
fn synced_headers_grandpa_info(
|
||||
) -> Vec<bp_header_chain::StoredHeaderGrandpaInfo<bp_rococo::Header>> {
|
||||
BridgeRococoGrandpa::synced_headers_grandpa_info()
|
||||
@@ -704,6 +728,10 @@ impl_runtime_apis! {
|
||||
bp_bridge_hub_rococo::BridgeHubRococo
|
||||
>().unwrap_or(None)
|
||||
}
|
||||
fn free_headers_interval() -> Option<bp_bridge_hub_rococo::BlockNumber> {
|
||||
// "free interval" is not currently used for parachains
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
impl bp_bridge_hub_rococo::FromBridgeHubRococoInboundLaneApi<Block> for Runtime {
|
||||
|
||||
@@ -17,8 +17,10 @@
|
||||
|
||||
//! Expose the auto generated weight files.
|
||||
|
||||
use ::pallet_bridge_grandpa::WeightInfoExt as GrandpaWeightInfoExt;
|
||||
use ::pallet_bridge_messages::WeightInfoExt as MessagesWeightInfoExt;
|
||||
use ::pallet_bridge_parachains::WeightInfoExt as ParachainsWeightInfoExt;
|
||||
use ::pallet_bridge_relayers::WeightInfo as _;
|
||||
|
||||
pub mod block_weights;
|
||||
pub mod cumulus_pallet_parachain_system;
|
||||
@@ -51,6 +53,16 @@ use frame_support::weights::Weight;
|
||||
// import trait from dependency module
|
||||
use ::pallet_bridge_relayers::WeightInfoExt as _;
|
||||
|
||||
impl GrandpaWeightInfoExt for pallet_bridge_grandpa::WeightInfo<crate::Runtime> {
|
||||
fn submit_finality_proof_overhead_from_runtime() -> Weight {
|
||||
// our signed extension:
|
||||
// 1) checks whether relayer registration is active from validate/pre_dispatch;
|
||||
// 2) may slash and deregister relayer from post_dispatch
|
||||
// (2) includes (1), so (2) is the worst case
|
||||
pallet_bridge_relayers::WeightInfo::<Runtime>::slash_and_deregister()
|
||||
}
|
||||
}
|
||||
|
||||
impl MessagesWeightInfoExt for pallet_bridge_messages::WeightInfo<crate::Runtime> {
|
||||
fn expected_extra_storage_proof_size() -> u32 {
|
||||
bp_bridge_hub_rococo::EXTRA_STORAGE_PROOF_SIZE
|
||||
@@ -70,4 +82,12 @@ impl ParachainsWeightInfoExt for pallet_bridge_parachains::WeightInfo<crate::Run
|
||||
fn expected_extra_storage_proof_size() -> u32 {
|
||||
bp_bridge_hub_rococo::EXTRA_STORAGE_PROOF_SIZE
|
||||
}
|
||||
|
||||
fn submit_parachain_heads_overhead_from_runtime() -> Weight {
|
||||
// our signed extension:
|
||||
// 1) checks whether relayer registration is active from validate/pre_dispatch;
|
||||
// 2) may slash and deregister relayer from post_dispatch
|
||||
// (2) includes (1), so (2) is the worst case
|
||||
pallet_bridge_relayers::WeightInfo::<Runtime>::slash_and_deregister()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,11 +94,10 @@ fn construct_and_apply_extrinsic(
|
||||
r.unwrap()
|
||||
}
|
||||
|
||||
fn construct_and_estimate_extrinsic_fee(batch: pallet_utility::Call<Runtime>) -> Balance {
|
||||
let batch_call = RuntimeCall::Utility(batch);
|
||||
let batch_info = batch_call.get_dispatch_info();
|
||||
let xt = construct_extrinsic(Alice, batch_call);
|
||||
TransactionPayment::compute_fee(xt.encoded_size() as _, &batch_info, 0)
|
||||
fn construct_and_estimate_extrinsic_fee(call: RuntimeCall) -> Balance {
|
||||
let info = call.get_dispatch_info();
|
||||
let xt = construct_extrinsic(Alice, call);
|
||||
TransactionPayment::compute_fee(xt.encoded_size() as _, &info, 0)
|
||||
}
|
||||
|
||||
fn collator_session_keys() -> bridge_hub_test_utils::CollatorSessionKeys<Runtime> {
|
||||
@@ -271,22 +270,6 @@ fn relayed_incoming_message_works() {
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn complex_relay_extrinsic_works() {
|
||||
from_parachain::complex_relay_extrinsic_works::<RuntimeTestsAdapter>(
|
||||
collator_session_keys(),
|
||||
slot_durations(),
|
||||
bp_bridge_hub_westend::BRIDGE_HUB_WESTEND_PARACHAIN_ID,
|
||||
bp_bridge_hub_rococo::BRIDGE_HUB_ROCOCO_PARACHAIN_ID,
|
||||
SIBLING_PARACHAIN_ID,
|
||||
BridgeHubRococoChainId::get(),
|
||||
Westend,
|
||||
XCM_LANE_FOR_ASSET_HUB_WESTEND_TO_ASSET_HUB_ROCOCO,
|
||||
|| (),
|
||||
construct_and_apply_extrinsic,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn can_calculate_weight_for_paid_export_message_with_reserve_transfer() {
|
||||
bridge_hub_test_utils::check_sane_fees_values(
|
||||
@@ -309,12 +292,12 @@ pub fn can_calculate_weight_for_paid_export_message_with_reserve_transfer() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn can_calculate_fee_for_complex_message_delivery_transaction() {
|
||||
pub fn can_calculate_fee_for_standalone_message_delivery_transaction() {
|
||||
bridge_hub_test_utils::check_sane_fees_values(
|
||||
"bp_bridge_hub_westend::BridgeHubWestendBaseDeliveryFeeInWnds",
|
||||
bp_bridge_hub_westend::BridgeHubWestendBaseDeliveryFeeInWnds::get(),
|
||||
|| {
|
||||
from_parachain::can_calculate_fee_for_complex_message_delivery_transaction::<
|
||||
from_parachain::can_calculate_fee_for_standalone_message_delivery_transaction::<
|
||||
RuntimeTestsAdapter,
|
||||
>(collator_session_keys(), construct_and_estimate_extrinsic_fee)
|
||||
},
|
||||
@@ -328,12 +311,12 @@ pub fn can_calculate_fee_for_complex_message_delivery_transaction() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn can_calculate_fee_for_complex_message_confirmation_transaction() {
|
||||
pub fn can_calculate_fee_for_standalone_message_confirmation_transaction() {
|
||||
bridge_hub_test_utils::check_sane_fees_values(
|
||||
"bp_bridge_hub_westend::BridgeHubWestendBaseConfirmationFeeInWnds",
|
||||
bp_bridge_hub_westend::BridgeHubWestendBaseConfirmationFeeInWnds::get(),
|
||||
|| {
|
||||
from_parachain::can_calculate_fee_for_complex_message_confirmation_transaction::<
|
||||
from_parachain::can_calculate_fee_for_standalone_message_confirmation_transaction::<
|
||||
RuntimeTestsAdapter,
|
||||
>(collator_session_keys(), construct_and_estimate_extrinsic_fee)
|
||||
},
|
||||
|
||||
+260
-2
@@ -41,6 +41,7 @@ use frame_system::pallet_prelude::BlockNumberFor;
|
||||
use parachains_runtimes_test_utils::{
|
||||
AccountIdOf, BasicParachainRuntime, CollatorSessionKeys, RuntimeCallOf, SlotDurations,
|
||||
};
|
||||
use sp_core::Get;
|
||||
use sp_keyring::AccountKeyring::*;
|
||||
use sp_runtime::{traits::Header as HeaderT, AccountId32};
|
||||
use xcm::latest::prelude::*;
|
||||
@@ -162,7 +163,14 @@ pub fn relayed_incoming_message_works<RuntimeHelper>(
|
||||
test_data::from_grandpa_chain::make_complex_relayer_delivery_proofs::<
|
||||
RuntimeHelper::MB,
|
||||
(),
|
||||
>(lane_id, xcm.into(), message_nonce, message_destination, relay_header_number);
|
||||
>(
|
||||
lane_id,
|
||||
xcm.into(),
|
||||
message_nonce,
|
||||
message_destination,
|
||||
relay_header_number,
|
||||
false,
|
||||
);
|
||||
|
||||
let relay_chain_header_hash = relay_chain_header.hash();
|
||||
vec![
|
||||
@@ -202,6 +210,142 @@ pub fn relayed_incoming_message_works<RuntimeHelper>(
|
||||
);
|
||||
}
|
||||
|
||||
/// Test-case makes sure that Runtime can dispatch XCM messages submitted by relayer,
|
||||
/// with proofs (finality, message) independently submitted.
|
||||
/// Finality proof is submitted for free in this test.
|
||||
/// Also verifies relayer transaction signed extensions work as intended.
|
||||
pub fn free_relay_extrinsic_works<RuntimeHelper>(
|
||||
collator_session_key: CollatorSessionKeys<RuntimeHelper::Runtime>,
|
||||
slot_durations: SlotDurations,
|
||||
runtime_para_id: u32,
|
||||
bridged_chain_id: bp_runtime::ChainId,
|
||||
sibling_parachain_id: u32,
|
||||
local_relay_chain_id: NetworkId,
|
||||
lane_id: LaneId,
|
||||
prepare_configuration: impl Fn(),
|
||||
construct_and_apply_extrinsic: fn(
|
||||
sp_keyring::AccountKeyring,
|
||||
RuntimeCallOf<RuntimeHelper::Runtime>,
|
||||
) -> sp_runtime::DispatchOutcome,
|
||||
) where
|
||||
RuntimeHelper: WithRemoteGrandpaChainHelper,
|
||||
RuntimeHelper::Runtime: pallet_balances::Config,
|
||||
AccountIdOf<RuntimeHelper::Runtime>: From<AccountId32>,
|
||||
RuntimeCallOf<RuntimeHelper::Runtime>: From<BridgeGrandpaCall<RuntimeHelper::Runtime, RuntimeHelper::GPI>>
|
||||
+ From<BridgeMessagesCall<RuntimeHelper::Runtime, RuntimeHelper::MPI>>,
|
||||
UnderlyingChainOf<MessageBridgedChain<RuntimeHelper::MB>>: ChainWithGrandpa,
|
||||
<RuntimeHelper::Runtime as BridgeMessagesConfig<RuntimeHelper::MPI>>::SourceHeaderChain:
|
||||
SourceHeaderChain<
|
||||
MessagesProof = FromBridgedChainMessagesProof<
|
||||
HashOf<MessageBridgedChain<RuntimeHelper::MB>>,
|
||||
>,
|
||||
>,
|
||||
{
|
||||
// ensure that the runtime allows free header submissions
|
||||
let free_headers_interval = <RuntimeHelper::Runtime as BridgeGrandpaConfig<
|
||||
RuntimeHelper::GPI,
|
||||
>>::FreeHeadersInterval::get()
|
||||
.expect("this test requires runtime, configured to accept headers for free; qed");
|
||||
|
||||
helpers::relayed_incoming_message_works::<
|
||||
RuntimeHelper::Runtime,
|
||||
RuntimeHelper::AllPalletsWithoutSystem,
|
||||
RuntimeHelper::MPI,
|
||||
>(
|
||||
collator_session_key,
|
||||
slot_durations,
|
||||
runtime_para_id,
|
||||
sibling_parachain_id,
|
||||
local_relay_chain_id,
|
||||
construct_and_apply_extrinsic,
|
||||
|relayer_id_at_this_chain,
|
||||
relayer_id_at_bridged_chain,
|
||||
message_destination,
|
||||
message_nonce,
|
||||
xcm| {
|
||||
prepare_configuration();
|
||||
|
||||
// start with bridged relay chain block#0
|
||||
let initial_block_number = 0;
|
||||
helpers::initialize_bridge_grandpa_pallet::<RuntimeHelper::Runtime, RuntimeHelper::GPI>(
|
||||
test_data::initialization_data::<RuntimeHelper::Runtime, RuntimeHelper::GPI>(
|
||||
initial_block_number,
|
||||
),
|
||||
);
|
||||
|
||||
// free relay chain header is `0 + free_headers_interval`
|
||||
let relay_header_number = initial_block_number + free_headers_interval;
|
||||
|
||||
// relayer balance shall not change after relay and para header submissions
|
||||
let initial_relayer_balance =
|
||||
pallet_balances::Pallet::<RuntimeHelper::Runtime>::free_balance(
|
||||
relayer_id_at_this_chain.clone(),
|
||||
);
|
||||
|
||||
// initialize the `FreeHeadersRemaining` storage value
|
||||
pallet_bridge_grandpa::Pallet::<RuntimeHelper::Runtime, RuntimeHelper::GPI>::on_initialize(
|
||||
0u32.into(),
|
||||
);
|
||||
|
||||
// generate bridged relay chain finality, parachain heads and message proofs,
|
||||
// to be submitted by relayer to this chain.
|
||||
let (relay_chain_header, grandpa_justification, message_proof) =
|
||||
test_data::from_grandpa_chain::make_complex_relayer_delivery_proofs::<
|
||||
RuntimeHelper::MB,
|
||||
(),
|
||||
>(
|
||||
lane_id,
|
||||
xcm.into(),
|
||||
message_nonce,
|
||||
message_destination,
|
||||
relay_header_number.into(),
|
||||
true,
|
||||
);
|
||||
|
||||
let relay_chain_header_hash = relay_chain_header.hash();
|
||||
vec![
|
||||
(
|
||||
BridgeGrandpaCall::<RuntimeHelper::Runtime, RuntimeHelper::GPI>::submit_finality_proof {
|
||||
finality_target: Box::new(relay_chain_header),
|
||||
justification: grandpa_justification,
|
||||
}.into(),
|
||||
Box::new((
|
||||
helpers::VerifySubmitGrandpaFinalityProofOutcome::<RuntimeHelper::Runtime, RuntimeHelper::GPI>::expect_best_header_hash(
|
||||
relay_chain_header_hash,
|
||||
),
|
||||
helpers::VerifyRelayerBalance::<RuntimeHelper::Runtime>::expect_relayer_balance(
|
||||
relayer_id_at_this_chain.clone(),
|
||||
initial_relayer_balance,
|
||||
),
|
||||
))
|
||||
),
|
||||
(
|
||||
BridgeMessagesCall::<RuntimeHelper::Runtime, RuntimeHelper::MPI>::receive_messages_proof {
|
||||
relayer_id_at_bridged_chain,
|
||||
proof: message_proof,
|
||||
messages_count: 1,
|
||||
dispatch_weight: Weight::from_parts(1000000000, 0),
|
||||
}.into(),
|
||||
Box::new((
|
||||
helpers::VerifySubmitMessagesProofOutcome::<RuntimeHelper::Runtime, RuntimeHelper::MPI>::expect_last_delivered_nonce(
|
||||
lane_id,
|
||||
1,
|
||||
),
|
||||
helpers::VerifyRelayerRewarded::<RuntimeHelper::Runtime>::expect_relayer_reward(
|
||||
relayer_id_at_this_chain,
|
||||
RewardsAccountParams::new(
|
||||
lane_id,
|
||||
bridged_chain_id,
|
||||
RewardsAccountOwner::ThisChain,
|
||||
),
|
||||
),
|
||||
)),
|
||||
),
|
||||
]
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/// Test-case makes sure that Runtime can dispatch XCM messages submitted by relayer,
|
||||
/// with proofs (finality, message) batched together in signed extrinsic.
|
||||
/// Also verifies relayer transaction signed extensions work as intended.
|
||||
@@ -265,7 +409,14 @@ pub fn complex_relay_extrinsic_works<RuntimeHelper>(
|
||||
test_data::from_grandpa_chain::make_complex_relayer_delivery_proofs::<
|
||||
RuntimeHelper::MB,
|
||||
(),
|
||||
>(lane_id, xcm.into(), message_nonce, message_destination, relay_header_number);
|
||||
>(
|
||||
lane_id,
|
||||
xcm.into(),
|
||||
message_nonce,
|
||||
message_destination,
|
||||
relay_header_number,
|
||||
false,
|
||||
);
|
||||
|
||||
let relay_chain_header_hash = relay_chain_header.hash();
|
||||
vec![(
|
||||
@@ -344,6 +495,7 @@ where
|
||||
1,
|
||||
[GlobalConsensus(Polkadot), Parachain(1_000)].into(),
|
||||
1u32.into(),
|
||||
false,
|
||||
);
|
||||
|
||||
// generate batch call that provides finality for bridged relay and parachains + message
|
||||
@@ -423,3 +575,109 @@ where
|
||||
compute_extrinsic_fee(batch)
|
||||
})
|
||||
}
|
||||
|
||||
/// Estimates transaction fee for default message delivery transaction from bridged GRANDPA chain.
|
||||
pub fn can_calculate_fee_for_standalone_message_delivery_transaction<RuntimeHelper>(
|
||||
collator_session_key: CollatorSessionKeys<RuntimeHelper::Runtime>,
|
||||
compute_extrinsic_fee: fn(
|
||||
<RuntimeHelper::Runtime as frame_system::Config>::RuntimeCall,
|
||||
) -> u128,
|
||||
) -> u128
|
||||
where
|
||||
RuntimeHelper: WithRemoteGrandpaChainHelper,
|
||||
RuntimeCallOf<RuntimeHelper::Runtime>:
|
||||
From<BridgeMessagesCall<RuntimeHelper::Runtime, RuntimeHelper::MPI>>,
|
||||
UnderlyingChainOf<MessageBridgedChain<RuntimeHelper::MB>>: ChainWithGrandpa,
|
||||
<RuntimeHelper::Runtime as BridgeMessagesConfig<RuntimeHelper::MPI>>::SourceHeaderChain:
|
||||
SourceHeaderChain<
|
||||
MessagesProof = FromBridgedChainMessagesProof<
|
||||
HashOf<MessageBridgedChain<RuntimeHelper::MB>>,
|
||||
>,
|
||||
>,
|
||||
{
|
||||
run_test::<RuntimeHelper::Runtime, _>(collator_session_key, 1000, vec![], || {
|
||||
// generate bridged relay chain finality, parachain heads and message proofs,
|
||||
// to be submitted by relayer to this chain.
|
||||
//
|
||||
// we don't care about parameter values here, apart from the XCM message size. But we
|
||||
// do not need to have a large message here, because we're charging for every byte of
|
||||
// the message additionally
|
||||
let (_, _, message_proof) =
|
||||
test_data::from_grandpa_chain::make_complex_relayer_delivery_proofs::<
|
||||
RuntimeHelper::MB,
|
||||
(),
|
||||
>(
|
||||
LaneId::default(),
|
||||
vec![Instruction::<()>::ClearOrigin; 1_024].into(),
|
||||
1,
|
||||
[GlobalConsensus(Polkadot), Parachain(1_000)].into(),
|
||||
1u32.into(),
|
||||
false,
|
||||
);
|
||||
|
||||
let call = test_data::from_grandpa_chain::make_standalone_relayer_delivery_call::<
|
||||
RuntimeHelper::Runtime,
|
||||
RuntimeHelper::GPI,
|
||||
RuntimeHelper::MPI,
|
||||
>(
|
||||
message_proof,
|
||||
helpers::relayer_id_at_bridged_chain::<RuntimeHelper::Runtime, RuntimeHelper::MPI>(),
|
||||
);
|
||||
|
||||
compute_extrinsic_fee(call)
|
||||
})
|
||||
}
|
||||
|
||||
/// Estimates transaction fee for default message confirmation transaction (batched with required
|
||||
/// proofs) from bridged parachain.
|
||||
pub fn can_calculate_fee_for_standalone_message_confirmation_transaction<RuntimeHelper>(
|
||||
collator_session_key: CollatorSessionKeys<RuntimeHelper::Runtime>,
|
||||
compute_extrinsic_fee: fn(
|
||||
<RuntimeHelper::Runtime as frame_system::Config>::RuntimeCall,
|
||||
) -> u128,
|
||||
) -> u128
|
||||
where
|
||||
RuntimeHelper: WithRemoteGrandpaChainHelper,
|
||||
AccountIdOf<RuntimeHelper::Runtime>: From<AccountId32>,
|
||||
MessageThisChain<RuntimeHelper::MB>:
|
||||
bp_runtime::Chain<AccountId = AccountIdOf<RuntimeHelper::Runtime>>,
|
||||
RuntimeCallOf<RuntimeHelper::Runtime>:
|
||||
From<BridgeMessagesCall<RuntimeHelper::Runtime, RuntimeHelper::MPI>>,
|
||||
UnderlyingChainOf<MessageBridgedChain<RuntimeHelper::MB>>: ChainWithGrandpa,
|
||||
<RuntimeHelper::Runtime as BridgeMessagesConfig<RuntimeHelper::MPI>>::TargetHeaderChain:
|
||||
TargetHeaderChain<
|
||||
XcmAsPlainPayload,
|
||||
AccountIdOf<RuntimeHelper::Runtime>,
|
||||
MessagesDeliveryProof = FromBridgedChainMessagesDeliveryProof<
|
||||
HashOf<UnderlyingChainOf<MessageBridgedChain<RuntimeHelper::MB>>>,
|
||||
>,
|
||||
>,
|
||||
{
|
||||
run_test::<RuntimeHelper::Runtime, _>(collator_session_key, 1000, vec![], || {
|
||||
// generate bridged relay chain finality, parachain heads and message proofs,
|
||||
// to be submitted by relayer to this chain.
|
||||
let unrewarded_relayers = UnrewardedRelayersState {
|
||||
unrewarded_relayer_entries: 1,
|
||||
total_messages: 1,
|
||||
..Default::default()
|
||||
};
|
||||
let (_, _, message_delivery_proof) =
|
||||
test_data::from_grandpa_chain::make_complex_relayer_confirmation_proofs::<
|
||||
RuntimeHelper::MB,
|
||||
(),
|
||||
>(
|
||||
LaneId::default(),
|
||||
1u32.into(),
|
||||
AccountId32::from(Alice.public()).into(),
|
||||
unrewarded_relayers.clone(),
|
||||
);
|
||||
|
||||
let call = test_data::from_grandpa_chain::make_standalone_relayer_confirmation_call::<
|
||||
RuntimeHelper::Runtime,
|
||||
RuntimeHelper::GPI,
|
||||
RuntimeHelper::MPI,
|
||||
>(message_delivery_proof, unrewarded_relayers);
|
||||
|
||||
compute_extrinsic_fee(call)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -42,6 +42,7 @@ use frame_system::pallet_prelude::BlockNumberFor;
|
||||
use parachains_runtimes_test_utils::{
|
||||
AccountIdOf, BasicParachainRuntime, CollatorSessionKeys, RuntimeCallOf, SlotDurations,
|
||||
};
|
||||
use sp_core::Get;
|
||||
use sp_keyring::AccountKeyring::*;
|
||||
use sp_runtime::{traits::Header as HeaderT, AccountId32};
|
||||
use xcm::latest::prelude::*;
|
||||
@@ -188,6 +189,7 @@ pub fn relayed_incoming_message_works<RuntimeHelper>(
|
||||
para_header_number,
|
||||
relay_header_number,
|
||||
bridged_para_id,
|
||||
false,
|
||||
);
|
||||
|
||||
let parachain_head_hash = parachain_head.hash();
|
||||
@@ -241,6 +243,177 @@ pub fn relayed_incoming_message_works<RuntimeHelper>(
|
||||
);
|
||||
}
|
||||
|
||||
/// Test-case makes sure that Runtime can dispatch XCM messages submitted by relayer,
|
||||
/// with proofs (finality, para heads, message) independently submitted.
|
||||
/// Finality and para heads are submitted for free in this test.
|
||||
/// Also verifies relayer transaction signed extensions work as intended.
|
||||
pub fn free_relay_extrinsic_works<RuntimeHelper>(
|
||||
collator_session_key: CollatorSessionKeys<RuntimeHelper::Runtime>,
|
||||
slot_durations: SlotDurations,
|
||||
runtime_para_id: u32,
|
||||
bridged_para_id: u32,
|
||||
bridged_chain_id: bp_runtime::ChainId,
|
||||
sibling_parachain_id: u32,
|
||||
local_relay_chain_id: NetworkId,
|
||||
lane_id: LaneId,
|
||||
prepare_configuration: impl Fn(),
|
||||
construct_and_apply_extrinsic: fn(
|
||||
sp_keyring::AccountKeyring,
|
||||
<RuntimeHelper::Runtime as frame_system::Config>::RuntimeCall,
|
||||
) -> sp_runtime::DispatchOutcome,
|
||||
) where
|
||||
RuntimeHelper: WithRemoteParachainHelper,
|
||||
RuntimeHelper::Runtime: pallet_balances::Config,
|
||||
AccountIdOf<RuntimeHelper::Runtime>: From<AccountId32>,
|
||||
RuntimeCallOf<RuntimeHelper::Runtime>: From<BridgeGrandpaCall<RuntimeHelper::Runtime, RuntimeHelper::GPI>>
|
||||
+ From<BridgeParachainsCall<RuntimeHelper::Runtime, RuntimeHelper::PPI>>
|
||||
+ From<BridgeMessagesCall<RuntimeHelper::Runtime, RuntimeHelper::MPI>>,
|
||||
UnderlyingChainOf<MessageBridgedChain<RuntimeHelper::MB>>:
|
||||
bp_runtime::Chain<Hash = ParaHash> + Parachain,
|
||||
<RuntimeHelper::Runtime as BridgeGrandpaConfig<RuntimeHelper::GPI>>::BridgedChain:
|
||||
bp_runtime::Chain<Hash = RelayBlockHash, BlockNumber = RelayBlockNumber> + ChainWithGrandpa,
|
||||
<RuntimeHelper::Runtime as BridgeMessagesConfig<RuntimeHelper::MPI>>::SourceHeaderChain:
|
||||
SourceHeaderChain<
|
||||
MessagesProof = FromBridgedChainMessagesProof<
|
||||
HashOf<MessageBridgedChain<RuntimeHelper::MB>>,
|
||||
>,
|
||||
>,
|
||||
{
|
||||
// ensure that the runtime allows free header submissions
|
||||
let free_headers_interval = <RuntimeHelper::Runtime as BridgeGrandpaConfig<
|
||||
RuntimeHelper::GPI,
|
||||
>>::FreeHeadersInterval::get()
|
||||
.expect("this test requires runtime, configured to accept headers for free; qed");
|
||||
|
||||
helpers::relayed_incoming_message_works::<
|
||||
RuntimeHelper::Runtime,
|
||||
RuntimeHelper::AllPalletsWithoutSystem,
|
||||
RuntimeHelper::MPI,
|
||||
>(
|
||||
collator_session_key,
|
||||
slot_durations,
|
||||
runtime_para_id,
|
||||
sibling_parachain_id,
|
||||
local_relay_chain_id,
|
||||
construct_and_apply_extrinsic,
|
||||
|relayer_id_at_this_chain,
|
||||
relayer_id_at_bridged_chain,
|
||||
message_destination,
|
||||
message_nonce,
|
||||
xcm| {
|
||||
prepare_configuration();
|
||||
|
||||
// start with bridged relay chain block#0
|
||||
let initial_block_number = 0;
|
||||
helpers::initialize_bridge_grandpa_pallet::<RuntimeHelper::Runtime, RuntimeHelper::GPI>(
|
||||
test_data::initialization_data::<RuntimeHelper::Runtime, RuntimeHelper::GPI>(
|
||||
initial_block_number,
|
||||
),
|
||||
);
|
||||
|
||||
// free relay chain header is `0 + free_headers_interval`
|
||||
let relay_header_number = initial_block_number + free_headers_interval;
|
||||
// first parachain header is always submitted for free
|
||||
let para_header_number = 1;
|
||||
|
||||
// relayer balance shall not change after relay and para header submissions
|
||||
let initial_relayer_balance =
|
||||
pallet_balances::Pallet::<RuntimeHelper::Runtime>::free_balance(
|
||||
relayer_id_at_this_chain.clone(),
|
||||
);
|
||||
|
||||
// initialize the `FreeHeadersRemaining` storage value
|
||||
pallet_bridge_grandpa::Pallet::<RuntimeHelper::Runtime, RuntimeHelper::GPI>::on_initialize(
|
||||
0u32.into(),
|
||||
);
|
||||
|
||||
// generate bridged relay chain finality, parachain heads and message proofs,
|
||||
// to be submitted by relayer to this chain.
|
||||
let (
|
||||
relay_chain_header,
|
||||
grandpa_justification,
|
||||
parachain_head,
|
||||
parachain_heads,
|
||||
para_heads_proof,
|
||||
message_proof,
|
||||
) = test_data::from_parachain::make_complex_relayer_delivery_proofs::<
|
||||
<RuntimeHelper::Runtime as BridgeGrandpaConfig<RuntimeHelper::GPI>>::BridgedChain,
|
||||
RuntimeHelper::MB,
|
||||
(),
|
||||
>(
|
||||
lane_id,
|
||||
xcm.into(),
|
||||
message_nonce,
|
||||
message_destination,
|
||||
para_header_number,
|
||||
relay_header_number,
|
||||
bridged_para_id,
|
||||
true,
|
||||
);
|
||||
|
||||
let parachain_head_hash = parachain_head.hash();
|
||||
let relay_chain_header_hash = relay_chain_header.hash();
|
||||
let relay_chain_header_number = *relay_chain_header.number();
|
||||
vec![
|
||||
(
|
||||
BridgeGrandpaCall::<RuntimeHelper::Runtime, RuntimeHelper::GPI>::submit_finality_proof {
|
||||
finality_target: Box::new(relay_chain_header),
|
||||
justification: grandpa_justification,
|
||||
}.into(),
|
||||
Box::new((
|
||||
helpers::VerifySubmitGrandpaFinalityProofOutcome::<RuntimeHelper::Runtime, RuntimeHelper::GPI>::expect_best_header_hash(
|
||||
relay_chain_header_hash,
|
||||
),
|
||||
helpers::VerifyRelayerBalance::<RuntimeHelper::Runtime>::expect_relayer_balance(
|
||||
relayer_id_at_this_chain.clone(),
|
||||
initial_relayer_balance,
|
||||
),
|
||||
)),
|
||||
),
|
||||
(
|
||||
BridgeParachainsCall::<RuntimeHelper::Runtime, RuntimeHelper::PPI>::submit_parachain_heads {
|
||||
at_relay_block: (relay_chain_header_number, relay_chain_header_hash),
|
||||
parachains: parachain_heads,
|
||||
parachain_heads_proof: para_heads_proof,
|
||||
}.into(),
|
||||
Box::new((
|
||||
helpers::VerifySubmitParachainHeaderProofOutcome::<RuntimeHelper::Runtime, RuntimeHelper::PPI>::expect_best_header_hash(
|
||||
bridged_para_id,
|
||||
parachain_head_hash,
|
||||
),
|
||||
/*helpers::VerifyRelayerBalance::<RuntimeHelper::Runtime>::expect_relayer_balance(
|
||||
relayer_id_at_this_chain.clone(),
|
||||
initial_relayer_balance,
|
||||
),*/
|
||||
)),
|
||||
),
|
||||
(
|
||||
BridgeMessagesCall::<RuntimeHelper::Runtime, RuntimeHelper::MPI>::receive_messages_proof {
|
||||
relayer_id_at_bridged_chain,
|
||||
proof: message_proof,
|
||||
messages_count: 1,
|
||||
dispatch_weight: Weight::from_parts(1000000000, 0),
|
||||
}.into(),
|
||||
Box::new((
|
||||
helpers::VerifySubmitMessagesProofOutcome::<RuntimeHelper::Runtime, RuntimeHelper::MPI>::expect_last_delivered_nonce(
|
||||
lane_id,
|
||||
1,
|
||||
),
|
||||
helpers::VerifyRelayerRewarded::<RuntimeHelper::Runtime>::expect_relayer_reward(
|
||||
relayer_id_at_this_chain,
|
||||
RewardsAccountParams::new(
|
||||
lane_id,
|
||||
bridged_chain_id,
|
||||
RewardsAccountOwner::ThisChain,
|
||||
),
|
||||
),
|
||||
)),
|
||||
),
|
||||
]
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/// Test-case makes sure that Runtime can dispatch XCM messages submitted by relayer,
|
||||
/// with proofs (finality, para heads, message) batched together in signed extrinsic.
|
||||
/// Also verifies relayer transaction signed extensions work as intended.
|
||||
@@ -325,6 +498,7 @@ pub fn complex_relay_extrinsic_works<RuntimeHelper>(
|
||||
para_header_number,
|
||||
relay_header_number,
|
||||
bridged_para_id,
|
||||
false,
|
||||
);
|
||||
|
||||
let parachain_head_hash = parachain_head.hash();
|
||||
@@ -428,6 +602,7 @@ where
|
||||
1,
|
||||
5,
|
||||
1_000,
|
||||
false,
|
||||
);
|
||||
|
||||
// generate batch call that provides finality for bridged relay and parachains + message
|
||||
@@ -527,3 +702,126 @@ where
|
||||
compute_extrinsic_fee(batch)
|
||||
})
|
||||
}
|
||||
|
||||
/// Estimates transaction fee for default message delivery transaction from bridged parachain.
|
||||
pub fn can_calculate_fee_for_standalone_message_delivery_transaction<RuntimeHelper>(
|
||||
collator_session_key: CollatorSessionKeys<RuntimeHelper::Runtime>,
|
||||
compute_extrinsic_fee: fn(
|
||||
<RuntimeHelper::Runtime as frame_system::Config>::RuntimeCall,
|
||||
) -> u128,
|
||||
) -> u128
|
||||
where
|
||||
RuntimeHelper: WithRemoteParachainHelper,
|
||||
RuntimeCallOf<RuntimeHelper::Runtime>:
|
||||
From<BridgeMessagesCall<RuntimeHelper::Runtime, RuntimeHelper::MPI>>,
|
||||
UnderlyingChainOf<MessageBridgedChain<RuntimeHelper::MB>>:
|
||||
bp_runtime::Chain<Hash = ParaHash> + Parachain,
|
||||
<RuntimeHelper::Runtime as BridgeGrandpaConfig<RuntimeHelper::GPI>>::BridgedChain:
|
||||
bp_runtime::Chain<Hash = RelayBlockHash, BlockNumber = RelayBlockNumber> + ChainWithGrandpa,
|
||||
<RuntimeHelper::Runtime as BridgeMessagesConfig<RuntimeHelper::MPI>>::SourceHeaderChain:
|
||||
SourceHeaderChain<
|
||||
MessagesProof = FromBridgedChainMessagesProof<
|
||||
HashOf<MessageBridgedChain<RuntimeHelper::MB>>,
|
||||
>,
|
||||
>,
|
||||
{
|
||||
run_test::<RuntimeHelper::Runtime, _>(collator_session_key, 1000, vec![], || {
|
||||
// generate bridged relay chain finality, parachain heads and message proofs,
|
||||
// to be submitted by relayer to this chain.
|
||||
//
|
||||
// we don't care about parameter values here, apart from the XCM message size. But we
|
||||
// do not need to have a large message here, because we're charging for every byte of
|
||||
// the message additionally
|
||||
let (
|
||||
_,
|
||||
_,
|
||||
_,
|
||||
_,
|
||||
_,
|
||||
message_proof,
|
||||
) = test_data::from_parachain::make_complex_relayer_delivery_proofs::<
|
||||
<RuntimeHelper::Runtime as pallet_bridge_grandpa::Config<RuntimeHelper::GPI>>::BridgedChain,
|
||||
RuntimeHelper::MB,
|
||||
(),
|
||||
>(
|
||||
LaneId::default(),
|
||||
vec![Instruction::<()>::ClearOrigin; 1_024].into(),
|
||||
1,
|
||||
[GlobalConsensus(Polkadot), Parachain(1_000)].into(),
|
||||
1,
|
||||
5,
|
||||
1_000,
|
||||
false,
|
||||
);
|
||||
|
||||
let call = test_data::from_parachain::make_standalone_relayer_delivery_call::<
|
||||
RuntimeHelper::Runtime,
|
||||
RuntimeHelper::MPI,
|
||||
_,
|
||||
>(
|
||||
message_proof,
|
||||
helpers::relayer_id_at_bridged_chain::<RuntimeHelper::Runtime, RuntimeHelper::MPI>(),
|
||||
);
|
||||
|
||||
compute_extrinsic_fee(call)
|
||||
})
|
||||
}
|
||||
|
||||
/// Estimates transaction fee for default message confirmation transaction (batched with required
|
||||
/// proofs) from bridged parachain.
|
||||
pub fn can_calculate_fee_for_standalone_message_confirmation_transaction<RuntimeHelper>(
|
||||
collator_session_key: CollatorSessionKeys<RuntimeHelper::Runtime>,
|
||||
compute_extrinsic_fee: fn(
|
||||
<RuntimeHelper::Runtime as frame_system::Config>::RuntimeCall,
|
||||
) -> u128,
|
||||
) -> u128
|
||||
where
|
||||
RuntimeHelper: WithRemoteParachainHelper,
|
||||
AccountIdOf<RuntimeHelper::Runtime>: From<AccountId32>,
|
||||
MessageThisChain<RuntimeHelper::MB>:
|
||||
bp_runtime::Chain<AccountId = AccountIdOf<RuntimeHelper::Runtime>>,
|
||||
RuntimeCallOf<RuntimeHelper::Runtime>:
|
||||
From<BridgeMessagesCall<RuntimeHelper::Runtime, RuntimeHelper::MPI>>,
|
||||
UnderlyingChainOf<MessageBridgedChain<RuntimeHelper::MB>>:
|
||||
bp_runtime::Chain<Hash = ParaHash> + Parachain,
|
||||
<RuntimeHelper::Runtime as BridgeGrandpaConfig<RuntimeHelper::GPI>>::BridgedChain:
|
||||
bp_runtime::Chain<Hash = RelayBlockHash, BlockNumber = RelayBlockNumber> + ChainWithGrandpa,
|
||||
<RuntimeHelper::Runtime as BridgeMessagesConfig<RuntimeHelper::MPI>>::TargetHeaderChain:
|
||||
TargetHeaderChain<
|
||||
XcmAsPlainPayload,
|
||||
AccountIdOf<RuntimeHelper::Runtime>,
|
||||
MessagesDeliveryProof = FromBridgedChainMessagesDeliveryProof<
|
||||
HashOf<UnderlyingChainOf<MessageBridgedChain<RuntimeHelper::MB>>>,
|
||||
>,
|
||||
>,
|
||||
{
|
||||
run_test::<RuntimeHelper::Runtime, _>(collator_session_key, 1000, vec![], || {
|
||||
// generate bridged relay chain finality, parachain heads and message proofs,
|
||||
// to be submitted by relayer to this chain.
|
||||
let unrewarded_relayers = UnrewardedRelayersState {
|
||||
unrewarded_relayer_entries: 1,
|
||||
total_messages: 1,
|
||||
..Default::default()
|
||||
};
|
||||
let (_, _, _, _, _, message_delivery_proof) =
|
||||
test_data::from_parachain::make_complex_relayer_confirmation_proofs::<
|
||||
<RuntimeHelper::Runtime as BridgeGrandpaConfig<RuntimeHelper::GPI>>::BridgedChain,
|
||||
RuntimeHelper::MB,
|
||||
(),
|
||||
>(
|
||||
LaneId::default(),
|
||||
1,
|
||||
5,
|
||||
1_000,
|
||||
AccountId32::from(Alice.public()).into(),
|
||||
unrewarded_relayers.clone(),
|
||||
);
|
||||
|
||||
let call = test_data::from_parachain::make_standalone_relayer_confirmation_call::<
|
||||
RuntimeHelper::Runtime,
|
||||
RuntimeHelper::MPI,
|
||||
>(message_delivery_proof, unrewarded_relayers);
|
||||
|
||||
compute_extrinsic_fee(call)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -193,6 +193,34 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
/// Verifies that relayer balance is equal to given value.
|
||||
pub struct VerifyRelayerBalance<Runtime: pallet_balances::Config> {
|
||||
relayer: Runtime::AccountId,
|
||||
balance: Runtime::Balance,
|
||||
}
|
||||
|
||||
impl<Runtime> VerifyRelayerBalance<Runtime>
|
||||
where
|
||||
Runtime: pallet_balances::Config,
|
||||
{
|
||||
/// Expect given relayer balance after transaction.
|
||||
pub fn expect_relayer_balance(
|
||||
relayer: Runtime::AccountId,
|
||||
balance: Runtime::Balance,
|
||||
) -> Box<dyn VerifyTransactionOutcome> {
|
||||
Box::new(Self { relayer, balance })
|
||||
}
|
||||
}
|
||||
|
||||
impl<Runtime> VerifyTransactionOutcome for VerifyRelayerBalance<Runtime>
|
||||
where
|
||||
Runtime: pallet_balances::Config,
|
||||
{
|
||||
fn verify_outcome(&self) {
|
||||
assert_eq!(pallet_balances::Pallet::<Runtime>::free_balance(&self.relayer), self.balance,);
|
||||
}
|
||||
}
|
||||
|
||||
/// Initialize bridge GRANDPA pallet.
|
||||
pub(crate) fn initialize_bridge_grandpa_pallet<Runtime, GPI>(
|
||||
init_data: bp_header_chain::InitializationData<BridgedHeader<Runtime, GPI>>,
|
||||
|
||||
+65
-4
@@ -121,6 +121,60 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
/// Prepare a call with message proof.
|
||||
pub fn make_standalone_relayer_delivery_call<Runtime, GPI, MPI>(
|
||||
message_proof: FromBridgedChainMessagesProof<HashOf<BridgedChain<Runtime, GPI>>>,
|
||||
relayer_id_at_bridged_chain: AccountIdOf<BridgedChain<Runtime, GPI>>,
|
||||
) -> Runtime::RuntimeCall
|
||||
where
|
||||
Runtime: pallet_bridge_grandpa::Config<GPI>
|
||||
+ pallet_bridge_messages::Config<
|
||||
MPI,
|
||||
InboundPayload = XcmAsPlainPayload,
|
||||
InboundRelayer = AccountIdOf<BridgedChain<Runtime, GPI>>,
|
||||
>,
|
||||
MPI: 'static,
|
||||
<Runtime as pallet_bridge_messages::Config<MPI>>::SourceHeaderChain: SourceHeaderChain<
|
||||
MessagesProof = FromBridgedChainMessagesProof<HashOf<BridgedChain<Runtime, GPI>>>,
|
||||
>,
|
||||
Runtime::RuntimeCall: From<pallet_bridge_messages::Call<Runtime, MPI>>,
|
||||
{
|
||||
pallet_bridge_messages::Call::<Runtime, MPI>::receive_messages_proof {
|
||||
relayer_id_at_bridged_chain,
|
||||
proof: message_proof,
|
||||
messages_count: 1,
|
||||
dispatch_weight: Weight::from_parts(1000000000, 0),
|
||||
}
|
||||
.into()
|
||||
}
|
||||
|
||||
/// Prepare a call with message delivery proof.
|
||||
pub fn make_standalone_relayer_confirmation_call<Runtime, GPI, MPI>(
|
||||
message_delivery_proof: FromBridgedChainMessagesDeliveryProof<
|
||||
HashOf<BridgedChain<Runtime, GPI>>,
|
||||
>,
|
||||
relayers_state: UnrewardedRelayersState,
|
||||
) -> Runtime::RuntimeCall
|
||||
where
|
||||
Runtime: pallet_bridge_grandpa::Config<GPI>
|
||||
+ pallet_bridge_messages::Config<MPI, OutboundPayload = XcmAsPlainPayload>,
|
||||
MPI: 'static,
|
||||
<Runtime as pallet_bridge_messages::Config<MPI>>::TargetHeaderChain: TargetHeaderChain<
|
||||
XcmAsPlainPayload,
|
||||
Runtime::AccountId,
|
||||
MessagesDeliveryProof = FromBridgedChainMessagesDeliveryProof<
|
||||
HashOf<BridgedChain<Runtime, GPI>>,
|
||||
>,
|
||||
>,
|
||||
Runtime::RuntimeCall: From<pallet_bridge_messages::Call<Runtime, MPI>>,
|
||||
{
|
||||
pallet_bridge_messages::Call::<Runtime, MPI>::receive_messages_delivery_proof {
|
||||
proof: message_delivery_proof,
|
||||
relayers_state,
|
||||
}
|
||||
.into()
|
||||
}
|
||||
|
||||
/// Prepare storage proofs of messages, stored at the (bridged) source GRANDPA chain.
|
||||
pub fn make_complex_relayer_delivery_proofs<MB, InnerXcmRuntimeCall>(
|
||||
lane_id: LaneId,
|
||||
@@ -128,6 +182,7 @@ pub fn make_complex_relayer_delivery_proofs<MB, InnerXcmRuntimeCall>(
|
||||
message_nonce: MessageNonce,
|
||||
message_destination: Junctions,
|
||||
header_number: BlockNumberOf<MessageBridgedChain<MB>>,
|
||||
is_minimal_call: bool,
|
||||
) -> (
|
||||
HeaderOf<MessageBridgedChain<MB>>,
|
||||
GrandpaJustification<HeaderOf<MessageBridgedChain<MB>>>,
|
||||
@@ -153,7 +208,7 @@ where
|
||||
|
||||
let (header, justification) = make_complex_bridged_grandpa_header_proof::<
|
||||
MessageBridgedChain<MB>,
|
||||
>(state_root, header_number);
|
||||
>(state_root, header_number, is_minimal_call);
|
||||
|
||||
let message_proof = FromBridgedChainMessagesProof {
|
||||
bridged_header_hash: header.hash(),
|
||||
@@ -200,8 +255,11 @@ where
|
||||
StorageProofSize::Minimal(0),
|
||||
);
|
||||
|
||||
let (header, justification) =
|
||||
make_complex_bridged_grandpa_header_proof::<MB::BridgedChain>(state_root, header_number);
|
||||
let (header, justification) = make_complex_bridged_grandpa_header_proof::<MB::BridgedChain>(
|
||||
state_root,
|
||||
header_number,
|
||||
false,
|
||||
);
|
||||
|
||||
let message_delivery_proof = FromBridgedChainMessagesDeliveryProof {
|
||||
bridged_header_hash: header.hash(),
|
||||
@@ -216,6 +274,7 @@ where
|
||||
pub fn make_complex_bridged_grandpa_header_proof<BridgedChain>(
|
||||
state_root: HashOf<BridgedChain>,
|
||||
header_number: BlockNumberOf<BridgedChain>,
|
||||
is_minimal_call: bool,
|
||||
) -> (HeaderOf<BridgedChain>, GrandpaJustification<HeaderOf<BridgedChain>>)
|
||||
where
|
||||
BridgedChain: ChainWithGrandpa,
|
||||
@@ -229,7 +288,9 @@ where
|
||||
// `submit_finality_proof` call size would be close to maximal expected (and refundable)
|
||||
let extra_bytes_required = maximal_expected_submit_finality_proof_call_size::<BridgedChain>()
|
||||
.saturating_sub(header.encoded_size());
|
||||
header.digest_mut().push(DigestItem::Other(vec![42; extra_bytes_required]));
|
||||
if !is_minimal_call {
|
||||
header.digest_mut().push(DigestItem::Other(vec![42; extra_bytes_required]));
|
||||
}
|
||||
|
||||
let justification = make_default_justification(&header);
|
||||
(header, justification)
|
||||
|
||||
@@ -159,6 +159,52 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
/// Prepare a call with message proof.
|
||||
pub fn make_standalone_relayer_delivery_call<Runtime, MPI, InboundRelayer>(
|
||||
message_proof: FromBridgedChainMessagesProof<ParaHash>,
|
||||
relayer_id_at_bridged_chain: InboundRelayer,
|
||||
) -> Runtime::RuntimeCall where
|
||||
Runtime: pallet_bridge_messages::Config<
|
||||
MPI,
|
||||
InboundPayload = XcmAsPlainPayload,
|
||||
InboundRelayer = InboundRelayer,
|
||||
>,
|
||||
MPI: 'static,
|
||||
Runtime::RuntimeCall: From<pallet_bridge_messages::Call::<Runtime, MPI>>,
|
||||
<<Runtime as pallet_bridge_messages::Config<MPI>>::SourceHeaderChain as SourceHeaderChain>::MessagesProof:
|
||||
From<FromBridgedChainMessagesProof<ParaHash>>,
|
||||
{
|
||||
pallet_bridge_messages::Call::<Runtime, MPI>::receive_messages_proof {
|
||||
relayer_id_at_bridged_chain: relayer_id_at_bridged_chain.into(),
|
||||
proof: message_proof.into(),
|
||||
messages_count: 1,
|
||||
dispatch_weight: Weight::from_parts(1000000000, 0),
|
||||
}
|
||||
.into()
|
||||
}
|
||||
|
||||
/// Prepare a call with message delivery proof.
|
||||
pub fn make_standalone_relayer_confirmation_call<Runtime, MPI>(
|
||||
message_delivery_proof: FromBridgedChainMessagesDeliveryProof<ParaHash>,
|
||||
relayers_state: UnrewardedRelayersState,
|
||||
) -> Runtime::RuntimeCall
|
||||
where
|
||||
Runtime: pallet_bridge_messages::Config<MPI, OutboundPayload = XcmAsPlainPayload>,
|
||||
MPI: 'static,
|
||||
Runtime::RuntimeCall: From<pallet_bridge_messages::Call<Runtime, MPI>>,
|
||||
<Runtime as pallet_bridge_messages::Config<MPI>>::TargetHeaderChain: TargetHeaderChain<
|
||||
XcmAsPlainPayload,
|
||||
Runtime::AccountId,
|
||||
MessagesDeliveryProof = FromBridgedChainMessagesDeliveryProof<ParaHash>,
|
||||
>,
|
||||
{
|
||||
pallet_bridge_messages::Call::<Runtime, MPI>::receive_messages_delivery_proof {
|
||||
proof: message_delivery_proof,
|
||||
relayers_state,
|
||||
}
|
||||
.into()
|
||||
}
|
||||
|
||||
/// Prepare storage proofs of messages, stored at the source chain.
|
||||
pub fn make_complex_relayer_delivery_proofs<BridgedRelayChain, MB, InnerXcmRuntimeCall>(
|
||||
lane_id: LaneId,
|
||||
@@ -168,6 +214,7 @@ pub fn make_complex_relayer_delivery_proofs<BridgedRelayChain, MB, InnerXcmRunti
|
||||
para_header_number: u32,
|
||||
relay_header_number: u32,
|
||||
bridged_para_id: u32,
|
||||
is_minimal_call: bool,
|
||||
) -> (
|
||||
HeaderOf<BridgedRelayChain>,
|
||||
GrandpaJustification<HeaderOf<BridgedRelayChain>>,
|
||||
@@ -201,6 +248,7 @@ where
|
||||
para_header_number,
|
||||
relay_header_number,
|
||||
bridged_para_id,
|
||||
is_minimal_call,
|
||||
);
|
||||
|
||||
let message_proof = FromBridgedChainMessagesProof {
|
||||
@@ -266,6 +314,7 @@ where
|
||||
para_header_number,
|
||||
relay_header_number,
|
||||
bridged_para_id,
|
||||
false,
|
||||
);
|
||||
|
||||
let message_delivery_proof = FromBridgedChainMessagesDeliveryProof {
|
||||
@@ -290,6 +339,7 @@ pub fn make_complex_bridged_parachain_heads_proof<BridgedRelayChain, MB>(
|
||||
para_header_number: u32,
|
||||
relay_header_number: BlockNumberOf<BridgedRelayChain>,
|
||||
bridged_para_id: u32,
|
||||
is_minimal_call: bool,
|
||||
) -> (
|
||||
HeaderOf<BridgedRelayChain>,
|
||||
GrandpaJustification<HeaderOf<BridgedRelayChain>>,
|
||||
@@ -319,9 +369,12 @@ where
|
||||
)]);
|
||||
assert_eq!(bridged_para_head.hash(), parachain_heads[0].1);
|
||||
|
||||
let (relay_chain_header, justification) = make_complex_bridged_grandpa_header_proof::<
|
||||
BridgedRelayChain,
|
||||
>(relay_state_root, relay_header_number);
|
||||
let (relay_chain_header, justification) =
|
||||
make_complex_bridged_grandpa_header_proof::<BridgedRelayChain>(
|
||||
relay_state_root,
|
||||
relay_header_number,
|
||||
is_minimal_call,
|
||||
);
|
||||
|
||||
(relay_chain_header, justification, bridged_para_head, parachain_heads, para_heads_proof)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user