global: snapshot

This commit is contained in:
nym21
2025-08-29 22:49:26 +02:00
parent 30affc884b
commit e106d30852
28 changed files with 1120 additions and 827 deletions

View File

@@ -1,279 +0,0 @@
use std::path::Path;
use brk_error::Result;
use brk_indexer::Indexer;
use brk_structs::{
CheckedSub, DifficultyEpoch, HalvingEpoch, Height, StoredU32, StoredU64, Timestamp, Version,
Weight,
};
use vecdb::{AnyCollectableVec, Database, EagerVec, Exit, PAGE_SIZE, VecIterator};
use crate::grouped::Source;
use super::{
Indexes,
grouped::{ComputedVecsFromDateIndex, ComputedVecsFromHeight, VecBuilderOptions},
indexes,
};
const VERSION: Version = Version::ZERO;
#[derive(Clone)]
pub struct Vecs {
db: Database,
pub height_to_interval: EagerVec<Height, Timestamp>,
pub height_to_vbytes: EagerVec<Height, StoredU64>,
pub difficultyepoch_to_timestamp: EagerVec<DifficultyEpoch, Timestamp>,
pub halvingepoch_to_timestamp: EagerVec<HalvingEpoch, Timestamp>,
pub timeindexes_to_timestamp: ComputedVecsFromDateIndex<Timestamp>,
pub indexes_to_block_count: ComputedVecsFromHeight<StoredU32>,
pub indexes_to_block_interval: ComputedVecsFromHeight<Timestamp>,
pub indexes_to_block_size: ComputedVecsFromHeight<StoredU64>,
pub indexes_to_block_vbytes: ComputedVecsFromHeight<StoredU64>,
pub indexes_to_block_weight: ComputedVecsFromHeight<Weight>,
}
impl Vecs {
pub fn forced_import(parent: &Path, version: Version, indexes: &indexes::Vecs) -> Result<Self> {
let db = Database::open(&parent.join("blocks"))?;
db.set_min_len(PAGE_SIZE * 1_000_000)?;
Ok(Self {
height_to_interval: EagerVec::forced_import_compressed(
&db,
"interval",
version + VERSION + Version::ZERO,
)?,
timeindexes_to_timestamp: ComputedVecsFromDateIndex::forced_import(
&db,
"timestamp",
Source::Compute,
version + VERSION + Version::ZERO,
indexes,
VecBuilderOptions::default().add_first(),
)?,
indexes_to_block_interval: ComputedVecsFromHeight::forced_import(
&db,
"block_interval",
Source::None,
version + VERSION + Version::ZERO,
indexes,
VecBuilderOptions::default()
.add_percentiles()
.add_minmax()
.add_average(),
)?,
indexes_to_block_count: ComputedVecsFromHeight::forced_import(
&db,
"block_count",
Source::Compute,
version + VERSION + Version::ZERO,
indexes,
VecBuilderOptions::default().add_sum().add_cumulative(),
)?,
indexes_to_block_weight: ComputedVecsFromHeight::forced_import(
&db,
"block_weight",
Source::None,
version + VERSION + Version::ZERO,
indexes,
VecBuilderOptions::default()
.add_sum()
.add_minmax()
.add_average()
.add_percentiles()
.add_cumulative(),
)?,
indexes_to_block_size: ComputedVecsFromHeight::forced_import(
&db,
"block_size",
Source::Compute,
version + VERSION + Version::ZERO,
indexes,
VecBuilderOptions::default()
.add_sum()
.add_minmax()
.add_average()
.add_percentiles()
.add_cumulative(),
)?,
height_to_vbytes: EagerVec::forced_import_compressed(
&db,
"vbytes",
version + VERSION + Version::ZERO,
)?,
indexes_to_block_vbytes: ComputedVecsFromHeight::forced_import(
&db,
"block_vbytes",
Source::None,
version + VERSION + Version::ZERO,
indexes,
VecBuilderOptions::default()
.add_sum()
.add_minmax()
.add_average()
.add_percentiles()
.add_cumulative(),
)?,
difficultyepoch_to_timestamp: EagerVec::forced_import_compressed(
&db,
"timestamp",
version + VERSION + Version::ZERO,
)?,
halvingepoch_to_timestamp: EagerVec::forced_import_compressed(
&db,
"timestamp",
version + VERSION + Version::ZERO,
)?,
db,
})
}
pub fn compute(
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
self.compute_(indexer, indexes, starting_indexes, exit)?;
self.db.flush_then_punch()?;
Ok(())
}
fn compute_(
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
self.timeindexes_to_timestamp.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|vec, _, indexes, starting_indexes, exit| {
vec.compute_transform(
starting_indexes.dateindex,
&indexes.dateindex_to_date,
|(di, d, ..)| (di, Timestamp::from(d)),
exit,
)?;
Ok(())
},
)?;
self.indexes_to_block_count.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|v, indexer, _, starting_indexes, exit| {
v.compute_range(
starting_indexes.height,
&indexer.vecs.height_to_weight,
|h| (h, StoredU32::from(1_u32)),
exit,
)?;
Ok(())
},
)?;
let mut height_to_timestamp_iter = indexer.vecs.height_to_timestamp.iter();
self.height_to_interval.compute_transform(
starting_indexes.height,
&indexer.vecs.height_to_timestamp,
|(height, timestamp, ..)| {
let interval = height.decremented().map_or(Timestamp::ZERO, |prev_h| {
let prev_timestamp = height_to_timestamp_iter.unwrap_get_inner(prev_h);
timestamp
.checked_sub(prev_timestamp)
.unwrap_or(Timestamp::ZERO)
});
(height, interval)
},
exit,
)?;
self.indexes_to_block_interval.compute_rest(
indexes,
starting_indexes,
exit,
Some(&self.height_to_interval),
)?;
self.indexes_to_block_weight.compute_rest(
indexes,
starting_indexes,
exit,
Some(&indexer.vecs.height_to_weight),
)?;
self.indexes_to_block_size.compute_rest(
indexes,
starting_indexes,
exit,
Some(&indexer.vecs.height_to_total_size),
)?;
self.height_to_vbytes.compute_transform(
starting_indexes.height,
&indexer.vecs.height_to_weight,
|(h, w, ..)| {
(
h,
StoredU64::from(bitcoin::Weight::from(w).to_vbytes_floor()),
)
},
exit,
)?;
self.indexes_to_block_vbytes.compute_rest(
indexes,
starting_indexes,
exit,
Some(&self.height_to_vbytes),
)?;
let mut height_to_timestamp_iter = indexer.vecs.height_to_timestamp.iter();
self.difficultyepoch_to_timestamp.compute_transform(
starting_indexes.difficultyepoch,
&indexes.difficultyepoch_to_first_height,
|(i, h, ..)| (i, height_to_timestamp_iter.unwrap_get_inner(h)),
exit,
)?;
self.halvingepoch_to_timestamp.compute_transform(
starting_indexes.halvingepoch,
&indexes.halvingepoch_to_first_height,
|(i, h, ..)| (i, height_to_timestamp_iter.unwrap_get_inner(h)),
exit,
)?;
Ok(())
}
pub fn vecs(&self) -> Vec<&dyn AnyCollectableVec> {
[
vec![
&self.height_to_interval as &dyn AnyCollectableVec,
&self.height_to_vbytes,
&self.difficultyepoch_to_timestamp,
&self.halvingepoch_to_timestamp,
],
self.timeindexes_to_timestamp.vecs(),
self.indexes_to_block_count.vecs(),
self.indexes_to_block_interval.vecs(),
self.indexes_to_block_size.vecs(),
self.indexes_to_block_vbytes.vecs(),
self.indexes_to_block_weight.vecs(),
]
.into_iter()
.flatten()
.collect::<Vec<_>>()
}
}

View File

