Newer
Older
Branislav Kontur
committed
// Copyright (C) Parity Technologies (UK) Ltd.
// This file is part of Cumulus.
// Cumulus is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Cumulus is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Cumulus. If not, see <http://www.gnu.org/licenses/>.
#![cfg(test)]
use bp_polkadot_core::Signature;
use bridge_common_config::{DeliveryRewardInBalance, RequiredStakeForStakeAndSlash};
use bridge_hub_westend_runtime::{
bridge_common_config, bridge_to_rococo_config,
xcm_config::{RelayNetwork, WestendLocation, XcmConfig},
AllPalletsWithoutSystem, BridgeRejectObsoleteHeadersAndMessages, Executive, ExistentialDeposit,
ParachainSystem, PolkadotXcm, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, SessionKeys,
SignedExtra, TransactionPayment, UncheckedExtrinsic,
Branislav Kontur
committed
};
use bridge_to_rococo_config::{
BridgeGrandpaRococoInstance, BridgeHubRococoChainId, BridgeHubRococoLocation,
BridgeParachainRococoInstance, WithBridgeHubRococoMessageBridge,
WithBridgeHubRococoMessagesInstance, XCM_LANE_FOR_ASSET_HUB_WESTEND_TO_ASSET_HUB_ROCOCO,
Branislav Kontur
committed
};
use codec::{Decode, Encode};
use frame_support::{dispatch::GetDispatchInfo, parameter_types, traits::ConstU8};
Branislav Kontur
committed
use parachains_common::{westend::fee::WeightToFee, AccountId, AuraId, Balance};
use sp_keyring::AccountKeyring::Alice;
use sp_runtime::{
generic::{Era, SignedPayload},
AccountId32,
};
use xcm::latest::prelude::*;
// Para id of sibling chain used in tests.
pub const SIBLING_PARACHAIN_ID: u32 = 1000;
parameter_types! {
pub CheckingAccount: AccountId = PolkadotXcm::check_account();
}
fn construct_extrinsic(
sender: sp_keyring::AccountKeyring,
call: RuntimeCall,
) -> UncheckedExtrinsic {
let account_id = AccountId32::from(sender.public());
Branislav Kontur
committed
let extra: SignedExtra = (
frame_system::CheckNonZeroSender::<Runtime>::new(),
frame_system::CheckSpecVersion::<Runtime>::new(),
frame_system::CheckTxVersion::<Runtime>::new(),
frame_system::CheckGenesis::<Runtime>::new(),
frame_system::CheckEra::<Runtime>::from(Era::immortal()),
frame_system::CheckNonce::<Runtime>::from(
frame_system::Pallet::<Runtime>::account(&account_id).nonce,
),
Branislav Kontur
committed
frame_system::CheckWeight::<Runtime>::new(),
pallet_transaction_payment::ChargeTransactionPayment::<Runtime>::from(0),
BridgeRejectObsoleteHeadersAndMessages::default(),
(bridge_to_rococo_config::OnBridgeHubWestendRefundBridgeHubRococoMessages::default(),),
);
let payload = SignedPayload::new(call.clone(), extra.clone()).unwrap();
let signature = payload.using_encoded(|e| sender.sign(e));
UncheckedExtrinsic::new_signed(
call,
account_id.into(),
Branislav Kontur
committed
Signature::Sr25519(signature.clone()),
extra,
)
}
fn construct_and_apply_extrinsic(
relayer_at_target: sp_keyring::AccountKeyring,
call: RuntimeCall,
Branislav Kontur
committed
) -> sp_runtime::DispatchOutcome {
let xt = construct_extrinsic(relayer_at_target, call);
Branislav Kontur
committed
let r = Executive::apply_extrinsic(xt);
r.unwrap()
}
![Svyatoslav Nikolsky Svyatoslav Nikolsky's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Svyatoslav Nikolsky
committed
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)
}
Branislav Kontur
committed
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
fn collator_session_keys() -> bridge_hub_test_utils::CollatorSessionKeys<Runtime> {
bridge_hub_test_utils::CollatorSessionKeys::new(
AccountId::from(Alice),
AccountId::from(Alice),
SessionKeys { aura: AuraId::from(Alice.public()) },
)
}
bridge_hub_test_utils::test_cases::include_teleports_for_native_asset_works!(
Runtime,
AllPalletsWithoutSystem,
XcmConfig,
CheckingAccount,
WeightToFee,
ParachainSystem,
collator_session_keys(),
ExistentialDeposit::get(),
Box::new(|runtime_event_encoded: Vec<u8>| {
match RuntimeEvent::decode(&mut &runtime_event_encoded[..]) {
Ok(RuntimeEvent::PolkadotXcm(event)) => Some(event),
_ => None,
}
}),
bp_bridge_hub_westend::BRIDGE_HUB_WESTEND_PARACHAIN_ID
);
#[test]
fn initialize_bridge_by_governance_works() {
bridge_hub_test_utils::test_cases::initialize_bridge_by_governance_works::<
Runtime,
BridgeGrandpaRococoInstance,
>(
collator_session_keys(),
bp_bridge_hub_westend::BRIDGE_HUB_WESTEND_PARACHAIN_ID,
Box::new(|call| RuntimeCall::BridgeRococoGrandpa(call).encode()),
)
}
#[test]
fn change_delivery_reward_by_governance_works() {
bridge_hub_test_utils::test_cases::change_storage_constant_by_governance_works::<
Runtime,
DeliveryRewardInBalance,
u64,
>(
collator_session_keys(),
bp_bridge_hub_westend::BRIDGE_HUB_WESTEND_PARACHAIN_ID,
Box::new(|call| RuntimeCall::System(call).encode()),
|| (DeliveryRewardInBalance::key().to_vec(), DeliveryRewardInBalance::get()),
|old_value| old_value.checked_mul(2).unwrap(),
)
}
#[test]
fn change_required_stake_by_governance_works() {
bridge_hub_test_utils::test_cases::change_storage_constant_by_governance_works::<
Runtime,
RequiredStakeForStakeAndSlash,
Balance,
>(
collator_session_keys(),
bp_bridge_hub_westend::BRIDGE_HUB_WESTEND_PARACHAIN_ID,
Box::new(|call| RuntimeCall::System(call).encode()),
|| (RequiredStakeForStakeAndSlash::key().to_vec(), RequiredStakeForStakeAndSlash::get()),
|old_value| old_value.checked_mul(2).unwrap(),
)
}
#[test]
fn handle_export_message_from_system_parachain_add_to_outbound_queue_works() {
bridge_hub_test_utils::test_cases::handle_export_message_from_system_parachain_to_outbound_queue_works::<
Runtime,
XcmConfig,
WithBridgeHubRococoMessagesInstance,
>(
collator_session_keys(),
bp_bridge_hub_westend::BRIDGE_HUB_WESTEND_PARACHAIN_ID,
SIBLING_PARACHAIN_ID,
Box::new(|runtime_event_encoded: Vec<u8>| {
match RuntimeEvent::decode(&mut &runtime_event_encoded[..]) {
Ok(RuntimeEvent::BridgeRococoMessages(event)) => Some(event),
_ => None,
}
}),
|| ExportMessage { network: Rococo, destination: X1(Parachain(bridge_to_rococo_config::AssetHubRococoParaId::get().into())), xcm: Xcm(vec![]) },
Branislav Kontur
committed
XCM_LANE_FOR_ASSET_HUB_WESTEND_TO_ASSET_HUB_ROCOCO,
Some((WestendLocation::get(), ExistentialDeposit::get()).into()),
// value should be >= than value generated by `can_calculate_weight_for_paid_export_message_with_reserve_transfer`
![Svyatoslav Nikolsky Svyatoslav Nikolsky's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Svyatoslav Nikolsky
committed
Some((WestendLocation::get(), bp_bridge_hub_westend::BridgeHubWestendBaseXcmFeeInWnds::get()).into()),
|| PolkadotXcm::force_xcm_version(RuntimeOrigin::root(), Box::new(BridgeHubRococoLocation::get()), XCM_VERSION).expect("version saved!"),
Branislav Kontur
committed
)
}
#[test]
fn message_dispatch_routing_works() {
bridge_hub_test_utils::test_cases::message_dispatch_routing_works::<
Runtime,
AllPalletsWithoutSystem,
XcmConfig,
ParachainSystem,
WithBridgeHubRococoMessagesInstance,
RelayNetwork,
bridge_to_rococo_config::RococoGlobalConsensusNetwork,
ConstU8<2>,
Branislav Kontur
committed
>(
collator_session_keys(),
bp_bridge_hub_westend::BRIDGE_HUB_WESTEND_PARACHAIN_ID,
SIBLING_PARACHAIN_ID,
Box::new(|runtime_event_encoded: Vec<u8>| {
match RuntimeEvent::decode(&mut &runtime_event_encoded[..]) {
Ok(RuntimeEvent::ParachainSystem(event)) => Some(event),
_ => None,
}
}),
Box::new(|runtime_event_encoded: Vec<u8>| {
match RuntimeEvent::decode(&mut &runtime_event_encoded[..]) {
Ok(RuntimeEvent::XcmpQueue(event)) => Some(event),
_ => None,
}
}),
XCM_LANE_FOR_ASSET_HUB_WESTEND_TO_ASSET_HUB_ROCOCO,
|| (),
)
}
#[test]
fn relayed_incoming_message_works() {
bridge_hub_test_utils::test_cases::from_parachain::relayed_incoming_message_works::<
Branislav Kontur
committed
Runtime,
AllPalletsWithoutSystem,
ParachainSystem,
BridgeGrandpaRococoInstance,
BridgeParachainRococoInstance,
WithBridgeHubRococoMessagesInstance,
WithBridgeHubRococoMessageBridge,
>(
collator_session_keys(),
bp_bridge_hub_westend::BRIDGE_HUB_WESTEND_PARACHAIN_ID,
bp_bridge_hub_rococo::BRIDGE_HUB_ROCOCO_PARACHAIN_ID,
BridgeHubRococoChainId::get(),
Branislav Kontur
committed
SIBLING_PARACHAIN_ID,
Westend,
XCM_LANE_FOR_ASSET_HUB_WESTEND_TO_ASSET_HUB_ROCOCO,
|| (),
construct_and_apply_extrinsic,
Branislav Kontur
committed
)
}
#[test]
pub fn complex_relay_extrinsic_works() {
bridge_hub_test_utils::test_cases::from_parachain::complex_relay_extrinsic_works::<
Branislav Kontur
committed
Runtime,
AllPalletsWithoutSystem,
XcmConfig,
ParachainSystem,
BridgeGrandpaRococoInstance,
BridgeParachainRococoInstance,
WithBridgeHubRococoMessagesInstance,
WithBridgeHubRococoMessageBridge,
>(
collator_session_keys(),
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,
Branislav Kontur
committed
);
}
#[test]
pub fn can_calculate_weight_for_paid_export_message_with_reserve_transfer() {
let estimated = bridge_hub_test_utils::test_cases::can_calculate_weight_for_paid_export_message_with_reserve_transfer::<
Runtime,
XcmConfig,
WeightToFee,
>();
// check if estimated value is sane
![Svyatoslav Nikolsky Svyatoslav Nikolsky's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Svyatoslav Nikolsky
committed
let max_expected = bp_bridge_hub_westend::BridgeHubWestendBaseXcmFeeInWnds::get();
Branislav Kontur
committed
assert!(
estimated <= max_expected,
![Svyatoslav Nikolsky Svyatoslav Nikolsky's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Svyatoslav Nikolsky
committed
"calculated: {:?}, max_expected: {:?}, please adjust `bp_bridge_hub_westend::BridgeHubWestendBaseXcmFeeInWnds` value",
Branislav Kontur
committed
estimated,
max_expected
);
}
![Svyatoslav Nikolsky Svyatoslav Nikolsky's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Svyatoslav Nikolsky
committed
#[test]
pub fn can_calculate_fee_for_complex_message_delivery_transaction() {
let estimated = bridge_hub_test_utils::test_cases::from_parachain::can_calculate_fee_for_complex_message_delivery_transaction::<
![Svyatoslav Nikolsky Svyatoslav Nikolsky's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Svyatoslav Nikolsky
committed
Runtime,
BridgeGrandpaRococoInstance,
BridgeParachainRococoInstance,
WithBridgeHubRococoMessagesInstance,
WithBridgeHubRococoMessageBridge,
>(
collator_session_keys(),
construct_and_estimate_extrinsic_fee
);
// check if estimated value is sane
let max_expected = bp_bridge_hub_westend::BridgeHubWestendBaseDeliveryFeeInWnds::get();
assert!(
estimated <= max_expected,
"calculated: {:?}, max_expected: {:?}, please adjust `bp_bridge_hub_westend::BridgeHubWestendBaseDeliveryFeeInWnds` value",
estimated,
max_expected
);
}
#[test]
pub fn can_calculate_fee_for_complex_message_confirmation_transaction() {
let estimated = bridge_hub_test_utils::test_cases::from_parachain::can_calculate_fee_for_complex_message_confirmation_transaction::<
![Svyatoslav Nikolsky Svyatoslav Nikolsky's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Svyatoslav Nikolsky
committed
Runtime,
BridgeGrandpaRococoInstance,
BridgeParachainRococoInstance,
WithBridgeHubRococoMessagesInstance,
WithBridgeHubRococoMessageBridge,
>(
collator_session_keys(),
construct_and_estimate_extrinsic_fee
);
// check if estimated value is sane
let max_expected = bp_bridge_hub_westend::BridgeHubWestendBaseConfirmationFeeInWnds::get();
assert!(
estimated <= max_expected,
"calculated: {:?}, max_expected: {:?}, please adjust `bp_bridge_hub_westend::BridgeHubWestendBaseConfirmationFeeInWnds` value",
estimated,
max_expected
);
}