Refactor finality relay helpers (#1220)

* refactor finality relay helper definitions

* add missing doc

* removed commented code

* fmt

* disable rustfmt for macro

* move best_finalized method const to relay chain def
This commit is contained in:
Svyatoslav Nikolsky
2021-12-03 14:43:33 +03:00
committed by Bastian Köcher
parent f84590817b
commit e675b13042
37 changed files with 475 additions and 823 deletions
@@ -16,17 +16,8 @@
//! Kusama-to-Polkadot headers sync entrypoint.
use codec::Encode;
use sp_core::{Bytes, Pair};
use bp_header_chain::justification::GrandpaJustification;
use relay_kusama_client::{Kusama, SyncHeader as KusamaSyncHeader};
use relay_polkadot_client::{Polkadot, SigningParams as PolkadotSigningParams};
use relay_substrate_client::{Client, TransactionSignScheme, UnsignedTransaction};
use relay_utils::metrics::MetricsParams;
use substrate_relay_helper::finality_pipeline::{
SubstrateFinalitySyncPipeline, SubstrateFinalityToSubstrate,
};
use sp_core::Pair;
use substrate_relay_helper::finality_pipeline::{SubstrateFinalitySyncPipeline, TransactionParams};
/// Maximal saturating difference between `balance(now)` and `balance(now-24h)` to treat
/// relay as gone wild.
@@ -35,77 +26,37 @@ use substrate_relay_helper::finality_pipeline::{
/// DOT, but let's round up to 30 DOT here.
pub(crate) const MAXIMAL_BALANCE_DECREASE_PER_DAY: bp_polkadot::Balance = 30_000_000_000;
/// Kusama-to-Polkadot finality sync pipeline.
pub(crate) type FinalityPipelineKusamaFinalityToPolkadot =
SubstrateFinalityToSubstrate<Kusama, Polkadot, PolkadotSigningParams>;
/// Description of Kusama -> Polkadot finalized headers bridge.
#[derive(Clone, Debug)]
pub(crate) struct KusamaFinalityToPolkadot {
finality_pipeline: FinalityPipelineKusamaFinalityToPolkadot,
}
impl KusamaFinalityToPolkadot {
pub fn new(target_client: Client<Polkadot>, target_sign: PolkadotSigningParams) -> Self {
Self {
finality_pipeline: FinalityPipelineKusamaFinalityToPolkadot::new(
target_client,
target_sign,
),
}
}
}
pub struct KusamaFinalityToPolkadot;
substrate_relay_helper::generate_mocked_submit_finality_proof_call_builder!(
KusamaFinalityToPolkadot,
KusamaFinalityToPolkadotCallBuilder,
relay_polkadot_client::runtime::Call::BridgeKusamaGrandpa,
relay_polkadot_client::runtime::BridgeKusamaGrandpaCall::submit_finality_proof
);
impl SubstrateFinalitySyncPipeline for KusamaFinalityToPolkadot {
type FinalitySyncPipeline = FinalityPipelineKusamaFinalityToPolkadot;
type SourceChain = relay_kusama_client::Kusama;
type TargetChain = relay_polkadot_client::Polkadot;
const BEST_FINALIZED_SOURCE_HEADER_ID_AT_TARGET: &'static str =
bp_kusama::BEST_FINALIZED_KUSAMA_HEADER_METHOD;
type SubmitFinalityProofCallBuilder = KusamaFinalityToPolkadotCallBuilder;
type TransactionSignScheme = relay_polkadot_client::Polkadot;
type TargetChain = Polkadot;
fn customize_metrics(params: MetricsParams) -> anyhow::Result<MetricsParams> {
crate::chains::add_polkadot_kusama_price_metrics::<Self::FinalitySyncPipeline>(params)
}
fn start_relay_guards(&self) {
fn start_relay_guards(
target_client: &relay_substrate_client::Client<relay_polkadot_client::Polkadot>,
transaction_params: &TransactionParams<sp_core::sr25519::Pair>,
) {
relay_substrate_client::guard::abort_on_spec_version_change(
self.finality_pipeline.target_client.clone(),
target_client.clone(),
bp_polkadot::VERSION.spec_version,
);
relay_substrate_client::guard::abort_when_account_balance_decreased(
self.finality_pipeline.target_client.clone(),
self.transactions_author(),
target_client.clone(),
transaction_params.transactions_signer.public().into(),
MAXIMAL_BALANCE_DECREASE_PER_DAY,
);
}
fn transactions_author(&self) -> bp_polkadot::AccountId {
(*self.finality_pipeline.target_sign.public().as_array_ref()).into()
}
fn make_submit_finality_proof_transaction(
&self,
era: bp_runtime::TransactionEraOf<Polkadot>,
transaction_nonce: bp_runtime::IndexOf<Polkadot>,
header: KusamaSyncHeader,
proof: GrandpaJustification<bp_kusama::Header>,
) -> Bytes {
let call = relay_polkadot_client::runtime::Call::BridgeKusamaGrandpa(
relay_polkadot_client::runtime::BridgeKusamaGrandpaCall::submit_finality_proof(
Box::new(header.into_inner()),
proof,
),
);
let genesis_hash = *self.finality_pipeline.target_client.genesis_hash();
let transaction = Polkadot::sign_transaction(
genesis_hash,
&self.finality_pipeline.target_sign,
era,
UnsignedTransaction::new(call, transaction_nonce),
);
Bytes(transaction.encode())
}
}
#[cfg(test)]
@@ -16,65 +16,22 @@
//! Millau-to-Rialto headers sync entrypoint.
use codec::Encode;
use sp_core::{Bytes, Pair};
use bp_header_chain::justification::GrandpaJustification;
use relay_millau_client::{Millau, SyncHeader as MillauSyncHeader};
use relay_rialto_client::{Rialto, SigningParams as RialtoSigningParams};
use relay_substrate_client::{Client, IndexOf, TransactionSignScheme, UnsignedTransaction};
use substrate_relay_helper::finality_pipeline::{
SubstrateFinalitySyncPipeline, SubstrateFinalityToSubstrate,
DirectSubmitFinalityProofCallBuilder, SubstrateFinalitySyncPipeline,
};
/// Millau-to-Rialto finality sync pipeline.
pub(crate) type FinalityPipelineMillauToRialto =
SubstrateFinalityToSubstrate<Millau, Rialto, RialtoSigningParams>;
/// Description of Millau -> Rialto finalized headers bridge.
#[derive(Clone, Debug)]
pub(crate) struct MillauFinalityToRialto {
finality_pipeline: FinalityPipelineMillauToRialto,
}
impl MillauFinalityToRialto {
pub fn new(target_client: Client<Rialto>, target_sign: RialtoSigningParams) -> Self {
Self { finality_pipeline: FinalityPipelineMillauToRialto::new(target_client, target_sign) }
}
}
pub struct MillauFinalityToRialto;
impl SubstrateFinalitySyncPipeline for MillauFinalityToRialto {
type FinalitySyncPipeline = FinalityPipelineMillauToRialto;
type SourceChain = relay_millau_client::Millau;
type TargetChain = relay_rialto_client::Rialto;
const BEST_FINALIZED_SOURCE_HEADER_ID_AT_TARGET: &'static str =
bp_millau::BEST_FINALIZED_MILLAU_HEADER_METHOD;
type TargetChain = Rialto;
fn transactions_author(&self) -> bp_rialto::AccountId {
(*self.finality_pipeline.target_sign.public().as_array_ref()).into()
}
fn make_submit_finality_proof_transaction(
&self,
era: bp_runtime::TransactionEraOf<Rialto>,
transaction_nonce: IndexOf<Rialto>,
header: MillauSyncHeader,
proof: GrandpaJustification<bp_millau::Header>,
) -> Bytes {
let call = rialto_runtime::BridgeGrandpaMillauCall::submit_finality_proof {
finality_target: Box::new(header.into_inner()),
justification: proof,
}
.into();
let genesis_hash = *self.finality_pipeline.target_client.genesis_hash();
let transaction = Rialto::sign_transaction(
genesis_hash,
&self.finality_pipeline.target_sign,
era,
UnsignedTransaction::new(call, transaction_nonce),
);
Bytes(transaction.encode())
}
type SubmitFinalityProofCallBuilder = DirectSubmitFinalityProofCallBuilder<
Self,
rialto_runtime::Runtime,
rialto_runtime::MillauGrandpaInstance,
>;
type TransactionSignScheme = relay_rialto_client::Rialto;
}
@@ -39,18 +39,6 @@ mod rococo;
mod westend;
mod wococo;
use relay_utils::metrics::{MetricsParams, StandaloneMetric};
pub(crate) fn add_polkadot_kusama_price_metrics<T: finality_relay::FinalitySyncPipeline>(
params: MetricsParams,
) -> anyhow::Result<MetricsParams> {
substrate_relay_helper::helpers::token_price_metric(polkadot::TOKEN_ID)?
.register_and_spawn(&params.registry)?;
substrate_relay_helper::helpers::token_price_metric(kusama::TOKEN_ID)?
.register_and_spawn(&params.registry)?;
Ok(params)
}
#[cfg(test)]
mod tests {
use crate::cli::{encode_call, send_message};
@@ -16,17 +16,8 @@
//! Polkadot-to-Kusama headers sync entrypoint.
use codec::Encode;
use sp_core::{Bytes, Pair};
use bp_header_chain::justification::GrandpaJustification;
use relay_kusama_client::{Kusama, SigningParams as KusamaSigningParams};
use relay_polkadot_client::{Polkadot, SyncHeader as PolkadotSyncHeader};
use relay_substrate_client::{Client, TransactionSignScheme, UnsignedTransaction};
use relay_utils::metrics::MetricsParams;
use substrate_relay_helper::finality_pipeline::{
SubstrateFinalitySyncPipeline, SubstrateFinalityToSubstrate,
};
use sp_core::Pair;
use substrate_relay_helper::finality_pipeline::{SubstrateFinalitySyncPipeline, TransactionParams};
/// Maximal saturating difference between `balance(now)` and `balance(now-24h)` to treat
/// relay as gone wild.
@@ -35,77 +26,37 @@ use substrate_relay_helper::finality_pipeline::{
/// KSM, but let's round up to 0.1 KSM here.
pub(crate) const MAXIMAL_BALANCE_DECREASE_PER_DAY: bp_polkadot::Balance = 100_000_000_000;
/// Polkadot-to-Kusama finality sync pipeline.
pub(crate) type FinalityPipelinePolkadotFinalityToKusama =
SubstrateFinalityToSubstrate<Polkadot, Kusama, KusamaSigningParams>;
/// Description of Polkadot -> Kusama finalized headers bridge.
#[derive(Clone, Debug)]
pub(crate) struct PolkadotFinalityToKusama {
finality_pipeline: FinalityPipelinePolkadotFinalityToKusama,
}
impl PolkadotFinalityToKusama {
pub fn new(target_client: Client<Kusama>, target_sign: KusamaSigningParams) -> Self {
Self {
finality_pipeline: FinalityPipelinePolkadotFinalityToKusama::new(
target_client,
target_sign,
),
}
}
}
pub struct PolkadotFinalityToKusama;
substrate_relay_helper::generate_mocked_submit_finality_proof_call_builder!(
PolkadotFinalityToKusama,
PolkadotFinalityToKusamaCallBuilder,
relay_kusama_client::runtime::Call::BridgePolkadotGrandpa,
relay_kusama_client::runtime::BridgePolkadotGrandpaCall::submit_finality_proof
);
impl SubstrateFinalitySyncPipeline for PolkadotFinalityToKusama {
type FinalitySyncPipeline = FinalityPipelinePolkadotFinalityToKusama;
type SourceChain = relay_polkadot_client::Polkadot;
type TargetChain = relay_kusama_client::Kusama;
const BEST_FINALIZED_SOURCE_HEADER_ID_AT_TARGET: &'static str =
bp_polkadot::BEST_FINALIZED_POLKADOT_HEADER_METHOD;
type SubmitFinalityProofCallBuilder = PolkadotFinalityToKusamaCallBuilder;
type TransactionSignScheme = relay_kusama_client::Kusama;
type TargetChain = Kusama;
fn customize_metrics(params: MetricsParams) -> anyhow::Result<MetricsParams> {
crate::chains::add_polkadot_kusama_price_metrics::<Self::FinalitySyncPipeline>(params)
}
fn start_relay_guards(&self) {
fn start_relay_guards(
target_client: &relay_substrate_client::Client<relay_kusama_client::Kusama>,
transaction_params: &TransactionParams<sp_core::sr25519::Pair>,
) {
relay_substrate_client::guard::abort_on_spec_version_change(
self.finality_pipeline.target_client.clone(),
target_client.clone(),
bp_kusama::VERSION.spec_version,
);
relay_substrate_client::guard::abort_when_account_balance_decreased(
self.finality_pipeline.target_client.clone(),
self.transactions_author(),
target_client.clone(),
transaction_params.transactions_signer.public().into(),
MAXIMAL_BALANCE_DECREASE_PER_DAY,
);
}
fn transactions_author(&self) -> bp_kusama::AccountId {
(*self.finality_pipeline.target_sign.public().as_array_ref()).into()
}
fn make_submit_finality_proof_transaction(
&self,
era: bp_runtime::TransactionEraOf<Kusama>,
transaction_nonce: bp_runtime::IndexOf<Kusama>,
header: PolkadotSyncHeader,
proof: GrandpaJustification<bp_polkadot::Header>,
) -> Bytes {
let call = relay_kusama_client::runtime::Call::BridgePolkadotGrandpa(
relay_kusama_client::runtime::BridgePolkadotGrandpaCall::submit_finality_proof(
Box::new(header.into_inner()),
proof,
),
);
let genesis_hash = *self.finality_pipeline.target_client.genesis_hash();
let transaction = Kusama::sign_transaction(
genesis_hash,
&self.finality_pipeline.target_sign,
era,
UnsignedTransaction::new(call, transaction_nonce),
);
Bytes(transaction.encode())
}
}
#[cfg(test)]
@@ -16,73 +16,22 @@
//! Rialto-to-Millau headers sync entrypoint.
use codec::Encode;
use sp_core::{Bytes, Pair};
use bp_header_chain::justification::GrandpaJustification;
use relay_millau_client::{Millau, SigningParams as MillauSigningParams};
use relay_rialto_client::{Rialto, SyncHeader as RialtoSyncHeader};
use relay_substrate_client::{Client, IndexOf, TransactionSignScheme, UnsignedTransaction};
use substrate_relay_helper::finality_pipeline::{
SubstrateFinalitySyncPipeline, SubstrateFinalityToSubstrate,
DirectSubmitFinalityProofCallBuilder, SubstrateFinalitySyncPipeline,
};
/// Rialto-to-Millau finality sync pipeline.
pub(crate) type FinalityPipelineRialtoFinalityToMillau =
SubstrateFinalityToSubstrate<Rialto, Millau, MillauSigningParams>;
/// Description of Millau -> Rialto finalized headers bridge.
#[derive(Clone, Debug)]
pub struct RialtoFinalityToMillau {
finality_pipeline: FinalityPipelineRialtoFinalityToMillau,
}
impl RialtoFinalityToMillau {
pub fn new(target_client: Client<Millau>, target_sign: MillauSigningParams) -> Self {
Self {
finality_pipeline: FinalityPipelineRialtoFinalityToMillau::new(
target_client,
target_sign,
),
}
}
}
pub struct RialtoFinalityToMillau;
impl SubstrateFinalitySyncPipeline for RialtoFinalityToMillau {
type FinalitySyncPipeline = FinalityPipelineRialtoFinalityToMillau;
type SourceChain = relay_rialto_client::Rialto;
type TargetChain = relay_millau_client::Millau;
const BEST_FINALIZED_SOURCE_HEADER_ID_AT_TARGET: &'static str =
bp_rialto::BEST_FINALIZED_RIALTO_HEADER_METHOD;
type TargetChain = Millau;
fn transactions_author(&self) -> bp_millau::AccountId {
(*self.finality_pipeline.target_sign.public().as_array_ref()).into()
}
fn make_submit_finality_proof_transaction(
&self,
era: bp_runtime::TransactionEraOf<Millau>,
transaction_nonce: IndexOf<Millau>,
header: RialtoSyncHeader,
proof: GrandpaJustification<bp_rialto::Header>,
) -> Bytes {
let call = millau_runtime::BridgeGrandpaCall::<
millau_runtime::Runtime,
millau_runtime::RialtoGrandpaInstance,
>::submit_finality_proof {
finality_target: Box::new(header.into_inner()),
justification: proof,
}
.into();
let genesis_hash = *self.finality_pipeline.target_client.genesis_hash();
let transaction = Millau::sign_transaction(
genesis_hash,
&self.finality_pipeline.target_sign,
era,
UnsignedTransaction::new(call, transaction_nonce),
);
Bytes(transaction.encode())
}
type SubmitFinalityProofCallBuilder = DirectSubmitFinalityProofCallBuilder<
Self,
millau_runtime::Runtime,
millau_runtime::RialtoGrandpaInstance,
>;
type TransactionSignScheme = relay_millau_client::Millau;
}
@@ -16,89 +16,40 @@
//! Rococo-to-Wococo headers sync entrypoint.
use codec::Encode;
use sp_core::{Bytes, Pair};
use bp_header_chain::justification::GrandpaJustification;
use relay_rococo_client::{Rococo, SyncHeader as RococoSyncHeader};
use relay_substrate_client::{Client, IndexOf, TransactionSignScheme, UnsignedTransaction};
use relay_utils::metrics::MetricsParams;
use relay_wococo_client::{SigningParams as WococoSigningParams, Wococo};
use substrate_relay_helper::finality_pipeline::{
SubstrateFinalitySyncPipeline, SubstrateFinalityToSubstrate,
};
use crate::chains::wococo_headers_to_rococo::MAXIMAL_BALANCE_DECREASE_PER_DAY;
/// Rococo-to-Wococo finality sync pipeline.
pub(crate) type FinalityPipelineRococoFinalityToWococo =
SubstrateFinalityToSubstrate<Rococo, Wococo, WococoSigningParams>;
use sp_core::Pair;
use substrate_relay_helper::finality_pipeline::{SubstrateFinalitySyncPipeline, TransactionParams};
/// Description of Rococo -> Wococo finalized headers bridge.
#[derive(Clone, Debug)]
pub(crate) struct RococoFinalityToWococo {
finality_pipeline: FinalityPipelineRococoFinalityToWococo,
}
impl RococoFinalityToWococo {
pub fn new(target_client: Client<Wococo>, target_sign: WococoSigningParams) -> Self {
Self {
finality_pipeline: FinalityPipelineRococoFinalityToWococo::new(
target_client,
target_sign,
),
}
}
}
pub struct RococoFinalityToWococo;
substrate_relay_helper::generate_mocked_submit_finality_proof_call_builder!(
RococoFinalityToWococo,
RococoFinalityToWococoCallBuilder,
relay_wococo_client::runtime::Call::BridgeGrandpaRococo,
relay_wococo_client::runtime::BridgeGrandpaRococoCall::submit_finality_proof
);
impl SubstrateFinalitySyncPipeline for RococoFinalityToWococo {
type FinalitySyncPipeline = FinalityPipelineRococoFinalityToWococo;
type SourceChain = relay_rococo_client::Rococo;
type TargetChain = relay_wococo_client::Wococo;
const BEST_FINALIZED_SOURCE_HEADER_ID_AT_TARGET: &'static str =
bp_rococo::BEST_FINALIZED_ROCOCO_HEADER_METHOD;
type SubmitFinalityProofCallBuilder = RococoFinalityToWococoCallBuilder;
type TransactionSignScheme = relay_wococo_client::Wococo;
type TargetChain = Wococo;
fn customize_metrics(params: MetricsParams) -> anyhow::Result<MetricsParams> {
crate::chains::add_polkadot_kusama_price_metrics::<Self::FinalitySyncPipeline>(params)
}
fn start_relay_guards(&self) {
fn start_relay_guards(
target_client: &relay_substrate_client::Client<relay_wococo_client::Wococo>,
transaction_params: &TransactionParams<sp_core::sr25519::Pair>,
) {
relay_substrate_client::guard::abort_on_spec_version_change(
self.finality_pipeline.target_client.clone(),
target_client.clone(),
bp_wococo::VERSION.spec_version,
);
relay_substrate_client::guard::abort_when_account_balance_decreased(
self.finality_pipeline.target_client.clone(),
self.transactions_author(),
target_client.clone(),
transaction_params.transactions_signer.public().into(),
MAXIMAL_BALANCE_DECREASE_PER_DAY,
);
}
fn transactions_author(&self) -> bp_wococo::AccountId {
(*self.finality_pipeline.target_sign.public().as_array_ref()).into()
}
fn make_submit_finality_proof_transaction(
&self,
era: bp_runtime::TransactionEraOf<Wococo>,
transaction_nonce: IndexOf<Wococo>,
header: RococoSyncHeader,
proof: GrandpaJustification<bp_rococo::Header>,
) -> Bytes {
let call = relay_wococo_client::runtime::Call::BridgeGrandpaRococo(
relay_wococo_client::runtime::BridgeGrandpaRococoCall::submit_finality_proof(
Box::new(header.into_inner()),
proof,
),
);
let genesis_hash = *self.finality_pipeline.target_client.genesis_hash();
let transaction = Wococo::sign_transaction(
genesis_hash,
&self.finality_pipeline.target_sign,
era,
UnsignedTransaction::new(call, transaction_nonce),
);
Bytes(transaction.encode())
}
}
@@ -16,78 +16,22 @@
//! Westend-to-Millau headers sync entrypoint.
use codec::Encode;
use sp_core::{Bytes, Pair};
use bp_header_chain::justification::GrandpaJustification;
use relay_millau_client::{Millau, SigningParams as MillauSigningParams};
use relay_substrate_client::{Client, IndexOf, TransactionSignScheme, UnsignedTransaction};
use relay_utils::metrics::MetricsParams;
use relay_westend_client::{SyncHeader as WestendSyncHeader, Westend};
use substrate_relay_helper::finality_pipeline::{
SubstrateFinalitySyncPipeline, SubstrateFinalityToSubstrate,
DirectSubmitFinalityProofCallBuilder, SubstrateFinalitySyncPipeline,
};
/// Westend-to-Millau finality sync pipeline.
pub(crate) type FinalityPipelineWestendFinalityToMillau =
SubstrateFinalityToSubstrate<Westend, Millau, MillauSigningParams>;
/// Description of Westend -> Millau finalized headers bridge.
#[derive(Clone, Debug)]
pub(crate) struct WestendFinalityToMillau {
finality_pipeline: FinalityPipelineWestendFinalityToMillau,
}
impl WestendFinalityToMillau {
pub fn new(target_client: Client<Millau>, target_sign: MillauSigningParams) -> Self {
Self {
finality_pipeline: FinalityPipelineWestendFinalityToMillau::new(
target_client,
target_sign,
),
}
}
}
pub struct WestendFinalityToMillau;
impl SubstrateFinalitySyncPipeline for WestendFinalityToMillau {
type FinalitySyncPipeline = FinalityPipelineWestendFinalityToMillau;
type SourceChain = relay_westend_client::Westend;
type TargetChain = relay_millau_client::Millau;
const BEST_FINALIZED_SOURCE_HEADER_ID_AT_TARGET: &'static str =
bp_westend::BEST_FINALIZED_WESTEND_HEADER_METHOD;
type TargetChain = Millau;
fn customize_metrics(params: MetricsParams) -> anyhow::Result<MetricsParams> {
crate::chains::add_polkadot_kusama_price_metrics::<Self::FinalitySyncPipeline>(params)
}
fn transactions_author(&self) -> bp_millau::AccountId {
(*self.finality_pipeline.target_sign.public().as_array_ref()).into()
}
fn make_submit_finality_proof_transaction(
&self,
era: bp_runtime::TransactionEraOf<Millau>,
transaction_nonce: IndexOf<Millau>,
header: WestendSyncHeader,
proof: GrandpaJustification<bp_westend::Header>,
) -> Bytes {
let call = millau_runtime::BridgeGrandpaCall::<
millau_runtime::Runtime,
millau_runtime::WestendGrandpaInstance,
>::submit_finality_proof {
finality_target: Box::new(header.into_inner()),
justification: proof,
}
.into();
let genesis_hash = *self.finality_pipeline.target_client.genesis_hash();
let transaction = Millau::sign_transaction(
genesis_hash,
&self.finality_pipeline.target_sign,
era,
UnsignedTransaction::new(call, transaction_nonce),
);
Bytes(transaction.encode())
}
type SubmitFinalityProofCallBuilder = DirectSubmitFinalityProofCallBuilder<
Self,
millau_runtime::Runtime,
millau_runtime::WestendGrandpaInstance,
>;
type TransactionSignScheme = relay_millau_client::Millau;
}
@@ -16,17 +16,8 @@
//! Wococo-to-Rococo headers sync entrypoint.
use codec::Encode;
use sp_core::{Bytes, Pair};
use bp_header_chain::justification::GrandpaJustification;
use relay_rococo_client::{Rococo, SigningParams as RococoSigningParams};
use relay_substrate_client::{Client, IndexOf, TransactionSignScheme, UnsignedTransaction};
use relay_utils::metrics::MetricsParams;
use relay_wococo_client::{SyncHeader as WococoSyncHeader, Wococo};
use substrate_relay_helper::finality_pipeline::{
SubstrateFinalitySyncPipeline, SubstrateFinalityToSubstrate,
};
use sp_core::Pair;
use substrate_relay_helper::finality_pipeline::{SubstrateFinalitySyncPipeline, TransactionParams};
/// Maximal saturating difference between `balance(now)` and `balance(now-24h)` to treat
/// relay as gone wild.
@@ -35,77 +26,37 @@ use substrate_relay_helper::finality_pipeline::{
/// Note that this is in plancks, so this corresponds to `1500 UNITS`.
pub(crate) const MAXIMAL_BALANCE_DECREASE_PER_DAY: bp_rococo::Balance = 1_500_000_000_000_000;
/// Wococo-to-Rococo finality sync pipeline.
pub(crate) type FinalityPipelineWococoFinalityToRococo =
SubstrateFinalityToSubstrate<Wococo, Rococo, RococoSigningParams>;
/// Description of Wococo -> Rococo finalized headers bridge.
#[derive(Clone, Debug)]
pub(crate) struct WococoFinalityToRococo {
finality_pipeline: FinalityPipelineWococoFinalityToRococo,
}
impl WococoFinalityToRococo {
pub fn new(target_client: Client<Rococo>, target_sign: RococoSigningParams) -> Self {
Self {
finality_pipeline: FinalityPipelineWococoFinalityToRococo::new(
target_client,
target_sign,
),
}
}
}
pub struct WococoFinalityToRococo;
substrate_relay_helper::generate_mocked_submit_finality_proof_call_builder!(
WococoFinalityToRococo,
WococoFinalityToRococoCallBuilder,
relay_rococo_client::runtime::Call::BridgeGrandpaWococo,
relay_rococo_client::runtime::BridgeGrandpaWococoCall::submit_finality_proof
);
impl SubstrateFinalitySyncPipeline for WococoFinalityToRococo {
type FinalitySyncPipeline = FinalityPipelineWococoFinalityToRococo;
type SourceChain = relay_wococo_client::Wococo;
type TargetChain = relay_rococo_client::Rococo;
const BEST_FINALIZED_SOURCE_HEADER_ID_AT_TARGET: &'static str =
bp_wococo::BEST_FINALIZED_WOCOCO_HEADER_METHOD;
type SubmitFinalityProofCallBuilder = WococoFinalityToRococoCallBuilder;
type TransactionSignScheme = relay_rococo_client::Rococo;
type TargetChain = Rococo;
fn customize_metrics(params: MetricsParams) -> anyhow::Result<MetricsParams> {
crate::chains::add_polkadot_kusama_price_metrics::<Self::FinalitySyncPipeline>(params)
}
fn start_relay_guards(&self) {
fn start_relay_guards(
target_client: &relay_substrate_client::Client<relay_rococo_client::Rococo>,
transaction_params: &TransactionParams<sp_core::sr25519::Pair>,
) {
relay_substrate_client::guard::abort_on_spec_version_change(
self.finality_pipeline.target_client.clone(),
target_client.clone(),
bp_rococo::VERSION.spec_version,
);
relay_substrate_client::guard::abort_when_account_balance_decreased(
self.finality_pipeline.target_client.clone(),
self.transactions_author(),
target_client.clone(),
transaction_params.transactions_signer.public().into(),
MAXIMAL_BALANCE_DECREASE_PER_DAY,
);
}
fn transactions_author(&self) -> bp_rococo::AccountId {
(*self.finality_pipeline.target_sign.public().as_array_ref()).into()
}
fn make_submit_finality_proof_transaction(
&self,
era: bp_runtime::TransactionEraOf<Rococo>,
transaction_nonce: IndexOf<Rococo>,
header: WococoSyncHeader,
proof: GrandpaJustification<bp_wococo::Header>,
) -> Bytes {
let call = relay_rococo_client::runtime::Call::BridgeGrandpaWococo(
relay_rococo_client::runtime::BridgeGrandpaWococoCall::submit_finality_proof(
Box::new(header.into_inner()),
proof,
),
);
let genesis_hash = *self.finality_pipeline.target_client.genesis_hash();
let transaction = Rococo::sign_transaction(
genesis_hash,
&self.finality_pipeline.target_sign,
era,
UnsignedTransaction::new(call, transaction_nonce),
);
Bytes(transaction.encode())
}
}
#[cfg(test)]
@@ -121,18 +121,22 @@ impl RelayHeaders {
let target_client = self.target.to_client::<Target>().await?;
let target_transactions_mortality = self.target_sign.target_transactions_mortality;
let target_sign = self.target_sign.to_keypair::<Target>()?;
let metrics_params = Finality::customize_metrics(self.prometheus_params.into())?;
let metrics_params: relay_utils::metrics::MetricsParams = self.prometheus_params.into();
GlobalMetrics::new()?.register_and_spawn(&metrics_params.registry)?;
let finality = Finality::new(target_client.clone(), target_sign);
finality.start_relay_guards();
let target_transactions_params =
substrate_relay_helper::finality_pipeline::TransactionParams {
transactions_signer: target_sign,
transactions_mortality: target_transactions_mortality,
};
Finality::start_relay_guards(&target_client, &target_transactions_params);
substrate_relay_helper::finality_pipeline::run(
finality,
substrate_relay_helper::finality_pipeline::run::<Finality>(
source_client,
target_client,
self.only_mandatory_headers,
target_transactions_mortality,
target_transactions_params,
metrics_params,
)
.await
@@ -489,25 +489,35 @@ impl RelayHeadersAndMessages {
}
// start on-demand header relays
let left_to_right_finality =
LeftToRightFinality::new(right_client.clone(), right_sign.clone());
let right_to_left_finality =
RightToLeftFinality::new(left_client.clone(), left_sign.clone());
left_to_right_finality.start_relay_guards();
right_to_left_finality.start_relay_guards();
let left_to_right_on_demand_headers = OnDemandHeadersRelay::new(
let left_to_right_transaction_params =
substrate_relay_helper::finality_pipeline::TransactionParams {
transactions_mortality: right_transactions_mortality,
transactions_signer: right_sign.clone(),
};
let right_to_left_transaction_params =
substrate_relay_helper::finality_pipeline::TransactionParams {
transactions_mortality: left_transactions_mortality,
transactions_signer: left_sign.clone(),
};
LeftToRightFinality::start_relay_guards(
&right_client,
&left_to_right_transaction_params,
);
RightToLeftFinality::start_relay_guards(
&left_client,
&right_to_left_transaction_params,
);
let left_to_right_on_demand_headers = OnDemandHeadersRelay::new::<LeftToRightFinality>(
left_client.clone(),
right_client.clone(),
right_transactions_mortality,
left_to_right_finality,
left_to_right_transaction_params,
MAX_MISSING_LEFT_HEADERS_AT_RIGHT,
params.shared.only_mandatory_headers,
);
let right_to_left_on_demand_headers = OnDemandHeadersRelay::new(
let right_to_left_on_demand_headers = OnDemandHeadersRelay::new::<RightToLeftFinality>(
right_client.clone(),
left_client.clone(),
left_transactions_mortality,
right_to_left_finality,
right_to_left_transaction_params,
MAX_MISSING_RIGHT_HEADERS_AT_LEFT,
params.shared.only_mandatory_headers,
);