// 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. //! Message receiving race delivers proof-of-messages-delivery from "lane.target" to "lane.source". use crate::{ message_lane::{MessageLane, SourceHeaderIdOf, TargetHeaderIdOf}, message_lane_loop::{ NoncesSubmitArtifacts, SourceClient as MessageLaneSourceClient, SourceClientState, TargetClient as MessageLaneTargetClient, TargetClientState, }, message_race_loop::{ MessageRace, NoncesRange, SourceClient, SourceClientNonces, TargetClient, TargetClientNonces, }, message_race_strategy::BasicStrategy, metrics::MessageLaneLoopMetrics, }; use async_trait::async_trait; use bp_messages::MessageNonce; use futures::stream::FusedStream; use relay_utils::{FailedClient, TrackedTransactionStatus, TransactionTracker}; use std::{marker::PhantomData, ops::RangeInclusive}; /// Message receiving confirmations delivery strategy. type ReceivingConfirmationsBasicStrategy
= BasicStrategy<
::TargetHeaderNumber,
::TargetHeaderHash,
::SourceHeaderNumber,
::SourceHeaderHash,
RangeInclusive ::MessagesReceivingProof,
>;
/// Run receiving confirmations race.
pub async fn run ,
source_state_updates: impl FusedStream ,
target_state_updates: impl FusedStream ::new(),
)
.await
}
/// Relay messages delivery confirmation.
pub async fn relay_messages_delivery_confirmation ,
target_client: impl MessageLaneTargetClient ,
at: TargetHeaderIdOf ,
) -> Result<(), ()> {
// prepare messages delivery proof
let (at, proof) = target_client.prove_messages_receiving(at.clone()).await.map_err(|e| {
tracing::error!(
target: "bridge",
error=?e,
?at,
"Failed to generate messages delivery proof",
);
})?;
// submit messages delivery proof to the source node
let tx_tracker =
source_client
.submit_messages_receiving_proof(None, at, proof)
.await
.map_err(|e| {
tracing::error!(
target: "bridge",
error=?e,
"Failed to submit messages delivery proof"
);
})?;
match tx_tracker.wait().await {
TrackedTransactionStatus::Finalized(_) => Ok(()),
TrackedTransactionStatus::Lost => {
tracing::error!(target: "bridge", "Transaction with messages delivery proof is considered lost");
Err(())
},
}
}
/// Messages receiving confirmations race.
struct ReceivingConfirmationsRace (std::marker::PhantomData );
impl {
type SourceHeaderId = TargetHeaderIdOf ;
type TargetHeaderId = SourceHeaderIdOf ;
type MessageNonce = MessageNonce;
type Proof = P::MessagesReceivingProof;
fn source_name() -> String {
format!("{}::ReceivingConfirmationsDelivery", P::TARGET_NAME)
}
fn target_name() -> String {
format!("{}::ReceivingConfirmationsDelivery", P::SOURCE_NAME)
}
}
/// Message receiving confirmations race source, which is a target of the lane.
struct ReceivingConfirmationsRaceSource ,
}
#[async_trait]
impl SourceClient
where
P: MessageLane,
C: MessageLaneTargetClient ,
{
type Error = C::Error;
type NoncesRange = RangeInclusive ,
prev_latest_nonce: MessageNonce,
) -> Result<(TargetHeaderIdOf , SourceClientNonces ,
nonces: RangeInclusive , RangeInclusive ,
}
#[async_trait]
impl TargetClient
where
P: MessageLane,
C: MessageLaneSourceClient ,
{
type Error = C::Error;
type TargetNoncesData = ();
type BatchTransaction = C::BatchTransaction;
type TransactionTracker = C::TransactionTracker;
async fn require_source_header(
&self,
id: TargetHeaderIdOf ,
) -> Result