stratus/eth/follower/
consensus.rs1use std::sync::Arc;
2
3use crate::eth::primitives::Bytes;
4use crate::eth::primitives::Hash;
5use crate::eth::primitives::StratusError;
6use crate::eth::rpc::RpcClientApp;
7use crate::infra::BlockchainClient;
8#[cfg(feature = "metrics")]
9use crate::infra::metrics;
10
11#[allow(async_fn_in_trait)]
12pub trait Consensus: Send + Sync {
13 async fn should_serve(&self) -> bool {
15 let lag = match self.lag().await {
16 Ok(lag) => lag,
17 Err(err) => {
18 tracing::error!(?err, "failed to get the lag between this node and the leader");
19 return false;
20 }
21 };
22
23 let should_serve = lag <= 3;
24
25 if !should_serve {
26 tracing::warn!(?lag, "validator and replica are too far apart");
27 }
28
29 should_serve
30 }
31
32 async fn forward_to_leader(&self, tx_hash: Hash, tx_data: Bytes, rpc_client: &RpcClientApp) -> Result<Hash, StratusError> {
34 #[cfg(feature = "metrics")]
35 let start = metrics::now();
36
37 tracing::info!(%tx_hash, %rpc_client, "forwarding transaction to leader");
38
39 let hash = self.get_chain()?.send_raw_transaction_to_leader(tx_data.into(), rpc_client).await?;
40
41 #[cfg(feature = "metrics")]
42 metrics::inc_consensus_forward(start.elapsed());
43
44 Ok(hash)
45 }
46
47 fn get_chain(&self) -> anyhow::Result<&Arc<BlockchainClient>>;
48
49 async fn lag(&self) -> anyhow::Result<u64>;
51}