GRANDPA module: store accepted justifications (#2298) (#2301)

Store accepted justifications in events.
This commit is contained in:
Serban Iorga
2023-07-27 15:50:17 +03:00
committed by Bastian Köcher
parent 5f73a456c5
commit 7807b9de93
27 changed files with 193 additions and 63 deletions
+1
View File
@@ -13,6 +13,7 @@ scale-info = { version = "2.9.0", default-features = false, features = ["derive"
# Bridge dependencies
bp-header-chain = { path = "../../../primitives/header-chain", default-features = false }
bp-messages = { path = "../../../primitives/messages", default-features = false }
bp-millau = { path = "../../../primitives/chain-millau", default-features = false }
bp-parachains = { path = "../../../primitives/parachains", default-features = false }
+10
View File
@@ -882,12 +882,22 @@ impl_runtime_apis! {
fn best_finalized() -> Option<HeaderId<bp_rialto::Hash, bp_rialto::BlockNumber>> {
BridgeRialtoGrandpa::best_finalized()
}
fn accepted_grandpa_finality_proofs(
) -> Vec<bp_header_chain::justification::GrandpaJustification<bp_rialto::Header>> {
BridgeRialtoGrandpa::accepted_finality_proofs()
}
}
impl bp_westend::WestendFinalityApi<Block> for Runtime {
fn best_finalized() -> Option<HeaderId<bp_westend::Hash, bp_westend::BlockNumber>> {
BridgeWestendGrandpa::best_finalized()
}
fn accepted_grandpa_finality_proofs(
) -> Vec<bp_header_chain::justification::GrandpaJustification<bp_westend::Header>> {
BridgeWestendGrandpa::accepted_finality_proofs()
}
}
impl bp_westend::AssetHubWestendFinalityApi<Block> for Runtime {
@@ -16,6 +16,7 @@ scale-info = { version = "2.9.0", default-features = false, features = ["derive"
# Bridge depedencies
bp-header-chain = { path = "../../../primitives/header-chain", default-features = false }
bp-messages = { path = "../../../primitives/messages", default-features = false }
bp-millau = { path = "../../../primitives/chain-millau", default-features = false }
bp-relayers = { path = "../../../primitives/relayers", default-features = false }
@@ -746,6 +746,11 @@ impl_runtime_apis! {
fn best_finalized() -> Option<HeaderId<bp_millau::Hash, bp_millau::BlockNumber>> {
BridgeMillauGrandpa::best_finalized()
}
fn accepted_grandpa_finality_proofs(
) -> Vec<bp_header_chain::justification::GrandpaJustification<bp_millau::Header>> {
BridgeMillauGrandpa::accepted_finality_proofs()
}
}
impl bp_millau::ToMillauOutboundLaneApi<Block> for Runtime {
+1
View File
@@ -12,6 +12,7 @@ scale-info = { version = "2.9.0", default-features = false, features = ["derive"
# Bridge dependencies
bp-header-chain = { path = "../../../primitives/header-chain", default-features = false }
bp-messages = { path = "../../../primitives/messages", default-features = false }
bp-millau = { path = "../../../primitives/chain-millau", default-features = false }
bp-relayers = { path = "../../../primitives/relayers", default-features = false }
+5
View File
@@ -694,6 +694,11 @@ impl_runtime_apis! {
fn best_finalized() -> Option<HeaderId<bp_millau::Hash, bp_millau::BlockNumber>> {
BridgeMillauGrandpa::best_finalized()
}
fn accepted_grandpa_finality_proofs(
) -> Vec<bp_header_chain::justification::GrandpaJustification<bp_millau::Header>> {
BridgeMillauGrandpa::accepted_finality_proofs()
}
}
impl sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block> for Runtime {
+22 -6
View File
@@ -49,7 +49,7 @@ use sp_runtime::{
traits::{Header as HeaderT, Zero},
SaturatedConversion,
};
use sp_std::{boxed::Box, convert::TryInto};
use sp_std::{boxed::Box, convert::TryInto, prelude::*};
mod call_ext;
#[cfg(test)]
@@ -237,7 +237,7 @@ 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 });
Self::deposit_event(Event::UpdatedBestFinalizedHeader { number, hash, justification });
Ok(PostDispatchInfo { actual_weight: Some(actual_weight), pays_fee })
}
@@ -402,6 +402,8 @@ pub mod pallet {
UpdatedBestFinalizedHeader {
number: BridgedBlockNumber<T, I>,
hash: BridgedBlockHash<T, I>,
/// Justification.
justification: GrandpaJustification<BridgedHeader<T, I>>,
},
}
@@ -603,10 +605,22 @@ pub mod pallet {
}
}
impl<T: Config<I>, I: 'static> Pallet<T, I> {
/// Get the best finalized block number.
pub fn best_finalized_number() -> Option<BridgedBlockNumber<T, I>> {
BestFinalized::<T, I>::get().map(|id| id.number())
impl<T: Config<I>, I: 'static> Pallet<T, I>
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>>> {
frame_system::Pallet::<T>::read_events_no_consensus()
.filter_map(|event| {
if let Event::<T, I>::UpdatedBestFinalizedHeader { justification, .. } =
event.event.try_into().ok()?
{
return Some(justification)
}
None
})
.collect()
}
}
@@ -913,10 +927,12 @@ mod tests {
event: TestEvent::Grandpa(Event::UpdatedBestFinalizedHeader {
number: *header.number(),
hash: header.hash(),
justification: justification.clone(),
}),
topics: vec![],
}],
);
assert_eq!(Pallet::<TestRuntime>::accepted_finality_proofs(), vec![justification]);
})
}
+16 -8
View File
@@ -691,12 +691,13 @@ pub(crate) mod tests {
use super::*;
use crate::mock::{
run_test, test_relay_header, BigParachainHeader, RegularParachainHasher,
RegularParachainHeader, RuntimeEvent as TestEvent, RuntimeOrigin, TestRuntime,
UNTRACKED_PARACHAIN_ID,
RegularParachainHeader, RelayBlockHeader, RuntimeEvent as TestEvent, RuntimeOrigin,
TestRuntime, UNTRACKED_PARACHAIN_ID,
};
use bp_test_utils::prepare_parachain_heads_proof;
use codec::Encode;
use bp_header_chain::justification::GrandpaJustification;
use bp_parachains::{
BestParaHeadHash, BridgeParachainCall, ImportedParaHeadsKeyProvider, ParasInfoKeyProvider,
};
@@ -740,7 +741,10 @@ pub(crate) mod tests {
test_relay_header(0, state_root).hash()
}
fn proceed(num: RelayBlockNumber, state_root: RelayBlockHash) -> ParaHash {
fn proceed(
num: RelayBlockNumber,
state_root: RelayBlockHash,
) -> (ParaHash, GrandpaJustification<RelayBlockHeader>) {
pallet_bridge_grandpa::Pallet::<TestRuntime, BridgesGrandpaPalletInstance>::on_initialize(
0,
);
@@ -752,11 +756,11 @@ pub(crate) mod tests {
pallet_bridge_grandpa::Pallet::<TestRuntime, BridgesGrandpaPalletInstance>::submit_finality_proof(
RuntimeOrigin::signed(1),
Box::new(header),
justification,
justification.clone(),
)
);
hash
(hash, justification)
}
fn initial_best_head(parachain: u32) -> ParaInfo {
@@ -993,7 +997,7 @@ pub(crate) mod tests {
);
// import head#10 of parachain#1 at relay block #1
let relay_1_hash = proceed(1, state_root_10);
let (relay_1_hash, justification) = proceed(1, state_root_10);
assert_ok!(import_parachain_1_head(1, state_root_10, parachains_10, proof_10));
assert_eq!(
ParasInfo::<TestRuntime>::get(ParaId(1)),
@@ -1032,6 +1036,7 @@ pub(crate) mod tests {
pallet_bridge_grandpa::Event::UpdatedBestFinalizedHeader {
number: 1,
hash: relay_1_hash,
justification
}
),
topics: vec![],
@@ -1149,7 +1154,7 @@ pub(crate) mod tests {
// try to import head#0 of parachain#1 at relay block#1
// => call succeeds, but nothing is changed
let relay_1_hash = proceed(1, state_root);
let (relay_1_hash, justification) = proceed(1, state_root);
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!(
@@ -1169,6 +1174,7 @@ pub(crate) mod tests {
pallet_bridge_grandpa::Event::UpdatedBestFinalizedHeader {
number: 1,
hash: relay_1_hash,
justification
}
),
topics: vec![],
@@ -1197,7 +1203,7 @@ pub(crate) mod tests {
initialize(state_root_5);
// head#10 of parachain#1 at relay block#1
let relay_1_hash = proceed(1, state_root_10);
let (relay_1_hash, justification) = proceed(1, state_root_10);
assert_ok!(import_parachain_1_head(1, state_root_10, parachains_10, proof_10));
assert_eq!(
ParasInfo::<TestRuntime>::get(ParaId(1)),
@@ -1218,6 +1224,7 @@ pub(crate) mod tests {
pallet_bridge_grandpa::Event::UpdatedBestFinalizedHeader {
number: 1,
hash: relay_1_hash,
justification: justification.clone()
}
),
topics: vec![],
@@ -1255,6 +1262,7 @@ pub(crate) mod tests {
pallet_bridge_grandpa::Event::UpdatedBestFinalizedHeader {
number: 1,
hash: relay_1_hash,
justification
}
),
topics: vec![],
+1 -1
View File
@@ -69,4 +69,4 @@ pub const WITH_KUSAMA_GRANDPA_PALLET_NAME: &str = "BridgeKusamaGrandpa";
/// reserve.
pub const MAX_NESTED_PARACHAIN_HEAD_DATA_SIZE: u32 = 128;
decl_bridge_finality_runtime_apis!(kusama);
decl_bridge_finality_runtime_apis!(kusama, grandpa);
+2 -2
View File
@@ -25,7 +25,7 @@ use bp_header_chain::ChainWithGrandpa;
use bp_messages::{
InboundMessageDetails, LaneId, MessageNonce, MessagePayload, OutboundMessageDetails,
};
use bp_runtime::{decl_bridge_runtime_apis, Chain};
use bp_runtime::{decl_bridge_finality_runtime_apis, decl_bridge_runtime_apis, Chain};
use frame_support::{
dispatch::DispatchClass,
weights::{constants::WEIGHT_REF_TIME_PER_SECOND, IdentityFee, Weight},
@@ -244,4 +244,4 @@ pub const WITH_MILLAU_MESSAGES_PALLET_NAME: &str = "BridgeMillauMessages";
/// Name of the transaction payment pallet at the Millau runtime.
pub const TRANSACTION_PAYMENT_PALLET_NAME: &str = "TransactionPayment";
decl_bridge_runtime_apis!(millau);
decl_bridge_runtime_apis!(millau, grandpa);
+1 -1
View File
@@ -69,4 +69,4 @@ pub const WITH_POLKADOT_GRANDPA_PALLET_NAME: &str = "BridgePolkadotGrandpa";
/// reserve.
pub const MAX_NESTED_PARACHAIN_HEAD_DATA_SIZE: u32 = 128;
decl_bridge_finality_runtime_apis!(polkadot);
decl_bridge_finality_runtime_apis!(polkadot, grandpa);
+2 -2
View File
@@ -22,7 +22,7 @@ use bp_header_chain::ChainWithGrandpa;
use bp_messages::{
InboundMessageDetails, LaneId, MessageNonce, MessagePayload, OutboundMessageDetails,
};
use bp_runtime::{decl_bridge_runtime_apis, Chain};
use bp_runtime::{decl_bridge_finality_runtime_apis, decl_bridge_runtime_apis, Chain};
use frame_support::{
dispatch::DispatchClass,
weights::{constants::WEIGHT_REF_TIME_PER_SECOND, IdentityFee, Weight},
@@ -211,4 +211,4 @@ pub const PARAS_REGISTRAR_PALLET_NAME: &str = "Registrar";
/// Name of the parachains pallet in the Rialto runtime.
pub const PARAS_PALLET_NAME: &str = "Paras";
decl_bridge_runtime_apis!(rialto);
decl_bridge_runtime_apis!(rialto, grandpa);
+1 -1
View File
@@ -73,4 +73,4 @@ pub const WITH_ROCOCO_GRANDPA_PALLET_NAME: &str = "BridgeRococoGrandpa";
/// reserve.
pub const MAX_NESTED_PARACHAIN_HEAD_DATA_SIZE: u32 = 128;
decl_bridge_finality_runtime_apis!(rococo);
decl_bridge_finality_runtime_apis!(rococo, grandpa);
+2 -1
View File
@@ -19,6 +19,7 @@
#![allow(clippy::too_many_arguments)]
pub use bp_polkadot_core::*;
use frame_support::sp_std::prelude::*;
use bp_header_chain::ChainWithGrandpa;
use bp_runtime::{decl_bridge_finality_runtime_apis, Chain, Parachain};
@@ -103,6 +104,6 @@ pub const MAX_NESTED_PARACHAIN_HEAD_DATA_SIZE: u32 = 128;
/// Identifier of `AssetHubWestend` parachain at the Westend relay chain.
pub const ASSET_HUB_WESTEND_PARACHAIN_ID: u32 = 1000;
decl_bridge_finality_runtime_apis!(westend);
decl_bridge_finality_runtime_apis!(westend, grandpa);
decl_bridge_finality_runtime_apis!(AssetHubWestend);
+1 -1
View File
@@ -62,4 +62,4 @@ impl ChainWithGrandpa for Wococo {
/// Name of the With-Wococo GRANDPA pallet instance that is deployed at bridged chains.
pub const WITH_WOCOCO_GRANDPA_PALLET_NAME: &str = "BridgeWococoGrandpa";
decl_bridge_finality_runtime_apis!(wococo);
decl_bridge_finality_runtime_apis!(wococo, grandpa);
+15 -1
View File
@@ -21,7 +21,7 @@
use bp_runtime::{
BasicOperatingMode, Chain, HashOf, HasherOf, HeaderOf, RawStorageProof, StorageProofChecker,
StorageProofError,
StorageProofError, UnderlyingChainProvider,
};
use codec::{Codec, Decode, Encode, EncodeLike, MaxEncodedLen};
use core::{clone::Clone, cmp::Eq, default::Default, fmt::Debug};
@@ -234,3 +234,17 @@ pub trait ChainWithGrandpa: Chain {
/// refund amount and doing calls which exceed the limit, may be costly to submitter.
const AVERAGE_HEADER_SIZE_IN_JUSTIFICATION: u32;
}
/// A trait that provides the type of the underlying `ChainWithGrandpa`.
pub trait UnderlyingChainWithGrandpaProvider: UnderlyingChainProvider {
/// Underlying `ChainWithGrandpa` type.
type ChainWithGrandpa: ChainWithGrandpa;
}
impl<T> UnderlyingChainWithGrandpaProvider for T
where
T: UnderlyingChainProvider,
T::Chain: ChainWithGrandpa,
{
type ChainWithGrandpa = T::Chain;
}
+20 -3
View File
@@ -279,10 +279,11 @@ pub type TransactionEraOf<C> = crate::TransactionEra<BlockNumberOf<C>, HashOf<C>
/// - `<ThisChain>FinalityApi`
/// - constants that are stringified names of runtime API methods:
/// - `BEST_FINALIZED_<THIS_CHAIN>_HEADER_METHOD`
/// - `<THIS_CHAIN>_ACCEPTED_<CONSENSUS>_FINALITY_PROOFS_METHOD`
/// The name of the chain has to be specified in snake case (e.g. `rialto_parachain`).
#[macro_export]
macro_rules! decl_bridge_finality_runtime_apis {
($chain: ident) => {
($chain: ident $(, $consensus: ident => $justification_type: ty)?) => {
bp_runtime::paste::item! {
mod [<$chain _finality_api>] {
use super::*;
@@ -291,6 +292,13 @@ macro_rules! decl_bridge_finality_runtime_apis {
pub const [<BEST_FINALIZED_ $chain:upper _HEADER_METHOD>]: &str =
stringify!([<$chain:camel FinalityApi_best_finalized>]);
$(
/// 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>]);
)?
sp_api::decl_runtime_apis! {
/// API for querying information about the finalized chain headers.
///
@@ -299,6 +307,12 @@ macro_rules! decl_bridge_finality_runtime_apis {
pub trait [<$chain:camel FinalityApi>] {
/// Returns number and hash of the best finalized header known to the bridge module.
fn best_finalized() -> Option<bp_runtime::HeaderId<Hash, BlockNumber>>;
$(
/// Returns the justifications accepted in the current block.
fn [<accepted_ $consensus:lower _finality_proofs>](
) -> Vec<$justification_type>;
)?
}
}
}
@@ -306,6 +320,9 @@ macro_rules! decl_bridge_finality_runtime_apis {
pub use [<$chain _finality_api>]::*;
}
};
($chain: ident, grandpa) => {
decl_bridge_finality_runtime_apis!($chain, grandpa => bp_header_chain::justification::GrandpaJustification<Header>);
};
}
/// Convenience macro that declares bridge messages runtime apis and related constants for a chain.
@@ -376,8 +393,8 @@ macro_rules! decl_bridge_messages_runtime_apis {
/// The name of the chain has to be specified in snake case (e.g. `rialto_parachain`).
#[macro_export]
macro_rules! decl_bridge_runtime_apis {
($chain: ident) => {
bp_runtime::decl_bridge_finality_runtime_apis!($chain);
($chain: ident $(, $consensus: ident)?) => {
bp_runtime::decl_bridge_finality_runtime_apis!($chain $(, $consensus)?);
bp_runtime::decl_bridge_messages_runtime_apis!($chain);
};
}
+9 -2
View File
@@ -16,9 +16,11 @@
//! Types used to connect to the Kusama chain.
use bp_kusama::AccountInfoStorageMapKeyProvider;
use bp_kusama::{AccountInfoStorageMapKeyProvider, KUSAMA_ACCEPTED_GRANDPA_FINALITY_PROOFS_METHOD};
use bp_runtime::ChainId;
use relay_substrate_client::{Chain, ChainWithBalances, RelayChain, UnderlyingChainProvider};
use relay_substrate_client::{
Chain, ChainWithBalances, ChainWithGrandpa, RelayChain, UnderlyingChainProvider,
};
use sp_core::storage::StorageKey;
use std::time::Duration;
@@ -47,6 +49,11 @@ impl Chain for Kusama {
type Call = ();
}
impl ChainWithGrandpa for Kusama {
const ACCEPTED_FINALITY_PROOFS_METHOD: &'static str =
KUSAMA_ACCEPTED_GRANDPA_FINALITY_PROOFS_METHOD;
}
impl ChainWithBalances for Kusama {
fn account_info_storage_key(account_id: &Self::AccountId) -> StorageKey {
AccountInfoStorageMapKeyProvider::final_key(account_id)
+9 -3
View File
@@ -17,12 +17,13 @@
//! Types used to connect to the Millau-Substrate chain.
use bp_messages::MessageNonce;
use bp_millau::MILLAU_ACCEPTED_GRANDPA_FINALITY_PROOFS_METHOD;
use bp_runtime::ChainId;
use codec::{Compact, Decode, Encode};
use relay_substrate_client::{
BalanceOf, Chain, ChainWithBalances, ChainWithMessages, ChainWithTransactions,
ChainWithUtilityPallet, Error as SubstrateError, FullRuntimeUtilityPallet, NonceOf, SignParam,
UnderlyingChainProvider, UnsignedTransaction,
BalanceOf, Chain, ChainWithBalances, ChainWithGrandpa, ChainWithMessages,
ChainWithTransactions, ChainWithUtilityPallet, Error as SubstrateError,
FullRuntimeUtilityPallet, NonceOf, SignParam, UnderlyingChainProvider, UnsignedTransaction,
};
use sp_core::{storage::StorageKey, Pair};
use sp_runtime::{generic::SignedPayload, traits::IdentifyAccount};
@@ -65,6 +66,11 @@ impl Chain for Millau {
type Call = millau_runtime::RuntimeCall;
}
impl ChainWithGrandpa for Millau {
const ACCEPTED_FINALITY_PROOFS_METHOD: &'static str =
MILLAU_ACCEPTED_GRANDPA_FINALITY_PROOFS_METHOD;
}
impl ChainWithBalances for Millau {
fn account_info_storage_key(account_id: &Self::AccountId) -> StorageKey {
use frame_support::storage::generator::StorageMap;
+11 -2
View File
@@ -16,9 +16,13 @@
//! Types used to connect to the Polkadot chain.
use bp_polkadot::AccountInfoStorageMapKeyProvider;
use bp_polkadot::{
AccountInfoStorageMapKeyProvider, POLKADOT_ACCEPTED_GRANDPA_FINALITY_PROOFS_METHOD,
};
use bp_runtime::ChainId;
use relay_substrate_client::{Chain, ChainWithBalances, RelayChain, UnderlyingChainProvider};
use relay_substrate_client::{
Chain, ChainWithBalances, ChainWithGrandpa, RelayChain, UnderlyingChainProvider,
};
use sp_core::storage::StorageKey;
use std::time::Duration;
@@ -47,6 +51,11 @@ impl Chain for Polkadot {
type Call = ();
}
impl ChainWithGrandpa for Polkadot {
const ACCEPTED_FINALITY_PROOFS_METHOD: &'static str =
POLKADOT_ACCEPTED_GRANDPA_FINALITY_PROOFS_METHOD;
}
impl ChainWithBalances for Polkadot {
fn account_info_storage_key(account_id: &Self::AccountId) -> StorageKey {
AccountInfoStorageMapKeyProvider::final_key(account_id)
+9 -3
View File
@@ -17,12 +17,13 @@
//! Types used to connect to the Rialto-Substrate chain.
use bp_messages::MessageNonce;
use bp_rialto::RIALTO_ACCEPTED_GRANDPA_FINALITY_PROOFS_METHOD;
use bp_runtime::ChainId;
use codec::{Compact, Decode, Encode};
use relay_substrate_client::{
BalanceOf, Chain, ChainWithBalances, ChainWithMessages, ChainWithTransactions,
Error as SubstrateError, NonceOf, RelayChain, SignParam, UnderlyingChainProvider,
UnsignedTransaction,
BalanceOf, Chain, ChainWithBalances, ChainWithGrandpa, ChainWithMessages,
ChainWithTransactions, Error as SubstrateError, NonceOf, RelayChain, SignParam,
UnderlyingChainProvider, UnsignedTransaction,
};
use sp_core::{storage::StorageKey, Pair};
use sp_runtime::{generic::SignedPayload, traits::IdentifyAccount};
@@ -50,6 +51,11 @@ impl Chain for Rialto {
type Call = rialto_runtime::RuntimeCall;
}
impl ChainWithGrandpa for Rialto {
const ACCEPTED_FINALITY_PROOFS_METHOD: &'static str =
RIALTO_ACCEPTED_GRANDPA_FINALITY_PROOFS_METHOD;
}
impl RelayChain for Rialto {
const PARAS_PALLET_NAME: &'static str = bp_rialto::PARAS_PALLET_NAME;
const PARACHAINS_FINALITY_PALLET_NAME: &'static str =
+9 -1
View File
@@ -16,8 +16,11 @@
//! Types used to connect to the Rococo-Substrate chain.
use bp_rococo::ROCOCO_ACCEPTED_GRANDPA_FINALITY_PROOFS_METHOD;
use bp_runtime::ChainId;
use relay_substrate_client::{Chain, ChainWithBalances, RelayChain, UnderlyingChainProvider};
use relay_substrate_client::{
Chain, ChainWithBalances, ChainWithGrandpa, RelayChain, UnderlyingChainProvider,
};
use sp_core::storage::StorageKey;
use std::time::Duration;
@@ -46,6 +49,11 @@ impl Chain for Rococo {
type Call = ();
}
impl ChainWithGrandpa for Rococo {
const ACCEPTED_FINALITY_PROOFS_METHOD: &'static str =
ROCOCO_ACCEPTED_GRANDPA_FINALITY_PROOFS_METHOD;
}
impl ChainWithBalances for Rococo {
fn account_info_storage_key(account_id: &Self::AccountId) -> StorageKey {
bp_rococo::AccountInfoStorageMapKeyProvider::final_key(account_id)
+7 -15
View File
@@ -16,6 +16,7 @@
use crate::calls::UtilityCall;
use bp_header_chain::UnderlyingChainWithGrandpaProvider;
use bp_messages::MessageNonce;
use bp_runtime::{
Chain as ChainBase, ChainId, EncodedOrDecodedCall, HashOf, Parachain as ParachainBase,
@@ -77,22 +78,13 @@ pub trait RelayChain: Chain {
///
/// Keep in mind that parachains are relying on relay chain GRANDPA, so they should not implement
/// this trait.
pub trait ChainWithGrandpa: Chain {
/// Name of the bridge GRANDPA pallet (used in `construct_runtime` macro call) that is deployed
/// at some other chain to bridge with this `ChainWithGrandpa`.
pub trait ChainWithGrandpa: Chain + UnderlyingChainWithGrandpaProvider {
/// Name of the runtime API method that is returning the GRANDPA justifications accepted
/// by the `submit_finality_proofs` extrinsic in the queried block.
///
/// We assume that all chains that are bridging with this `ChainWithGrandpa` are using
/// the same name.
const WITH_CHAIN_GRANDPA_PALLET_NAME: &'static str;
}
impl<T> ChainWithGrandpa for T
where
T: Chain + UnderlyingChainProvider,
T::Chain: bp_header_chain::ChainWithGrandpa,
{
const WITH_CHAIN_GRANDPA_PALLET_NAME: &'static str =
<T::Chain as bp_header_chain::ChainWithGrandpa>::WITH_CHAIN_GRANDPA_PALLET_NAME;
/// Keep in mind that this method is normally provided by the other chain, which is
/// bridged with this chain.
const ACCEPTED_FINALITY_PROOFS_METHOD: &'static str;
}
/// Substrate-based parachain from minimal relay-client point of view.
+9 -1
View File
@@ -17,7 +17,10 @@
//! Types used to connect to the Westend chain.
use bp_runtime::ChainId;
use relay_substrate_client::{Chain, ChainWithBalances, RelayChain, UnderlyingChainProvider};
use bp_westend::WESTEND_ACCEPTED_GRANDPA_FINALITY_PROOFS_METHOD;
use relay_substrate_client::{
Chain, ChainWithBalances, ChainWithGrandpa, RelayChain, UnderlyingChainProvider,
};
use sp_core::storage::StorageKey;
use std::time::Duration;
@@ -46,6 +49,11 @@ impl Chain for Westend {
type Call = ();
}
impl ChainWithGrandpa for Westend {
const ACCEPTED_FINALITY_PROOFS_METHOD: &'static str =
WESTEND_ACCEPTED_GRANDPA_FINALITY_PROOFS_METHOD;
}
impl RelayChain for Westend {
const PARAS_PALLET_NAME: &'static str = bp_westend::PARAS_PALLET_NAME;
const PARACHAINS_FINALITY_PALLET_NAME: &'static str =
+9 -1
View File
@@ -17,7 +17,10 @@
//! Types used to connect to the Wococo-Substrate chain.
use bp_runtime::ChainId;
use relay_substrate_client::{Chain, ChainWithBalances, RelayChain, UnderlyingChainProvider};
use bp_wococo::WOCOCO_ACCEPTED_GRANDPA_FINALITY_PROOFS_METHOD;
use relay_substrate_client::{
Chain, ChainWithBalances, ChainWithGrandpa, RelayChain, UnderlyingChainProvider,
};
use sp_core::storage::StorageKey;
use std::time::Duration;
@@ -46,6 +49,11 @@ impl Chain for Wococo {
type Call = ();
}
impl ChainWithGrandpa for Wococo {
const ACCEPTED_FINALITY_PROOFS_METHOD: &'static str =
WOCOCO_ACCEPTED_GRANDPA_FINALITY_PROOFS_METHOD;
}
impl ChainWithBalances for Wococo {
fn account_info_storage_key(account_id: &Self::AccountId) -> StorageKey {
bp_wococo::AccountInfoStorageMapKeyProvider::final_key(account_id)
@@ -20,7 +20,8 @@ use crate::error::Error;
use async_trait::async_trait;
use bp_header_chain::{
justification::{verify_and_optimize_justification, GrandpaJustification},
ConsensusLogReader, FinalityProof, GrandpaConsensusLogReader,
ChainWithGrandpa as ChainWithGrandpaBase, ConsensusLogReader, FinalityProof,
GrandpaConsensusLogReader,
};
use bp_runtime::{BasicOperatingMode, HeaderIdProvider, OperatingMode};
use codec::{Decode, Encode};
@@ -83,8 +84,10 @@ pub trait Engine<C: Chain>: Send {
}
/// A method to subscribe to encoded finality proofs, given source client.
async fn finality_proofs(client: &Client<C>) -> Result<Subscription<Bytes>, SubstrateError> {
client.subscribe_finality_justifications::<Self::FinalityClient>().await
async fn source_finality_proofs(
source_client: &Client<C>,
) -> Result<Subscription<Bytes>, SubstrateError> {
source_client.subscribe_finality_justifications::<Self::FinalityClient>().await
}
/// Optimize finality proof before sending it to the target node.
@@ -139,11 +142,15 @@ impl<C: ChainWithGrandpa> Engine<C> for Grandpa<C> {
type OperatingMode = BasicOperatingMode;
fn is_initialized_key() -> StorageKey {
bp_header_chain::storage_keys::best_finalized_key(C::WITH_CHAIN_GRANDPA_PALLET_NAME)
bp_header_chain::storage_keys::best_finalized_key(
C::ChainWithGrandpa::WITH_CHAIN_GRANDPA_PALLET_NAME,
)
}
fn pallet_operating_mode_key() -> StorageKey {
bp_header_chain::storage_keys::pallet_operating_mode_key(C::WITH_CHAIN_GRANDPA_PALLET_NAME)
bp_header_chain::storage_keys::pallet_operating_mode_key(
C::ChainWithGrandpa::WITH_CHAIN_GRANDPA_PALLET_NAME,
)
}
async fn optimize_proof<TargetChain: Chain>(
@@ -152,7 +159,7 @@ impl<C: ChainWithGrandpa> Engine<C> for Grandpa<C> {
proof: &mut Self::FinalityProof,
) -> Result<(), SubstrateError> {
let current_authority_set_key = bp_header_chain::storage_keys::current_authority_set_key(
C::WITH_CHAIN_GRANDPA_PALLET_NAME,
C::ChainWithGrandpa::WITH_CHAIN_GRANDPA_PALLET_NAME,
);
let (authority_set, authority_set_id): (
sp_consensus_grandpa::AuthorityList,
@@ -199,7 +206,7 @@ impl<C: ChainWithGrandpa> Engine<C> for Grandpa<C> {
// But now there are problems with this approach - `CurrentSetId` may return invalid value.
// So here we're waiting for the next justification, read the authorities set and then try
// to figure out the set id with bruteforce.
let justifications = Self::finality_proofs(&source_client)
let justifications = Self::source_finality_proofs(&source_client)
.await
.map_err(|err| Error::Subscribe(C::NAME, err))?;
// Read next justification - the header that it finalizes will be used as initial header.
@@ -234,7 +234,7 @@ impl<P: SubstrateFinalitySyncPipeline> SourceClient<FinalitySyncPipelineAdapter<
async fn finality_proofs(&self) -> Result<Self::FinalityProofsStream, Error> {
Ok(unfold(
P::FinalityEngine::finality_proofs(&self.client).await?,
P::FinalityEngine::source_finality_proofs(&self.client).await?,
move |subscription| async move {
loop {
let log_error = |err| {