fuel_core/service/adapters/
block_importer.rs

1use crate::{
2    database::{
3        Database,
4        commit_changes_with_height_update,
5    },
6    service::adapters::{
7        BlockImporterAdapter,
8        ExecutorAdapter,
9        VerifierAdapter,
10    },
11};
12use fuel_core_importer::{
13    Config,
14    Importer,
15    ports::{
16        BlockVerifier,
17        ImporterDatabase,
18        Validator,
19    },
20};
21use fuel_core_storage::{
22    MerkleRoot,
23    Result as StorageResult,
24    StorageAsRef,
25    iter::{
26        IterDirection,
27        IteratorOverTable,
28    },
29    tables::{
30        FuelBlocks,
31        merkle::{
32            DenseMetadataKey,
33            FuelBlockMerkleMetadata,
34        },
35    },
36    transactional::{
37        Changes,
38        StorageChanges,
39    },
40};
41use fuel_core_txpool::ports::{
42    WasmChecker,
43    WasmValidityError,
44};
45use fuel_core_types::{
46    blockchain::{
47        SealedBlock,
48        block::Block,
49        consensus::Consensus,
50    },
51    fuel_tx::Bytes32,
52    fuel_types::{
53        BlockHeight,
54        ChainId,
55    },
56    services::executor::{
57        Result as ExecutorResult,
58        UncommittedValidationResult,
59    },
60};
61use itertools::Itertools;
62use std::sync::Arc;
63
64impl BlockImporterAdapter {
65    pub fn new(
66        chain_id: ChainId,
67        config: Config,
68        database: Database,
69        executor: ExecutorAdapter,
70        verifier: VerifierAdapter,
71    ) -> Self {
72        let importer = Importer::new(chain_id, config, database, executor, verifier);
73        Self {
74            block_importer: Arc::new(importer),
75        }
76    }
77
78    pub async fn execute_and_commit(
79        &self,
80        sealed_block: SealedBlock,
81    ) -> anyhow::Result<()> {
82        self.block_importer.execute_and_commit(sealed_block).await?;
83        Ok(())
84    }
85}
86
87impl BlockVerifier for VerifierAdapter {
88    fn verify_block_fields(
89        &self,
90        consensus: &Consensus,
91        block: &Block,
92    ) -> anyhow::Result<()> {
93        self.block_verifier.verify_block_fields(consensus, block)
94    }
95}
96
97impl ImporterDatabase for Database {
98    fn latest_block_height(&self) -> StorageResult<Option<BlockHeight>> {
99        self.iter_all_keys::<FuelBlocks>(Some(IterDirection::Reverse))
100            .next()
101            .transpose()
102    }
103
104    fn latest_block_root(&self) -> StorageResult<Option<MerkleRoot>> {
105        Ok(self
106            .storage_as_ref::<FuelBlockMerkleMetadata>()
107            .get(&DenseMetadataKey::Latest)?
108            .map(|cow| *cow.root()))
109    }
110
111    fn commit_changes(&mut self, changes: StorageChanges) -> StorageResult<()> {
112        commit_changes_with_height_update(self, changes, |iter| {
113            iter.iter_all_keys::<FuelBlocks>(Some(IterDirection::Reverse))
114                .try_collect()
115        })
116    }
117}
118
119impl Validator for ExecutorAdapter {
120    fn validate(
121        &self,
122        block: &Block,
123    ) -> ExecutorResult<UncommittedValidationResult<Changes>> {
124        self.executor.validate(block)
125    }
126}
127
128#[cfg(feature = "wasm-executor")]
129impl WasmChecker for ExecutorAdapter {
130    fn validate_uploaded_wasm(
131        &self,
132        wasm_root: &Bytes32,
133    ) -> Result<(), WasmValidityError> {
134        self.executor
135            .validate_uploaded_wasm(wasm_root)
136            .map_err(|err| match err {
137                fuel_core_upgradable_executor::error::UpgradableError::InvalidWasm(_) => {
138                    WasmValidityError::NotValid
139                }
140                _ => WasmValidityError::NotFound,
141            })
142    }
143}
144
145#[cfg(not(feature = "wasm-executor"))]
146impl WasmChecker for ExecutorAdapter {
147    fn validate_uploaded_wasm(
148        &self,
149        _wasm_root: &Bytes32,
150    ) -> Result<(), WasmValidityError> {
151        Err(WasmValidityError::NotEnabled)
152    }
153}