mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-06-30 22:09:00 -07:00
global: snapshot
This commit is contained in:
@@ -1,24 +1,21 @@
|
||||
use std::str::FromStr;
|
||||
|
||||
use bitcoin::{Address, Network, PublicKey, ScriptBuf};
|
||||
use bitcoin::{Network, PublicKey, ScriptBuf};
|
||||
use brk_error::{Error, Result};
|
||||
use brk_structs::{
|
||||
AddressBytes, AddressBytesHash, AddressInfo, AddressPath, AnyAddressDataIndexEnum, Bitcoin,
|
||||
Address, AddressBytes, AddressBytesHash, AddressStats, AnyAddressDataIndexEnum, Bitcoin,
|
||||
OutputType,
|
||||
};
|
||||
use vecdb::{AnyIterableVec, VecIterator};
|
||||
|
||||
use crate::Interface;
|
||||
|
||||
pub fn get_address_info(
|
||||
AddressPath { address }: AddressPath,
|
||||
interface: &Interface,
|
||||
) -> Result<AddressInfo> {
|
||||
pub fn get_address(Address { address }: Address, interface: &Interface) -> Result<AddressStats> {
|
||||
let indexer = interface.indexer();
|
||||
let computer = interface.computer();
|
||||
let stores = &indexer.stores;
|
||||
|
||||
let script = if let Ok(address) = Address::from_str(&address) {
|
||||
let script = if let Ok(address) = bitcoin::Address::from_str(&address) {
|
||||
if !address.is_valid_for_network(Network::Bitcoin) {
|
||||
return Err(Error::InvalidNetwork);
|
||||
}
|
||||
@@ -109,16 +106,18 @@ pub fn get_address_info(
|
||||
|
||||
let balance = address_data.balance();
|
||||
|
||||
Ok(AddressInfo {
|
||||
address: address.to_string(),
|
||||
r#type: type_,
|
||||
type_index,
|
||||
utxo_count: address_data.utxo_count,
|
||||
total_sent: address_data.sent,
|
||||
total_received: address_data.received,
|
||||
balance,
|
||||
balance_usd: price.map(|p| p * Bitcoin::from(balance)),
|
||||
estimated_total_invested: price.map(|_| address_data.realized_cap),
|
||||
estimated_avg_entry_price: price.map(|_| address_data.realized_price()),
|
||||
})
|
||||
todo!();
|
||||
|
||||
// Ok(Address {
|
||||
// address: address.to_string(),
|
||||
// r#type: type_,
|
||||
// type_index,
|
||||
// utxo_count: address_data.utxo_count,
|
||||
// total_sent: address_data.sent,
|
||||
// total_received: address_data.received,
|
||||
// balance,
|
||||
// balance_usd: price.map(|p| p * Bitcoin::from(balance)),
|
||||
// estimated_total_invested: price.map(|_| address_data.realized_cap),
|
||||
// estimated_avg_entry_price: price.map(|_| address_data.realized_price()),
|
||||
// })
|
||||
}
|
||||
|
||||
@@ -7,15 +7,12 @@ use std::{
|
||||
use bitcoin::{Transaction, consensus::Decodable};
|
||||
use brk_error::{Error, Result};
|
||||
use brk_parser::XORIndex;
|
||||
use brk_structs::{TransactionInfo, Txid, TxidPath, TxidPrefix};
|
||||
use brk_structs::{Tx, Txid, TxidPath, TxidPrefix};
|
||||
use vecdb::VecIterator;
|
||||
|
||||
use crate::Interface;
|
||||
|
||||
pub fn get_transaction_info(
|
||||
TxidPath { txid }: TxidPath,
|
||||
interface: &Interface,
|
||||
) -> Result<TransactionInfo> {
|
||||
pub fn get_transaction_info(TxidPath { txid }: TxidPath, interface: &Interface) -> Result<Tx> {
|
||||
let Ok(txid) = bitcoin::Txid::from_str(&txid) else {
|
||||
return Err(Error::InvalidTxid);
|
||||
};
|
||||
@@ -79,9 +76,11 @@ pub fn get_transaction_info(
|
||||
return Err(Error::Str("Failed decode the transaction"));
|
||||
};
|
||||
|
||||
Ok(TransactionInfo {
|
||||
txid,
|
||||
index,
|
||||
// tx
|
||||
})
|
||||
todo!();
|
||||
|
||||
// Ok(TxInfo {
|
||||
// txid,
|
||||
// index,
|
||||
// // tx
|
||||
// })
|
||||
}
|
||||
|
||||
@@ -7,26 +7,26 @@ use brk_error::Result;
|
||||
use brk_indexer::Indexer;
|
||||
use brk_parser::Parser;
|
||||
use brk_structs::{
|
||||
AddressInfo, AddressPath, Format, Height, Index, IndexInfo, MetricCount, MetricSearchQuery,
|
||||
TransactionInfo, TxidPath,
|
||||
Address, AddressStats, Format, Height, Index, IndexInfo, Limit, Metric, MetricCount, Tx,
|
||||
TxidPath,
|
||||
};
|
||||
use brk_traversable::TreeNode;
|
||||
use vecdb::{AnyCollectableVec, AnyStoredVec};
|
||||
|
||||
mod chain;
|
||||
mod deser;
|
||||
mod metrics;
|
||||
mod output;
|
||||
mod pagination;
|
||||
mod params;
|
||||
mod vecs;
|
||||
|
||||
pub use metrics::{Output, Value};
|
||||
pub use output::{Output, Value};
|
||||
pub use pagination::{PaginatedIndexParam, PaginatedMetrics, PaginationParam};
|
||||
pub use params::{Params, ParamsDeprec, ParamsOpt};
|
||||
use vecs::Vecs;
|
||||
|
||||
use crate::{
|
||||
chain::{get_address_info, get_transaction_info},
|
||||
chain::{get_address, get_transaction_info},
|
||||
vecs::{IndexToVec, MetricToVec},
|
||||
};
|
||||
|
||||
@@ -57,16 +57,16 @@ impl<'a> Interface<'a> {
|
||||
Height::from(self.indexer.vecs.height_to_blockhash.stamp())
|
||||
}
|
||||
|
||||
pub fn get_address_info(&self, address: AddressPath) -> Result<AddressInfo> {
|
||||
get_address_info(address, self)
|
||||
pub fn get_address(&self, address: Address) -> Result<AddressStats> {
|
||||
get_address(address, self)
|
||||
}
|
||||
|
||||
pub fn get_transaction_info(&self, txid: TxidPath) -> Result<TransactionInfo> {
|
||||
pub fn get_transaction_info(&self, txid: TxidPath) -> Result<Tx> {
|
||||
get_transaction_info(txid, self)
|
||||
}
|
||||
|
||||
pub fn match_metric(&self, query: MetricSearchQuery) -> Vec<&str> {
|
||||
self.vecs.matches(query)
|
||||
pub fn match_metric(&self, metric: &Metric, limit: Limit) -> Vec<&str> {
|
||||
self.vecs.matches(metric, limit)
|
||||
}
|
||||
|
||||
pub fn search_metric_with_index(
|
||||
|
||||
@@ -1,91 +0,0 @@
|
||||
use std::fmt;
|
||||
|
||||
use derive_deref::Deref;
|
||||
use schemars::JsonSchema;
|
||||
use serde::Deserialize;
|
||||
|
||||
mod output;
|
||||
|
||||
pub use output::*;
|
||||
|
||||
#[derive(Debug, Deref, JsonSchema)]
|
||||
pub struct MaybeMetrics(Vec<String>);
|
||||
|
||||
const MAX_VECS: usize = 32;
|
||||
const MAX_STRING_SIZE: usize = 64 * MAX_VECS;
|
||||
|
||||
impl From<String> for MaybeMetrics {
|
||||
fn from(value: String) -> Self {
|
||||
Self(vec![value.replace("-", "_").to_lowercase()])
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<Vec<&'a str>> for MaybeMetrics {
|
||||
fn from(value: Vec<&'a str>) -> Self {
|
||||
Self(
|
||||
value
|
||||
.iter()
|
||||
.map(|s| s.replace("-", "_").to_lowercase())
|
||||
.collect::<Vec<_>>(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for MaybeMetrics {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: serde::Deserializer<'de>,
|
||||
{
|
||||
let value = serde_json::Value::deserialize(deserializer)?;
|
||||
|
||||
if let Some(str) = value.as_str() {
|
||||
if str.len() <= MAX_STRING_SIZE {
|
||||
Ok(MaybeMetrics(sanitize_metrics(
|
||||
str.split(",").map(|s| s.to_string()),
|
||||
)))
|
||||
} else {
|
||||
Err(serde::de::Error::custom("Given parameter is too long"))
|
||||
}
|
||||
} else if let Some(vec) = value.as_array() {
|
||||
if vec.len() <= MAX_VECS {
|
||||
Ok(MaybeMetrics(sanitize_metrics(
|
||||
vec.iter().map(|s| s.as_str().unwrap().to_string()),
|
||||
)))
|
||||
} else {
|
||||
Err(serde::de::Error::custom("Given parameter is too long"))
|
||||
}
|
||||
} else {
|
||||
Err(serde::de::Error::custom("Bad ids format"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for MaybeMetrics {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let s = self.0.join(",");
|
||||
write!(f, "{s}")
|
||||
}
|
||||
}
|
||||
|
||||
fn sanitize_metrics(raw_ids: impl Iterator<Item = String>) -> Vec<String> {
|
||||
let mut results = Vec::new();
|
||||
raw_ids.for_each(|s| {
|
||||
let mut current = String::new();
|
||||
for c in s.to_lowercase().chars() {
|
||||
match c {
|
||||
' ' | ',' | '+' => {
|
||||
if !current.is_empty() {
|
||||
results.push(std::mem::take(&mut current));
|
||||
}
|
||||
}
|
||||
'-' => current.push('_'),
|
||||
c if c.is_alphanumeric() || c == '_' => current.push(c),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
if !current.is_empty() {
|
||||
results.push(current);
|
||||
}
|
||||
});
|
||||
results
|
||||
}
|
||||
@@ -1,21 +1,18 @@
|
||||
use std::ops::Deref;
|
||||
|
||||
use brk_structs::{Format, Index};
|
||||
use brk_structs::{Format, Index, Metric, Metrics};
|
||||
use derive_deref::Deref;
|
||||
use schemars::JsonSchema;
|
||||
use serde::Deserialize;
|
||||
|
||||
use crate::{
|
||||
deser::{de_unquote_i64, de_unquote_usize},
|
||||
metrics::MaybeMetrics,
|
||||
};
|
||||
use crate::deser::{de_unquote_i64, de_unquote_usize};
|
||||
|
||||
#[derive(Debug, Deserialize, JsonSchema)]
|
||||
pub struct Params {
|
||||
/// Requested metrics
|
||||
#[serde(alias = "m")]
|
||||
pub metrics: MaybeMetrics,
|
||||
pub metrics: Metrics,
|
||||
|
||||
/// Requested index
|
||||
#[serde(alias = "i")]
|
||||
pub index: Index,
|
||||
|
||||
@@ -30,11 +27,21 @@ impl Deref for Params {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<((Index, String), ParamsOpt)> for Params {
|
||||
fn from(((index, metric), rest): ((Index, String), ParamsOpt)) -> Self {
|
||||
impl From<(Index, Metric, ParamsOpt)> for Params {
|
||||
fn from((index, metric, rest): (Index, Metric, ParamsOpt)) -> Self {
|
||||
Self {
|
||||
index,
|
||||
metrics: MaybeMetrics::from(metric),
|
||||
metrics: Metrics::from(metric),
|
||||
rest,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<(Index, Metrics, ParamsOpt)> for Params {
|
||||
fn from((index, metrics, rest): (Index, Metrics, ParamsOpt)) -> Self {
|
||||
Self {
|
||||
index,
|
||||
metrics,
|
||||
rest,
|
||||
}
|
||||
}
|
||||
@@ -105,7 +112,7 @@ pub struct ParamsDeprec {
|
||||
#[serde(alias = "i")]
|
||||
pub index: Index,
|
||||
#[serde(alias = "v")]
|
||||
pub ids: MaybeMetrics,
|
||||
pub ids: Metrics,
|
||||
#[serde(flatten)]
|
||||
pub rest: ParamsOpt,
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ use std::collections::BTreeMap;
|
||||
|
||||
use brk_computer::Computer;
|
||||
use brk_indexer::Indexer;
|
||||
use brk_structs::{Index, IndexInfo, MetricSearchQuery};
|
||||
use brk_structs::{Index, IndexInfo, Limit, Metric};
|
||||
use brk_traversable::{Traversable, TreeNode};
|
||||
use derive_deref::{Deref, DerefMut};
|
||||
use quickmatch::{QuickMatch, QuickMatchConfig};
|
||||
@@ -172,9 +172,9 @@ impl<'a> Vecs<'a> {
|
||||
self.catalog.as_ref().unwrap()
|
||||
}
|
||||
|
||||
pub fn matches(&self, query: MetricSearchQuery) -> Vec<&'_ str> {
|
||||
pub fn matches(&self, metric: &Metric, limit: Limit) -> Vec<&'_ str> {
|
||||
self.matcher()
|
||||
.matches_with(&query.q, &QuickMatchConfig::new().with_limit(query.limit))
|
||||
.matches_with(metric, &QuickMatchConfig::new().with_limit(*limit))
|
||||
}
|
||||
|
||||
fn matcher(&self) -> &QuickMatch<'_> {
|
||||
|
||||
Reference in New Issue
Block a user