fuel_core/service/adapters/
import_result_provider.rs1use crate::{
2    database::Database,
3    service::adapters::ExecutorAdapter,
4};
5use fuel_core_importer::ports::Validator;
6use fuel_core_storage::{
7    not_found,
8    transactional::AtomicView,
9};
10use fuel_core_types::{
11    fuel_types::BlockHeight,
12    services::{
13        block_importer::{
14            ImportResult,
15            SharedImportResult,
16        },
17        executor::ValidationResult,
18    },
19};
20use std::sync::Arc;
21
22#[derive(Clone)]
23pub struct ImportResultProvider {
24    on_chain_database: Database,
25    executor_adapter: ExecutorAdapter,
26}
27
28impl ImportResultProvider {
29    pub fn new(on_chain_database: Database, executor_adapter: ExecutorAdapter) -> Self {
30        Self {
31            on_chain_database,
32            executor_adapter,
33        }
34    }
35}
36
37#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Ord, PartialOrd)]
39pub enum BlockAt {
40    Specific(BlockHeight),
42    Genesis,
44}
45
46impl ImportResultProvider {
47    pub fn result_at_height(
48        &self,
49        height: BlockAt,
50    ) -> anyhow::Result<SharedImportResult> {
51        match height {
52            BlockAt::Specific(height) => {
53                let sealed_block = self
54                    .on_chain_database
55                    .latest_view()?
56                    .get_sealed_block_by_height(&height)?
57                    .ok_or(not_found!("SealedBlock"))?;
58
59                let ValidationResult { tx_status, events } = self
60                    .executor_adapter
61                    .validate(&sealed_block.entity)?
62                    .into_result();
63                let result =
64                    ImportResult::new_from_local(sealed_block, tx_status, events);
65                Ok(Arc::new(result.wrap()))
66            }
67            BlockAt::Genesis => {
68                let genesis_height = self
69                    .on_chain_database
70                    .latest_view()?
71                    .genesis_height()?
72                    .ok_or(not_found!("Genesis height"))?;
73                let sealed_block = self
74                    .on_chain_database
75                    .latest_view()?
76                    .get_sealed_block_by_height(&genesis_height)?
77                    .ok_or(not_found!("SealedBlock"))?;
78
79                Ok(Arc::new(
80                    ImportResult::new_from_local(sealed_block, vec![], vec![]).wrap(),
81                ))
82            }
83        }
84    }
85}