mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-04-24 06:39:58 -07:00
global: snapshot part 7
This commit is contained in:
@@ -13,7 +13,7 @@ impl Vecs {
|
|||||||
exit: &Exit,
|
exit: &Exit,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
// Block count raw + cumulative
|
// Block count raw + cumulative
|
||||||
self.total.block.height.compute_range(
|
self.total.block.compute_range(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&indexer.vecs.blocks.weight,
|
&indexer.vecs.blocks.weight,
|
||||||
|h| (h, StoredU32::from(1_u32)),
|
|h| (h, StoredU32::from(1_u32)),
|
||||||
|
|||||||
@@ -30,8 +30,8 @@ impl Vecs {
|
|||||||
.compute(starting_indexes.height, exit, |vec| {
|
.compute(starting_indexes.height, exit, |vec| {
|
||||||
vec.compute_subtract(
|
vec.compute_subtract(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&self.coinblocks_created.block.height,
|
&self.coinblocks_created.block,
|
||||||
&distribution.coinblocks_destroyed.block.height,
|
&distribution.coinblocks_destroyed.block,
|
||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ impl Vecs {
|
|||||||
self.vocdd_median_1y.compute_rolling_median_from_starts(
|
self.vocdd_median_1y.compute_rolling_median_from_starts(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&blocks.lookback._1y,
|
&blocks.lookback._1y,
|
||||||
&value.vocdd.block.height,
|
&value.vocdd.block,
|
||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ impl Vecs {
|
|||||||
vec.compute_multiply(
|
vec.compute_multiply(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&prices.spot.usd.height,
|
&prices.spot.usd.height,
|
||||||
&coinblocks_destroyed.block.height,
|
&coinblocks_destroyed.block,
|
||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -36,7 +36,7 @@ impl Vecs {
|
|||||||
vec.compute_multiply(
|
vec.compute_multiply(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&prices.spot.usd.height,
|
&prices.spot.usd.height,
|
||||||
&activity.coinblocks_created.block.height,
|
&activity.coinblocks_created.block,
|
||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -47,7 +47,7 @@ impl Vecs {
|
|||||||
vec.compute_multiply(
|
vec.compute_multiply(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&prices.spot.usd.height,
|
&prices.spot.usd.height,
|
||||||
&activity.coinblocks_stored.block.height,
|
&activity.coinblocks_stored.block,
|
||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -61,7 +61,7 @@ impl Vecs {
|
|||||||
vec.compute_transform3(
|
vec.compute_transform3(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&prices.spot.usd.height,
|
&prices.spot.usd.height,
|
||||||
&coindays_destroyed.block.height,
|
&coindays_destroyed.block,
|
||||||
circulating_supply,
|
circulating_supply,
|
||||||
|(i, price, cdd, supply, _): (_, Dollars, StoredF64, Bitcoin, _)| {
|
|(i, price, cdd, supply, _): (_, Dollars, StoredF64, Bitcoin, _)| {
|
||||||
let supply_f64 = f64::from(supply);
|
let supply_f64 = f64::from(supply);
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ use brk_traversable::Traversable;
|
|||||||
use brk_types::{Cents, CentsSquaredSats, Dollars, Height, Indexes, Sats, Version};
|
use brk_types::{Cents, CentsSquaredSats, Dollars, Height, Indexes, Sats, Version};
|
||||||
use rayon::prelude::*;
|
use rayon::prelude::*;
|
||||||
use vecdb::{
|
use vecdb::{
|
||||||
AnyStoredVec, Database, Exit, ReadOnlyClone, ReadableVec, Rw, StorageMode, WritableVec,
|
AnyStoredVec, AnyVec, Database, Exit, ReadOnlyClone, ReadableVec, Rw, StorageMode, WritableVec,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
@@ -342,7 +342,7 @@ impl UTXOCohorts<Rw> {
|
|||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn push_maturation(&mut self, matured: &AgeRange<Sats>) {
|
pub(crate) fn push_maturation(&mut self, matured: &AgeRange<Sats>) {
|
||||||
for (v, &sats) in self.matured.iter_mut().zip(matured.iter()) {
|
for (v, &sats) in self.matured.iter_mut().zip(matured.iter()) {
|
||||||
v.block.sats.height.push(sats);
|
v.block.sats.push(sats);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -542,9 +542,7 @@ impl UTXOCohorts<Rw> {
|
|||||||
.metrics
|
.metrics
|
||||||
.activity
|
.activity
|
||||||
.transfer_volume
|
.transfer_volume
|
||||||
.block
|
.block.cents
|
||||||
.cents
|
|
||||||
.height
|
|
||||||
.read_only_clone();
|
.read_only_clone();
|
||||||
let under_1h_value_destroyed = self
|
let under_1h_value_destroyed = self
|
||||||
.age_range
|
.age_range
|
||||||
@@ -554,7 +552,6 @@ impl UTXOCohorts<Rw> {
|
|||||||
.sopr
|
.sopr
|
||||||
.value_destroyed
|
.value_destroyed
|
||||||
.block
|
.block
|
||||||
.height
|
|
||||||
.read_only_clone();
|
.read_only_clone();
|
||||||
|
|
||||||
// "all" cohort computed first (no all_supply_sats needed).
|
// "all" cohort computed first (no all_supply_sats needed).
|
||||||
@@ -714,8 +711,8 @@ impl UTXOCohorts<Rw> {
|
|||||||
vecs.extend(self.profitability.collect_all_vecs_mut());
|
vecs.extend(self.profitability.collect_all_vecs_mut());
|
||||||
for v in self.matured.iter_mut() {
|
for v in self.matured.iter_mut() {
|
||||||
let inner = &mut v.inner;
|
let inner = &mut v.inner;
|
||||||
vecs.push(&mut inner.block.sats.height);
|
vecs.push(&mut inner.block.sats);
|
||||||
vecs.push(&mut inner.block.cents.height);
|
vecs.push(&mut inner.block.cents);
|
||||||
vecs.push(&mut inner.cumulative.sats.height);
|
vecs.push(&mut inner.cumulative.sats.height);
|
||||||
vecs.push(&mut inner.cumulative.cents.height);
|
vecs.push(&mut inner.cumulative.cents.height);
|
||||||
}
|
}
|
||||||
@@ -734,7 +731,7 @@ impl UTXOCohorts<Rw> {
|
|||||||
.chain(
|
.chain(
|
||||||
self.matured
|
self.matured
|
||||||
.iter()
|
.iter()
|
||||||
.map(|v| Height::from(v.block.min_stateful_len())),
|
.map(|v| Height::from(v.block.sats.len())),
|
||||||
)
|
)
|
||||||
.min()
|
.min()
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ pub(crate) fn process_blocks(
|
|||||||
let height_to_first_tx_index = &indexer.vecs.transactions.first_tx_index;
|
let height_to_first_tx_index = &indexer.vecs.transactions.first_tx_index;
|
||||||
let height_to_first_txout_index = &indexer.vecs.outputs.first_txout_index;
|
let height_to_first_txout_index = &indexer.vecs.outputs.first_txout_index;
|
||||||
let height_to_first_txin_index = &indexer.vecs.inputs.first_txin_index;
|
let height_to_first_txin_index = &indexer.vecs.inputs.first_txin_index;
|
||||||
let height_to_tx_count = &transactions.count.total.block.height;
|
let height_to_tx_count = &transactions.count.total.block;
|
||||||
let height_to_output_count = &outputs.count.total.sum.height;
|
let height_to_output_count = &outputs.count.total.sum.height;
|
||||||
let height_to_input_count = &inputs.count.sum.height;
|
let height_to_input_count = &inputs.count.sum.height;
|
||||||
let tx_index_to_output_count = &indexes.tx_index.output_count;
|
let tx_index_to_output_count = &indexes.tx_index.output_count;
|
||||||
@@ -221,7 +221,7 @@ pub(crate) fn process_blocks(
|
|||||||
.chain(vecs.addrs.empty.par_iter_height_mut())
|
.chain(vecs.addrs.empty.par_iter_height_mut())
|
||||||
.chain(vecs.addrs.activity.par_iter_height_mut())
|
.chain(vecs.addrs.activity.par_iter_height_mut())
|
||||||
.chain(rayon::iter::once(
|
.chain(rayon::iter::once(
|
||||||
&mut vecs.coinblocks_destroyed.block.height as &mut dyn AnyStoredVec,
|
&mut vecs.coinblocks_destroyed.block as &mut dyn AnyStoredVec,
|
||||||
))
|
))
|
||||||
.try_for_each(|v| v.any_truncate_if_needed_at(start))?;
|
.try_for_each(|v| v.any_truncate_if_needed_at(start))?;
|
||||||
}
|
}
|
||||||
@@ -380,7 +380,7 @@ pub(crate) fn process_blocks(
|
|||||||
blocks_old as u128 * u64::from(sent.spendable_supply.value) as u128
|
blocks_old as u128 * u64::from(sent.spendable_supply.value) as u128
|
||||||
})
|
})
|
||||||
.sum();
|
.sum();
|
||||||
vecs.coinblocks_destroyed.block.height.push(
|
vecs.coinblocks_destroyed.block.push(
|
||||||
StoredF64::from(total_satblocks as f64 / Sats::ONE_BTC_U128 as f64),
|
StoredF64::from(total_satblocks as f64 / Sats::ONE_BTC_U128 as f64),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ pub(crate) fn write(
|
|||||||
.chain(
|
.chain(
|
||||||
[
|
[
|
||||||
&mut vecs.supply_state as &mut dyn AnyStoredVec,
|
&mut vecs.supply_state as &mut dyn AnyStoredVec,
|
||||||
&mut vecs.coinblocks_destroyed.block.height,
|
&mut vecs.coinblocks_destroyed.block,
|
||||||
]
|
]
|
||||||
.into_par_iter(),
|
.into_par_iter(),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -40,9 +40,9 @@ impl ActivityCore {
|
|||||||
pub(crate) fn min_len(&self) -> usize {
|
pub(crate) fn min_len(&self) -> usize {
|
||||||
self.minimal
|
self.minimal
|
||||||
.min_len()
|
.min_len()
|
||||||
.min(self.coindays_destroyed.block.height.len())
|
.min(self.coindays_destroyed.block.len())
|
||||||
.min(self.transfer_volume_in_profit.block.sats.height.len())
|
.min(self.transfer_volume_in_profit.block.sats.len())
|
||||||
.min(self.transfer_volume_in_loss.block.sats.height.len())
|
.min(self.transfer_volume_in_loss.block.sats.len())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
@@ -51,28 +51,24 @@ impl ActivityCore {
|
|||||||
state: &CohortState<impl RealizedOps, impl CostBasisOps>,
|
state: &CohortState<impl RealizedOps, impl CostBasisOps>,
|
||||||
) {
|
) {
|
||||||
self.minimal.push_state(state);
|
self.minimal.push_state(state);
|
||||||
self.coindays_destroyed.block.height.push(
|
self.coindays_destroyed.block.push(
|
||||||
StoredF64::from(Bitcoin::from(state.satdays_destroyed)),
|
StoredF64::from(Bitcoin::from(state.satdays_destroyed)),
|
||||||
);
|
);
|
||||||
self.transfer_volume_in_profit
|
self.transfer_volume_in_profit
|
||||||
.block
|
.block.sats
|
||||||
.sats
|
|
||||||
.height
|
|
||||||
.push(state.realized.sent_in_profit());
|
.push(state.realized.sent_in_profit());
|
||||||
self.transfer_volume_in_loss
|
self.transfer_volume_in_loss
|
||||||
.block
|
.block.sats
|
||||||
.sats
|
|
||||||
.height
|
|
||||||
.push(state.realized.sent_in_loss());
|
.push(state.realized.sent_in_loss());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn collect_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {
|
pub(crate) fn collect_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {
|
||||||
let mut vecs = self.minimal.collect_vecs_mut();
|
let mut vecs = self.minimal.collect_vecs_mut();
|
||||||
vecs.push(&mut self.coindays_destroyed.block.height);
|
vecs.push(&mut self.coindays_destroyed.block);
|
||||||
vecs.push(&mut self.transfer_volume_in_profit.inner.block.sats.height);
|
vecs.push(&mut self.transfer_volume_in_profit.inner.block.sats);
|
||||||
vecs.push(&mut self.transfer_volume_in_profit.inner.block.cents.height);
|
vecs.push(&mut self.transfer_volume_in_profit.inner.block.cents);
|
||||||
vecs.push(&mut self.transfer_volume_in_loss.inner.block.sats.height);
|
vecs.push(&mut self.transfer_volume_in_loss.inner.block.sats);
|
||||||
vecs.push(&mut self.transfer_volume_in_loss.inner.block.cents.height);
|
vecs.push(&mut self.transfer_volume_in_loss.inner.block.cents);
|
||||||
vecs
|
vecs
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,9 +86,9 @@ impl ActivityCore {
|
|||||||
self.minimal
|
self.minimal
|
||||||
.compute_from_stateful(starting_indexes, &minimal_refs, exit)?;
|
.compute_from_stateful(starting_indexes, &minimal_refs, exit)?;
|
||||||
|
|
||||||
sum_others!(self, starting_indexes, others, exit; coindays_destroyed.block.height);
|
sum_others!(self, starting_indexes, others, exit; coindays_destroyed.block);
|
||||||
sum_others!(self, starting_indexes, others, exit; transfer_volume_in_profit.block.sats.height);
|
sum_others!(self, starting_indexes, others, exit; transfer_volume_in_profit.block.sats);
|
||||||
sum_others!(self, starting_indexes, others, exit; transfer_volume_in_loss.block.sats.height);
|
sum_others!(self, starting_indexes, others, exit; transfer_volume_in_loss.block.sats);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,9 +24,7 @@ impl ActivityMinimal {
|
|||||||
|
|
||||||
pub(crate) fn min_len(&self) -> usize {
|
pub(crate) fn min_len(&self) -> usize {
|
||||||
self.transfer_volume
|
self.transfer_volume
|
||||||
.block
|
.block.sats
|
||||||
.sats
|
|
||||||
.height
|
|
||||||
.len()
|
.len()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -35,14 +33,14 @@ impl ActivityMinimal {
|
|||||||
&mut self,
|
&mut self,
|
||||||
state: &CohortState<impl RealizedOps, impl CostBasisOps>,
|
state: &CohortState<impl RealizedOps, impl CostBasisOps>,
|
||||||
) {
|
) {
|
||||||
self.transfer_volume.block.sats.height.push(state.sent);
|
self.transfer_volume.block.sats.push(state.sent);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn collect_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {
|
pub(crate) fn collect_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {
|
||||||
let inner = &mut self.transfer_volume.inner;
|
let inner = &mut self.transfer_volume.inner;
|
||||||
vec![
|
vec![
|
||||||
&mut inner.block.sats.height as &mut dyn AnyStoredVec,
|
&mut inner.block.sats as &mut dyn AnyStoredVec,
|
||||||
&mut inner.block.cents.height,
|
&mut inner.block.cents,
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,11 +50,11 @@ impl ActivityMinimal {
|
|||||||
others: &[&Self],
|
others: &[&Self],
|
||||||
exit: &Exit,
|
exit: &Exit,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
self.transfer_volume.block.sats.height.compute_sum_of_others(
|
self.transfer_volume.block.sats.compute_sum_of_others(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&others
|
&others
|
||||||
.iter()
|
.iter()
|
||||||
.map(|v| &v.transfer_volume.block.sats.height)
|
.map(|v| &v.transfer_volume.block.sats)
|
||||||
.collect::<Vec<_>>(),
|
.collect::<Vec<_>>(),
|
||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
|
|||||||
@@ -128,8 +128,8 @@ impl AllCohortMetrics {
|
|||||||
|
|
||||||
self.asopr.compute_rest_part2(
|
self.asopr.compute_rest_part2(
|
||||||
starting_indexes,
|
starting_indexes,
|
||||||
&self.activity.transfer_volume.block.cents.height,
|
&self.activity.transfer_volume.block.cents,
|
||||||
&self.realized.core.sopr.value_destroyed.block.height,
|
&self.realized.core.sopr.value_destroyed.block,
|
||||||
under_1h_value_created,
|
under_1h_value_created,
|
||||||
under_1h_value_destroyed,
|
under_1h_value_destroyed,
|
||||||
exit,
|
exit,
|
||||||
|
|||||||
@@ -80,8 +80,8 @@ impl ExtendedAdjustedCohortMetrics {
|
|||||||
|
|
||||||
self.asopr.compute_rest_part2(
|
self.asopr.compute_rest_part2(
|
||||||
starting_indexes,
|
starting_indexes,
|
||||||
&self.inner.activity.transfer_volume.block.cents.height,
|
&self.inner.activity.transfer_volume.block.cents,
|
||||||
&self.inner.realized.core.sopr.value_destroyed.block.height,
|
&self.inner.realized.core.sopr.value_destroyed.block,
|
||||||
under_1h_value_created,
|
under_1h_value_created,
|
||||||
under_1h_value_destroyed,
|
under_1h_value_destroyed,
|
||||||
exit,
|
exit,
|
||||||
|
|||||||
@@ -34,13 +34,13 @@ impl AdjustedSopr {
|
|||||||
under_1h_value_destroyed: &impl ReadableVec<Height, Cents>,
|
under_1h_value_destroyed: &impl ReadableVec<Height, Cents>,
|
||||||
exit: &Exit,
|
exit: &Exit,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
self.transfer_volume.block.height.compute_subtract(
|
self.transfer_volume.block.compute_subtract(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
base_transfer_volume,
|
base_transfer_volume,
|
||||||
under_1h_transfer_volume,
|
under_1h_transfer_volume,
|
||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
self.value_destroyed.block.height.compute_subtract(
|
self.value_destroyed.block.compute_subtract(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
base_value_destroyed,
|
base_value_destroyed,
|
||||||
under_1h_value_destroyed,
|
under_1h_value_destroyed,
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ impl RealizedCore {
|
|||||||
let neg_loss_base = LazyPerBlock::from_height_source::<NegCentsUnsignedToDollars>(
|
let neg_loss_base = LazyPerBlock::from_height_source::<NegCentsUnsignedToDollars>(
|
||||||
&cfg.name("neg_realized_loss"),
|
&cfg.name("neg_realized_loss"),
|
||||||
cfg.version + Version::ONE,
|
cfg.version + Version::ONE,
|
||||||
minimal.loss.block.cents.height.read_only_boxed_clone(),
|
minimal.loss.block.cents.read_only_boxed_clone(),
|
||||||
cfg.indexes,
|
cfg.indexes,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -107,12 +107,12 @@ impl RealizedCore {
|
|||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn push_state(&mut self, state: &CohortState<impl RealizedOps, impl CostBasisOps>) {
|
pub(crate) fn push_state(&mut self, state: &CohortState<impl RealizedOps, impl CostBasisOps>) {
|
||||||
self.minimal.push_state(state);
|
self.minimal.push_state(state);
|
||||||
self.sopr.value_destroyed.block.height.push(state.realized.value_destroyed());
|
self.sopr.value_destroyed.block.push(state.realized.value_destroyed());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn collect_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {
|
pub(crate) fn collect_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {
|
||||||
let mut vecs = self.minimal.collect_vecs_mut();
|
let mut vecs = self.minimal.collect_vecs_mut();
|
||||||
vecs.push(&mut self.sopr.value_destroyed.block.height);
|
vecs.push(&mut self.sopr.value_destroyed.block);
|
||||||
vecs
|
vecs
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -126,7 +126,7 @@ impl RealizedCore {
|
|||||||
self.minimal
|
self.minimal
|
||||||
.compute_from_stateful(starting_indexes, &minimal_refs, exit)?;
|
.compute_from_stateful(starting_indexes, &minimal_refs, exit)?;
|
||||||
|
|
||||||
sum_others!(self, starting_indexes, others, exit; sopr.value_destroyed.block.height);
|
sum_others!(self, starting_indexes, others, exit; sopr.value_destroyed.block);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,10 +142,10 @@ impl RealizedCore {
|
|||||||
.value_destroyed
|
.value_destroyed
|
||||||
.compute_rest(starting_indexes.height, exit)?;
|
.compute_rest(starting_indexes.height, exit)?;
|
||||||
|
|
||||||
self.net_pnl.block.cents.height.compute_transform2(
|
self.net_pnl.block.cents.compute_transform2(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&self.minimal.profit.block.cents.height,
|
&self.minimal.profit.block.cents,
|
||||||
&self.minimal.loss.block.cents.height,
|
&self.minimal.loss.block.cents,
|
||||||
|(i, profit, loss, ..)| {
|
|(i, profit, loss, ..)| {
|
||||||
(
|
(
|
||||||
i,
|
i,
|
||||||
|
|||||||
@@ -183,7 +183,7 @@ impl RealizedFull {
|
|||||||
.len()
|
.len()
|
||||||
.min(self.cap_raw.len())
|
.min(self.cap_raw.len())
|
||||||
.min(self.investor.cap_raw.len())
|
.min(self.investor.cap_raw.len())
|
||||||
.min(self.peak_regret.value.block.cents.height.len())
|
.min(self.peak_regret.value.block.cents.len())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
@@ -203,9 +203,7 @@ impl RealizedFull {
|
|||||||
.push(state.realized.investor_cap_raw());
|
.push(state.realized.investor_cap_raw());
|
||||||
self.peak_regret
|
self.peak_regret
|
||||||
.value
|
.value
|
||||||
.block
|
.block.cents
|
||||||
.cents
|
|
||||||
.height
|
|
||||||
.push(state.realized.peak_regret());
|
.push(state.realized.peak_regret());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -214,7 +212,7 @@ impl RealizedFull {
|
|||||||
vecs.push(&mut self.investor.price.cents.height);
|
vecs.push(&mut self.investor.price.cents.height);
|
||||||
vecs.push(&mut self.cap_raw as &mut dyn AnyStoredVec);
|
vecs.push(&mut self.cap_raw as &mut dyn AnyStoredVec);
|
||||||
vecs.push(&mut self.investor.cap_raw as &mut dyn AnyStoredVec);
|
vecs.push(&mut self.investor.cap_raw as &mut dyn AnyStoredVec);
|
||||||
vecs.push(&mut self.peak_regret.value.block.cents.height);
|
vecs.push(&mut self.peak_regret.value.block.cents);
|
||||||
vecs
|
vecs
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -247,9 +245,7 @@ impl RealizedFull {
|
|||||||
|
|
||||||
self.peak_regret
|
self.peak_regret
|
||||||
.value
|
.value
|
||||||
.block
|
.block.cents
|
||||||
.cents
|
|
||||||
.height
|
|
||||||
.push(accum.peak_regret());
|
.push(accum.peak_regret());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -307,7 +303,7 @@ impl RealizedFull {
|
|||||||
.to_rcap
|
.to_rcap
|
||||||
.compute_binary::<Cents, Cents, RatioCentsBp32>(
|
.compute_binary::<Cents, Cents, RatioCentsBp32>(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&self.core.minimal.profit.block.cents.height,
|
&self.core.minimal.profit.block.cents,
|
||||||
&self.core.minimal.cap.cents.height,
|
&self.core.minimal.cap.cents.height,
|
||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
@@ -315,7 +311,7 @@ impl RealizedFull {
|
|||||||
.to_rcap
|
.to_rcap
|
||||||
.compute_binary::<Cents, Cents, RatioCentsBp32>(
|
.compute_binary::<Cents, Cents, RatioCentsBp32>(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&self.core.minimal.loss.block.cents.height,
|
&self.core.minimal.loss.block.cents,
|
||||||
&self.core.minimal.cap.cents.height,
|
&self.core.minimal.cap.cents.height,
|
||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
@@ -323,16 +319,16 @@ impl RealizedFull {
|
|||||||
.to_rcap
|
.to_rcap
|
||||||
.compute_binary::<CentsSigned, Cents, RatioCentsSignedCentsBps32>(
|
.compute_binary::<CentsSigned, Cents, RatioCentsSignedCentsBps32>(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&self.core.net_pnl.block.cents.height,
|
&self.core.net_pnl.block.cents,
|
||||||
&self.core.minimal.cap.cents.height,
|
&self.core.minimal.cap.cents.height,
|
||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
// Gross PnL
|
// Gross PnL
|
||||||
self.gross_pnl.block.cents.height.compute_add(
|
self.gross_pnl.block.cents.compute_add(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&self.core.minimal.profit.block.cents.height,
|
&self.core.minimal.profit.block.cents,
|
||||||
&self.core.minimal.loss.block.cents.height,
|
&self.core.minimal.loss.block.cents,
|
||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
self.gross_pnl.compute_rest(starting_indexes.height, exit)?;
|
self.gross_pnl.compute_rest(starting_indexes.height, exit)?;
|
||||||
@@ -360,7 +356,7 @@ impl RealizedFull {
|
|||||||
.to_rcap
|
.to_rcap
|
||||||
.compute_binary::<Cents, Cents, RatioCentsBp32>(
|
.compute_binary::<Cents, Cents, RatioCentsBp32>(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&self.peak_regret.value.block.cents.height,
|
&self.peak_regret.value.block.cents,
|
||||||
&self.core.minimal.cap.cents.height,
|
&self.core.minimal.cap.cents.height,
|
||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
|
|||||||
@@ -62,22 +62,22 @@ impl RealizedMinimal {
|
|||||||
.cents
|
.cents
|
||||||
.height
|
.height
|
||||||
.len()
|
.len()
|
||||||
.min(self.profit.block.cents.height.len())
|
.min(self.profit.block.cents.len())
|
||||||
.min(self.loss.block.cents.height.len())
|
.min(self.loss.block.cents.len())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn push_state(&mut self, state: &CohortState<impl RealizedOps, impl CostBasisOps>) {
|
pub(crate) fn push_state(&mut self, state: &CohortState<impl RealizedOps, impl CostBasisOps>) {
|
||||||
self.cap.cents.height.push(state.realized.cap());
|
self.cap.cents.height.push(state.realized.cap());
|
||||||
self.profit.block.cents.height.push(state.realized.profit());
|
self.profit.block.cents.push(state.realized.profit());
|
||||||
self.loss.block.cents.height.push(state.realized.loss());
|
self.loss.block.cents.push(state.realized.loss());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn collect_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {
|
pub(crate) fn collect_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {
|
||||||
vec![
|
vec![
|
||||||
&mut self.cap.cents.height as &mut dyn AnyStoredVec,
|
&mut self.cap.cents.height as &mut dyn AnyStoredVec,
|
||||||
&mut self.profit.block.cents.height,
|
&mut self.profit.block.cents,
|
||||||
&mut self.loss.block.cents.height,
|
&mut self.loss.block.cents,
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,8 +88,8 @@ impl RealizedMinimal {
|
|||||||
exit: &Exit,
|
exit: &Exit,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
sum_others!(self, starting_indexes, others, exit; cap.cents.height);
|
sum_others!(self, starting_indexes, others, exit; cap.cents.height);
|
||||||
sum_others!(self, starting_indexes, others, exit; profit.block.cents.height);
|
sum_others!(self, starting_indexes, others, exit; profit.block.cents);
|
||||||
sum_others!(self, starting_indexes, others, exit; loss.block.cents.height);
|
sum_others!(self, starting_indexes, others, exit; loss.block.cents);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -490,6 +490,6 @@ impl Vecs {
|
|||||||
.min(Height::from(self.addrs.funded.min_stateful_len()))
|
.min(Height::from(self.addrs.funded.min_stateful_len()))
|
||||||
.min(Height::from(self.addrs.empty.min_stateful_len()))
|
.min(Height::from(self.addrs.empty.min_stateful_len()))
|
||||||
.min(Height::from(self.addrs.activity.min_stateful_len()))
|
.min(Height::from(self.addrs.activity.min_stateful_len()))
|
||||||
.min(Height::from(self.coinblocks_destroyed.block.height.len()))
|
.min(Height::from(self.coinblocks_destroyed.block.len()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ impl Vecs {
|
|||||||
.bps
|
.bps
|
||||||
.compute_binary::<Dollars, Dollars, RatioDollarsBp32>(
|
.compute_binary::<Dollars, Dollars, RatioDollarsBp32>(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&mining.rewards.subsidy.block.usd.height,
|
&mining.rewards.subsidy.block.usd,
|
||||||
&mining.rewards.subsidy_sma_1y.usd.height,
|
&mining.rewards.subsidy_sma_1y.usd.height,
|
||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
@@ -146,7 +146,7 @@ impl Vecs {
|
|||||||
self.stock_to_flow.height.compute_transform2(
|
self.stock_to_flow.height.compute_transform2(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
supply_total_sats,
|
supply_total_sats,
|
||||||
&mining.rewards.subsidy.block.sats.height,
|
&mining.rewards.subsidy.block.sats,
|
||||||
|(i, supply_sats, subsidy_sats, ..)| {
|
|(i, supply_sats, subsidy_sats, ..)| {
|
||||||
let annual_flow = subsidy_sats.as_u128() as f64 * 52560.0;
|
let annual_flow = subsidy_sats.as_u128() as f64 * 52560.0;
|
||||||
if annual_flow == 0.0 {
|
if annual_flow == 0.0 {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use brk_error::Result;
|
use brk_error::Result;
|
||||||
use brk_traversable::Traversable;
|
use brk_traversable::Traversable;
|
||||||
use brk_types::{Bitcoin, Cents, Dollars, Height, Sats, Version};
|
use brk_types::{Bitcoin, Cents, Dollars, Height, Sats, Version};
|
||||||
use vecdb::{AnyVec, Database, Exit, ReadableCloneableVec, Rw, StorageMode};
|
use vecdb::{Database, Exit, ReadableCloneableVec, Rw, StorageMode};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
indexes,
|
indexes,
|
||||||
@@ -54,10 +54,6 @@ impl AmountPerBlock {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn min_stateful_len(&self) -> usize {
|
|
||||||
self.sats.height.len()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn compute(
|
pub(crate) fn compute(
|
||||||
&mut self,
|
&mut self,
|
||||||
prices: &prices::Vecs,
|
prices: &prices::Vecs,
|
||||||
|
|||||||
53
crates/brk_computer/src/internal/per_block/amount/block.rs
Normal file
53
crates/brk_computer/src/internal/per_block/amount/block.rs
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
use brk_error::Result;
|
||||||
|
use brk_traversable::Traversable;
|
||||||
|
use brk_types::{Bitcoin, Cents, Dollars, Height, Sats, Version};
|
||||||
|
use vecdb::{Database, EagerVec, Exit, ImportableVec, LazyVecFrom1, PcoVec, ReadableCloneableVec, Rw, StorageMode};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
internal::{CentsUnsignedToDollars, SatsToBitcoin, SatsToCents},
|
||||||
|
prices,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Raw per-block amount data: sats + cents (stored), btc + usd (lazy), no resolutions.
|
||||||
|
#[derive(Traversable)]
|
||||||
|
pub struct AmountBlock<M: StorageMode = Rw> {
|
||||||
|
pub btc: LazyVecFrom1<Height, Bitcoin, Height, Sats>,
|
||||||
|
pub sats: M::Stored<EagerVec<PcoVec<Height, Sats>>>,
|
||||||
|
pub usd: LazyVecFrom1<Height, Dollars, Height, Cents>,
|
||||||
|
pub cents: M::Stored<EagerVec<PcoVec<Height, Cents>>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AmountBlock {
|
||||||
|
pub(crate) fn forced_import(db: &Database, name: &str, version: Version) -> Result<Self> {
|
||||||
|
let sats: EagerVec<PcoVec<Height, Sats>> =
|
||||||
|
EagerVec::forced_import(db, &format!("{name}_sats"), version)?;
|
||||||
|
let btc = LazyVecFrom1::transformed::<SatsToBitcoin>(
|
||||||
|
name,
|
||||||
|
version,
|
||||||
|
sats.read_only_boxed_clone(),
|
||||||
|
);
|
||||||
|
let cents: EagerVec<PcoVec<Height, Cents>> =
|
||||||
|
EagerVec::forced_import(db, &format!("{name}_cents"), version)?;
|
||||||
|
let usd = LazyVecFrom1::transformed::<CentsUnsignedToDollars>(
|
||||||
|
&format!("{name}_usd"),
|
||||||
|
version,
|
||||||
|
cents.read_only_boxed_clone(),
|
||||||
|
);
|
||||||
|
Ok(Self { btc, sats, usd, cents })
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn compute_cents(
|
||||||
|
&mut self,
|
||||||
|
max_from: Height,
|
||||||
|
prices: &prices::Vecs,
|
||||||
|
exit: &Exit,
|
||||||
|
) -> Result<()> {
|
||||||
|
self.cents.compute_binary::<Sats, Cents, SatsToCents>(
|
||||||
|
max_from,
|
||||||
|
&self.sats,
|
||||||
|
&prices.spot.cents.height,
|
||||||
|
exit,
|
||||||
|
)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,17 +1,17 @@
|
|||||||
use brk_error::Result;
|
use brk_error::Result;
|
||||||
use brk_traversable::Traversable;
|
use brk_traversable::Traversable;
|
||||||
use brk_types::{Cents, Height, Sats, Version};
|
use brk_types::{Height, Version};
|
||||||
use vecdb::{Database, Exit, Rw, StorageMode};
|
use vecdb::{Database, Exit, Rw, StorageMode};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
indexes,
|
indexes,
|
||||||
internal::{AmountPerBlock, SatsToCents},
|
internal::{AmountBlock, AmountPerBlock},
|
||||||
prices,
|
prices,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Traversable)]
|
#[derive(Traversable)]
|
||||||
pub struct AmountPerBlockCumulative<M: StorageMode = Rw> {
|
pub struct AmountPerBlockCumulative<M: StorageMode = Rw> {
|
||||||
pub block: AmountPerBlock<M>,
|
pub block: AmountBlock<M>,
|
||||||
pub cumulative: AmountPerBlock<M>,
|
pub cumulative: AmountPerBlock<M>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -27,7 +27,7 @@ impl AmountPerBlockCumulative {
|
|||||||
let v = version + VERSION;
|
let v = version + VERSION;
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
block: AmountPerBlock::forced_import(db, name, v, indexes)?,
|
block: AmountBlock::forced_import(db, name, v)?,
|
||||||
cumulative: AmountPerBlock::forced_import(
|
cumulative: AmountPerBlock::forced_import(
|
||||||
db,
|
db,
|
||||||
&format!("{name}_cumulative"),
|
&format!("{name}_cumulative"),
|
||||||
@@ -46,19 +46,14 @@ impl AmountPerBlockCumulative {
|
|||||||
self.cumulative
|
self.cumulative
|
||||||
.sats
|
.sats
|
||||||
.height
|
.height
|
||||||
.compute_cumulative(max_from, &self.block.sats.height, exit)?;
|
.compute_cumulative(max_from, &self.block.sats, exit)?;
|
||||||
|
|
||||||
self.block.cents.compute_binary::<Sats, Cents, SatsToCents>(
|
self.block.compute_cents(max_from, prices, exit)?;
|
||||||
max_from,
|
|
||||||
&self.block.sats.height,
|
|
||||||
&prices.spot.cents.height,
|
|
||||||
exit,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
self.cumulative
|
self.cumulative
|
||||||
.cents
|
.cents
|
||||||
.height
|
.height
|
||||||
.compute_cumulative(max_from, &self.block.cents.height, exit)?;
|
.compute_cumulative(max_from, &self.block.cents, exit)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ impl AmountPerBlockCumulativeRolling {
|
|||||||
exit: &Exit,
|
exit: &Exit,
|
||||||
compute_sats: impl FnOnce(&mut EagerVec<PcoVec<Height, Sats>>) -> Result<()>,
|
compute_sats: impl FnOnce(&mut EagerVec<PcoVec<Height, Sats>>) -> Result<()>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
compute_sats(&mut self.block.sats.height)?;
|
compute_sats(&mut self.block.sats)?;
|
||||||
self.compute_rest(max_from, prices, exit)
|
self.compute_rest(max_from, prices, exit)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -54,15 +54,15 @@ impl AmountPerBlockFull {
|
|||||||
exit: &Exit,
|
exit: &Exit,
|
||||||
compute_sats: impl FnOnce(&mut EagerVec<PcoVec<Height, Sats>>) -> Result<()>,
|
compute_sats: impl FnOnce(&mut EagerVec<PcoVec<Height, Sats>>) -> Result<()>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
compute_sats(&mut self.inner.block.sats.height)?;
|
compute_sats(&mut self.inner.block.sats)?;
|
||||||
|
|
||||||
self.inner.compute_rest(max_from, prices, exit)?;
|
self.inner.compute_rest(max_from, prices, exit)?;
|
||||||
|
|
||||||
self.distribution.compute(
|
self.distribution.compute(
|
||||||
max_from,
|
max_from,
|
||||||
windows,
|
windows,
|
||||||
&self.inner.block.sats.height,
|
&self.inner.block.sats,
|
||||||
&self.inner.block.cents.height,
|
&self.inner.block.cents,
|
||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
mod base;
|
mod base;
|
||||||
|
mod block;
|
||||||
mod cumulative;
|
mod cumulative;
|
||||||
mod cumulative_rolling;
|
mod cumulative_rolling;
|
||||||
mod full;
|
mod full;
|
||||||
@@ -10,6 +11,7 @@ mod rolling_distribution;
|
|||||||
mod with_deltas;
|
mod with_deltas;
|
||||||
|
|
||||||
pub use base::*;
|
pub use base::*;
|
||||||
|
pub use block::*;
|
||||||
pub use cumulative::*;
|
pub use cumulative::*;
|
||||||
pub use cumulative_rolling::*;
|
pub use cumulative_rolling::*;
|
||||||
pub use full::*;
|
pub use full::*;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
//! PerBlockCumulativeRolling - base PerBlock + cumulative PerBlock + lazy rolling sums.
|
//! PerBlockCumulativeRolling - base EagerVec + cumulative PerBlock + lazy rolling sums.
|
||||||
//!
|
//!
|
||||||
//! Rolling sums are derived lazily from the cumulative vec via LazyDeltaVec.
|
//! Rolling sums are derived lazily from the cumulative vec via LazyDeltaVec.
|
||||||
//! No rolling sum vecs are stored on disk.
|
//! No rolling sum vecs are stored on disk.
|
||||||
@@ -13,7 +13,7 @@ use brk_error::Result;
|
|||||||
use brk_traversable::Traversable;
|
use brk_traversable::Traversable;
|
||||||
use brk_types::{Height, Version};
|
use brk_types::{Height, Version};
|
||||||
use schemars::JsonSchema;
|
use schemars::JsonSchema;
|
||||||
use vecdb::{Database, EagerVec, Exit, PcoVec, Rw, StorageMode};
|
use vecdb::{Database, EagerVec, Exit, ImportableVec, PcoVec, Rw, StorageMode};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
indexes,
|
indexes,
|
||||||
@@ -29,7 +29,8 @@ where
|
|||||||
T: NumericValue + JsonSchema,
|
T: NumericValue + JsonSchema,
|
||||||
C: NumericValue + JsonSchema,
|
C: NumericValue + JsonSchema,
|
||||||
{
|
{
|
||||||
pub block: PerBlock<T, M>,
|
#[traversable(hidden)]
|
||||||
|
pub block: M::Stored<EagerVec<PcoVec<Height, T>>>,
|
||||||
pub cumulative: PerBlock<C, M>,
|
pub cumulative: PerBlock<C, M>,
|
||||||
pub sum: LazyRollingSumsFromHeight<C>,
|
pub sum: LazyRollingSumsFromHeight<C>,
|
||||||
pub average: LazyRollingAvgsFromHeight<C>,
|
pub average: LazyRollingAvgsFromHeight<C>,
|
||||||
@@ -47,7 +48,7 @@ where
|
|||||||
indexes: &indexes::Vecs,
|
indexes: &indexes::Vecs,
|
||||||
cached_starts: &CachedWindowStarts,
|
cached_starts: &CachedWindowStarts,
|
||||||
) -> Result<Self> {
|
) -> Result<Self> {
|
||||||
let block = PerBlock::forced_import(db, name, version, indexes)?;
|
let block = EagerVec::forced_import(db, name, version)?;
|
||||||
let cumulative =
|
let cumulative =
|
||||||
PerBlock::forced_import(db, &format!("{name}_cumulative"), version, indexes)?;
|
PerBlock::forced_import(db, &format!("{name}_cumulative"), version, indexes)?;
|
||||||
let sum = LazyRollingSumsFromHeight::new(
|
let sum = LazyRollingSumsFromHeight::new(
|
||||||
@@ -83,7 +84,7 @@ where
|
|||||||
where
|
where
|
||||||
C: Default,
|
C: Default,
|
||||||
{
|
{
|
||||||
compute_base(&mut self.block.height)?;
|
compute_base(&mut self.block)?;
|
||||||
self.compute_rest(max_from, exit)
|
self.compute_rest(max_from, exit)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,7 +95,7 @@ where
|
|||||||
{
|
{
|
||||||
self.cumulative
|
self.cumulative
|
||||||
.height
|
.height
|
||||||
.compute_cumulative(max_from, &self.block.height, exit)?;
|
.compute_cumulative(max_from, &self.block, exit)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
//! PerBlockFull - base PerBlock + cumulative PerBlock + RollingComplete.
|
//! PerBlockFull - base EagerVec + cumulative PerBlock + RollingComplete.
|
||||||
//!
|
//!
|
||||||
//! For metrics with stored per-block data, cumulative sums, and rolling windows.
|
//! For metrics with stored per-block data, cumulative sums, and rolling windows.
|
||||||
|
|
||||||
@@ -6,7 +6,7 @@ use brk_error::Result;
|
|||||||
use brk_traversable::Traversable;
|
use brk_traversable::Traversable;
|
||||||
use brk_types::{Height, Version};
|
use brk_types::{Height, Version};
|
||||||
use schemars::JsonSchema;
|
use schemars::JsonSchema;
|
||||||
use vecdb::{Database, EagerVec, Exit, PcoVec, Rw, StorageMode};
|
use vecdb::{Database, EagerVec, Exit, ImportableVec, PcoVec, Rw, StorageMode};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
indexes,
|
indexes,
|
||||||
@@ -18,7 +18,8 @@ pub struct PerBlockFull<T, M: StorageMode = Rw>
|
|||||||
where
|
where
|
||||||
T: NumericValue + JsonSchema,
|
T: NumericValue + JsonSchema,
|
||||||
{
|
{
|
||||||
pub block: PerBlock<T, M>,
|
#[traversable(hidden)]
|
||||||
|
pub block: M::Stored<EagerVec<PcoVec<Height, T>>>,
|
||||||
pub cumulative: PerBlock<T, M>,
|
pub cumulative: PerBlock<T, M>,
|
||||||
#[traversable(flatten)]
|
#[traversable(flatten)]
|
||||||
pub rolling: RollingComplete<T, M>,
|
pub rolling: RollingComplete<T, M>,
|
||||||
@@ -35,7 +36,7 @@ where
|
|||||||
indexes: &indexes::Vecs,
|
indexes: &indexes::Vecs,
|
||||||
cached_starts: &CachedWindowStarts,
|
cached_starts: &CachedWindowStarts,
|
||||||
) -> Result<Self> {
|
) -> Result<Self> {
|
||||||
let block = PerBlock::forced_import(db, name, version, indexes)?;
|
let block = EagerVec::forced_import(db, name, version)?;
|
||||||
let cumulative =
|
let cumulative =
|
||||||
PerBlock::forced_import(db, &format!("{name}_cumulative"), version, indexes)?;
|
PerBlock::forced_import(db, &format!("{name}_cumulative"), version, indexes)?;
|
||||||
let rolling = RollingComplete::forced_import(
|
let rolling = RollingComplete::forced_import(
|
||||||
@@ -66,12 +67,12 @@ where
|
|||||||
T: From<f64> + Default + Copy + Ord,
|
T: From<f64> + Default + Copy + Ord,
|
||||||
f64: From<T>,
|
f64: From<T>,
|
||||||
{
|
{
|
||||||
compute_base(&mut self.block.height)?;
|
compute_base(&mut self.block)?;
|
||||||
self.cumulative
|
self.cumulative
|
||||||
.height
|
.height
|
||||||
.compute_cumulative(max_from, &self.block.height, exit)?;
|
.compute_cumulative(max_from, &self.block, exit)?;
|
||||||
self.rolling
|
self.rolling
|
||||||
.compute(max_from, windows, &self.block.height, exit)?;
|
.compute(max_from, windows, &self.block, exit)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ pub struct PerBlockRollingAverage<T, M: StorageMode = Rw>
|
|||||||
where
|
where
|
||||||
T: NumericValue + JsonSchema,
|
T: NumericValue + JsonSchema,
|
||||||
{
|
{
|
||||||
|
#[traversable(hidden)]
|
||||||
pub block: M::Stored<EagerVec<PcoVec<Height, T>>>,
|
pub block: M::Stored<EagerVec<PcoVec<Height, T>>>,
|
||||||
#[traversable(hidden)]
|
#[traversable(hidden)]
|
||||||
pub cumulative: M::Stored<EagerVec<PcoVec<Height, T>>>,
|
pub cumulative: M::Stored<EagerVec<PcoVec<Height, T>>>,
|
||||||
|
|||||||
26
crates/brk_computer/src/internal/per_block/fiat/block.rs
Normal file
26
crates/brk_computer/src/internal/per_block/fiat/block.rs
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
use brk_error::Result;
|
||||||
|
use brk_traversable::Traversable;
|
||||||
|
use brk_types::{Dollars, Height, Version};
|
||||||
|
use vecdb::{Database, EagerVec, ImportableVec, LazyVecFrom1, PcoVec, ReadableCloneableVec, Rw, StorageMode};
|
||||||
|
|
||||||
|
use super::CentsType;
|
||||||
|
|
||||||
|
/// Raw per-block fiat data: cents (stored) + usd (lazy), no resolutions.
|
||||||
|
#[derive(Traversable)]
|
||||||
|
pub struct FiatBlock<C: CentsType, M: StorageMode = Rw> {
|
||||||
|
pub usd: LazyVecFrom1<Height, Dollars, Height, C>,
|
||||||
|
pub cents: M::Stored<EagerVec<PcoVec<Height, C>>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<C: CentsType> FiatBlock<C> {
|
||||||
|
pub(crate) fn forced_import(db: &Database, name: &str, version: Version) -> Result<Self> {
|
||||||
|
let cents: EagerVec<PcoVec<Height, C>> =
|
||||||
|
EagerVec::forced_import(db, &format!("{name}_cents"), version)?;
|
||||||
|
let usd = LazyVecFrom1::transformed::<C::ToDollars>(
|
||||||
|
name,
|
||||||
|
version,
|
||||||
|
cents.read_only_boxed_clone(),
|
||||||
|
);
|
||||||
|
Ok(Self { usd, cents })
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,12 +5,12 @@ use vecdb::{Database, Exit, Rw, StorageMode};
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
indexes,
|
indexes,
|
||||||
internal::{CachedWindowStarts, CentsType, FiatPerBlock, LazyRollingSumsFiatFromHeight},
|
internal::{CachedWindowStarts, CentsType, FiatBlock, FiatPerBlock, LazyRollingSumsFiatFromHeight},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Traversable)]
|
#[derive(Traversable)]
|
||||||
pub struct FiatPerBlockCumulativeWithSums<C: CentsType, M: StorageMode = Rw> {
|
pub struct FiatPerBlockCumulativeWithSums<C: CentsType, M: StorageMode = Rw> {
|
||||||
pub block: FiatPerBlock<C, M>,
|
pub block: FiatBlock<C, M>,
|
||||||
pub cumulative: FiatPerBlock<C, M>,
|
pub cumulative: FiatPerBlock<C, M>,
|
||||||
pub sum: LazyRollingSumsFiatFromHeight<C>,
|
pub sum: LazyRollingSumsFiatFromHeight<C>,
|
||||||
}
|
}
|
||||||
@@ -23,7 +23,7 @@ impl<C: CentsType> FiatPerBlockCumulativeWithSums<C> {
|
|||||||
indexes: &indexes::Vecs,
|
indexes: &indexes::Vecs,
|
||||||
cached_starts: &CachedWindowStarts,
|
cached_starts: &CachedWindowStarts,
|
||||||
) -> Result<Self> {
|
) -> Result<Self> {
|
||||||
let block = FiatPerBlock::forced_import(db, name, version, indexes)?;
|
let block = FiatBlock::forced_import(db, name, version)?;
|
||||||
let cumulative = FiatPerBlock::forced_import(
|
let cumulative = FiatPerBlock::forced_import(
|
||||||
db,
|
db,
|
||||||
&format!("{name}_cumulative"),
|
&format!("{name}_cumulative"),
|
||||||
@@ -47,7 +47,7 @@ impl<C: CentsType> FiatPerBlockCumulativeWithSums<C> {
|
|||||||
self.cumulative
|
self.cumulative
|
||||||
.cents
|
.cents
|
||||||
.height
|
.height
|
||||||
.compute_cumulative(max_from, &self.block.cents.height, exit)?;
|
.compute_cumulative(max_from, &self.block.cents, exit)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
mod base;
|
mod base;
|
||||||
|
mod block;
|
||||||
mod cumulative_sum;
|
mod cumulative_sum;
|
||||||
mod cumulative_sum_with_deltas;
|
mod cumulative_sum_with_deltas;
|
||||||
mod lazy;
|
mod lazy;
|
||||||
mod lazy_rolling_sum;
|
mod lazy_rolling_sum;
|
||||||
mod with_deltas;
|
mod with_deltas;
|
||||||
pub use base::*;
|
pub use base::*;
|
||||||
|
pub use block::*;
|
||||||
pub use cumulative_sum::*;
|
pub use cumulative_sum::*;
|
||||||
pub use cumulative_sum_with_deltas::*;
|
pub use cumulative_sum_with_deltas::*;
|
||||||
pub use lazy::*;
|
pub use lazy::*;
|
||||||
|
|||||||
@@ -81,10 +81,10 @@ impl Vecs {
|
|||||||
r_coinbase?;
|
r_coinbase?;
|
||||||
r_fees?;
|
r_fees?;
|
||||||
|
|
||||||
self.subsidy.block.sats.height.compute_transform2(
|
self.subsidy.block.sats.compute_transform2(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&self.coinbase.block.sats.height,
|
&self.coinbase.block.sats,
|
||||||
&self.fees.block.sats.height,
|
&self.fees.block.sats,
|
||||||
|(height, coinbase, fees, ..)| {
|
|(height, coinbase, fees, ..)| {
|
||||||
(
|
(
|
||||||
height,
|
height,
|
||||||
@@ -97,9 +97,9 @@ impl Vecs {
|
|||||||
)?;
|
)?;
|
||||||
self.subsidy.compute_rest(starting_indexes.height, prices, exit)?;
|
self.subsidy.compute_rest(starting_indexes.height, prices, exit)?;
|
||||||
|
|
||||||
self.unclaimed.block.sats.height.compute_transform(
|
self.unclaimed.block.sats.compute_transform(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&self.subsidy.block.sats.height,
|
&self.subsidy.block.sats,
|
||||||
|(height, subsidy, ..)| {
|
|(height, subsidy, ..)| {
|
||||||
let halving = Halving::from(height);
|
let halving = Halving::from(height);
|
||||||
let expected = Sats::FIFTY_BTC / 2_usize.pow(halving.to_usize() as u32);
|
let expected = Sats::FIFTY_BTC / 2_usize.pow(halving.to_usize() as u32);
|
||||||
@@ -136,7 +136,7 @@ impl Vecs {
|
|||||||
self.subsidy_sma_1y.cents.height.compute_rolling_average(
|
self.subsidy_sma_1y.cents.height.compute_rolling_average(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&lookback._1y,
|
&lookback._1y,
|
||||||
&self.subsidy.block.cents.height,
|
&self.subsidy.block.cents,
|
||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
|||||||
@@ -93,8 +93,8 @@ impl Vecs {
|
|||||||
|vec| {
|
|vec| {
|
||||||
Ok(vec.compute_transform2(
|
Ok(vec.compute_transform2(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&self.base.blocks_mined.block.height,
|
&self.base.blocks_mined.block,
|
||||||
&mining.rewards.coinbase.block.sats.height,
|
&mining.rewards.coinbase.block.sats,
|
||||||
|(h, mask, val, ..)| (h, MaskSats::apply(mask, val)),
|
|(h, mask, val, ..)| (h, MaskSats::apply(mask, val)),
|
||||||
exit,
|
exit,
|
||||||
)?)
|
)?)
|
||||||
|
|||||||
@@ -14,8 +14,8 @@ impl Vecs {
|
|||||||
starting_indexes: &Indexes,
|
starting_indexes: &Indexes,
|
||||||
exit: &Exit,
|
exit: &Exit,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let op_return_height = &scripts.value.op_return.block.sats.height;
|
let op_return_height = &scripts.value.op_return.block.sats;
|
||||||
let unclaimed_height = &mining.rewards.unclaimed.block.sats.height;
|
let unclaimed_height = &mining.rewards.unclaimed.block.sats;
|
||||||
|
|
||||||
self.total.compute(
|
self.total.compute(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ impl Vecs {
|
|||||||
self.native.height.compute_rolling_ratio(
|
self.native.height.compute_rolling_ratio(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&blocks.lookback._1y,
|
&blocks.lookback._1y,
|
||||||
&transactions.volume.transfer_volume.block.sats.height,
|
&transactions.volume.transfer_volume.block.sats,
|
||||||
&circulating_supply.sats.height,
|
&circulating_supply.sats.height,
|
||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
@@ -30,7 +30,7 @@ impl Vecs {
|
|||||||
self.fiat.height.compute_rolling_ratio(
|
self.fiat.height.compute_rolling_ratio(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&blocks.lookback._1y,
|
&blocks.lookback._1y,
|
||||||
&transactions.volume.transfer_volume.block.usd.height,
|
&transactions.volume.transfer_volume.block.usd,
|
||||||
&circulating_supply.usd.height,
|
&circulating_supply.usd.height,
|
||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
|
|||||||
@@ -17,9 +17,9 @@ impl Vecs {
|
|||||||
+ indexer.vecs.transactions.txid.version();
|
+ indexer.vecs.transactions.txid.version();
|
||||||
|
|
||||||
for vec in [
|
for vec in [
|
||||||
&mut self.v1.block.height,
|
&mut self.v1.block,
|
||||||
&mut self.v2.block.height,
|
&mut self.v2.block,
|
||||||
&mut self.v3.block.height,
|
&mut self.v3.block,
|
||||||
] {
|
] {
|
||||||
vec.validate_and_truncate(dep_version, starting_indexes.height)?;
|
vec.validate_and_truncate(dep_version, starting_indexes.height)?;
|
||||||
}
|
}
|
||||||
@@ -27,10 +27,9 @@ impl Vecs {
|
|||||||
let skip = self
|
let skip = self
|
||||||
.v1
|
.v1
|
||||||
.block
|
.block
|
||||||
.height
|
|
||||||
.len()
|
.len()
|
||||||
.min(self.v2.block.height.len())
|
.min(self.v2.block.len())
|
||||||
.min(self.v3.block.height.len());
|
.min(self.v3.block.len());
|
||||||
|
|
||||||
let first_tx_index = &indexer.vecs.transactions.first_tx_index;
|
let first_tx_index = &indexer.vecs.transactions.first_tx_index;
|
||||||
let end = first_tx_index.len();
|
let end = first_tx_index.len();
|
||||||
@@ -39,9 +38,9 @@ impl Vecs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Truncate all 3 to skip, then push (no per-element bounds checks).
|
// Truncate all 3 to skip, then push (no per-element bounds checks).
|
||||||
self.v1.block.height.truncate_if_needed_at(skip)?;
|
self.v1.block.truncate_if_needed_at(skip)?;
|
||||||
self.v2.block.height.truncate_if_needed_at(skip)?;
|
self.v2.block.truncate_if_needed_at(skip)?;
|
||||||
self.v3.block.height.truncate_if_needed_at(skip)?;
|
self.v3.block.truncate_if_needed_at(skip)?;
|
||||||
|
|
||||||
// Single cursor over tx_version — scanned once for all 3 version counts.
|
// Single cursor over tx_version — scanned once for all 3 version counts.
|
||||||
let mut cursor = indexer.vecs.transactions.tx_version.cursor();
|
let mut cursor = indexer.vecs.transactions.tx_version.cursor();
|
||||||
@@ -69,23 +68,23 @@ impl Vecs {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.v1.block.height.push(StoredU64::from(c1 as u64));
|
self.v1.block.push(StoredU64::from(c1 as u64));
|
||||||
self.v2.block.height.push(StoredU64::from(c2 as u64));
|
self.v2.block.push(StoredU64::from(c2 as u64));
|
||||||
self.v3.block.height.push(StoredU64::from(c3 as u64));
|
self.v3.block.push(StoredU64::from(c3 as u64));
|
||||||
|
|
||||||
if self.v1.block.height.batch_limit_reached() {
|
if self.v1.block.batch_limit_reached() {
|
||||||
let _lock = exit.lock();
|
let _lock = exit.lock();
|
||||||
self.v1.block.height.write()?;
|
self.v1.block.write()?;
|
||||||
self.v2.block.height.write()?;
|
self.v2.block.write()?;
|
||||||
self.v3.block.height.write()?;
|
self.v3.block.write()?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
let _lock = exit.lock();
|
let _lock = exit.lock();
|
||||||
self.v1.block.height.write()?;
|
self.v1.block.write()?;
|
||||||
self.v2.block.height.write()?;
|
self.v2.block.write()?;
|
||||||
self.v3.block.height.write()?;
|
self.v3.block.write()?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Derive cumulative + sums from base
|
// Derive cumulative + sums from base
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ impl Query {
|
|||||||
let current_height = self.height().to_usize();
|
let current_height = self.height().to_usize();
|
||||||
let start = current_height.saturating_sub(time_period.block_count());
|
let start = current_height.saturating_sub(time_period.block_count());
|
||||||
|
|
||||||
let coinbase_vec = &computer.mining.rewards.coinbase.block.sats.height;
|
let coinbase_vec = &computer.mining.rewards.coinbase.block.sats;
|
||||||
let timestamp_vec = &indexer.vecs.blocks.timestamp;
|
let timestamp_vec = &indexer.vecs.blocks.timestamp;
|
||||||
|
|
||||||
match time_period {
|
match time_period {
|
||||||
|
|||||||
@@ -12,9 +12,9 @@ impl Query {
|
|||||||
let end_block = current_height;
|
let end_block = current_height;
|
||||||
let start_block = Height::from(current_height.to_usize().saturating_sub(block_count - 1));
|
let start_block = Height::from(current_height.to_usize().saturating_sub(block_count - 1));
|
||||||
|
|
||||||
let coinbase_vec = &computer.mining.rewards.coinbase.block.sats.height;
|
let coinbase_vec = &computer.mining.rewards.coinbase.block.sats;
|
||||||
let fee_vec = &computer.mining.rewards.fees.block.sats.height;
|
let fee_vec = &computer.mining.rewards.fees.block.sats;
|
||||||
let tx_count_vec = &computer.transactions.count.total.block.height;
|
let tx_count_vec = &computer.transactions.count.total.block;
|
||||||
|
|
||||||
let start = start_block.to_usize();
|
let start = start_block.to_usize();
|
||||||
let end = end_block.to_usize() + 1;
|
let end = end_block.to_usize() + 1;
|
||||||
|
|||||||
Reference in New Issue
Block a user