// Copyright 2019-2023 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 .
use crate::{
handle_client_error, reporter::EquivocationsReporter, EquivocationDetectionPipeline,
SourceClient, TargetClient,
};
use crate::block_checker::BlockChecker;
use finality_relay::{FinalityProofsBuf, FinalityProofsStream};
use futures::{select, FutureExt};
use num_traits::Saturating;
use relay_utils::{metrics::MetricsParams, FailedClient};
use std::{future::Future, time::Duration};
/// Equivocations detection loop state.
struct EquivocationDetectionLoop<
P: EquivocationDetectionPipeline,
SC: SourceClient
,
TC: TargetClient
,
> {
source_client: SC,
target_client: TC,
from_block_num: Option,
until_block_num: Option,
reporter: EquivocationsReporter,
finality_proofs_stream: FinalityProofsStream
,
finality_proofs_buf: FinalityProofsBuf
,
}
impl, TC: TargetClient>
EquivocationDetectionLoop
{
async fn ensure_finality_proofs_stream(&mut self) {
match self.finality_proofs_stream.ensure_stream(&self.source_client).await {
Ok(_) => {},
Err(e) => {
log::error!(
target: "bridge",
"Could not connect to the {} `FinalityProofsStream`: {e:?}",
P::SOURCE_NAME,
);
// Reconnect to the source client if needed
handle_client_error(&mut self.source_client, e).await;
},
}
}
async fn best_finalized_target_block_number(&mut self) -> Option {
match self.target_client.best_finalized_header_number().await {
Ok(block_num) => Some(block_num),
Err(e) => {
log::error!(
target: "bridge",
"Could not read best finalized header number from {}: {e:?}",
P::TARGET_NAME,
);
// Reconnect target client and move on
handle_client_error(&mut self.target_client, e).await;
None
},
}
}
async fn do_run(&mut self, tick: Duration, exit_signal: impl Future