use async_trait::async_trait; use fuel_core_services::stream::BoxStream; use fuel_core_storage::{ iter::{ BoxedIter, IterDirection, }, tables::{ Coins, ContractsAssets, ContractsRawCode, FuelBlocks, Messages, SealedBlockConsensus, Transactions, }, Error as StorageError, Result as StorageResult, StorageInspect, }; use fuel_core_txpool::service::TxStatusMessage; use fuel_core_types::{ blockchain::{ block::CompressedBlock, consensus::Consensus, primitives::{ BlockId, DaBlockHeight, }, }, entities::relayer::{ message::{ MerkleProof, Message, }, transaction::RelayedTransactionStatus, }, fuel_tx::{ Bytes32, ConsensusParameters, Salt, Transaction, TxId, TxPointer, UtxoId, }, fuel_types::{ Address, AssetId, BlockHeight, ContractId, Nonce, }, services::{ executor::TransactionExecutionStatus, graphql_api::ContractBalance, p2p::PeerInfo, txpool::{ InsertionResult, TransactionStatus, }, }, tai64::Tai64, }; use std::sync::Arc; pub trait OffChainDatabase: Send + Sync { fn block_height(&self, block_id: &BlockId) -> StorageResult; fn tx_status(&self, tx_id: &TxId) -> StorageResult; fn owned_coins_ids( &self, owner: &Address, start_coin: Option, direction: IterDirection, ) -> BoxedIter<'_, StorageResult>; fn owned_message_ids( &self, owner: &Address, start_message_id: Option, direction: IterDirection, ) -> BoxedIter<'_, StorageResult>; fn owned_transactions_ids( &self, owner: Address, start: Option, direction: IterDirection, ) -> BoxedIter>; fn contract_salt(&self, contract_id: &ContractId) -> StorageResult; fn old_blocks( &self, height: Option, direction: IterDirection, ) -> BoxedIter<'_, StorageResult>; fn old_block_consensus(&self, height: BlockHeight) -> StorageResult; fn old_transaction(&self, id: &TxId) -> StorageResult>; fn relayed_tx_status( &self, id: Bytes32, ) -> StorageResult>; fn message_is_spent(&self, nonce: &Nonce) -> StorageResult; } /// The on chain database port expected by GraphQL API service. pub trait OnChainDatabase: Send + Sync + DatabaseBlocks + StorageInspect + DatabaseMessages + StorageInspect + DatabaseContracts + DatabaseChain + DatabaseMessageProof { } /// Trait that specifies all the getters required for blocks. pub trait DatabaseBlocks: StorageInspect + StorageInspect { fn blocks( &self, height: Option, direction: IterDirection, ) -> BoxedIter<'_, StorageResult>; fn latest_height(&self) -> StorageResult; /// First (i.e. lowest) height stored in this db. fn latest_genesis_height(&self) -> StorageResult; } /// Trait that specifies all the getters required for messages. pub trait DatabaseMessages: StorageInspect { fn all_messages( &self, start_message_id: Option, direction: IterDirection, ) -> BoxedIter<'_, StorageResult>; fn message_exists(&self, nonce: &Nonce) -> StorageResult; } pub trait DatabaseRelayedTransactions { fn transaction_status( &self, id: Bytes32, ) -> StorageResult>; } /// Trait that specifies all the getters required for contract. pub trait DatabaseContracts: StorageInspect + StorageInspect { fn contract_balances( &self, contract: ContractId, start_asset: Option, direction: IterDirection, ) -> BoxedIter>; } /// Trait that specifies all the getters required for chain metadata. pub trait DatabaseChain { fn da_height(&self) -> StorageResult; } #[async_trait] pub trait TxPoolPort: Send + Sync { fn transaction(&self, id: TxId) -> Option; fn submission_time(&self, id: TxId) -> Option; async fn insert( &self, txs: Vec>, ) -> Vec>; fn tx_update_subscribe( &self, tx_id: TxId, ) -> anyhow::Result>; } #[async_trait] pub trait BlockProducerPort: Send + Sync { async fn dry_run_txs( &self, transactions: Vec, height: Option, utxo_validation: Option, ) -> anyhow::Result>; } #[async_trait::async_trait] pub trait ConsensusModulePort: Send + Sync { async fn manually_produce_blocks( &self, start_time: Option, number_of_blocks: u32, ) -> anyhow::Result<()>; } /// Trait that specifies queries supported by the database. pub trait DatabaseMessageProof: Send + Sync { /// Gets the [`MerkleProof`] for the message block at `message_block_height` height /// relatively to the commit block where message block <= commit block. fn block_history_proof( &self, message_block_height: &BlockHeight, commit_block_height: &BlockHeight, ) -> StorageResult; } #[async_trait::async_trait] pub trait P2pPort: Send + Sync { async fn all_peer_info(&self) -> anyhow::Result>; } /// Trait for defining how to estimate gas price for future blocks #[async_trait::async_trait] pub trait GasPriceEstimate: Send + Sync { /// The worst case scenario for gas price at a given horizon async fn worst_case_gas_price(&self, height: BlockHeight) -> u64; } pub mod worker { use super::super::storage::blocks::FuelBlockIdsToHeights; use crate::{ fuel_core_graphql_api::storage::{ coins::OwnedCoins, contracts::ContractsInfo, messages::{ OwnedMessageIds, SpentMessages, }, }, graphql_api::storage::{ old::{ OldFuelBlockConsensus, OldFuelBlocks, OldTransactions, }, relayed_transactions::RelayedTransactionStatuses, }, }; use fuel_core_services::stream::BoxStream; use fuel_core_storage::{ Error as StorageError, Result as StorageResult, StorageMutate, }; use fuel_core_types::{ fuel_tx::{ Address, Bytes32, }, fuel_types::BlockHeight, services::{ block_importer::SharedImportResult, txpool::TransactionStatus, }, }; pub trait Transactional: Send + Sync { type Transaction<'a>: OffChainDatabase where Self: 'a; /// Creates a write database transaction. fn transaction(&mut self) -> Self::Transaction<'_>; } pub trait OffChainDatabase: StorageMutate + StorageMutate + StorageMutate + StorageMutate + StorageMutate + StorageMutate + StorageMutate + StorageMutate + StorageMutate { fn record_tx_id_owner( &mut self, owner: &Address, block_height: BlockHeight, tx_idx: u16, tx_id: &Bytes32, ) -> StorageResult>; fn update_tx_status( &mut self, id: &Bytes32, status: TransactionStatus, ) -> StorageResult>; /// Update metadata about the total number of transactions on the chain. /// Returns the total count after the update. fn increase_tx_count(&mut self, new_txs_count: u64) -> StorageResult; /// Gets the total number of transactions on the chain from metadata. fn get_tx_count(&self) -> StorageResult; /// Commits the underlying changes into the database. fn commit(self) -> StorageResult<()>; } pub trait BlockImporter { /// Returns a stream of imported block. fn block_events(&self) -> BoxStream; } pub trait TxPool: Send + Sync { /// Sends the complete status of the transaction. fn send_complete( &self, id: Bytes32, block_height: &BlockHeight, status: TransactionStatus, ); } } pub trait ConsensusProvider: Send + Sync { /// Returns latest consensus parameters. fn latest_consensus_params(&self) -> Arc; }