use zaino_proto::proto::utils::PoolTypeFilter;
use crate::{
chain_index::{finalised_state::capability::CapabilityRequest, types::TransactionHash},
error::FinalisedStateError,
BlockHash, BlockHeaderData, CommitmentTreeData, CompactBlockStream, Height, IndexedBlock,
OrchardCompactTx, OrchardTxList, SaplingCompactTx, SaplingTxList, StatusType,
TransparentCompactTx, TransparentTxList, TxLocation, TxidList,
};
#[cfg(feature = "transparent_address_history_experimental")]
use crate::{
chain_index::{finalised_state::capability::TransparentHistExt, types::AddrEventBytes},
AddrScript, Outpoint,
};
use super::{
capability::{
BlockCoreExt, BlockShieldedExt, BlockTransparentExt, CompactBlockExt, DbMetadata,
IndexedBlockExt,
},
db::DbBackend,
ZainoDB,
};
use std::sync::Arc;
#[derive(Clone, Debug)]
pub(crate) struct DbReader {
pub(crate) inner: Arc<ZainoDB>,
}
impl DbReader {
#[inline(always)]
fn db(&self, cap: CapabilityRequest) -> Result<Arc<DbBackend>, FinalisedStateError> {
self.inner.backend_for_cap(cap)
}
pub(crate) fn status(&self) -> StatusType {
self.inner.status()
}
pub(crate) async fn db_height(&self) -> Result<Option<Height>, FinalisedStateError> {
self.inner.db_height().await
}
pub(crate) async fn get_metadata(&self) -> Result<DbMetadata, FinalisedStateError> {
self.inner.get_metadata().await
}
pub(crate) async fn wait_until_ready(&self) {
self.inner.wait_until_ready().await
}
pub(crate) async fn get_block_height(
&self,
hash: BlockHash,
) -> Result<Option<Height>, FinalisedStateError> {
self.inner.get_block_height(hash).await
}
pub(crate) async fn get_block_hash(
&self,
height: Height,
) -> Result<Option<BlockHash>, FinalisedStateError> {
self.inner.get_block_hash(height).await
}
pub(crate) async fn get_tx_location(
&self,
txid: &TransactionHash,
) -> Result<Option<TxLocation>, FinalisedStateError> {
self.db(CapabilityRequest::BlockCoreExt)?
.get_tx_location(txid)
.await
}
pub(crate) async fn get_block_header(
&self,
height: Height,
) -> Result<BlockHeaderData, FinalisedStateError> {
self.db(CapabilityRequest::BlockCoreExt)?
.get_block_header(height)
.await
}
pub(crate) async fn get_block_range_headers(
&self,
start: Height,
end: Height,
) -> Result<Vec<BlockHeaderData>, FinalisedStateError> {
self.db(CapabilityRequest::BlockCoreExt)?
.get_block_range_headers(start, end)
.await
}
pub(crate) async fn get_txid(
&self,
tx_location: TxLocation,
) -> Result<TransactionHash, FinalisedStateError> {
self.db(CapabilityRequest::BlockCoreExt)?
.get_txid(tx_location)
.await
}
pub(crate) async fn get_block_txids(
&self,
height: Height,
) -> Result<TxidList, FinalisedStateError> {
self.db(CapabilityRequest::BlockCoreExt)?
.get_block_txids(height)
.await
}
pub(crate) async fn get_block_range_txids(
&self,
start: Height,
end: Height,
) -> Result<Vec<TxidList>, FinalisedStateError> {
self.db(CapabilityRequest::BlockCoreExt)?
.get_block_range_txids(start, end)
.await
}
pub(crate) async fn get_transparent(
&self,
tx_location: TxLocation,
) -> Result<Option<TransparentCompactTx>, FinalisedStateError> {
self.db(CapabilityRequest::BlockTransparentExt)?
.get_transparent(tx_location)
.await
}
pub(crate) async fn get_block_transparent(
&self,
height: Height,
) -> Result<TransparentTxList, FinalisedStateError> {
self.db(CapabilityRequest::BlockTransparentExt)?
.get_block_transparent(height)
.await
}
pub(crate) async fn get_block_range_transparent(
&self,
start: Height,
end: Height,
) -> Result<Vec<TransparentTxList>, FinalisedStateError> {
self.db(CapabilityRequest::BlockTransparentExt)?
.get_block_range_transparent(start, end)
.await
}
pub(crate) async fn get_sapling(
&self,
tx_location: TxLocation,
) -> Result<Option<SaplingCompactTx>, FinalisedStateError> {
self.db(CapabilityRequest::BlockShieldedExt)?
.get_sapling(tx_location)
.await
}
pub(crate) async fn get_block_sapling(
&self,
height: Height,
) -> Result<SaplingTxList, FinalisedStateError> {
self.db(CapabilityRequest::BlockShieldedExt)?
.get_block_sapling(height)
.await
}
pub(crate) async fn get_block_range_sapling(
&self,
start: Height,
end: Height,
) -> Result<Vec<SaplingTxList>, FinalisedStateError> {
self.db(CapabilityRequest::BlockShieldedExt)?
.get_block_range_sapling(start, end)
.await
}
pub(crate) async fn get_orchard(
&self,
tx_location: TxLocation,
) -> Result<Option<OrchardCompactTx>, FinalisedStateError> {
self.db(CapabilityRequest::BlockShieldedExt)?
.get_orchard(tx_location)
.await
}
pub(crate) async fn get_block_orchard(
&self,
height: Height,
) -> Result<OrchardTxList, FinalisedStateError> {
self.db(CapabilityRequest::BlockShieldedExt)?
.get_block_orchard(height)
.await
}
pub(crate) async fn get_block_range_orchard(
&self,
start: Height,
end: Height,
) -> Result<Vec<OrchardTxList>, FinalisedStateError> {
self.db(CapabilityRequest::BlockShieldedExt)?
.get_block_range_orchard(start, end)
.await
}
pub(crate) async fn get_block_commitment_tree_data(
&self,
height: Height,
) -> Result<CommitmentTreeData, FinalisedStateError> {
self.db(CapabilityRequest::BlockShieldedExt)?
.get_block_commitment_tree_data(height)
.await
}
pub(crate) async fn get_block_range_commitment_tree_data(
&self,
start: Height,
end: Height,
) -> Result<Vec<CommitmentTreeData>, FinalisedStateError> {
self.db(CapabilityRequest::BlockShieldedExt)?
.get_block_range_commitment_tree_data(start, end)
.await
}
#[cfg(feature = "transparent_address_history_experimental")]
pub(crate) async fn addr_records(
&self,
addr_script: AddrScript,
) -> Result<Option<Vec<AddrEventBytes>>, FinalisedStateError> {
self.db(CapabilityRequest::TransparentHistExt)?
.addr_records(addr_script)
.await
}
#[cfg(feature = "transparent_address_history_experimental")]
pub(crate) async fn addr_and_index_records(
&self,
addr_script: AddrScript,
tx_location: TxLocation,
) -> Result<Option<Vec<AddrEventBytes>>, FinalisedStateError> {
self.db(CapabilityRequest::TransparentHistExt)?
.addr_and_index_records(addr_script, tx_location)
.await
}
#[cfg(feature = "transparent_address_history_experimental")]
pub(crate) async fn addr_tx_locations_by_range(
&self,
addr_script: AddrScript,
start_height: Height,
end_height: Height,
) -> Result<Option<Vec<TxLocation>>, FinalisedStateError> {
self.db(CapabilityRequest::TransparentHistExt)?
.addr_tx_locations_by_range(addr_script, start_height, end_height)
.await
}
#[cfg(feature = "transparent_address_history_experimental")]
pub(crate) async fn addr_utxos_by_range(
&self,
addr_script: AddrScript,
start_height: Height,
end_height: Height,
) -> Result<Option<Vec<(TxLocation, u16, u64)>>, FinalisedStateError> {
self.db(CapabilityRequest::TransparentHistExt)?
.addr_utxos_by_range(addr_script, start_height, end_height)
.await
}
#[cfg(feature = "transparent_address_history_experimental")]
pub(crate) async fn addr_balance_by_range(
&self,
addr_script: AddrScript,
start_height: Height,
end_height: Height,
) -> Result<i64, FinalisedStateError> {
self.db(CapabilityRequest::TransparentHistExt)?
.addr_balance_by_range(addr_script, start_height, end_height)
.await
}
#[cfg(feature = "transparent_address_history_experimental")]
pub(crate) async fn get_outpoint_spender(
&self,
outpoint: Outpoint,
) -> Result<Option<TxLocation>, FinalisedStateError> {
self.db(CapabilityRequest::TransparentHistExt)?
.get_outpoint_spender(outpoint)
.await
}
#[cfg(feature = "transparent_address_history_experimental")]
pub(crate) async fn get_outpoint_spenders(
&self,
outpoints: Vec<Outpoint>,
) -> Result<Vec<Option<TxLocation>>, FinalisedStateError> {
self.db(CapabilityRequest::TransparentHistExt)?
.get_outpoint_spenders(outpoints)
.await
}
pub(crate) async fn get_chain_block_by_height(
&self,
height: Height,
) -> Result<Option<IndexedBlock>, FinalisedStateError> {
self.db(CapabilityRequest::IndexedBlockExt)?
.get_chain_block(height)
.await
}
pub(crate) async fn get_chain_block_by_hash(
&self,
hash: BlockHash,
) -> Result<Option<IndexedBlock>, FinalisedStateError> {
let Some(height) = self.inner.get_block_height(hash).await? else {
return Ok(None);
};
self.get_chain_block_by_height(height).await
}
pub(crate) async fn get_compact_block(
&self,
height: Height,
pool_types: PoolTypeFilter,
) -> Result<zaino_proto::proto::compact_formats::CompactBlock, FinalisedStateError> {
self.db(CapabilityRequest::CompactBlockExt)?
.get_compact_block(height, pool_types)
.await
}
pub(crate) async fn get_compact_block_stream(
&self,
start_height: Height,
end_height: Height,
pool_types: PoolTypeFilter,
) -> Result<CompactBlockStream, FinalisedStateError> {
self.db(CapabilityRequest::CompactBlockExt)?
.get_compact_block_stream(start_height, end_height, pool_types)
.await
}
}