mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-05-29 23:19:28 -07:00
lazy: done
This commit is contained in:
44
Cargo.lock
generated
44
Cargo.lock
generated
@@ -235,9 +235,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "backtrace"
|
||||
version = "0.3.74"
|
||||
version = "0.3.75"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a"
|
||||
checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002"
|
||||
dependencies = [
|
||||
"addr2line",
|
||||
"cfg-if",
|
||||
@@ -590,9 +590,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "brotli"
|
||||
version = "8.0.0"
|
||||
version = "8.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf19e729cdbd51af9a397fb9ef8ac8378007b797f8273cfbfdf45dcaa316167b"
|
||||
checksum = "9991eea70ea4f293524138648e41ee89b0b2b12ddef3b255effa43c8056e0e0d"
|
||||
dependencies = [
|
||||
"alloc-no-stdlib",
|
||||
"alloc-stdlib",
|
||||
@@ -837,9 +837,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "crc"
|
||||
version = "3.2.1"
|
||||
version = "3.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "69e6e4d7b33a94f0991c26729976b10ebde1d34c3ee82408fb536164fa10d636"
|
||||
checksum = "9710d3b3739c2e349eb44fe848ad0b7c8cb1e42bd87ee49371df2f7acaf3e675"
|
||||
dependencies = [
|
||||
"crc-catalog",
|
||||
]
|
||||
@@ -1103,7 +1103,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "976dd42dc7e85965fe702eb8164f21f450704bdde31faefd6471dba214cb594e"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys 0.52.0",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1501,9 +1501,9 @@ checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
|
||||
|
||||
[[package]]
|
||||
name = "jiff"
|
||||
version = "0.2.12"
|
||||
version = "0.2.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d07d8d955d798e7a4d6f9c58cd1f1916e790b42b092758a9ef6e16fef9f1b3fd"
|
||||
checksum = "f02000660d30638906021176af16b17498bd0d12813dbfe7b276d8bc7f3c0806"
|
||||
dependencies = [
|
||||
"jiff-static",
|
||||
"jiff-tzdb-platform",
|
||||
@@ -1511,14 +1511,14 @@ dependencies = [
|
||||
"portable-atomic",
|
||||
"portable-atomic-util",
|
||||
"serde",
|
||||
"windows-sys 0.52.0",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jiff-static"
|
||||
version = "0.2.12"
|
||||
version = "0.2.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f244cfe006d98d26f859c7abd1318d85327e1882dc9cef80f62daeeb0adcf300"
|
||||
checksum = "f3c30758ddd7188629c6713fc45d1188af4f44c90582311d0c8d8c9907f60c48"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -2422,9 +2422,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.5.11"
|
||||
version = "0.5.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2f103c6d277498fbceb16e84d317e2a400f160f46904d5f5410848c829511a3"
|
||||
checksum = "928fca9cf2aa042393a8325b9ead81d2f0df4cb12e1e24cef072922ccd99c5af"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
@@ -2503,7 +2503,7 @@ dependencies = [
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
"windows-sys 0.52.0",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2858,7 +2858,7 @@ dependencies = [
|
||||
"getrandom 0.3.2",
|
||||
"once_cell",
|
||||
"rustix",
|
||||
"windows-sys 0.52.0",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2944,9 +2944,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.44.2"
|
||||
version = "1.45.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6b88822cbe49de4185e3a4cbf8321dd487cf5fe0c5c65695fef6346371e9c48"
|
||||
checksum = "2513ca694ef9ede0fb23fe71a4ee4107cb102b9dc1930f6d0fd77aae068ae165"
|
||||
dependencies = [
|
||||
"backtrace",
|
||||
"bytes",
|
||||
@@ -3043,9 +3043,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tower-http"
|
||||
version = "0.6.2"
|
||||
version = "0.6.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "403fa3b783d4b626a8ad51d766ab03cb6d2dbfc46b1c5d4448395e6628dc9697"
|
||||
checksum = "a1cfca9ae570b2a6efc764a88e914c29b3dfaa1fafe5f495812ae97ec9bc4d53"
|
||||
dependencies = [
|
||||
"async-compression",
|
||||
"bitflags",
|
||||
@@ -3432,9 +3432,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
||||
|
||||
[[package]]
|
||||
name = "winnow"
|
||||
version = "0.7.9"
|
||||
version = "0.7.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d9fb597c990f03753e08d3c29efbfcf2019a003b4bf4ba19225c158e1549f0f3"
|
||||
checksum = "c06928c8748d81b05c9be96aad92e1b6ff01833332f281e8cfca3be4b35fc9ec"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
@@ -36,7 +36,7 @@ clap_derive = "4.5.32"
|
||||
color-eyre = "0.6.4"
|
||||
derive_deref = "1.1.1"
|
||||
fjall = "2.10.0"
|
||||
jiff = "0.2.12"
|
||||
jiff = "0.2.13"
|
||||
log = { version = "0.4.27" }
|
||||
minreq = { version = "2.13.4", features = ["https", "serde_json"] }
|
||||
rayon = "1.10.0"
|
||||
|
||||
@@ -83,6 +83,7 @@ where
|
||||
})
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
pub fn compute_all<F>(
|
||||
&mut self,
|
||||
indexer: &Indexer,
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
use std::path::Path;
|
||||
|
||||
use brk_core::{Bitcoin, Dollars, Sats, TxIndex};
|
||||
use brk_core::{Bitcoin, Close, Dollars, Height, Sats, TxIndex};
|
||||
use brk_exit::Exit;
|
||||
use brk_indexer::Indexer;
|
||||
use brk_vec::{
|
||||
AnyCollectableVec, CollectableVec, Compressed, EagerVec, Result, StoredVec, Version,
|
||||
AnyCollectableVec, BoxedAnyIterableVec, CloneableAnyIterableVec, CollectableVec, Compressed,
|
||||
Computation, ComputedVecFrom3, LazyVecFrom1, StoredIndex, StoredVec, Version,
|
||||
};
|
||||
|
||||
use crate::storage::{
|
||||
@@ -17,44 +18,113 @@ use super::{ComputedVecsFromTxindex, StorableVecGeneatorOptions};
|
||||
#[derive(Clone)]
|
||||
pub struct ComputedValueVecsFromTxindex {
|
||||
pub sats: ComputedVecsFromTxindex<Sats>,
|
||||
pub bitcoin_txindex: LazyVecFrom1<TxIndex, Bitcoin, TxIndex, Sats>,
|
||||
pub bitcoin: ComputedVecsFromTxindex<Bitcoin>,
|
||||
#[allow(clippy::type_complexity)]
|
||||
pub dollars_txindex: Option<
|
||||
ComputedVecFrom3<
|
||||
TxIndex,
|
||||
Dollars,
|
||||
TxIndex,
|
||||
Bitcoin,
|
||||
TxIndex,
|
||||
Height,
|
||||
Height,
|
||||
Close<Dollars>,
|
||||
>,
|
||||
>,
|
||||
pub dollars: Option<ComputedVecsFromTxindex<Dollars>>,
|
||||
}
|
||||
|
||||
const VERSION: Version = Version::ONE;
|
||||
|
||||
impl ComputedValueVecsFromTxindex {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn forced_import(
|
||||
path: &Path,
|
||||
name: &str,
|
||||
compute_source: bool,
|
||||
indexes: &indexes::Vecs,
|
||||
source: Option<BoxedAnyIterableVec<TxIndex, Sats>>,
|
||||
version: Version,
|
||||
computation: Computation,
|
||||
compressed: Compressed,
|
||||
marketprices: Option<&marketprice::Vecs>,
|
||||
options: StorableVecGeneatorOptions,
|
||||
compute_dollars: bool,
|
||||
) -> color_eyre::Result<Self> {
|
||||
let compute_source = source.is_none();
|
||||
let compute_dollars = marketprices.is_some();
|
||||
|
||||
let sats = ComputedVecsFromTxindex::forced_import(
|
||||
path,
|
||||
name,
|
||||
compute_source,
|
||||
VERSION + version,
|
||||
compressed,
|
||||
options,
|
||||
)?;
|
||||
|
||||
let bitcoin_txindex = LazyVecFrom1::init(
|
||||
"txindex_to_{name}_in_btc",
|
||||
VERSION + version,
|
||||
source.map_or_else(|| sats.txindex.as_ref().unwrap().boxed_clone(), |s| s),
|
||||
|txindex: TxIndex, iter| {
|
||||
iter.next_at(txindex.unwrap_to_usize()).map(|(_, value)| {
|
||||
let sats = value.into_inner();
|
||||
Bitcoin::from(sats)
|
||||
})
|
||||
},
|
||||
);
|
||||
|
||||
let bitcoin = ComputedVecsFromTxindex::forced_import(
|
||||
path,
|
||||
&format!("{name}_in_btc"),
|
||||
false,
|
||||
VERSION + version,
|
||||
compressed,
|
||||
options,
|
||||
)?;
|
||||
|
||||
let dollars_txindex = marketprices.map(|marketprices| {
|
||||
ComputedVecFrom3::forced_import_or_init_from_3(
|
||||
computation,
|
||||
path,
|
||||
"txindex_to_{name}_in_usd",
|
||||
VERSION + version,
|
||||
compressed,
|
||||
bitcoin_txindex.boxed_clone(),
|
||||
indexes.txindex_to_height.boxed_clone(),
|
||||
marketprices.chainindexes_to_close.height.boxed_clone(),
|
||||
|txindex: TxIndex,
|
||||
txindex_to_btc_iter,
|
||||
txindex_to_height_iter,
|
||||
height_to_close_iter| {
|
||||
let txindex = txindex.unwrap_to_usize();
|
||||
txindex_to_btc_iter.next_at(txindex).and_then(|(_, value)| {
|
||||
let btc = value.into_inner();
|
||||
txindex_to_height_iter
|
||||
.next_at(txindex)
|
||||
.and_then(|(_, value)| {
|
||||
let height = value.into_inner();
|
||||
height_to_close_iter
|
||||
.next_at(height.unwrap_to_usize())
|
||||
.map(|(_, close)| *close.into_inner() * btc)
|
||||
})
|
||||
})
|
||||
},
|
||||
)
|
||||
.unwrap()
|
||||
});
|
||||
|
||||
Ok(Self {
|
||||
sats: ComputedVecsFromTxindex::forced_import(
|
||||
path,
|
||||
name,
|
||||
compute_source,
|
||||
VERSION + version,
|
||||
compressed,
|
||||
options,
|
||||
)?,
|
||||
bitcoin: ComputedVecsFromTxindex::forced_import(
|
||||
path,
|
||||
&format!("{name}_in_btc"),
|
||||
true,
|
||||
VERSION + version,
|
||||
compressed,
|
||||
options,
|
||||
)?,
|
||||
sats,
|
||||
bitcoin_txindex,
|
||||
bitcoin,
|
||||
dollars_txindex,
|
||||
dollars: compute_dollars.then(|| {
|
||||
ComputedVecsFromTxindex::forced_import(
|
||||
path,
|
||||
&format!("{name}_in_usd"),
|
||||
true,
|
||||
false,
|
||||
VERSION + version,
|
||||
compressed,
|
||||
options,
|
||||
@@ -64,50 +134,49 @@ impl ComputedValueVecsFromTxindex {
|
||||
})
|
||||
}
|
||||
|
||||
pub fn compute_all<F>(
|
||||
&mut self,
|
||||
indexer: &Indexer,
|
||||
indexes: &indexes::Vecs,
|
||||
marketprices: Option<&marketprice::Vecs>,
|
||||
starting_indexes: &Indexes,
|
||||
exit: &Exit,
|
||||
mut compute: F,
|
||||
) -> color_eyre::Result<()>
|
||||
where
|
||||
F: FnMut(
|
||||
&mut EagerVec<TxIndex, Sats>,
|
||||
&Indexer,
|
||||
&indexes::Vecs,
|
||||
&Indexes,
|
||||
&Exit,
|
||||
) -> Result<()>,
|
||||
{
|
||||
compute(
|
||||
self.sats.txindex.as_mut().unwrap(),
|
||||
indexer,
|
||||
indexes,
|
||||
starting_indexes,
|
||||
exit,
|
||||
)?;
|
||||
// pub fn compute_all<F>(
|
||||
// &mut self,
|
||||
// indexer: &Indexer,
|
||||
// indexes: &indexes::Vecs,
|
||||
// marketprices: Option<&marketprice::Vecs>,
|
||||
// starting_indexes: &Indexes,
|
||||
// exit: &Exit,
|
||||
// mut compute: F,
|
||||
// ) -> color_eyre::Result<()>
|
||||
// where
|
||||
// F: FnMut(
|
||||
// &mut EagerVec<TxIndex, Sats>,
|
||||
// &Indexer,
|
||||
// &indexes::Vecs,
|
||||
// &Indexes,
|
||||
// &Exit,
|
||||
// ) -> Result<()>,
|
||||
// {
|
||||
// compute(
|
||||
// self.sats.txindex.as_mut().unwrap(),
|
||||
// indexer,
|
||||
// indexes,
|
||||
// starting_indexes,
|
||||
// exit,
|
||||
// )?;
|
||||
|
||||
let txindex: Option<&StoredVec<TxIndex, Sats>> = None;
|
||||
self.compute_rest(
|
||||
indexer,
|
||||
indexes,
|
||||
marketprices,
|
||||
starting_indexes,
|
||||
exit,
|
||||
txindex,
|
||||
)?;
|
||||
// let txindex: Option<&StoredVec<TxIndex, Sats>> = None;
|
||||
// self.compute_rest(
|
||||
// indexer,
|
||||
// indexes,
|
||||
// marketprices,
|
||||
// starting_indexes,
|
||||
// exit,
|
||||
// txindex,
|
||||
// )?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
// Ok(())
|
||||
// }
|
||||
|
||||
pub fn compute_rest(
|
||||
&mut self,
|
||||
indexer: &Indexer,
|
||||
indexes: &indexes::Vecs,
|
||||
marketprices: Option<&marketprice::Vecs>,
|
||||
starting_indexes: &Indexes,
|
||||
exit: &Exit,
|
||||
txindex: Option<&impl CollectableVec<TxIndex, Sats>>,
|
||||
@@ -115,55 +184,31 @@ impl ComputedValueVecsFromTxindex {
|
||||
if let Some(txindex) = txindex {
|
||||
self.sats
|
||||
.compute_rest(indexer, indexes, starting_indexes, exit, Some(txindex))?;
|
||||
|
||||
self.bitcoin.compute_all(
|
||||
indexer,
|
||||
indexes,
|
||||
starting_indexes,
|
||||
exit,
|
||||
|v, _, _, starting_indexes, exit| {
|
||||
v.compute_from_sats(starting_indexes.txindex, txindex, exit)
|
||||
},
|
||||
)?;
|
||||
} else {
|
||||
let txindex: Option<&StoredVec<TxIndex, Sats>> = None;
|
||||
self.sats
|
||||
.compute_rest(indexer, indexes, starting_indexes, exit, txindex)?;
|
||||
|
||||
self.bitcoin.compute_all(
|
||||
indexer,
|
||||
indexes,
|
||||
starting_indexes,
|
||||
exit,
|
||||
|v, _, _, starting_indexes, exit| {
|
||||
v.compute_from_sats(
|
||||
starting_indexes.txindex,
|
||||
self.sats.txindex.as_ref().unwrap(),
|
||||
exit,
|
||||
)
|
||||
},
|
||||
)?;
|
||||
}
|
||||
|
||||
let txindex = self.bitcoin.txindex.as_mut().unwrap();
|
||||
self.bitcoin.compute_rest(
|
||||
indexer,
|
||||
indexes,
|
||||
starting_indexes,
|
||||
exit,
|
||||
Some(&self.bitcoin_txindex),
|
||||
)?;
|
||||
|
||||
if let Some(dollars) = self.dollars.as_mut() {
|
||||
let price = &marketprices.unwrap().chainindexes_to_close.height;
|
||||
let dollars_txindex = self.dollars_txindex.as_mut().unwrap();
|
||||
|
||||
dollars.compute_all(
|
||||
dollars_txindex.compute_if_necessary(starting_indexes.txindex, exit)?;
|
||||
|
||||
dollars.compute_rest(
|
||||
indexer,
|
||||
indexes,
|
||||
starting_indexes,
|
||||
exit,
|
||||
|v, _, indexes, starting_indexes, exit| {
|
||||
v.compute_from_bitcoin(
|
||||
starting_indexes.txindex,
|
||||
txindex,
|
||||
&indexes.txindex_to_height,
|
||||
price,
|
||||
exit,
|
||||
)
|
||||
},
|
||||
Some(dollars_txindex),
|
||||
)?;
|
||||
}
|
||||
|
||||
|
||||
@@ -33,19 +33,24 @@ impl Vecs {
|
||||
) -> color_eyre::Result<Self> {
|
||||
fs::create_dir_all(path)?;
|
||||
|
||||
let indexes = indexes::Vecs::forced_import(path, indexer, computation, compressed)?;
|
||||
|
||||
let marketprice =
|
||||
fetch.then(|| marketprice::Vecs::forced_import(path, computation, compressed).unwrap());
|
||||
|
||||
Ok(Self {
|
||||
blocks: blocks::Vecs::forced_import(path, computation, compressed)?,
|
||||
indexes: indexes::Vecs::forced_import(path, indexer, computation, compressed)?,
|
||||
mining: mining::Vecs::forced_import(path, computation, compressed)?,
|
||||
transactions: transactions::Vecs::forced_import(
|
||||
path,
|
||||
indexer,
|
||||
&indexes,
|
||||
computation,
|
||||
compressed,
|
||||
fetch,
|
||||
marketprice.as_ref(),
|
||||
)?,
|
||||
marketprice: fetch
|
||||
.then(|| marketprice::Vecs::forced_import(path, computation, compressed).unwrap()),
|
||||
indexes,
|
||||
marketprice,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
use std::{fs, path::Path};
|
||||
|
||||
use brk_core::{
|
||||
CheckedSub, Feerate, InputIndex, OutputIndex, Sats, StoredUsize, TxIndex, TxVersion, Weight,
|
||||
CheckedSub, Feerate, Height, InputIndex, OutputIndex, Sats, StoredU32, StoredUsize, TxIndex,
|
||||
TxVersion, Weight,
|
||||
};
|
||||
use brk_exit::Exit;
|
||||
use brk_indexer::Indexer;
|
||||
use brk_parser::bitcoin;
|
||||
use brk_vec::{
|
||||
AnyCollectableVec, AnyIterableVec, CloneableAnyIterableVec, Compressed, Computation,
|
||||
ComputedVec, ComputedVecFrom2, EagerVec, StoredIndex, Version,
|
||||
ComputedVec, ComputedVecFrom1, ComputedVecFrom2, ComputedVecFrom3, StoredIndex, Version,
|
||||
};
|
||||
|
||||
use super::{
|
||||
@@ -30,9 +31,29 @@ pub struct Vecs {
|
||||
pub indexes_to_fee: ComputedValueVecsFromTxindex,
|
||||
pub indexes_to_feerate: ComputedVecsFromTxindex<Feerate>,
|
||||
/// Value == 0 when Coinbase
|
||||
pub indexes_to_input_value: ComputedVecsFromTxindex<Sats>,
|
||||
pub txindex_to_input_value: ComputedVecFrom3<
|
||||
TxIndex,
|
||||
Sats,
|
||||
TxIndex,
|
||||
InputIndex,
|
||||
TxIndex,
|
||||
StoredUsize,
|
||||
InputIndex,
|
||||
Sats,
|
||||
>,
|
||||
// pub indexes_to_input_value: ComputedVecsFromTxindex<Sats>,
|
||||
pub indexes_to_opreturn_count: ComputedVecsFromHeight<StoredUsize>,
|
||||
pub indexes_to_output_value: ComputedVecsFromTxindex<Sats>,
|
||||
pub txindex_to_output_value: ComputedVecFrom3<
|
||||
TxIndex,
|
||||
Sats,
|
||||
TxIndex,
|
||||
OutputIndex,
|
||||
TxIndex,
|
||||
StoredUsize,
|
||||
OutputIndex,
|
||||
Sats,
|
||||
>,
|
||||
// pub indexes_to_output_value: ComputedVecsFromTxindex<Sats>,
|
||||
pub indexes_to_p2a_count: ComputedVecsFromHeight<StoredUsize>,
|
||||
pub indexes_to_p2ms_count: ComputedVecsFromHeight<StoredUsize>,
|
||||
pub indexes_to_p2pk33_count: ComputedVecsFromHeight<StoredUsize>,
|
||||
@@ -51,25 +72,317 @@ pub struct Vecs {
|
||||
pub indexes_to_tx_weight: ComputedVecsFromTxindex<Weight>,
|
||||
pub indexes_to_unknownoutput_count: ComputedVecsFromHeight<StoredUsize>,
|
||||
pub inputindex_to_value:
|
||||
ComputedVecFrom2<InputIndex, Sats, OutputIndex, Sats, InputIndex, OutputIndex>,
|
||||
// Bitcoin and dollar version too
|
||||
ComputedVecFrom2<InputIndex, Sats, InputIndex, OutputIndex, OutputIndex, Sats>,
|
||||
pub txindex_to_input_count:
|
||||
ComputedVecFrom2<TxIndex, StoredUsize, TxIndex, InputIndex, InputIndex, OutputIndex>,
|
||||
pub indexes_to_input_count: ComputedVecsFromTxindex<StoredUsize>,
|
||||
pub txindex_to_is_coinbase: EagerVec<TxIndex, bool>,
|
||||
pub txindex_to_is_coinbase: ComputedVecFrom2<TxIndex, bool, TxIndex, Height, Height, TxIndex>,
|
||||
pub txindex_to_output_count:
|
||||
ComputedVecFrom2<TxIndex, StoredUsize, TxIndex, OutputIndex, OutputIndex, Sats>,
|
||||
pub indexes_to_output_count: ComputedVecsFromTxindex<StoredUsize>,
|
||||
pub txindex_to_vsize: EagerVec<TxIndex, StoredUsize>,
|
||||
pub txindex_to_weight: EagerVec<TxIndex, Weight>,
|
||||
pub txindex_to_vsize: ComputedVecFrom1<TxIndex, StoredUsize, TxIndex, Weight>,
|
||||
pub txindex_to_weight:
|
||||
ComputedVecFrom2<TxIndex, Weight, TxIndex, StoredU32, TxIndex, StoredU32>,
|
||||
pub txindex_to_fee: ComputedVecFrom2<TxIndex, Sats, TxIndex, Sats, TxIndex, Sats>,
|
||||
pub txindex_to_feerate: ComputedVecFrom2<TxIndex, Feerate, TxIndex, Sats, TxIndex, StoredUsize>,
|
||||
}
|
||||
|
||||
impl Vecs {
|
||||
pub fn forced_import(
|
||||
path: &Path,
|
||||
indexer: &Indexer,
|
||||
indexes: &indexes::Vecs,
|
||||
computation: Computation,
|
||||
compressed: Compressed,
|
||||
compute_dollars: bool,
|
||||
marketprices: Option<&marketprice::Vecs>,
|
||||
) -> color_eyre::Result<Self> {
|
||||
let compute_dollars = marketprices.is_some();
|
||||
|
||||
fs::create_dir_all(path)?;
|
||||
|
||||
let inputindex_to_value = ComputedVec::forced_import_or_init_from_2(
|
||||
computation,
|
||||
path,
|
||||
"inputindex_to_value",
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
indexer.vecs().inputindex_to_outputindex.boxed_clone(),
|
||||
indexer.vecs().outputindex_to_value.boxed_clone(),
|
||||
|index: InputIndex, inputindex_to_outputindex_iter, outputindex_to_value_iter| {
|
||||
inputindex_to_outputindex_iter
|
||||
.next_at(index.unwrap_to_usize())
|
||||
.map(|(inputindex, outputindex)| {
|
||||
let outputindex = outputindex.into_inner();
|
||||
if outputindex == OutputIndex::COINBASE {
|
||||
Sats::ZERO
|
||||
} else if let Some((_, value)) =
|
||||
outputindex_to_value_iter.next_at(outputindex.unwrap_to_usize())
|
||||
{
|
||||
value.into_inner()
|
||||
} else {
|
||||
dbg!(inputindex, outputindex);
|
||||
panic!()
|
||||
}
|
||||
})
|
||||
},
|
||||
)?;
|
||||
|
||||
let txindex_to_weight = ComputedVec::forced_import_or_init_from_2(
|
||||
computation,
|
||||
path,
|
||||
"txindex_to_weight",
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
indexer.vecs().txindex_to_base_size.boxed_clone(),
|
||||
indexer.vecs().txindex_to_total_size.boxed_clone(),
|
||||
|index: TxIndex, txindex_to_base_size_iter, txindex_to_total_size_iter| {
|
||||
let index = index.unwrap_to_usize();
|
||||
txindex_to_base_size_iter
|
||||
.next_at(index)
|
||||
.map(|(_, base_size)| {
|
||||
let base_size = base_size.into_inner();
|
||||
let total_size = txindex_to_total_size_iter
|
||||
.next_at(index)
|
||||
.unwrap()
|
||||
.1
|
||||
.into_inner();
|
||||
|
||||
// This is the exact definition of a weight unit, as defined by BIP-141 (quote above).
|
||||
let wu = usize::from(base_size) * 3 + usize::from(total_size);
|
||||
|
||||
Weight::from(bitcoin::Weight::from_wu_usize(wu))
|
||||
})
|
||||
},
|
||||
)?;
|
||||
|
||||
let txindex_to_vsize = ComputedVec::forced_import_or_init_from_1(
|
||||
computation,
|
||||
path,
|
||||
"txindex_to_vsize",
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
txindex_to_weight.boxed_clone(),
|
||||
|index: TxIndex, iter| {
|
||||
let index = index.unwrap_to_usize();
|
||||
iter.next_at(index).map(|(_, weight)| {
|
||||
StoredUsize::from(
|
||||
bitcoin::Weight::from(weight.into_inner()).to_vbytes_ceil() as usize
|
||||
)
|
||||
})
|
||||
},
|
||||
)?;
|
||||
|
||||
let txindex_to_is_coinbase = ComputedVec::forced_import_or_init_from_2(
|
||||
computation,
|
||||
path,
|
||||
"txindex_to_is_coinbase",
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
indexes.txindex_to_height.boxed_clone(),
|
||||
indexer.vecs().height_to_first_txindex.boxed_clone(),
|
||||
|index: TxIndex, txindex_to_height_iter, height_to_first_txindex_iter| {
|
||||
txindex_to_height_iter
|
||||
.next_at(index.unwrap_to_usize())
|
||||
.map(|(_, height)| {
|
||||
let height = height.into_inner();
|
||||
let txindex = height_to_first_txindex_iter
|
||||
.next_at(height.unwrap_to_usize())
|
||||
.unwrap()
|
||||
.1
|
||||
.into_inner();
|
||||
|
||||
index == txindex
|
||||
})
|
||||
},
|
||||
)?;
|
||||
|
||||
let txindex_to_input_count = ComputedVec::forced_import_or_init_from_2(
|
||||
computation,
|
||||
path,
|
||||
"txindex_to_input_count",
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
indexer.vecs().txindex_to_first_inputindex.boxed_clone(),
|
||||
indexer.vecs().inputindex_to_outputindex.boxed_clone(),
|
||||
|index: TxIndex, txindex_to_first_inputindex_iter, inputindex_to_outputindex_iter| {
|
||||
let txindex = index.unwrap_to_usize();
|
||||
txindex_to_first_inputindex_iter
|
||||
.next_at(txindex)
|
||||
.map(|(_, start)| {
|
||||
let start = usize::from(start.into_inner());
|
||||
let end = txindex_to_first_inputindex_iter
|
||||
.next_at(txindex + 1)
|
||||
.map(|(_, v)| usize::from(v.into_inner()))
|
||||
.unwrap_or_else(|| inputindex_to_outputindex_iter.len());
|
||||
StoredUsize::from((start..end).count())
|
||||
})
|
||||
},
|
||||
)?;
|
||||
|
||||
let txindex_to_input_value = ComputedVec::forced_import_or_init_from_3(
|
||||
computation,
|
||||
path,
|
||||
"txindex_to_input_value",
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
indexer.vecs().txindex_to_first_inputindex.boxed_clone(),
|
||||
txindex_to_input_count.boxed_clone(),
|
||||
inputindex_to_value.boxed_clone(),
|
||||
|index: TxIndex,
|
||||
txindex_to_first_inputindex_iter,
|
||||
txindex_to_input_count_iter,
|
||||
inputindex_to_value_iter| {
|
||||
let txindex = index.unwrap_to_usize();
|
||||
txindex_to_first_inputindex_iter
|
||||
.next_at(txindex)
|
||||
.map(|(_, first_index)| {
|
||||
let first_index = usize::from(first_index.into_inner());
|
||||
let count = *txindex_to_input_count_iter
|
||||
.next_at(txindex)
|
||||
.unwrap()
|
||||
.1
|
||||
.into_inner();
|
||||
let range = first_index..first_index + count;
|
||||
range.into_iter().fold(Sats::ZERO, |total, inputindex| {
|
||||
total
|
||||
+ inputindex_to_value_iter
|
||||
.next_at(inputindex)
|
||||
.unwrap()
|
||||
.1
|
||||
.into_inner()
|
||||
})
|
||||
})
|
||||
},
|
||||
)?;
|
||||
|
||||
// let indexes_to_input_value: ComputedVecsFromTxindex<Sats> =
|
||||
// ComputedVecsFromTxindex::forced_import(
|
||||
// path,
|
||||
// "input_value",
|
||||
// true,
|
||||
// Version::ZERO,
|
||||
// compressed,
|
||||
// StorableVecGeneatorOptions::default()
|
||||
// .add_average()
|
||||
// .add_sum()
|
||||
// .add_total(),
|
||||
// )?;
|
||||
|
||||
let txindex_to_output_count = ComputedVec::forced_import_or_init_from_2(
|
||||
computation,
|
||||
path,
|
||||
"txindex_to_output_count",
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
indexer.vecs().txindex_to_first_outputindex.boxed_clone(),
|
||||
indexer.vecs().outputindex_to_value.boxed_clone(),
|
||||
|index: TxIndex, txindex_to_first_outputindex_iter, outputindex_to_value_iter| {
|
||||
let txindex = index.unwrap_to_usize();
|
||||
txindex_to_first_outputindex_iter
|
||||
.next_at(txindex)
|
||||
.map(|(_, start)| {
|
||||
let start = usize::from(start.into_inner());
|
||||
let end = txindex_to_first_outputindex_iter
|
||||
.next_at(txindex + 1)
|
||||
.map(|(_, v)| usize::from(v.into_inner()))
|
||||
.unwrap_or_else(|| outputindex_to_value_iter.len());
|
||||
StoredUsize::from((start..end).count())
|
||||
})
|
||||
},
|
||||
)?;
|
||||
|
||||
let txindex_to_output_value = ComputedVec::forced_import_or_init_from_3(
|
||||
computation,
|
||||
path,
|
||||
"txindex_to_output_value",
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
indexer.vecs().txindex_to_first_outputindex.boxed_clone(),
|
||||
txindex_to_output_count.boxed_clone(),
|
||||
indexer.vecs().outputindex_to_value.boxed_clone(),
|
||||
|index: TxIndex,
|
||||
txindex_to_first_outputindex_iter,
|
||||
txindex_to_output_count_iter,
|
||||
outputindex_to_value_iter| {
|
||||
let txindex = index.unwrap_to_usize();
|
||||
txindex_to_first_outputindex_iter
|
||||
.next_at(txindex)
|
||||
.map(|(_, first_index)| {
|
||||
let first_index = usize::from(first_index.into_inner());
|
||||
let count = *txindex_to_output_count_iter
|
||||
.next_at(txindex)
|
||||
.unwrap()
|
||||
.1
|
||||
.into_inner();
|
||||
let range = first_index..first_index + count;
|
||||
range.into_iter().fold(Sats::ZERO, |total, outputindex| {
|
||||
total
|
||||
+ outputindex_to_value_iter
|
||||
.next_at(outputindex)
|
||||
.unwrap()
|
||||
.1
|
||||
.into_inner()
|
||||
})
|
||||
})
|
||||
},
|
||||
)?;
|
||||
|
||||
// let indexes_to_output_value: ComputedVecsFromTxindex<Sats> =
|
||||
// ComputedVecsFromTxindex::forced_import(
|
||||
// path,
|
||||
// "output_value",
|
||||
// true,
|
||||
// Version::ZERO,
|
||||
// compressed,
|
||||
// StorableVecGeneatorOptions::default()
|
||||
// .add_average()
|
||||
// .add_sum()
|
||||
// .add_total(),
|
||||
// )?;
|
||||
|
||||
let txindex_to_fee = ComputedVecFrom2::forced_import_or_init_from_2(
|
||||
computation,
|
||||
path,
|
||||
"txindex_to_fee",
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
txindex_to_input_value.boxed_clone(),
|
||||
txindex_to_output_value.boxed_clone(),
|
||||
|txindex: TxIndex, input_iter, output_iter| {
|
||||
let txindex = txindex.unwrap_to_usize();
|
||||
input_iter.next_at(txindex).and_then(|(_, value)| {
|
||||
let input = value.into_inner();
|
||||
if input.is_zero() {
|
||||
return Some(Sats::ZERO);
|
||||
}
|
||||
output_iter.next_at(txindex).map(|(_, value)| {
|
||||
let output = value.into_inner();
|
||||
input.checked_sub(output).unwrap()
|
||||
})
|
||||
})
|
||||
},
|
||||
)?;
|
||||
|
||||
let txindex_to_feerate = ComputedVecFrom2::forced_import_or_init_from_2(
|
||||
computation,
|
||||
path,
|
||||
"txindex_to_feerate",
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
txindex_to_fee.boxed_clone(),
|
||||
txindex_to_vsize.boxed_clone(),
|
||||
|txindex: TxIndex, fee_iter, vsize_iter| {
|
||||
let txindex = txindex.unwrap_to_usize();
|
||||
fee_iter.next_at(txindex).and_then(|(_, value)| {
|
||||
let fee = value.into_inner();
|
||||
vsize_iter.next_at(txindex).map(|(_, value)| {
|
||||
let vsize = value.into_inner();
|
||||
Feerate::from((fee, vsize))
|
||||
})
|
||||
})
|
||||
},
|
||||
)?;
|
||||
|
||||
Ok(Self {
|
||||
indexes_to_tx_count: ComputedVecsFromHeight::forced_import(
|
||||
path,
|
||||
@@ -84,15 +397,10 @@ impl Vecs {
|
||||
.add_sum()
|
||||
.add_total(),
|
||||
)?,
|
||||
txindex_to_is_coinbase: EagerVec::forced_import(
|
||||
&path.join("txindex_to_is_coinbase"),
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
)?,
|
||||
indexes_to_input_count: ComputedVecsFromTxindex::forced_import(
|
||||
path,
|
||||
"input_count",
|
||||
true,
|
||||
false,
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
StorableVecGeneatorOptions::default()
|
||||
@@ -105,7 +413,7 @@ impl Vecs {
|
||||
indexes_to_output_count: ComputedVecsFromTxindex::forced_import(
|
||||
path,
|
||||
"output_count",
|
||||
true,
|
||||
false,
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
StorableVecGeneatorOptions::default()
|
||||
@@ -115,32 +423,6 @@ impl Vecs {
|
||||
.add_sum()
|
||||
.add_total(),
|
||||
)?,
|
||||
inputindex_to_value: ComputedVec::forced_import_or_init_from_2(
|
||||
computation,
|
||||
path,
|
||||
"inputindex_to_value",
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
indexer.vecs().outputindex_to_value.boxed_clone(),
|
||||
indexer.vecs().inputindex_to_outputindex.boxed_clone(),
|
||||
|index: InputIndex, outputindex_to_value_iter, inputindex_to_outputindex_iter| {
|
||||
inputindex_to_outputindex_iter
|
||||
.next_at(index.unwrap_to_usize())
|
||||
.map(|(inputindex, outputindex)| {
|
||||
let outputindex = outputindex.into_inner();
|
||||
if outputindex == OutputIndex::COINBASE {
|
||||
Sats::ZERO
|
||||
} else if let Some((_, value)) =
|
||||
outputindex_to_value_iter.next_at(outputindex.unwrap_to_usize())
|
||||
{
|
||||
value.into_inner()
|
||||
} else {
|
||||
dbg!(inputindex, outputindex);
|
||||
panic!()
|
||||
}
|
||||
})
|
||||
},
|
||||
)?,
|
||||
indexes_to_tx_v1: ComputedVecsFromHeight::forced_import(
|
||||
path,
|
||||
"tx_v1",
|
||||
@@ -165,46 +447,26 @@ impl Vecs {
|
||||
compressed,
|
||||
StorableVecGeneatorOptions::default().add_sum().add_total(),
|
||||
)?,
|
||||
indexes_to_input_value: ComputedVecsFromTxindex::forced_import(
|
||||
path,
|
||||
"input_value",
|
||||
true,
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
StorableVecGeneatorOptions::default()
|
||||
.add_average()
|
||||
.add_sum()
|
||||
.add_total(),
|
||||
)?,
|
||||
indexes_to_output_value: ComputedVecsFromTxindex::forced_import(
|
||||
path,
|
||||
"output_value",
|
||||
true,
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
StorableVecGeneatorOptions::default()
|
||||
.add_average()
|
||||
.add_sum()
|
||||
.add_total(),
|
||||
)?,
|
||||
indexes_to_fee: ComputedValueVecsFromTxindex::forced_import(
|
||||
path,
|
||||
"fee",
|
||||
true,
|
||||
indexes,
|
||||
Some(txindex_to_fee.boxed_clone()),
|
||||
Version::ZERO,
|
||||
computation,
|
||||
compressed,
|
||||
marketprices,
|
||||
StorableVecGeneatorOptions::default()
|
||||
.add_sum()
|
||||
.add_total()
|
||||
.add_percentiles()
|
||||
.add_minmax()
|
||||
.add_average(),
|
||||
compute_dollars,
|
||||
)?,
|
||||
indexes_to_feerate: ComputedVecsFromTxindex::forced_import(
|
||||
path,
|
||||
"feerate",
|
||||
true,
|
||||
false,
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
StorableVecGeneatorOptions::default()
|
||||
@@ -212,16 +474,6 @@ impl Vecs {
|
||||
.add_minmax()
|
||||
.add_average(),
|
||||
)?,
|
||||
txindex_to_weight: EagerVec::forced_import(
|
||||
&path.join("txindex_to_weight"),
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
)?,
|
||||
txindex_to_vsize: EagerVec::forced_import(
|
||||
&path.join("txindex_to_vsize"),
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
)?,
|
||||
indexes_to_tx_vsize: ComputedVecsFromTxindex::forced_import(
|
||||
path,
|
||||
"tx_vsize",
|
||||
@@ -428,6 +680,18 @@ impl Vecs {
|
||||
.add_sum()
|
||||
.add_total(),
|
||||
)?,
|
||||
txindex_to_is_coinbase,
|
||||
inputindex_to_value,
|
||||
// indexes_to_input_value,
|
||||
// indexes_to_output_value,
|
||||
txindex_to_input_value,
|
||||
txindex_to_output_value,
|
||||
txindex_to_fee,
|
||||
txindex_to_feerate,
|
||||
txindex_to_vsize,
|
||||
txindex_to_weight,
|
||||
txindex_to_input_count,
|
||||
txindex_to_output_count,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -454,34 +718,20 @@ impl Vecs {
|
||||
},
|
||||
)?;
|
||||
|
||||
self.indexes_to_input_count.compute_all(
|
||||
self.indexes_to_input_count.compute_rest(
|
||||
indexer,
|
||||
indexes,
|
||||
starting_indexes,
|
||||
exit,
|
||||
|v, indexer, _, starting_indexes, exit| {
|
||||
v.compute_count_from_indexes(
|
||||
starting_indexes.txindex,
|
||||
&indexer.vecs().txindex_to_first_inputindex,
|
||||
&indexer.vecs().inputindex_to_outputindex,
|
||||
exit,
|
||||
)
|
||||
},
|
||||
Some(&self.txindex_to_input_count),
|
||||
)?;
|
||||
|
||||
self.indexes_to_output_count.compute_all(
|
||||
self.indexes_to_output_count.compute_rest(
|
||||
indexer,
|
||||
indexes,
|
||||
starting_indexes,
|
||||
exit,
|
||||
|v, indexer, _, starting_indexes, exit| {
|
||||
v.compute_count_from_indexes(
|
||||
starting_indexes.txindex,
|
||||
&indexer.vecs().txindex_to_first_outputindex,
|
||||
&indexer.vecs().outputindex_to_value,
|
||||
exit,
|
||||
)
|
||||
},
|
||||
Some(&self.txindex_to_output_count),
|
||||
)?;
|
||||
|
||||
let compute_indexes_to_tx_vany =
|
||||
@@ -510,122 +760,70 @@ 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)?;
|
||||
|
||||
self.txindex_to_is_coinbase.compute_is_first_ordered(
|
||||
starting_indexes.txindex,
|
||||
&indexes.txindex_to_height,
|
||||
&indexer.vecs().height_to_first_txindex,
|
||||
exit,
|
||||
)?;
|
||||
self.txindex_to_is_coinbase
|
||||
.compute_if_necessary(starting_indexes.txindex, exit)?;
|
||||
|
||||
let mut txindex_to_total_size_iter = indexer.vecs().txindex_to_total_size.iter();
|
||||
self.txindex_to_weight.compute_transform(
|
||||
starting_indexes.txindex,
|
||||
&indexer.vecs().txindex_to_base_size,
|
||||
|(txindex, base_size, ..)| {
|
||||
let total_size = txindex_to_total_size_iter.unwrap_get_inner(txindex);
|
||||
self.txindex_to_weight
|
||||
.compute_if_necessary(starting_indexes.txindex, exit)?;
|
||||
|
||||
// This is the exact definition of a weight unit, as defined by BIP-141 (quote above).
|
||||
let wu = usize::from(base_size) * 3 + usize::from(total_size);
|
||||
let weight = Weight::from(bitcoin::Weight::from_wu_usize(wu));
|
||||
|
||||
(txindex, weight)
|
||||
},
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.txindex_to_vsize.compute_transform(
|
||||
starting_indexes.txindex,
|
||||
&self.txindex_to_weight,
|
||||
|(txindex, weight, ..)| {
|
||||
let vbytes =
|
||||
StoredUsize::from(bitcoin::Weight::from(weight).to_vbytes_ceil() as usize);
|
||||
(txindex, vbytes)
|
||||
},
|
||||
exit,
|
||||
)?;
|
||||
self.txindex_to_vsize
|
||||
.compute_if_necessary(starting_indexes.txindex, exit)?;
|
||||
|
||||
self.inputindex_to_value
|
||||
.compute_if_necessary(starting_indexes.inputindex, exit)?;
|
||||
|
||||
self.indexes_to_output_value.compute_all(
|
||||
self.txindex_to_output_value
|
||||
.compute_if_necessary(starting_indexes.txindex, exit)?;
|
||||
|
||||
// self.indexes_to_output_value.compute_all(
|
||||
// indexer,
|
||||
// indexes,
|
||||
// starting_indexes,
|
||||
// exit,
|
||||
// |vec, indexer, _, starting_indexes, exit| {
|
||||
// vec.compute_sum_from_indexes(
|
||||
// starting_indexes.txindex,
|
||||
// &indexer.vecs().txindex_to_first_outputindex,
|
||||
// self.indexes_to_output_count.txindex.as_ref().unwrap(),
|
||||
// &indexer.vecs().outputindex_to_value,
|
||||
// exit,
|
||||
// )
|
||||
// },
|
||||
// )?;
|
||||
|
||||
self.txindex_to_input_value
|
||||
.compute_if_necessary(starting_indexes.txindex, exit)?;
|
||||
|
||||
// self.indexes_to_input_value.compute_all(
|
||||
// indexer,
|
||||
// indexes,
|
||||
// starting_indexes,
|
||||
// exit,
|
||||
// |vec, indexer, _, starting_indexes, exit| {
|
||||
// vec.compute_sum_from_indexes(
|
||||
// starting_indexes.txindex,
|
||||
// &indexer.vecs().txindex_to_first_inputindex,
|
||||
// self.indexes_to_input_count.txindex.as_ref().unwrap(),
|
||||
// &self.inputindex_to_value,
|
||||
// exit,
|
||||
// )
|
||||
// },
|
||||
// )?;
|
||||
|
||||
self.indexes_to_fee.compute_rest(
|
||||
indexer,
|
||||
indexes,
|
||||
starting_indexes,
|
||||
exit,
|
||||
|vec, indexer, _, starting_indexes, exit| {
|
||||
vec.compute_sum_from_indexes(
|
||||
starting_indexes.txindex,
|
||||
&indexer.vecs().txindex_to_first_outputindex,
|
||||
self.indexes_to_output_count.txindex.as_ref().unwrap(),
|
||||
&indexer.vecs().outputindex_to_value,
|
||||
exit,
|
||||
)
|
||||
},
|
||||
Some(&self.txindex_to_fee),
|
||||
)?;
|
||||
|
||||
self.indexes_to_input_value.compute_all(
|
||||
self.indexes_to_feerate.compute_rest(
|
||||
indexer,
|
||||
indexes,
|
||||
starting_indexes,
|
||||
exit,
|
||||
|vec, indexer, _, starting_indexes, exit| {
|
||||
vec.compute_sum_from_indexes(
|
||||
starting_indexes.txindex,
|
||||
&indexer.vecs().txindex_to_first_inputindex,
|
||||
self.indexes_to_input_count.txindex.as_ref().unwrap(),
|
||||
&self.inputindex_to_value,
|
||||
exit,
|
||||
)
|
||||
},
|
||||
)?;
|
||||
|
||||
self.indexes_to_fee.compute_all(
|
||||
indexer,
|
||||
indexes,
|
||||
marketprices,
|
||||
starting_indexes,
|
||||
exit,
|
||||
|vec, _, _, starting_indexes, exit| {
|
||||
let mut txindex_to_output_value_iter = self
|
||||
.indexes_to_output_value
|
||||
.txindex
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.iter();
|
||||
vec.compute_transform(
|
||||
starting_indexes.txindex,
|
||||
self.indexes_to_input_value.txindex.as_ref().unwrap(),
|
||||
|(txindex, input_value, ..)| {
|
||||
if input_value.is_zero() {
|
||||
(txindex, input_value)
|
||||
} else {
|
||||
let output_value =
|
||||
txindex_to_output_value_iter.unwrap_get_inner(txindex);
|
||||
(txindex, input_value.checked_sub(output_value).unwrap())
|
||||
}
|
||||
},
|
||||
exit,
|
||||
)
|
||||
},
|
||||
)?;
|
||||
|
||||
self.indexes_to_feerate.compute_all(
|
||||
indexer,
|
||||
indexes,
|
||||
starting_indexes,
|
||||
exit,
|
||||
|vec, _, _, starting_indexes, exit| {
|
||||
let mut txindex_to_vsize_iter = self.txindex_to_vsize.iter();
|
||||
vec.compute_transform(
|
||||
starting_indexes.txindex,
|
||||
self.indexes_to_fee.sats.txindex.as_ref().unwrap(),
|
||||
|(txindex, fee, ..)| {
|
||||
let vsize = txindex_to_vsize_iter.unwrap_get_inner(txindex);
|
||||
(txindex, Feerate::from((fee, vsize)))
|
||||
},
|
||||
exit,
|
||||
)
|
||||
},
|
||||
Some(&self.txindex_to_feerate),
|
||||
)?;
|
||||
|
||||
self.indexes_to_tx_weight.compute_rest(
|
||||
@@ -653,12 +851,7 @@ impl Vecs {
|
||||
|vec, indexer, _, starting_indexes, exit| {
|
||||
let mut txindex_to_first_outputindex_iter =
|
||||
indexer.vecs().txindex_to_first_outputindex.iter();
|
||||
let mut txindex_to_output_count_iter = self
|
||||
.indexes_to_output_count
|
||||
.txindex
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.iter();
|
||||
let mut txindex_to_output_count_iter = self.txindex_to_output_count.iter();
|
||||
let mut outputindex_to_value_iter = indexer.vecs().outputindex_to_value.iter();
|
||||
vec.compute_transform(
|
||||
starting_indexes.height,
|
||||
@@ -890,23 +1083,22 @@ impl Vecs {
|
||||
[
|
||||
vec![
|
||||
&self.inputindex_to_value as &dyn AnyCollectableVec,
|
||||
&self.txindex_to_fee,
|
||||
&self.txindex_to_feerate,
|
||||
&self.txindex_to_input_count,
|
||||
&self.txindex_to_input_value,
|
||||
&self.txindex_to_is_coinbase,
|
||||
&self.txindex_to_output_count,
|
||||
&self.txindex_to_output_value,
|
||||
&self.txindex_to_vsize,
|
||||
&self.txindex_to_weight,
|
||||
],
|
||||
self.indexes_to_tx_count.vecs(),
|
||||
self.indexes_to_coinbase.vecs(),
|
||||
self.indexes_to_emptyoutput_count.vecs(),
|
||||
self.indexes_to_fee.vecs(),
|
||||
self.indexes_to_feerate.vecs(),
|
||||
self.indexes_to_input_value.vecs(),
|
||||
self.indexes_to_output_value.vecs(),
|
||||
self.indexes_to_subsidy.vecs(),
|
||||
self.indexes_to_tx_v1.vecs(),
|
||||
self.indexes_to_tx_v2.vecs(),
|
||||
self.indexes_to_tx_v3.vecs(),
|
||||
self.indexes_to_tx_vsize.vecs(),
|
||||
self.indexes_to_tx_weight.vecs(),
|
||||
self.indexes_to_input_count.vecs(),
|
||||
self.indexes_to_opreturn_count.vecs(),
|
||||
self.indexes_to_output_count.vecs(),
|
||||
self.indexes_to_p2a_count.vecs(),
|
||||
self.indexes_to_p2ms_count.vecs(),
|
||||
@@ -917,9 +1109,14 @@ impl Vecs {
|
||||
self.indexes_to_p2tr_count.vecs(),
|
||||
self.indexes_to_p2wpkh_count.vecs(),
|
||||
self.indexes_to_p2wsh_count.vecs(),
|
||||
self.indexes_to_opreturn_count.vecs(),
|
||||
self.indexes_to_subsidy.vecs(),
|
||||
self.indexes_to_tx_count.vecs(),
|
||||
self.indexes_to_tx_v1.vecs(),
|
||||
self.indexes_to_tx_v2.vecs(),
|
||||
self.indexes_to_tx_v3.vecs(),
|
||||
self.indexes_to_tx_vsize.vecs(),
|
||||
self.indexes_to_tx_weight.vecs(),
|
||||
self.indexes_to_unknownoutput_count.vecs(),
|
||||
self.indexes_to_emptyoutput_count.vecs(),
|
||||
]
|
||||
.concat()
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ log = { workspace = true }
|
||||
minreq = { workspace = true }
|
||||
oxc = { version = "0.68.1", features = ["codegen", "minifier"] }
|
||||
serde = { workspace = true }
|
||||
tokio = { version = "1.44.2", features = ["full"] }
|
||||
tower-http = { version = "0.6.2", features = ["compression-full", "trace"] }
|
||||
tokio = { version = "1.45.0", features = ["full"] }
|
||||
tower-http = { version = "0.6.3", features = ["compression-full", "trace"] }
|
||||
zip = "2.6.1"
|
||||
tracing = "0.1.41"
|
||||
|
||||
@@ -4,6 +4,7 @@ use super::{AnyIterableVec, AnyVec, StoredIndex, StoredType};
|
||||
|
||||
pub trait CollectableVec<I, T>: AnyVec + AnyIterableVec<I, T>
|
||||
where
|
||||
Self: Clone,
|
||||
I: StoredIndex,
|
||||
T: StoredType,
|
||||
{
|
||||
@@ -56,7 +57,7 @@ where
|
||||
|
||||
impl<I, T, V> CollectableVec<I, T> for V
|
||||
where
|
||||
V: AnyVec + AnyIterableVec<I, T>,
|
||||
V: AnyVec + AnyIterableVec<I, T> + Clone,
|
||||
I: StoredIndex,
|
||||
T: StoredType,
|
||||
{
|
||||
|
||||
@@ -73,6 +73,10 @@ pub trait VecIterator<'a>: BaseVecIterator<Item = (Self::I, Value<'a, Self::T>)>
|
||||
self.set_(i);
|
||||
self.next().map(|(i, v)| (i, Value::Owned(v.into_inner())))
|
||||
}
|
||||
|
||||
fn index_type_to_string(&self) -> &str {
|
||||
Self::I::to_string()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, I, T, Iter> VecIterator<'a> for Iter
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
use core::panic;
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use crate::{
|
||||
@@ -30,6 +31,10 @@ where
|
||||
source: BoxedAnyIterableVec<S1I, S1T>,
|
||||
compute: ComputeFrom1<I, T, S1I, S1T>,
|
||||
) -> Self {
|
||||
if source.index_type_to_string() != I::to_string() {
|
||||
panic!("Should have same index");
|
||||
}
|
||||
|
||||
Self {
|
||||
name: name.to_owned(),
|
||||
version,
|
||||
|
||||
@@ -37,6 +37,18 @@ where
|
||||
source2: BoxedAnyIterableVec<S2I, S2T>,
|
||||
compute: ComputeFrom2<I, T, S1I, S1T, S2I, S2T>,
|
||||
) -> Self {
|
||||
if ([
|
||||
source1.index_type_to_string(),
|
||||
source2.index_type_to_string(),
|
||||
])
|
||||
.into_iter()
|
||||
.filter(|t| *t == I::to_string())
|
||||
.count()
|
||||
== 0
|
||||
{
|
||||
panic!("At least one should have same index");
|
||||
}
|
||||
|
||||
Self {
|
||||
name: name.to_string(),
|
||||
version,
|
||||
@@ -98,7 +110,17 @@ where
|
||||
|
||||
#[inline]
|
||||
fn len(&self) -> usize {
|
||||
self.source1.len().min(self.source2.len())
|
||||
let len1 = if self.source1.index_type_to_string() == I::to_string() {
|
||||
self.source1.len()
|
||||
} else {
|
||||
usize::MAX
|
||||
};
|
||||
let len2 = if self.source2.index_type_to_string() == I::to_string() {
|
||||
self.source2.len()
|
||||
} else {
|
||||
usize::MAX
|
||||
};
|
||||
len1.min(len2)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,7 +168,17 @@ where
|
||||
}
|
||||
|
||||
fn len(&self) -> usize {
|
||||
self.source1.len().min(self.source2.len())
|
||||
let len1 = if self.source1.index_type_to_string() == I::to_string() {
|
||||
self.source1.len()
|
||||
} else {
|
||||
usize::MAX
|
||||
};
|
||||
let len2 = if self.source2.index_type_to_string() == I::to_string() {
|
||||
self.source2.len()
|
||||
} else {
|
||||
usize::MAX
|
||||
};
|
||||
len1.min(len2)
|
||||
}
|
||||
|
||||
fn modified_time(&self) -> Result<std::time::Duration> {
|
||||
|
||||
@@ -42,6 +42,19 @@ where
|
||||
source3: BoxedAnyIterableVec<S3I, S3T>,
|
||||
compute: ComputeFrom3<I, T, S1I, S1T, S2I, S2T, S3I, S3T>,
|
||||
) -> Self {
|
||||
if ([
|
||||
source1.index_type_to_string(),
|
||||
source2.index_type_to_string(),
|
||||
source3.index_type_to_string(),
|
||||
])
|
||||
.into_iter()
|
||||
.filter(|t| *t == I::to_string())
|
||||
.count()
|
||||
== 0
|
||||
{
|
||||
panic!("At least one should have same index");
|
||||
}
|
||||
|
||||
Self {
|
||||
name: name.to_string(),
|
||||
version,
|
||||
@@ -115,10 +128,22 @@ where
|
||||
|
||||
#[inline]
|
||||
fn len(&self) -> usize {
|
||||
self.source1
|
||||
.len()
|
||||
.min(self.source2.len())
|
||||
.min(self.source3.len())
|
||||
let len1 = if self.source1.index_type_to_string() == I::to_string() {
|
||||
self.source1.len()
|
||||
} else {
|
||||
usize::MAX
|
||||
};
|
||||
let len2 = if self.source2.index_type_to_string() == I::to_string() {
|
||||
self.source2.len()
|
||||
} else {
|
||||
usize::MAX
|
||||
};
|
||||
let len3 = if self.source3.index_type_to_string() == I::to_string() {
|
||||
self.source3.len()
|
||||
} else {
|
||||
usize::MAX
|
||||
};
|
||||
len1.min(len2).min(len3)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -172,10 +197,22 @@ where
|
||||
}
|
||||
|
||||
fn len(&self) -> usize {
|
||||
self.source1
|
||||
.len()
|
||||
.min(self.source2.len())
|
||||
.min(self.source3.len())
|
||||
let len1 = if self.source1.index_type_to_string() == I::to_string() {
|
||||
self.source1.len()
|
||||
} else {
|
||||
usize::MAX
|
||||
};
|
||||
let len2 = if self.source2.index_type_to_string() == I::to_string() {
|
||||
self.source2.len()
|
||||
} else {
|
||||
usize::MAX
|
||||
};
|
||||
let len3 = if self.source3.index_type_to_string() == I::to_string() {
|
||||
self.source3.len()
|
||||
} else {
|
||||
usize::MAX
|
||||
};
|
||||
len1.min(len2).min(len3)
|
||||
}
|
||||
|
||||
fn modified_time(&self) -> Result<std::time::Duration> {
|
||||
|
||||
@@ -476,14 +476,14 @@ function createPartialOptions(colors) {
|
||||
}),
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Value",
|
||||
title: "Transaction Input Value",
|
||||
bottom: [
|
||||
createAverageSeries({ concat: "input-value" }),
|
||||
...createSumTotalSeries({ concat: "input-value" }),
|
||||
],
|
||||
},
|
||||
// {
|
||||
// name: "Value",
|
||||
// title: "Transaction Input Value",
|
||||
// bottom: [
|
||||
// createAverageSeries({ concat: "input-value" }),
|
||||
// ...createSumTotalSeries({ concat: "input-value" }),
|
||||
// ],
|
||||
// },
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -500,14 +500,14 @@ function createPartialOptions(colors) {
|
||||
}),
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Value",
|
||||
title: "Transaction Output Value",
|
||||
bottom: [
|
||||
createAverageSeries({ concat: "output-value" }),
|
||||
...createSumTotalSeries({ concat: "output-value" }),
|
||||
],
|
||||
},
|
||||
// {
|
||||
// name: "Value",
|
||||
// title: "Transaction Output Value",
|
||||
// bottom: [
|
||||
// createAverageSeries({ concat: "output-value" }),
|
||||
// ...createSumTotalSeries({ concat: "output-value" }),
|
||||
// ],
|
||||
// },
|
||||
{
|
||||
name: "By type",
|
||||
tree: [],
|
||||
|
||||
@@ -128,7 +128,6 @@ export function createVecIdToIndexes() {
|
||||
"fee-75p": [Height],
|
||||
"fee-90p": [Height],
|
||||
"fee-average": [DateIndex, DecadeIndex, DifficultyEpoch, Height, MonthIndex, QuarterIndex, WeekIndex, YearIndex],
|
||||
"fee-in-btc": [TxIndex],
|
||||
"fee-in-btc-10p": [Height],
|
||||
"fee-in-btc-25p": [Height],
|
||||
"fee-in-btc-75p": [Height],
|
||||
@@ -138,7 +137,6 @@ export function createVecIdToIndexes() {
|
||||
"fee-in-btc-median": [Height],
|
||||
"fee-in-btc-min": [DateIndex, DecadeIndex, DifficultyEpoch, Height, MonthIndex, QuarterIndex, WeekIndex, YearIndex],
|
||||
"fee-in-btc-sum": [DateIndex, DecadeIndex, DifficultyEpoch, Height, MonthIndex, QuarterIndex, WeekIndex, YearIndex],
|
||||
"fee-in-usd": [TxIndex],
|
||||
"fee-in-usd-10p": [Height],
|
||||
"fee-in-usd-25p": [Height],
|
||||
"fee-in-usd-75p": [Height],
|
||||
@@ -197,8 +195,6 @@ export function createVecIdToIndexes() {
|
||||
"input-count-min": [DateIndex, DecadeIndex, DifficultyEpoch, Height, MonthIndex, QuarterIndex, WeekIndex, YearIndex],
|
||||
"input-count-sum": [DateIndex, DecadeIndex, DifficultyEpoch, Height, MonthIndex, QuarterIndex, WeekIndex, YearIndex],
|
||||
"input-value": [TxIndex],
|
||||
"input-value-average": [DateIndex, DecadeIndex, DifficultyEpoch, Height, MonthIndex, QuarterIndex, WeekIndex, YearIndex],
|
||||
"input-value-sum": [DateIndex, DecadeIndex, DifficultyEpoch, Height, MonthIndex, QuarterIndex, WeekIndex, YearIndex],
|
||||
inputindex: [InputIndex],
|
||||
interval: [Height],
|
||||
"is-coinbase": [TxIndex],
|
||||
@@ -236,8 +232,6 @@ export function createVecIdToIndexes() {
|
||||
"output-count-min": [DateIndex, DecadeIndex, DifficultyEpoch, Height, MonthIndex, QuarterIndex, WeekIndex, YearIndex],
|
||||
"output-count-sum": [DateIndex, DecadeIndex, DifficultyEpoch, Height, MonthIndex, QuarterIndex, WeekIndex, YearIndex],
|
||||
"output-value": [TxIndex],
|
||||
"output-value-average": [DateIndex, DecadeIndex, DifficultyEpoch, Height, MonthIndex, QuarterIndex, WeekIndex, YearIndex],
|
||||
"output-value-sum": [DateIndex, DecadeIndex, DifficultyEpoch, Height, MonthIndex, QuarterIndex, WeekIndex, YearIndex],
|
||||
outputindex: [InputIndex, OutputIndex],
|
||||
outputtype: [OutputIndex],
|
||||
outputtypeindex: [OutputIndex],
|
||||
@@ -394,10 +388,8 @@ export function createVecIdToIndexes() {
|
||||
"total-fee-in-btc": [DateIndex, DecadeIndex, DifficultyEpoch, Height, MonthIndex, QuarterIndex, WeekIndex, YearIndex],
|
||||
"total-fee-in-usd": [DateIndex, DecadeIndex, DifficultyEpoch, Height, MonthIndex, QuarterIndex, WeekIndex, YearIndex],
|
||||
"total-input-count": [DateIndex, DecadeIndex, DifficultyEpoch, Height, MonthIndex, QuarterIndex, WeekIndex, YearIndex],
|
||||
"total-input-value": [DateIndex, DecadeIndex, DifficultyEpoch, Height, MonthIndex, QuarterIndex, WeekIndex, YearIndex],
|
||||
"total-opreturn-count": [DateIndex, DecadeIndex, DifficultyEpoch, Height, MonthIndex, QuarterIndex, WeekIndex, YearIndex],
|
||||
"total-output-count": [DateIndex, DecadeIndex, DifficultyEpoch, Height, MonthIndex, QuarterIndex, WeekIndex, YearIndex],
|
||||
"total-output-value": [DateIndex, DecadeIndex, DifficultyEpoch, Height, MonthIndex, QuarterIndex, WeekIndex, YearIndex],
|
||||
"total-p2a-count": [DateIndex, DecadeIndex, DifficultyEpoch, Height, MonthIndex, QuarterIndex, WeekIndex, YearIndex],
|
||||
"total-p2ms-count": [DateIndex, DecadeIndex, DifficultyEpoch, Height, MonthIndex, QuarterIndex, WeekIndex, YearIndex],
|
||||
"total-p2pk33-count": [DateIndex, DecadeIndex, DifficultyEpoch, Height, MonthIndex, QuarterIndex, WeekIndex, YearIndex],
|
||||
|
||||
Reference in New Issue
Block a user