Always run on-demand headers relay in complex relay (#975)

* always run on-demand headers relay in complex relay

* fix compilation
This commit is contained in:
Svyatoslav Nikolsky
2021-05-26 09:23:31 +03:00
committed by Bastian Köcher
parent cae105b55f
commit 6301ae0636
10 changed files with 175 additions and 290 deletions
+1 -1
View File
@@ -6,7 +6,7 @@ edition = "2018"
license = "GPL-3.0-or-later WITH Classpath-exception-2.0"
[dependencies]
async-std = "1.6.5"
async-std = { version = "1.6.5", features = ["attributes"] }
async-trait = "0.1.40"
codec = { package = "parity-scale-codec", version = "2.0.0" }
jsonrpsee-proc-macros = "=0.2.0-alpha.6"
@@ -21,6 +21,7 @@ use crate::client::Client;
use crate::error::Error;
use crate::sync_header::SyncHeader;
use async_std::sync::{Arc, Mutex};
use async_trait::async_trait;
use bp_header_chain::justification::GrandpaJustification;
use codec::Decode;
@@ -30,26 +31,41 @@ use relay_utils::relay_loop::Client as RelayClient;
use sp_runtime::traits::Header as HeaderT;
use std::{marker::PhantomData, pin::Pin};
/// Shared updatable reference to the maximal header number that we want to sync from the source.
pub type RequiredHeaderNumberRef<C> = Arc<Mutex<<C as bp_runtime::Chain>::BlockNumber>>;
/// Substrate node as finality source.
pub struct FinalitySource<C: Chain, P> {
client: Client<C>,
maximal_header_number: Option<RequiredHeaderNumberRef<C>>,
_phantom: PhantomData<P>,
}
impl<C: Chain, P> FinalitySource<C, P> {
/// Create new headers source using given client.
pub fn new(client: Client<C>) -> Self {
pub fn new(client: Client<C>, maximal_header_number: Option<RequiredHeaderNumberRef<C>>) -> Self {
FinalitySource {
client,
maximal_header_number,
_phantom: Default::default(),
}
}
/// Returns best finalized block number.
pub async fn on_chain_best_finalized_block_number(&self) -> Result<C::BlockNumber, Error> {
// we **CAN** continue to relay finality proofs if source node is out of sync, because
// target node may be missing proofs that are already available at the source
let finalized_header_hash = self.client.best_finalized_header_hash().await?;
let finalized_header = self.client.header_by_hash(finalized_header_hash).await?;
Ok(*finalized_header.number())
}
}
impl<C: Chain, P> Clone for FinalitySource<C, P> {
fn clone(&self) -> Self {
FinalitySource {
client: self.client.clone(),
maximal_header_number: self.maximal_header_number.clone(),
_phantom: Default::default(),
}
}
@@ -80,11 +96,16 @@ where
type FinalityProofsStream = Pin<Box<dyn Stream<Item = GrandpaJustification<C::Header>> + Send>>;
async fn best_finalized_block_number(&self) -> Result<P::Number, Error> {
// we **CAN** continue to relay finality proofs if source node is out of sync, because
// target node may be missing proofs that are already available at the source
let finalized_header_hash = self.client.best_finalized_header_hash().await?;
let finalized_header = self.client.header_by_hash(finalized_header_hash).await?;
Ok(*finalized_header.number())
let mut finalized_header_number = self.on_chain_best_finalized_block_number().await?;
// never return block number larger than requested. This way we'll never sync headers
// past `maximal_header_number`
if let Some(ref maximal_header_number) = self.maximal_header_number {
let maximal_header_number = *maximal_header_number.lock().await;
if finalized_header_number > maximal_header_number {
finalized_header_number = maximal_header_number;
}
}
Ok(finalized_header_number)
}
async fn header_and_finality_proof(