From 17c82777aa13a6c337cf0289d13941e9e7f56b4d Mon Sep 17 00:00:00 2001 From: claravanstaden Date: Mon, 28 Oct 2024 21:12:00 +0200 Subject: [PATCH 1/2] fix test --- Cargo.lock | 1 + Cargo.toml | 1 + .../bridge-hub-polkadot/Cargo.toml | 1 + .../bridge-hub-polkadot/tests/snowbridge.rs | 162 +++++++++++++++++- 4 files changed, 156 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b6a138eba0..d62c45ddec 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1953,6 +1953,7 @@ dependencies = [ "snowbridge-core", "snowbridge-outbound-queue-runtime-api", "snowbridge-pallet-ethereum-client", + "snowbridge-pallet-ethereum-client-fixtures", "snowbridge-pallet-inbound-queue", "snowbridge-pallet-outbound-queue", "snowbridge-pallet-system", diff --git a/Cargo.toml b/Cargo.toml index 87a852cfda..f6c1a3710b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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 } diff --git a/system-parachains/bridge-hubs/bridge-hub-polkadot/Cargo.toml b/system-parachains/bridge-hubs/bridge-hub-polkadot/Cargo.toml index 1f56851440..34a83bba78 100644 --- a/system-parachains/bridge-hubs/bridge-hub-polkadot/Cargo.toml +++ b/system-parachains/bridge-hubs/bridge-hub-polkadot/Cargo.toml @@ -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] diff --git a/system-parachains/bridge-hubs/bridge-hub-polkadot/tests/snowbridge.rs b/system-parachains/bridge-hubs/bridge-hub-polkadot/tests/snowbridge.rs index e4b4027d81..be6df283c0 100644 --- a/system-parachains/bridge-hubs/bridge-hub-polkadot/tests/snowbridge.rs +++ b/system-parachains/bridge-hubs/bridge-hub-polkadot/tests/snowbridge.rs @@ -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 = + parachains_runtimes_test_utils::RuntimeHelper; fn collator_session_keys() -> bridge_hub_test_utils::CollatorSessionKeys { bridge_hub_test_utils::CollatorSessionKeys::new( @@ -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] @@ -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( + collator_session_key: CollatorSessionKeys, + runtime_para_id: u32, + construct_and_apply_extrinsic: fn( + sp_keyring::AccountKeyring, + ::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: From>, + ::RuntimeCall: + From>, + ::RuntimeCall: From>, + AccountIdOf: From, +{ + ExtBuilder::::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(); + >::mint_into( + &alice_account.clone().into(), + 10_000_000_000_000_u128.saturated_into::>(), + ) + .unwrap(); + let balance_before = + >::free_balance(&alice_account.clone().into()); + + assert_ok!(>::force_checkpoint( + RuntimeHelper::::root_origin(), + initial_checkpoint.clone(), + )); + let balance_after_checkpoint = + >::free_balance(&alice_account.clone().into()); + + let update_call: ::RuntimeCall = + snowbridge_pallet_ethereum_client::Call::::submit { + update: Box::new(*update.clone()), + } + .into(); + + let invalid_update_call: ::RuntimeCall = + snowbridge_pallet_ethereum_client::Call::::submit { + update: Box::new(*invalid_update), + } + .into(); + + let update_sync_committee_call: ::RuntimeCall = + snowbridge_pallet_ethereum_client::Call::::submit { + update: Box::new(*sync_committee_update), + } + .into(); + + let invalid_update_sync_committee_call: ::RuntimeCall = + snowbridge_pallet_ethereum_client::Call::::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 = + >::free_balance(&alice_account.clone().into()); + + // All the extrinsics in this test do no fit into 1 block + let _ = RuntimeHelper::::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::::InvalidUpdateSlot + ); + let balance_after_invalid_update = + >::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 = + >::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::::InvalidUpdateSlot + ); + let balance_after_invalid_sync_com_update = + >::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 = + ::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, From 7350711f9a5bb8340fbf7a2a24efac110a3494e8 Mon Sep 17 00:00:00 2001 From: claravanstaden Date: Mon, 28 Oct 2024 21:15:41 +0200 Subject: [PATCH 2/2] revert weight --- .../src/weights/snowbridge_pallet_ethereum_client.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system-parachains/bridge-hubs/bridge-hub-polkadot/src/weights/snowbridge_pallet_ethereum_client.rs b/system-parachains/bridge-hubs/bridge-hub-polkadot/src/weights/snowbridge_pallet_ethereum_client.rs index 6a08d4fb51..9ba101d701 100644 --- a/system-parachains/bridge-hubs/bridge-hub-polkadot/src/weights/snowbridge_pallet_ethereum_client.rs +++ b/system-parachains/bridge-hubs/bridge-hub-polkadot/src/weights/snowbridge_pallet_ethereum_client.rs @@ -111,7 +111,7 @@ impl snowbridge_pallet_ethereum_client::WeightInfo for // Measured: `92787` // Estimated: `93857` // Minimum execution time: 169_086_936_000 picoseconds. - Weight::from_parts(69_539_621_000, 0) + Weight::from_parts(169_539_621_000, 0) .saturating_add(Weight::from_parts(0, 93857)) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(1))