mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-04-24 06:39:58 -07:00
global: improve errors
This commit is contained in:
13
Cargo.lock
generated
13
Cargo.lock
generated
@@ -647,6 +647,7 @@ dependencies = [
|
||||
"jiff",
|
||||
"minreq",
|
||||
"serde_json",
|
||||
"thiserror 2.0.17",
|
||||
"tokio",
|
||||
"vecdb",
|
||||
]
|
||||
@@ -4189,7 +4190,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rawdb"
|
||||
version = "0.4.0"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "abd96eb8d340052584b01120ce302e283b9176b278b5b5944a5f0fc00493f861"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"log",
|
||||
@@ -5370,7 +5373,9 @@ checksum = "8f54a172d0620933a27a4360d3db3e2ae0dd6cceae9730751a036bbf182c4b23"
|
||||
|
||||
[[package]]
|
||||
name = "vecdb"
|
||||
version = "0.4.0"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "371b5a52a650ac0661a56ceae92e8af88e7930448ae9d3bb29c68a71437dc5d4"
|
||||
dependencies = [
|
||||
"ctrlc",
|
||||
"log",
|
||||
@@ -5388,7 +5393,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "vecdb_derive"
|
||||
version = "0.4.0"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f035c1c36fae53aeed226bdda0009292294986ea0ed6a932535cacdbec08d73d"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn 2.0.111",
|
||||
|
||||
@@ -76,9 +76,9 @@ serde_derive = "1.0.228"
|
||||
serde_json = { version = "1.0.145", features = ["float_roundtrip"] }
|
||||
smallvec = "1.15.1"
|
||||
tokio = { version = "1.48.0", features = ["rt-multi-thread"] }
|
||||
vecdb = { path = "../anydb/crates/vecdb", features = ["derive", "serde_json", "pco"] }
|
||||
vecdb = { version = "0.4.1", features = ["derive", "serde_json", "pco"] }
|
||||
# vecdb = { path = "../anydb/crates/vecdb", features = ["derive", "serde_json", "pco"] }
|
||||
# vecdb = { git = "https://github.com/anydb-rs/anydb", features = ["derive", "serde_json", "pco"] }
|
||||
# vecdb = { version = "0.4.0", features = ["derive", "serde_json", "pco"] }
|
||||
|
||||
[workspace.metadata.release]
|
||||
shared-version = true
|
||||
|
||||
@@ -9,7 +9,7 @@ use std::{
|
||||
time::{Duration, Instant, SystemTime, UNIX_EPOCH},
|
||||
};
|
||||
|
||||
use brk_error::Result;
|
||||
use brk_error::{Error, Result};
|
||||
|
||||
mod disk;
|
||||
mod io;
|
||||
@@ -84,7 +84,7 @@ impl Bencher {
|
||||
|
||||
current = current
|
||||
.parent()
|
||||
.ok_or("Workspace root not found")?
|
||||
.ok_or(Error::NotFound("Workspace root not found".into()))?
|
||||
.to_path_buf();
|
||||
};
|
||||
|
||||
@@ -94,7 +94,7 @@ impl Bencher {
|
||||
/// Start monitoring disk usage and memory footprint
|
||||
pub fn start(&mut self) -> Result<()> {
|
||||
if self.0.monitor_thread.lock().is_some() {
|
||||
return Err("Bencher already started".into());
|
||||
return Err(Error::Internal("Bencher already started"));
|
||||
}
|
||||
|
||||
let stop_flag = self.0.stop_flag.clone();
|
||||
@@ -113,7 +113,7 @@ impl Bencher {
|
||||
self.0.stop_flag.store(true, Ordering::Relaxed);
|
||||
|
||||
if let Some(handle) = self.0.monitor_thread.lock().take() {
|
||||
handle.join().map_err(|_| "Monitor thread panicked")??;
|
||||
handle.join().map_err(|_| Error::Internal("Monitor thread panicked"))??;
|
||||
}
|
||||
|
||||
self.0.progression.flush()?;
|
||||
|
||||
@@ -218,7 +218,7 @@ Finally, you can run the program with '-h' for help."
|
||||
self.rpcpassword.clone().unwrap(),
|
||||
))
|
||||
} else {
|
||||
Err(Error::Str("Failed to find correct auth"))
|
||||
Err(Error::AuthFailed)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ use brk_iterator::Blocks;
|
||||
use brk_reader::Reader;
|
||||
use brk_rpc::{Auth, Client};
|
||||
use log::{debug, info};
|
||||
use vecdb::{AnyStoredVec, Exit};
|
||||
use vecdb::Exit;
|
||||
|
||||
pub fn main() -> Result<()> {
|
||||
// Can't increase main thread's stack size, thus we need to use another thread
|
||||
@@ -45,15 +45,6 @@ fn run() -> Result<()> {
|
||||
|
||||
let mut computer = Computer::forced_import(&outputs_benches_dir, &indexer, Some(fetcher))?;
|
||||
|
||||
dbg!(
|
||||
computer
|
||||
.indexes
|
||||
.txinindex_to_txoutindex
|
||||
.region()
|
||||
.meta()
|
||||
.reserved()
|
||||
);
|
||||
|
||||
let mut bencher =
|
||||
Bencher::from_cargo_env(env!("CARGO_PKG_NAME"), &outputs_dir.join("computed"))?;
|
||||
bencher.start()?;
|
||||
|
||||
@@ -5,7 +5,7 @@ use brk_error::Result;
|
||||
use brk_fetcher::Fetcher;
|
||||
use brk_indexer::Indexer;
|
||||
use brk_types::TxIndex;
|
||||
use vecdb::{AnyStoredVec, Exit, GenericStoredVec};
|
||||
use vecdb::{Exit, GenericStoredVec};
|
||||
|
||||
pub fn main() -> Result<()> {
|
||||
// Can't increase main thread's stack size, thus we need to use another thread
|
||||
@@ -61,18 +61,7 @@ fn run() -> Result<()> {
|
||||
.txindex_to_output_count
|
||||
.read_once(txindex)?;
|
||||
dbg!(output_count);
|
||||
let _ = dbg!(
|
||||
computer
|
||||
.indexes
|
||||
.txinindex_to_txoutindex
|
||||
.read_once(first_txinindex)
|
||||
);
|
||||
let _ = dbg!(
|
||||
computer
|
||||
.indexes
|
||||
.txinindex_to_txoutindex
|
||||
.read_once(first_txinindex + 1)
|
||||
);
|
||||
|
||||
let _ = dbg!(computer.chain.txinindex_to_value.read_once(first_txinindex));
|
||||
let _ = dbg!(
|
||||
computer
|
||||
@@ -98,13 +87,6 @@ fn run() -> Result<()> {
|
||||
let _ = dbg!(computer.chain.txindex_to_input_value.read_once(txindex));
|
||||
let _ = dbg!(computer.chain.txindex_to_output_value.read_once(txindex));
|
||||
// dbg!(computer.indexes.txindex_to_txindex.ge(txindex));
|
||||
dbg!(
|
||||
computer
|
||||
.indexes
|
||||
.txinindex_to_txoutindex
|
||||
.region()
|
||||
.meta()
|
||||
.len()
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -853,19 +853,33 @@ impl Vecs {
|
||||
compute_indexes_to_tx_vany(&mut self.indexes_to_tx_v2, TxVersion::TWO)?;
|
||||
compute_indexes_to_tx_vany(&mut self.indexes_to_tx_v3, TxVersion::THREE)?;
|
||||
|
||||
// ---
|
||||
// TxInIndex
|
||||
// ---
|
||||
|
||||
let txindex_to_first_txoutindex = &indexer.vecs.tx.txindex_to_first_txoutindex;
|
||||
let txindex_to_first_txoutindex_reader = txindex_to_first_txoutindex.create_reader();
|
||||
let txoutindex_to_value = &indexer.vecs.txout.txoutindex_to_value;
|
||||
let txoutindex_to_value_reader = indexer.vecs.txout.txoutindex_to_value.create_reader();
|
||||
self.txinindex_to_value.compute_transform(
|
||||
starting_indexes.txinindex,
|
||||
&indexes.txinindex_to_txoutindex,
|
||||
|(txinindex, txoutindex, ..)| {
|
||||
let value = if txoutindex == TxOutIndex::COINBASE {
|
||||
Sats::MAX
|
||||
&indexer.vecs.txin.txinindex_to_outpoint,
|
||||
|(txinindex, outpoint, ..)| {
|
||||
if unlikely(outpoint.is_coinbase()) {
|
||||
return (txinindex, Sats::MAX);
|
||||
}
|
||||
let txoutindex = txindex_to_first_txoutindex
|
||||
.read_unwrap(outpoint.txindex(), &txindex_to_first_txoutindex_reader)
|
||||
+ outpoint.vout();
|
||||
|
||||
let value = if unlikely(txoutindex == TxOutIndex::COINBASE) {
|
||||
unreachable!()
|
||||
} else {
|
||||
txoutindex_to_value
|
||||
.unchecked_read(txoutindex, &txoutindex_to_value_reader)
|
||||
.unwrap()
|
||||
};
|
||||
|
||||
(txinindex, value)
|
||||
},
|
||||
exit,
|
||||
|
||||
@@ -159,7 +159,7 @@ where
|
||||
/// Compute percentiles from sorted values (assumes values is already sorted)
|
||||
fn compute_percentiles_from_sorted(&mut self, index: usize, values: &[T]) -> Result<()> {
|
||||
if let Some(max) = self.max.as_mut() {
|
||||
max.truncate_push_at(index, *values.last().ok_or(Error::Str("expect some"))?)?;
|
||||
max.truncate_push_at(index, *values.last().ok_or(Error::Internal("Empty values for percentiles"))?)?;
|
||||
}
|
||||
if let Some(pct90) = self.pct90.as_mut() {
|
||||
pct90.truncate_push_at(index, get_percentile(values, 0.90))?;
|
||||
|
||||
@@ -13,8 +13,8 @@ use brk_types::{
|
||||
YearIndex,
|
||||
};
|
||||
use vecdb::{
|
||||
Database, EagerVec, Exit, GenericStoredVec, ImportableVec, IterableCloneableVec, LazyVecFrom1,
|
||||
PAGE_SIZE, PcoVec, TypedVecIterator, unlikely,
|
||||
Database, EagerVec, Exit, ImportableVec, IterableCloneableVec, LazyVecFrom1, PAGE_SIZE, PcoVec,
|
||||
TypedVecIterator,
|
||||
};
|
||||
|
||||
const VERSION: Version = Version::ZERO;
|
||||
@@ -83,7 +83,6 @@ pub struct Vecs {
|
||||
pub txindex_to_output_count: EagerVec<PcoVec<TxIndex, StoredU64>>,
|
||||
pub txindex_to_txindex: LazyVecFrom1<TxIndex, TxIndex, TxIndex, Txid>,
|
||||
pub txinindex_to_txinindex: LazyVecFrom1<TxInIndex, TxInIndex, TxInIndex, OutPoint>,
|
||||
pub txinindex_to_txoutindex: EagerVec<PcoVec<TxInIndex, TxOutIndex>>,
|
||||
pub txoutindex_to_txoutindex: LazyVecFrom1<TxOutIndex, TxOutIndex, TxOutIndex, Sats>,
|
||||
pub unknownoutputindex_to_unknownoutputindex:
|
||||
LazyVecFrom1<UnknownOutputIndex, UnknownOutputIndex, UnknownOutputIndex, TxIndex>,
|
||||
@@ -121,7 +120,6 @@ impl Vecs {
|
||||
}
|
||||
|
||||
let this = Self {
|
||||
txinindex_to_txoutindex: eager!("txoutindex"),
|
||||
txoutindex_to_txoutindex: lazy!("txoutindex", indexer.vecs.txout.txoutindex_to_value),
|
||||
txinindex_to_txinindex: lazy!("txinindex", indexer.vecs.txin.txinindex_to_outpoint),
|
||||
p2pk33addressindex_to_p2pk33addressindex: lazy!(
|
||||
@@ -247,27 +245,6 @@ impl Vecs {
|
||||
starting_indexes: brk_indexer::Indexes,
|
||||
exit: &Exit,
|
||||
) -> Result<Indexes> {
|
||||
// ---
|
||||
// TxInIndex
|
||||
// ---
|
||||
|
||||
let txindex_to_first_txoutindex = &indexer.vecs.tx.txindex_to_first_txoutindex;
|
||||
let txindex_to_first_txoutindex_reader = txindex_to_first_txoutindex.create_reader();
|
||||
self.txinindex_to_txoutindex.compute_transform(
|
||||
starting_indexes.txinindex,
|
||||
&indexer.vecs.txin.txinindex_to_outpoint,
|
||||
|(txinindex, outpoint, ..)| {
|
||||
if unlikely(outpoint.is_coinbase()) {
|
||||
return (txinindex, TxOutIndex::COINBASE);
|
||||
}
|
||||
let txoutindex = txindex_to_first_txoutindex
|
||||
.read_unwrap(outpoint.txindex(), &txindex_to_first_txoutindex_reader)
|
||||
+ outpoint.vout();
|
||||
(txinindex, txoutindex)
|
||||
},
|
||||
exit,
|
||||
)?;
|
||||
|
||||
// ---
|
||||
// TxIndex
|
||||
// ---
|
||||
|
||||
@@ -821,7 +821,7 @@ impl Vecs {
|
||||
|
||||
Ok(prev_height.incremented())
|
||||
} else {
|
||||
Err(Error::Str("Unset"))
|
||||
Err(Error::Internal("No previous height to import state from"))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ impl PriceToAmount {
|
||||
let (&height, path) = files
|
||||
.range(..=height)
|
||||
.next_back()
|
||||
.ok_or(Error::Str("Not found"))?;
|
||||
.ok_or(Error::NotFound("No price state found at or before height".into()))?;
|
||||
self.state = Some(State::deserialize(&fs::read(path)?)?);
|
||||
Ok(height)
|
||||
}
|
||||
|
||||
@@ -15,5 +15,6 @@ fjall = { workspace = true }
|
||||
jiff = { workspace = true }
|
||||
minreq = { workspace = true }
|
||||
serde_json = { workspace = true }
|
||||
thiserror = "2.0"
|
||||
tokio = { workspace = true }
|
||||
vecdb = { workspace = true }
|
||||
|
||||
@@ -1,210 +1,130 @@
|
||||
#![doc = include_str!("../README.md")]
|
||||
|
||||
use std::{
|
||||
fmt::{self, Debug, Display},
|
||||
io, result, time,
|
||||
};
|
||||
use std::{io, result, time};
|
||||
|
||||
use thiserror::Error;
|
||||
|
||||
pub type Result<T, E = Error> = result::Result<T, E>;
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Error)]
|
||||
pub enum Error {
|
||||
IO(io::Error),
|
||||
BitcoinRPC(bitcoincore_rpc::Error),
|
||||
Jiff(jiff::Error),
|
||||
Fjall(fjall::Error),
|
||||
VecDB(vecdb::Error),
|
||||
RawDB(vecdb::RawDBError),
|
||||
Minreq(minreq::Error),
|
||||
SystemTimeError(time::SystemTimeError),
|
||||
BitcoinConsensusEncode(bitcoin::consensus::encode::Error),
|
||||
BitcoinBip34Error(bitcoin::block::Bip34Error),
|
||||
BitcoinHexError(bitcoin::consensus::encode::FromHexError),
|
||||
BitcoinFromScriptError(bitcoin::address::FromScriptError),
|
||||
BitcoinHexToArrayError(bitcoin::hex::HexToArrayError),
|
||||
SerdeJSON(serde_json::Error),
|
||||
TokioJoin(tokio::task::JoinError),
|
||||
ZeroCopyError,
|
||||
Vecs(vecdb::Error),
|
||||
#[error(transparent)]
|
||||
IO(#[from] io::Error),
|
||||
|
||||
#[error(transparent)]
|
||||
BitcoinRPC(#[from] bitcoincore_rpc::Error),
|
||||
|
||||
#[error(transparent)]
|
||||
Jiff(#[from] jiff::Error),
|
||||
|
||||
#[error(transparent)]
|
||||
Fjall(#[from] fjall::Error),
|
||||
|
||||
#[error(transparent)]
|
||||
VecDB(#[from] vecdb::Error),
|
||||
|
||||
#[error(transparent)]
|
||||
RawDB(#[from] vecdb::RawDBError),
|
||||
|
||||
#[error(transparent)]
|
||||
Minreq(#[from] minreq::Error),
|
||||
|
||||
#[error(transparent)]
|
||||
SystemTimeError(#[from] time::SystemTimeError),
|
||||
|
||||
#[error(transparent)]
|
||||
BitcoinConsensusEncode(#[from] bitcoin::consensus::encode::Error),
|
||||
|
||||
#[error(transparent)]
|
||||
BitcoinBip34Error(#[from] bitcoin::block::Bip34Error),
|
||||
|
||||
#[error(transparent)]
|
||||
BitcoinHexError(#[from] bitcoin::consensus::encode::FromHexError),
|
||||
|
||||
#[error(transparent)]
|
||||
BitcoinFromScriptError(#[from] bitcoin::address::FromScriptError),
|
||||
|
||||
#[error(transparent)]
|
||||
BitcoinHexToArrayError(#[from] bitcoin::hex::HexToArrayError),
|
||||
|
||||
#[error(transparent)]
|
||||
SerdeJSON(#[from] serde_json::Error),
|
||||
|
||||
#[error(transparent)]
|
||||
TokioJoin(#[from] tokio::task::JoinError),
|
||||
|
||||
#[error("ZeroCopy error")]
|
||||
ZeroCopyError,
|
||||
|
||||
#[error("Wrong length, expected: {expected}, received: {received}")]
|
||||
WrongLength { expected: usize, received: usize },
|
||||
|
||||
#[error("Wrong address type")]
|
||||
WrongAddressType,
|
||||
|
||||
#[error("Date cannot be indexed, must be 2009-01-03, 2009-01-09 or greater")]
|
||||
UnindexableDate,
|
||||
|
||||
#[error("Quick cache error")]
|
||||
QuickCacheError,
|
||||
|
||||
#[error("The provided address appears to be invalid")]
|
||||
InvalidAddress,
|
||||
|
||||
#[error("Invalid network")]
|
||||
InvalidNetwork,
|
||||
|
||||
#[error("The provided TXID appears to be invalid")]
|
||||
InvalidTxid,
|
||||
|
||||
#[error("Mempool data is not available")]
|
||||
MempoolNotAvailable,
|
||||
|
||||
#[error("Address not found in the blockchain (no transaction history)")]
|
||||
UnknownAddress,
|
||||
|
||||
#[error("Failed to find the TXID in the blockchain")]
|
||||
UnknownTxid,
|
||||
|
||||
#[error("Unsupported type ({0})")]
|
||||
UnsupportedType(String),
|
||||
|
||||
Str(&'static str),
|
||||
String(String),
|
||||
// Generic errors with context
|
||||
#[error("{0}")]
|
||||
NotFound(String),
|
||||
|
||||
#[error("{0}")]
|
||||
OutOfRange(String),
|
||||
|
||||
#[error("Parse error: {0}")]
|
||||
Parse(String),
|
||||
|
||||
#[error("Internal error: {0}")]
|
||||
Internal(&'static str),
|
||||
|
||||
#[error("Authentication failed")]
|
||||
AuthFailed,
|
||||
|
||||
// Metric-specific errors
|
||||
#[error("'{metric}' not found{}", suggestion.as_ref().map(|s| format!(", did you mean '{s}'?")).unwrap_or_default())]
|
||||
MetricNotFound {
|
||||
metric: String,
|
||||
suggestion: Option<String>,
|
||||
},
|
||||
|
||||
#[error("'{metric}' doesn't support the requested index. Supported indexes: {supported}")]
|
||||
MetricUnsupportedIndex { metric: String, supported: String },
|
||||
|
||||
#[error("No metrics specified")]
|
||||
NoMetrics,
|
||||
|
||||
#[error("Request weight {requested} exceeds maximum {max}")]
|
||||
WeightExceeded { requested: usize, max: usize },
|
||||
|
||||
#[error("Fetch failed after retries: {0}")]
|
||||
FetchFailed(String),
|
||||
}
|
||||
|
||||
impl From<bitcoin::block::Bip34Error> for Error {
|
||||
#[inline]
|
||||
fn from(value: bitcoin::block::Bip34Error) -> Self {
|
||||
Self::BitcoinBip34Error(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<bitcoin::consensus::encode::Error> for Error {
|
||||
#[inline]
|
||||
fn from(value: bitcoin::consensus::encode::Error) -> Self {
|
||||
Self::BitcoinConsensusEncode(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<bitcoin::consensus::encode::FromHexError> for Error {
|
||||
#[inline]
|
||||
fn from(value: bitcoin::consensus::encode::FromHexError) -> Self {
|
||||
Self::BitcoinHexError(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<bitcoin::hex::HexToArrayError> for Error {
|
||||
#[inline]
|
||||
fn from(value: bitcoin::hex::HexToArrayError) -> Self {
|
||||
Self::BitcoinHexToArrayError(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<bitcoin::address::FromScriptError> for Error {
|
||||
#[inline]
|
||||
fn from(value: bitcoin::address::FromScriptError) -> Self {
|
||||
Self::BitcoinFromScriptError(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<time::SystemTimeError> for Error {
|
||||
#[inline]
|
||||
fn from(value: time::SystemTimeError) -> Self {
|
||||
Self::SystemTimeError(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<serde_json::Error> for Error {
|
||||
#[inline]
|
||||
fn from(error: serde_json::Error) -> Self {
|
||||
Self::SerdeJSON(error)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<tokio::task::JoinError> for Error {
|
||||
#[inline]
|
||||
fn from(error: tokio::task::JoinError) -> Self {
|
||||
Self::TokioJoin(error)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<io::Error> for Error {
|
||||
#[inline]
|
||||
fn from(value: io::Error) -> Self {
|
||||
Self::IO(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<vecdb::Error> for Error {
|
||||
#[inline]
|
||||
fn from(value: vecdb::Error) -> Self {
|
||||
Self::VecDB(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<vecdb::RawDBError> for Error {
|
||||
#[inline]
|
||||
fn from(value: vecdb::RawDBError) -> Self {
|
||||
Self::RawDB(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<bitcoincore_rpc::Error> for Error {
|
||||
#[inline]
|
||||
fn from(value: bitcoincore_rpc::Error) -> Self {
|
||||
Self::BitcoinRPC(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<minreq::Error> for Error {
|
||||
#[inline]
|
||||
fn from(value: minreq::Error) -> Self {
|
||||
Self::Minreq(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<jiff::Error> for Error {
|
||||
#[inline]
|
||||
fn from(value: jiff::Error) -> Self {
|
||||
Self::Jiff(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<fjall::Error> for Error {
|
||||
#[inline]
|
||||
fn from(value: fjall::Error) -> Self {
|
||||
Self::Fjall(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&'static str> for Error {
|
||||
#[inline]
|
||||
fn from(value: &'static str) -> Self {
|
||||
Self::Str(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Error {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
Error::BitcoinConsensusEncode(error) => Display::fmt(&error, f),
|
||||
Error::BitcoinBip34Error(error) => Display::fmt(&error, f),
|
||||
Error::BitcoinFromScriptError(error) => Display::fmt(&error, f),
|
||||
Error::BitcoinHexError(error) => Display::fmt(&error, f),
|
||||
Error::BitcoinHexToArrayError(error) => Display::fmt(&error, f),
|
||||
Error::BitcoinRPC(error) => Display::fmt(&error, f),
|
||||
Error::Fjall(error) => Display::fmt(&error, f),
|
||||
Error::IO(error) => Display::fmt(&error, f),
|
||||
Error::Jiff(error) => Display::fmt(&error, f),
|
||||
Error::Minreq(error) => Display::fmt(&error, f),
|
||||
Error::RawDB(error) => Display::fmt(&error, f),
|
||||
Error::SerdeJSON(error) => Display::fmt(&error, f),
|
||||
Error::SystemTimeError(error) => Display::fmt(&error, f),
|
||||
Error::TokioJoin(error) => Display::fmt(&error, f),
|
||||
Error::VecDB(error) => Display::fmt(&error, f),
|
||||
Error::Vecs(error) => Display::fmt(&error, f),
|
||||
Error::ZeroCopyError => write!(f, "ZeroCopy error"),
|
||||
Error::WrongLength { expected, received } => write!(
|
||||
f,
|
||||
"Wrong length, expected: {expected}, received: {received}"
|
||||
),
|
||||
Error::QuickCacheError => write!(f, "Quick cache error"),
|
||||
Error::WrongAddressType => write!(f, "Wrong address type"),
|
||||
Error::UnindexableDate => write!(
|
||||
f,
|
||||
"Date cannot be indexed, must be 2009-01-03, 2009-01-09 or greater"
|
||||
),
|
||||
|
||||
Error::InvalidTxid => write!(f, "The provided TXID appears to be invalid"),
|
||||
Error::InvalidNetwork => write!(f, "Invalid network"),
|
||||
Error::InvalidAddress => write!(f, "The provided address appears to be invalid"),
|
||||
Error::MempoolNotAvailable => write!(f, "Mempool data is not available"),
|
||||
Error::UnknownAddress => write!(
|
||||
f,
|
||||
"Address not found in the blockchain (no transaction history)"
|
||||
),
|
||||
Error::UnknownTxid => write!(f, "Failed to find the TXID in the blockchain"),
|
||||
Error::UnsupportedType(t) => write!(f, "Unsupported type ({t})"),
|
||||
|
||||
Error::Str(s) => write!(f, "{s}"),
|
||||
Error::String(s) => write!(f, "{s}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::error::Error for Error {}
|
||||
|
||||
impl Error {
|
||||
/// Returns true if this network/fetch error indicates a permanent/blocking condition
|
||||
|
||||
@@ -88,7 +88,7 @@ impl Binance {
|
||||
.unwrap()
|
||||
.get(date)
|
||||
.cloned()
|
||||
.ok_or(Error::Str("Couldn't find date"))
|
||||
.ok_or(Error::NotFound("Couldn't find date".into()))
|
||||
}
|
||||
|
||||
pub fn fetch_1d() -> Result<BTreeMap<Date, OHLCCents>> {
|
||||
@@ -102,7 +102,7 @@ impl Binance {
|
||||
|
||||
fn read_har(&self) -> Result<BTreeMap<Timestamp, OHLCCents>> {
|
||||
if self.path.is_none() {
|
||||
return Err(Error::Str("Path missing"));
|
||||
return Err(Error::NotFound("HAR path not configured".into()));
|
||||
}
|
||||
|
||||
info!("Reading Binance har file...");
|
||||
@@ -116,7 +116,7 @@ impl Binance {
|
||||
let file = if let Ok(file) = File::open(path_binance_har) {
|
||||
file
|
||||
} else {
|
||||
return Err(Error::Str("Missing binance file"));
|
||||
return Err(Error::NotFound("Binance HAR file not found".into()));
|
||||
};
|
||||
|
||||
let reader = BufReader::new(file);
|
||||
@@ -128,13 +128,13 @@ impl Binance {
|
||||
};
|
||||
|
||||
json.get("log")
|
||||
.ok_or(Error::Str("Expect object to have log attribute"))?
|
||||
.ok_or(Error::Parse("HAR missing 'log' field".into()))?
|
||||
.as_object()
|
||||
.ok_or(Error::Str("Expect to be an object"))?
|
||||
.ok_or(Error::Parse("HAR 'log' is not an object".into()))?
|
||||
.get("entries")
|
||||
.ok_or(Error::Str("Expect object to have entries"))?
|
||||
.ok_or(Error::Parse("HAR missing 'entries' field".into()))?
|
||||
.as_array()
|
||||
.ok_or(Error::Str("Expect to be an array"))?
|
||||
.ok_or(Error::Parse("HAR 'entries' is not an array".into()))?
|
||||
.iter()
|
||||
.filter(|entry| {
|
||||
entry
|
||||
@@ -180,7 +180,7 @@ impl Binance {
|
||||
fn parse_ohlc_array(json: &Value) -> Result<BTreeMap<Timestamp, OHLCCents>> {
|
||||
let result = json
|
||||
.as_array()
|
||||
.ok_or(Error::Str("Expected JSON array"))?
|
||||
.ok_or(Error::Parse("Expected JSON array".into()))?
|
||||
.iter()
|
||||
.filter_map(|v| v.as_array())
|
||||
.map(|arr| {
|
||||
|
||||
@@ -34,7 +34,7 @@ impl BRK {
|
||||
.unwrap()
|
||||
.get(usize::from(height.checked_sub(key).unwrap()))
|
||||
.cloned()
|
||||
.ok_or(Error::Str("Couldn't find height in BRK"))
|
||||
.ok_or(Error::NotFound("Couldn't find height in BRK".into()))
|
||||
}
|
||||
|
||||
fn fetch_height_prices(height: Height) -> Result<Vec<OHLCCents>> {
|
||||
@@ -49,7 +49,7 @@ impl BRK {
|
||||
let body: Value = serde_json::from_slice(minreq::get(url).send()?.as_bytes())?;
|
||||
|
||||
body.as_array()
|
||||
.ok_or(Error::Str("Expect to be an array"))?
|
||||
.ok_or(Error::Parse("Expected JSON array".into()))?
|
||||
.iter()
|
||||
.map(Self::value_to_ohlc)
|
||||
.collect::<Result<Vec<_>, _>>()
|
||||
@@ -74,7 +74,7 @@ impl BRK {
|
||||
.unwrap()
|
||||
.get(usize::from(dateindex.checked_sub(key).unwrap()))
|
||||
.cloned()
|
||||
.ok_or(Error::Str("Couldn't find date in BRK"))
|
||||
.ok_or(Error::NotFound("Couldn't find date in BRK".into()))
|
||||
}
|
||||
|
||||
fn fetch_date_prices(dateindex: DateIndex) -> Result<Vec<OHLCCents>> {
|
||||
@@ -89,7 +89,7 @@ impl BRK {
|
||||
let body: Value = serde_json::from_slice(minreq::get(url).send()?.as_bytes())?;
|
||||
|
||||
body.as_array()
|
||||
.ok_or(Error::Str("Expect to be an array"))?
|
||||
.ok_or(Error::Parse("Expected JSON array".into()))?
|
||||
.iter()
|
||||
.map(Self::value_to_ohlc)
|
||||
.collect::<Result<Vec<_>, _>>()
|
||||
@@ -99,14 +99,14 @@ impl BRK {
|
||||
fn value_to_ohlc(value: &Value) -> Result<OHLCCents> {
|
||||
let ohlc = value
|
||||
.as_array()
|
||||
.ok_or(Error::Str("Expect as_array to work"))?;
|
||||
.ok_or(Error::Parse("Expected OHLC array".into()))?;
|
||||
|
||||
let get_value = |index: usize| -> Result<_> {
|
||||
Ok(Cents::from(Dollars::from(
|
||||
ohlc.get(index)
|
||||
.ok_or(Error::Str("Expect index key to work"))?
|
||||
.ok_or(Error::Parse("Missing OHLC value at index".into()))?
|
||||
.as_f64()
|
||||
.ok_or(Error::Str("Expect as_f64 to work"))?,
|
||||
.ok_or(Error::Parse("Invalid OHLC value type".into()))?,
|
||||
)))
|
||||
};
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ impl Kraken {
|
||||
.unwrap()
|
||||
.get(date)
|
||||
.cloned()
|
||||
.ok_or(Error::Str("Couldn't find date"))
|
||||
.ok_or(Error::NotFound("Couldn't find date".into()))
|
||||
}
|
||||
|
||||
pub fn fetch_1d() -> Result<BTreeMap<Date, OHLCCents>> {
|
||||
@@ -71,7 +71,7 @@ impl Kraken {
|
||||
.get("result")
|
||||
.and_then(|r| r.get("XXBTZUSD"))
|
||||
.and_then(|v| v.as_array())
|
||||
.ok_or(Error::Str("Invalid Kraken response format"))?
|
||||
.ok_or(Error::Parse("Invalid Kraken response format".into()))?
|
||||
.iter()
|
||||
.filter_map(|v| v.as_array())
|
||||
.map(|arr| {
|
||||
|
||||
@@ -146,7 +146,7 @@ How to fix this:
|
||||
}
|
||||
}
|
||||
|
||||
Err(Error::String(error_message()))
|
||||
Err(Error::FetchFailed(error_message()))
|
||||
}
|
||||
|
||||
fn clear_caches(&mut self) {
|
||||
|
||||
@@ -38,7 +38,7 @@ pub fn compute_ohlc_from_range(
|
||||
let last_ohlc = tree.get(×tamp);
|
||||
|
||||
if previous_ohlc.is_none() || last_ohlc.is_none() {
|
||||
return Err(Error::String(format!(
|
||||
return Err(Error::NotFound(format!(
|
||||
"Couldn't find timestamp in {source_name}"
|
||||
)));
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ impl<T: PriceSource> TrackedSource<T> {
|
||||
/// Try to fetch, tracking health state
|
||||
fn try_fetch<R>(&mut self, fetch: impl FnOnce(&mut T) -> Option<Result<R>>) -> Option<Result<R>> {
|
||||
if !self.is_healthy() {
|
||||
return Some(Err(Error::String(format!(
|
||||
return Some(Err(Error::FetchFailed(format!(
|
||||
"{} temporarily disabled (recheck in {}s)",
|
||||
self.name(),
|
||||
self.remaining_cooldown()
|
||||
|
||||
@@ -76,7 +76,7 @@ impl<'a> BlockProcessor<'a> {
|
||||
.is_some_and(|prev_height| *prev_height != height)
|
||||
{
|
||||
error!("BlockHash: {blockhash}");
|
||||
return Err(Error::Str("Collision, expect prefix to need be set yet"));
|
||||
return Err(Error::Internal("BlockHash prefix collision"));
|
||||
}
|
||||
|
||||
self.indexes.push_if_needed(self.vecs)?;
|
||||
@@ -234,7 +234,7 @@ impl<'a> BlockProcessor<'a> {
|
||||
.tx
|
||||
.txindex_to_first_txoutindex
|
||||
.get_pushed_or_read(prev_txindex, &self.readers.txindex_to_first_txoutindex)?
|
||||
.ok_or(Error::Str("Expect txoutindex to not be none"))?
|
||||
.ok_or(Error::Internal("Missing txoutindex"))?
|
||||
+ vout;
|
||||
|
||||
let outpoint = OutPoint::new(prev_txindex, vout);
|
||||
@@ -243,7 +243,7 @@ impl<'a> BlockProcessor<'a> {
|
||||
.txout
|
||||
.txoutindex_to_outputtype
|
||||
.get_pushed_or_read(txoutindex, &self.readers.txoutindex_to_outputtype)?
|
||||
.ok_or(Error::Str("Expect outputtype to not be none"))?;
|
||||
.ok_or(Error::Internal("Missing outputtype"))?;
|
||||
|
||||
let address_info = if outputtype.is_address() {
|
||||
let typeindex = self
|
||||
@@ -251,7 +251,7 @@ impl<'a> BlockProcessor<'a> {
|
||||
.txout
|
||||
.txoutindex_to_typeindex
|
||||
.get_pushed_or_read(txoutindex, &self.readers.txoutindex_to_typeindex)?
|
||||
.ok_or(Error::Str("Expect typeindex to not be none"))?;
|
||||
.ok_or(Error::Internal("Missing typeindex"))?;
|
||||
Some((outputtype, typeindex))
|
||||
} else {
|
||||
None
|
||||
@@ -358,7 +358,7 @@ impl<'a> BlockProcessor<'a> {
|
||||
)?;
|
||||
let prev_addressbytes = prev_addressbytes_opt
|
||||
.as_ref()
|
||||
.ok_or(Error::Str("Expect to have addressbytes"))?;
|
||||
.ok_or(Error::Internal("Missing addressbytes"))?;
|
||||
|
||||
if self
|
||||
.stores
|
||||
@@ -574,7 +574,7 @@ impl<'a> BlockProcessor<'a> {
|
||||
} else {
|
||||
let outputtype_typeindex = same_block_output_info
|
||||
.remove(&outpoint)
|
||||
.ok_or(Error::Str("should have found addressindex from same block"))
|
||||
.ok_or(Error::Internal("Same-block addressindex not found"))
|
||||
.inspect_err(|_| {
|
||||
dbg!(&same_block_output_info, txin);
|
||||
})?;
|
||||
@@ -646,7 +646,7 @@ impl<'a> BlockProcessor<'a> {
|
||||
let len = self.vecs.tx.txindex_to_txid.len();
|
||||
let prev_txid = txindex_to_txid_iter
|
||||
.get(prev_txindex)
|
||||
.ok_or(Error::Str("To have txid for txindex"))
|
||||
.ok_or(Error::Internal("Missing txid for txindex"))
|
||||
.inspect_err(|_| {
|
||||
dbg!(ct.txindex, len);
|
||||
})?;
|
||||
@@ -655,7 +655,7 @@ impl<'a> BlockProcessor<'a> {
|
||||
|
||||
if !is_dup {
|
||||
dbg!(self.height, ct.txindex, prev_txid, prev_txindex);
|
||||
return Err(Error::Str("Expect none"));
|
||||
return Err(Error::Internal("Unexpected TXID collision"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ impl Query {
|
||||
let outputtype = OutputType::from(&script);
|
||||
dbg!(outputtype);
|
||||
let Ok(bytes) = AddressBytes::try_from((&script, outputtype)) else {
|
||||
return Err(Error::Str("Failed to convert the address to bytes"));
|
||||
return Err(Error::InvalidAddress);
|
||||
};
|
||||
let addresstype = outputtype;
|
||||
let hash = AddressHash::from(&bytes);
|
||||
@@ -116,8 +116,8 @@ impl Query {
|
||||
let txindex = stores
|
||||
.txidprefix_to_txindex
|
||||
.get(&after_txid.into())
|
||||
.map_err(|_| Error::Str("Failed to look up after_txid"))?
|
||||
.ok_or(Error::Str("after_txid not found"))?
|
||||
.map_err(|_| Error::UnknownTxid)?
|
||||
.ok_or(Error::UnknownTxid)?
|
||||
.into_owned();
|
||||
Some(txindex)
|
||||
} else {
|
||||
@@ -202,7 +202,7 @@ impl Query {
|
||||
}
|
||||
|
||||
pub fn address_mempool_txids(&self, address: Address) -> Result<Vec<Txid>> {
|
||||
let mempool = self.mempool().ok_or(Error::Str("Mempool not available"))?;
|
||||
let mempool = self.mempool().ok_or(Error::MempoolNotAvailable)?;
|
||||
|
||||
let bytes = AddressBytes::from_str(&address)?;
|
||||
let addresses = mempool.get_addresses();
|
||||
|
||||
@@ -17,7 +17,7 @@ impl Query {
|
||||
|
||||
let max_height = self.max_height();
|
||||
if height > max_height {
|
||||
return Err(Error::Str("Block height out of range"));
|
||||
return Err(Error::OutOfRange("Block height out of range".into()));
|
||||
}
|
||||
|
||||
let blockhash = indexer.vecs.block.height_to_blockhash.read_once(height)?;
|
||||
@@ -68,7 +68,7 @@ impl Query {
|
||||
.blockhashprefix_to_height
|
||||
.get(&prefix)?
|
||||
.map(|h| *h)
|
||||
.ok_or(Error::Str("Block not found"))
|
||||
.ok_or(Error::NotFound("Block not found".into()))
|
||||
}
|
||||
|
||||
fn max_height(&self) -> Height {
|
||||
|
||||
@@ -24,7 +24,7 @@ impl Query {
|
||||
.saturating_sub(1),
|
||||
);
|
||||
if height > max_height {
|
||||
return Err(Error::Str("Block height out of range"));
|
||||
return Err(Error::OutOfRange("Block height out of range".into()));
|
||||
}
|
||||
|
||||
let position = computer.blks.height_to_position.read_once(height)?;
|
||||
|
||||
@@ -14,7 +14,7 @@ impl Query {
|
||||
let max_height_usize: usize = max_height.into();
|
||||
|
||||
if max_height_usize == 0 {
|
||||
return Err(Error::Str("No blocks indexed"));
|
||||
return Err(Error::NotFound("No blocks indexed".into()));
|
||||
}
|
||||
|
||||
let target = timestamp;
|
||||
|
||||
@@ -28,7 +28,7 @@ impl Query {
|
||||
|
||||
let max_height = self.height();
|
||||
if height > max_height {
|
||||
return Err(Error::Str("Block height out of range"));
|
||||
return Err(Error::OutOfRange("Block height out of range".into()));
|
||||
}
|
||||
|
||||
let first_txindex = indexer.vecs.tx.height_to_first_txindex.read_once(height)?;
|
||||
@@ -64,7 +64,7 @@ impl Query {
|
||||
|
||||
let max_height = self.height();
|
||||
if height > max_height {
|
||||
return Err(Error::Str("Block height out of range"));
|
||||
return Err(Error::OutOfRange("Block height out of range".into()));
|
||||
}
|
||||
|
||||
let first_txindex = indexer.vecs.tx.height_to_first_txindex.read_once(height)?;
|
||||
@@ -101,7 +101,7 @@ impl Query {
|
||||
|
||||
let max_height = self.height();
|
||||
if height > max_height {
|
||||
return Err(Error::Str("Block height out of range"));
|
||||
return Err(Error::OutOfRange("Block height out of range".into()));
|
||||
}
|
||||
|
||||
let first_txindex = indexer.vecs.tx.height_to_first_txindex.read_once(height)?;
|
||||
@@ -117,7 +117,7 @@ impl Query {
|
||||
let tx_count = next - first;
|
||||
|
||||
if index >= tx_count {
|
||||
return Err(Error::Str("Transaction index out of range"));
|
||||
return Err(Error::OutOfRange("Transaction index out of range".into()));
|
||||
}
|
||||
|
||||
let txindex = TxIndex::from(first + index);
|
||||
|
||||
@@ -5,12 +5,12 @@ use crate::Query;
|
||||
|
||||
impl Query {
|
||||
pub fn mempool_info(&self) -> Result<MempoolInfo> {
|
||||
let mempool = self.mempool().ok_or(Error::Str("Mempool not available"))?;
|
||||
let mempool = self.mempool().ok_or(Error::MempoolNotAvailable)?;
|
||||
Ok(mempool.get_info())
|
||||
}
|
||||
|
||||
pub fn mempool_txids(&self) -> Result<Vec<Txid>> {
|
||||
let mempool = self.mempool().ok_or(Error::Str("Mempool not available"))?;
|
||||
let mempool = self.mempool().ok_or(Error::MempoolNotAvailable)?;
|
||||
let txs = mempool.get_txs();
|
||||
Ok(txs.keys().cloned().collect())
|
||||
}
|
||||
@@ -22,7 +22,7 @@ impl Query {
|
||||
}
|
||||
|
||||
pub fn mempool_blocks(&self) -> Result<Vec<MempoolBlock>> {
|
||||
let mempool = self.mempool().ok_or(Error::Str("Mempool not available"))?;
|
||||
let mempool = self.mempool().ok_or(Error::MempoolNotAvailable)?;
|
||||
|
||||
let block_stats = mempool.get_block_stats();
|
||||
|
||||
|
||||
@@ -25,17 +25,16 @@ impl Query {
|
||||
// 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();
|
||||
return Error::String(format!(
|
||||
"'{metric}' doesn't support the requested index. Supported indexes: {}",
|
||||
index_list.join(", ")
|
||||
));
|
||||
return Error::MetricUnsupportedIndex {
|
||||
metric: metric.to_string(),
|
||||
supported: index_list.join(", "),
|
||||
};
|
||||
}
|
||||
|
||||
// Metric doesn't exist, suggest alternatives
|
||||
if let Some(first) = self.match_metric(metric, Limit::MIN).first() {
|
||||
Error::String(format!("Could not find '{metric}', did you mean '{first}'?"))
|
||||
} else {
|
||||
Error::String(format!("Could not find '{metric}'."))
|
||||
Error::MetricNotFound {
|
||||
metric: metric.to_string(),
|
||||
suggestion: self.match_metric(metric, Limit::MIN).first().map(|s| s.to_string()),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -161,7 +160,7 @@ impl Query {
|
||||
/// Returns error if no metrics requested or any requested metric is not found.
|
||||
pub fn search(&self, params: &MetricSelection) -> Result<Vec<&'static dyn AnyExportableVec>> {
|
||||
if params.metrics.is_empty() {
|
||||
return Err(Error::String("No metrics specified".to_string()));
|
||||
return Err(Error::NoMetrics);
|
||||
}
|
||||
let mut vecs = Vec::with_capacity(params.metrics.len());
|
||||
for metric in params.metrics.iter() {
|
||||
@@ -195,9 +194,10 @@ impl Query {
|
||||
|
||||
let weight = Self::weight(&vecs, params.from(), params.to_for_len(metric.len()));
|
||||
if weight > max_weight {
|
||||
return Err(Error::String(format!(
|
||||
"Request too heavy: {weight} bytes exceeds limit of {max_weight} bytes"
|
||||
)));
|
||||
return Err(Error::WeightExceeded {
|
||||
requested: weight,
|
||||
max: max_weight,
|
||||
});
|
||||
}
|
||||
|
||||
self.format(*metric, ¶ms.range)
|
||||
@@ -219,9 +219,10 @@ impl Query {
|
||||
let min_len = vecs.iter().map(|v| v.len()).min().expect("search guarantees non-empty");
|
||||
let weight = Self::weight(&vecs, params.from(), params.to_for_len(min_len));
|
||||
if weight > max_weight {
|
||||
return Err(Error::String(format!(
|
||||
"Request too heavy: {weight} bytes exceeds limit of {max_weight} bytes"
|
||||
)));
|
||||
return Err(Error::WeightExceeded {
|
||||
requested: weight,
|
||||
max: max_weight,
|
||||
});
|
||||
}
|
||||
|
||||
self.format_bulk(&vecs, ¶ms.range)
|
||||
|
||||
@@ -64,9 +64,10 @@ impl Query {
|
||||
let min_len = vecs.iter().map(|v| v.len()).min().expect("search guarantees non-empty");
|
||||
let weight = Self::weight(&vecs, params.from(), params.to_for_len(min_len));
|
||||
if weight > max_weight {
|
||||
return Err(Error::String(format!(
|
||||
"Request too heavy: {weight} bytes exceeds limit of {max_weight} bytes"
|
||||
)));
|
||||
return Err(Error::WeightExceeded {
|
||||
requested: weight,
|
||||
max: max_weight,
|
||||
});
|
||||
}
|
||||
|
||||
self.format_legacy(&vecs, ¶ms.range)
|
||||
|
||||
@@ -8,10 +8,14 @@
|
||||
#![allow(dead_code)]
|
||||
|
||||
use brk_error::Result;
|
||||
use brk_types::{BlockFeeRatesEntry, FeeRatePercentiles, TimePeriod};
|
||||
use vecdb::{IterableVec, VecIndex};
|
||||
use brk_types::{
|
||||
BlockFeeRatesEntry,
|
||||
// FeeRatePercentiles,
|
||||
TimePeriod,
|
||||
};
|
||||
// use vecdb::{IterableVec, VecIndex};
|
||||
|
||||
use super::dateindex_iter::DateIndexIter;
|
||||
// use super::dateindex_iter::DateIndexIter;
|
||||
use crate::Query;
|
||||
|
||||
impl Query {
|
||||
|
||||
@@ -98,7 +98,7 @@ impl Query {
|
||||
.pools
|
||||
.vecs
|
||||
.get(&slug)
|
||||
.ok_or_else(|| Error::Str("Pool data not found"))?;
|
||||
.ok_or_else(|| Error::NotFound("Pool data not found".into()))?;
|
||||
|
||||
let mut cumulative = pool_vecs
|
||||
.indexes_to_blocks_mined
|
||||
|
||||
@@ -213,7 +213,7 @@ impl Query {
|
||||
let buffer = reader.read_raw_bytes(position, *total_size as usize)?;
|
||||
let mut cursor = Cursor::new(buffer);
|
||||
let tx = bitcoin::Transaction::consensus_decode(&mut cursor)
|
||||
.map_err(|_| Error::Str("Failed to decode transaction"))?;
|
||||
.map_err(|_| Error::Parse("Failed to decode transaction".into()))?;
|
||||
|
||||
// For iterating through inputs, we need iterators (multiple lookups)
|
||||
let mut txindex_to_txid_iter = indexer.vecs.tx.txindex_to_txid.iter()?;
|
||||
|
||||
@@ -14,7 +14,7 @@ use std::{
|
||||
|
||||
use bitcoin::{block::Header, consensus::Decodable};
|
||||
use blk_index_to_blk_path::*;
|
||||
use brk_error::Result;
|
||||
use brk_error::{Error, Result};
|
||||
use brk_rpc::Client;
|
||||
use brk_types::{BlkMetadata, BlkPosition, BlockHash, Height, ReadBlock};
|
||||
pub use crossbeam::channel::Receiver;
|
||||
@@ -88,7 +88,7 @@ impl ReaderInner {
|
||||
let blk_paths = self.blk_index_to_blk_path();
|
||||
let blk_path = blk_paths
|
||||
.get(&position.blk_index())
|
||||
.ok_or("Blk file not found")?;
|
||||
.ok_or(Error::NotFound("Blk file not found".into()))?;
|
||||
|
||||
let mut file = File::open(blk_path)?;
|
||||
file.seek(SeekFrom::Start(position.offset() as u64))?;
|
||||
@@ -361,7 +361,7 @@ impl ReaderInner {
|
||||
|
||||
loop {
|
||||
if file.read_exact(&mut byte_buffer).is_err() {
|
||||
return Err("No magic bytes found".into());
|
||||
return Err(Error::NotFound("No magic bytes found".into()));
|
||||
}
|
||||
|
||||
current_4bytes.rotate_left(1);
|
||||
|
||||
@@ -8,7 +8,7 @@ use bitcoincore_rpc::{
|
||||
json::{GetBlockHeaderResult, GetBlockResult, GetBlockchainInfoResult, GetTxOutResult},
|
||||
{Client as CoreClient, Error as RpcError, RpcApi},
|
||||
};
|
||||
use brk_error::Result;
|
||||
use brk_error::{Error, Result};
|
||||
use brk_types::{
|
||||
BlockHash, Height, MempoolEntryInfo, Sats, Transaction, TxIn, TxOut, TxStatus, TxWithHex, Txid,
|
||||
Vout,
|
||||
@@ -262,7 +262,7 @@ impl Client {
|
||||
let mut hash = block_info
|
||||
.previous_block_hash
|
||||
.map(BlockHash::from)
|
||||
.ok_or("Genesis block has no previous block")?;
|
||||
.ok_or(Error::NotFound("Genesis block has no previous block".into()))?;
|
||||
|
||||
loop {
|
||||
if self.is_in_main_chain(&hash)? {
|
||||
@@ -274,10 +274,10 @@ impl Client {
|
||||
hash = info
|
||||
.previous_block_hash
|
||||
.map(BlockHash::from)
|
||||
.ok_or("Reached genesis without finding main chain")?;
|
||||
.ok_or(Error::NotFound("Reached genesis without finding main chain".into()))?;
|
||||
}
|
||||
}
|
||||
Err(_) => Err("Block hash not found in blockchain".into()),
|
||||
Err(_) => Err(Error::NotFound("Block hash not found in blockchain".into())),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -179,7 +179,7 @@ impl TryFrom<&str> for Index {
|
||||
v if (Self::EmptyAddressIndex).possible_values().contains(&v) => {
|
||||
Self::EmptyAddressIndex
|
||||
}
|
||||
_ => return Err(Error::Str("Bad index")),
|
||||
_ => return Err(Error::Parse(format!("Invalid index: {value}"))),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ impl LoadedAddressData {
|
||||
|
||||
pub fn send(&mut self, amount: Sats, previous_price: Option<Dollars>) -> Result<()> {
|
||||
if self.balance() < amount {
|
||||
return Err(Error::Str("Previous_amount smaller than sent amount"));
|
||||
return Err(Error::Internal("Previous amount smaller than sent amount"));
|
||||
}
|
||||
self.sent += amount;
|
||||
self.spent_txo_count += 1;
|
||||
|
||||
@@ -907,7 +907,7 @@ impl TryFrom<OutputType> for AddressType {
|
||||
OutputType::P2TR => Self::P2tr,
|
||||
OutputType::P2WPKH => Self::P2wpkh,
|
||||
OutputType::P2WSH => Self::P2wsh,
|
||||
_ => return Err(Error::Str("Bad output format")),
|
||||
_ => return Err(Error::UnsupportedType(format!("{:?}", value))),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user