Skip to content

Commit

Permalink
fix test
Browse files Browse the repository at this point in the history
  • Loading branch information
claravanstaden committed Oct 28, 2024
1 parent ae42f9c commit 17c8277
Show file tree
Hide file tree
Showing 4 changed files with 156 additions and 9 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,7 @@ snowbridge-outbound-queue-runtime-api = { version = "0.10.0", default-features =
snowbridge-pallet-ethereum-client = { version = "0.10.0", default-features = false }
snowbridge-pallet-inbound-queue = { version = "0.10.0", default-features = false }
snowbridge-pallet-inbound-queue-fixtures = { version = "0.18.0" }
snowbridge-pallet-ethereum-client-fixtures = { version = "0.18.0" }
snowbridge-pallet-outbound-queue = { version = "0.10.0", default-features = false }
snowbridge-pallet-system = { version = "0.10.0", default-features = false }
snowbridge-router-primitives = { version = "0.16.0", default-features = false }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ pallet-bridge-relayers = { workspace = true, features = ["integrity-test"] }
sp-keyring = { workspace = true }
static_assertions = { workspace = true }
snowbridge-runtime-test-common = { workspace = true }
snowbridge-pallet-ethereum-client-fixtures = { workspace = true }
parachains-runtimes-test-utils = { workspace = true }

[features]
Expand Down
162 changes: 153 additions & 9 deletions system-parachains/bridge-hubs/bridge-hub-polkadot/tests/snowbridge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,23 +27,31 @@ use bridge_hub_polkadot_runtime::{
};
use codec::{Decode, Encode};
use cumulus_primitives_core::XcmError::{FailedToTransactAsset, TooExpensive};
use frame_support::{parameter_types, traits::Contains};
use frame_support::{
assert_err, assert_ok, parameter_types,
traits::{fungible::Mutate, Contains},
};
use parachains_common::{AccountId, AuraId, Balance};
pub use parachains_runtimes_test_utils::test_cases::change_storage_constant_by_governance_works;
use parachains_runtimes_test_utils::{
AccountIdOf, BalanceOf, CollatorSessionKeys, ExtBuilder, ValidatorIdOf,
};
use snowbridge_pallet_ethereum_client::WeightInfo;
use sp_core::H160;
use snowbridge_pallet_ethereum_client_fixtures::*;
use sp_core::{Get, H160};
use sp_keyring::AccountKeyring::Alice;
use sp_runtime::{
generic::{Era, SignedPayload},
AccountId32,
AccountId32, SaturatedConversion,
};
use xcm::latest::prelude::*;
use xcm_builder::HandleFee;
use xcm_executor::traits::{FeeManager, FeeReason};

parameter_types! {
pub const DefaultBridgeHubEthereumBaseFee: Balance = 2_750_872_500_000;
}
type RuntimeHelper<Runtime, AllPalletsWithoutSystem = ()> =
parachains_runtimes_test_utils::RuntimeHelper<Runtime, AllPalletsWithoutSystem>;

fn collator_session_keys() -> bridge_hub_test_utils::CollatorSessionKeys<Runtime> {
bridge_hub_test_utils::CollatorSessionKeys::new(
Expand Down Expand Up @@ -199,11 +207,7 @@ fn max_message_queue_service_weight_is_more_than_beacon_extrinsic_weights() {
// FAIL-CI @bkontur can you help me to check why it's exceeding the weight limits?
#[test]
fn ethereum_client_consensus_extrinsics_work() {
snowbridge_runtime_test_common::ethereum_extrinsic(
collator_session_keys(),
1013,
construct_and_apply_extrinsic,
);
ethereum_extrinsic(collator_session_keys(), 1013, construct_and_apply_extrinsic);
}

#[test]
Expand Down Expand Up @@ -238,6 +242,146 @@ fn ethereum_outbound_queue_processes_messages_before_message_queue_works() {
)
}

// TODO replace with snowbridge runtime common method in stable-2412 release.
pub fn ethereum_extrinsic<Runtime>(
collator_session_key: CollatorSessionKeys<Runtime>,
runtime_para_id: u32,
construct_and_apply_extrinsic: fn(
sp_keyring::AccountKeyring,
<Runtime as frame_system::Config>::RuntimeCall,
) -> sp_runtime::DispatchOutcome,
) where
Runtime: frame_system::Config
+ pallet_balances::Config
+ pallet_session::Config
+ pallet_xcm::Config
+ pallet_utility::Config
+ parachain_info::Config
+ pallet_collator_selection::Config
+ cumulus_pallet_parachain_system::Config
+ snowbridge_pallet_outbound_queue::Config
+ snowbridge_pallet_system::Config
+ snowbridge_pallet_ethereum_client::Config
+ pallet_timestamp::Config,
ValidatorIdOf<Runtime>: From<AccountIdOf<Runtime>>,
<Runtime as pallet_utility::Config>::RuntimeCall:
From<snowbridge_pallet_ethereum_client::Call<Runtime>>,
<Runtime as frame_system::Config>::RuntimeCall: From<pallet_utility::Call<Runtime>>,
AccountIdOf<Runtime>: From<AccountId32>,
{
ExtBuilder::<Runtime>::default()
.with_collators(collator_session_key.collators())
.with_session_keys(collator_session_key.session_keys())
.with_para_id(runtime_para_id.into())
.with_tracing()
.build()
.execute_with(|| {
let initial_checkpoint = make_checkpoint();
let update = make_finalized_header_update();
let sync_committee_update = make_sync_committee_update();
let mut invalid_update = make_finalized_header_update();
let mut invalid_sync_committee_update = make_sync_committee_update();
invalid_update.finalized_header.slot = 4354;
invalid_sync_committee_update.finalized_header.slot = 4354;

let alice = Alice;
let alice_account = alice.to_account_id();
<pallet_balances::Pallet<Runtime>>::mint_into(
&alice_account.clone().into(),
10_000_000_000_000_u128.saturated_into::<BalanceOf<Runtime>>(),
)
.unwrap();
let balance_before =
<pallet_balances::Pallet<Runtime>>::free_balance(&alice_account.clone().into());

assert_ok!(<snowbridge_pallet_ethereum_client::Pallet<Runtime>>::force_checkpoint(
RuntimeHelper::<Runtime>::root_origin(),
initial_checkpoint.clone(),
));
let balance_after_checkpoint =
<pallet_balances::Pallet<Runtime>>::free_balance(&alice_account.clone().into());

let update_call: <Runtime as pallet_utility::Config>::RuntimeCall =
snowbridge_pallet_ethereum_client::Call::<Runtime>::submit {
update: Box::new(*update.clone()),
}
.into();

let invalid_update_call: <Runtime as pallet_utility::Config>::RuntimeCall =
snowbridge_pallet_ethereum_client::Call::<Runtime>::submit {
update: Box::new(*invalid_update),
}
.into();

let update_sync_committee_call: <Runtime as pallet_utility::Config>::RuntimeCall =
snowbridge_pallet_ethereum_client::Call::<Runtime>::submit {
update: Box::new(*sync_committee_update),
}
.into();

let invalid_update_sync_committee_call: <Runtime as pallet_utility::Config>::RuntimeCall =
snowbridge_pallet_ethereum_client::Call::<Runtime>::submit {
update: Box::new(*invalid_sync_committee_update),
}
.into();

// Finalized header update
let update_outcome = construct_and_apply_extrinsic(alice, update_call.into());
assert_ok!(update_outcome);
let balance_after_update =
<pallet_balances::Pallet<Runtime>>::free_balance(&alice_account.clone().into());

// All the extrinsics in this test do no fit into 1 block
let _ = RuntimeHelper::<Runtime>::run_to_block(2, AccountId::from(alice).into());

// Invalid finalized header update
let invalid_update_outcome =
construct_and_apply_extrinsic(alice, invalid_update_call.into());
assert_err!(
invalid_update_outcome,
snowbridge_pallet_ethereum_client::Error::<Runtime>::InvalidUpdateSlot
);
let balance_after_invalid_update =
<pallet_balances::Pallet<Runtime>>::free_balance(&alice_account.clone().into());

// Sync committee update
let sync_committee_outcome =
construct_and_apply_extrinsic(alice, update_sync_committee_call.into());
assert_ok!(sync_committee_outcome);
let balance_after_sync_com_update =
<pallet_balances::Pallet<Runtime>>::free_balance(&alice_account.clone().into());

// Invalid sync committee update
let invalid_sync_committee_outcome =
construct_and_apply_extrinsic(alice, invalid_update_sync_committee_call.into());
assert_err!(
invalid_sync_committee_outcome,
snowbridge_pallet_ethereum_client::Error::<Runtime>::InvalidUpdateSlot
);
let balance_after_invalid_sync_com_update =
<pallet_balances::Pallet<Runtime>>::free_balance(&alice_account.clone().into());

// Assert paid operations are charged and free operations are free
// Checkpoint is a free operation
assert!(balance_before == balance_after_checkpoint);
let gap =
<Runtime as snowbridge_pallet_ethereum_client::Config>::FreeHeadersInterval::get();
// Large enough header gap is free
if update.finalized_header.slot >= initial_checkpoint.header.slot + gap as u64 {
assert!(balance_after_checkpoint == balance_after_update);
} else {
// Otherwise paid
assert!(balance_after_checkpoint > balance_after_update);
}
// An invalid update is paid
assert!(balance_after_update > balance_after_invalid_update);
// A successful sync committee update is free
assert!(balance_after_invalid_update == balance_after_sync_com_update);
// An invalid sync committee update is paid
assert!(balance_after_sync_com_update > balance_after_invalid_sync_com_update);
});
}

fn construct_extrinsic(
sender: sp_keyring::AccountKeyring,
call: RuntimeCall,
Expand Down

0 comments on commit 17c8277

Please sign in to comment.