fuel_core/service/adapters/
consensus_module.rs

1use crate::{
2    database::{
3        Database,
4        OnChainIterableKeyValueView,
5    },
6    service::adapters::{
7        MaybeRelayerAdapter,
8        VerifierAdapter,
9    },
10};
11use fuel_core_chain_config::ConsensusConfig;
12use fuel_core_consensus_module::block_verifier::{
13    Verifier,
14    config::Config as VerifierConfig,
15};
16use fuel_core_poa::ports::RelayerPort;
17use fuel_core_producer::ports::BlockProducerDatabase;
18use fuel_core_storage::{
19    Result as StorageResult,
20    StorageAsRef,
21    tables::FuelBlocks,
22};
23use fuel_core_types::{
24    blockchain::{
25        block::CompressedBlock,
26        header::BlockHeader,
27        primitives::DaBlockHeight,
28    },
29    fuel_tx::Bytes32,
30    fuel_types::BlockHeight,
31};
32use std::sync::Arc;
33
34pub mod poa;
35
36impl VerifierAdapter {
37    pub fn new(
38        genesis_block: &CompressedBlock,
39        consensus: ConsensusConfig,
40        database: Database,
41    ) -> Self {
42        let block_height = *genesis_block.header().height();
43        let da_block_height = genesis_block.header().da_height();
44        let config = VerifierConfig::new(consensus, block_height, da_block_height);
45        Self {
46            block_verifier: Arc::new(Verifier::new(config, database)),
47        }
48    }
49}
50
51impl fuel_core_poa::ports::Database for OnChainIterableKeyValueView {
52    fn block_header(&self, height: &BlockHeight) -> StorageResult<BlockHeader> {
53        Ok(self.get_block(height)?.header().clone())
54    }
55
56    fn block_header_merkle_root(&self, height: &BlockHeight) -> StorageResult<Bytes32> {
57        self.storage::<FuelBlocks>().root(height).map(Into::into)
58    }
59}
60
61#[async_trait::async_trait]
62impl RelayerPort for MaybeRelayerAdapter {
63    async fn await_until_if_in_range(
64        &self,
65        da_height: &DaBlockHeight,
66        _max_da_lag: &DaBlockHeight,
67    ) -> anyhow::Result<()> {
68        #[cfg(feature = "relayer")]
69        {
70            if let Some(sync) = &self.relayer_synced {
71                let current_height = sync.get_finalized_da_height();
72                anyhow::ensure!(
73                    da_height.saturating_sub(*current_height) <= **_max_da_lag,
74                    "Relayer is too far out of sync"
75                );
76                sync.await_at_least_synced(da_height).await?;
77            }
78            Ok(())
79        }
80        #[cfg(not(feature = "relayer"))]
81        {
82            anyhow::ensure!(
83                **da_height == 0,
84                "Cannot have a da height above zero without a relayer"
85            );
86            Ok(())
87        }
88    }
89}