Skip to content

Commit

Permalink
Grandpa: Store the authority set changes (paritytech#2336) (paritytec…
Browse files Browse the repository at this point in the history
…h#2337)

* Grandpa: Store the authority set changes
  • Loading branch information
serban300 committed Apr 8, 2024
1 parent 8ab5e10 commit 2e1a607
Show file tree
Hide file tree
Showing 17 changed files with 128 additions and 69 deletions.
12 changes: 6 additions & 6 deletions bridges/bin/millau/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -883,9 +883,9 @@ impl_runtime_apis! {
BridgeRialtoGrandpa::best_finalized()
}

fn accepted_grandpa_finality_proofs(
) -> Vec<bp_header_chain::justification::GrandpaJustification<bp_rialto::Header>> {
BridgeRialtoGrandpa::accepted_finality_proofs()
fn synced_headers_grandpa_info(
) -> Vec<bp_header_chain::HeaderGrandpaInfo<bp_rialto::Header>> {
BridgeRialtoGrandpa::synced_headers_grandpa_info()
}
}

Expand All @@ -894,9 +894,9 @@ impl_runtime_apis! {
BridgeWestendGrandpa::best_finalized()
}

fn accepted_grandpa_finality_proofs(
) -> Vec<bp_header_chain::justification::GrandpaJustification<bp_westend::Header>> {
BridgeWestendGrandpa::accepted_finality_proofs()
fn synced_headers_grandpa_info(
) -> Vec<bp_header_chain::HeaderGrandpaInfo<bp_westend::Header>> {
BridgeWestendGrandpa::synced_headers_grandpa_info()
}
}

Expand Down
6 changes: 3 additions & 3 deletions bridges/bin/rialto-parachain/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -747,9 +747,9 @@ impl_runtime_apis! {
BridgeMillauGrandpa::best_finalized()
}

fn accepted_grandpa_finality_proofs(
) -> Vec<bp_header_chain::justification::GrandpaJustification<bp_millau::Header>> {
BridgeMillauGrandpa::accepted_finality_proofs()
fn synced_headers_grandpa_info(
) -> Vec<bp_header_chain::HeaderGrandpaInfo<bp_millau::Header>> {
BridgeMillauGrandpa::synced_headers_grandpa_info()
}
}

Expand Down
6 changes: 3 additions & 3 deletions bridges/bin/rialto/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -695,9 +695,9 @@ impl_runtime_apis! {
BridgeMillauGrandpa::best_finalized()
}

fn accepted_grandpa_finality_proofs(
) -> Vec<bp_header_chain::justification::GrandpaJustification<bp_millau::Header>> {
BridgeMillauGrandpa::accepted_finality_proofs()
fn synced_headers_grandpa_info(
) -> Vec<bp_header_chain::HeaderGrandpaInfo<bp_millau::Header>> {
BridgeMillauGrandpa::synced_headers_grandpa_info()
}
}

Expand Down
75 changes: 56 additions & 19 deletions bridges/modules/grandpa/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@
pub use storage_types::StoredAuthoritySet;

use bp_header_chain::{
justification::GrandpaJustification, ChainWithGrandpa, GrandpaConsensusLogReader, HeaderChain,
InitializationData, StoredHeaderData, StoredHeaderDataBuilder,
justification::GrandpaJustification, AuthoritySet, ChainWithGrandpa, GrandpaConsensusLogReader,
HeaderChain, HeaderGrandpaInfo, InitializationData, StoredHeaderData, StoredHeaderDataBuilder,
};
use bp_runtime::{BlockNumberOf, HashOf, HasherOf, HeaderId, HeaderOf, OwnedBridgeModule};
use finality_grandpa::voter_set::VoterSet;
Expand Down Expand Up @@ -194,11 +194,12 @@ pub mod pallet {
let authority_set = <CurrentAuthoritySet<T, I>>::get();
let unused_proof_size = authority_set.unused_proof_size();
let set_id = authority_set.set_id;
verify_justification::<T, I>(&justification, hash, number, authority_set.into())?;
let authority_set: AuthoritySet = authority_set.into();
verify_justification::<T, I>(&justification, hash, number, authority_set)?;

let is_authorities_change_enacted =
let maybe_new_authority_set =
try_enact_authority_change::<T, I>(&finality_target, set_id)?;
let may_refund_call_fee = is_authorities_change_enacted &&
let may_refund_call_fee = maybe_new_authority_set.is_some() &&
// if we have seen too many mandatory headers in this block, we don't want to refund
Self::free_mandatory_headers_remaining() > 0 &&
// if arguments out of expected bounds, we don't want to refund
Expand Down Expand Up @@ -237,7 +238,14 @@ 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, justification });
Self::deposit_event(Event::UpdatedBestFinalizedHeader {
number,
hash,
grandpa_info: HeaderGrandpaInfo {
justification,
authority_set: maybe_new_authority_set,
},
});

