global: snapshot

This commit is contained in:
nym21
2026-03-11 13:43:46 +01:00
parent c5d63b3090
commit 984122f394
82 changed files with 3962 additions and 3412 deletions
@@ -43,7 +43,7 @@ impl Vecs {
)?;
// Compute blocks before next adjustment
self.blocks_before_next_adjustment
self.blocks_before_next
.height
.compute_transform(
starting_indexes.height,
@@ -53,9 +53,9 @@ impl Vecs {
)?;
// Compute days before next adjustment
self.days_before_next_adjustment.height.compute_transform(
self.days_before_next.height.compute_transform(
starting_indexes.height,
&self.blocks_before_next_adjustment.height,
&self.blocks_before_next.height,
|(h, blocks, ..)| (h, (*blocks as f32 / TARGET_BLOCKS_PER_DAY_F32).into()),
exit,
)?;
@@ -33,13 +33,13 @@ impl Vecs {
indexes,
)?,
epoch: ComputedPerBlock::forced_import(db, "difficulty_epoch", version, indexes)?,
blocks_before_next_adjustment: ComputedPerBlock::forced_import(
blocks_before_next: ComputedPerBlock::forced_import(
db,
"blocks_before_next_difficulty_adjustment",
version + v2,
indexes,
)?,
days_before_next_adjustment: ComputedPerBlock::forced_import(
days_before_next: ComputedPerBlock::forced_import(
db,
"days_before_next_difficulty_adjustment",
version + v2,
@@ -9,6 +9,6 @@ pub struct Vecs<M: StorageMode = Rw> {
pub as_hash: ComputedPerBlock<StoredF64, M>,
pub adjustment: PercentPerBlock<BasisPointsSigned32, M>,
pub epoch: ComputedPerBlock<Epoch, M>,
pub blocks_before_next_adjustment: ComputedPerBlock<StoredU32, M>,
pub days_before_next_adjustment: ComputedPerBlock<StoredF32, M>,
pub blocks_before_next: ComputedPerBlock<StoredU32, M>,
pub days_before_next: ComputedPerBlock<StoredF32, M>,
}
@@ -20,16 +20,16 @@ impl Vecs {
exit,
)?;
self.blocks_before_next_halving.height.compute_transform(
self.blocks_before_next.height.compute_transform(
starting_indexes.height,
&indexes.height.identity,
|(h, ..)| (h, StoredU32::from(h.left_before_next_halving())),
exit,
)?;
self.days_before_next_halving.height.compute_transform(
self.days_before_next.height.compute_transform(
starting_indexes.height,
&self.blocks_before_next_halving.height,
&self.blocks_before_next.height,
|(h, blocks, ..)| (h, (*blocks as f32 / TARGET_BLOCKS_PER_DAY_F32).into()),
exit,
)?;
@@ -15,13 +15,13 @@ impl Vecs {
Ok(Self {
epoch: ComputedPerBlock::forced_import(db, "halving_epoch", version, indexes)?,
blocks_before_next_halving: ComputedPerBlock::forced_import(
blocks_before_next: ComputedPerBlock::forced_import(
db,
"blocks_before_next_halving",
version + v2,
indexes,
)?,
days_before_next_halving: ComputedPerBlock::forced_import(
days_before_next: ComputedPerBlock::forced_import(
db,
"days_before_next_halving",
version + v2,
@@ -6,6 +6,6 @@ use crate::internal::ComputedPerBlock;
#[derive(Traversable)]
pub struct Vecs<M: StorageMode = Rw> {
pub epoch: ComputedPerBlock<Halving, M>,
pub blocks_before_next_halving: ComputedPerBlock<StoredU32, M>,
pub days_before_next_halving: ComputedPerBlock<StoredF32, M>,
pub blocks_before_next: ComputedPerBlock<StoredU32, M>,
pub days_before_next: ComputedPerBlock<StoredF32, M>,
}
@@ -23,7 +23,7 @@ impl Vecs {
self.hodl_bank.compute_cumulative_transformed_binary(
starting_indexes.height,
&prices.price.usd.height,
&prices.spot.usd.height,
&self.vocdd_median_1y,
|price, median| StoredF64::from(f64::from(price) - f64::from(median)),
exit,
@@ -31,7 +31,7 @@ impl Vecs {
self.value.height.compute_divide(
starting_indexes.height,
&prices.price.usd.height,
&prices.spot.usd.height,
&self.hodl_bank,
exit,
)?;
@@ -27,7 +27,7 @@ impl Vecs {
.compute(starting_indexes.height, &window_starts, exit, |vec| {
vec.compute_multiply(
starting_indexes.height,
&prices.price.usd.height,
&prices.spot.usd.height,
&coinblocks_destroyed.raw.height,
exit,
)?;
@@ -38,7 +38,7 @@ impl Vecs {
.compute(starting_indexes.height, &window_starts, exit, |vec| {
vec.compute_multiply(
starting_indexes.height,
&prices.price.usd.height,
&prices.spot.usd.height,
&activity.coinblocks_created.raw.height,
exit,
)?;
@@ -49,7 +49,7 @@ impl Vecs {
.compute(starting_indexes.height, &window_starts, exit, |vec| {
vec.compute_multiply(
starting_indexes.height,
&prices.price.usd.height,
&prices.spot.usd.height,
&activity.coinblocks_stored.raw.height,
exit,
)?;
@@ -63,7 +63,7 @@ impl Vecs {
.compute(starting_indexes.height, &window_starts, exit, |vec| {
vec.compute_transform3(
starting_indexes.height,
&prices.price.usd.height,
&prices.spot.usd.height,
&coindays_destroyed.raw.height,
circulating_supply,
|(i, price, cdd, supply, _): (_, Dollars, StoredF64, Bitcoin, _)| {
@@ -144,42 +144,42 @@ pub(crate) fn process_blocks(
let first_p2a_vec = indexer
.vecs
.addresses
.first_p2aaddressindex
.p2a.first_index
.collect_range_at(start_usize, end_usize);
let first_p2pk33_vec = indexer
.vecs
.addresses
.first_p2pk33addressindex
.p2pk33.first_index
.collect_range_at(start_usize, end_usize);
let first_p2pk65_vec = indexer
.vecs
.addresses
.first_p2pk65addressindex
.p2pk65.first_index
.collect_range_at(start_usize, end_usize);
let first_p2pkh_vec = indexer
.vecs
.addresses
.first_p2pkhaddressindex
.p2pkh.first_index
.collect_range_at(start_usize, end_usize);
let first_p2sh_vec = indexer
.vecs
.addresses
.first_p2shaddressindex
.p2sh.first_index
.collect_range_at(start_usize, end_usize);
let first_p2tr_vec = indexer
.vecs
.addresses
.first_p2traddressindex
.p2tr.first_index
.collect_range_at(start_usize, end_usize);
let first_p2wpkh_vec = indexer
.vecs
.addresses
.first_p2wpkhaddressindex
.p2wpkh.first_index
.collect_range_at(start_usize, end_usize);
let first_p2wsh_vec = indexer
.vecs
.addresses
.first_p2wshaddressindex
.p2wsh.first_index
.collect_range_at(start_usize, end_usize);
// Track running totals - recover from previous height if resuming
@@ -182,7 +182,7 @@ impl RealizedMinimal {
self.nupl.bps.height.compute_transform2(
starting_indexes.height,
&prices.price.cents.height,
&prices.spot.cents.height,
&self.price.cents.height,
|(i, price, realized_price, ..)| {
let p = price.as_u128();
@@ -10,11 +10,11 @@ use crate::distribution::metrics::{ImportConfig, UnrealizedCore};
/// Extended relative metrics for own total unrealized PnL (extended only).
#[derive(Traversable)]
pub struct RelativeExtendedOwnPnl<M: StorageMode = Rw> {
#[traversable(wrap = "unrealized/profit", rename = "rel_to_own_gross_pnl")]
#[traversable(wrap = "unrealized/profit", rename = "rel_to_own_gross")]
pub unrealized_profit_rel_to_own_gross_pnl: PercentPerBlock<BasisPoints16, M>,
#[traversable(wrap = "unrealized/loss", rename = "rel_to_own_gross_pnl")]
#[traversable(wrap = "unrealized/loss", rename = "rel_to_own_gross")]
pub unrealized_loss_rel_to_own_gross_pnl: PercentPerBlock<BasisPoints16, M>,
#[traversable(wrap = "unrealized/net_pnl", rename = "rel_to_own_gross_pnl")]
#[traversable(wrap = "unrealized/net_pnl", rename = "rel_to_own_gross")]
pub net_unrealized_pnl_rel_to_own_gross_pnl: PercentPerBlock<BasisPointsSigned32, M>,
}
@@ -10,11 +10,11 @@ use crate::distribution::metrics::{ImportConfig, SupplyCore};
/// Relative-to-all metrics (not present for the "all" cohort itself).
#[derive(Traversable)]
pub struct RelativeToAll<M: StorageMode = Rw> {
#[traversable(wrap = "supply", rename = "rel_to_circulating_supply")]
#[traversable(wrap = "supply", rename = "rel_to_circulating")]
pub supply_rel_to_circulating_supply: PercentPerBlock<BasisPoints16, M>,
#[traversable(wrap = "supply/in_profit", rename = "rel_to_circulating_supply")]
#[traversable(wrap = "supply/in_profit", rename = "rel_to_circulating")]
pub supply_in_profit_rel_to_circulating_supply: PercentPerBlock<BasisPoints16, M>,
#[traversable(wrap = "supply/in_loss", rename = "rel_to_circulating_supply")]
#[traversable(wrap = "supply/in_loss", rename = "rel_to_circulating")]
pub supply_in_loss_rel_to_circulating_supply: PercentPerBlock<BasisPoints16, M>,
}
@@ -136,7 +136,7 @@ impl UnrealizedFull {
starting_indexes.height,
&self.inner.investor_cap_in_loss_raw,
&self.inner.invested_capital_in_loss_raw,
&prices.price.cents.height,
&prices.spot.cents.height,
|(h, investor_cap, invested_cap, spot, ..)| {
if invested_cap.inner() == 0 {
return (h, Cents::ZERO);
@@ -152,7 +152,7 @@ impl UnrealizedFull {
starting_indexes.height,
&self.inner.investor_cap_in_profit_raw,
&self.inner.invested_capital_in_profit_raw,
&prices.price.cents.height,
&prices.spot.cents.height,
|(h, investor_cap, invested_cap, spot, ..)| {
if invested_cap.inner() == 0 {
return (h, Cents::ZERO);
+1 -2
View File
@@ -3,11 +3,10 @@ mod block;
pub mod cohorts;
pub mod compute;
pub mod metrics;
mod range_map;
mod state;
mod vecs;
pub use range_map::RangeMap;
pub use brk_types::RangeMap;
pub use vecs::Vecs;
pub const DB_NAME: &str = "distribution";
@@ -1,103 +0,0 @@
use std::marker::PhantomData;
/// Direct-mapped cache size. Power of 2 for fast masking.
const CACHE_SIZE: usize = 128;
const CACHE_MASK: usize = CACHE_SIZE - 1;
/// Maps ranges of indices to values for efficient reverse lookups.
///
/// Instead of storing a value for every index, stores first_index values
/// in a sorted Vec and uses binary search to find the value for any index.
/// The value is derived from the position in the Vec.
///
/// Includes a direct-mapped cache for O(1) lookups when there's locality.
#[derive(Debug, Clone)]
pub struct RangeMap<I, V> {
/// Sorted vec of first_index values. Position in vec = value.
first_indexes: Vec<I>,
/// Direct-mapped cache: (range_low, range_high, value, occupied). Inline for zero indirection.
cache: [(I, I, V, bool); CACHE_SIZE],
_phantom: PhantomData<V>,
}
impl<I: Default + Copy, V: Default + Copy> Default for RangeMap<I, V> {
fn default() -> Self {
Self {
first_indexes: Vec::new(),
cache: [(I::default(), I::default(), V::default(), false); CACHE_SIZE],
_phantom: PhantomData,
}
}
}
impl<I: Ord + Copy + Default + Into<usize>, V: From<usize> + Copy + Default> RangeMap<I, V> {
/// Number of ranges stored.
pub(crate) fn len(&self) -> usize {
self.first_indexes.len()
}
/// Truncate to `new_len` ranges and clear the cache.
pub(crate) fn truncate(&mut self, new_len: usize) {
self.first_indexes.truncate(new_len);
self.clear_cache();
}
/// Push a new first_index. Value is implicitly the current length.
/// Must be called in order (first_index must be >= all previous).
#[inline]
pub(crate) fn push(&mut self, first_index: I) {
debug_assert!(
self.first_indexes
.last()
.is_none_or(|&last| first_index >= last),
"RangeMap: first_index must be monotonically increasing"
);
self.first_indexes.push(first_index);
}
/// Look up value for an index, checking cache first.
/// Returns the value (position) of the largest first_index <= given index.
#[inline]
pub(crate) fn get(&mut self, index: I) -> Option<V> {
if self.first_indexes.is_empty() {
return None;
}
// Direct-mapped cache lookup: O(1), no aging
let slot = Self::cache_slot(&index);
let entry = &self.cache[slot];
if entry.3 && index >= entry.0 && index < entry.1 {
return Some(entry.2);
}
// Cache miss - binary search
let pos = self.first_indexes.partition_point(|&first| first <= index);
if pos > 0 {
let value = V::from(pos - 1);
let low = self.first_indexes[pos - 1];
let is_last = pos == self.first_indexes.len();
// Cache non-last ranges (last range has unbounded high)
if !is_last {
let high = self.first_indexes[pos];
self.cache[slot] = (low, high, value, true);
}
Some(value)
} else {
None
}
}
#[inline]
fn cache_slot(index: &I) -> usize {
let v: usize = (*index).into();
v & CACHE_MASK
}
fn clear_cache(&mut self) {
for entry in self.cache.iter_mut() {
entry.3 = false;
}
}
}
+8 -2
View File
@@ -45,8 +45,10 @@ pub struct AddressMetricsVecs<M: StorageMode = Rw> {
pub total: TotalAddrCountVecs<M>,
pub new: NewAddrCountVecs<M>,
pub delta: DeltaVecs<M>,
#[traversable(wrap = "indexes", rename = "funded")]
pub funded_index:
LazyVecFrom1<FundedAddressIndex, FundedAddressIndex, FundedAddressIndex, FundedAddressData>,
#[traversable(wrap = "indexes", rename = "empty")]
pub empty_index:
LazyVecFrom1<EmptyAddressIndex, EmptyAddressIndex, EmptyAddressIndex, EmptyAddressData>,
}
@@ -59,9 +61,13 @@ pub struct Vecs<M: StorageMode = Rw> {
pub states_path: PathBuf,
pub supply_state: M::Stored<BytesVec<Height, SupplyState>>,
#[traversable(wrap = "addresses", rename = "indexes")]
pub any_address_indexes: AnyAddressIndexesVecs<M>,
#[traversable(wrap = "addresses", rename = "data")]
pub addresses_data: AddressesDataVecs<M>,
#[traversable(wrap = "cohorts", rename = "utxo")]
pub utxo_cohorts: UTXOCohorts<M>,
#[traversable(wrap = "cohorts", rename = "address")]
pub address_cohorts: AddressCohorts<M>,
pub coinblocks_destroyed: ComputedPerBlockCumulative<StoredF64, M>,
pub addresses: AddressMetricsVecs<M>,
@@ -213,7 +219,7 @@ impl Vecs {
exit: &Exit,
) -> Result<()> {
let cache_target_len = prices
.price
.spot
.cents
.height
.len()
@@ -225,7 +231,7 @@ impl Vecs {
self.cached_price_range_max.truncate(cache_target_len);
} else if cache_target_len > cache_current_len {
let new_prices = prices
.price
.spot
.cents
.height
.collect_range_at(cache_current_len, cache_target_len);
+12 -12
View File
@@ -94,7 +94,7 @@ impl Vecs {
identity: LazyVecFrom1::init(
"p2pk33addressindex",
version,
indexer.vecs.addresses.p2pk33bytes.read_only_boxed_clone(),
indexer.vecs.addresses.p2pk33.bytes.read_only_boxed_clone(),
|index, _| index,
),
},
@@ -102,7 +102,7 @@ impl Vecs {
identity: LazyVecFrom1::init(
"p2pk65addressindex",
version,
indexer.vecs.addresses.p2pk65bytes.read_only_boxed_clone(),
indexer.vecs.addresses.p2pk65.bytes.read_only_boxed_clone(),
|index, _| index,
),
},
@@ -110,7 +110,7 @@ impl Vecs {
identity: LazyVecFrom1::init(
"p2pkhaddressindex",
version,
indexer.vecs.addresses.p2pkhbytes.read_only_boxed_clone(),
indexer.vecs.addresses.p2pkh.bytes.read_only_boxed_clone(),
|index, _| index,
),
},
@@ -118,7 +118,7 @@ impl Vecs {
identity: LazyVecFrom1::init(
"p2shaddressindex",
version,
indexer.vecs.addresses.p2shbytes.read_only_boxed_clone(),
indexer.vecs.addresses.p2sh.bytes.read_only_boxed_clone(),
|index, _| index,
),
},
@@ -126,7 +126,7 @@ impl Vecs {
identity: LazyVecFrom1::init(
"p2traddressindex",
version,
indexer.vecs.addresses.p2trbytes.read_only_boxed_clone(),
indexer.vecs.addresses.p2tr.bytes.read_only_boxed_clone(),
|index, _| index,
),
},
@@ -134,7 +134,7 @@ impl Vecs {
identity: LazyVecFrom1::init(
"p2wpkhaddressindex",
version,
indexer.vecs.addresses.p2wpkhbytes.read_only_boxed_clone(),
indexer.vecs.addresses.p2wpkh.bytes.read_only_boxed_clone(),
|index, _| index,
),
},
@@ -142,7 +142,7 @@ impl Vecs {
identity: LazyVecFrom1::init(
"p2wshaddressindex",
version,
indexer.vecs.addresses.p2wshbytes.read_only_boxed_clone(),
indexer.vecs.addresses.p2wsh.bytes.read_only_boxed_clone(),
|index, _| index,
),
},
@@ -150,7 +150,7 @@ impl Vecs {
identity: LazyVecFrom1::init(
"p2aaddressindex",
version,
indexer.vecs.addresses.p2abytes.read_only_boxed_clone(),
indexer.vecs.addresses.p2a.bytes.read_only_boxed_clone(),
|index, _| index,
),
},
@@ -158,7 +158,7 @@ impl Vecs {
identity: LazyVecFrom1::init(
"p2msoutputindex",
version,
indexer.vecs.scripts.p2ms_to_txindex.read_only_boxed_clone(),
indexer.vecs.scripts.p2ms.to_txindex.read_only_boxed_clone(),
|index, _| index,
),
},
@@ -169,7 +169,7 @@ impl Vecs {
indexer
.vecs
.scripts
.empty_to_txindex
.empty.to_txindex
.read_only_boxed_clone(),
|index, _| index,
),
@@ -181,7 +181,7 @@ impl Vecs {
indexer
.vecs
.scripts
.unknown_to_txindex
.unknown.to_txindex
.read_only_boxed_clone(),
|index, _| index,
),
@@ -193,7 +193,7 @@ impl Vecs {
indexer
.vecs
.scripts
.opreturn_to_txindex
.opreturn.to_txindex
.read_only_boxed_clone(),
|index, _| index,
),
@@ -59,7 +59,7 @@ impl Amount<Height> {
self.cents.compute_binary::<Sats, Cents, SatsToCents>(
max_from,
&self.sats,
&prices.price.cents.height,
&prices.spot.cents.height,
exit,
)?;
Ok(())
@@ -68,7 +68,7 @@ impl AmountPerBlock {
self.cents.compute_binary::<Sats, Cents, SatsToCents>(
max_from,
&self.sats.height,
&prices.price.cents.height,
&prices.spot.cents.height,
exit,
)?;
Ok(())
@@ -62,7 +62,7 @@ impl AmountPerBlockCumulative {
self.base.cents.compute_binary::<Sats, Cents, SatsToCents>(
max_from,
&self.base.sats.height,
&prices.price.cents.height,
&prices.spot.cents.height,
exit,
)?;
@@ -60,7 +60,7 @@ impl AmountPerBlockCumulativeSum {
.compute_binary::<Sats, Cents, SatsToCents>(
max_from,
&self.base.sats.height,
&prices.price.cents.height,
&prices.spot.cents.height,
exit,
)?;
@@ -61,7 +61,7 @@ impl AmountPerBlockFull {
.compute_binary::<Sats, Cents, SatsToCents>(
max_from,
&self.base.sats.height,
&prices.price.cents.height,
&prices.spot.cents.height,
exit,
)?;
@@ -1,7 +1,7 @@
use brk_traversable::Traversable;
use brk_types::{
Day1, Day3, Epoch, FromCoarserIndex, Halving, Height, Hour1, Hour4, Hour12,
Minute10, Minute30, Month1, Month3, Month6, Version, Week1, Year1, Year10,
Day1, Day3, Epoch, FromCoarserIndex, Halving, Height, Hour1, Hour4, Hour12, Minute10, Minute30,
Month1, Month3, Month6, Version, Week1, Year1, Year10,
};
use derive_more::{Deref, DerefMut};
use schemars::JsonSchema;
@@ -70,7 +70,7 @@ where
};
}
fn for_each_range_from_coarser<
fn for_each_range<
I: VecIndex,
O: VecValue,
S1I: VecIndex + FromCoarserIndex<I>,
@@ -103,7 +103,7 @@ where
version,
height_source.clone(),
indexes.$idx.identity.read_only_boxed_clone(),
for_each_range_from_coarser,
for_each_range,
)
};
}
@@ -71,7 +71,7 @@ impl PriceWithRatioPerBlock {
F: FnMut(&mut EagerVec<PcoVec<Height, Cents>>) -> Result<()>,
{
compute_price(&mut self.cents.height)?;
self.compute_ratio(starting_indexes, &prices.price.cents.height, exit)
self.compute_ratio(starting_indexes, &prices.spot.cents.height, exit)
}
}
@@ -104,7 +104,7 @@ impl PriceWithRatioExtendedPerBlock {
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
let close_price = &prices.price.cents.height;
let close_price = &prices.spot.cents.height;
self.base.compute_ratio(starting_indexes, close_price, exit)?;
self.percentiles.compute(
starting_indexes,
@@ -13,17 +13,17 @@ impl Vecs {
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
self.price.cents.height.compute_all_time_high(
self.high.cents.height.compute_all_time_high(
starting_indexes.height,
&prices.price.cents.height,
&prices.spot.cents.height,
exit,
)?;
let mut ath_ts: Option<Timestamp> = None;
self.days_since.height.compute_transform3(
starting_indexes.height,
&self.price.cents.height,
&prices.price.cents.height,
&self.high.cents.height,
&prices.spot.cents.height,
&blocks.time.timestamp_monotonic,
|(i, ath, price, ts, slf)| {
if ath_ts.is_none() {
@@ -68,8 +68,8 @@ impl Vecs {
self.drawdown.compute_drawdown(
starting_indexes.height,
&prices.price.cents.height,
&self.price.cents.height,
&prices.spot.cents.height,
&self.high.cents.height,
exit,
)?;
+2 -2
View File
@@ -18,7 +18,7 @@ impl Vecs {
) -> Result<Self> {
let v = version + VERSION;
let price = Price::forced_import(db, "price_ath", v, indexes)?;
let high = Price::forced_import(db, "price_ath", v, indexes)?;
let max_days_between =
ComputedPerBlock::forced_import(db, "max_days_between_price_ath", v, indexes)?;
@@ -41,7 +41,7 @@ impl Vecs {
let drawdown = PercentPerBlock::forced_import(db, "price_drawdown", v, indexes)?;
Ok(Self {
price,
high,
drawdown,
days_since,
years_since,
+1 -1
View File
@@ -6,7 +6,7 @@ use crate::internal::{ComputedPerBlock, DerivedResolutions, PercentPerBlock, Pri
#[derive(Traversable)]
pub struct Vecs<M: StorageMode = Rw> {
pub price: Price<ComputedPerBlock<Cents, M>>,
pub high: Price<ComputedPerBlock<Cents, M>>,
pub drawdown: PercentPerBlock<BasisPointsSigned16, M>,
pub days_since: ComputedPerBlock<StoredF32, M>,
pub years_since: DerivedResolutions<StoredF32, StoredF32>,
@@ -98,7 +98,7 @@ impl Vecs {
{
returns.compute_binary::<Cents, Cents, RatioDiffCentsBps32>(
starting_indexes.height,
&prices.price.cents.height,
&prices.spot.cents.height,
&average_price.cents.height,
exit,
)?;
@@ -155,7 +155,7 @@ impl Vecs {
{
returns.compute_binary::<Cents, Cents, RatioDiffCentsBps32>(
starting_indexes.height,
&prices.price.cents.height,
&prices.spot.cents.height,
&lookback_price.cents.height,
exit,
)?;
@@ -253,7 +253,7 @@ impl Vecs {
{
returns.compute_binary::<Cents, Cents, RatioDiffCentsBps32>(
starting_indexes.height,
&prices.price.cents.height,
&prices.spot.cents.height,
&average_price.cents.height,
exit,
)?;
@@ -13,7 +13,7 @@ impl Vecs {
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
let price = &prices.price.cents.height;
let price = &prices.spot.cents.height;
for (price_lookback, days) in self.price_lookback.iter_mut_with_days() {
let window_starts = blocks.lookback.start_vec(days as usize);
@@ -13,7 +13,7 @@ impl Vecs {
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
let close = &prices.price.cents.height;
let close = &prices.spot.cents.height;
for (sma, period) in [
(&mut self.sma._1w, 7),
@@ -13,7 +13,7 @@ impl Vecs {
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
let price = &prices.price.cents.height;
let price = &prices.spot.cents.height;
for (min_vec, max_vec, starts) in [
(
@@ -22,7 +22,7 @@ impl Vecs {
{
returns.compute_binary::<Dollars, Dollars, RatioDiffDollarsBps32>(
starting_indexes.height,
&prices.price.usd.height,
&prices.spot.usd.height,
&lookback_price.usd.height,
exit,
)?;
@@ -24,7 +24,7 @@ impl Vecs {
) -> Result<()> {
// Stochastic Oscillator: K = (close - low_2w) / (high_2w - low_2w), stored as ratio (0-1)
{
let price = &prices.price.usd.height;
let price = &prices.spot.usd.height;
self.stoch_k.bps.height.compute_transform3(
starting_indexes.height,
price,
@@ -16,7 +16,7 @@ pub(super) fn compute(
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
let close = &prices.price.usd.height;
let close = &prices.spot.usd.height;
let ws_fast = blocks.lookback.start_vec(fast_days);
let ws_slow = blocks.lookback.start_vec(slow_days);
let ws_signal = blocks.lookback.start_vec(signal_days);
@@ -92,7 +92,7 @@ impl Vecs {
)?;
self.subsidy.compute(prices, starting_indexes.height, exit)?;
self.unclaimed_rewards.compute(
self.unclaimed.compute(
starting_indexes.height,
&window_starts,
prices,
@@ -23,7 +23,7 @@ impl Vecs {
)?,
subsidy: AmountPerBlockCumulative::forced_import(db, "subsidy", version, indexes)?,
fees: AmountPerBlockFull::forced_import(db, "fees", version, indexes)?,
unclaimed_rewards: AmountPerBlockCumulativeSum::forced_import(
unclaimed: AmountPerBlockCumulativeSum::forced_import(
db,
"unclaimed_rewards",
version,
@@ -12,13 +12,17 @@ pub struct Vecs<M: StorageMode = Rw> {
pub coinbase: AmountPerBlockCumulativeSum<M>,
pub subsidy: AmountPerBlockCumulative<M>,
pub fees: AmountPerBlockFull<M>,
pub unclaimed_rewards: AmountPerBlockCumulativeSum<M>,
pub unclaimed: AmountPerBlockCumulativeSum<M>,
#[traversable(wrap = "fees", rename = "dominance")]
pub fee_dominance: PercentPerBlock<BasisPoints16, M>,
#[traversable(rename = "fee_dominance")]
#[traversable(wrap = "fees", rename = "dominance")]
pub fee_dominance_rolling: PercentRollingWindows<BasisPoints16, M>,
#[traversable(wrap = "subsidy", rename = "dominance")]
pub subsidy_dominance: PercentPerBlock<BasisPoints16, M>,
#[traversable(rename = "subsidy_dominance")]
#[traversable(wrap = "subsidy", rename = "dominance")]
pub subsidy_dominance_rolling: PercentRollingWindows<BasisPoints16, M>,
#[traversable(wrap = "subsidy", rename = "sma_1y")]
pub subsidy_sma_1y: FiatPerBlock<Cents, M>,
#[traversable(wrap = "fees", rename = "ratio_multiple")]
pub fee_ratio_multiple: RatioRollingWindows<BasisPoints32, M>,
}
@@ -31,7 +31,7 @@ impl Vecs {
)
})?;
self.utxo_count.height.compute_transform3(
self.unspent.height.compute_transform3(
starting_indexes.height,
&self.total.full.cumulative,
&inputs_count.full.cumulative,
@@ -21,7 +21,7 @@ impl Vecs {
version,
indexes,
)?,
utxo_count: ComputedPerBlock::forced_import(
unspent: ComputedPerBlock::forced_import(
db,
"exact_utxo_count",
version,
@@ -7,5 +7,5 @@ use crate::internal::{ComputedPerBlock, ComputedPerBlockAggregated};
#[derive(Traversable)]
pub struct Vecs<M: StorageMode = Rw> {
pub total: ComputedPerBlockAggregated<StoredU64, M>,
pub utxo_count: ComputedPerBlock<StoredU64, M>,
pub unspent: ComputedPerBlock<StoredU64, M>,
}
+8 -8
View File
@@ -120,14 +120,14 @@ impl Vecs {
let first_txoutindex = indexer.vecs.transactions.first_txoutindex.reader();
let outputtype = indexer.vecs.outputs.outputtype.reader();
let typeindex = indexer.vecs.outputs.typeindex.reader();
let p2pk65 = indexer.vecs.addresses.p2pk65bytes.reader();
let p2pk33 = indexer.vecs.addresses.p2pk33bytes.reader();
let p2pkh = indexer.vecs.addresses.p2pkhbytes.reader();
let p2sh = indexer.vecs.addresses.p2shbytes.reader();
let p2wpkh = indexer.vecs.addresses.p2wpkhbytes.reader();
let p2wsh = indexer.vecs.addresses.p2wshbytes.reader();
let p2tr = indexer.vecs.addresses.p2trbytes.reader();
let p2a = indexer.vecs.addresses.p2abytes.reader();
let p2pk65 = indexer.vecs.addresses.p2pk65.bytes.reader();
let p2pk33 = indexer.vecs.addresses.p2pk33.bytes.reader();
let p2pkh = indexer.vecs.addresses.p2pkh.bytes.reader();
let p2sh = indexer.vecs.addresses.p2sh.bytes.reader();
let p2wpkh = indexer.vecs.addresses.p2wpkh.bytes.reader();
let p2wsh = indexer.vecs.addresses.p2wsh.bytes.reader();
let p2tr = indexer.vecs.addresses.p2tr.bytes.reader();
let p2a = indexer.vecs.addresses.p2a.bytes.reader();
let unknown = self.pools.get_unknown();
+3 -3
View File
@@ -73,7 +73,7 @@ impl Vecs {
// Reorg: truncate to starting_indexes
let truncate_to = self
.price
.spot
.cents
.height
.len()
@@ -101,7 +101,7 @@ impl Vecs {
let config = Config::default();
let committed = self.spot.cents.height.len();
let prev_cents = self
.price
.spot
.cents
.height
.collect_one_at(committed - 1)
@@ -234,7 +234,7 @@ impl<M: StorageMode> Vecs<M> {
let config = Config::default();
let height = indexer.vecs.blocks.timestamp.len();
let last_cents = self
.price
.spot
.cents
.height
.collect_one_at(self.spot.cents.height.len() - 1)
@@ -20,8 +20,8 @@ impl Vecs {
.compute(starting_indexes.height, &window_starts, exit, |v| {
Ok(v.compute_count_from_indexes(
starting_indexes.height,
&indexer.vecs.addresses.first_p2aaddressindex,
&indexer.vecs.addresses.p2abytes,
&indexer.vecs.addresses.p2a.first_index,
&indexer.vecs.addresses.p2a.bytes,
exit,
)?)
})?;
@@ -30,8 +30,8 @@ impl Vecs {
.compute(starting_indexes.height, &window_starts, exit, |v| {
Ok(v.compute_count_from_indexes(
starting_indexes.height,
&indexer.vecs.scripts.first_p2msoutputindex,
&indexer.vecs.scripts.p2ms_to_txindex,
&indexer.vecs.scripts.p2ms.first_index,
&indexer.vecs.scripts.p2ms.to_txindex,
exit,
)?)
})?;
@@ -40,8 +40,8 @@ impl Vecs {
.compute(starting_indexes.height, &window_starts, exit, |v| {
Ok(v.compute_count_from_indexes(
starting_indexes.height,
&indexer.vecs.addresses.first_p2pk33addressindex,
&indexer.vecs.addresses.p2pk33bytes,
&indexer.vecs.addresses.p2pk33.first_index,
&indexer.vecs.addresses.p2pk33.bytes,
exit,
)?)
})?;
@@ -50,8 +50,8 @@ impl Vecs {
.compute(starting_indexes.height, &window_starts, exit, |v| {
Ok(v.compute_count_from_indexes(
starting_indexes.height,
&indexer.vecs.addresses.first_p2pk65addressindex,
&indexer.vecs.addresses.p2pk65bytes,
&indexer.vecs.addresses.p2pk65.first_index,
&indexer.vecs.addresses.p2pk65.bytes,
exit,
)?)
})?;
@@ -60,8 +60,8 @@ impl Vecs {
.compute(starting_indexes.height, &window_starts, exit, |v| {
Ok(v.compute_count_from_indexes(
starting_indexes.height,
&indexer.vecs.addresses.first_p2pkhaddressindex,
&indexer.vecs.addresses.p2pkhbytes,
&indexer.vecs.addresses.p2pkh.first_index,
&indexer.vecs.addresses.p2pkh.bytes,
exit,
)?)
})?;
@@ -70,8 +70,8 @@ impl Vecs {
.compute(starting_indexes.height, &window_starts, exit, |v| {
Ok(v.compute_count_from_indexes(
starting_indexes.height,
&indexer.vecs.addresses.first_p2shaddressindex,
&indexer.vecs.addresses.p2shbytes,
&indexer.vecs.addresses.p2sh.first_index,
&indexer.vecs.addresses.p2sh.bytes,
exit,
)?)
})?;
@@ -80,8 +80,8 @@ impl Vecs {
.compute(starting_indexes.height, &window_starts, exit, |v| {
Ok(v.compute_count_from_indexes(
starting_indexes.height,
&indexer.vecs.addresses.first_p2traddressindex,
&indexer.vecs.addresses.p2trbytes,
&indexer.vecs.addresses.p2tr.first_index,
&indexer.vecs.addresses.p2tr.bytes,
exit,
)?)
})?;
@@ -90,8 +90,8 @@ impl Vecs {
.compute(starting_indexes.height, &window_starts, exit, |v| {
Ok(v.compute_count_from_indexes(
starting_indexes.height,
&indexer.vecs.addresses.first_p2wpkhaddressindex,
&indexer.vecs.addresses.p2wpkhbytes,
&indexer.vecs.addresses.p2wpkh.first_index,
&indexer.vecs.addresses.p2wpkh.bytes,
exit,
)?)
})?;
@@ -100,8 +100,8 @@ impl Vecs {
.compute(starting_indexes.height, &window_starts, exit, |v| {
Ok(v.compute_count_from_indexes(
starting_indexes.height,
&indexer.vecs.addresses.first_p2wshaddressindex,
&indexer.vecs.addresses.p2wshbytes,
&indexer.vecs.addresses.p2wsh.first_index,
&indexer.vecs.addresses.p2wsh.bytes,
exit,
)?)
})?;
@@ -110,8 +110,8 @@ impl Vecs {
.compute(starting_indexes.height, &window_starts, exit, |v| {
Ok(v.compute_count_from_indexes(
starting_indexes.height,
&indexer.vecs.scripts.first_opreturnindex,
&indexer.vecs.scripts.opreturn_to_txindex,
&indexer.vecs.scripts.opreturn.first_index,
&indexer.vecs.scripts.opreturn.to_txindex,
exit,
)?)
})?;
@@ -120,8 +120,8 @@ impl Vecs {
.compute(starting_indexes.height, &window_starts, exit, |v| {
Ok(v.compute_count_from_indexes(
starting_indexes.height,
&indexer.vecs.scripts.first_unknownoutputindex,
&indexer.vecs.scripts.unknown_to_txindex,
&indexer.vecs.scripts.unknown.first_index,
&indexer.vecs.scripts.unknown.to_txindex,
exit,
)?)
})?;
@@ -130,8 +130,8 @@ impl Vecs {
.compute(starting_indexes.height, &window_starts, exit, |v| {
Ok(v.compute_count_from_indexes(
starting_indexes.height,
&indexer.vecs.scripts.first_emptyoutputindex,
&indexer.vecs.scripts.empty_to_txindex,
&indexer.vecs.scripts.empty.first_index,
&indexer.vecs.scripts.empty.to_txindex,
exit,
)?)
})?;
@@ -60,7 +60,7 @@ impl Vecs {
// 2. Compute unspendable supply = opreturn + unclaimed_rewards + genesis (at height 0)
// Get reference to opreturn height vec for computing unspendable
let opreturn_height = &self.opreturn.base.sats.height;
let unclaimed_height = &mining.rewards.unclaimed_rewards.base.sats.height;
let unclaimed_height = &mining.rewards.unclaimed.base.sats.height;
self.unspendable.compute(
starting_indexes.height,
@@ -58,13 +58,13 @@ impl Vecs {
)?;
// Annualized volume: rolling 1y sum of per-block sent volume
self.annualized_volume.sats.height.compute_rolling_sum(
self.annualized.sats.height.compute_rolling_sum(
starting_indexes.height,
&blocks.lookback._1y,
&self.sent_sum.sats,
exit,
)?;
self.annualized_volume
self.annualized
.compute(prices, starting_indexes.height, exit)?;
self.tx_per_sec
@@ -23,7 +23,7 @@ impl Vecs {
version,
indexes,
)?,
annualized_volume: AmountPerBlock::forced_import(
annualized: AmountPerBlock::forced_import(
db,
"annualized_volume",
version,
@@ -8,7 +8,7 @@ use crate::internal::{AmountPerBlock, AmountPerBlockRolling, ComputedPerBlock};
pub struct Vecs<M: StorageMode = Rw> {
pub sent_sum: AmountPerBlockRolling<M>,
pub received_sum: AmountPerBlockRolling<M>,
pub annualized_volume: AmountPerBlock<M>,
pub annualized: AmountPerBlock<M>,
pub tx_per_sec: ComputedPerBlock<StoredF32, M>,
pub outputs_per_sec: ComputedPerBlock<StoredF32, M>,
pub inputs_per_sec: ComputedPerBlock<StoredF32, M>,