// 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; 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
}
/// 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 (latest_received_nonce);
}
Ok((
at_block,
SourceClientNonces {
new_nonces: prev_latest_nonce + 1..=latest_received_nonce,
confirmed_nonce: None,
},
))
}
#[allow(clippy::unit_arg)]
async fn generate_proof(
&self,
at_block: TargetHeaderIdOf ,
nonces: RangeInclusive , RangeInclusive ,
}
#[async_trait]
impl TargetClient
where
P: MessageLane,
C: MessageLaneSourceClient ,
{
type Error = C::Error;
type TargetNoncesData = ();
type TransactionTracker = C::TransactionTracker;
async fn require_source_header(&self, id: TargetHeaderIdOf ) {
self.client.require_target_header_on_source(id).await
}
async fn nonces(
&self,
at_block: SourceHeaderIdOf ,
update_metrics: bool,
) -> Result<(SourceHeaderIdOf , TargetClientNonces<()>), Self::Error> {
let (at_block, latest_confirmed_nonce) =
self.client.latest_confirmed_received_nonce(at_block).await?;
if update_metrics {
if let Some(metrics_msg) = self.metrics_msg.as_ref() {
metrics_msg.update_source_latest_confirmed_nonce:: (latest_confirmed_nonce);
}
}
Ok((at_block, TargetClientNonces { latest_nonce: latest_confirmed_nonce, nonces_data: () }))
}
async fn submit_proof(
&self,
generated_at_block: TargetHeaderIdOf ,
nonces: RangeInclusive