fuel_core/database/
sealed_block.rs

1use crate::database::OnChainIterableKeyValueView;
2use fuel_core_storage::{
3    Result as StorageResult,
4    StorageAsRef,
5    iter::{
6        IterDirection,
7        IteratorOverTable,
8    },
9    not_found,
10    tables::{
11        FuelBlocks,
12        SealedBlockConsensus,
13    },
14};
15use fuel_core_types::{
16    blockchain::{
17        SealedBlock,
18        SealedBlockHeader,
19        block::CompressedBlock,
20        consensus::{
21            Consensus,
22            Genesis,
23        },
24    },
25    fuel_types::BlockHeight,
26    services::p2p::Transactions,
27};
28use std::ops::Range;
29
30impl OnChainIterableKeyValueView {
31    /// Returns `SealedBlock` by `height`.
32    /// Reusable across different trait implementations
33    pub fn get_sealed_block_by_height(
34        &self,
35        height: &BlockHeight,
36    ) -> StorageResult<Option<SealedBlock>> {
37        // combine the block and consensus metadata into a sealed fuel block type
38        let consensus = self.storage::<SealedBlockConsensus>().get(height)?;
39
40        if let Some(consensus) = consensus {
41            let block = self.get_full_block(height)?.ok_or(not_found!(FuelBlocks))?;
42
43            let sealed_block = SealedBlock {
44                entity: block,
45                consensus: consensus.into_owned(),
46            };
47
48            Ok(Some(sealed_block))
49        } else {
50            Ok(None)
51        }
52    }
53
54    pub fn genesis_height(&self) -> StorageResult<Option<BlockHeight>> {
55        self.iter_all_keys::<FuelBlocks>(Some(IterDirection::Forward))
56            .next()
57            .transpose()
58    }
59
60    pub fn genesis_block(&self) -> StorageResult<Option<CompressedBlock>> {
61        Ok(self
62            .iter_all::<FuelBlocks>(Some(IterDirection::Forward))
63            .next()
64            .transpose()?
65            .map(|(_, block)| block))
66    }
67
68    pub fn get_genesis(&self) -> StorageResult<Genesis> {
69        let pair = self
70            .iter_all::<SealedBlockConsensus>(Some(IterDirection::Forward))
71            .next()
72            .transpose()?;
73
74        if let Some((_, Consensus::Genesis(genesis))) = pair {
75            Ok(genesis)
76        } else {
77            Err(not_found!(SealedBlockConsensus))
78        }
79    }
80
81    pub fn get_sealed_block_headers(
82        &self,
83        block_height_range: Range<u32>,
84    ) -> StorageResult<Option<Vec<SealedBlockHeader>>> {
85        let headers = block_height_range
86            .map(BlockHeight::from)
87            .map(|height| self.get_sealed_block_header(&height))
88            .collect::<StorageResult<Option<Vec<_>>>>()?;
89        Ok(headers)
90    }
91
92    pub fn get_sealed_block_header(
93        &self,
94        height: &BlockHeight,
95    ) -> StorageResult<Option<SealedBlockHeader>> {
96        let consensus = self.storage::<SealedBlockConsensus>().get(height)?;
97
98        if let Some(consensus) = consensus {
99            let header = self
100                .storage::<FuelBlocks>()
101                .get(height)?
102                .ok_or(not_found!(FuelBlocks))?; // This shouldn't happen if a block has been sealed
103
104            let sealed_block = SealedBlockHeader {
105                entity: header.into_owned().header().clone(),
106                consensus: consensus.into_owned(),
107            };
108
109            Ok(Some(sealed_block))
110        } else {
111            Ok(None)
112        }
113    }
114
115    pub fn get_transactions_on_blocks(
116        &self,
117        block_height_range: Range<u32>,
118    ) -> StorageResult<Option<Vec<Transactions>>> {
119        let transactions = block_height_range
120            .into_iter()
121            .map(BlockHeight::from)
122            .map(|block_height| {
123                let transactions = self
124                    .get_full_block(&block_height)?
125                    .map(|block| block.into_inner().1)
126                    .map(Transactions);
127                Ok(transactions)
128            })
129            .collect::<StorageResult<_>>()?;
130        Ok(transactions)
131    }
132}