use crate::mempool::MEMPOOL_HEIGHT;
use crate::query::queryutil::height_by_txid;
use crate::{app::App, chaindef::BlockHeader};
use anyhow::{Context, Result};
use bitcoincash::hash_types::Txid;
use std::sync::Arc;
pub struct HeaderQuery {
app: Arc<App>,
}
impl HeaderQuery {
pub fn new(app: Arc<App>) -> HeaderQuery {
HeaderQuery { app }
}
pub async fn get_by_txid(
&self,
txid: &Txid,
blockheight: Option<u32>,
) -> Result<Option<BlockHeader>> {
let height = match blockheight {
Some(height) => {
if height == MEMPOOL_HEIGHT {
return Ok(None);
}
height
}
None => self
.get_confirmed_height_for_tx(txid)
.await
.context("could not get height for txid")?,
};
let header = self
.app
.index()
.chain()
.get_block_header(height as usize)
.await
.context(format!("missing header at height {}", height))?;
Ok(Some(header))
}
pub async fn best(&self) -> BlockHeader {
self.app.index().chain().tip().await
}
pub async fn at_height(&self, height: usize) -> Option<BlockHeader> {
self.app.index().chain().get_block_header(height).await
}
pub async fn get_confirmed_height_for_tx(&self, txid: &Txid) -> Option<u32> {
height_by_txid(self.app.index().read_store(), txid).await
}
#[cfg(nexa)]
pub async fn get_height(&self, header: &BlockHeader) -> Option<u64> {
Some(header.height())
}
#[cfg(bch)]
pub async fn get_height(&self, header: &BlockHeader) -> Option<u64> {
self.app
.index()
.chain()
.get_block_height(&header.block_hash())
.await
}
}