// Copyright 2019-2021 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 .
//! Tools for supporting message lanes between two Substrate-based chains.
use crate::{
messages_source::{SubstrateMessagesProof, SubstrateMessagesSource},
messages_target::{SubstrateMessagesDeliveryProof, SubstrateMessagesTarget},
on_demand::OnDemandRelay,
BatchCallBuilder, BatchCallBuilderConstructor, TransactionParams,
};
use async_std::sync::Arc;
use bp_messages::{LaneId, MessageNonce};
use bp_runtime::{AccountIdOf, Chain as _, HeaderIdOf, WeightExtraOps};
use bridge_runtime_common::messages::{
source::FromBridgedChainMessagesDeliveryProof, target::FromBridgedChainMessagesProof,
};
use codec::Encode;
use frame_support::{dispatch::GetDispatchInfo, weights::Weight};
use messages_relay::{message_lane::MessageLane, message_lane_loop::BatchTransaction};
use pallet_bridge_messages::{Call as BridgeMessagesCall, Config as BridgeMessagesConfig};
use relay_substrate_client::{
transaction_stall_timeout, AccountKeyPairOf, BalanceOf, BlockNumberOf, CallOf, Chain,
ChainWithMessages, ChainWithTransactions, Client, Error as SubstrateError, HashOf,
};
use relay_utils::{
metrics::{GlobalMetrics, MetricsParams, StandaloneMetric},
STALL_TIMEOUT,
};
use sp_core::Pair;
use std::{convert::TryFrom, fmt::Debug, marker::PhantomData};
/// Substrate -> Substrate messages synchronization pipeline.
pub trait SubstrateMessageLane: 'static + Clone + Debug + Send + Sync {
/// Messages of this chain are relayed to the `TargetChain`.
type SourceChain: ChainWithMessages + ChainWithTransactions;
/// Messages from the `SourceChain` are dispatched on this chain.
type TargetChain: ChainWithMessages + ChainWithTransactions;
/// How receive messages proof call is built?
type ReceiveMessagesProofCallBuilder: ReceiveMessagesProofCallBuilder;
/// How receive messages delivery proof call is built?
type ReceiveMessagesDeliveryProofCallBuilder: ReceiveMessagesDeliveryProofCallBuilder;
/// How batch calls are built at the source chain?
type SourceBatchCallBuilder: BatchCallBuilderConstructor>;
/// How batch calls are built at the target chain?
type TargetBatchCallBuilder: BatchCallBuilderConstructor>;
}
/// Adapter that allows all `SubstrateMessageLane` to act as `MessageLane`.
#[derive(Clone, Debug)]
pub struct MessageLaneAdapter {
_phantom: PhantomData
,
}
impl MessageLane for MessageLaneAdapter
{
const SOURCE_NAME: &'static str = P::SourceChain::NAME;
const TARGET_NAME: &'static str = P::TargetChain::NAME;
type MessagesProof = SubstrateMessagesProof;
type MessagesReceivingProof = SubstrateMessagesDeliveryProof;
type SourceChainBalance = BalanceOf;
type SourceHeaderNumber = BlockNumberOf;
type SourceHeaderHash = HashOf;
type TargetHeaderNumber = BlockNumberOf;
type TargetHeaderHash = HashOf;
}
/// Substrate <-> Substrate messages relay parameters.
pub struct MessagesRelayParams {
/// Messages source client.
pub source_client: Client,
/// Source transaction params.
pub source_transaction_params: TransactionParams>,
/// Messages target client.
pub target_client: Client,
/// Target transaction params.
pub target_transaction_params: TransactionParams>,
/// Optional on-demand source to target headers relay.
pub source_to_target_headers_relay:
Option>>,
/// Optional on-demand target to source headers relay.
pub target_to_source_headers_relay:
Option>>,
/// Identifier of lane that needs to be served.
pub lane_id: LaneId,
/// Metrics parameters.
pub metrics_params: MetricsParams,
}
/// Batch transaction that brings headers + and messages delivery/receiving confirmations to the
/// source node.
pub struct BatchProofTransaction>> {
builder: Box>>,
proved_header: HeaderIdOf,
prove_calls: Vec>,
/// Using `fn() -> B` in order to avoid implementing `Send` for `B`.
_phantom: PhantomData B>,
}
impl>>
BatchProofTransaction
{
/// Creates a new instance of `BatchProofTransaction`.
pub async fn new(
relay: Arc>,
block_num: BlockNumberOf,
) -> Result