@@ -3,8 +3,9 @@ use std::path::Path;
use brk_error::Result;
use brk_indexer::Indexer;
use brk_structs::{
CheckedSub, Feerate, HalvingEpoch, Height, InputIndex, OutputIndex, Sats, StoredBool,
StoredU32, StoredU64, TxIndex, TxVersion, Version, Weight,
CheckedSub, Date, DateIndex, DifficultyEpoch, Dollars, FeeRate, HalvingEpoch, Height,
InputIndex, OutputIndex, Sats, StoredBool, StoredF32, StoredF64, StoredU32, StoredU64,
Timestamp, TxIndex, TxVersion, Version, Weight,
};
use vecdb::{
AnyCloneableIterableVec, AnyCollectableVec, AnyIterableVec, Database, EagerVec, Exit,
@@ -12,25 +13,37 @@ use vecdb::{
};
use crate::grouped::{
ComputedValueVecsFromHeight, ComputedValueVecsFromTxindex, ComputedVecsFromHeight,
ComputedVecsFromTxindex, Source, VecBuilderOptions,
ComputedValueVecsFromHeight, ComputedValueVecsFromTxindex, ComputedVecsFromDateIndex,
ComputedVecsFromHeight, ComputedVecsFromTxindex, Source, VecBuilderOptions,
};
use super::{Indexes, indexes, price};
const VERSION: Version = Version::ZERO;
const TARGET_BLOCKS_PER_DAY: f64 = 144.0;
#[derive(Clone)]
pub struct Vecs {
db: Database,
// pub txindex_to_is_v1: LazyVec<Txindex, bool>,
// pub txindex_to_is_v2: LazyVec<Txindex, bool>,
// pub txindex_to_is_v3: LazyVec<Txindex, bool>,
pub height_to_interval: EagerVec<Height, Timestamp>,
pub height_to_vbytes: EagerVec<Height, StoredU64>,
pub difficultyepoch_to_timestamp: EagerVec<DifficultyEpoch, Timestamp>,
pub halvingepoch_to_timestamp: EagerVec<HalvingEpoch, Timestamp>,
pub timeindexes_to_timestamp: ComputedVecsFromDateIndex<Timestamp>,
pub indexes_to_block_count: ComputedVecsFromHeight<StoredU32>,
pub indexes_to_block_interval: ComputedVecsFromHeight<Timestamp>,
pub indexes_to_block_size: ComputedVecsFromHeight<StoredU64>,
pub indexes_to_block_vbytes: ComputedVecsFromHeight<StoredU64>,
pub indexes_to_block_weight: ComputedVecsFromHeight<Weight>,
pub indexes_to_difficulty: ComputedVecsFromHeight<StoredF64>,
pub indexes_to_difficultyepoch: ComputedVecsFromDateIndex<DifficultyEpoch>,
pub indexes_to_halvingepoch: ComputedVecsFromDateIndex<HalvingEpoch>,
pub indexes_to_coinbase: ComputedValueVecsFromHeight,
pub indexes_to_emptyoutput_count: ComputedVecsFromHeight<StoredU64>,
pub indexes_to_fee: ComputedValueVecsFromTxindex,
pub indexes_to_feerate: ComputedVecsFromTxindex<Feerate>,
pub indexes_to_fee_rate: ComputedVecsFromTxindex<FeeRate>,
/// Value == 0 when Coinbase
pub txindex_to_input_value:
LazyVecFrom3<TxIndex, Sats, TxIndex, InputIndex, TxIndex, StoredU64, InputIndex, Sats>,
@@ -65,8 +78,18 @@ pub struct Vecs {
pub txindex_to_vsize: LazyVecFrom1<TxIndex, StoredU64, TxIndex, Weight>,
pub txindex_to_weight: LazyVecFrom2<TxIndex, Weight, TxIndex, StoredU32, TxIndex, StoredU32>,
pub txindex_to_fee: EagerVec<TxIndex, Sats>,
pub txindex_to_feerate: EagerVec<TxIndex, Feerate>,
pub txindex_to_fee_rate: EagerVec<TxIndex, FeeRate>,
pub indexes_to_exact_utxo_count: ComputedVecsFromHeight<StoredU64>,
pub dateindex_to_fee_dominance: EagerVec<DateIndex, StoredF32>,
pub dateindex_to_subsidy_dominance: EagerVec<DateIndex, StoredF32>,
pub indexes_to_subsidy_usd_1y_sma: Option<ComputedVecsFromDateIndex<Dollars>>,
pub indexes_to_puell_multiple: Option<ComputedVecsFromDateIndex<StoredF32>>,
pub indexes_to_hash_rate: ComputedVecsFromDateIndex<StoredF64>,
pub indexes_to_hash_rate_1w_sma: ComputedVecsFromDateIndex<StoredF64>,
pub indexes_to_hash_rate_1m_sma: ComputedVecsFromDateIndex<StoredF32>,
pub indexes_to_hash_rate_2m_sma: ComputedVecsFromDateIndex<StoredF32>,
pub indexes_to_hash_rate_1y_sma: ComputedVecsFromDateIndex<StoredF32>,
pub indexes_to_difficulty_as_hash: ComputedVecsFromDateIndex<StoredF32>,
}
impl Vecs {
@@ -77,7 +100,7 @@ impl Vecs {
indexes: &indexes::Vecs,
price: Option<&price::Vecs>,
) -> Result<Self> {
let db = Database::open(&parent.join("transactions"))?;
let db = Database::open(&parent.join("chain"))?;
db.set_min_len(PAGE_SIZE * 10_000_000)?;
let compute_dollars = price.is_some();
@@ -262,10 +285,131 @@ impl Vecs {
let txindex_to_fee =
EagerVec::forced_import_compressed(&db, "fee", version + VERSION + Version::ZERO)?;
let txindex_to_feerate =
EagerVec::forced_import_compressed(&db, "feerate", version + VERSION + Version::ZERO)?;
let txindex_to_fee_rate =
EagerVec::forced_import_compressed(&db, "fee_rate", version + VERSION + Version::ZERO)?;
Ok(Self {
height_to_interval: EagerVec::forced_import_compressed(
&db,
"interval",
version + VERSION + Version::ZERO,
)?,
timeindexes_to_timestamp: ComputedVecsFromDateIndex::forced_import(
&db,
"timestamp",
Source::Compute,
version + VERSION + Version::ZERO,
indexes,
VecBuilderOptions::default().add_first(),
)?,
indexes_to_block_interval: ComputedVecsFromHeight::forced_import(
&db,
"block_interval",
Source::None,
version + VERSION + Version::ZERO,
indexes,
VecBuilderOptions::default()
.add_percentiles()
.add_minmax()
.add_average(),
)?,
indexes_to_block_count: ComputedVecsFromHeight::forced_import(
&db,
"block_count",
Source::Compute,
version + VERSION + Version::ZERO,
indexes,
VecBuilderOptions::default().add_sum().add_cumulative(),
)?,
indexes_to_block_weight: ComputedVecsFromHeight::forced_import(
&db,
"block_weight",
Source::None,
version + VERSION + Version::ZERO,
indexes,
VecBuilderOptions::default()
.add_sum()
.add_minmax()
.add_average()
.add_percentiles()
.add_cumulative(),
)?,
indexes_to_block_size: ComputedVecsFromHeight::forced_import(
&db,
"block_size",
Source::Compute,
version + VERSION + Version::ZERO,
indexes,
VecBuilderOptions::default()
.add_sum()
.add_minmax()
.add_average()
.add_percentiles()
.add_cumulative(),
)?,
height_to_vbytes: EagerVec::forced_import_compressed(
&db,
"vbytes",
version + VERSION + Version::ZERO,
)?,
indexes_to_block_vbytes: ComputedVecsFromHeight::forced_import(
&db,
"block_vbytes",
Source::None,
version + VERSION + Version::ZERO,
indexes,
VecBuilderOptions::default()
.add_sum()
.add_minmax()
.add_average()
.add_percentiles()
.add_cumulative(),
)?,
difficultyepoch_to_timestamp: EagerVec::forced_import_compressed(
&db,
"timestamp",
version + VERSION + Version::ZERO,
)?,
halvingepoch_to_timestamp: EagerVec::forced_import_compressed(
&db,
"timestamp",
version + VERSION + Version::ZERO,
)?,
dateindex_to_fee_dominance: EagerVec::forced_import_compressed(
&db,
"fee_dominance",
version + VERSION + Version::ZERO,
)?,
dateindex_to_subsidy_dominance: EagerVec::forced_import_compressed(
&db,
"subsidy_dominance",
version + VERSION + Version::ZERO,
)?,
indexes_to_difficulty: ComputedVecsFromHeight::forced_import(
&db,
"difficulty",
Source::None,
version + VERSION + Version::ZERO,
indexes,
VecBuilderOptions::default().add_last(),
)?,
indexes_to_difficultyepoch: ComputedVecsFromDateIndex::forced_import(
&db,
"difficultyepoch",
Source::Compute,
version + VERSION + Version::ZERO,
indexes,
VecBuilderOptions::default().add_last(),
)?,
indexes_to_halvingepoch: ComputedVecsFromDateIndex::forced_import(
&db,
"halvingepoch",
Source::Compute,
version + VERSION + Version::ZERO,
indexes,
VecBuilderOptions::default().add_last(),
)?,
indexes_to_tx_count: ComputedVecsFromHeight::forced_import(
&db,
"tx_count",
@@ -343,9 +487,9 @@ impl Vecs {
.add_minmax()
.add_average(),
)?,
indexes_to_feerate: ComputedVecsFromTxindex::forced_import(
indexes_to_fee_rate: ComputedVecsFromTxindex::forced_import(
&db,
"feerate",
"fee_rate",
Source::None,
version + VERSION + Version::ZERO,
indexes,
@@ -577,6 +721,77 @@ impl Vecs {
indexes,
VecBuilderOptions::default().add_last(),
)?,
indexes_to_subsidy_usd_1y_sma: compute_dollars.then(|| {
ComputedVecsFromDateIndex::forced_import(
&db,
"subsidy_usd_1y_sma",
Source::Compute,
version + VERSION + Version::ZERO,
indexes,
VecBuilderOptions::default().add_last(),
)
.unwrap()
}),
indexes_to_puell_multiple: compute_dollars.then(|| {
ComputedVecsFromDateIndex::forced_import(
&db,
"puell_multiple",
Source::Compute,
version + VERSION + Version::ZERO,
indexes,
VecBuilderOptions::default().add_last(),
)
.unwrap()
}),
indexes_to_hash_rate: ComputedVecsFromDateIndex::forced_import(
&db,
"hash_rate",
Source::Compute,
version + VERSION + Version::ONE,
indexes,
VecBuilderOptions::default().add_last(),
)?,
indexes_to_hash_rate_1w_sma: ComputedVecsFromDateIndex::forced_import(
&db,
"hash_rate_1w_sma",
Source::Compute,
version + VERSION + Version::ZERO,
indexes,
VecBuilderOptions::default().add_last(),
)?,
indexes_to_hash_rate_1m_sma: ComputedVecsFromDateIndex::forced_import(
&db,
"hash_rate_1m_sma",
Source::Compute,
version + VERSION + Version::ZERO,
indexes,
VecBuilderOptions::default().add_last(),
)?,
indexes_to_hash_rate_2m_sma: ComputedVecsFromDateIndex::forced_import(
&db,
"hash_rate_2m_sma",
Source::Compute,
version + VERSION + Version::ZERO,
indexes,
VecBuilderOptions::default().add_last(),
)?,
indexes_to_hash_rate_1y_sma: ComputedVecsFromDateIndex::forced_import(
&db,
"hash_rate_1y_sma",
Source::Compute,
version + VERSION + Version::ZERO,
indexes,
VecBuilderOptions::default().add_last(),
)?,
indexes_to_difficulty_as_hash: ComputedVecsFromDateIndex::forced_import(
&db,
"difficulty_as_hash",
Source::Compute,
version + VERSION + Version::ZERO,
indexes,
VecBuilderOptions::default().add_last(),
)?,
txindex_to_is_coinbase,
inputindex_to_value,
// indexes_to_input_value,
@@ -584,7 +799,7 @@ impl Vecs {
txindex_to_input_value,
txindex_to_output_value,
txindex_to_fee,
txindex_to_feerate,
txindex_to_fee_rate,
txindex_to_vsize,
txindex_to_weight,
@@ -613,6 +828,167 @@ impl Vecs {
price: Option<&price::Vecs>,
exit: &Exit,
) -> Result<()> {
self.timeindexes_to_timestamp.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|vec, _, indexes, starting_indexes, exit| {
vec.compute_transform(
starting_indexes.dateindex,
&indexes.dateindex_to_date,
|(di, d, ..)| (di, Timestamp::from(d)),
exit,
)?;
Ok(())
},
)?;
self.indexes_to_block_count.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|v, indexer, _, starting_indexes, exit| {
v.compute_range(
starting_indexes.height,
&indexer.vecs.height_to_weight,
|h| (h, StoredU32::from(1_u32)),
exit,
)?;
Ok(())
},
)?;
let mut height_to_timestamp_iter = indexer.vecs.height_to_timestamp.iter();
self.height_to_interval.compute_transform(
starting_indexes.height,
&indexer.vecs.height_to_timestamp,
|(height, timestamp, ..)| {
let interval = height.decremented().map_or(Timestamp::ZERO, |prev_h| {
let prev_timestamp = height_to_timestamp_iter.unwrap_get_inner(prev_h);
timestamp
.checked_sub(prev_timestamp)
.unwrap_or(Timestamp::ZERO)
});
(height, interval)
},
exit,
)?;
self.indexes_to_block_interval.compute_rest(
indexes,
starting_indexes,
exit,
Some(&self.height_to_interval),
)?;
self.indexes_to_block_weight.compute_rest(
indexes,
starting_indexes,
exit,
Some(&indexer.vecs.height_to_weight),
)?;
self.indexes_to_block_size.compute_rest(
indexes,
starting_indexes,
exit,
Some(&indexer.vecs.height_to_total_size),
)?;
self.height_to_vbytes.compute_transform(
starting_indexes.height,
&indexer.vecs.height_to_weight,
|(h, w, ..)| {
(
h,
StoredU64::from(bitcoin::Weight::from(w).to_vbytes_floor()),
)
},
exit,
)?;
self.indexes_to_block_vbytes.compute_rest(
indexes,
starting_indexes,
exit,
Some(&self.height_to_vbytes),
)?;
let mut height_to_timestamp_iter = indexer.vecs.height_to_timestamp.iter();
self.difficultyepoch_to_timestamp.compute_transform(
starting_indexes.difficultyepoch,
&indexes.difficultyepoch_to_first_height,
|(i, h, ..)| (i, height_to_timestamp_iter.unwrap_get_inner(h)),
exit,
)?;
self.halvingepoch_to_timestamp.compute_transform(
starting_indexes.halvingepoch,
&indexes.halvingepoch_to_first_height,
|(i, h, ..)| (i, height_to_timestamp_iter.unwrap_get_inner(h)),
exit,
)?;
let mut height_to_difficultyepoch_iter = indexes.height_to_difficultyepoch.into_iter();
self.indexes_to_difficultyepoch.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|vec, _, indexes, starting_indexes, exit| {
let mut height_count_iter = indexes.dateindex_to_height_count.into_iter();
vec.compute_transform(
starting_indexes.dateindex,
&indexes.dateindex_to_first_height,
|(di, height, ..)| {
(
di,
height_to_difficultyepoch_iter.unwrap_get_inner(
height + (*height_count_iter.unwrap_get_inner(di) - 1),
),
)
},
exit,
)?;
Ok(())
},
)?;
let mut height_to_halvingepoch_iter = indexes.height_to_halvingepoch.into_iter();
self.indexes_to_halvingepoch.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|vec, _, indexes, starting_indexes, exit| {
let mut height_count_iter = indexes.dateindex_to_height_count.into_iter();
vec.compute_transform(
starting_indexes.dateindex,
&indexes.dateindex_to_first_height,
|(di, height, ..)| {
(
di,
height_to_halvingepoch_iter.unwrap_get_inner(
height + (*height_count_iter.unwrap_get_inner(di) - 1),
),
)
},
exit,
)?;
Ok(())
},
)?;
self.indexes_to_difficulty.compute_rest(
indexes,
starting_indexes,
exit,
Some(&indexer.vecs.height_to_difficulty),
)?;
self.indexes_to_tx_count.compute_all(
indexer,
indexes,
@@ -722,11 +1098,11 @@ impl Vecs {
exit,
)?;
self.txindex_to_feerate.compute_transform2(
self.txindex_to_fee_rate.compute_transform2(
starting_indexes.txindex,
&self.txindex_to_fee,
&self.txindex_to_vsize,
|(txindex, fee, vsize, ..)| (txindex, Feerate::from((fee, vsize))),
|(txindex, fee, vsize, ..)| (txindex, FeeRate::from((fee, vsize))),
exit,
)?;
@@ -739,12 +1115,12 @@ impl Vecs {
price,
)?;
self.indexes_to_feerate.compute_rest(
self.indexes_to_fee_rate.compute_rest(
indexer,
indexes,
starting_indexes,
exit,
Some(&self.txindex_to_feerate),
Some(&self.txindex_to_fee_rate),
)?;
self.indexes_to_tx_weight.compute_rest(
@@ -1085,25 +1461,241 @@ impl Vecs {
},
)?;
self.dateindex_to_fee_dominance.compute_transform2(
starting_indexes.dateindex,
self.indexes_to_fee.sats.dateindex.unwrap_sum(),
self.indexes_to_coinbase.sats.dateindex.unwrap_sum(),
|(i, fee, coinbase, ..)| {
(
i,
StoredF32::from(u64::from(fee) as f64 / u64::from(coinbase) as f64 * 100.0),
)
},
exit,
)?;
self.dateindex_to_subsidy_dominance.compute_transform2(
starting_indexes.dateindex,
self.indexes_to_subsidy.sats.dateindex.unwrap_sum(),
self.indexes_to_coinbase.sats.dateindex.unwrap_sum(),
|(i, subsidy, coinbase, ..)| {
(
i,
StoredF32::from(u64::from(subsidy) as f64 / u64::from(coinbase) as f64 * 100.0),
)
},
exit,
)?;
self.indexes_to_difficulty_as_hash.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
let multiplier = 2.0_f64.powi(32) / 600.0;
v.compute_transform(
starting_indexes.dateindex,
self.indexes_to_difficulty.dateindex.unwrap_last(),
|(i, v, ..)| (i, StoredF32::from(*v * multiplier)),
exit,
)?;
Ok(())
},
)?;
let now = Timestamp::now();
let today = Date::from(now);
self.indexes_to_hash_rate.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
v.compute_transform3(
starting_indexes.dateindex,
self.indexes_to_block_count.dateindex.unwrap_sum(),
self.indexes_to_difficulty_as_hash
.dateindex
.as_ref()
.unwrap(),
&indexes.dateindex_to_date,
|(i, block_count_sum, difficulty_as_hash, date, ..)| {
let target_multiplier = if date == today {
now.day_completion()
} else {
1.0
};
(
i,
StoredF64::from(
(f64::from(block_count_sum)
/ (target_multiplier * TARGET_BLOCKS_PER_DAY))
* f64::from(difficulty_as_hash),
),
)
},
exit,
)?;
Ok(())
},
)?;
self.indexes_to_hash_rate_1w_sma.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
v.compute_sma(
starting_indexes.dateindex,
self.indexes_to_hash_rate.dateindex.as_ref().unwrap(),
7,
exit,
)?;
Ok(())
},
)?;
self.indexes_to_hash_rate_1m_sma.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
v.compute_sma(
starting_indexes.dateindex,
self.indexes_to_hash_rate.dateindex.as_ref().unwrap(),
30,
exit,
)?;
Ok(())
},
)?;
self.indexes_to_hash_rate_2m_sma.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
v.compute_sma(
starting_indexes.dateindex,
self.indexes_to_hash_rate.dateindex.as_ref().unwrap(),
2 * 30,
exit,
)?;
Ok(())
},
)?;
self.indexes_to_hash_rate_1y_sma.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
v.compute_sma(
starting_indexes.dateindex,
self.indexes_to_hash_rate.dateindex.as_ref().unwrap(),
365,
exit,
)?;
Ok(())
},
)?;
if self.indexes_to_subsidy_usd_1y_sma.is_some() {
let date_to_coinbase_usd_sum = self
.indexes_to_coinbase
.dollars
.as_ref()
.unwrap()
.dateindex
.unwrap_sum();
self.indexes_to_subsidy_usd_1y_sma
.as_mut()
.unwrap()
.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
v.compute_sma(
starting_indexes.dateindex,
date_to_coinbase_usd_sum,
365,
exit,
)?;
Ok(())
},
)?;
self.indexes_to_puell_multiple
.as_mut()
.unwrap()
.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
v.compute_divide(
starting_indexes.dateindex,
date_to_coinbase_usd_sum,
self.indexes_to_subsidy_usd_1y_sma
.as_ref()
.unwrap()
.dateindex
.as_ref()
.unwrap(),
exit,
)?;
Ok(())
},
)?;
}
Ok(())
}
pub fn vecs(&self) -> Vec<&dyn AnyCollectableVec> {
[
vec![
&self.inputindex_to_value as &dyn AnyCollectableVec,
&self.height_to_interval as &dyn AnyCollectableVec,
&self.height_to_vbytes,
&self.difficultyepoch_to_timestamp,
&self.halvingepoch_to_timestamp,
&self.inputindex_to_value,
&self.txindex_to_fee,
&self.txindex_to_feerate,
&self.txindex_to_fee_rate,
&self.txindex_to_input_value,
&self.txindex_to_is_coinbase,
&self.txindex_to_output_value,
&self.txindex_to_vsize,
&self.txindex_to_weight,
&self.dateindex_to_fee_dominance,
&self.dateindex_to_subsidy_dominance,
],
self.indexes_to_hash_rate.vecs(),
self.indexes_to_hash_rate_1w_sma.vecs(),
self.indexes_to_hash_rate_1m_sma.vecs(),
self.indexes_to_hash_rate_2m_sma.vecs(),
self.indexes_to_hash_rate_1y_sma.vecs(),
self.timeindexes_to_timestamp.vecs(),
self.indexes_to_block_count.vecs(),
self.indexes_to_block_interval.vecs(),
self.indexes_to_block_size.vecs(),
self.indexes_to_block_vbytes.vecs(),
self.indexes_to_block_weight.vecs(),
self.indexes_to_difficulty.vecs(),
self.indexes_to_difficultyepoch.vecs(),
self.indexes_to_halvingepoch.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_fee_rate.vecs(),
self.indexes_to_input_count.vecs(),
self.indexes_to_opreturn_count.vecs(),
self.indexes_to_output_count.vecs(),
@@ -1111,6 +1703,7 @@ impl Vecs {
self.indexes_to_p2ms_count.vecs(),
self.indexes_to_p2pk33_count.vecs(),
self.indexes_to_p2pk65_count.vecs(),
self.indexes_to_difficulty_as_hash.vecs(),
self.indexes_to_p2pkh_count.vecs(),
self.indexes_to_p2sh_count.vecs(),
self.indexes_to_p2tr_count.vecs(),
@@ -1126,6 +1719,12 @@ impl Vecs {
self.indexes_to_unknownoutput_count.vecs(),
self.indexes_to_exact_utxo_count.vecs(),
self.indexes_to_unclaimed_rewards.vecs(),
self.indexes_to_subsidy_usd_1y_sma
.as_ref()
.map_or(vec![], |v| v.vecs()),
self.indexes_to_puell_multiple
.as_ref()
.map_or(vec![], |v| v.vecs()),
]
.into_iter()
.flatten()

View File

@@ -6,12 +6,12 @@ use brk_structs::{Bitcoin, CheckedSub, Dollars, StoredF64, Version};
use vecdb::{AnyCollectableVec, Database, Exit, PAGE_SIZE, VecIterator};
use super::{
Indexes,
Indexes, chain,
grouped::{
ComputedRatioVecsFromDateIndex, ComputedValueVecsFromHeight, ComputedVecsFromHeight,
Source, VecBuilderOptions,
},
indexes, price, stateful, transactions,
indexes, price, stateful,
};
const VERSION: Version = Version::ZERO;
@@ -257,7 +257,7 @@ impl Vecs {
indexes: &indexes::Vecs,
starting_indexes: &Indexes,
price: Option<&price::Vecs>,
transactions: &transactions::Vecs,
chain: &chain::Vecs,
stateful: &stateful::Vecs,
exit: &Exit,
) -> Result<()> {
@@ -266,7 +266,7 @@ impl Vecs {
indexes,
starting_indexes,
price,
transactions,
chain,
stateful,
exit,
)?;
@@ -281,7 +281,7 @@ impl Vecs {
indexes: &indexes::Vecs,
starting_indexes: &Indexes,
price: Option<&price::Vecs>,
transactions: &transactions::Vecs,
chain: &chain::Vecs,
stateful: &stateful::Vecs,
exit: &Exit,
) -> Result<()> {
@@ -446,7 +446,7 @@ impl Vecs {
|vec, _, _, starting_indexes, exit| {
vec.compute_transform(
starting_indexes.height,
transactions
chain
.indexes_to_subsidy
.dollars
.as_ref()

View File

@@ -19,11 +19,11 @@ where
pub average: Option<Box<EagerVec<I, T>>>,
pub sum: Option<Box<EagerVec<I, T>>>,
pub max: Option<Box<EagerVec<I, T>>>,
pub _90p: Option<Box<EagerVec<I, T>>>,
pub _75p: Option<Box<EagerVec<I, T>>>,
pub p90: Option<Box<EagerVec<I, T>>>,
pub p75: Option<Box<EagerVec<I, T>>>,
pub median: Option<Box<EagerVec<I, T>>>,
pub _25p: Option<Box<EagerVec<I, T>>>,
pub _10p: Option<Box<EagerVec<I, T>>>,
pub p25: Option<Box<EagerVec<I, T>>>,
pub p10: Option<Box<EagerVec<I, T>>>,
pub min: Option<Box<EagerVec<I, T>>>,
pub last: Option<Box<EagerVec<I, T>>>,
pub cumulative: Option<Box<EagerVec<I, T>>>,
@@ -118,7 +118,7 @@ where
Box::new(
EagerVec::forced_import(
db,
&maybe_suffix("average"),
&maybe_suffix("avg"),
version + VERSION + Version::ZERO,
format,
)
@@ -144,51 +144,51 @@ where
Box::new(
EagerVec::forced_import(
db,
&suffix("cumulative"),
&suffix("cum"),
version + VERSION + Version::ZERO,
format,
)
.unwrap(),
)
}),
_90p: options._90p.then(|| {
p90: options.p90.then(|| {
Box::new(
EagerVec::forced_import(
db,
&maybe_suffix("90p"),
&maybe_suffix("p90"),
version + VERSION + Version::ZERO,
format,
)
.unwrap(),
)
}),
_75p: options._75p.then(|| {
p75: options.p75.then(|| {
Box::new(
EagerVec::forced_import(
db,
&maybe_suffix("75p"),
&maybe_suffix("p75"),
version + VERSION + Version::ZERO,
format,
)
.unwrap(),
)
}),
_25p: options._25p.then(|| {
p25: options.p25.then(|| {
Box::new(
EagerVec::forced_import(
db,
&maybe_suffix("25p"),
&maybe_suffix("p25"),
version + VERSION + Version::ZERO,
format,
)
.unwrap(),
)
}),
_10p: options._10p.then(|| {
p10: options.p10.then(|| {
Box::new(
EagerVec::forced_import(
db,
&maybe_suffix("10p"),
&maybe_suffix("p10"),
version + VERSION + Version::ZERO,
format,
)
@@ -292,11 +292,11 @@ where
let needs_average_sum_or_cumulative =
needs_sum_or_cumulative || self.average.is_some();
let needs_sorted = self.max.is_some()
|| self._90p.is_some()
|| self._75p.is_some()
|| self.p90.is_some()
|| self.p75.is_some()
|| self.median.is_some()
|| self._25p.is_some()
|| self._10p.is_some()
|| self.p25.is_some()
|| self.p10.is_some()
|| self.min.is_some();
let needs_values = needs_sorted || needs_average_sum_or_cumulative;
@@ -333,24 +333,24 @@ where
)?;
}
if let Some(_90p) = self._90p.as_mut() {
_90p.forced_push_at(index, get_percentile(&values, 0.90), exit)?;
if let Some(p90) = self.p90.as_mut() {
p90.forced_push_at(index, get_percentile(&values, 0.90), exit)?;
}
if let Some(_75p) = self._75p.as_mut() {
_75p.forced_push_at(index, get_percentile(&values, 0.75), exit)?;
if let Some(p75) = self.p75.as_mut() {
p75.forced_push_at(index, get_percentile(&values, 0.75), exit)?;
}
if let Some(median) = self.median.as_mut() {
median.forced_push_at(index, get_percentile(&values, 0.50), exit)?;
}
if let Some(_25p) = self._25p.as_mut() {
_25p.forced_push_at(index, get_percentile(&values, 0.25), exit)?;
if let Some(p25) = self.p25.as_mut() {
p25.forced_push_at(index, get_percentile(&values, 0.25), exit)?;
}
if let Some(_10p) = self._10p.as_mut() {
_10p.forced_push_at(index, get_percentile(&values, 0.10), exit)?;
if let Some(p10) = self.p10.as_mut() {
p10.forced_push_at(index, get_percentile(&values, 0.10), exit)?;
}
if let Some(min) = self.min.as_mut() {
@@ -401,11 +401,11 @@ where
where
I2: StoredIndex + StoredRaw + CheckedSub<I2>,
{
if self._90p.is_some()
|| self._75p.is_some()
if self.p90.is_some()
|| self.p75.is_some()
|| self.median.is_some()
|| self._25p.is_some()
|| self._10p.is_some()
|| self.p25.is_some()
|| self.p10.is_some()
{
panic!("unsupported");
}
@@ -558,24 +558,24 @@ where
self.max.as_ref().unwrap()
}
#[allow(unused)]
pub fn unwrap_90p(&self) -> &EagerVec<I, T> {
self._90p.as_ref().unwrap()
pub fn unwrap_p90(&self) -> &EagerVec<I, T> {
self.p90.as_ref().unwrap()
}
#[allow(unused)]
pub fn unwrap_75p(&self) -> &EagerVec<I, T> {
self._75p.as_ref().unwrap()
pub fn unwrap_p75(&self) -> &EagerVec<I, T> {
self.p75.as_ref().unwrap()
}
#[allow(unused)]
pub fn unwrap_median(&self) -> &EagerVec<I, T> {
self.median.as_ref().unwrap()
}
#[allow(unused)]
pub fn unwrap_25p(&self) -> &EagerVec<I, T> {
self._25p.as_ref().unwrap()
pub fn unwrap_p25(&self) -> &EagerVec<I, T> {
self.p25.as_ref().unwrap()
}
#[allow(unused)]
pub fn unwrap_10p(&self) -> &EagerVec<I, T> {
self._10p.as_ref().unwrap()
pub fn unwrap_p10(&self) -> &EagerVec<I, T> {
self.p10.as_ref().unwrap()
}
pub fn unwrap_min(&self) -> &EagerVec<I, T> {
self.min.as_ref().unwrap()
@@ -615,17 +615,17 @@ where
if let Some(cumulative) = self.cumulative.as_ref() {
v.push(cumulative.as_ref());
}
if let Some(_90p) = self._90p.as_ref() {
v.push(_90p.as_ref());
if let Some(p90) = self.p90.as_ref() {
v.push(p90.as_ref());
}
if let Some(_75p) = self._75p.as_ref() {
v.push(_75p.as_ref());
if let Some(p75) = self.p75.as_ref() {
v.push(p75.as_ref());
}
if let Some(_25p) = self._25p.as_ref() {
v.push(_25p.as_ref());
if let Some(p25) = self.p25.as_ref() {
v.push(p25.as_ref());
}
if let Some(_10p) = self._10p.as_ref() {
v.push(_10p.as_ref());
if let Some(p10) = self.p10.as_ref() {
v.push(p10.as_ref());
}
v
@@ -656,17 +656,17 @@ where
if let Some(cumulative) = self.cumulative.as_mut() {
cumulative.safe_flush(exit)?;
}
if let Some(_90p) = self._90p.as_mut() {
_90p.safe_flush(exit)?;
if let Some(p90) = self.p90.as_mut() {
p90.safe_flush(exit)?;
}
if let Some(_75p) = self._75p.as_mut() {
_75p.safe_flush(exit)?;
if let Some(p75) = self.p75.as_mut() {
p75.safe_flush(exit)?;
}
if let Some(_25p) = self._25p.as_mut() {
_25p.safe_flush(exit)?;
if let Some(p25) = self.p25.as_mut() {
p25.safe_flush(exit)?;
}
if let Some(_10p) = self._10p.as_mut() {
_10p.safe_flush(exit)?;
if let Some(p10) = self.p10.as_mut() {
p10.safe_flush(exit)?;
}
Ok(())
@@ -697,17 +697,17 @@ where
if let Some(cumulative) = self.cumulative.as_mut() {
cumulative.validate_computed_version_or_reset(Version::ZERO + version)?;
}
if let Some(_90p) = self._90p.as_mut() {
_90p.validate_computed_version_or_reset(Version::ZERO + version)?;
if let Some(p90) = self.p90.as_mut() {
p90.validate_computed_version_or_reset(Version::ZERO + version)?;
}
if let Some(_75p) = self._75p.as_mut() {
_75p.validate_computed_version_or_reset(Version::ZERO + version)?;
if let Some(p75) = self.p75.as_mut() {
p75.validate_computed_version_or_reset(Version::ZERO + version)?;
}
if let Some(_25p) = self._25p.as_mut() {
_25p.validate_computed_version_or_reset(Version::ZERO + version)?;
if let Some(p25) = self.p25.as_mut() {
p25.validate_computed_version_or_reset(Version::ZERO + version)?;
}
if let Some(_10p) = self._10p.as_mut() {
_10p.validate_computed_version_or_reset(Version::ZERO + version)?;
if let Some(p10) = self.p10.as_mut() {
p10.validate_computed_version_or_reset(Version::ZERO + version)?;
}
Ok(())
@@ -719,11 +719,11 @@ pub struct VecBuilderOptions {
average: bool,
sum: bool,
max: bool,
_90p: bool,
_75p: bool,
p90: bool,
p75: bool,
median: bool,
_25p: bool,
_10p: bool,
p25: bool,
p10: bool,
min: bool,
first: bool,
last: bool,
@@ -743,24 +743,24 @@ impl VecBuilderOptions {
self.max
}
pub fn _90p(&self) -> bool {
self._90p
pub fn p90(&self) -> bool {
self.p90
}
pub fn _75p(&self) -> bool {
self._75p
pub fn p75(&self) -> bool {
self.p75
}
pub fn median(&self) -> bool {
self.median
}
pub fn _25p(&self) -> bool {
self._25p
pub fn p25(&self) -> bool {
self.p25
}
pub fn _10p(&self) -> bool {
self._10p
pub fn p10(&self) -> bool {
self.p10
}
pub fn min(&self) -> bool {
@@ -816,26 +816,26 @@ impl VecBuilderOptions {
}
#[allow(unused)]
pub fn add_90p(mut self) -> Self {
self._90p = true;
pub fn add_p90(mut self) -> Self {
self.p90 = true;
self
}
#[allow(unused)]
pub fn add_75p(mut self) -> Self {
self._75p = true;
pub fn add_p75(mut self) -> Self {
self.p75 = true;
self
}
#[allow(unused)]
pub fn add_25p(mut self) -> Self {
self._25p = true;
pub fn add_p25(mut self) -> Self {
self.p25 = true;
self
}
#[allow(unused)]
pub fn add_10p(mut self) -> Self {
self._10p = true;
pub fn add_p10(mut self) -> Self {
self.p10 = true;
self
}
@@ -875,26 +875,26 @@ impl VecBuilderOptions {
}
#[allow(unused)]
pub fn rm_90p(mut self) -> Self {
self._90p = false;
pub fn rm_p90(mut self) -> Self {
self.p90 = false;
self
}
#[allow(unused)]
pub fn rm_75p(mut self) -> Self {
self._75p = false;
pub fn rm_p75(mut self) -> Self {
self.p75 = false;
self
}
#[allow(unused)]
pub fn rm_25p(mut self) -> Self {
self._25p = false;
pub fn rm_p25(mut self) -> Self {
self.p25 = false;
self
}
#[allow(unused)]
pub fn rm_10p(mut self) -> Self {
self._10p = false;
pub fn rm_p10(mut self) -> Self {
self.p10 = false;
self
}
@@ -911,20 +911,20 @@ impl VecBuilderOptions {
}
pub fn add_percentiles(mut self) -> Self {
self._90p = true;
self._75p = true;
self.p90 = true;
self.p75 = true;
self.median = true;
self._25p = true;
self._10p = true;
self.p25 = true;
self.p10 = true;
self
}
pub fn remove_percentiles(mut self) -> Self {
self._90p = false;
self._75p = false;
self.p90 = false;
self.p75 = false;
self.median = false;
self._25p = false;
self._10p = false;
self.p25 = false;
self.p10 = false;
self
}
@@ -933,11 +933,11 @@ impl VecBuilderOptions {
self.average,
self.sum,
self.max,
self._90p,
self._75p,
self.p90,
self.p75,
self.median,
self._25p,
self._10p,
self.p25,
self.p10,
self.min,
self.first,
self.last,

View File

@@ -142,7 +142,7 @@ where
}),
average: options.average.then(|| {
Box::new(LazyVecFrom2::init(
&maybe_suffix("average"),
&maybe_suffix("avg"),
version + VERSION + Version::ZERO,
source_extra
.average
@@ -197,7 +197,7 @@ where
}),
cumulative: options.cumulative.then(|| {
Box::new(LazyVecFrom2::init(
&suffix("cumulative"),
&suffix("cum"),
version + VERSION + Version::ZERO,
source_extra.cumulative.as_ref().unwrap().boxed_clone(),
len_source.clone(),

View File

@@ -319,24 +319,24 @@ impl ComputedVecsFromTxindex<Bitcoin> {
exit,
)?;
}
if let Some(_90p) = self.height._90p.as_mut() {
if let Some(_90p) = self.height.p90.as_mut() {
_90p.forced_push_at(
height,
Bitcoin::from(
sats.height
.unwrap_90p()
.unwrap_p90()
.into_iter()
.unwrap_get_inner(height),
),
exit,
)?;
}
if let Some(_75p) = self.height._75p.as_mut() {
if let Some(_75p) = self.height.p75.as_mut() {
_75p.forced_push_at(
height,
Bitcoin::from(
sats.height
.unwrap_75p()
.unwrap_p75()
.into_iter()
.unwrap_get_inner(height),
),
@@ -355,24 +355,24 @@ impl ComputedVecsFromTxindex<Bitcoin> {
exit,
)?;
}
if let Some(_25p) = self.height._25p.as_mut() {
if let Some(_25p) = self.height.p25.as_mut() {
_25p.forced_push_at(
height,
Bitcoin::from(
sats.height
.unwrap_25p()
.unwrap_p25()
.into_iter()
.unwrap_get_inner(height),
),
exit,
)?;
}
if let Some(_10p) = self.height._10p.as_mut() {
if let Some(_10p) = self.height.p10.as_mut() {
_10p.forced_push_at(
height,
Bitcoin::from(
sats.height
.unwrap_10p()
.unwrap_p10()
.into_iter()
.unwrap_get_inner(height),
),
@@ -502,25 +502,25 @@ impl ComputedVecsFromTxindex<Dollars> {
exit,
)?;
}
if let Some(_90p) = self.height._90p.as_mut() {
if let Some(_90p) = self.height.p90.as_mut() {
_90p.forced_push_at(
height,
price
* bitcoin
.height
.unwrap_90p()
.unwrap_p90()
.into_iter()
.unwrap_get_inner(height),
exit,
)?;
}
if let Some(_75p) = self.height._75p.as_mut() {
if let Some(_75p) = self.height.p75.as_mut() {
_75p.forced_push_at(
height,
price
* bitcoin
.height
.unwrap_75p()
.unwrap_p75()
.into_iter()
.unwrap_get_inner(height),
exit,
@@ -538,25 +538,25 @@ impl ComputedVecsFromTxindex<Dollars> {
exit,
)?;
}
if let Some(_25p) = self.height._25p.as_mut() {
if let Some(_25p) = self.height.p25.as_mut() {
_25p.forced_push_at(
height,
price
* bitcoin
.height
.unwrap_25p()
.unwrap_p25()
.into_iter()
.unwrap_get_inner(height),
exit,
)?;
}
if let Some(_10p) = self.height._10p.as_mut() {
if let Some(_10p) = self.height.p10.as_mut() {
_10p.forced_push_at(
height,
price
* bitcoin
.height
.unwrap_10p()
.unwrap_p10()
.into_iter()
.unwrap_get_inner(height),
exit,

View File

@@ -1,6 +1,6 @@
#![doc = include_str!("../README.md")]
use std::path::Path;
use std::{path::Path, thread};
use brk_error::Result;
use brk_fetcher::Fetcher;
@@ -9,19 +9,17 @@ use brk_structs::Version;
use log::info;
use vecdb::{AnyCollectableVec, Exit, Format};
mod blocks;
mod chain;
mod cointime;
mod constants;
mod fetched;
mod grouped;
mod indexes;
mod market;
mod mining;
mod price;
mod stateful;
mod states;
mod traits;
mod transactions;
mod utils;
use indexes::Indexes;
@@ -33,11 +31,9 @@ use states::*;
pub struct Computer {
pub indexes: indexes::Vecs,
pub constants: constants::Vecs,
pub blocks: blocks::Vecs,
pub mining: mining::Vecs,
pub market: market::Vecs,
pub price: Option<price::Vecs>,
pub transactions: transactions::Vecs,
pub chain: chain::Vecs,
pub stateful: stateful::Vecs,
pub fetched: Option<fetched::Vecs>,
pub cointime: cointime::Vecs,
@@ -68,8 +64,6 @@ impl Computer {
});
Ok(Self {
blocks: blocks::Vecs::forced_import(&computed_path, VERSION + Version::ZERO, &indexes)?,
mining: mining::Vecs::forced_import(&computed_path, VERSION + Version::ZERO, &indexes)?,
constants: constants::Vecs::forced_import(
&computed_path,
VERSION + Version::ZERO,
@@ -83,7 +77,7 @@ impl Computer {
&indexes,
price.as_ref(),
)?,
transactions: transactions::Vecs::forced_import(
chain: chain::Vecs::forced_import(
&computed_path,
VERSION + Version::ZERO,
indexer,
@@ -115,14 +109,6 @@ impl Computer {
self.constants
.compute(indexer, &self.indexes, &starting_indexes, exit)?;
info!("Computing blocks...");
self.blocks
.compute(indexer, &self.indexes, &starting_indexes, exit)?;
info!("Computing mining...");
self.mining
.compute(indexer, &self.indexes, &starting_indexes, exit)?;
if let Some(fetched) = self.fetched.as_mut() {
info!("Computing fetched...");
fetched.compute(indexer, &self.indexes, &starting_indexes, exit)?;
@@ -137,44 +123,49 @@ impl Computer {
)?;
}
info!("Computing transactions...");
self.transactions.compute(
indexer,
&self.indexes,
&starting_indexes,
self.price.as_ref(),
exit,
)?;
thread::scope(|scope| -> Result<()> {
let chain = scope.spawn(|| {
info!("Computing chain...");
self.chain.compute(
indexer,
&self.indexes,
&starting_indexes,
self.price.as_ref(),
exit,
)
});
if let Some(price) = self.price.as_ref() {
info!("Computing market...");
self.market.compute(
indexer,
&self.indexes,
price,
&mut self.transactions,
&starting_indexes,
exit,
)?;
}
let market = scope.spawn(|| -> Result<()> {
if let Some(price) = self.price.as_ref() {
info!("Computing market...");
self.market
.compute(indexer, &self.indexes, price, &starting_indexes, exit)?;
}
Ok(())
});
chain.join().unwrap()?;
market.join().unwrap()?;
Ok(())
})?;
info!("Computing stateful...");
self.stateful.compute(
indexer,
&self.indexes,
&self.transactions,
&self.chain,
self.price.as_ref(),
&self.market,
&mut starting_indexes,
exit,
)?;
info!("Computing cointime...");
self.cointime.compute(
indexer,
&self.indexes,
&starting_indexes,
self.price.as_ref(),
&self.transactions,
&self.chain,
&self.stateful,
exit,
)?;
@@ -186,10 +177,8 @@ impl Computer {
[
self.constants.vecs(),
self.indexes.vecs(),
self.blocks.vecs(),
self.mining.vecs(),
self.market.vecs(),
self.transactions.vecs(),
self.chain.vecs(),
self.stateful.vecs(),
self.cointime.vecs(),
self.fetched.as_ref().map_or(vec![], |v| v.vecs()),

View File

@@ -14,7 +14,7 @@ use crate::{
use super::{
Indexes,
grouped::{ComputedRatioVecsFromDateIndex, ComputedVecsFromDateIndex, VecBuilderOptions},
indexes, transactions,
indexes,
};
const VERSION: Version = Version::ZERO;
@@ -23,10 +23,8 @@ const VERSION: Version = Version::ZERO;
pub struct Vecs {
db: Database,
pub height_to_marketcap: EagerVec<Height, Dollars>,
pub height_to_ath: EagerVec<Height, Dollars>,
pub height_to_drawdown: EagerVec<Height, StoredF32>,
pub indexes_to_marketcap: ComputedVecsFromDateIndex<Dollars>,
pub indexes_to_ath: ComputedVecsFromDateIndex<Dollars>,
pub indexes_to_drawdown: ComputedVecsFromDateIndex<StoredF32>,
pub indexes_to_days_since_ath: ComputedVecsFromDateIndex<StoredU16>,
@@ -188,11 +186,6 @@ impl Vecs {
db.set_min_len(PAGE_SIZE * 1_000_000)?;
Ok(Self {
height_to_marketcap: EagerVec::forced_import_compressed(
&db,
"marketcap",
version + VERSION + Version::ZERO,
)?,
height_to_ath: EagerVec::forced_import_compressed(
&db,
"ath",
@@ -203,14 +196,6 @@ impl Vecs {
"drawdown",
version + VERSION + Version::ZERO,
)?,
indexes_to_marketcap: ComputedVecsFromDateIndex::forced_import(
&db,
"marketcap",
Source::Compute,
version + VERSION + Version::ZERO,
indexes,
VecBuilderOptions::default().add_last(),
)?,
indexes_to_ath: ComputedVecsFromDateIndex::forced_import(
&db,
"ath",
@@ -1381,18 +1366,10 @@ impl Vecs {
indexer: &Indexer,
indexes: &indexes::Vecs,
price: &price::Vecs,
transactions: &mut transactions::Vecs,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
self.compute_(
indexer,
indexes,
price,
transactions,
starting_indexes,
exit,
)?;
self.compute_(indexer, indexes, price, starting_indexes, exit)?;
self.db.flush_then_punch()?;
Ok(())
}
@@ -1402,20 +1379,9 @@ impl Vecs {
indexer: &Indexer,
indexes: &indexes::Vecs,
price: &price::Vecs,
transactions: &mut transactions::Vecs,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
self.height_to_marketcap.compute_multiply(
starting_indexes.height,
&price.chainindexes_to_close.height,
transactions
.indexes_to_subsidy
.bitcoin
.height_extra
.unwrap_cumulative(),
exit,
)?;
self.height_to_ath.compute_max(
starting_indexes.height,
&price.chainindexes_to_high.height,
@@ -1428,26 +1394,6 @@ impl Vecs {
exit,
)?;
self.indexes_to_marketcap.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
v.compute_multiply(
starting_indexes.dateindex,
price.timeindexes_to_close.dateindex.as_ref().unwrap(),
transactions
.indexes_to_subsidy
.bitcoin
.dateindex
.unwrap_cumulative(),
exit,
)?;
Ok(())
},
)?;
self.indexes_to_ath.compute_all(
indexer,
indexes,
@@ -2104,7 +2050,6 @@ impl Vecs {
pub fn vecs(&self) -> Vec<&dyn AnyCollectableVec> {
[
self.indexes_to_marketcap.vecs(),
self.indexes_to_ath.vecs(),
self.indexes_to_drawdown.vecs(),
self.indexes_to_days_since_ath.vecs(),
@@ -2249,11 +2194,7 @@ impl Vecs {
self.dca_class_2017_returns.vecs(),
self.dca_class_2016_returns.vecs(),
self.dca_class_2015_returns.vecs(),
vec![
&self.height_to_marketcap,
&self.height_to_ath,
&self.height_to_drawdown,
],
vec![&self.height_to_ath, &self.height_to_drawdown],
]
.into_iter()
.flatten()

View File

@@ -1,151 +0,0 @@
use std::path::Path;
use brk_error::Result;
use brk_indexer::Indexer;
use brk_structs::{DifficultyEpoch, HalvingEpoch, StoredF64, Version};
use vecdb::{AnyCollectableVec, Database, Exit, PAGE_SIZE, VecIterator};
use crate::grouped::Source;
use super::{
Indexes,
grouped::{ComputedVecsFromDateIndex, ComputedVecsFromHeight, VecBuilderOptions},
indexes,
};
const VERSION: Version = Version::ZERO;
#[derive(Clone)]
pub struct Vecs {
db: Database,
pub indexes_to_difficulty: ComputedVecsFromHeight<StoredF64>,
pub indexes_to_difficultyepoch: ComputedVecsFromDateIndex<DifficultyEpoch>,
pub indexes_to_halvingepoch: ComputedVecsFromDateIndex<HalvingEpoch>,
}
impl Vecs {
pub fn forced_import(parent: &Path, version: Version, indexes: &indexes::Vecs) -> Result<Self> {
let db = Database::open(&parent.join("mining"))?;
db.set_min_len(PAGE_SIZE * 1_000_000)?;
Ok(Self {
indexes_to_difficulty: ComputedVecsFromHeight::forced_import(
&db,
"difficulty",
Source::None,
version + VERSION + Version::ZERO,
indexes,
VecBuilderOptions::default().add_last(),
)?,
indexes_to_difficultyepoch: ComputedVecsFromDateIndex::forced_import(
&db,
"difficultyepoch",
Source::Compute,
version + VERSION + Version::ZERO,
indexes,
VecBuilderOptions::default().add_last(),
)?,
indexes_to_halvingepoch: ComputedVecsFromDateIndex::forced_import(
&db,
"halvingepoch",
Source::Compute,
version + VERSION + Version::ZERO,
indexes,
VecBuilderOptions::default().add_last(),
)?,
db,
})
}
pub fn compute(
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
self.compute_(indexer, indexes, starting_indexes, exit)?;
self.db.flush_then_punch()?;
Ok(())
}
fn compute_(
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
let mut height_to_difficultyepoch_iter = indexes.height_to_difficultyepoch.into_iter();
self.indexes_to_difficultyepoch.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|vec, _, indexes, starting_indexes, exit| {
let mut height_count_iter = indexes.dateindex_to_height_count.into_iter();
vec.compute_transform(
starting_indexes.dateindex,
&indexes.dateindex_to_first_height,
|(di, height, ..)| {
(
di,
height_to_difficultyepoch_iter.unwrap_get_inner(
height + (*height_count_iter.unwrap_get_inner(di) - 1),
),
)
},
exit,
)?;
Ok(())
},
)?;
let mut height_to_halvingepoch_iter = indexes.height_to_halvingepoch.into_iter();
self.indexes_to_halvingepoch.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|vec, _, indexes, starting_indexes, exit| {
let mut height_count_iter = indexes.dateindex_to_height_count.into_iter();
vec.compute_transform(
starting_indexes.dateindex,
&indexes.dateindex_to_first_height,
|(di, height, ..)| {
(
di,
height_to_halvingepoch_iter.unwrap_get_inner(
height + (*height_count_iter.unwrap_get_inner(di) - 1),
),
)
},
exit,
)?;
Ok(())
},
)?;
self.indexes_to_difficulty.compute_rest(
indexes,
starting_indexes,
exit,
Some(&indexer.vecs.height_to_difficulty),
)?;
Ok(())
}
pub fn vecs(&self) -> Vec<&dyn AnyCollectableVec> {
[
self.indexes_to_difficulty.vecs(),
self.indexes_to_difficultyepoch.vecs(),
self.indexes_to_halvingepoch.vecs(),
]
.into_iter()
.flatten()
.collect::<Vec<_>>()
}
}

View File

@@ -11,7 +11,7 @@ use vecdb::{
use crate::{
Indexes,
grouped::{ComputedVecsFromHeight, Source, VecBuilderOptions},
indexes, market, price,
indexes, price,
stateful::{
common,
r#trait::{CohortVecs, DynCohortVecs},
@@ -228,9 +228,10 @@ impl CohortVecs for Vecs {
indexes: &indexes::Vecs,
price: Option<&price::Vecs>,
starting_indexes: &Indexes,
market: &market::Vecs,
height_to_supply: &impl AnyIterableVec<Height, Bitcoin>,
dateindex_to_supply: &impl AnyIterableVec<DateIndex, Bitcoin>,
height_to_market_cap: Option<&impl AnyIterableVec<Height, Dollars>>,
dateindex_to_market_cap: Option<&impl AnyIterableVec<DateIndex, Dollars>>,
height_to_realized_cap: Option<&impl AnyIterableVec<Height, Dollars>>,
dateindex_to_realized_cap: Option<&impl AnyIterableVec<DateIndex, Dollars>>,
exit: &Exit,
@@ -240,9 +241,10 @@ impl CohortVecs for Vecs {
indexes,
price,
starting_indexes,
market,
height_to_supply,
dateindex_to_supply,
height_to_market_cap,
dateindex_to_market_cap,
height_to_realized_cap,
dateindex_to_realized_cap,
exit,

View File

@@ -10,7 +10,7 @@ use derive_deref::{Deref, DerefMut};
use vecdb::{AnyIterableVec, Database, Exit, Format};
use crate::{
Indexes, indexes, market, price,
Indexes, indexes, price,
stateful::{
address_cohort,
r#trait::{CohortVecs, DynCohortVecs},
@@ -520,9 +520,10 @@ impl Vecs {
indexes: &indexes::Vecs,
price: Option<&price::Vecs>,
starting_indexes: &Indexes,
market: &market::Vecs,
height_to_supply: &impl AnyIterableVec<Height, Bitcoin>,
dateindex_to_supply: &impl AnyIterableVec<DateIndex, Bitcoin>,
height_to_market_cap: Option<&impl AnyIterableVec<Height, Dollars>>,
dateindex_to_market_cap: Option<&impl AnyIterableVec<DateIndex, Dollars>>,
height_to_realized_cap: Option<&impl AnyIterableVec<Height, Dollars>>,
dateindex_to_realized_cap: Option<&impl AnyIterableVec<DateIndex, Dollars>>,
exit: &Exit,
@@ -534,9 +535,10 @@ impl Vecs {
indexes,
price,
starting_indexes,
market,
height_to_supply,
dateindex_to_supply,
height_to_market_cap,
dateindex_to_market_cap,
height_to_realized_cap,
dateindex_to_realized_cap,
exit,

View File

@@ -14,7 +14,7 @@ use crate::{
ComputedHeightValueVecs, ComputedRatioVecsFromDateIndex, ComputedValueVecsFromDateIndex,
ComputedVecsFromDateIndex, ComputedVecsFromHeight, Source, VecBuilderOptions,
},
indexes, market, price,
indexes, price,
states::CohortState,
};
@@ -2353,9 +2353,10 @@ impl Vecs {
indexes: &indexes::Vecs,
price: Option<&price::Vecs>,
starting_indexes: &Indexes,
market: &market::Vecs,
height_to_supply: &impl AnyIterableVec<Height, Bitcoin>,
dateindex_to_supply: &impl AnyIterableVec<DateIndex, Bitcoin>,
height_to_market_cap: Option<&impl AnyIterableVec<Height, Dollars>>,
dateindex_to_market_cap: Option<&impl AnyIterableVec<DateIndex, Dollars>>,
height_to_realized_cap: Option<&impl AnyIterableVec<Height, Dollars>>,
dateindex_to_realized_cap: Option<&impl AnyIterableVec<DateIndex, Dollars>>,
exit: &Exit,
@@ -2382,6 +2383,9 @@ impl Vecs {
}
if let Some(indexes_to_realized_cap) = self.indexes_to_realized_cap.as_mut() {
let height_to_market_cap = height_to_market_cap.unwrap();
let dateindex_to_market_cap = dateindex_to_market_cap.unwrap();
indexes_to_realized_cap.compute_rest(
indexes,
starting_indexes,
@@ -2780,7 +2784,7 @@ impl Vecs {
.compute_percentage(
starting_indexes.height,
self.height_to_unrealized_profit.as_ref().unwrap(),
&market.height_to_marketcap,
height_to_market_cap,
exit,
)?;
self.height_to_unrealized_loss_relative_to_market_cap
@@ -2789,7 +2793,7 @@ impl Vecs {
.compute_percentage(
starting_indexes.height,
self.height_to_unrealized_loss.as_ref().unwrap(),
&market.height_to_marketcap,
height_to_market_cap,
exit,
)?;
self.height_to_negative_unrealized_loss_relative_to_market_cap
@@ -2798,7 +2802,7 @@ impl Vecs {
.compute_percentage(
starting_indexes.height,
self.height_to_negative_unrealized_loss.as_ref().unwrap(),
&market.height_to_marketcap,
height_to_market_cap,
exit,
)?;
self.height_to_net_unrealized_profit_and_loss_relative_to_market_cap
@@ -2809,7 +2813,7 @@ impl Vecs {
self.height_to_net_unrealized_profit_and_loss
.as_ref()
.unwrap(),
&market.height_to_marketcap,
height_to_market_cap,
exit,
)?;
self.indexes_to_unrealized_profit_relative_to_market_cap
@@ -2824,7 +2828,7 @@ impl Vecs {
vec.compute_percentage(
starting_indexes.dateindex,
self.dateindex_to_unrealized_profit.as_ref().unwrap(),
market.indexes_to_marketcap.dateindex.as_ref().unwrap(),
dateindex_to_market_cap,
exit,
)?;
Ok(())
@@ -2842,7 +2846,7 @@ impl Vecs {
vec.compute_percentage(
starting_indexes.dateindex,
self.dateindex_to_unrealized_loss.as_ref().unwrap(),
market.indexes_to_marketcap.dateindex.as_ref().unwrap(),
dateindex_to_market_cap,
exit,
)?;
Ok(())
@@ -2865,7 +2869,7 @@ impl Vecs {
.dateindex
.as_ref()
.unwrap(),
market.indexes_to_marketcap.dateindex.as_ref().unwrap(),
dateindex_to_market_cap,
exit,
)?;
Ok(())
@@ -2888,7 +2892,7 @@ impl Vecs {
.dateindex
.as_ref()
.unwrap(),
market.indexes_to_marketcap.dateindex.as_ref().unwrap(),
dateindex_to_market_cap,
exit,
)?;
Ok(())
@@ -3442,7 +3446,7 @@ impl Vecs {
v.compute_percentage(
starting_indexes.dateindex,
self.indexes_to_net_realized_profit_and_loss_cumulative_30d_change.as_ref().unwrap().dateindex.as_ref().unwrap(),
market.indexes_to_marketcap.dateindex.as_ref().unwrap(),
dateindex_to_market_cap,
exit,
)?;
Ok(())

View File

@@ -18,15 +18,18 @@ use brk_structs::{
use log::info;
use rayon::prelude::*;
use vecdb::{
AnyCollectableVec, AnyStoredVec, AnyVec, CollectableVec, Database, EagerVec, Exit, Format,
GenericStoredVec, ImportOptions, PAGE_SIZE, RawVec, Reader, Stamp, StoredIndex, VecIterator,
AnyCloneableIterableVec, AnyCollectableVec, AnyStoredVec, AnyVec, CollectableVec, Database,
EagerVec, Exit, Format, GenericStoredVec, ImportOptions, LazyVecFrom1, PAGE_SIZE, RawVec,
Reader, Stamp, StoredIndex, VecIterator,
};
use crate::{
BlockState, Indexes, SupplyState, Transacted,
grouped::{ComputedValueVecsFromHeight, VecBuilderOptions},
grouped::{ComputedVecsFromHeight, Source},
indexes, market, price, transactions,
BlockState, Indexes, SupplyState, Transacted, chain,
grouped::{
ComputedValueVecsFromHeight, ComputedVecsFromDateIndex, ComputedVecsFromHeight, Source,
VecBuilderOptions,
},
indexes, price,
};
mod address_cohort;
@@ -82,6 +85,8 @@ pub struct Vecs {
pub indexes_to_opreturn_supply: ComputedValueVecsFromHeight,
pub indexes_to_address_count: ComputedVecsFromHeight<StoredU64>,
pub indexes_to_empty_address_count: ComputedVecsFromHeight<StoredU64>,
pub height_to_market_cap: Option<LazyVecFrom1<Height, Dollars, Height, Dollars>>,
pub indexes_to_market_cap: Option<ComputedVecsFromDateIndex<Dollars>>,
}
const SAVED_STAMPED_CHANGES: u16 = 10;
@@ -103,6 +108,9 @@ impl Vecs {
let compute_dollars = price.is_some();
let utxo_cohorts =
utxo_cohorts::Vecs::forced_import(&db, version, format, indexes, price, &states_path)?;
Ok(Self {
chain_state: RawVec::forced_import_with(
ImportOptions::new(&db, "chain", version + VERSION + Version::ZERO)
@@ -153,6 +161,37 @@ impl Vecs {
indexes,
VecBuilderOptions::default().add_last(),
)?,
height_to_market_cap: compute_dollars.then(|| {
LazyVecFrom1::init(
"market_cap",
version + VERSION + Version::ONE,
utxo_cohorts
.all
.1
.height_to_supply_value
.dollars
.as_ref()
.unwrap()
.boxed_clone(),
|height: Height, iter| {
iter.next_at(height.unwrap_to_usize()).map(|(_, value)| {
let d: Dollars = value.into_owned();
d
})
},
)
}),
indexes_to_market_cap: compute_dollars.then(|| {
ComputedVecsFromDateIndex::forced_import(
&db,
"market_cap",
Source::Compute,
version + VERSION + Version::TWO,
indexes,
VecBuilderOptions::default().add_last(),
)
.unwrap()
}),
addresstype_to_height_to_address_count: AddressTypeToHeightToAddressCount::from(
ByAddressType {
p2pk65: EagerVec::forced_import_compressed(
@@ -377,14 +416,7 @@ impl Vecs {
)?,
},
),
utxo_cohorts: utxo_cohorts::Vecs::forced_import(
&db,
version,
format,
indexes,
price,
&states_path,
)?,
utxo_cohorts,
address_cohorts: address_cohorts::Vecs::forced_import(
&db,
version,
@@ -445,22 +477,13 @@ impl Vecs {
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
transactions: &transactions::Vecs,
chain: &chain::Vecs,
price: Option<&price::Vecs>,
market: &market::Vecs,
// Must take ownership as its indexes will be updated for this specific function
starting_indexes: &mut Indexes,
exit: &Exit,
) -> Result<()> {
self.compute_(
indexer,
indexes,
transactions,
price,
market,
starting_indexes,
exit,
)?;
self.compute_(indexer, indexes, chain, price, starting_indexes, exit)?;
self.db.flush_then_punch()?;
Ok(())
}
@@ -470,9 +493,8 @@ impl Vecs {
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
transactions: &transactions::Vecs,
chain: &chain::Vecs,
price: Option<&price::Vecs>,
market: &market::Vecs,
// Must take ownership as its indexes will be updated for this specific function
starting_indexes: &mut Indexes,
exit: &Exit,
@@ -487,8 +509,8 @@ impl Vecs {
let height_to_first_p2traddressindex = &indexer.vecs.height_to_first_p2traddressindex;
let height_to_first_p2wpkhaddressindex = &indexer.vecs.height_to_first_p2wpkhaddressindex;
let height_to_first_p2wshaddressindex = &indexer.vecs.height_to_first_p2wshaddressindex;
let height_to_output_count = transactions.indexes_to_output_count.height.unwrap_sum();
let height_to_input_count = transactions.indexes_to_input_count.height.unwrap_sum();
let height_to_output_count = chain.indexes_to_output_count.height.unwrap_sum();
let height_to_input_count = chain.indexes_to_input_count.height.unwrap_sum();
let inputindex_to_outputindex = &indexer.vecs.inputindex_to_outputindex;
let outputindex_to_value = &indexer.vecs.outputindex_to_value;
let txindex_to_height = &indexes.txindex_to_height;
@@ -496,7 +518,7 @@ impl Vecs {
let outputindex_to_txindex = &indexes.outputindex_to_txindex;
let outputindex_to_outputtype = &indexer.vecs.outputindex_to_outputtype;
let outputindex_to_typeindex = &indexer.vecs.outputindex_to_typeindex;
let height_to_unclaimed_rewards = transactions
let height_to_unclaimed_rewards = chain
.indexes_to_unclaimed_rewards
.sats
.height
@@ -1331,6 +1353,33 @@ impl Vecs {
self.address_cohorts
.compute_rest_part1(indexer, indexes, price, starting_indexes, exit)?;
if let Some(indexes_to_market_cap) = self.indexes_to_market_cap.as_mut() {
indexes_to_market_cap.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
v.compute_transform(
starting_indexes.dateindex,
self.utxo_cohorts
.all
.1
.indexes_to_supply
.dollars
.as_ref()
.unwrap()
.dateindex
.as_ref()
.unwrap(),
|(i, v, ..)| (i, v),
exit,
)?;
Ok(())
},
)?;
}
info!("Computing rest part 2...");
let height_to_supply = &self
@@ -1348,6 +1397,11 @@ impl Vecs {
.bitcoin
.dateindex
.clone();
let height_to_market_cap = self.height_to_market_cap.clone();
let dateindex_to_market_cap = self
.indexes_to_market_cap
.as_ref()
.map(|v| v.dateindex.as_ref().unwrap().clone());
let height_to_realized_cap = self.utxo_cohorts.all.1.height_to_realized_cap.clone();
let dateindex_to_realized_cap = self
.utxo_cohorts
@@ -1357,6 +1411,8 @@ impl Vecs {
.as_ref()
.map(|v| v.dateindex.unwrap_last().clone());
let dateindex_to_supply_ref = dateindex_to_supply.as_ref().unwrap();
let height_to_market_cap_ref = height_to_market_cap.as_ref();
let dateindex_to_market_cap_ref = dateindex_to_market_cap.as_ref();
let height_to_realized_cap_ref = height_to_realized_cap.as_ref();
let dateindex_to_realized_cap_ref = dateindex_to_realized_cap.as_ref();
@@ -1365,9 +1421,10 @@ impl Vecs {
indexes,
price,
starting_indexes,
market,
height_to_supply,
dateindex_to_supply_ref,
height_to_market_cap_ref,
dateindex_to_market_cap_ref,
height_to_realized_cap_ref,
dateindex_to_realized_cap_ref,
exit,
@@ -1378,9 +1435,10 @@ impl Vecs {
indexes,
price,
starting_indexes,
market,
height_to_supply,
dateindex_to_supply_ref,
height_to_market_cap_ref,
dateindex_to_market_cap_ref,
height_to_realized_cap_ref,
dateindex_to_realized_cap_ref,
exit,
@@ -1790,6 +1848,9 @@ impl Vecs {
self.indexes_to_address_count.vecs(),
self.indexes_to_empty_address_count.vecs(),
self.addresstype_to_indexes_to_address_count.vecs(),
self.indexes_to_market_cap
.as_ref()
.map_or(vec![], |v| v.vecs()),
self.addresstype_to_indexes_to_empty_address_count.vecs(),
self.addresstype_to_height_to_address_count
.as_typed_vec()
@@ -1801,6 +1862,9 @@ impl Vecs {
.into_iter()
.map(|(_, v)| v as &dyn AnyCollectableVec)
.collect::<Vec<_>>(),
self.height_to_market_cap
.as_ref()
.map_or(vec![], |v| vec![v]),
vec![
&self.height_to_unspendable_supply,
&self.height_to_opreturn_supply,

View File

@@ -3,7 +3,7 @@ use brk_indexer::Indexer;
use brk_structs::{Bitcoin, DateIndex, Dollars, Height, Version};
use vecdb::{AnyCollectableVec, AnyIterableVec, Exit};
use crate::{Indexes, indexes, market, price};
use crate::{Indexes, indexes, price};
pub trait DynCohortVecs: Send + Sync {
fn min_height_vecs_len(&self) -> usize;
@@ -54,9 +54,10 @@ pub trait CohortVecs: DynCohortVecs {
indexes: &indexes::Vecs,
price: Option<&price::Vecs>,
starting_indexes: &Indexes,
market: &market::Vecs,
height_to_supply: &impl AnyIterableVec<Height, Bitcoin>,
dateindex_to_supply: &impl AnyIterableVec<DateIndex, Bitcoin>,
height_to_market_cap: Option<&impl AnyIterableVec<Height, Dollars>>,
dateindex_to_market_cap: Option<&impl AnyIterableVec<DateIndex, Dollars>>,
height_to_realized_cap: Option<&impl AnyIterableVec<Height, Dollars>>,
dateindex_to_realized_cap: Option<&impl AnyIterableVec<DateIndex, Dollars>>,
exit: &Exit,

View File

@@ -6,7 +6,7 @@ use brk_structs::{Bitcoin, DateIndex, Dollars, Height, Version};
use vecdb::{AnyCollectableVec, AnyIterableVec, Database, Exit, Format};
use crate::{
Indexes, UTXOCohortState, indexes, market, price,
Indexes, UTXOCohortState, indexes, price,
stateful::{
common,
r#trait::{CohortVecs, DynCohortVecs},
@@ -158,9 +158,10 @@ impl CohortVecs for Vecs {
indexes: &indexes::Vecs,
price: Option<&price::Vecs>,
starting_indexes: &Indexes,
market: &market::Vecs,
height_to_supply: &impl AnyIterableVec<Height, Bitcoin>,
dateindex_to_supply: &impl AnyIterableVec<DateIndex, Bitcoin>,
height_to_market_cap: Option<&impl AnyIterableVec<Height, Dollars>>,
dateindex_to_market_cap: Option<&impl AnyIterableVec<DateIndex, Dollars>>,
height_to_realized_cap: Option<&impl AnyIterableVec<Height, Dollars>>,
dateindex_to_realized_cap: Option<&impl AnyIterableVec<DateIndex, Dollars>>,
exit: &Exit,
@@ -170,9 +171,10 @@ impl CohortVecs for Vecs {
indexes,
price,
starting_indexes,
market,
height_to_supply,
dateindex_to_supply,
height_to_market_cap,
dateindex_to_market_cap,
height_to_realized_cap,
dateindex_to_realized_cap,
exit,

View File

@@ -11,7 +11,7 @@ use derive_deref::{Deref, DerefMut};
use vecdb::{AnyIterableVec, Database, Exit, Format, StoredIndex};
use crate::{
Indexes, indexes, market, price,
Indexes, indexes, price,
stateful::r#trait::DynCohortVecs,
states::{BlockState, Transacted},
};
@@ -1754,9 +1754,10 @@ impl Vecs {
indexes: &indexes::Vecs,
price: Option<&price::Vecs>,
starting_indexes: &Indexes,
market: &market::Vecs,
height_to_supply: &impl AnyIterableVec<Height, Bitcoin>,
dateindex_to_supply: &impl AnyIterableVec<DateIndex, Bitcoin>,
height_to_market_cap: Option<&impl AnyIterableVec<Height, Dollars>>,
dateindex_to_market_cap: Option<&impl AnyIterableVec<DateIndex, Dollars>>,
height_to_realized_cap: Option<&impl AnyIterableVec<Height, Dollars>>,
dateindex_to_realized_cap: Option<&impl AnyIterableVec<DateIndex, Dollars>>,
exit: &Exit,
@@ -1768,9 +1769,10 @@ impl Vecs {
indexes,
price,
starting_indexes,
market,
height_to_supply,
dateindex_to_supply,
height_to_market_cap,
dateindex_to_market_cap,
height_to_realized_cap,
dateindex_to_realized_cap,
exit,