Ok(PostDispatchInfo { actual_weight: Some(actual_weight), pays_fee })
}
Expand Down Expand Up @@ -402,8 +410,8 @@ pub mod pallet {
UpdatedBestFinalizedHeader {
number: BridgedBlockNumber<T, I>,
hash: BridgedBlockHash<T, I>,
/// Justification.
justification: GrandpaJustification<BridgedHeader<T, I>>,
/// The Grandpa info associated to the new best finalized header.
grandpa_info: HeaderGrandpaInfo<BridgedHeader<T, I>>,
},
}

Expand Down Expand Up @@ -439,9 +447,7 @@ pub mod pallet {
pub(crate) fn try_enact_authority_change<T: Config<I>, I: 'static>(
header: &BridgedHeader<T, I>,
current_set_id: sp_consensus_grandpa::SetId,
) -> Result<bool, sp_runtime::DispatchError> {
let mut change_enacted = false;

) -> Result<Option<AuthoritySet>, DispatchError> {
// We don't support forced changes - at that point governance intervention is required.
ensure!(
GrandpaConsensusLogReader::<BridgedBlockNumber<T, I>>::find_forced_change(
Expand Down Expand Up @@ -470,7 +476,6 @@ pub mod pallet {
// Since our header schedules a change and we know the delay is 0, it must also enact
// the change.
<CurrentAuthoritySet<T, I>>::put(&next_authorities);
change_enacted = true;

log::info!(
target: LOG_TARGET,
Expand All @@ -479,9 +484,11 @@ pub mod pallet {
current_set_id + 1,
next_authorities,
);

return Ok(Some(next_authorities.into()))
};

Ok(change_enacted)
Ok(None)
}

/// Verify a GRANDPA justification (finality proof) for a given header.
Expand Down Expand Up @@ -610,13 +617,13 @@ where
<T as frame_system::Config>::RuntimeEvent: TryInto<Event<T, I>>,
{
/// Get the GRANDPA justifications accepted in the current block.
pub fn accepted_finality_proofs() -> Vec<GrandpaJustification<BridgedHeader<T, I>>> {
pub fn synced_headers_grandpa_info() -> Vec<HeaderGrandpaInfo<BridgedHeader<T, I>>> {
frame_system::Pallet::<T>::read_events_no_consensus()
.filter_map(|event| {
if let Event::<T, I>::UpdatedBestFinalizedHeader { justification, .. } =
if let Event::<T, I>::UpdatedBestFinalizedHeader { grandpa_info, .. } =
event.event.try_into().ok()?
{
return Some(justification)
return Some(grandpa_info)
}
None
})
Expand Down Expand Up @@ -927,12 +934,18 @@ mod tests {
event: TestEvent::Grandpa(Event::UpdatedBestFinalizedHeader {
number: *header.number(),
hash: header.hash(),
justification: justification.clone(),
grandpa_info: HeaderGrandpaInfo {
justification: justification.clone(),
authority_set: None,
},
}),
topics: vec![],
}],
);
assert_eq!(Pallet::<TestRuntime>::accepted_finality_proofs(), vec![justification]);
assert_eq!(
Pallet::<TestRuntime>::synced_headers_grandpa_info(),
vec![HeaderGrandpaInfo { justification, authority_set: None }]
);
})
}

Expand Down Expand Up @@ -1038,7 +1051,7 @@ mod tests {
let result = Pallet::<TestRuntime>::submit_finality_proof(
RuntimeOrigin::signed(1),
Box::new(header.clone()),
justification,
justification.clone(),
);
assert_ok!(result);
assert_eq!(result.unwrap().pays_fee, frame_support::dispatch::Pays::No);
Expand All @@ -1053,6 +1066,30 @@ mod tests {
StoredAuthoritySet::<TestRuntime, ()>::try_new(next_authorities, next_set_id)
.unwrap(),
);

// Here
assert_eq!(
System::events(),
vec![EventRecord {
phase: Phase::Initialization,
event: TestEvent::Grandpa(Event::UpdatedBestFinalizedHeader {
number: *header.number(),
hash: header.hash(),
grandpa_info: HeaderGrandpaInfo {
justification: justification.clone(),
authority_set: Some(<CurrentAuthoritySet<TestRuntime>>::get().into()),
},
}),
topics: vec![],
}],
);
assert_eq!(
Pallet::<TestRuntime>::synced_headers_grandpa_info(),
vec![HeaderGrandpaInfo {
justification,
authority_set: Some(<CurrentAuthoritySet<TestRuntime>>::get().into()),
}]
);
})
}

