use crate::{ database::Database, fuel_core_graphql_api::ports::{ DatabaseBlocks, DatabaseChain, DatabaseContracts, DatabaseMessages, OnChainDatabase, }, }; use fuel_core_importer::ports::ImporterDatabase; use fuel_core_storage::{ iter::{ BoxedIter, IntoBoxedIter, IterDirection, IteratorOverTable, }, not_found, tables::{ FuelBlocks, SealedBlockConsensus, Transactions, }, Error as StorageError, Result as StorageResult, StorageAsRef, }; use fuel_core_txpool::types::{ ContractId, TxId, }; use fuel_core_types::{ blockchain::{ block::CompressedBlock, consensus::Consensus, primitives::DaBlockHeight, }, entities::relayer::message::Message, fuel_tx::{ AssetId, Transaction, }, fuel_types::{ BlockHeight, Nonce, }, services::graphql_api::ContractBalance, }; use itertools::Itertools; impl DatabaseBlocks for Database { fn transaction(&self, tx_id: &TxId) -> StorageResult { Ok(self .storage::() .get(tx_id)? .ok_or(not_found!(Transactions))? .into_owned()) } fn block(&self, height: &BlockHeight) -> StorageResult { let block = self .storage_as_ref::() .get(height)? .ok_or_else(|| not_found!(FuelBlocks))? .into_owned(); Ok(block) } fn blocks( &self, height: Option, direction: IterDirection, ) -> BoxedIter<'_, StorageResult> { self.iter_all_by_start::(height.as_ref(), Some(direction)) .map(|result| result.map(|(_, block)| block)) .into_boxed() } fn latest_height(&self) -> StorageResult { self.latest_block_height() .transpose() .ok_or(not_found!("BlockHeight"))? } fn consensus(&self, id: &BlockHeight) -> StorageResult { self.storage_as_ref::() .get(id) .map(|c| c.map(|c| c.into_owned()))? .ok_or(not_found!(SealedBlockConsensus)) } } impl DatabaseMessages for Database { fn all_messages( &self, start_message_id: Option, direction: IterDirection, ) -> BoxedIter<'_, StorageResult> { self.all_messages(start_message_id, Some(direction)) .map(|result| result.map_err(StorageError::from)) .into_boxed() } fn message_exists(&self, nonce: &Nonce) -> StorageResult { self.message_exists(nonce) } } impl DatabaseContracts for Database { fn contract_balances( &self, contract: ContractId, start_asset: Option, direction: IterDirection, ) -> BoxedIter> { self.filter_contract_balances(contract, start_asset, Some(direction)) .map_ok(|entry| ContractBalance { owner: *entry.key.contract_id(), amount: entry.value, asset_id: *entry.key.asset_id(), }) .map(|res| res.map_err(StorageError::from)) .into_boxed() } } impl DatabaseChain for Database { fn da_height(&self) -> StorageResult { self.latest_compressed_block()? .map(|block| block.header().da_height) .ok_or(not_found!("DaBlockHeight")) } } impl OnChainDatabase for Database {}