lazy: done

This commit is contained in:
nym21
2025-05-08 11:15:47 +02:00
parent 3f62da879c
commit 96eeacbe2b
14 changed files with 690 additions and 371 deletions

44
Cargo.lock generated
View File

@@ -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",
]

View File

@@ -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"

View File

@@ -83,6 +83,7 @@ where
})
}
#[allow(unused)]
pub fn compute_all<F>(
&mut self,
indexer: &Indexer,

View File

@@ -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),
)?;
}

View File

@@ -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,
})
}

View File

@@ -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()
}

View File

@@ -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"

View File

@@ -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,
{

View File

@@ -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

View File

@@ -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,

View File

@@ -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> {

View File

@@ -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> {

View File

@@ -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: [],

View File

@@ -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],