diff --git a/bridges/bin/millau/runtime/src/lib.rs b/bridges/bin/millau/runtime/src/lib.rs index 21fff0e564e4..574b0569875c 100644 --- a/bridges/bin/millau/runtime/src/lib.rs +++ b/bridges/bin/millau/runtime/src/lib.rs @@ -393,6 +393,7 @@ impl pallet_bridge_relayers::Config for Runtime { pub type RialtoGrandpaInstance = (); impl pallet_bridge_grandpa::Config for Runtime { + type RuntimeEvent = RuntimeEvent; type BridgedChain = bp_rialto::Rialto; // This is a pretty unscientific cap. // @@ -405,6 +406,7 @@ impl pallet_bridge_grandpa::Config for Runtime { pub type WestendGrandpaInstance = pallet_bridge_grandpa::Instance1; impl pallet_bridge_grandpa::Config for Runtime { + type RuntimeEvent = RuntimeEvent; type BridgedChain = bp_westend::Westend; type MaxRequests = ConstU32<50>; type HeadersToKeep = ConstU32<{ bp_westend::DAYS }>; @@ -559,11 +561,11 @@ construct_runtime!( // Rialto bridge modules. BridgeRelayers: pallet_bridge_relayers::{Pallet, Call, Storage, Event}, - BridgeRialtoGrandpa: pallet_bridge_grandpa::{Pallet, Call, Storage}, + BridgeRialtoGrandpa: pallet_bridge_grandpa::{Pallet, Call, Storage, Event}, BridgeRialtoMessages: pallet_bridge_messages::{Pallet, Call, Storage, Event, Config}, // Westend bridge modules. - BridgeWestendGrandpa: pallet_bridge_grandpa::::{Pallet, Call, Config, Storage}, + BridgeWestendGrandpa: pallet_bridge_grandpa::::{Pallet, Call, Config, Storage, Event}, BridgeWestendParachains: pallet_bridge_parachains::::{Pallet, Call, Storage, Event}, // RialtoParachain bridge modules. diff --git a/bridges/bin/rialto-parachain/runtime/src/lib.rs b/bridges/bin/rialto-parachain/runtime/src/lib.rs index d8e087c5a6a9..2621b0096a7f 100644 --- a/bridges/bin/rialto-parachain/runtime/src/lib.rs +++ b/bridges/bin/rialto-parachain/runtime/src/lib.rs @@ -525,6 +525,7 @@ impl pallet_bridge_relayers::Config for Runtime { pub type MillauGrandpaInstance = (); impl pallet_bridge_grandpa::Config for Runtime { + type RuntimeEvent = RuntimeEvent; type BridgedChain = bp_millau::Millau; /// This is a pretty unscientific cap. /// @@ -604,7 +605,7 @@ construct_runtime!( // Millau bridge modules. BridgeRelayers: pallet_bridge_relayers::{Pallet, Call, Storage, Event}, - BridgeMillauGrandpa: pallet_bridge_grandpa::{Pallet, Call, Storage}, + BridgeMillauGrandpa: pallet_bridge_grandpa::{Pallet, Call, Storage, Event}, BridgeMillauMessages: pallet_bridge_messages::{Pallet, Call, Storage, Event, Config}, } ); diff --git a/bridges/bin/rialto/runtime/src/lib.rs b/bridges/bin/rialto/runtime/src/lib.rs index 9db181e28403..bdc205bec140 100644 --- a/bridges/bin/rialto/runtime/src/lib.rs +++ b/bridges/bin/rialto/runtime/src/lib.rs @@ -390,6 +390,7 @@ impl pallet_bridge_relayers::Config for Runtime { pub type MillauGrandpaInstance = (); impl pallet_bridge_grandpa::Config for Runtime { + type RuntimeEvent = RuntimeEvent; type BridgedChain = bp_millau::Millau; /// This is a pretty unscientific cap. /// @@ -479,7 +480,7 @@ construct_runtime!( // Millau bridge modules. BridgeRelayers: pallet_bridge_relayers::{Pallet, Call, Storage, Event}, - BridgeMillauGrandpa: pallet_bridge_grandpa::{Pallet, Call, Storage}, + BridgeMillauGrandpa: pallet_bridge_grandpa::{Pallet, Call, Storage, Event}, BridgeMillauMessages: pallet_bridge_messages::{Pallet, Call, Storage, Event, Config}, // Millau bridge modules (BEEFY based). diff --git a/bridges/bin/runtime-common/src/mock.rs b/bridges/bin/runtime-common/src/mock.rs index c2cd8e9ba830..056fd3a2ccf0 100644 --- a/bridges/bin/runtime-common/src/mock.rs +++ b/bridges/bin/runtime-common/src/mock.rs @@ -107,7 +107,7 @@ frame_support::construct_runtime! { Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, TransactionPayment: pallet_transaction_payment::{Pallet, Storage, Event}, BridgeRelayers: pallet_bridge_relayers::{Pallet, Call, Storage, Event}, - BridgeGrandpa: pallet_bridge_grandpa::{Pallet, Call, Storage}, + BridgeGrandpa: pallet_bridge_grandpa::{Pallet, Call, Storage, Event}, BridgeParachains: pallet_bridge_parachains::{Pallet, Call, Storage, Event}, BridgeMessages: pallet_bridge_messages::{Pallet, Call, Storage, Event, Config}, } @@ -194,6 +194,7 @@ impl pallet_transaction_payment::Config for TestRuntime { } impl pallet_bridge_grandpa::Config for TestRuntime { + type RuntimeEvent = RuntimeEvent; type BridgedChain = BridgedUnderlyingChain; type MaxRequests = ConstU32<50>; type HeadersToKeep = ConstU32<8>; diff --git a/bridges/modules/grandpa/src/lib.rs b/bridges/modules/grandpa/src/lib.rs index 2b9e49d4c95e..2d81f3106fc9 100644 --- a/bridges/modules/grandpa/src/lib.rs +++ b/bridges/modules/grandpa/src/lib.rs @@ -96,6 +96,10 @@ pub mod pallet { #[pallet::config] pub trait Config: frame_system::Config { + /// The overarching event type. + type RuntimeEvent: From> + + IsType<::RuntimeEvent>; + /// The chain we are bridging to here. type BridgedChain: ChainWithGrandpa; @@ -164,19 +168,19 @@ pub mod pallet { ensure!(Self::request_count() < T::MaxRequests::get(), >::TooManyRequests); - let (hash, number) = (finality_target.hash(), finality_target.number()); + let (hash, number) = (finality_target.hash(), *finality_target.number()); log::trace!( target: LOG_TARGET, "Going to try and finalize header {:?}", finality_target ); - SubmitFinalityProofHelper::::check_obsolete(*number)?; + SubmitFinalityProofHelper::::check_obsolete(number)?; let authority_set = >::get(); let unused_proof_size = authority_set.unused_proof_size(); let set_id = authority_set.set_id; - verify_justification::(&justification, hash, *number, authority_set.into())?; + verify_justification::(&justification, hash, number, authority_set.into())?; let is_authorities_change_enacted = try_enact_authority_change::(&finality_target, set_id)?; @@ -212,6 +216,8 @@ pub mod pallet { let actual_weight = pre_dispatch_weight .set_proof_size(pre_dispatch_weight.proof_size().saturating_sub(unused_proof_size)); + Self::deposit_event(Event::UpdatedBestFinalizedHeader { number, hash }); + Ok(PostDispatchInfo { actual_weight: Some(actual_weight), pays_fee }) } @@ -370,6 +376,16 @@ pub mod pallet { } } + #[pallet::event] + #[pallet::generate_deposit(pub(super) fn deposit_event)] + pub enum Event, I: 'static = ()> { + /// Best finalized chain header has been updated to the header with given number and hash. + UpdatedBestFinalizedHeader { + number: BridgedBlockNumber, + hash: BridgedBlockHash, + }, + } + #[pallet::error] pub enum Error { /// The given justification is invalid for the given header. @@ -635,8 +651,8 @@ pub fn initialize_for_benchmarks, I: 'static>(header: BridgedHeader mod tests { use super::*; use crate::mock::{ - run_test, test_header, RuntimeOrigin, TestBridgedChain, TestHeader, TestNumber, - TestRuntime, MAX_BRIDGED_AUTHORITIES, + run_test, test_header, RuntimeEvent as TestEvent, RuntimeOrigin, System, TestBridgedChain, + TestHeader, TestNumber, TestRuntime, MAX_BRIDGED_AUTHORITIES, }; use bp_header_chain::BridgeGrandpaCall; use bp_runtime::BasicOperatingMode; @@ -649,10 +665,14 @@ mod tests { assert_err, assert_noop, assert_ok, dispatch::PostDispatchInfo, storage::generator::StorageValue, }; + use frame_system::{EventRecord, Phase}; use sp_core::Get; use sp_runtime::{Digest, DigestItem, DispatchError}; fn initialize_substrate_bridge() { + System::set_block_number(1); + System::reset_events(); + assert_ok!(init_with_origin(RuntimeOrigin::root())); } @@ -847,6 +867,18 @@ mod tests { let header = test_header(1); assert_eq!(>::get().unwrap().1, header.hash()); assert!(>::contains_key(header.hash())); + + assert_eq!( + System::events(), + vec![EventRecord { + phase: Phase::Initialization, + event: TestEvent::Grandpa(Event::UpdatedBestFinalizedHeader { + number: *header.number(), + hash: header.hash(), + }), + topics: vec![], + }], + ); }) } diff --git a/bridges/modules/grandpa/src/mock.rs b/bridges/modules/grandpa/src/mock.rs index acedfc3582c2..b10f5d86c3de 100644 --- a/bridges/modules/grandpa/src/mock.rs +++ b/bridges/modules/grandpa/src/mock.rs @@ -49,7 +49,7 @@ construct_runtime! { UncheckedExtrinsic = UncheckedExtrinsic, { System: frame_system::{Pallet, Call, Config, Storage, Event}, - Grandpa: grandpa::{Pallet, Call}, + Grandpa: grandpa::{Pallet, Call, Event}, } } @@ -69,7 +69,7 @@ impl frame_system::Config for TestRuntime { type AccountId = AccountId; type Lookup = IdentityLookup; type Header = Header; - type RuntimeEvent = (); + type RuntimeEvent = RuntimeEvent; type BlockHashCount = ConstU64<250>; type Version = (); type PalletInfo = PalletInfo; @@ -94,6 +94,7 @@ parameter_types! { } impl grandpa::Config for TestRuntime { + type RuntimeEvent = RuntimeEvent; type BridgedChain = TestBridgedChain; type MaxRequests = MaxRequests; type HeadersToKeep = HeadersToKeep; diff --git a/bridges/modules/parachains/src/lib.rs b/bridges/modules/parachains/src/lib.rs index 20a9ef9b95bd..e72e2aec8c20 100644 --- a/bridges/modules/parachains/src/lib.rs +++ b/bridges/modules/parachains/src/lib.rs @@ -735,14 +735,18 @@ mod tests { }, ) .unwrap(); + + System::::set_block_number(1); + System::::reset_events(); } - fn proceed(num: RelayBlockNumber, state_root: RelayBlockHash) { + fn proceed(num: RelayBlockNumber, state_root: RelayBlockHash) -> ParaHash { pallet_bridge_grandpa::Pallet::::on_initialize( 0, ); let header = test_relay_header(num, state_root); + let hash = header.hash(); let justification = make_default_justification(&header); assert_ok!( pallet_bridge_grandpa::Pallet::::submit_finality_proof( @@ -751,6 +755,8 @@ mod tests { justification, ) ); + + hash } fn prepare_parachain_heads_proof( @@ -1010,7 +1016,7 @@ mod tests { ); // import head#10 of parachain#1 at relay block #1 - proceed(1, state_root_10); + let relay_1_hash = proceed(1, state_root_10); assert_ok!(import_parachain_1_head(1, state_root_10, parachains_10, proof_10)); assert_eq!( ParasInfo::::get(ParaId(1)), @@ -1043,6 +1049,16 @@ mod tests { }), topics: vec![], }, + EventRecord { + phase: Phase::Initialization, + event: TestEvent::Grandpa1( + pallet_bridge_grandpa::Event::UpdatedBestFinalizedHeader { + number: 1, + hash: relay_1_hash, + } + ), + topics: vec![], + }, EventRecord { phase: Phase::Initialization, event: TestEvent::Parachains(Event::UpdatedParachainHead { @@ -1155,7 +1171,7 @@ mod tests { // try to import head#0 of parachain#1 at relay block#1 // => call succeeds, but nothing is changed - proceed(1, state_root); + let relay_1_hash = proceed(1, state_root); assert_ok!(import_parachain_1_head(1, state_root, parachains, proof)); assert_eq!(ParasInfo::::get(ParaId(1)), Some(initial_best_head(1))); assert_eq!( @@ -1169,6 +1185,16 @@ mod tests { }), topics: vec![], }, + EventRecord { + phase: Phase::Initialization, + event: TestEvent::Grandpa1( + pallet_bridge_grandpa::Event::UpdatedBestFinalizedHeader { + number: 1, + hash: relay_1_hash, + } + ), + topics: vec![], + }, EventRecord { phase: Phase::Initialization, event: TestEvent::Parachains(Event::RejectedObsoleteParachainHead { @@ -1193,7 +1219,7 @@ mod tests { initialize(state_root_5); // head#10 of parachain#1 at relay block#1 - proceed(1, state_root_10); + let relay_1_hash = proceed(1, state_root_10); assert_ok!(import_parachain_1_head(1, state_root_10, parachains_10, proof_10)); assert_eq!( ParasInfo::::get(ParaId(1)), @@ -1207,14 +1233,26 @@ mod tests { ); assert_eq!( System::::events(), - vec![EventRecord { - phase: Phase::Initialization, - event: TestEvent::Parachains(Event::UpdatedParachainHead { - parachain: ParaId(1), - parachain_head_hash: head_data(1, 10).hash(), - }), - topics: vec![], - }], + vec![ + EventRecord { + phase: Phase::Initialization, + event: TestEvent::Grandpa1( + pallet_bridge_grandpa::Event::UpdatedBestFinalizedHeader { + number: 1, + hash: relay_1_hash, + } + ), + topics: vec![], + }, + EventRecord { + phase: Phase::Initialization, + event: TestEvent::Parachains(Event::UpdatedParachainHead { + parachain: ParaId(1), + parachain_head_hash: head_data(1, 10).hash(), + }), + topics: vec![], + } + ], ); // now try to import head#5 at relay block#0 @@ -1233,6 +1271,16 @@ mod tests { assert_eq!( System::::events(), vec![ + EventRecord { + phase: Phase::Initialization, + event: TestEvent::Grandpa1( + pallet_bridge_grandpa::Event::UpdatedBestFinalizedHeader { + number: 1, + hash: relay_1_hash, + } + ), + topics: vec![], + }, EventRecord { phase: Phase::Initialization, event: TestEvent::Parachains(Event::UpdatedParachainHead { diff --git a/bridges/modules/parachains/src/mock.rs b/bridges/modules/parachains/src/mock.rs index 83d347018e45..c19ce98eba2f 100644 --- a/bridges/modules/parachains/src/mock.rs +++ b/bridges/modules/parachains/src/mock.rs @@ -150,8 +150,8 @@ construct_runtime! { UncheckedExtrinsic = UncheckedExtrinsic, { System: frame_system::{Pallet, Call, Config, Storage, Event}, - Grandpa1: pallet_bridge_grandpa::::{Pallet}, - Grandpa2: pallet_bridge_grandpa::::{Pallet}, + Grandpa1: pallet_bridge_grandpa::::{Pallet, Event}, + Grandpa2: pallet_bridge_grandpa::::{Pallet, Event}, Parachains: pallet_bridge_parachains::{Call, Pallet, Event}, } } @@ -197,6 +197,7 @@ parameter_types! { } impl pallet_bridge_grandpa::Config for TestRuntime { + type RuntimeEvent = RuntimeEvent; type BridgedChain = TestBridgedChain; type MaxRequests = ConstU32<2>; type HeadersToKeep = HeadersToKeep; @@ -204,6 +205,7 @@ impl pallet_bridge_grandpa::Config for TestRun } impl pallet_bridge_grandpa::Config for TestRuntime { + type RuntimeEvent = RuntimeEvent; type BridgedChain = TestBridgedChain; type MaxRequests = ConstU32<2>; type HeadersToKeep = HeadersToKeep;