Expand Down
4 changes: 2 additions & 2 deletions bridges/modules/grandpa/src/storage_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use crate::{Config, Error};

use bp_header_chain::{AuthoritySet, ChainWithGrandpa};
use codec::{Decode, Encode, MaxEncodedLen};
use frame_support::{traits::Get, BoundedVec, RuntimeDebugNoBound};
use frame_support::{traits::Get, BoundedVec, CloneNoBound, RuntimeDebugNoBound};
use scale_info::TypeInfo;
use sp_consensus_grandpa::{AuthorityId, AuthorityList, AuthorityWeight, SetId};
use sp_std::marker::PhantomData;
Expand All @@ -39,7 +39,7 @@ impl<T: Config<I>, I: 'static> Get<u32> for StoredAuthorityListLimit<T, I> {
}

/// A bounded GRANDPA Authority List and ID.
#[derive(Clone, Decode, Encode, Eq, TypeInfo, MaxEncodedLen, RuntimeDebugNoBound)]
#[derive(CloneNoBound, Decode, Encode, Eq, TypeInfo, MaxEncodedLen, RuntimeDebugNoBound)]
#[scale_info(skip_type_params(T, I))]
pub struct StoredAuthoritySet<T: Config<I>, I: 'static> {
/// List of GRANDPA authorities for the current round.
Expand Down
22 changes: 17 additions & 5 deletions bridges/modules/parachains/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -697,7 +697,7 @@ pub(crate) mod tests {
use bp_test_utils::prepare_parachain_heads_proof;
use codec::Encode;

use bp_header_chain::justification::GrandpaJustification;
use bp_header_chain::{justification::GrandpaJustification, HeaderGrandpaInfo};
use bp_parachains::{
BestParaHeadHash, BridgeParachainCall, ImportedParaHeadsKeyProvider, ParasInfoKeyProvider,
};
Expand Down Expand Up @@ -1036,7 +1036,10 @@ pub(crate) mod tests {
pallet_bridge_grandpa::Event::UpdatedBestFinalizedHeader {
number: 1,
hash: relay_1_hash,
justification
grandpa_info: HeaderGrandpaInfo {
justification,
authority_set: None,
},
}
),
topics: vec![],
Expand Down Expand Up @@ -1174,7 +1177,10 @@ pub(crate) mod tests {
pallet_bridge_grandpa::Event::UpdatedBestFinalizedHeader {
number: 1,
hash: relay_1_hash,
justification
grandpa_info: HeaderGrandpaInfo {
justification,
authority_set: None,
}
}
),
topics: vec![],
Expand Down Expand Up @@ -1224,7 +1230,10 @@ pub(crate) mod tests {
pallet_bridge_grandpa::Event::UpdatedBestFinalizedHeader {
number: 1,
hash: relay_1_hash,
justification: justification.clone()
grandpa_info: HeaderGrandpaInfo {
justification: justification.clone(),
authority_set: None,
}
}
),
topics: vec![],
Expand Down Expand Up @@ -1262,7 +1271,10 @@ pub(crate) mod tests {
pallet_bridge_grandpa::Event::UpdatedBestFinalizedHeader {
number: 1,
hash: relay_1_hash,
justification
grandpa_info: HeaderGrandpaInfo {
justification,
authority_set: None,
}
}
),
topics: vec![],
Expand Down
5 changes: 4 additions & 1 deletion bridges/primitives/chain-millau/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ license = "GPL-3.0-or-later WITH Classpath-exception-2.0"

[dependencies]

fixed-hash = { version = "0.8.0", default-features = false }
# TODO: Consume `fixed-hash` from crates.io when the following fix is published:
# https://github.com/paritytech/parity-common/commit/d3a9327124a66e52ca1114bb8640c02c18c134b8
# Expected in a version > 0.8.0
fixed-hash = { git = "https://github.com/paritytech/parity-common", branch = "master", default-features = false }
hash256-std-hasher = { version = "0.15.2", default-features = false }
impl-codec = { version = "0.6", default-features = false }
impl-serde = { version = "0.4.0", default-features = false }
Expand Down
9 changes: 9 additions & 0 deletions bridges/primitives/header-chain/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,15 @@ impl<Number: Codec> ConsensusLogReader for GrandpaConsensusLogReader<Number> {
}
}

