mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-31 11:01:01 +00:00
Backport: Implement basic equivocations detection loop (#2375)
* Implement basic equivocations detection loop (#2367) * FinalityProofsBuf adjustments - store a Vec<FinalityProof> - transform prune `buf_limit` to Option * FinalityProof: add target_header_hash() * Target client: implement best_synced_header_hash() * Implement first version of the equivocations detection loop * Address code review comments * Leftover * polkadot-staging adjustments
This commit is contained in:
committed by
Bastian Köcher
parent
cc3bbc690b
commit
588508acd4
@@ -17,14 +17,16 @@
|
||||
//! Default generic implementation of equivocation source for basic Substrate client.
|
||||
|
||||
use crate::{
|
||||
equivocation::{EquivocationDetectionPipelineAdapter, SubstrateEquivocationDetectionPipeline},
|
||||
finality_base::engine::Engine,
|
||||
equivocation::{
|
||||
EquivocationDetectionPipelineAdapter, FinalityProoffOf, FinalityVerificationContextfOf,
|
||||
SubstrateEquivocationDetectionPipeline,
|
||||
},
|
||||
finality_base::{best_synced_header_id, engine::Engine},
|
||||
};
|
||||
|
||||
use crate::equivocation::{FinalityProoffOf, FinalityVerificationContextfOf};
|
||||
use async_trait::async_trait;
|
||||
use bp_header_chain::HeaderFinalityInfo;
|
||||
use bp_runtime::BlockNumberOf;
|
||||
use bp_runtime::{BlockNumberOf, HashOf};
|
||||
use equivocation_detector::TargetClient;
|
||||
use relay_substrate_client::{Client, Error};
|
||||
use relay_utils::relay_loop::Client as RelayClient;
|
||||
@@ -59,6 +61,24 @@ impl<P: SubstrateEquivocationDetectionPipeline> RelayClient for SubstrateEquivoc
|
||||
impl<P: SubstrateEquivocationDetectionPipeline>
|
||||
TargetClient<EquivocationDetectionPipelineAdapter<P>> for SubstrateEquivocationTarget<P>
|
||||
{
|
||||
async fn best_finalized_header_number(
|
||||
&self,
|
||||
) -> Result<BlockNumberOf<P::TargetChain>, Self::Error> {
|
||||
self.client.best_finalized_header_number().await
|
||||
}
|
||||
|
||||
async fn best_synced_header_hash(
|
||||
&self,
|
||||
at: BlockNumberOf<P::TargetChain>,
|
||||
) -> Result<Option<HashOf<P::SourceChain>>, Self::Error> {
|
||||
Ok(best_synced_header_id::<P::SourceChain, P::TargetChain>(
|
||||
&self.client,
|
||||
self.client.header_by_number(at).await?.hash(),
|
||||
)
|
||||
.await?
|
||||
.map(|id| id.hash()))
|
||||
}
|
||||
|
||||
async fn finality_verification_context(
|
||||
&self,
|
||||
at: BlockNumberOf<P::TargetChain>,
|
||||
|
||||
@@ -20,7 +20,7 @@ use crate::{
|
||||
finality::{
|
||||
FinalitySyncPipelineAdapter, SubmitFinalityProofCallBuilder, SubstrateFinalitySyncPipeline,
|
||||
},
|
||||
finality_base::{engine::Engine, SubstrateFinalityProof},
|
||||
finality_base::{best_synced_header_id, engine::Engine, SubstrateFinalityProof},
|
||||
TransactionParams,
|
||||
};
|
||||
|
||||
@@ -31,6 +31,7 @@ use relay_substrate_client::{
|
||||
TransactionTracker, UnsignedTransaction,
|
||||
};
|
||||
use relay_utils::relay_loop::Client as RelayClient;
|
||||
use sp_runtime::traits::Header;
|
||||
|
||||
/// Substrate client as Substrate finality target.
|
||||
pub struct SubstrateFinalityTarget<P: SubstrateFinalitySyncPipeline> {
|
||||
@@ -94,12 +95,11 @@ impl<P: SubstrateFinalitySyncPipeline> TargetClient<FinalitySyncPipelineAdapter<
|
||||
// we can't relay finality if bridge pallet at target chain is halted
|
||||
self.ensure_pallet_active().await?;
|
||||
|
||||
Ok(crate::messages_source::read_client_state::<P::TargetChain, P::SourceChain>(
|
||||
Ok(best_synced_header_id::<P::SourceChain, P::TargetChain>(
|
||||
&self.client,
|
||||
None,
|
||||
self.client.best_header().await?.hash(),
|
||||
)
|
||||
.await?
|
||||
.best_finalized_peer_at_best_self
|
||||
.ok_or(Error::BridgePalletIsNotInitialized)?)
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ use relay_substrate_client::{
|
||||
use sp_consensus_grandpa::{AuthorityList as GrandpaAuthoritiesSet, GRANDPA_ENGINE_ID};
|
||||
use sp_core::{storage::StorageKey, Bytes};
|
||||
use sp_runtime::{scale_info::TypeInfo, traits::Header, ConsensusEngineId};
|
||||
use std::marker::PhantomData;
|
||||
use std::{fmt::Debug, marker::PhantomData};
|
||||
|
||||
/// Finality engine, used by the Substrate chain.
|
||||
#[async_trait]
|
||||
@@ -48,11 +48,11 @@ pub trait Engine<C: Chain>: Send {
|
||||
/// Type of Finality RPC client used by this engine.
|
||||
type FinalityClient: SubstrateFinalityClient<C>;
|
||||
/// Type of finality proofs, used by consensus engine.
|
||||
type FinalityProof: FinalityProof<BlockNumberOf<C>> + Decode + Encode;
|
||||
type FinalityProof: FinalityProof<HashOf<C>, BlockNumberOf<C>> + Decode + Encode;
|
||||
/// The context needed for verifying finality proofs.
|
||||
type FinalityVerificationContext;
|
||||
type FinalityVerificationContext: Send;
|
||||
/// The type of the equivocation proof used by the consensus engine.
|
||||
type EquivocationProof: Send + Sync;
|
||||
type EquivocationProof: Clone + Debug + Send + Sync;
|
||||
/// The equivocations finder.
|
||||
type EquivocationsFinder: FindEquivocations<
|
||||
Self::FinalityProof,
|
||||
@@ -62,7 +62,7 @@ pub trait Engine<C: Chain>: Send {
|
||||
/// The type of the key owner proof used by the consensus engine.
|
||||
type KeyOwnerProof: Send;
|
||||
/// Type of bridge pallet initialization data.
|
||||
type InitializationData: std::fmt::Debug + Send + Sync + 'static;
|
||||
type InitializationData: Debug + Send + Sync + 'static;
|
||||
/// Type of bridge pallet operating mode.
|
||||
type OperatingMode: OperatingMode + 'static;
|
||||
|
||||
|
||||
@@ -20,7 +20,9 @@
|
||||
pub mod engine;
|
||||
|
||||
use crate::finality_base::engine::Engine;
|
||||
|
||||
use async_trait::async_trait;
|
||||
use bp_runtime::{HashOf, HeaderIdOf};
|
||||
use codec::Decode;
|
||||
use futures::{stream::unfold, Stream, StreamExt};
|
||||
use relay_substrate_client::{Chain, Client, Error};
|
||||
@@ -85,3 +87,21 @@ pub async fn finality_proofs<P: SubstrateFinalityPipeline>(
|
||||
)
|
||||
.boxed())
|
||||
}
|
||||
|
||||
/// Get the id of the best `SourceChain` header known to the `TargetChain` at the provided
|
||||
/// target block using the exposed runtime API method.
|
||||
///
|
||||
/// The runtime API method should be `<TargetChain>FinalityApi::best_finalized()`.
|
||||
pub async fn best_synced_header_id<SourceChain, TargetChain>(
|
||||
target_client: &Client<TargetChain>,
|
||||
at: HashOf<TargetChain>,
|
||||
) -> Result<Option<HeaderIdOf<SourceChain>>, Error>
|
||||
where
|
||||
SourceChain: Chain,
|
||||
TargetChain: Chain,
|
||||
{
|
||||
// now let's read id of best finalized peer header at our best finalized block
|
||||
target_client
|
||||
.typed_state_call(SourceChain::BEST_FINALIZED_HEADER_ID_METHOD.into(), (), Some(at))
|
||||
.await
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
//! `<BridgedName>` chain.
|
||||
|
||||
use crate::{
|
||||
finality_base::best_synced_header_id,
|
||||
messages_lane::{
|
||||
BatchProofTransaction, MessageLaneAdapter, ReceiveMessagesDeliveryProofCallBuilder,
|
||||
SubstrateMessageLane,
|
||||
@@ -428,11 +429,7 @@ where
|
||||
|
||||
// now let's read id of best finalized peer header at our best finalized block
|
||||
let peer_on_self_best_finalized_id =
|
||||
best_finalized_peer_header_at_self::<SelfChain, PeerChain>(
|
||||
self_client,
|
||||
self_best_id.hash(),
|
||||
)
|
||||
.await?;
|
||||
best_synced_header_id::<PeerChain, SelfChain>(self_client, self_best_id.hash()).await?;
|
||||
|
||||
// read actual header, matching the `peer_on_self_best_finalized_id` from the peer chain
|
||||
let actual_peer_on_self_best_finalized_id =
|
||||
|
||||
Reference in New Issue
Block a user