use crate::{ database::{ database_description::off_chain::OffChain, Database, }, fuel_core_graphql_api::{ ports::{ worker::Transactional, OffChainDatabase, }, storage::{ contracts::ContractsInfo, relayed_transactions::RelayedTransactionStatuses, transactions::OwnedTransactionIndexCursor, }, }, graphql_api::storage::old::{ OldFuelBlockConsensus, OldFuelBlocks, OldTransactions, }, }; use fuel_core_storage::{ iter::{ BoxedIter, IntoBoxedIter, IterDirection, IteratorOverTable, }, not_found, transactional::{ IntoTransaction, StorageTransaction, }, Error as StorageError, Result as StorageResult, StorageAsRef, }; use fuel_core_txpool::types::{ ContractId, TxId, }; use fuel_core_types::{ blockchain::{ block::CompressedBlock, consensus::Consensus, primitives::BlockId, }, entities::relayer::transaction::RelayedTransactionStatus, fuel_tx::{ Address, Bytes32, Salt, Transaction, TxPointer, UtxoId, }, fuel_types::{ BlockHeight, Nonce, }, services::txpool::TransactionStatus, }; impl OffChainDatabase for Database { fn block_height(&self, id: &BlockId) -> StorageResult { self.get_block_height(id) .and_then(|height| height.ok_or(not_found!("BlockHeight"))) } fn tx_status(&self, tx_id: &TxId) -> StorageResult { self.get_tx_status(tx_id) .transpose() .ok_or(not_found!("TransactionId"))? } fn owned_coins_ids( &self, owner: &Address, start_coin: Option, direction: IterDirection, ) -> BoxedIter<'_, StorageResult> { self.owned_coins_ids(owner, start_coin, Some(direction)) .map(|res| res.map_err(StorageError::from)) .into_boxed() } fn owned_message_ids( &self, owner: &Address, start_message_id: Option, direction: IterDirection, ) -> BoxedIter<'_, StorageResult> { self.owned_message_ids(owner, start_message_id, Some(direction)) .map(|result| result.map_err(StorageError::from)) .into_boxed() } fn owned_transactions_ids( &self, owner: Address, start: Option, direction: IterDirection, ) -> BoxedIter> { let start = start.map(|tx_pointer| OwnedTransactionIndexCursor { block_height: tx_pointer.block_height(), tx_idx: tx_pointer.tx_index(), }); self.owned_transactions(owner, start, Some(direction)) .map(|result| result.map_err(StorageError::from)) .into_boxed() } fn contract_salt(&self, contract_id: &ContractId) -> StorageResult { let salt = *self .storage_as_ref::() .get(contract_id)? .ok_or(not_found!(ContractsInfo))? .salt(); Ok(salt) } fn old_block(&self, height: &BlockHeight) -> StorageResult { let block = self .storage_as_ref::() .get(height)? .ok_or(not_found!(OldFuelBlocks))? .into_owned(); Ok(block) } fn old_blocks( &self, height: Option, direction: IterDirection, ) -> BoxedIter<'_, StorageResult> { self.iter_all_by_start::(height.as_ref(), Some(direction)) .map(|r| r.map(|(_, block)| block)) .into_boxed() } fn old_block_consensus(&self, height: &BlockHeight) -> StorageResult { Ok(self .storage_as_ref::() .get(height)? .ok_or(not_found!(OldFuelBlockConsensus))? .into_owned()) } fn old_transaction(&self, id: &TxId) -> StorageResult> { self.storage_as_ref::() .get(id) .map(|tx| tx.map(|tx| tx.into_owned())) } fn relayed_tx_status( &self, id: Bytes32, ) -> StorageResult> { let status = self .storage_as_ref::() .get(&id) .map_err(StorageError::from)? .map(|cow| cow.into_owned()); Ok(status) } fn message_is_spent(&self, nonce: &Nonce) -> StorageResult { self.message_is_spent(nonce) } } impl Transactional for Database { type Transaction<'a> = StorageTransaction<&'a mut Self> where Self: 'a; fn transaction(&mut self) -> Self::Transaction<'_> { self.into_transaction() } }