/// The Grandpa-related info associated to a header.
#[derive(Encode, Decode, Debug, PartialEq, Clone, TypeInfo)]
pub struct HeaderGrandpaInfo<Header: HeaderT> {
/// The header justification
pub justification: justification::GrandpaJustification<Header>,
/// The authority set introduced by the header.
pub authority_set: Option<AuthoritySet>,
}

/// A minimized version of `pallet-bridge-grandpa::Call` that can be used without a runtime.
#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)]
#[allow(non_camel_case_types)]
Expand Down
8 changes: 4 additions & 4 deletions bridges/primitives/runtime/src/chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -295,8 +295,8 @@ macro_rules! decl_bridge_finality_runtime_apis {
$(
/// Name of the `<ThisChain>FinalityApi::accepted_<consensus>_finality_proofs`
/// runtime method.
pub const [<$chain:upper _ACCEPTED_ $consensus:upper _FINALITY_PROOFS_METHOD>]: &str =
stringify!([<$chain:camel FinalityApi_accepted_ $consensus:lower _finality_proofs>]);
pub const [<$chain:upper _SYNCED_HEADERS_ $consensus:upper _INFO_METHOD>]: &str =
stringify!([<$chain:camel FinalityApi_synced_headers_ $consensus:lower _info>]);
)?

sp_api::decl_runtime_apis! {
Expand All @@ -310,7 +310,7 @@ macro_rules! decl_bridge_finality_runtime_apis {

$(
/// Returns the justifications accepted in the current block.
fn [<accepted_ $consensus:lower _finality_proofs>](
fn [<synced_headers_ $consensus:lower _info>](
) -> Vec<$justification_type>;
)?
}
Expand All @@ -321,7 +321,7 @@ macro_rules! decl_bridge_finality_runtime_apis {
}
};
($chain: ident, grandpa) => {
decl_bridge_finality_runtime_apis!($chain, grandpa => bp_header_chain::justification::GrandpaJustification<Header>);
decl_bridge_finality_runtime_apis!($chain, grandpa => bp_header_chain::HeaderGrandpaInfo<Header>);
};
}

Expand Down
6 changes: 3 additions & 3 deletions bridges/relays/client-kusama/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

//! Types used to connect to the Kusama chain.

use bp_kusama::{AccountInfoStorageMapKeyProvider, KUSAMA_ACCEPTED_GRANDPA_FINALITY_PROOFS_METHOD};
use bp_kusama::{AccountInfoStorageMapKeyProvider, KUSAMA_SYNCED_HEADERS_GRANDPA_INFO_METHOD};
use bp_runtime::ChainId;
use relay_substrate_client::{
Chain, ChainWithBalances, ChainWithGrandpa, RelayChain, UnderlyingChainProvider,
Expand Down Expand Up @@ -50,8 +50,8 @@ impl Chain for Kusama {
}

impl ChainWithGrandpa for Kusama {
const ACCEPTED_FINALITY_PROOFS_METHOD: &'static str =
KUSAMA_ACCEPTED_GRANDPA_FINALITY_PROOFS_METHOD;
const SYNCED_HEADERS_GRANDPA_INFO_METHOD: &'static str =
KUSAMA_SYNCED_HEADERS_GRANDPA_INFO_METHOD;
}

impl ChainWithBalances for Kusama {
Expand Down
6 changes: 3 additions & 3 deletions bridges/relays/client-millau/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
//! Types used to connect to the Millau-Substrate chain.

use bp_messages::MessageNonce;
use bp_millau::MILLAU_ACCEPTED_GRANDPA_FINALITY_PROOFS_METHOD;
use bp_millau::MILLAU_SYNCED_HEADERS_GRANDPA_INFO_METHOD;
use bp_runtime::ChainId;
use codec::{Compact, Decode, Encode};
use relay_substrate_client::{
Expand Down Expand Up @@ -67,8 +67,8 @@ impl Chain for Millau {
}

impl ChainWithGrandpa for Millau {
const ACCEPTED_FINALITY_PROOFS_METHOD: &'static str =
MILLAU_ACCEPTED_GRANDPA_FINALITY_PROOFS_METHOD;
const SYNCED_HEADERS_GRANDPA_INFO_METHOD: &'static str =
MILLAU_SYNCED_HEADERS_GRANDPA_INFO_METHOD;
}

impl ChainWithBalances for Millau {
Expand Down
Loading

0 comments on commit 2e1a607

Please sign in to comment.