added UpdatedBestFinalizedHeader event to pallet-bridge-grandpa (#1967)

This commit is contained in:
Svyatoslav Nikolsky
2023-03-16 14:48:27 +03:00
committed by Bastian Köcher
parent 802e134368
commit 74b0eca59c
8 changed files with 114 additions and 26 deletions
+4 -2
View File
@@ -393,6 +393,7 @@ impl pallet_bridge_relayers::Config for Runtime {
pub type RialtoGrandpaInstance = (); pub type RialtoGrandpaInstance = ();
impl pallet_bridge_grandpa::Config for Runtime { impl pallet_bridge_grandpa::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type BridgedChain = bp_rialto::Rialto; type BridgedChain = bp_rialto::Rialto;
// This is a pretty unscientific cap. // This is a pretty unscientific cap.
// //
@@ -405,6 +406,7 @@ impl pallet_bridge_grandpa::Config for Runtime {
pub type WestendGrandpaInstance = pallet_bridge_grandpa::Instance1; pub type WestendGrandpaInstance = pallet_bridge_grandpa::Instance1;
impl pallet_bridge_grandpa::Config<WestendGrandpaInstance> for Runtime { impl pallet_bridge_grandpa::Config<WestendGrandpaInstance> for Runtime {
type RuntimeEvent = RuntimeEvent;
type BridgedChain = bp_westend::Westend; type BridgedChain = bp_westend::Westend;
type MaxRequests = ConstU32<50>; type MaxRequests = ConstU32<50>;
type HeadersToKeep = ConstU32<{ bp_westend::DAYS }>; type HeadersToKeep = ConstU32<{ bp_westend::DAYS }>;
@@ -559,11 +561,11 @@ construct_runtime!(
// Rialto bridge modules. // Rialto bridge modules.
BridgeRelayers: pallet_bridge_relayers::{Pallet, Call, Storage, Event<T>}, BridgeRelayers: pallet_bridge_relayers::{Pallet, Call, Storage, Event<T>},
BridgeRialtoGrandpa: pallet_bridge_grandpa::{Pallet, Call, Storage}, BridgeRialtoGrandpa: pallet_bridge_grandpa::{Pallet, Call, Storage, Event<T>},
BridgeRialtoMessages: pallet_bridge_messages::{Pallet, Call, Storage, Event<T>, Config<T>}, BridgeRialtoMessages: pallet_bridge_messages::{Pallet, Call, Storage, Event<T>, Config<T>},
// Westend bridge modules. // Westend bridge modules.
BridgeWestendGrandpa: pallet_bridge_grandpa::<Instance1>::{Pallet, Call, Config<T>, Storage}, BridgeWestendGrandpa: pallet_bridge_grandpa::<Instance1>::{Pallet, Call, Config<T>, Storage, Event<T>},
BridgeWestendParachains: pallet_bridge_parachains::<Instance1>::{Pallet, Call, Storage, Event<T>}, BridgeWestendParachains: pallet_bridge_parachains::<Instance1>::{Pallet, Call, Storage, Event<T>},
// RialtoParachain bridge modules. // RialtoParachain bridge modules.
@@ -525,6 +525,7 @@ impl pallet_bridge_relayers::Config for Runtime {
pub type MillauGrandpaInstance = (); pub type MillauGrandpaInstance = ();
impl pallet_bridge_grandpa::Config for Runtime { impl pallet_bridge_grandpa::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type BridgedChain = bp_millau::Millau; type BridgedChain = bp_millau::Millau;
/// This is a pretty unscientific cap. /// This is a pretty unscientific cap.
/// ///
@@ -604,7 +605,7 @@ construct_runtime!(
// Millau bridge modules. // Millau bridge modules.
BridgeRelayers: pallet_bridge_relayers::{Pallet, Call, Storage, Event<T>}, BridgeRelayers: pallet_bridge_relayers::{Pallet, Call, Storage, Event<T>},
BridgeMillauGrandpa: pallet_bridge_grandpa::{Pallet, Call, Storage}, BridgeMillauGrandpa: pallet_bridge_grandpa::{Pallet, Call, Storage, Event<T>},
BridgeMillauMessages: pallet_bridge_messages::{Pallet, Call, Storage, Event<T>, Config<T>}, BridgeMillauMessages: pallet_bridge_messages::{Pallet, Call, Storage, Event<T>, Config<T>},
} }
); );
+2 -1
View File
@@ -390,6 +390,7 @@ impl pallet_bridge_relayers::Config for Runtime {
pub type MillauGrandpaInstance = (); pub type MillauGrandpaInstance = ();
impl pallet_bridge_grandpa::Config for Runtime { impl pallet_bridge_grandpa::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type BridgedChain = bp_millau::Millau; type BridgedChain = bp_millau::Millau;
/// This is a pretty unscientific cap. /// This is a pretty unscientific cap.
/// ///
@@ -479,7 +480,7 @@ construct_runtime!(
// Millau bridge modules. // Millau bridge modules.
BridgeRelayers: pallet_bridge_relayers::{Pallet, Call, Storage, Event<T>}, BridgeRelayers: pallet_bridge_relayers::{Pallet, Call, Storage, Event<T>},
BridgeMillauGrandpa: pallet_bridge_grandpa::{Pallet, Call, Storage}, BridgeMillauGrandpa: pallet_bridge_grandpa::{Pallet, Call, Storage, Event<T>},
BridgeMillauMessages: pallet_bridge_messages::{Pallet, Call, Storage, Event<T>, Config<T>}, BridgeMillauMessages: pallet_bridge_messages::{Pallet, Call, Storage, Event<T>, Config<T>},
// Millau bridge modules (BEEFY based). // Millau bridge modules (BEEFY based).
+2 -1
View File
@@ -107,7 +107,7 @@ frame_support::construct_runtime! {
Balances: pallet_balances::{Pallet, Call, Storage, Config<T>, Event<T>}, Balances: pallet_balances::{Pallet, Call, Storage, Config<T>, Event<T>},
TransactionPayment: pallet_transaction_payment::{Pallet, Storage, Event<T>}, TransactionPayment: pallet_transaction_payment::{Pallet, Storage, Event<T>},
BridgeRelayers: pallet_bridge_relayers::{Pallet, Call, Storage, Event<T>}, BridgeRelayers: pallet_bridge_relayers::{Pallet, Call, Storage, Event<T>},
BridgeGrandpa: pallet_bridge_grandpa::{Pallet, Call, Storage}, BridgeGrandpa: pallet_bridge_grandpa::{Pallet, Call, Storage, Event<T>},
BridgeParachains: pallet_bridge_parachains::{Pallet, Call, Storage, Event<T>}, BridgeParachains: pallet_bridge_parachains::{Pallet, Call, Storage, Event<T>},
BridgeMessages: pallet_bridge_messages::{Pallet, Call, Storage, Event<T>, Config<T>}, BridgeMessages: pallet_bridge_messages::{Pallet, Call, Storage, Event<T>, Config<T>},
} }
@@ -194,6 +194,7 @@ impl pallet_transaction_payment::Config for TestRuntime {
} }
impl pallet_bridge_grandpa::Config for TestRuntime { impl pallet_bridge_grandpa::Config for TestRuntime {
type RuntimeEvent = RuntimeEvent;
type BridgedChain = BridgedUnderlyingChain; type BridgedChain = BridgedUnderlyingChain;
type MaxRequests = ConstU32<50>; type MaxRequests = ConstU32<50>;
type HeadersToKeep = ConstU32<8>; type HeadersToKeep = ConstU32<8>;
+37 -5
View File
@@ -96,6 +96,10 @@ pub mod pallet {
#[pallet::config] #[pallet::config]
pub trait Config<I: 'static = ()>: frame_system::Config { pub trait Config<I: 'static = ()>: frame_system::Config {
/// The overarching event type.
type RuntimeEvent: From<Event<Self, I>>
+ IsType<<Self as frame_system::Config>::RuntimeEvent>;
/// The chain we are bridging to here. /// The chain we are bridging to here.
type BridgedChain: ChainWithGrandpa; type BridgedChain: ChainWithGrandpa;
@@ -164,19 +168,19 @@ pub mod pallet {
ensure!(Self::request_count() < T::MaxRequests::get(), <Error<T, I>>::TooManyRequests); ensure!(Self::request_count() < T::MaxRequests::get(), <Error<T, I>>::TooManyRequests);
let (hash, number) = (finality_target.hash(), finality_target.number()); let (hash, number) = (finality_target.hash(), *finality_target.number());
log::trace!( log::trace!(
target: LOG_TARGET, target: LOG_TARGET,
"Going to try and finalize header {:?}", "Going to try and finalize header {:?}",
finality_target finality_target
); );
SubmitFinalityProofHelper::<T, I>::check_obsolete(*number)?; SubmitFinalityProofHelper::<T, I>::check_obsolete(number)?;
let authority_set = <CurrentAuthoritySet<T, I>>::get(); let authority_set = <CurrentAuthoritySet<T, I>>::get();
let unused_proof_size = authority_set.unused_proof_size(); let unused_proof_size = authority_set.unused_proof_size();
let set_id = authority_set.set_id; let set_id = authority_set.set_id;
verify_justification::<T, I>(&justification, hash, *number, authority_set.into())?; verify_justification::<T, I>(&justification, hash, number, authority_set.into())?;
let is_authorities_change_enacted = let is_authorities_change_enacted =
try_enact_authority_change::<T, I>(&finality_target, set_id)?; try_enact_authority_change::<T, I>(&finality_target, set_id)?;
@@ -212,6 +216,8 @@ pub mod pallet {
let actual_weight = pre_dispatch_weight let actual_weight = pre_dispatch_weight
.set_proof_size(pre_dispatch_weight.proof_size().saturating_sub(unused_proof_size)); .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 }) 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<T: Config<I>, I: 'static = ()> {
/// Best finalized chain header has been updated to the header with given number and hash.
UpdatedBestFinalizedHeader {
number: BridgedBlockNumber<T, I>,
hash: BridgedBlockHash<T, I>,
},
}
#[pallet::error] #[pallet::error]
pub enum Error<T, I = ()> { pub enum Error<T, I = ()> {
/// The given justification is invalid for the given header. /// The given justification is invalid for the given header.
@@ -635,8 +651,8 @@ pub fn initialize_for_benchmarks<T: Config<I>, I: 'static>(header: BridgedHeader
mod tests { mod tests {
use super::*; use super::*;
use crate::mock::{ use crate::mock::{
run_test, test_header, RuntimeOrigin, TestBridgedChain, TestHeader, TestNumber, run_test, test_header, RuntimeEvent as TestEvent, RuntimeOrigin, System, TestBridgedChain,
TestRuntime, MAX_BRIDGED_AUTHORITIES, TestHeader, TestNumber, TestRuntime, MAX_BRIDGED_AUTHORITIES,
}; };
use bp_header_chain::BridgeGrandpaCall; use bp_header_chain::BridgeGrandpaCall;
use bp_runtime::BasicOperatingMode; use bp_runtime::BasicOperatingMode;
@@ -649,10 +665,14 @@ mod tests {
assert_err, assert_noop, assert_ok, dispatch::PostDispatchInfo, assert_err, assert_noop, assert_ok, dispatch::PostDispatchInfo,
storage::generator::StorageValue, storage::generator::StorageValue,
}; };
use frame_system::{EventRecord, Phase};
use sp_core::Get; use sp_core::Get;
use sp_runtime::{Digest, DigestItem, DispatchError}; use sp_runtime::{Digest, DigestItem, DispatchError};
fn initialize_substrate_bridge() { fn initialize_substrate_bridge() {
System::set_block_number(1);
System::reset_events();
assert_ok!(init_with_origin(RuntimeOrigin::root())); assert_ok!(init_with_origin(RuntimeOrigin::root()));
} }
@@ -847,6 +867,18 @@ mod tests {
let header = test_header(1); let header = test_header(1);
assert_eq!(<BestFinalized<TestRuntime>>::get().unwrap().1, header.hash()); assert_eq!(<BestFinalized<TestRuntime>>::get().unwrap().1, header.hash());
assert!(<ImportedHeaders<TestRuntime>>::contains_key(header.hash())); assert!(<ImportedHeaders<TestRuntime>>::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![],
}],
);
}) })
} }
+3 -2
View File
@@ -49,7 +49,7 @@ construct_runtime! {
UncheckedExtrinsic = UncheckedExtrinsic, UncheckedExtrinsic = UncheckedExtrinsic,
{ {
System: frame_system::{Pallet, Call, Config, Storage, Event<T>}, System: frame_system::{Pallet, Call, Config, Storage, Event<T>},
Grandpa: grandpa::{Pallet, Call}, Grandpa: grandpa::{Pallet, Call, Event<T>},
} }
} }
@@ -69,7 +69,7 @@ impl frame_system::Config for TestRuntime {
type AccountId = AccountId; type AccountId = AccountId;
type Lookup = IdentityLookup<Self::AccountId>; type Lookup = IdentityLookup<Self::AccountId>;
type Header = Header; type Header = Header;
type RuntimeEvent = (); type RuntimeEvent = RuntimeEvent;
type BlockHashCount = ConstU64<250>; type BlockHashCount = ConstU64<250>;
type Version = (); type Version = ();
type PalletInfo = PalletInfo; type PalletInfo = PalletInfo;
@@ -94,6 +94,7 @@ parameter_types! {
} }
impl grandpa::Config for TestRuntime { impl grandpa::Config for TestRuntime {
type RuntimeEvent = RuntimeEvent;
type BridgedChain = TestBridgedChain; type BridgedChain = TestBridgedChain;
type MaxRequests = MaxRequests; type MaxRequests = MaxRequests;
type HeadersToKeep = HeadersToKeep; type HeadersToKeep = HeadersToKeep;
+60 -12
View File
@@ -735,14 +735,18 @@ mod tests {
}, },
) )
.unwrap(); .unwrap();
System::<TestRuntime>::set_block_number(1);
System::<TestRuntime>::reset_events();
} }
fn proceed(num: RelayBlockNumber, state_root: RelayBlockHash) { fn proceed(num: RelayBlockNumber, state_root: RelayBlockHash) -> ParaHash {
pallet_bridge_grandpa::Pallet::<TestRuntime, BridgesGrandpaPalletInstance>::on_initialize( pallet_bridge_grandpa::Pallet::<TestRuntime, BridgesGrandpaPalletInstance>::on_initialize(
0, 0,
); );
let header = test_relay_header(num, state_root); let header = test_relay_header(num, state_root);
let hash = header.hash();
let justification = make_default_justification(&header); let justification = make_default_justification(&header);
assert_ok!( assert_ok!(
pallet_bridge_grandpa::Pallet::<TestRuntime, BridgesGrandpaPalletInstance>::submit_finality_proof( pallet_bridge_grandpa::Pallet::<TestRuntime, BridgesGrandpaPalletInstance>::submit_finality_proof(
@@ -751,6 +755,8 @@ mod tests {
justification, justification,
) )
); );
hash
} }
fn prepare_parachain_heads_proof( fn prepare_parachain_heads_proof(
@@ -1010,7 +1016,7 @@ mod tests {
); );
// import head#10 of parachain#1 at relay block #1 // 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_ok!(import_parachain_1_head(1, state_root_10, parachains_10, proof_10));
assert_eq!( assert_eq!(
ParasInfo::<TestRuntime>::get(ParaId(1)), ParasInfo::<TestRuntime>::get(ParaId(1)),
@@ -1043,6 +1049,16 @@ mod tests {
}), }),
topics: vec![], topics: vec![],
}, },
EventRecord {
phase: Phase::Initialization,
event: TestEvent::Grandpa1(
pallet_bridge_grandpa::Event::UpdatedBestFinalizedHeader {
number: 1,
hash: relay_1_hash,
}
),
topics: vec![],
},
EventRecord { EventRecord {
phase: Phase::Initialization, phase: Phase::Initialization,
event: TestEvent::Parachains(Event::UpdatedParachainHead { event: TestEvent::Parachains(Event::UpdatedParachainHead {
@@ -1155,7 +1171,7 @@ mod tests {
// try to import head#0 of parachain#1 at relay block#1 // try to import head#0 of parachain#1 at relay block#1
// => call succeeds, but nothing is changed // => 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_ok!(import_parachain_1_head(1, state_root, parachains, proof));
assert_eq!(ParasInfo::<TestRuntime>::get(ParaId(1)), Some(initial_best_head(1))); assert_eq!(ParasInfo::<TestRuntime>::get(ParaId(1)), Some(initial_best_head(1)));
assert_eq!( assert_eq!(
@@ -1169,6 +1185,16 @@ mod tests {
}), }),
topics: vec![], topics: vec![],
}, },
EventRecord {
phase: Phase::Initialization,
event: TestEvent::Grandpa1(
pallet_bridge_grandpa::Event::UpdatedBestFinalizedHeader {
number: 1,
hash: relay_1_hash,
}
),
topics: vec![],
},
EventRecord { EventRecord {
phase: Phase::Initialization, phase: Phase::Initialization,
event: TestEvent::Parachains(Event::RejectedObsoleteParachainHead { event: TestEvent::Parachains(Event::RejectedObsoleteParachainHead {
@@ -1193,7 +1219,7 @@ mod tests {
initialize(state_root_5); initialize(state_root_5);
// head#10 of parachain#1 at relay block#1 // 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_ok!(import_parachain_1_head(1, state_root_10, parachains_10, proof_10));
assert_eq!( assert_eq!(
ParasInfo::<TestRuntime>::get(ParaId(1)), ParasInfo::<TestRuntime>::get(ParaId(1)),
@@ -1207,14 +1233,26 @@ mod tests {
); );
assert_eq!( assert_eq!(
System::<TestRuntime>::events(), System::<TestRuntime>::events(),
vec![EventRecord { vec![
phase: Phase::Initialization, EventRecord {
event: TestEvent::Parachains(Event::UpdatedParachainHead { phase: Phase::Initialization,
parachain: ParaId(1), event: TestEvent::Grandpa1(
parachain_head_hash: head_data(1, 10).hash(), pallet_bridge_grandpa::Event::UpdatedBestFinalizedHeader {
}), number: 1,
topics: vec![], 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 // now try to import head#5 at relay block#0
@@ -1233,6 +1271,16 @@ mod tests {
assert_eq!( assert_eq!(
System::<TestRuntime>::events(), System::<TestRuntime>::events(),
vec![ vec![
EventRecord {
phase: Phase::Initialization,
event: TestEvent::Grandpa1(
pallet_bridge_grandpa::Event::UpdatedBestFinalizedHeader {
number: 1,
hash: relay_1_hash,
}
),
topics: vec![],
},
EventRecord { EventRecord {
phase: Phase::Initialization, phase: Phase::Initialization,
event: TestEvent::Parachains(Event::UpdatedParachainHead { event: TestEvent::Parachains(Event::UpdatedParachainHead {
+4 -2
View File
@@ -150,8 +150,8 @@ construct_runtime! {
UncheckedExtrinsic = UncheckedExtrinsic, UncheckedExtrinsic = UncheckedExtrinsic,
{ {
System: frame_system::{Pallet, Call, Config, Storage, Event<T>}, System: frame_system::{Pallet, Call, Config, Storage, Event<T>},
Grandpa1: pallet_bridge_grandpa::<Instance1>::{Pallet}, Grandpa1: pallet_bridge_grandpa::<Instance1>::{Pallet, Event<T>},
Grandpa2: pallet_bridge_grandpa::<Instance2>::{Pallet}, Grandpa2: pallet_bridge_grandpa::<Instance2>::{Pallet, Event<T>},
Parachains: pallet_bridge_parachains::{Call, Pallet, Event<T>}, Parachains: pallet_bridge_parachains::{Call, Pallet, Event<T>},
} }
} }
@@ -197,6 +197,7 @@ parameter_types! {
} }
impl pallet_bridge_grandpa::Config<pallet_bridge_grandpa::Instance1> for TestRuntime { impl pallet_bridge_grandpa::Config<pallet_bridge_grandpa::Instance1> for TestRuntime {
type RuntimeEvent = RuntimeEvent;
type BridgedChain = TestBridgedChain; type BridgedChain = TestBridgedChain;
type MaxRequests = ConstU32<2>; type MaxRequests = ConstU32<2>;
type HeadersToKeep = HeadersToKeep; type HeadersToKeep = HeadersToKeep;
@@ -204,6 +205,7 @@ impl pallet_bridge_grandpa::Config<pallet_bridge_grandpa::Instance1> for TestRun
} }
impl pallet_bridge_grandpa::Config<pallet_bridge_grandpa::Instance2> for TestRuntime { impl pallet_bridge_grandpa::Config<pallet_bridge_grandpa::Instance2> for TestRuntime {
type RuntimeEvent = RuntimeEvent;
type BridgedChain = TestBridgedChain; type BridgedChain = TestBridgedChain;
type MaxRequests = ConstU32<2>; type MaxRequests = ConstU32<2>;
type HeadersToKeep = HeadersToKeep; type HeadersToKeep = HeadersToKeep;