Remove pallet::without_storage_info from bridge GRANDPA pallet (#1478)

* remove pallet::without_storage_info from bridge GRANDPA pallet

* StoredBridgedHeader

* spelling

* fix benchmarks

* MAX_BRIDGED_AUTHORITIES: 256 -> 2048

* Update modules/grandpa/src/storage_types.rs

Co-authored-by: Adrian Catangiu <adrian@parity.io>

* Update modules/grandpa/src/storage_types.rs

Co-authored-by: Adrian Catangiu <adrian@parity.io>

* moved max authorities + header size to chain primitives

* removed unused code

* new -> try_new

* fix benchmarks compilation

Co-authored-by: Adrian Catangiu <adrian@parity.io>
This commit is contained in:
Svyatoslav Nikolsky
2022-10-10 11:32:53 +03:00
committed by Bastian Köcher
parent 6f9bda5db0
commit f38852f661
12 changed files with 349 additions and 66 deletions
+16
View File
@@ -426,11 +426,25 @@ parameter_types! {
pub const HeadersToKeep: u32 = 7 * bp_rialto::DAYS as u32;
}
parameter_types! {
/// Maximal number of authorities at Rialto.
pub const MaxAuthoritiesAtRialto: u32 = bp_rialto::MAX_AUTHORITIES_COUNT;
/// Maximal size of SCALE-encoded Rialto header.
pub const MaxRialtoHeaderSize: u32 = bp_rialto::MAX_HEADER_SIZE;
/// Maximal number of authorities at Westend.
pub const MaxAuthoritiesAtWestend: u32 = bp_westend::MAX_AUTHORITIES_COUNT;
/// Maximal size of SCALE-encoded Westend header.
pub const MaxWestendHeaderSize: u32 = bp_westend::MAX_HEADER_SIZE;
}
pub type RialtoGrandpaInstance = ();
impl pallet_bridge_grandpa::Config for Runtime {
type BridgedChain = bp_rialto::Rialto;
type MaxRequests = MaxRequests;
type HeadersToKeep = HeadersToKeep;
type MaxBridgedAuthorities = MaxAuthoritiesAtRialto;
type MaxBridgedHeaderSize = MaxRialtoHeaderSize;
type WeightInfo = pallet_bridge_grandpa::weights::BridgeWeight<Runtime>;
}
@@ -440,6 +454,8 @@ impl pallet_bridge_grandpa::Config<WestendGrandpaInstance> for Runtime {
type BridgedChain = bp_westend::Westend;
type MaxRequests = MaxRequests;
type HeadersToKeep = HeadersToKeep;
type MaxBridgedAuthorities = MaxAuthoritiesAtWestend;
type MaxBridgedHeaderSize = MaxWestendHeaderSize;
type WeightInfo = pallet_bridge_grandpa::weights::BridgeWeight<Runtime>;
}
@@ -531,6 +531,11 @@ parameter_types! {
/// Assuming the worst case of every header being finalized, we will keep headers at least for a
/// week.
pub const HeadersToKeep: u32 = 7 * bp_millau::DAYS as u32;
/// Maximal number of authorities at Millau.
pub const MaxAuthoritiesAtMillau: u32 = bp_millau::MAX_AUTHORITIES_COUNT;
/// Maximal size of SCALE-encoded Millau header.
pub const MaxMillauHeaderSize: u32 = bp_millau::MAX_HEADER_SIZE;
}
pub type MillauGrandpaInstance = ();
@@ -538,6 +543,8 @@ impl pallet_bridge_grandpa::Config for Runtime {
type BridgedChain = bp_millau::Millau;
type MaxRequests = MaxRequests;
type HeadersToKeep = HeadersToKeep;
type MaxBridgedAuthorities = MaxAuthoritiesAtMillau;
type MaxBridgedHeaderSize = MaxMillauHeaderSize;
type WeightInfo = pallet_bridge_grandpa::weights::BridgeWeight<Runtime>;
}
+7
View File
@@ -417,6 +417,11 @@ parameter_types! {
/// Assuming the worst case of every header being finalized, we will keep headers at least for a
/// week.
pub const HeadersToKeep: u32 = 7 * bp_rialto::DAYS as u32;
/// Maximal number of authorities at Millau.
pub const MaxAuthoritiesAtMillau: u32 = bp_millau::MAX_AUTHORITIES_COUNT;
/// Maximal size of SCALE-encoded Millau header.
pub const MaxMillauHeaderSize: u32 = bp_millau::MAX_HEADER_SIZE;
}
pub type MillauGrandpaInstance = ();
@@ -424,6 +429,8 @@ impl pallet_bridge_grandpa::Config for Runtime {
type BridgedChain = bp_millau::Millau;
type MaxRequests = MaxRequests;
type HeadersToKeep = HeadersToKeep;
type MaxBridgedAuthorities = MaxAuthoritiesAtMillau;
type MaxBridgedHeaderSize = MaxMillauHeaderSize;
type WeightInfo = pallet_bridge_grandpa::weights::BridgeWeight<Runtime>;
}
+165 -20
View File
@@ -36,6 +36,8 @@
// Runtime-generated enums
#![allow(clippy::large_enum_variant)]
use storage_types::{StoredAuthoritySet, StoredBridgedHeader};
use bp_header_chain::{justification::GrandpaJustification, InitializationData};
use bp_runtime::{BlockNumberOf, Chain, HashOf, HasherOf, HeaderOf, OwnedBridgeModule};
use finality_grandpa::voter_set::VoterSet;
@@ -48,6 +50,7 @@ use sp_std::{boxed::Box, convert::TryInto};
mod extension;
#[cfg(test)]
mod mock;
mod storage_types;
/// Module, containing weights for this pallet.
pub mod weights;
@@ -102,12 +105,24 @@ pub mod pallet {
#[pallet::constant]
type HeadersToKeep: Get<u32>;
/// Max number of authorities at the bridged chain.
#[pallet::constant]
type MaxBridgedAuthorities: Get<u32>;
/// Maximal size (in bytes) of the SCALE-encoded bridged chain header.
///
/// This constant must be selected with care. The pallet requires mandatory headers to be
/// submitted to be able to proceed. Mandatory headers contain public keys of all GRANDPA
/// authorities. E.g. for 1024 authorities, the size of encoded keys will be at least 32 KB.
/// The same header may also contain other digest items as well, so some reserve here
/// is required.
#[pallet::constant]
type MaxBridgedHeaderSize: Get<u32>;
/// Weights gathered through benchmarking.
type WeightInfo: WeightInfo;
}
#[pallet::pallet]
#[pallet::without_storage_info]
pub struct Pallet<T, I = ()>(PhantomData<(T, I)>);
#[pallet::hooks]
@@ -180,12 +195,14 @@ pub mod pallet {
let authority_set = <CurrentAuthoritySet<T, I>>::get();
let set_id = authority_set.set_id;
verify_justification::<T, I>(&justification, hash, *number, authority_set)?;
verify_justification::<T, I>(&justification, hash, *number, authority_set.into())?;
let is_authorities_change_enacted =
try_enact_authority_change::<T, I>(&finality_target, set_id)?;
let finality_target =
StoredBridgedHeader::<T, I>::try_from_bridged_header(*finality_target)?;
<RequestCount<T, I>>::mutate(|count| *count += 1);
insert_header::<T, I>(*finality_target, hash);
insert_header::<T, I>(finality_target, hash);
log::info!(
target: LOG_TARGET,
"Successfully imported finalized header with hash {:?}!",
@@ -221,7 +238,7 @@ pub mod pallet {
let init_allowed = !<BestFinalized<T, I>>::exists();
ensure!(init_allowed, <Error<T, I>>::AlreadyInitialized);
initialize_bridge::<T, I>(init_data.clone());
initialize_bridge::<T, I>(init_data.clone())?;
log::info!(
target: LOG_TARGET,
@@ -286,12 +303,12 @@ pub mod pallet {
/// Headers which have been imported into the pallet.
#[pallet::storage]
pub type ImportedHeaders<T: Config<I>, I: 'static = ()> =
StorageMap<_, Identity, BridgedBlockHash<T, I>, BridgedHeader<T, I>>;
StorageMap<_, Identity, BridgedBlockHash<T, I>, StoredBridgedHeader<T, I>>;
/// The current GRANDPA Authority set.
#[pallet::storage]
pub(super) type CurrentAuthoritySet<T: Config<I>, I: 'static = ()> =
StorageValue<_, bp_header_chain::AuthoritySet, ValueQuery>;
StorageValue<_, StoredAuthoritySet<T, I>, ValueQuery>;
/// Optional pallet owner.
///
@@ -333,7 +350,7 @@ pub mod pallet {
}
if let Some(init_data) = self.init_data.clone() {
initialize_bridge::<T, I>(init_data);
initialize_bridge::<T, I>(init_data).expect("genesis config is correct; qed");
} else {
// Since the bridge hasn't been initialized we shouldn't allow anyone to perform
// transactions.
@@ -364,6 +381,10 @@ pub mod pallet {
AlreadyInitialized,
/// The storage proof doesn't contains storage root. So it is invalid for given header.
StorageRootMismatch,
/// Too many authorities in the set.
TooManyAuthoritiesInSet,
/// Too large header.
TooLargeHeader,
/// Error generated by the `OwnedBridgeModule` trait.
BridgeModule(bp_runtime::OwnedBridgeModuleError),
}
@@ -392,8 +413,11 @@ pub mod pallet {
ensure!(change.delay == Zero::zero(), <Error<T, I>>::UnsupportedScheduledChange);
// TODO [#788]: Stop manually increasing the `set_id` here.
let next_authorities = bp_header_chain::AuthoritySet {
authorities: change.next_authorities,
let next_authorities = StoredAuthoritySet::<T, I> {
authorities: change
.next_authorities
.try_into()
.map_err(|_| Error::<T, I>::TooManyAuthoritiesInSet)?,
set_id: current_set_id + 1,
};
@@ -454,7 +478,7 @@ pub mod pallet {
/// Note this function solely takes care of updating the storage and pruning old entries,
/// but does not verify the validity of such import.
pub(crate) fn insert_header<T: Config<I>, I: 'static>(
header: BridgedHeader<T, I>,
header: StoredBridgedHeader<T, I>,
hash: BridgedBlockHash<T, I>,
) {
let index = <ImportedHashesPointer<T, I>>::get();
@@ -475,19 +499,23 @@ pub mod pallet {
/// were called by a trusted origin.
pub(crate) fn initialize_bridge<T: Config<I>, I: 'static>(
init_params: super::InitializationData<BridgedHeader<T, I>>,
) {
) -> Result<(), Error<T, I>> {
let super::InitializationData { header, authority_list, set_id, operating_mode } =
init_params;
let authority_set = StoredAuthoritySet::<T, I>::try_new(authority_list, set_id)
.map_err(|_| Error::TooManyAuthoritiesInSet)?;
let header = StoredBridgedHeader::<T, I>::try_from_bridged_header(*header)?;
let initial_hash = header.hash();
<InitialHash<T, I>>::put(initial_hash);
<ImportedHashesPointer<T, I>>::put(0);
insert_header::<T, I>(*header, initial_hash);
insert_header::<T, I>(header, initial_hash);
let authority_set = bp_header_chain::AuthoritySet::new(authority_list, set_id);
<CurrentAuthoritySet<T, I>>::put(authority_set);
<PalletOperatingMode<T, I>>::put(operating_mode);
Ok(())
}
#[cfg(feature = "runtime-benchmarks")]
@@ -496,7 +524,7 @@ pub mod pallet {
) {
let start_number = *init_params.header.number();
let end_number = start_number + T::HeadersToKeep::get().into();
initialize_bridge::<T, I>(init_params);
initialize_bridge::<T, I>(init_params).expect("benchmarks are correct");
let mut number = start_number;
while number < end_number {
@@ -509,7 +537,11 @@ pub mod pallet {
Default::default(),
);
let hash = header.hash();
insert_header::<T, I>(header, hash);
insert_header::<T, I>(
StoredBridgedHeader::try_from_bridged_header(header)
.expect("only used from benchmarks; benchmarks are correct; qed"),
hash,
);
}
}
}
@@ -521,7 +553,7 @@ impl<T: Config<I>, I: 'static> Pallet<T, I> {
/// if the pallet has not been initialized yet.
pub fn best_finalized() -> Option<BridgedHeader<T, I>> {
let (_, hash) = <BestFinalized<T, I>>::get()?;
<ImportedHeaders<T, I>>::get(hash)
<ImportedHeaders<T, I>>::get(hash).map(|h| h.0)
}
/// Check if a particular header is known to the bridge pallet.
@@ -591,13 +623,17 @@ pub fn initialize_for_benchmarks<T: Config<I>, I: 'static>(header: BridgedHeader
* benchmarks */
set_id: 0,
operating_mode: bp_runtime::BasicOperatingMode::Normal,
});
})
.expect("only used from benchmarks; benchmarks are correct; qed");
}
#[cfg(test)]
mod tests {
use super::*;
use crate::mock::{run_test, test_header, Origin, TestHeader, TestNumber, TestRuntime};
use crate::mock::{
run_test, test_header, Origin, TestHeader, TestNumber, TestRuntime,
MAX_BRIDGED_AUTHORITIES, MAX_HEADER_SIZE,
};
use bp_runtime::BasicOperatingMode;
use bp_test_utils::{
authority_list, generate_owned_bridge_module_tests, make_default_justification,
@@ -673,6 +709,22 @@ mod tests {
Digest { logs: vec![DigestItem::Consensus(GRANDPA_ENGINE_ID, consensus_log.encode())] }
}
fn many_authorities_log() -> Digest {
let consensus_log =
ConsensusLog::<TestNumber>::ScheduledChange(sp_finality_grandpa::ScheduledChange {
next_authorities: std::iter::repeat((ALICE.into(), 1))
.take(MAX_BRIDGED_AUTHORITIES as usize + 1)
.collect(),
delay: 0,
});
Digest { logs: vec![DigestItem::Consensus(GRANDPA_ENGINE_ID, consensus_log.encode())] }
}
fn large_digest() -> Digest {
Digest { logs: vec![DigestItem::Other(vec![42; MAX_HEADER_SIZE as _])] }
}
#[test]
fn init_root_or_owner_origin_can_initialize_pallet() {
run_test(|| {
@@ -715,6 +767,45 @@ mod tests {
})
}
#[test]
fn init_fails_if_there_are_too_many_authorities_in_the_set() {
run_test(|| {
let genesis = test_header(0);
let init_data = InitializationData {
header: Box::new(genesis),
authority_list: std::iter::repeat(authority_list().remove(0))
.take(MAX_BRIDGED_AUTHORITIES as usize + 1)
.collect(),
set_id: 1,
operating_mode: BasicOperatingMode::Normal,
};
assert_noop!(
Pallet::<TestRuntime>::initialize(Origin::root(), init_data),
Error::<TestRuntime>::TooManyAuthoritiesInSet,
);
});
}
#[test]
fn init_fails_if_header_is_too_large() {
run_test(|| {
let mut genesis = test_header(0);
genesis.digest = large_digest();
let init_data = InitializationData {
header: Box::new(genesis),
authority_list: authority_list(),
set_id: 1,
operating_mode: BasicOperatingMode::Normal,
};
assert_noop!(
Pallet::<TestRuntime>::initialize(Origin::root(), init_data),
Error::<TestRuntime>::TooLargeHeader,
);
});
}
#[test]
fn pallet_rejects_transactions_if_halted() {
run_test(|| {
@@ -880,7 +971,8 @@ mod tests {
// Make sure that the authority set actually changed upon importing our header
assert_eq!(
<CurrentAuthoritySet<TestRuntime>>::get(),
bp_header_chain::AuthoritySet::new(next_authorities, next_set_id),
StoredAuthoritySet::<TestRuntime, ()>::try_new(next_authorities, next_set_id)
.unwrap(),
);
})
}
@@ -935,6 +1027,56 @@ mod tests {
})
}
#[test]
fn importing_header_rejects_header_with_too_many_authorities() {
run_test(|| {
initialize_substrate_bridge();
// Need to update the header digest to indicate that our header signals an authority set
// change. However, the change doesn't happen until the next block.
let mut header = test_header(2);
header.digest = many_authorities_log();
// Create a valid justification for the header
let justification = make_default_justification(&header);
// Should not be allowed to import this header
assert_err!(
Pallet::<TestRuntime>::submit_finality_proof(
Origin::signed(1),
Box::new(header),
justification
),
<Error<TestRuntime>>::TooManyAuthoritiesInSet
);
});
}
#[test]
fn importing_header_rejects_header_if_it_is_too_large() {
run_test(|| {
initialize_substrate_bridge();
// Need to update the header digest to indicate that our header signals an authority set
// change. However, the change doesn't happen until the next block.
let mut header = test_header(2);
header.digest = large_digest();
// Create a valid justification for the header
let justification = make_default_justification(&header);
// Should not be allowed to import this header
assert_err!(
Pallet::<TestRuntime>::submit_finality_proof(
Origin::signed(1),
Box::new(header),
justification
),
<Error<TestRuntime>>::TooLargeHeader
);
});
}
#[test]
fn parse_finalized_storage_proof_rejects_proof_on_unknown_header() {
run_test(|| {
@@ -959,7 +1101,10 @@ mod tests {
let hash = header.hash();
<BestFinalized<TestRuntime>>::put((2, hash));
<ImportedHeaders<TestRuntime>>::insert(hash, header);
<ImportedHeaders<TestRuntime>>::insert(
hash,
StoredBridgedHeader::try_from_bridged_header(header).unwrap(),
);
assert_ok!(
Pallet::<TestRuntime>::parse_finalized_storage_proof(hash, storage_proof, |_| (),),
+5
View File
@@ -33,6 +33,9 @@ pub type TestNumber = crate::BridgedBlockNumber<TestRuntime, ()>;
type Block = frame_system::mocking::MockBlock<TestRuntime>;
type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic<TestRuntime>;
pub const MAX_BRIDGED_AUTHORITIES: u32 = 2048;
pub const MAX_HEADER_SIZE: u32 = 65536;
use crate as grandpa;
construct_runtime! {
@@ -91,6 +94,8 @@ impl grandpa::Config for TestRuntime {
type BridgedChain = TestBridgedChain;
type MaxRequests = MaxRequests;
type HeadersToKeep = HeadersToKeep;
type MaxBridgedAuthorities = frame_support::traits::ConstU32<MAX_BRIDGED_AUTHORITIES>;
type MaxBridgedHeaderSize = frame_support::traits::ConstU32<MAX_HEADER_SIZE>;
type WeightInfo = ();
}
@@ -0,0 +1,106 @@
// Copyright 2022 Parity Technologies (UK) Ltd.
// This file is part of Parity Bridges Common.
// Parity Bridges Common is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity Bridges Common is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity Bridges Common. If not, see <http://www.gnu.org/licenses/>.
//! Wrappers for public types that are implementing `MaxEncodedLen`
use crate::{BridgedHeader, Config, Error};
use bp_header_chain::AuthoritySet;
use codec::{Decode, Encode, MaxEncodedLen};
use frame_support::{traits::Get, BoundedVec, RuntimeDebugNoBound};
use scale_info::{Type, TypeInfo};
use sp_finality_grandpa::{AuthorityId, AuthorityList, AuthorityWeight, SetId};
/// A bounded list of Grandpa authorities with associated weights.
pub type StoredAuthorityList<MaxBridgedAuthorities> =
BoundedVec<(AuthorityId, AuthorityWeight), MaxBridgedAuthorities>;
/// A bounded GRANDPA Authority List and ID.
#[derive(Clone, 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.
pub authorities: StoredAuthorityList<<T as Config<I>>::MaxBridgedAuthorities>,
/// Monotonic identifier of the current GRANDPA authority set.
pub set_id: SetId,
}
impl<T: Config<I>, I: 'static> StoredAuthoritySet<T, I> {
/// Try to create a new bounded GRANDPA Authority Set from unbounded list.
///
/// Returns error if number of authorities in the provided list is too large.
pub fn try_new(authorities: AuthorityList, set_id: SetId) -> Result<Self, ()> {
Ok(Self { authorities: TryFrom::try_from(authorities)?, set_id })
}
}
impl<T: Config<I>, I: 'static> PartialEq for StoredAuthoritySet<T, I> {
fn eq(&self, other: &Self) -> bool {
self.set_id == other.set_id && self.authorities == other.authorities
}
}
impl<T: Config<I>, I: 'static> Default for StoredAuthoritySet<T, I> {
fn default() -> Self {
StoredAuthoritySet { authorities: BoundedVec::default(), set_id: 0 }
}
}
impl<T: Config<I>, I: 'static> From<StoredAuthoritySet<T, I>> for AuthoritySet {
fn from(t: StoredAuthoritySet<T, I>) -> Self {
AuthoritySet { authorities: t.authorities.into(), set_id: t.set_id }
}
}
/// A bounded chain header.
#[derive(Clone, Decode, Encode, Eq, PartialEq, RuntimeDebugNoBound)]
pub struct StoredBridgedHeader<T: Config<I>, I: 'static>(pub BridgedHeader<T, I>);
impl<T: Config<I>, I: 'static> StoredBridgedHeader<T, I> {
/// Construct `StoredBridgedHeader` from the `BridgedHeader` with all required checks.
pub fn try_from_bridged_header(header: BridgedHeader<T, I>) -> Result<Self, Error<T, I>> {
// this conversion is heavy (since we do encoding here), so we may want to optimize it later
// (e.g. by introducing custom Encode implementation, and turning `StoredBridgedHeader` into
// `enum StoredBridgedHeader { Decoded(BridgedHeader), Encoded(Vec<u8>) }`)
if header.encoded_size() > T::MaxBridgedHeaderSize::get() as usize {
Err(Error::TooLargeHeader)
} else {
Ok(StoredBridgedHeader(header))
}
}
}
impl<T: Config<I>, I: 'static> sp_std::ops::Deref for StoredBridgedHeader<T, I> {
type Target = BridgedHeader<T, I>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<T: Config<I>, I: 'static> TypeInfo for StoredBridgedHeader<T, I> {
type Identity = Self;
fn type_info() -> Type {
BridgedHeader::<T, I>::type_info()
}
}
impl<T: Config<I>, I: 'static> MaxEncodedLen for StoredBridgedHeader<T, I> {
fn max_encoded_len() -> usize {
T::MaxBridgedHeaderSize::get() as usize
}
}
+4
View File
@@ -95,6 +95,8 @@ impl pallet_bridge_grandpa::Config<pallet_bridge_grandpa::Instance1> for TestRun
type BridgedChain = TestBridgedChain;
type MaxRequests = MaxRequests;
type HeadersToKeep = HeadersToKeep;
type MaxBridgedAuthorities = frame_support::traits::ConstU32<5>;
type MaxBridgedHeaderSize = frame_support::traits::ConstU32<512>;
type WeightInfo = ();
}
@@ -102,6 +104,8 @@ impl pallet_bridge_grandpa::Config<pallet_bridge_grandpa::Instance2> for TestRun
type BridgedChain = TestBridgedChain;
type MaxRequests = MaxRequests;
type HeadersToKeep = HeadersToKeep;
type MaxBridgedAuthorities = frame_support::traits::ConstU32<5>;
type MaxBridgedHeaderSize = frame_support::traits::ConstU32<512>;
type WeightInfo = ();
}
@@ -109,6 +109,12 @@ pub const PAY_INBOUND_DISPATCH_FEE_WEIGHT: Weight = 700_000_000;
/// conditions.
pub const SESSION_LENGTH: BlockNumber = 5 * time_units::MINUTES;
/// Maximal number of GRANDPA authorities at Millau.
pub const MAX_AUTHORITIES_COUNT: u32 = 5;
/// Maximal SCALE-encoded header size (in bytes) at Millau.
pub const MAX_HEADER_SIZE: u32 = 512;
/// Re-export `time_units` to make usage easier.
pub use time_units::*;
@@ -100,6 +100,12 @@ pub const PAY_INBOUND_DISPATCH_FEE_WEIGHT: Weight = 700_000_000;
/// conditions.
pub const SESSION_LENGTH: BlockNumber = 4;
/// Maximal number of GRANDPA authorities at Rialto.
pub const MAX_AUTHORITIES_COUNT: u32 = 5;
/// Maximal SCALE-encoded header size (in bytes) at Rialto.
pub const MAX_HEADER_SIZE: u32 = 512;
/// Re-export `time_units` to make usage easier.
pub use time_units::*;
@@ -58,6 +58,18 @@ pub const WITH_WESTEND_BRIDGE_PARAS_PALLET_NAME: &str = "BridgeWestendParachains
/// conditions.
pub const SESSION_LENGTH: BlockNumber = 10 * time_units::MINUTES;
/// Maximal number of GRANDPA authorities at Westend.
///
/// Corresponds to the `MaxAuthorities` constant value from the Westend runtime configuration.
pub const MAX_AUTHORITIES_COUNT: u32 = 100_000;
/// Maximal SCALE-encoded header size (in bytes) at Westend.
///
/// Let's assume that the largest header is header that enacts new authorities set with
/// `MAX_AUTHORITES_COUNT`. Every authority means 32-byte key and 8-byte weight. Let's also have
/// some fixed reserve for other things (digest, block hash and number, ...) as well.
pub const MAX_HEADER_SIZE: u32 = 4096 + MAX_AUTHORITIES_COUNT * 40;
/// Identifier of Westmint parachain at the Westend relay chain.
pub const WESTMINT_PARACHAIN_ID: u32 = 2000;
@@ -71,47 +71,6 @@ pub struct InitializationData<H: HeaderT> {
pub operating_mode: BasicOperatingMode,
}
/// base trait for verifying transaction inclusion proofs.
pub trait InclusionProofVerifier {
/// Transaction type.
type Transaction: Parameter;
/// Transaction inclusion proof type.
type TransactionInclusionProof: Parameter;
/// Verify that transaction is a part of given block.
///
/// Returns Some(transaction) if proof is valid and None otherwise.
fn verify_transaction_inclusion_proof(
proof: &Self::TransactionInclusionProof,
) -> Option<Self::Transaction>;
}
/// A trait for pallets which want to keep track of finalized headers from a bridged chain.
pub trait HeaderChain<H, E> {
/// Get the best finalized header known to the header chain.
fn best_finalized() -> Option<H>;
/// Get the best authority set known to the header chain.
fn authority_set() -> AuthoritySet;
/// Write a header finalized by GRANDPA to the underlying pallet storage.
fn append_header(header: H) -> Result<(), E>;
}
impl<H: Default, E> HeaderChain<H, E> for () {
fn best_finalized() -> Option<H> {
None
}
fn authority_set() -> AuthoritySet {
AuthoritySet::default()
}
fn append_header(_header: H) -> Result<(), E> {
Ok(())
}
}
/// Abstract finality proof that is justifying block finality.
pub trait FinalityProof<Number>: Clone + Send + Sync + Debug {
/// Return number of header that this proof is generated for.
+15 -5
View File
@@ -15,7 +15,7 @@
// along with Parity Bridges Common. If not, see <http://www.gnu.org/licenses/>.
use crate::HeaderIdProvider;
use codec::{Decode, Encode};
use codec::{Decode, Encode, MaxEncodedLen};
use frame_support::{weights::Weight, Parameter};
use num_traits::{AsPrimitive, Bounded, CheckedSub, Saturating, SaturatingAdd, Zero};
use sp_runtime::{
@@ -111,6 +111,7 @@ pub trait Chain: Send + Sync + 'static {
+ AsPrimitive<usize>
+ Default
+ Saturating
+ MaxEncodedLen
// original `sp_runtime::traits::Header::BlockNumber` doesn't have this trait, but
// `sp_runtime::generic::Era` requires block number -> `u64` conversion.
+ Into<u64>;
@@ -130,7 +131,8 @@ pub trait Chain: Send + Sync + 'static {
+ SimpleBitOps
+ AsRef<[u8]>
+ AsMut<[u8]>
+ MaybeMallocSizeOf;
+ MaybeMallocSizeOf
+ MaxEncodedLen;
/// A type that fulfills the abstract idea of what a Substrate hasher (a type
/// that produces hashes) is.
@@ -148,7 +150,13 @@ pub trait Chain: Send + Sync + 'static {
+ MaybeSerializeDeserialize;
/// The user account identifier type for the runtime.
type AccountId: Parameter + Member + MaybeSerializeDeserialize + Debug + MaybeDisplay + Ord;
type AccountId: Parameter
+ Member
+ MaybeSerializeDeserialize
+ Debug
+ MaybeDisplay
+ Ord
+ MaxEncodedLen;
/// Balance of an account in native tokens.
///
/// The chain may support multiple tokens, but this particular type is for token that is used
@@ -165,7 +173,8 @@ pub trait Chain: Send + Sync + 'static {
+ PartialOrd
+ SaturatingAdd
+ Zero
+ TryFrom<sp_core::U256>;
+ TryFrom<sp_core::U256>
+ MaxEncodedLen;
/// Index of a transaction used by the chain.
type Index: Parameter
+ Member
@@ -175,7 +184,8 @@ pub trait Chain: Send + Sync + 'static {
+ MaybeDisplay
+ MaybeSerializeDeserialize
+ AtLeast32Bit
+ Copy;
+ Copy
+ MaxEncodedLen;
/// Signature type, used on this chain.
type Signature: Parameter + Verify;