mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-05-02 02:20:00 -07:00
global: snapshot
This commit is contained in:
@@ -1,18 +1,130 @@
|
||||
// Should be async
|
||||
// anything related to IO should use
|
||||
//
|
||||
// Sync function
|
||||
// fn get(db: &CandyStore, key: &str) -> Option<Vec<u8>> {
|
||||
// db.get(key).ok().flatten()
|
||||
// }
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use crate::Query;
|
||||
use brk_computer::Computer;
|
||||
use brk_error::Result;
|
||||
use brk_indexer::Indexer;
|
||||
use brk_reader::Reader;
|
||||
use brk_types::{
|
||||
Address, AddressStats, Height, Index, IndexInfo, Limit, Metric, MetricCount, Transaction,
|
||||
TreeNode, TxidPath,
|
||||
};
|
||||
#[cfg(feature = "tokio")]
|
||||
use tokio::task::spawn_blocking;
|
||||
|
||||
use crate::{
|
||||
Output, PaginatedIndexParam, PaginatedMetrics, PaginationParam, Params, ParamsOpt, Query,
|
||||
vecs::{IndexToVec, MetricToVec, Vecs},
|
||||
};
|
||||
|
||||
// // Async function
|
||||
// async fn get_async(db: Arc<CandyStore>, key: String) -> Option<Vec<u8>> {
|
||||
// tokio::task::spawn_blocking(move || {
|
||||
// db.get(&key).ok().flatten()
|
||||
// }).await.ok()?
|
||||
// }
|
||||
#[derive(Clone)]
|
||||
#[cfg(feature = "tokio")]
|
||||
pub struct AsyncQuery(Query);
|
||||
|
||||
impl AsyncQuery {
|
||||
pub async fn build(reader: &Reader, indexer: &Indexer, computer: &Computer) -> Self {
|
||||
Self(Query::build(reader, indexer, computer))
|
||||
}
|
||||
|
||||
pub async fn get_height(&self) -> Height {
|
||||
self.0.get_height()
|
||||
}
|
||||
|
||||
pub async fn get_address(&self, address: Address) -> Result<AddressStats> {
|
||||
let query = self.0.clone();
|
||||
spawn_blocking(move || query.get_address(address)).await?
|
||||
}
|
||||
|
||||
pub async fn get_transaction(&self, txid: TxidPath) -> Result<Transaction> {
|
||||
let query = self.0.clone();
|
||||
spawn_blocking(move || query.get_transaction(txid)).await?
|
||||
}
|
||||
|
||||
pub async fn match_metric(&self, metric: Metric, limit: Limit) -> Result<Vec<&'static str>> {
|
||||
let query = self.0.clone();
|
||||
spawn_blocking(move || Ok(query.match_metric(&metric, limit))).await?
|
||||
}
|
||||
|
||||
// pub async fn search_metric_with_index(
|
||||
// &self,
|
||||
// metric: &str,
|
||||
// index: Index,
|
||||
// // params: &Params,
|
||||
// ) -> Result<Vec<(String, &&dyn AnyCollectableVec)>> {
|
||||
// let query = self.0.clone();
|
||||
// spawn_blocking(move || query.search_metric_with_index(metric, index)).await?
|
||||
// }
|
||||
|
||||
// pub async fn format(
|
||||
// &self,
|
||||
// metrics: Vec<(String, &&dyn AnyCollectableVec)>,
|
||||
// params: &ParamsOpt,
|
||||
// ) -> Result<Output> {
|
||||
// let query = self.0.clone();
|
||||
// spawn_blocking(move || query.format(metrics, params)).await?
|
||||
// }
|
||||
|
||||
pub async fn search_and_format(&self, params: Params) -> Result<Output> {
|
||||
let query = self.0.clone();
|
||||
spawn_blocking(move || query.search_and_format(params)).await?
|
||||
}
|
||||
|
||||
pub async fn metric_to_index_to_vec(&self) -> &BTreeMap<&str, IndexToVec<'_>> {
|
||||
self.0.metric_to_index_to_vec()
|
||||
}
|
||||
|
||||
pub async fn index_to_metric_to_vec(&self) -> &BTreeMap<Index, MetricToVec<'_>> {
|
||||
self.0.index_to_metric_to_vec()
|
||||
}
|
||||
|
||||
pub async fn metric_count(&self) -> MetricCount {
|
||||
self.0.metric_count()
|
||||
}
|
||||
|
||||
pub async fn distinct_metric_count(&self) -> usize {
|
||||
self.0.distinct_metric_count()
|
||||
}
|
||||
|
||||
pub async fn total_metric_count(&self) -> usize {
|
||||
self.0.total_metric_count()
|
||||
}
|
||||
|
||||
pub async fn get_indexes(&self) -> &[IndexInfo] {
|
||||
self.0.get_indexes()
|
||||
}
|
||||
|
||||
pub async fn get_metrics(&self, pagination: PaginationParam) -> PaginatedMetrics {
|
||||
self.0.get_metrics(pagination)
|
||||
}
|
||||
|
||||
pub async fn get_metrics_catalog(&self) -> &TreeNode {
|
||||
self.0.get_metrics_catalog()
|
||||
}
|
||||
|
||||
pub async fn get_index_to_vecids(&self, paginated_index: PaginatedIndexParam) -> Vec<&str> {
|
||||
self.0.get_index_to_vecids(paginated_index)
|
||||
}
|
||||
|
||||
pub async fn metric_to_indexes(&self, metric: String) -> Option<&Vec<Index>> {
|
||||
self.0.metric_to_indexes(metric)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub async fn reader(&self) -> &Reader {
|
||||
self.0.reader()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub async fn indexer(&self) -> &Indexer {
|
||||
self.0.indexer()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub async fn computer(&self) -> &Computer {
|
||||
self.0.computer()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub async fn vecs(&self) -> &'static Vecs<'static> {
|
||||
self.0.vecs()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,10 +3,10 @@ use std::str::FromStr;
|
||||
use bitcoin::{Network, PublicKey, ScriptBuf};
|
||||
use brk_error::{Error, Result};
|
||||
use brk_types::{
|
||||
Address, AddressBytes, AddressBytesHash, AddressChainStats, AddressMempoolStats, AddressStats,
|
||||
Address, AddressBytes, AddressChainStats, AddressHash, AddressMempoolStats, AddressStats,
|
||||
AnyAddressDataIndexEnum, OutputType,
|
||||
};
|
||||
use vecdb::{AnyIterableVec, VecIterator};
|
||||
use vecdb::{AnyIterableVec, VecIteratorExtended};
|
||||
|
||||
use crate::Query;
|
||||
|
||||
@@ -27,14 +27,17 @@ pub fn get_address(Address { address }: Address, query: &Query) -> Result<Addres
|
||||
return Err(Error::InvalidAddress);
|
||||
};
|
||||
|
||||
let type_ = OutputType::from(&script);
|
||||
let Ok(bytes) = AddressBytes::try_from((&script, type_)) else {
|
||||
let outputtype = OutputType::from(&script);
|
||||
let Ok(bytes) = AddressBytes::try_from((&script, outputtype)) else {
|
||||
return Err(Error::Str("Failed to convert the address to bytes"));
|
||||
};
|
||||
let hash = AddressBytesHash::from(&bytes);
|
||||
let addresstype = outputtype;
|
||||
let hash = AddressHash::from(&bytes);
|
||||
|
||||
let Ok(Some(type_index)) = stores
|
||||
.addressbyteshash_to_typeindex
|
||||
.addresstype_to_addresshash_to_addressindex
|
||||
.get(addresstype)
|
||||
.unwrap()
|
||||
.get(&hash)
|
||||
.map(|opt| opt.map(|cow| cow.into_owned()))
|
||||
else {
|
||||
@@ -50,57 +53,63 @@ pub fn get_address(Address { address }: Address, query: &Query) -> Result<Addres
|
||||
.iter()
|
||||
.last()
|
||||
.unwrap()
|
||||
.1
|
||||
.into_owned()
|
||||
});
|
||||
|
||||
let any_address_index = match type_ {
|
||||
let any_address_index = match outputtype {
|
||||
OutputType::P2PK33 => stateful
|
||||
.p2pk33addressindex_to_anyaddressindex
|
||||
.iter()
|
||||
.unwrap_get_inner(type_index.into()),
|
||||
.any_address_indexes
|
||||
.p2pk33
|
||||
.iter()?
|
||||
.get_unwrap(type_index.into()),
|
||||
OutputType::P2PK65 => stateful
|
||||
.p2pk65addressindex_to_anyaddressindex
|
||||
.iter()
|
||||
.unwrap_get_inner(type_index.into()),
|
||||
.any_address_indexes
|
||||
.p2pk65
|
||||
.iter()?
|
||||
.get_unwrap(type_index.into()),
|
||||
OutputType::P2PKH => stateful
|
||||
.p2pkhaddressindex_to_anyaddressindex
|
||||
.iter()
|
||||
.unwrap_get_inner(type_index.into()),
|
||||
.any_address_indexes
|
||||
.p2pkh
|
||||
.iter()?
|
||||
.get_unwrap(type_index.into()),
|
||||
OutputType::P2SH => stateful
|
||||
.p2shaddressindex_to_anyaddressindex
|
||||
.iter()
|
||||
.unwrap_get_inner(type_index.into()),
|
||||
.any_address_indexes
|
||||
.p2sh
|
||||
.iter()?
|
||||
.get_unwrap(type_index.into()),
|
||||
OutputType::P2TR => stateful
|
||||
.p2traddressindex_to_anyaddressindex
|
||||
.iter()
|
||||
.unwrap_get_inner(type_index.into()),
|
||||
.any_address_indexes
|
||||
.p2tr
|
||||
.iter()?
|
||||
.get_unwrap(type_index.into()),
|
||||
OutputType::P2WPKH => stateful
|
||||
.p2wpkhaddressindex_to_anyaddressindex
|
||||
.iter()
|
||||
.unwrap_get_inner(type_index.into()),
|
||||
.any_address_indexes
|
||||
.p2wpkh
|
||||
.iter()?
|
||||
.get_unwrap(type_index.into()),
|
||||
OutputType::P2WSH => stateful
|
||||
.p2wshaddressindex_to_anyaddressindex
|
||||
.iter()
|
||||
.unwrap_get_inner(type_index.into()),
|
||||
.any_address_indexes
|
||||
.p2wsh
|
||||
.iter()?
|
||||
.get_unwrap(type_index.into()),
|
||||
OutputType::P2A => stateful
|
||||
.p2aaddressindex_to_anyaddressindex
|
||||
.iter()
|
||||
.unwrap_get_inner(type_index.into()),
|
||||
.any_address_indexes
|
||||
.p2a
|
||||
.iter()?
|
||||
.get_unwrap(type_index.into()),
|
||||
t => {
|
||||
return Err(Error::UnsupportedType(t.to_string()));
|
||||
}
|
||||
};
|
||||
|
||||
let address_data = match any_address_index.to_enum() {
|
||||
AnyAddressDataIndexEnum::Loaded(index) => stateful
|
||||
.loadedaddressindex_to_loadedaddressdata
|
||||
.iter()
|
||||
.unwrap_get_inner(index),
|
||||
AnyAddressDataIndexEnum::Loaded(index) => {
|
||||
stateful.addresses_data.loaded.iter()?.get_unwrap(index)
|
||||
}
|
||||
AnyAddressDataIndexEnum::Empty(index) => stateful
|
||||
.emptyaddressindex_to_emptyaddressdata
|
||||
.iter()
|
||||
.unwrap_get_inner(index)
|
||||
.addresses_data
|
||||
.empty
|
||||
.iter()?
|
||||
.get_unwrap(index)
|
||||
.into(),
|
||||
};
|
||||
|
||||
|
||||
@@ -8,11 +8,11 @@ use bitcoin::consensus::Decodable;
|
||||
use brk_error::{Error, Result};
|
||||
use brk_reader::XORIndex;
|
||||
use brk_types::{Transaction, Txid, TxidPath, TxidPrefix};
|
||||
use vecdb::VecIterator;
|
||||
use vecdb::VecIteratorExtended;
|
||||
|
||||
use crate::Query;
|
||||
|
||||
pub fn get_transaction_info(TxidPath { txid }: TxidPath, query: &Query) -> Result<Transaction> {
|
||||
pub fn get_transaction(TxidPath { txid }: TxidPath, query: &Query) -> Result<Transaction> {
|
||||
let Ok(txid) = bitcoin::Txid::from_str(&txid) else {
|
||||
return Err(Error::InvalidTxid);
|
||||
};
|
||||
@@ -29,21 +29,13 @@ pub fn get_transaction_info(TxidPath { txid }: TxidPath, query: &Query) -> Resul
|
||||
return Err(Error::UnknownTxid);
|
||||
};
|
||||
|
||||
let txid = indexer.vecs.txindex_to_txid.iter().unwrap_get_inner(index);
|
||||
let txid = indexer.vecs.txindex_to_txid.iter()?.get_unwrap(index);
|
||||
|
||||
let reader = query.reader();
|
||||
let computer = query.computer();
|
||||
|
||||
let position = computer
|
||||
.blks
|
||||
.txindex_to_position
|
||||
.iter()
|
||||
.unwrap_get_inner(index);
|
||||
let len = indexer
|
||||
.vecs
|
||||
.txindex_to_total_size
|
||||
.iter()
|
||||
.unwrap_get_inner(index);
|
||||
let position = computer.blks.txindex_to_position.iter()?.get_unwrap(index);
|
||||
let len = indexer.vecs.txindex_to_total_size.iter()?.get_unwrap(index);
|
||||
|
||||
let blk_index_to_blk_path = reader.blk_index_to_blk_path();
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ pub use params::{Params, ParamsDeprec, ParamsOpt};
|
||||
use vecs::Vecs;
|
||||
|
||||
use crate::{
|
||||
chain::{get_address, get_transaction_info},
|
||||
chain::{get_address, get_transaction},
|
||||
vecs::{IndexToVec, MetricToVec},
|
||||
};
|
||||
|
||||
@@ -64,11 +64,11 @@ impl Query {
|
||||
get_address(address, self)
|
||||
}
|
||||
|
||||
pub fn get_transaction_info(&self, txid: TxidPath) -> Result<Transaction> {
|
||||
get_transaction_info(txid, self)
|
||||
pub fn get_transaction(&self, txid: TxidPath) -> Result<Transaction> {
|
||||
get_transaction(txid, self)
|
||||
}
|
||||
|
||||
pub fn match_metric(&self, metric: &Metric, limit: Limit) -> Vec<&str> {
|
||||
pub fn match_metric(&self, metric: &Metric, limit: Limit) -> Vec<&'static str> {
|
||||
self.vecs().matches(metric, limit)
|
||||
}
|
||||
|
||||
|
||||
@@ -89,9 +89,7 @@ impl<'a> Vecs<'a> {
|
||||
.iter()
|
||||
.map(|(index, id_to_vec)| (*index, id_to_vec.keys().cloned().collect::<Vec<_>>()))
|
||||
.collect();
|
||||
this.index_to_metrics
|
||||
.values_mut()
|
||||
.for_each(|ids| sort_ids(ids));
|
||||
this.index_to_metrics.values_mut().for_each(sort_ids);
|
||||
this.catalog.replace(
|
||||
TreeNode::Branch(
|
||||
[
|
||||
|
||||
Reference in New Issue
Block a user