From 05d9e84c9181c885d5dedc6e04c1a0ce00ac35ca Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Mon, 27 Jun 2022 13:30:32 +0300 Subject: [PATCH 01/12] remove pallet::without_storage_info from bridge GRANDPA pallet --- modules/grandpa/src/lib.rs | 86 +++++++++++++++++++++++++----- modules/grandpa/src/mock.rs | 1 + primitives/header-chain/src/lib.rs | 41 -------------- primitives/runtime/src/chain.rs | 17 +++--- 4 files changed, 85 insertions(+), 60 deletions(-) diff --git a/modules/grandpa/src/lib.rs b/modules/grandpa/src/lib.rs index 1527de80fc..4a573f96c8 100644 --- a/modules/grandpa/src/lib.rs +++ b/modules/grandpa/src/lib.rs @@ -36,12 +36,14 @@ // Runtime-generated enums #![allow(clippy::large_enum_variant)] -use bp_header_chain::{justification::GrandpaJustification, InitializationData}; +use bp_header_chain::{justification::GrandpaJustification, AuthoritySet, InitializationData}; use bp_runtime::{BlockNumberOf, Chain, HashOf, HasherOf, HeaderOf}; +use codec::{Decode, Encode, MaxEncodedLen}; use finality_grandpa::voter_set::VoterSet; -use frame_support::{ensure, fail}; +use frame_support::{traits::Get, BoundedVec, RuntimeDebugNoBound, ensure, fail}; use frame_system::{ensure_signed, RawOrigin}; -use sp_finality_grandpa::{ConsensusLog, GRANDPA_ENGINE_ID}; +use scale_info::TypeInfo; +use sp_finality_grandpa::{AuthorityId, AuthorityList, AuthorityWeight, ConsensusLog, GRANDPA_ENGINE_ID, SetId}; use sp_runtime::traits::{BadOrigin, Header as HeaderT, Zero}; use sp_std::{boxed::Box, convert::TryInto}; @@ -68,6 +70,56 @@ pub type BridgedBlockHasher = HasherOf<>::BridgedChain>; /// Header of the bridged chain. pub type BridgedHeader = HeaderOf<>::BridgedChain>; +/// A bounded list of Grandpa authorities with associated weights. +type StoredAuthorityList = BoundedVec<(AuthorityId, AuthorityWeight), T>; + +/// A bounded GRANDPA Authority List and ID. +#[derive(Encode, Eq, Decode, RuntimeDebugNoBound, PartialEq, Clone, TypeInfo, MaxEncodedLen)] +struct StoredAuthoritySet> { + /// List of GRANDPA authorities for the current round. + pub authorities: StoredAuthorityList, + /// Monotonic identifier of the current GRANDPA authority set. + pub set_id: SetId, +} + +impl> StoredAuthoritySet { + /// 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 new(authorities: AuthorityList, set_id: SetId) -> Result { + Ok(Self { authorities: TryFrom::try_from(authorities)?, set_id }) + } +} + +impl> Default for StoredAuthoritySet { + fn default() -> Self { + StoredAuthoritySet { + authorities: BoundedVec::default(), + set_id: 0, + } + } +} + +impl> From> for AuthoritySet { + fn from(t: StoredAuthoritySet) -> Self { + AuthoritySet { + authorities: t.authorities.into(), + set_id: t.set_id, + } + } +} + +impl> TryFrom for StoredAuthoritySet { + type Error = (); + + fn try_from(t: AuthoritySet) -> Result { + Ok(StoredAuthoritySet { + authorities: TryFrom::try_from(t.authorities)?, + set_id: t.set_id + }) + } +} + #[frame_support::pallet] pub mod pallet { use super::*; @@ -98,12 +150,15 @@ pub mod pallet { #[pallet::constant] type HeadersToKeep: Get; + /// Max number of authorities at the bridged chain. + #[pallet::constant] + type MaxBridgedAuthorities: Get; + /// Weights gathered through benchmarking. type WeightInfo: WeightInfo; } #[pallet::pallet] - #[pallet::without_storage_info] pub struct Pallet(PhantomData<(T, I)>); #[pallet::hooks] @@ -165,7 +220,7 @@ pub mod pallet { let authority_set = >::get(); let set_id = authority_set.set_id; - verify_justification::(&justification, hash, *number, authority_set)?; + verify_justification::(&justification, hash, *number, authority_set.into())?; let is_authorities_change_enacted = try_enact_authority_change::(&finality_target, set_id)?; @@ -202,7 +257,7 @@ pub mod pallet { let init_allowed = !>::exists(); ensure!(init_allowed, >::AlreadyInitialized); - initialize_bridge::(init_data.clone()); + initialize_bridge::(init_data.clone())?; log::info!( target: "runtime::bridge-grandpa", @@ -296,7 +351,7 @@ pub mod pallet { /// The current GRANDPA Authority set. #[pallet::storage] pub(super) type CurrentAuthoritySet, I: 'static = ()> = - StorageValue<_, bp_header_chain::AuthoritySet, ValueQuery>; + StorageValue<_, StoredAuthoritySet, ValueQuery>; /// Optional pallet owner. /// @@ -335,7 +390,7 @@ pub mod pallet { } if let Some(init_data) = self.init_data.clone() { - initialize_bridge::(init_data); + initialize_bridge::(init_data).expect("genesis config is correct; qed"); } else { // Since the bridge hasn't been initialized we shouldn't allow anyone to perform // transactions. @@ -368,6 +423,8 @@ pub mod pallet { Halted, /// The storage proof doesn't contains storage root. So it is invalid for given header. StorageRootMismatch, + /// Too many authorities in the set. + TooManyAuthoritiesInSet, } /// Check the given header for a GRANDPA scheduled authority set change. If a change @@ -394,8 +451,8 @@ pub mod pallet { ensure!(change.delay == Zero::zero(), >::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 { + authorities: change.next_authorities.try_into().map_err(|_| Error::::TooManyAuthoritiesInSet)?, set_id: current_set_id + 1, }; @@ -477,7 +534,7 @@ pub mod pallet { /// were called by a trusted origin. pub(crate) fn initialize_bridge, I: 'static>( init_params: super::InitializationData>, - ) { + ) -> Result<(), Error>{ let super::InitializationData { header, authority_list, set_id, is_halted } = init_params; let initial_hash = header.hash(); @@ -485,10 +542,13 @@ pub mod pallet { >::put(0); insert_header::(*header, initial_hash); - let authority_set = bp_header_chain::AuthoritySet::new(authority_list, set_id); + let authority_set = StoredAuthoritySet::new(authority_list, set_id) + .map_err(|_| Error::TooManyAuthoritiesInSet)?; >::put(authority_set); >::put(is_halted); + + Ok(()) } #[cfg(feature = "runtime-benchmarks")] @@ -949,7 +1009,7 @@ mod tests { // Make sure that the authority set actually changed upon importing our header assert_eq!( >::get(), - bp_header_chain::AuthoritySet::new(next_authorities, next_set_id), + StoredAuthoritySet::new(next_authorities, next_set_id).unwrap(), ); }) } diff --git a/modules/grandpa/src/mock.rs b/modules/grandpa/src/mock.rs index a0327761fc..2446aefec6 100644 --- a/modules/grandpa/src/mock.rs +++ b/modules/grandpa/src/mock.rs @@ -91,6 +91,7 @@ impl grandpa::Config for TestRuntime { type BridgedChain = TestBridgedChain; type MaxRequests = MaxRequests; type HeadersToKeep = HeadersToKeep; + type MaxBridgedAuthorities = frame_support::traits::ConstU32<256>; type WeightInfo = (); } diff --git a/primitives/header-chain/src/lib.rs b/primitives/header-chain/src/lib.rs index ff8ee82f41..b3ba6603e4 100644 --- a/primitives/header-chain/src/lib.rs +++ b/primitives/header-chain/src/lib.rs @@ -70,47 +70,6 @@ pub struct InitializationData { pub is_halted: bool, } -/// 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; -} - -/// A trait for pallets which want to keep track of finalized headers from a bridged chain. -pub trait HeaderChain { - /// Get the best finalized header known to the header chain. - fn best_finalized() -> Option; - - /// 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 HeaderChain for () { - fn best_finalized() -> Option { - 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: Clone + Send + Sync + Debug { /// Return number of header that this proof is generated for. diff --git a/primitives/runtime/src/chain.rs b/primitives/runtime/src/chain.rs index 4f88e701fb..ac216200fb 100644 --- a/primitives/runtime/src/chain.rs +++ b/primitives/runtime/src/chain.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Parity Bridges Common. If not, see . -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::{ @@ -110,6 +110,7 @@ pub trait Chain: Send + Sync + 'static { + AsPrimitive + 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; @@ -129,7 +130,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. @@ -143,10 +145,11 @@ pub trait Chain: Send + Sync + 'static { // https://crates.parity.io/sp_runtime/traits/trait.Header.html type Header: Parameter + HeaderT - + MaybeSerializeDeserialize; + + MaybeSerializeDeserialize + + MaxEncodedLen; /// 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 @@ -163,7 +166,8 @@ pub trait Chain: Send + Sync + 'static { + PartialOrd + SaturatingAdd + Zero - + TryFrom; + + TryFrom + + MaxEncodedLen; /// Index of a transaction used by the chain. type Index: Parameter + Member @@ -173,7 +177,8 @@ pub trait Chain: Send + Sync + 'static { + MaybeDisplay + MaybeSerializeDeserialize + AtLeast32Bit - + Copy; + + Copy + + MaxEncodedLen; /// Signature type, used on this chain. type Signature: Parameter + Verify; From b59d3aef300f309562c0fa411aebe8c82d78c75a Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Fri, 7 Oct 2022 15:52:02 +0300 Subject: [PATCH 02/12] StoredBridgedHeader --- bin/millau/runtime/src/lib.rs | 4 + bin/rialto-parachain/runtime/src/lib.rs | 2 + bin/rialto/runtime/src/lib.rs | 2 + modules/grandpa/src/lib.rs | 196 +++++++++++++++++------- modules/grandpa/src/mock.rs | 6 +- modules/grandpa/src/storage_types.rs | 114 ++++++++++++++ modules/parachains/src/mock.rs | 4 + primitives/runtime/src/chain.rs | 3 +- 8 files changed, 274 insertions(+), 57 deletions(-) create mode 100644 modules/grandpa/src/storage_types.rs diff --git a/bin/millau/runtime/src/lib.rs b/bin/millau/runtime/src/lib.rs index 8470efa7e8..7e0b90e85b 100644 --- a/bin/millau/runtime/src/lib.rs +++ b/bin/millau/runtime/src/lib.rs @@ -431,6 +431,8 @@ impl pallet_bridge_grandpa::Config for Runtime { type BridgedChain = bp_rialto::Rialto; type MaxRequests = MaxRequests; type HeadersToKeep = HeadersToKeep; + type MaxBridgedAuthorities = frame_support::traits::ConstU32<5>; + type MaxBridgedHeaderSize = frame_support::traits::ConstU32<512>; type WeightInfo = pallet_bridge_grandpa::weights::BridgeWeight; } @@ -440,6 +442,8 @@ impl pallet_bridge_grandpa::Config for Runtime { type BridgedChain = bp_westend::Westend; type MaxRequests = MaxRequests; type HeadersToKeep = HeadersToKeep; + type MaxBridgedAuthorities = frame_support::traits::ConstU32<2048>; + type MaxBridgedHeaderSize = frame_support::traits::ConstU32<65536>; type WeightInfo = pallet_bridge_grandpa::weights::BridgeWeight; } diff --git a/bin/rialto-parachain/runtime/src/lib.rs b/bin/rialto-parachain/runtime/src/lib.rs index b714e6d631..3424e791ed 100644 --- a/bin/rialto-parachain/runtime/src/lib.rs +++ b/bin/rialto-parachain/runtime/src/lib.rs @@ -538,6 +538,8 @@ impl pallet_bridge_grandpa::Config for Runtime { type BridgedChain = bp_millau::Millau; type MaxRequests = MaxRequests; type HeadersToKeep = HeadersToKeep; + type MaxBridgedAuthorities = frame_support::traits::ConstU32<5>; + type MaxBridgedHeaderSize = frame_support::traits::ConstU32<512>; type WeightInfo = pallet_bridge_grandpa::weights::BridgeWeight; } diff --git a/bin/rialto/runtime/src/lib.rs b/bin/rialto/runtime/src/lib.rs index 09afe728fd..c55465ba43 100644 --- a/bin/rialto/runtime/src/lib.rs +++ b/bin/rialto/runtime/src/lib.rs @@ -424,6 +424,8 @@ impl pallet_bridge_grandpa::Config for Runtime { type BridgedChain = bp_millau::Millau; type MaxRequests = MaxRequests; type HeadersToKeep = HeadersToKeep; + type MaxBridgedAuthorities = frame_support::traits::ConstU32<5>; + type MaxBridgedHeaderSize = frame_support::traits::ConstU32<512>; type WeightInfo = pallet_bridge_grandpa::weights::BridgeWeight; } diff --git a/modules/grandpa/src/lib.rs b/modules/grandpa/src/lib.rs index 2fba009887..f8ce735b6d 100644 --- a/modules/grandpa/src/lib.rs +++ b/modules/grandpa/src/lib.rs @@ -36,9 +36,10 @@ // 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 codec::{Decode, Encode}; use finality_grandpa::voter_set::VoterSet; use frame_support::{ensure, fail}; use frame_system::ensure_signed; @@ -49,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; @@ -72,47 +74,6 @@ pub type BridgedBlockHasher = HasherOf<>::BridgedChain>; /// Header of the bridged chain. pub type BridgedHeader = HeaderOf<>::BridgedChain>; -/// A bounded list of Grandpa authorities with associated weights. -type StoredAuthorityList = BoundedVec<(AuthorityId, AuthorityWeight), T>; - -/// A bounded GRANDPA Authority List and ID. -#[derive(Encode, Eq, Decode, RuntimeDebugNoBound, PartialEq, Clone, TypeInfo, MaxEncodedLen)] -struct StoredAuthoritySet> { - /// List of GRANDPA authorities for the current round. - pub authorities: StoredAuthorityList, - /// Monotonic identifier of the current GRANDPA authority set. - pub set_id: SetId, -} - -impl> StoredAuthoritySet { - /// 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 new(authorities: AuthorityList, set_id: SetId) -> Result { - Ok(Self { authorities: TryFrom::try_from(authorities)?, set_id }) - } -} - -impl> Default for StoredAuthoritySet { - fn default() -> Self { - StoredAuthoritySet { authorities: BoundedVec::default(), set_id: 0 } - } -} - -impl> From> for AuthoritySet { - fn from(t: StoredAuthoritySet) -> Self { - AuthoritySet { authorities: t.authorities.into(), set_id: t.set_id } - } -} - -impl> TryFrom for StoredAuthoritySet { - type Error = (); - - fn try_from(t: AuthoritySet) -> Result { - Ok(StoredAuthoritySet { authorities: TryFrom::try_from(t.authorities)?, set_id: t.set_id }) - } -} - #[frame_support::pallet] pub mod pallet { use super::*; @@ -147,6 +108,15 @@ pub mod pallet { /// Max number of authorities at the bridged chain. #[pallet::constant] type MaxBridgedAuthorities: Get; + /// 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 ~32kb. + /// The same header may also contain other digest items as well, so some reserve here + /// is required. + #[pallet::constant] + type MaxBridgedHeaderSize: Get; /// Weights gathered through benchmarking. type WeightInfo: WeightInfo; @@ -229,8 +199,10 @@ pub mod pallet { let is_authorities_change_enacted = try_enact_authority_change::(&finality_target, set_id)?; + let finality_target = + StoredBridgedHeader::::try_from_bridged_header(*finality_target)?; >::mutate(|count| *count += 1); - insert_header::(*finality_target, hash); + insert_header::(finality_target, hash); log::info!( target: LOG_TARGET, "Successfully imported finalized header with hash {:?}!", @@ -331,12 +303,12 @@ pub mod pallet { /// Headers which have been imported into the pallet. #[pallet::storage] pub type ImportedHeaders, I: 'static = ()> = - StorageMap<_, Identity, BridgedBlockHash, BridgedHeader>; + StorageMap<_, Identity, BridgedBlockHash, StoredBridgedHeader>; /// The current GRANDPA Authority set. #[pallet::storage] pub(super) type CurrentAuthoritySet, I: 'static = ()> = - StorageValue<_, StoredAuthoritySet, ValueQuery>; + StorageValue<_, StoredAuthoritySet, ValueQuery>; /// Optional pallet owner. /// @@ -411,6 +383,8 @@ pub mod pallet { StorageRootMismatch, /// Too many authorities in the set. TooManyAuthoritiesInSet, + /// Too large header. + TooLargeHeader, /// Error generated by the `OwnedBridgeModule` trait. BridgeModule(bp_runtime::OwnedBridgeModuleError), } @@ -439,7 +413,7 @@ pub mod pallet { ensure!(change.delay == Zero::zero(), >::UnsupportedScheduledChange); // TODO [#788]: Stop manually increasing the `set_id` here. - let next_authorities = StoredAuthoritySet { + let next_authorities = StoredAuthoritySet:: { authorities: change .next_authorities .try_into() @@ -504,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, I: 'static>( - header: BridgedHeader, + header: StoredBridgedHeader, hash: BridgedBlockHash, ) { let index = >::get(); @@ -528,17 +502,20 @@ pub mod pallet { ) -> Result<(), Error> { let super::InitializationData { header, authority_list, set_id, operating_mode } = init_params; + let authority_set = StoredAuthoritySet::::new(authority_list, set_id) + .map_err(|_| Error::TooManyAuthoritiesInSet)?; + let header = StoredBridgedHeader::::try_from_bridged_header(*header)?; let initial_hash = header.hash(); >::put(initial_hash); >::put(0); - insert_header::(*header, initial_hash); + insert_header::(header, initial_hash); - let authority_set = StoredAuthoritySet::new(authority_list, set_id) - .map_err(|_| Error::TooManyAuthoritiesInSet)?; >::put(authority_set); >::put(operating_mode); + + Ok(()) } #[cfg(feature = "runtime-benchmarks")] @@ -572,7 +549,7 @@ impl, I: 'static> Pallet { /// if the pallet has not been initialized yet. pub fn best_finalized() -> Option> { let (_, hash) = >::get()?; - >::get(hash) + >::get(hash).map(|h| h.0) } /// Check if a particular header is known to the bridge pallet. @@ -648,7 +625,10 @@ pub fn initialize_for_benchmarks, I: 'static>(header: BridgedHeader #[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, @@ -724,6 +704,22 @@ mod tests { Digest { logs: vec![DigestItem::Consensus(GRANDPA_ENGINE_ID, consensus_log.encode())] } } + fn many_authorities_log() -> Digest { + let consensus_log = + ConsensusLog::::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(|| { @@ -766,6 +762,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::::initialize(Origin::root(), init_data), + Error::::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::::initialize(Origin::root(), init_data), + Error::::TooLargeHeader, + ); + }); + } + #[test] fn pallet_rejects_transactions_if_halted() { run_test(|| { @@ -931,7 +966,7 @@ mod tests { // Make sure that the authority set actually changed upon importing our header assert_eq!( >::get(), - StoredAuthoritySet::new(next_authorities, next_set_id).unwrap(), + StoredAuthoritySet::::new(next_authorities, next_set_id).unwrap(), ); }) } @@ -986,6 +1021,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::::submit_finality_proof( + Origin::signed(1), + Box::new(header), + justification + ), + >::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::::submit_finality_proof( + Origin::signed(1), + Box::new(header), + justification + ), + >::TooLargeHeader + ); + }); + } + #[test] fn parse_finalized_storage_proof_rejects_proof_on_unknown_header() { run_test(|| { @@ -1010,7 +1095,10 @@ mod tests { let hash = header.hash(); >::put((2, hash)); - >::insert(hash, header); + >::insert( + hash, + StoredBridgedHeader::try_from_bridged_header(header).unwrap(), + ); assert_ok!( Pallet::::parse_finalized_storage_proof(hash, storage_proof, |_| (),), diff --git a/modules/grandpa/src/mock.rs b/modules/grandpa/src/mock.rs index 2446aefec6..7819473657 100644 --- a/modules/grandpa/src/mock.rs +++ b/modules/grandpa/src/mock.rs @@ -33,6 +33,9 @@ pub type TestNumber = crate::BridgedBlockNumber; type Block = frame_system::mocking::MockBlock; type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; +pub const MAX_BRIDGED_AUTHORITIES: u32 = 256; +pub const MAX_HEADER_SIZE: u32 = 65536; + use crate as grandpa; construct_runtime! { @@ -91,7 +94,8 @@ impl grandpa::Config for TestRuntime { type BridgedChain = TestBridgedChain; type MaxRequests = MaxRequests; type HeadersToKeep = HeadersToKeep; - type MaxBridgedAuthorities = frame_support::traits::ConstU32<256>; + type MaxBridgedAuthorities = frame_support::traits::ConstU32; + type MaxBridgedHeaderSize = frame_support::traits::ConstU32; type WeightInfo = (); } diff --git a/modules/grandpa/src/storage_types.rs b/modules/grandpa/src/storage_types.rs new file mode 100644 index 0000000000..e5c8d5dbeb --- /dev/null +++ b/modules/grandpa/src/storage_types.rs @@ -0,0 +1,114 @@ +// Copyright 2021 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 . + +//! Wrappers for public types that are implementing Max + +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 = + 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, I: 'static> { + /// List of GRANDPA authorities for the current round. + pub authorities: StoredAuthorityList<>::MaxBridgedAuthorities>, + /// Monotonic identifier of the current GRANDPA authority set. + pub set_id: SetId, +} + +impl, I: 'static> StoredAuthoritySet { + /// 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 new(authorities: AuthorityList, set_id: SetId) -> Result { + Ok(Self { authorities: TryFrom::try_from(authorities)?, set_id }) + } +} + +impl, I: 'static> PartialEq for StoredAuthoritySet { + fn eq(&self, other: &Self) -> bool { + self.set_id == other.set_id && self.authorities == other.authorities + } +} + +impl, I: 'static> Default for StoredAuthoritySet { + fn default() -> Self { + StoredAuthoritySet { authorities: BoundedVec::default(), set_id: 0 } + } +} + +impl, I: 'static> From> for AuthoritySet { + fn from(t: StoredAuthoritySet) -> Self { + AuthoritySet { authorities: t.authorities.into(), set_id: t.set_id } + } +} + +impl, I: 'static> TryFrom for StoredAuthoritySet { + type Error = (); + + fn try_from(t: AuthoritySet) -> Result { + Ok(StoredAuthoritySet { authorities: TryFrom::try_from(t.authorities)?, set_id: t.set_id }) + } +} + +/// A bounded chain header. +#[derive(Clone, Decode, Encode, Eq, PartialEq, RuntimeDebugNoBound)] +pub struct StoredBridgedHeader, I: 'static>(pub BridgedHeader); + +impl, I: 'static> StoredBridgedHeader { + /// Construct `StoredBridgedHeader` from the `BridgedHeader` with all required checks. + pub fn try_from_bridged_header(header: BridgedHeader) -> Result> { + // 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) }`) + if header.encoded_size() > T::MaxBridgedHeaderSize::get() as usize { + Err(Error::TooLargeHeader) + } else { + Ok(StoredBridgedHeader(header)) + } + } +} + +impl, I: 'static> sp_std::ops::Deref for StoredBridgedHeader { + type Target = BridgedHeader; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl, I: 'static> TypeInfo for StoredBridgedHeader { + type Identity = Self; + + fn type_info() -> Type { + BridgedHeader::::type_info() + } +} + +impl, I: 'static> MaxEncodedLen for StoredBridgedHeader { + fn max_encoded_len() -> usize { + T::MaxBridgedHeaderSize::get() as usize + } +} diff --git a/modules/parachains/src/mock.rs b/modules/parachains/src/mock.rs index 292856f35a..a31fb4c47f 100644 --- a/modules/parachains/src/mock.rs +++ b/modules/parachains/src/mock.rs @@ -95,6 +95,8 @@ impl pallet_bridge_grandpa::Config 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 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 = (); } diff --git a/primitives/runtime/src/chain.rs b/primitives/runtime/src/chain.rs index 4437e6e8d1..be95f17480 100644 --- a/primitives/runtime/src/chain.rs +++ b/primitives/runtime/src/chain.rs @@ -147,8 +147,7 @@ pub trait Chain: Send + Sync + 'static { type Header: Parameter + HeaderT + HeaderIdProvider - + MaybeSerializeDeserialize - + MaxEncodedLen; + + MaybeSerializeDeserialize; /// The user account identifier type for the runtime. type AccountId: Parameter From 52f1108e18d386fb8f2a0685a7fa511c3533843f Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Fri, 7 Oct 2022 15:55:17 +0300 Subject: [PATCH 03/12] spelling --- modules/grandpa/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/grandpa/src/lib.rs b/modules/grandpa/src/lib.rs index f8ce735b6d..b80fbf491b 100644 --- a/modules/grandpa/src/lib.rs +++ b/modules/grandpa/src/lib.rs @@ -112,7 +112,7 @@ pub mod pallet { /// /// 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 ~32kb. + /// 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] From 9b66c6fe2dc0e428b4cfcb9011e8881234d390cc Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Fri, 7 Oct 2022 16:11:04 +0300 Subject: [PATCH 04/12] fix benchmarks --- modules/grandpa/src/lib.rs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/modules/grandpa/src/lib.rs b/modules/grandpa/src/lib.rs index b80fbf491b..6bbfbf37a1 100644 --- a/modules/grandpa/src/lib.rs +++ b/modules/grandpa/src/lib.rs @@ -524,7 +524,7 @@ pub mod pallet { ) { let start_number = *init_params.header.number(); let end_number = start_number + T::HeadersToKeep::get().into(); - initialize_bridge::(init_params); + initialize_bridge::(init_params).expect("benchmarks are correct"); let mut number = start_number; while number < end_number { @@ -537,7 +537,11 @@ pub mod pallet { Default::default(), ); let hash = header.hash(); - insert_header::(header, hash); + insert_header::( + StoredBridgedHeader::try_from_bridged_header(header) + .expect("only used from benchmarks; benchmarks are correct; qed"), + hash, + ); } } } @@ -619,7 +623,8 @@ pub fn initialize_for_benchmarks, 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)] From 37649d89e1efa2fe892011d706aa77aa35806d16 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Mon, 10 Oct 2022 10:02:30 +0300 Subject: [PATCH 05/12] MAX_BRIDGED_AUTHORITIES: 256 -> 2048 --- modules/grandpa/src/mock.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/grandpa/src/mock.rs b/modules/grandpa/src/mock.rs index 7819473657..babdd4b792 100644 --- a/modules/grandpa/src/mock.rs +++ b/modules/grandpa/src/mock.rs @@ -33,7 +33,7 @@ pub type TestNumber = crate::BridgedBlockNumber; type Block = frame_system::mocking::MockBlock; type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; -pub const MAX_BRIDGED_AUTHORITIES: u32 = 256; +pub const MAX_BRIDGED_AUTHORITIES: u32 = 2048; pub const MAX_HEADER_SIZE: u32 = 65536; use crate as grandpa; From 6def5a30bc51705b45144fca7c3b9094a419c94a Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Mon, 10 Oct 2022 10:03:29 +0300 Subject: [PATCH 06/12] Update modules/grandpa/src/storage_types.rs Co-authored-by: Adrian Catangiu --- modules/grandpa/src/storage_types.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/grandpa/src/storage_types.rs b/modules/grandpa/src/storage_types.rs index e5c8d5dbeb..ef142a8bdc 100644 --- a/modules/grandpa/src/storage_types.rs +++ b/modules/grandpa/src/storage_types.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Parity Bridges Common. If not, see . -//! Wrappers for public types that are implementing Max +//! Wrappers for public types that are implementing `MaxEncodedLen` use crate::{BridgedHeader, Config, Error}; From 607babe6c1a0c0f8e1f829b2a6d7d83279097b6c Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Mon, 10 Oct 2022 10:03:35 +0300 Subject: [PATCH 07/12] Update modules/grandpa/src/storage_types.rs Co-authored-by: Adrian Catangiu --- modules/grandpa/src/storage_types.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/grandpa/src/storage_types.rs b/modules/grandpa/src/storage_types.rs index ef142a8bdc..30302b2884 100644 --- a/modules/grandpa/src/storage_types.rs +++ b/modules/grandpa/src/storage_types.rs @@ -1,4 +1,4 @@ -// Copyright 2021 Parity Technologies (UK) Ltd. +// 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 From 21ce37c5680373655e134899d3132b6f7600ad9c Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Mon, 10 Oct 2022 10:30:31 +0300 Subject: [PATCH 08/12] moved max authorities + header size to chain primitives --- bin/millau/runtime/src/lib.rs | 18 ++++++++++++++---- bin/rialto-parachain/runtime/src/lib.rs | 9 +++++++-- bin/rialto/runtime/src/lib.rs | 9 +++++++-- primitives/chain-millau/src/lib.rs | 6 ++++++ primitives/chain-rialto/src/lib.rs | 6 ++++++ primitives/chain-westend/src/lib.rs | 12 ++++++++++++ 6 files changed, 52 insertions(+), 8 deletions(-) diff --git a/bin/millau/runtime/src/lib.rs b/bin/millau/runtime/src/lib.rs index 7e0b90e85b..cae2c388ca 100644 --- a/bin/millau/runtime/src/lib.rs +++ b/bin/millau/runtime/src/lib.rs @@ -424,6 +424,16 @@ 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 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 = (); @@ -431,8 +441,8 @@ impl pallet_bridge_grandpa::Config for Runtime { type BridgedChain = bp_rialto::Rialto; type MaxRequests = MaxRequests; type HeadersToKeep = HeadersToKeep; - type MaxBridgedAuthorities = frame_support::traits::ConstU32<5>; - type MaxBridgedHeaderSize = frame_support::traits::ConstU32<512>; + type MaxBridgedAuthorities = MaxAuthoritiesAtRialto; + type MaxBridgedHeaderSize = MaxRialtoHeaderSize; type WeightInfo = pallet_bridge_grandpa::weights::BridgeWeight; } @@ -442,8 +452,8 @@ impl pallet_bridge_grandpa::Config for Runtime { type BridgedChain = bp_westend::Westend; type MaxRequests = MaxRequests; type HeadersToKeep = HeadersToKeep; - type MaxBridgedAuthorities = frame_support::traits::ConstU32<2048>; - type MaxBridgedHeaderSize = frame_support::traits::ConstU32<65536>; + type MaxBridgedAuthorities = MaxAuthoritiesAtWestend; + type MaxBridgedHeaderSize = MaxWestendHeaderSize; type WeightInfo = pallet_bridge_grandpa::weights::BridgeWeight; } diff --git a/bin/rialto-parachain/runtime/src/lib.rs b/bin/rialto-parachain/runtime/src/lib.rs index 3424e791ed..752270f04c 100644 --- a/bin/rialto-parachain/runtime/src/lib.rs +++ b/bin/rialto-parachain/runtime/src/lib.rs @@ -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,8 +543,8 @@ impl pallet_bridge_grandpa::Config for Runtime { type BridgedChain = bp_millau::Millau; type MaxRequests = MaxRequests; type HeadersToKeep = HeadersToKeep; - type MaxBridgedAuthorities = frame_support::traits::ConstU32<5>; - type MaxBridgedHeaderSize = frame_support::traits::ConstU32<512>; + type MaxBridgedAuthorities = MaxAuthoritiesAtMillau; + type MaxBridgedHeaderSize = MaxMillauHeaderSize; type WeightInfo = pallet_bridge_grandpa::weights::BridgeWeight; } diff --git a/bin/rialto/runtime/src/lib.rs b/bin/rialto/runtime/src/lib.rs index c55465ba43..161b031950 100644 --- a/bin/rialto/runtime/src/lib.rs +++ b/bin/rialto/runtime/src/lib.rs @@ -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,8 +429,8 @@ impl pallet_bridge_grandpa::Config for Runtime { type BridgedChain = bp_millau::Millau; type MaxRequests = MaxRequests; type HeadersToKeep = HeadersToKeep; - type MaxBridgedAuthorities = frame_support::traits::ConstU32<5>; - type MaxBridgedHeaderSize = frame_support::traits::ConstU32<512>; + type MaxBridgedAuthorities = MaxAuthoritiesAtMillau; + type MaxBridgedHeaderSize = MaxMillauHeaderSize; type WeightInfo = pallet_bridge_grandpa::weights::BridgeWeight; } diff --git a/primitives/chain-millau/src/lib.rs b/primitives/chain-millau/src/lib.rs index 2f5b12eed0..60fe218844 100644 --- a/primitives/chain-millau/src/lib.rs +++ b/primitives/chain-millau/src/lib.rs @@ -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::*; diff --git a/primitives/chain-rialto/src/lib.rs b/primitives/chain-rialto/src/lib.rs index 1b8d19249e..9698da8877 100644 --- a/primitives/chain-rialto/src/lib.rs +++ b/primitives/chain-rialto/src/lib.rs @@ -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::*; diff --git a/primitives/chain-westend/src/lib.rs b/primitives/chain-westend/src/lib.rs index 08803b7a3d..eeb30709ac 100644 --- a/primitives/chain-westend/src/lib.rs +++ b/primitives/chain-westend/src/lib.rs @@ -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; From 8024dfd3d139e395fedbbf58cd3877c1c1653be4 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Mon, 10 Oct 2022 10:36:16 +0300 Subject: [PATCH 09/12] removed unused code --- modules/grandpa/src/storage_types.rs | 8 -------- 1 file changed, 8 deletions(-) diff --git a/modules/grandpa/src/storage_types.rs b/modules/grandpa/src/storage_types.rs index 30302b2884..1879bf010c 100644 --- a/modules/grandpa/src/storage_types.rs +++ b/modules/grandpa/src/storage_types.rs @@ -65,14 +65,6 @@ impl, I: 'static> From> for AuthoritySet { } } -impl, I: 'static> TryFrom for StoredAuthoritySet { - type Error = (); - - fn try_from(t: AuthoritySet) -> Result { - Ok(StoredAuthoritySet { authorities: TryFrom::try_from(t.authorities)?, set_id: t.set_id }) - } -} - /// A bounded chain header. #[derive(Clone, Decode, Encode, Eq, PartialEq, RuntimeDebugNoBound)] pub struct StoredBridgedHeader, I: 'static>(pub BridgedHeader); From ec841d3cf7df91bb9f3144bc089eb96cc24208cc Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Mon, 10 Oct 2022 11:01:20 +0300 Subject: [PATCH 10/12] new -> try_new --- modules/grandpa/src/lib.rs | 4 ++-- modules/grandpa/src/storage_types.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/grandpa/src/lib.rs b/modules/grandpa/src/lib.rs index 6bbfbf37a1..772d5dc6f2 100644 --- a/modules/grandpa/src/lib.rs +++ b/modules/grandpa/src/lib.rs @@ -502,7 +502,7 @@ pub mod pallet { ) -> Result<(), Error> { let super::InitializationData { header, authority_list, set_id, operating_mode } = init_params; - let authority_set = StoredAuthoritySet::::new(authority_list, set_id) + let authority_set = StoredAuthoritySet::::try_new(authority_list, set_id) .map_err(|_| Error::TooManyAuthoritiesInSet)?; let header = StoredBridgedHeader::::try_from_bridged_header(*header)?; @@ -971,7 +971,7 @@ mod tests { // Make sure that the authority set actually changed upon importing our header assert_eq!( >::get(), - StoredAuthoritySet::::new(next_authorities, next_set_id).unwrap(), + StoredAuthoritySet::::try_new(next_authorities, next_set_id).unwrap(), ); }) } diff --git a/modules/grandpa/src/storage_types.rs b/modules/grandpa/src/storage_types.rs index 1879bf010c..5d2cb661d8 100644 --- a/modules/grandpa/src/storage_types.rs +++ b/modules/grandpa/src/storage_types.rs @@ -42,7 +42,7 @@ impl, I: 'static> StoredAuthoritySet { /// 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 new(authorities: AuthorityList, set_id: SetId) -> Result { + pub fn try_new(authorities: AuthorityList, set_id: SetId) -> Result { Ok(Self { authorities: TryFrom::try_from(authorities)?, set_id }) } } From bfb225d38ad720c43afa0cbe811feb530ce59795 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Mon, 10 Oct 2022 11:08:33 +0300 Subject: [PATCH 11/12] fix benchmarks compilation --- bin/millau/runtime/src/lib.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/bin/millau/runtime/src/lib.rs b/bin/millau/runtime/src/lib.rs index cae2c388ca..538417127e 100644 --- a/bin/millau/runtime/src/lib.rs +++ b/bin/millau/runtime/src/lib.rs @@ -424,7 +424,9 @@ 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; +} +parameter_types! { /// Maximal number of authorities at Rialto. pub const MaxAuthoritiesAtRialto: u32 = bp_rialto::MAX_AUTHORITIES_COUNT; /// Maximal size of SCALE-encoded Rialto header. From 166c76a70f717a613cadc0be0b93e4728a2c11e8 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Mon, 10 Oct 2022 11:16:38 +0300 Subject: [PATCH 12/12] fmt --- modules/grandpa/src/lib.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/grandpa/src/lib.rs b/modules/grandpa/src/lib.rs index 772d5dc6f2..c4cbadcb38 100644 --- a/modules/grandpa/src/lib.rs +++ b/modules/grandpa/src/lib.rs @@ -971,7 +971,8 @@ mod tests { // Make sure that the authority set actually changed upon importing our header assert_eq!( >::get(), - StoredAuthoritySet::::try_new(next_authorities, next_set_id).unwrap(), + StoredAuthoritySet::::try_new(next_authorities, next_set_id) + .unwrap(), ); }) }