mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-04-28 08:39:59 -07:00
global: snapshot
This commit is contained in:
@@ -39,7 +39,7 @@ impl Query {
|
||||
}
|
||||
|
||||
pub fn blocks(&self, start_height: Option<Height>) -> Result<Vec<BlockInfo>> {
|
||||
let max_height = self.height();
|
||||
let max_height = self.indexed_height();
|
||||
|
||||
let start = start_height.unwrap_or(max_height);
|
||||
let start = start.min(max_height);
|
||||
|
||||
@@ -10,7 +10,7 @@ impl Query {
|
||||
let indexer = self.indexer();
|
||||
let computer = self.computer();
|
||||
|
||||
let max_height = self.height();
|
||||
let max_height = self.indexed_height();
|
||||
let max_height_usize: usize = max_height.into();
|
||||
|
||||
if max_height_usize == 0 {
|
||||
|
||||
@@ -26,7 +26,7 @@ impl Query {
|
||||
fn block_txids_by_height(&self, height: Height) -> Result<Vec<Txid>> {
|
||||
let indexer = self.indexer();
|
||||
|
||||
let max_height = self.height();
|
||||
let max_height = self.indexed_height();
|
||||
if height > max_height {
|
||||
return Err(Error::OutOfRange("Block height out of range".into()));
|
||||
}
|
||||
@@ -55,7 +55,7 @@ impl Query {
|
||||
fn block_txs_by_height(&self, height: Height, start_index: usize) -> Result<Vec<Transaction>> {
|
||||
let indexer = self.indexer();
|
||||
|
||||
let max_height = self.height();
|
||||
let max_height = self.indexed_height();
|
||||
if height > max_height {
|
||||
return Err(Error::OutOfRange("Block height out of range".into()));
|
||||
}
|
||||
@@ -97,7 +97,7 @@ impl Query {
|
||||
fn block_txid_at_index_by_height(&self, height: Height, index: usize) -> Result<Txid> {
|
||||
let indexer = self.indexer();
|
||||
|
||||
let max_height = self.height();
|
||||
let max_height = self.indexed_height();
|
||||
if height > max_height {
|
||||
return Err(Error::OutOfRange("Block height out of range".into()));
|
||||
}
|
||||
|
||||
@@ -37,7 +37,10 @@ impl Query {
|
||||
.join(format!("utxo_{cohort}_cost_basis/by_date"));
|
||||
|
||||
if !dir.exists() {
|
||||
return Err(Error::NotFound(format!("Unknown cohort '{cohort}'")));
|
||||
let valid = self.cost_basis_cohorts().unwrap_or_default().join(", ");
|
||||
return Err(Error::NotFound(format!(
|
||||
"Unknown cohort '{cohort}'. Available: {valid}"
|
||||
)));
|
||||
}
|
||||
|
||||
Ok(dir)
|
||||
|
||||
@@ -27,21 +27,24 @@ impl Query {
|
||||
pub fn metric_not_found_error(&self, metric: &Metric) -> Error {
|
||||
// Check if metric exists but with different indexes
|
||||
if let Some(indexes) = self.vecs().metric_to_indexes(metric.clone()) {
|
||||
let index_list: Vec<_> = indexes.iter().map(|i| i.to_string()).collect();
|
||||
let supported = indexes
|
||||
.iter()
|
||||
.map(|i| format!("/api/metric/{metric}/{i}"))
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ");
|
||||
return Error::MetricUnsupportedIndex {
|
||||
metric: metric.to_string(),
|
||||
supported: index_list.join(", "),
|
||||
supported,
|
||||
};
|
||||
}
|
||||
|
||||
// Metric doesn't exist, suggest alternatives
|
||||
Error::MetricNotFound {
|
||||
metric: metric.to_string(),
|
||||
suggestion: self
|
||||
.match_metric(metric, Limit::MIN)
|
||||
.first()
|
||||
.map(|s| s.to_string()),
|
||||
}
|
||||
let matches = self
|
||||
.match_metric(metric, Limit::DEFAULT)
|
||||
.into_iter()
|
||||
.map(|s| s.to_string())
|
||||
.collect();
|
||||
Error::MetricNotFound(brk_error::MetricNotFound::new(metric.to_string(), matches))
|
||||
}
|
||||
|
||||
pub(crate) fn columns_to_csv(
|
||||
@@ -334,4 +337,9 @@ impl ResolvedQuery {
|
||||
pub fn format(&self) -> Format {
|
||||
self.format
|
||||
}
|
||||
|
||||
pub fn csv_filename(&self) -> String {
|
||||
let names: Vec<_> = self.vecs.iter().map(|v| v.name()).collect();
|
||||
format!("{}-{}.csv", names.join("_"), self.index)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,8 +8,8 @@ use brk_indexer::Indexer;
|
||||
use brk_mempool::Mempool;
|
||||
use brk_reader::Reader;
|
||||
use brk_rpc::Client;
|
||||
use brk_types::Height;
|
||||
use vecdb::{ReadOnlyClone, Ro};
|
||||
use brk_types::{Height, SyncStatus};
|
||||
use vecdb::{AnyVec, ReadOnlyClone, ReadableVec, Ro};
|
||||
|
||||
#[cfg(feature = "tokio")]
|
||||
mod r#async;
|
||||
@@ -57,10 +57,43 @@ impl Query {
|
||||
}
|
||||
|
||||
/// Current indexed height
|
||||
pub fn height(&self) -> Height {
|
||||
pub fn indexed_height(&self) -> Height {
|
||||
Height::from(self.indexer().vecs.blocks.blockhash.stamp())
|
||||
}
|
||||
|
||||
/// Current computed height (metrics)
|
||||
pub fn computed_height(&self) -> Height {
|
||||
Height::from(self.computer().distribution.supply_state.len())
|
||||
}
|
||||
|
||||
/// Minimum of indexed and computed heights
|
||||
pub fn height(&self) -> Height {
|
||||
self.indexed_height().min(self.computed_height())
|
||||
}
|
||||
|
||||
/// Build sync status with the given tip height
|
||||
pub fn sync_status(&self, tip_height: Height) -> SyncStatus {
|
||||
let indexed_height = self.indexed_height();
|
||||
let computed_height = self.computed_height();
|
||||
let blocks_behind = Height::from(tip_height.saturating_sub(*indexed_height));
|
||||
let last_indexed_at_unix = self
|
||||
.indexer()
|
||||
.vecs
|
||||
.blocks
|
||||
.timestamp
|
||||
.collect_one(indexed_height)
|
||||
.unwrap();
|
||||
|
||||
SyncStatus {
|
||||
indexed_height,
|
||||
computed_height,
|
||||
tip_height,
|
||||
blocks_behind,
|
||||
last_indexed_at: last_indexed_at_unix.to_iso8601(),
|
||||
last_indexed_at_unix,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn reader(&self) -> &Reader {
|
||||
&self.0.reader
|
||||
|
||||
Reference in New Issue
Block a user