// Copyright 2019-2023 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 .
//! Types and functions intended to ease adding of new Bizinikiwi -> Bizinikiwi
//! finality pipelines.
pub mod engine;
use crate::finality_base::engine::Engine;
use async_trait::async_trait;
use codec::Decode;
use futures::{stream::unfold, Stream, StreamExt};
use pezbp_runtime::{HashOf, HeaderIdOf};
use relay_bizinikiwi_client::{Chain, Client, Error};
use std::{fmt::Debug, pin::Pin};
/// Bizinikiwi -> Bizinikiwi finality related pipeline.
#[async_trait]
pub trait BizinikiwiFinalityPipeline: 'static + Clone + Debug + Send + Sync {
/// Headers of this chain are submitted to the `TargetChain`.
type SourceChain: Chain;
/// Headers of the `SourceChain` are submitted to this chain.
type TargetChain: Chain;
/// Finality engine.
type FinalityEngine: Engine;
}
/// Bizinikiwi finality proof. Specific to the used `FinalityEngine`.
pub type BizinikiwiFinalityProof
=
<
::FinalityEngine as Engine<
::SourceChain,
>>::FinalityProof;
/// Bizinikiwi finality proofs stream.
pub type BizinikiwiFinalityProofsStream
=
Pin> + Send>>;
/// Subscribe to new finality proofs.
pub async fn finality_proofs(
client: &impl Client,
) -> Result, Error> {
Ok(unfold(
P::FinalityEngine::source_finality_proofs(client).await?,
move |mut subscription| async move {
loop {
let log_error = |err| {
tracing::error!(
target: "bridge",
error=?err,
source=%P::SourceChain::NAME,
"Failed to read justification target from the justifications stream"
);
};
let next_justification = subscription.next().await?;
let decoded_justification =
>::FinalityProof::decode(
&mut &next_justification[..],
);
let justification = match decoded_justification {
Ok(j) => j,
Err(err) => {
log_error(format!("decode failed with error {err:?}"));
continue;
},
};
return Some((justification, subscription));
}
},
)
.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 `FinalityApi::best_finalized()`.
pub async fn best_synced_header_id(
target_client: &impl Client,
at: HashOf,
) -> Result