stratus/eth/follower/
consensus.rs

1use 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    /// Whether this node should serve requests.
14    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    /// Forwards a transaction to leader.
33    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    /// Get the lag between this node and the leader.
50    async fn lag(&self) -> anyhow::Result<u64>;
51}