fuel_core/database/
genesis_progress.rs1use crate::graphql_api::storage::Column as OffChainColumn;
2
3use super::{
4 GenesisDatabase,
5 database_description::{
6 DatabaseDescription,
7 off_chain::OffChain,
8 on_chain::OnChain,
9 },
10};
11use fuel_core_chain_config::GenesisCommitment;
12use fuel_core_executor::refs::ContractRef;
13use fuel_core_storage::{
14 Error as StorageError,
15 Mappable,
16 MerkleRoot,
17 Result,
18 StorageAsMut,
19 StorageInspect,
20 StorageMutate,
21 blueprint::plain::Plain,
22 codec::postcard::Postcard,
23 column::Column,
24 iter::IteratorOverTable,
25 structured_storage::TableWithBlueprint,
26 tables::{
27 Coins,
28 ContractsLatestUtxo,
29 Messages,
30 ProcessedTransactions,
31 },
32};
33use fuel_core_types::fuel_merkle::binary::root_calculator::MerkleRootCalculator;
34
35pub struct GenesisMetadata<Description>(core::marker::PhantomData<Description>);
36
37impl<Description> Mappable for GenesisMetadata<Description> {
38 type Key = str;
39 type OwnedKey = String;
40 type Value = Self::OwnedValue;
41 type OwnedValue = usize;
42}
43
44impl TableWithBlueprint for GenesisMetadata<OnChain> {
45 type Blueprint = Plain<Postcard, Postcard>;
46 type Column = <OnChain as DatabaseDescription>::Column;
47 fn column() -> Self::Column {
48 Column::GenesisMetadata
49 }
50}
51
52impl TableWithBlueprint for GenesisMetadata<OffChain> {
53 type Blueprint = Plain<Postcard, Postcard>;
54 type Column = <OffChain as DatabaseDescription>::Column;
55 fn column() -> Self::Column {
56 OffChainColumn::GenesisMetadata
57 }
58}
59
60pub trait GenesisProgressInspect<Description> {
61 fn genesis_progress(&self, key: &str) -> Option<usize>;
62}
63
64pub trait GenesisProgressMutate<Description> {
65 fn update_genesis_progress(
66 &mut self,
67 key: &str,
68 processed_group: usize,
69 ) -> Result<()>;
70}
71
72impl<S, DbDesc> GenesisProgressInspect<DbDesc> for S
73where
74 S: StorageInspect<GenesisMetadata<DbDesc>, Error = StorageError>,
75 DbDesc: DatabaseDescription,
76{
77 fn genesis_progress(
78 &self,
79 key: &<GenesisMetadata<DbDesc> as Mappable>::Key,
80 ) -> Option<usize> {
81 Some(
82 StorageInspect::<GenesisMetadata<DbDesc>>::get(self, key)
83 .ok()??
84 .into_owned(),
85 )
86 }
87}
88
89impl<S, DbDesc> GenesisProgressMutate<DbDesc> for S
90where
91 S: StorageMutate<GenesisMetadata<DbDesc>, Error = StorageError>,
92{
93 fn update_genesis_progress(
94 &mut self,
95 key: &<GenesisMetadata<DbDesc> as Mappable>::Key,
96 processed_group: usize,
97 ) -> Result<()> {
98 self.storage_as_mut::<GenesisMetadata<DbDesc>>()
99 .insert(key, &processed_group)?;
100
101 Ok(())
102 }
103}
104
105impl GenesisDatabase {
106 pub fn genesis_coins_root(&self) -> Result<MerkleRoot> {
107 let coins = self.iter_all::<Coins>(None);
108
109 let mut root_calculator = MerkleRootCalculator::new();
110 for coin in coins {
111 let (utxo_id, coin) = coin?;
112 root_calculator.push(coin.uncompress(utxo_id).root()?.as_slice());
113 }
114
115 Ok(root_calculator.root())
116 }
117
118 pub fn genesis_messages_root(&self) -> Result<MerkleRoot> {
119 let messages = self.iter_all::<Messages>(None);
120
121 let mut root_calculator = MerkleRootCalculator::new();
122 for message in messages {
123 let (_, message) = message?;
124 root_calculator.push(message.root()?.as_slice());
125 }
126
127 Ok(root_calculator.root())
128 }
129
130 pub fn genesis_contracts_root(&self) -> Result<MerkleRoot> {
131 let contracts = self.iter_all::<ContractsLatestUtxo>(None);
132
133 let mut root_calculator = MerkleRootCalculator::new();
134 for contract in contracts {
135 let (contract_id, _) = contract?;
136 let root = ContractRef::new(self, contract_id).root()?;
137 root_calculator.push(root.as_slice());
138 }
139
140 Ok(root_calculator.root())
141 }
142
143 pub fn processed_transactions_root(&self) -> Result<MerkleRoot> {
144 let txs = self.iter_all::<ProcessedTransactions>(None);
145
146 let mut root_calculator = MerkleRootCalculator::new();
147 for tx in txs {
148 let (tx_id, _) = tx?;
149 root_calculator.push(tx_id.as_slice());
150 }
151
152 Ok(root_calculator.root())
153 }
154}