mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-05-02 02:20:00 -07:00
computer: snapshot
This commit is contained in:
@@ -225,6 +225,7 @@ impl AddressTypeToAddrCountVecs {
|
||||
#[derive(Clone, Traversable)]
|
||||
pub struct AddrCountVecs {
|
||||
pub all: ComputedBlockLast<StoredU64>,
|
||||
#[traversable(flatten)]
|
||||
pub by_addresstype: AddressTypeToAddrCountVecs,
|
||||
}
|
||||
|
||||
|
||||
@@ -8,10 +8,7 @@ use rayon::prelude::*;
|
||||
use vecdb::{AnyStoredVec, AnyVec, Database, Exit, GenericStoredVec, IterableVec};
|
||||
|
||||
use crate::{
|
||||
ComputeIndexes,
|
||||
distribution::state::AddressCohortState,
|
||||
indexes,
|
||||
internal::ComputedBlockLast,
|
||||
ComputeIndexes, distribution::state::AddressCohortState, indexes, internal::ComputedBlockLast,
|
||||
price,
|
||||
};
|
||||
|
||||
@@ -155,7 +152,7 @@ impl DynCohortVecs for AddressCohortVecs {
|
||||
state.inner.supply.value = self
|
||||
.metrics
|
||||
.supply
|
||||
.supply
|
||||
.total
|
||||
.sats
|
||||
.height
|
||||
.read_once(prev_height)?;
|
||||
|
||||
@@ -7,7 +7,7 @@ use brk_types::{DateIndex, Dollars, Height, Version};
|
||||
use rayon::prelude::*;
|
||||
use vecdb::{AnyStoredVec, Database, Exit, IterableVec};
|
||||
|
||||
use crate::{ComputeIndexes, indexes, price, distribution::state::UTXOCohortState};
|
||||
use crate::{ComputeIndexes, distribution::state::UTXOCohortState, indexes, price};
|
||||
|
||||
use crate::distribution::metrics::{CohortMetrics, ImportConfig, RealizedMetrics, SupplyMetrics};
|
||||
|
||||
@@ -149,7 +149,7 @@ impl DynCohortVecs for UTXOCohortVecs {
|
||||
state.supply.value = self
|
||||
.metrics
|
||||
.supply
|
||||
.supply
|
||||
.total
|
||||
.sats
|
||||
.height
|
||||
.read_once(prev_height)?;
|
||||
|
||||
@@ -92,7 +92,11 @@ impl CohortMetrics {
|
||||
|
||||
/// Get minimum length across height-indexed vectors written in block loop.
|
||||
pub fn min_stateful_height_len(&self) -> usize {
|
||||
let mut min = self.supply.min_len().min(self.outputs.min_len()).min(self.activity.min_len());
|
||||
let mut min = self
|
||||
.supply
|
||||
.min_len()
|
||||
.min(self.outputs.min_len())
|
||||
.min(self.activity.min_len());
|
||||
|
||||
if let Some(realized) = &self.realized {
|
||||
min = min.min(realized.min_stateful_height_len());
|
||||
@@ -124,7 +128,8 @@ impl CohortMetrics {
|
||||
/// Push state values to height-indexed vectors.
|
||||
pub fn truncate_push(&mut self, height: Height, state: &CohortState) -> Result<()> {
|
||||
self.supply.truncate_push(height, state.supply.value)?;
|
||||
self.outputs.truncate_push(height, state.supply.utxo_count)?;
|
||||
self.outputs
|
||||
.truncate_push(height, state.supply.utxo_count)?;
|
||||
self.activity.truncate_push(
|
||||
height,
|
||||
state.sent,
|
||||
@@ -309,8 +314,7 @@ impl CohortMetrics {
|
||||
) -> Result<()> {
|
||||
self.supply
|
||||
.compute_rest_part1(indexes, price, starting_indexes, exit)?;
|
||||
self.outputs
|
||||
.compute_rest(indexes, starting_indexes, exit)?;
|
||||
self.outputs.compute_rest(indexes, starting_indexes, exit)?;
|
||||
self.activity
|
||||
.compute_rest_part1(indexes, starting_indexes, exit)?;
|
||||
|
||||
@@ -345,7 +349,7 @@ impl CohortMetrics {
|
||||
indexes,
|
||||
price,
|
||||
starting_indexes,
|
||||
&self.supply.supply.bitcoin.height,
|
||||
&self.supply.total.bitcoin.height,
|
||||
height_to_market_cap,
|
||||
dateindex_to_market_cap,
|
||||
exit,
|
||||
|
||||
@@ -77,14 +77,14 @@ impl RelativeMetrics {
|
||||
let compute_rel_to_all = cfg.compute_rel_to_all();
|
||||
|
||||
// Global sources from "all" cohort
|
||||
let global_supply_sats_height = all_supply.map(|s| &s.supply.sats.height);
|
||||
let global_supply_sats_difficultyepoch = all_supply.map(|s| &s.supply.sats.difficultyepoch);
|
||||
let global_supply_sats_dates = all_supply.map(|s| &s.supply.sats.rest.dates);
|
||||
let global_supply_sats_dateindex = all_supply.map(|s| &s.supply.sats.rest.dateindex);
|
||||
let global_market_cap = all_supply.and_then(|s| s.supply.dollars.as_ref());
|
||||
let global_supply_sats_height = all_supply.map(|s| &s.total.sats.height);
|
||||
let global_supply_sats_difficultyepoch = all_supply.map(|s| &s.total.sats.difficultyepoch);
|
||||
let global_supply_sats_dates = all_supply.map(|s| &s.total.sats.rest.dates);
|
||||
let global_supply_sats_dateindex = all_supply.map(|s| &s.total.sats.rest.dateindex);
|
||||
let global_market_cap = all_supply.and_then(|s| s.total.dollars.as_ref());
|
||||
|
||||
// Own market cap source
|
||||
let own_market_cap = supply.supply.dollars.as_ref();
|
||||
let own_market_cap = supply.total.dollars.as_ref();
|
||||
|
||||
Ok(Self {
|
||||
// === Supply Relative to Circulating Supply (lazy from global supply) ===
|
||||
@@ -94,8 +94,8 @@ impl RelativeMetrics {
|
||||
LazyBinaryDateLast::from_both_derived_last::<PercentageSatsF64>(
|
||||
&cfg.name("supply_rel_to_circulating_supply"),
|
||||
cfg.version + v1,
|
||||
supply.supply.sats.rest.dateindex.boxed_clone(),
|
||||
&supply.supply.sats.rest.dates,
|
||||
supply.total.sats.rest.dateindex.boxed_clone(),
|
||||
&supply.total.sats.rest.dates,
|
||||
global_supply_sats_dateindex.unwrap().boxed_clone(),
|
||||
global_supply_sats_dates.unwrap(),
|
||||
)
|
||||
@@ -107,34 +107,34 @@ impl RelativeMetrics {
|
||||
&cfg.name("supply_in_profit_rel_to_own_supply"),
|
||||
cfg.version + v1,
|
||||
unrealized.supply_in_profit.height.boxed_clone(),
|
||||
supply.supply.sats.height.boxed_clone(),
|
||||
unrealized.supply_in_profit.difficultyepoch.boxed_clone(),
|
||||
supply.supply.sats.difficultyepoch.boxed_clone(),
|
||||
supply.total.sats.height.boxed_clone(),
|
||||
unrealized.supply_in_profit.difficultyepoch.sats.boxed_clone(),
|
||||
supply.total.sats.difficultyepoch.boxed_clone(),
|
||||
unrealized
|
||||
.supply_in_profit
|
||||
.indexes
|
||||
.sats_dateindex
|
||||
.boxed_clone(),
|
||||
&unrealized.supply_in_profit.indexes.sats,
|
||||
supply.supply.sats.rest.dateindex.boxed_clone(),
|
||||
&supply.supply.sats.rest.dates,
|
||||
supply.total.sats.rest.dateindex.boxed_clone(),
|
||||
&supply.total.sats.rest.dates,
|
||||
),
|
||||
supply_in_loss_rel_to_own_supply:
|
||||
LazyBinaryBlockLast::from_height_difficultyepoch_dates::<PercentageSatsF64>(
|
||||
&cfg.name("supply_in_loss_rel_to_own_supply"),
|
||||
cfg.version + v1,
|
||||
unrealized.supply_in_loss.height.boxed_clone(),
|
||||
supply.supply.sats.height.boxed_clone(),
|
||||
unrealized.supply_in_loss.difficultyepoch.boxed_clone(),
|
||||
supply.supply.sats.difficultyepoch.boxed_clone(),
|
||||
supply.total.sats.height.boxed_clone(),
|
||||
unrealized.supply_in_loss.difficultyepoch.sats.boxed_clone(),
|
||||
supply.total.sats.difficultyepoch.boxed_clone(),
|
||||
unrealized
|
||||
.supply_in_loss
|
||||
.indexes
|
||||
.sats_dateindex
|
||||
.boxed_clone(),
|
||||
&unrealized.supply_in_loss.indexes.sats,
|
||||
supply.supply.sats.rest.dateindex.boxed_clone(),
|
||||
&supply.supply.sats.rest.dates,
|
||||
supply.total.sats.rest.dateindex.boxed_clone(),
|
||||
&supply.total.sats.rest.dates,
|
||||
),
|
||||
|
||||
// === Supply in Profit/Loss Relative to Circulating Supply (lazy from global supply) ===
|
||||
@@ -146,7 +146,7 @@ impl RelativeMetrics {
|
||||
cfg.version + v1,
|
||||
unrealized.supply_in_profit.height.boxed_clone(),
|
||||
global_supply_sats_height.unwrap().boxed_clone(),
|
||||
unrealized.supply_in_profit.difficultyepoch.boxed_clone(),
|
||||
unrealized.supply_in_profit.difficultyepoch.sats.boxed_clone(),
|
||||
global_supply_sats_difficultyepoch.unwrap().boxed_clone(),
|
||||
unrealized
|
||||
.supply_in_profit
|
||||
@@ -166,7 +166,7 @@ impl RelativeMetrics {
|
||||
cfg.version + v1,
|
||||
unrealized.supply_in_loss.height.boxed_clone(),
|
||||
global_supply_sats_height.unwrap().boxed_clone(),
|
||||
unrealized.supply_in_loss.difficultyepoch.boxed_clone(),
|
||||
unrealized.supply_in_loss.difficultyepoch.sats.boxed_clone(),
|
||||
global_supply_sats_difficultyepoch.unwrap().boxed_clone(),
|
||||
unrealized
|
||||
.supply_in_loss
|
||||
|
||||
@@ -4,13 +4,13 @@ use brk_types::{Height, Sats, Version};
|
||||
|
||||
use crate::ComputeIndexes;
|
||||
use rayon::prelude::*;
|
||||
use vecdb::{AnyStoredVec, AnyVec, Exit, GenericStoredVec, IterableCloneableVec};
|
||||
use vecdb::{AnyStoredVec, AnyVec, Exit, GenericStoredVec};
|
||||
|
||||
use crate::{
|
||||
indexes,
|
||||
internal::{
|
||||
HalfClosePriceTimesSats, HalveDollars, HalveSats, HalveSatsToBitcoin, LazyBlockValue,
|
||||
LazyValueDateLast, ValueBlockLast,
|
||||
HalfClosePriceTimesSats, HalveDollars, HalveSats, HalveSatsToBitcoin, LazyBinaryLastBlockValue,
|
||||
ValueBlockLast,
|
||||
},
|
||||
price,
|
||||
};
|
||||
@@ -20,9 +20,8 @@ use super::ImportConfig;
|
||||
/// Supply metrics for a cohort.
|
||||
#[derive(Clone, Traversable)]
|
||||
pub struct SupplyMetrics {
|
||||
pub supply: ValueBlockLast,
|
||||
pub supply_half_value: LazyBlockValue,
|
||||
pub supply_half: LazyValueDateLast,
|
||||
pub total: ValueBlockLast,
|
||||
pub halved: LazyBinaryLastBlockValue,
|
||||
}
|
||||
|
||||
impl SupplyMetrics {
|
||||
@@ -38,52 +37,39 @@ impl SupplyMetrics {
|
||||
compute_dollars,
|
||||
)?;
|
||||
|
||||
let price_source = cfg
|
||||
.price
|
||||
.map(|p| p.usd.split.close.height.boxed_clone());
|
||||
|
||||
// Create lazy supply_half from supply sources
|
||||
let supply_half_value =
|
||||
LazyBlockValue::from_sources::<HalveSats, HalveSatsToBitcoin, HalfClosePriceTimesSats>(
|
||||
&cfg.name("supply_half"),
|
||||
supply.sats.height.boxed_clone(),
|
||||
price_source,
|
||||
cfg.version,
|
||||
);
|
||||
|
||||
let supply_half = LazyValueDateLast::from_block_source::<
|
||||
let supply_half = LazyBinaryLastBlockValue::from_block_source::<
|
||||
HalveSats,
|
||||
HalveSatsToBitcoin,
|
||||
HalfClosePriceTimesSats,
|
||||
HalveDollars,
|
||||
>(&cfg.name("supply_half"), &supply, cfg.version);
|
||||
>(&cfg.name("supply_half"), &supply, cfg.price, cfg.version);
|
||||
|
||||
Ok(Self {
|
||||
supply,
|
||||
supply_half_value,
|
||||
supply_half,
|
||||
total: supply,
|
||||
halved: supply_half,
|
||||
})
|
||||
}
|
||||
|
||||
/// Get minimum length across height-indexed vectors.
|
||||
pub fn min_len(&self) -> usize {
|
||||
self.supply.sats.height.len()
|
||||
self.total.sats.height.len()
|
||||
}
|
||||
|
||||
/// Push supply state values to height-indexed vectors.
|
||||
pub fn truncate_push(&mut self, height: Height, supply: Sats) -> Result<()> {
|
||||
self.supply.sats.height.truncate_push(height, supply)?;
|
||||
self.total.sats.height.truncate_push(height, supply)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Write height-indexed vectors to disk.
|
||||
pub fn write(&mut self) -> Result<()> {
|
||||
self.supply.sats.height.write()?;
|
||||
self.total.sats.height.write()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Returns a parallel iterator over all vecs for parallel writing.
|
||||
pub fn par_iter_mut(&mut self) -> impl ParallelIterator<Item = &mut dyn AnyStoredVec> {
|
||||
vec![&mut self.supply.sats.height as &mut dyn AnyStoredVec].into_par_iter()
|
||||
vec![&mut self.total.sats.height as &mut dyn AnyStoredVec].into_par_iter()
|
||||
}
|
||||
|
||||
/// Validate computed versions against base version.
|
||||
@@ -99,11 +85,11 @@ impl SupplyMetrics {
|
||||
others: &[&Self],
|
||||
exit: &Exit,
|
||||
) -> Result<()> {
|
||||
self.supply.sats.height.compute_sum_of_others(
|
||||
self.total.sats.height.compute_sum_of_others(
|
||||
starting_indexes.height,
|
||||
&others
|
||||
.iter()
|
||||
.map(|v| &v.supply.sats.height)
|
||||
.map(|v| &v.total.sats.height)
|
||||
.collect::<Vec<_>>(),
|
||||
exit,
|
||||
)?;
|
||||
@@ -118,7 +104,7 @@ impl SupplyMetrics {
|
||||
starting_indexes: &ComputeIndexes,
|
||||
exit: &Exit,
|
||||
) -> Result<()> {
|
||||
self.supply
|
||||
self.total
|
||||
.compute_rest(indexes, price, starting_indexes, exit)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -297,13 +297,13 @@ impl Vecs {
|
||||
let supply_metrics = &self.utxo_cohorts.all.metrics.supply;
|
||||
|
||||
let height_to_market_cap = supply_metrics
|
||||
.supply
|
||||
.total
|
||||
.dollars
|
||||
.as_ref()
|
||||
.map(|d| d.height.clone());
|
||||
|
||||
let dateindex_to_market_cap = supply_metrics
|
||||
.supply
|
||||
.total
|
||||
.dollars
|
||||
.as_ref()
|
||||
.map(|d| d.dateindex.0.clone());
|
||||
@@ -373,16 +373,10 @@ fn adjust_for_dateindex_gap(
|
||||
}
|
||||
|
||||
// Get the dateindex at the height we want to resume at
|
||||
let required_dateindex: usize = indexes
|
||||
.height
|
||||
.dateindex
|
||||
.read_once(height_based_min)?
|
||||
.into();
|
||||
let required_dateindex: usize = indexes.height.dateindex.read_once(height_based_min)?.into();
|
||||
|
||||
// If dateindex vecs are behind, restart from first height of the missing day
|
||||
if dateindex_min < required_dateindex
|
||||
&& dateindex_min < indexes.dateindex.first_height.len()
|
||||
{
|
||||
if dateindex_min < required_dateindex && dateindex_min < indexes.dateindex.first_height.len() {
|
||||
Ok(indexes
|
||||
.dateindex
|
||||
.first_height
|
||||
|
||||
Reference in New Issue
Block a user