global: snapshot

This commit is contained in:
nym21
2026-03-10 23:24:18 +01:00
parent 6a728a3357
commit c5d63b3090
75 changed files with 873 additions and 791 deletions

View File

@@ -16,24 +16,24 @@ impl Vecs {
exit: &Exit,
) -> Result<()> {
// Block count raw + cumulative
self.block_count.raw.height.compute_range(
self.total.raw.height.compute_range(
starting_indexes.height,
&indexer.vecs.blocks.weight,
|h| (h, StoredU32::from(1_u32)),
exit,
)?;
self.block_count.cumulative.height.compute_cumulative(
self.total.cumulative.height.compute_cumulative(
starting_indexes.height,
&self.block_count.raw.height,
&self.total.raw.height,
exit,
)?;
// Rolling window block counts
let ws = lookback.window_starts();
self.block_count.sum.compute_rolling_sum(
self.total.sum.compute_rolling_sum(
starting_indexes.height,
&ws,
&self.block_count.raw.height,
&self.total.raw.height,
exit,
)?;

View File

@@ -15,12 +15,12 @@ impl Vecs {
indexes: &indexes::Vecs,
) -> Result<Self> {
Ok(Self {
block_count_target: ConstantVecs::new::<BlockCountTarget>(
target: ConstantVecs::new::<BlockCountTarget>(
"block_count_target",
version,
indexes,
),
block_count: ComputedPerBlockCumulativeSum::forced_import(
total: ComputedPerBlockCumulativeSum::forced_import(
db,
"block_count",
version,

View File

@@ -6,6 +6,6 @@ use crate::internal::{ComputedPerBlockCumulativeSum, ConstantVecs};
#[derive(Traversable)]
pub struct Vecs<M: StorageMode = Rw> {
pub block_count_target: ConstantVecs<StoredU64>,
pub block_count: ComputedPerBlockCumulativeSum<StoredU32, M>,
pub target: ConstantVecs<StoredU64>,
pub total: ComputedPerBlockCumulativeSum<StoredU32, M>,
}

View File

@@ -31,7 +31,7 @@ impl Vecs {
self.size.compute(
starting_indexes.height,
&window_starts,
&indexer.vecs.blocks.total_size,
&indexer.vecs.blocks.total,
exit,
)?;

View File

@@ -54,7 +54,7 @@ impl Vecs {
exit,
)?;
self.activity_to_vaultedness_ratio.height.compute_divide(
self.ratio.height.compute_divide(
starting_indexes.height,
&self.liveliness.height,
&self.vaultedness.height,

View File

@@ -29,7 +29,7 @@ impl Vecs {
)?,
liveliness: ComputedPerBlock::forced_import(db, "liveliness", version, indexes)?,
vaultedness: ComputedPerBlock::forced_import(db, "vaultedness", version, indexes)?,
activity_to_vaultedness_ratio: ComputedPerBlock::forced_import(
ratio: ComputedPerBlock::forced_import(
db,
"activity_to_vaultedness_ratio",
version,

View File

@@ -10,5 +10,5 @@ pub struct Vecs<M: StorageMode = Rw> {
pub coinblocks_stored: ComputedPerBlockCumulativeSum<StoredF64, M>,
pub liveliness: ComputedPerBlock<StoredF64, M>,
pub vaultedness: ComputedPerBlock<StoredF64, M>,
pub activity_to_vaultedness_ratio: ComputedPerBlock<StoredF64, M>,
pub ratio: ComputedPerBlock<StoredF64, M>,
}

View File

@@ -29,14 +29,14 @@ impl Vecs {
self.tx_velocity_btc.height.compute_multiply(
starting_indexes.height,
&activity.activity_to_vaultedness_ratio.height,
&activity.ratio.height,
&supply.velocity.btc.height,
exit,
)?;
self.tx_velocity_usd.height.compute_multiply(
starting_indexes.height,
&activity.activity_to_vaultedness_ratio.height,
&activity.ratio.height,
&supply.velocity.usd.height,
exit,
)?;

View File

@@ -21,28 +21,28 @@ impl Vecs {
let realized_cap_cents = &all_metrics.realized.cap.cents.height;
let circulating_supply = &all_metrics.supply.total.btc.height;
self.thermo_cap.cents.height.compute_transform(
self.thermo.cents.height.compute_transform(
starting_indexes.height,
&mining.rewards.subsidy.cumulative.cents.height,
|(i, v, ..)| (i, v),
exit,
)?;
self.investor_cap.cents.height.compute_subtract(
self.investor.cents.height.compute_subtract(
starting_indexes.height,
realized_cap_cents,
&self.thermo_cap.cents.height,
&self.thermo.cents.height,
exit,
)?;
self.vaulted_cap.cents.height.compute_multiply(
self.vaulted.cents.height.compute_multiply(
starting_indexes.height,
realized_cap_cents,
&activity.vaultedness.height,
exit,
)?;
self.active_cap.cents.height.compute_multiply(
self.active.cents.height.compute_multiply(
starting_indexes.height,
realized_cap_cents,
&activity.liveliness.height,
@@ -50,9 +50,9 @@ impl Vecs {
)?;
// cointime_cap = (cointime_value_destroyed_cumulative * circulating_supply) / coinblocks_stored_cumulative
self.cointime_cap.cents.height.compute_transform3(
self.cointime.cents.height.compute_transform3(
starting_indexes.height,
&value.value_destroyed.cumulative.height,
&value.destroyed.cumulative.height,
circulating_supply,
&activity.coinblocks_stored.cumulative.height,
|(i, destroyed, supply, stored, ..)| {
@@ -67,8 +67,8 @@ impl Vecs {
// AVIV = active_cap / investor_cap
self.aviv.compute_ratio(
starting_indexes,
&self.active_cap.cents.height,
&self.investor_cap.cents.height,
&self.active.cents.height,
&self.investor.cents.height,
exit,
)?;

View File

@@ -12,11 +12,11 @@ impl Vecs {
indexes: &indexes::Vecs,
) -> Result<Self> {
Ok(Self {
thermo_cap: FiatPerBlock::forced_import(db, "thermo_cap", version, indexes)?,
investor_cap: FiatPerBlock::forced_import(db, "investor_cap", version, indexes)?,
vaulted_cap: FiatPerBlock::forced_import(db, "vaulted_cap", version, indexes)?,
active_cap: FiatPerBlock::forced_import(db, "active_cap", version, indexes)?,
cointime_cap: FiatPerBlock::forced_import(db, "cointime_cap", version, indexes)?,
thermo: FiatPerBlock::forced_import(db, "thermo_cap", version, indexes)?,
investor: FiatPerBlock::forced_import(db, "investor_cap", version, indexes)?,
vaulted: FiatPerBlock::forced_import(db, "vaulted_cap", version, indexes)?,
active: FiatPerBlock::forced_import(db, "active_cap", version, indexes)?,
cointime: FiatPerBlock::forced_import(db, "cointime_cap", version, indexes)?,
aviv: RatioPerBlock::forced_import(db, "aviv", version, indexes)?,
})
}

View File

@@ -6,10 +6,10 @@ use crate::internal::{FiatPerBlock, RatioPerBlock};
#[derive(Traversable)]
pub struct Vecs<M: StorageMode = Rw> {
pub thermo_cap: FiatPerBlock<Cents, M>,
pub investor_cap: FiatPerBlock<Cents, M>,
pub vaulted_cap: FiatPerBlock<Cents, M>,
pub active_cap: FiatPerBlock<Cents, M>,
pub cointime_cap: FiatPerBlock<Cents, M>,
pub thermo: FiatPerBlock<Cents, M>,
pub investor: FiatPerBlock<Cents, M>,
pub vaulted: FiatPerBlock<Cents, M>,
pub active: FiatPerBlock<Cents, M>,
pub cointime: FiatPerBlock<Cents, M>,
pub aviv: RatioPerBlock<BasisPoints32, M>,
}

View File

@@ -63,7 +63,7 @@ impl Vecs {
// Phase 4: pricing and reserve_risk are independent
let (r3, r4) = rayon::join(
|| {
self.pricing.compute(
self.prices.compute(
starting_indexes,
prices,
distribution,

View File

@@ -9,7 +9,7 @@ use crate::{
};
use super::{
ActivityVecs, AdjustedVecs, CapVecs, DB_NAME, PricingVecs, ReserveRiskVecs, SupplyVecs,
ActivityVecs, AdjustedVecs, CapVecs, DB_NAME, PricesVecs, ReserveRiskVecs, SupplyVecs,
ValueVecs, Vecs,
};
@@ -26,7 +26,7 @@ impl Vecs {
let supply = SupplyVecs::forced_import(&db, v1, indexes)?;
let value = ValueVecs::forced_import(&db, v1, indexes)?;
let cap = CapVecs::forced_import(&db, v1, indexes)?;
let pricing = PricingVecs::forced_import(&db, version, indexes)?;
let prices = PricesVecs::forced_import(&db, version, indexes)?;
let adjusted = AdjustedVecs::forced_import(&db, version, indexes)?;
let reserve_risk = ReserveRiskVecs::forced_import(&db, v1, indexes)?;
@@ -36,7 +36,7 @@ impl Vecs {
supply,
value,
cap,
pricing,
prices,
adjusted,
reserve_risk,
};

View File

@@ -1,7 +1,7 @@
pub mod activity;
pub mod adjusted;
pub mod cap;
pub mod pricing;
pub mod prices;
pub mod reserve_risk;
pub mod supply;
pub mod value;
@@ -15,7 +15,7 @@ use vecdb::{Database, Rw, StorageMode};
pub use activity::Vecs as ActivityVecs;
pub use adjusted::Vecs as AdjustedVecs;
pub use cap::Vecs as CapVecs;
pub use pricing::Vecs as PricingVecs;
pub use prices::Vecs as PricesVecs;
pub use reserve_risk::Vecs as ReserveRiskVecs;
pub use supply::Vecs as SupplyVecs;
pub use value::Vecs as ValueVecs;
@@ -31,7 +31,7 @@ pub struct Vecs<M: StorageMode = Rw> {
pub supply: SupplyVecs<M>,
pub value: ValueVecs<M>,
pub cap: CapVecs<M>,
pub pricing: PricingVecs<M>,
pub prices: PricesVecs<M>,
pub adjusted: AdjustedVecs<M>,
pub reserve_risk: ReserveRiskVecs<M>,
}

View File

@@ -23,7 +23,7 @@ impl Vecs {
let realized_price = &all_metrics.realized.price.cents.height;
let realized_cap = &all_metrics.realized.cap.cents.height;
self.vaulted_price.compute_all(
self.vaulted.compute_all(
prices,
starting_indexes,
exit,
@@ -40,7 +40,7 @@ impl Vecs {
},
)?;
self.active_price.compute_all(
self.active.compute_all(
prices,
starting_indexes,
exit,
@@ -61,8 +61,8 @@ impl Vecs {
|v| {
Ok(v.compute_transform2(
starting_indexes.height,
&cap.investor_cap.cents.height,
&supply.active_supply.btc.height,
&cap.investor.cents.height,
&supply.active.btc.height,
|(i, cap_cents, supply_btc, ..)| {
(i, Cents::from(f64::from(cap_cents) / f64::from(supply_btc)))
},
@@ -72,14 +72,14 @@ impl Vecs {
)?;
// cointime_price = cointime_cap / circulating_supply
self.cointime_price.compute_all(
self.cointime.compute_all(
prices,
starting_indexes,
exit,
|v| {
Ok(v.compute_transform2(
starting_indexes.height,
&cap.cointime_cap.cents.height,
&cap.cointime.cents.height,
circulating_supply,
|(i, cap_cents, supply_btc, ..)| {
(i, Cents::from(f64::from(cap_cents) / f64::from(supply_btc)))
@@ -90,29 +90,29 @@ impl Vecs {
)?;
// transfer_price = cointime_price - vaulted_price
self.transfer_price.cents.height.compute_transform2(
self.transfer.cents.height.compute_transform2(
starting_indexes.height,
&self.cointime_price.cents.height,
&self.vaulted_price.cents.height,
&self.cointime.cents.height,
&self.vaulted.cents.height,
|(i, cointime, vaulted, ..)| (i, cointime.saturating_sub(vaulted)),
exit,
)?;
self.transfer_price.compute_rest(prices, starting_indexes, exit)?;
self.transfer.compute_rest(prices, starting_indexes, exit)?;
// balanced_price = (realized_price + transfer_price) / 2
self.balanced_price.cents.height.compute_transform2(
self.balanced.cents.height.compute_transform2(
starting_indexes.height,
realized_price,
&self.transfer_price.cents.height,
&self.transfer.cents.height,
|(i, realized, transfer, ..)| (i, (realized + transfer) / 2u64),
exit,
)?;
self.balanced_price.compute_rest(prices, starting_indexes, exit)?;
self.balanced.compute_rest(prices, starting_indexes, exit)?;
// terminal_price = 21M × transfer_price / circulating_supply_btc
self.terminal_price.cents.height.compute_transform2(
self.terminal.cents.height.compute_transform2(
starting_indexes.height,
&self.transfer_price.cents.height,
&self.transfer.cents.height,
circulating_supply,
|(i, transfer, supply_btc, ..)| {
let supply = f64::from(supply_btc);
@@ -124,7 +124,7 @@ impl Vecs {
},
exit,
)?;
self.terminal_price.compute_rest(prices, starting_indexes, exit)?;
self.terminal.compute_rest(prices, starting_indexes, exit)?;
// cumulative_market_cap = Σ(market_cap) in dollars
self.cumulative_market_cap
@@ -137,7 +137,7 @@ impl Vecs {
// delta_price = (realized_cap - average_cap) / circulating_supply
// average_cap = cumulative_market_cap / (height + 1)
self.delta_price.cents.height.compute_transform3(
self.delta.cents.height.compute_transform3(
starting_indexes.height,
realized_cap,
&self.cumulative_market_cap.height,
@@ -153,7 +153,7 @@ impl Vecs {
},
exit,
)?;
self.delta_price.compute_rest(prices, starting_indexes, exit)?;
self.delta.compute_rest(prices, starting_indexes, exit)?;
Ok(())
}

View File

@@ -21,14 +21,14 @@ impl Vecs {
}
Ok(Self {
vaulted_price: import!("vaulted_price"),
active_price: import!("active_price"),
vaulted: import!("vaulted_price"),
active: import!("active_price"),
true_market_mean: import!("true_market_mean"),
cointime_price: import!("cointime_price"),
transfer_price: import!("transfer_price"),
balanced_price: import!("balanced_price"),
terminal_price: import!("terminal_price"),
delta_price: import!("delta_price"),
cointime: import!("cointime_price"),
transfer: import!("transfer_price"),
balanced: import!("balanced_price"),
terminal: import!("terminal_price"),
delta: import!("delta_price"),
cumulative_market_cap: ComputedPerBlock::forced_import(
db,
"cumulative_market_cap",

View File

@@ -0,0 +1,19 @@
use brk_traversable::Traversable;
use brk_types::Dollars;
use vecdb::{Rw, StorageMode};
use crate::internal::{ComputedPerBlock, PriceWithRatioExtendedPerBlock};
#[derive(Traversable)]
pub struct Vecs<M: StorageMode = Rw> {
pub vaulted: PriceWithRatioExtendedPerBlock<M>,
pub active: PriceWithRatioExtendedPerBlock<M>,
pub true_market_mean: PriceWithRatioExtendedPerBlock<M>,
pub cointime: PriceWithRatioExtendedPerBlock<M>,
pub transfer: PriceWithRatioExtendedPerBlock<M>,
pub balanced: PriceWithRatioExtendedPerBlock<M>,
pub terminal: PriceWithRatioExtendedPerBlock<M>,
pub delta: PriceWithRatioExtendedPerBlock<M>,
pub cumulative_market_cap: ComputedPerBlock<Dollars, M>,
}

View File

@@ -1,19 +0,0 @@
use brk_traversable::Traversable;
use brk_types::Dollars;
use vecdb::{Rw, StorageMode};
use crate::internal::{ComputedPerBlock, PriceWithRatioExtendedPerBlock};
#[derive(Traversable)]
pub struct Vecs<M: StorageMode = Rw> {
pub vaulted_price: PriceWithRatioExtendedPerBlock<M>,
pub active_price: PriceWithRatioExtendedPerBlock<M>,
pub true_market_mean: PriceWithRatioExtendedPerBlock<M>,
pub cointime_price: PriceWithRatioExtendedPerBlock<M>,
pub transfer_price: PriceWithRatioExtendedPerBlock<M>,
pub balanced_price: PriceWithRatioExtendedPerBlock<M>,
pub terminal_price: PriceWithRatioExtendedPerBlock<M>,
pub delta_price: PriceWithRatioExtendedPerBlock<M>,
pub cumulative_market_cap: ComputedPerBlock<Dollars, M>,
}

View File

@@ -23,14 +23,14 @@ impl Vecs {
.sats
.height;
self.vaulted_supply.sats.height.compute_multiply(
self.vaulted.sats.height.compute_multiply(
starting_indexes.height,
circulating_supply,
&activity.vaultedness.height,
exit,
)?;
self.active_supply.sats.height.compute_multiply(
self.active.sats.height.compute_multiply(
starting_indexes.height,
circulating_supply,
&activity.liveliness.height,

View File

@@ -12,13 +12,13 @@ impl Vecs {
indexes: &indexes::Vecs,
) -> Result<Self> {
Ok(Self {
vaulted_supply: AmountPerBlock::forced_import(
vaulted: AmountPerBlock::forced_import(
db,
"vaulted_supply",
version,
indexes,
)?,
active_supply: AmountPerBlock::forced_import(db, "active_supply", version, indexes)?,
active: AmountPerBlock::forced_import(db, "active_supply", version, indexes)?,
})
}
}

View File

@@ -5,6 +5,6 @@ use crate::internal::AmountPerBlock;
#[derive(Traversable)]
pub struct Vecs<M: StorageMode = Rw> {
pub vaulted_supply: AmountPerBlock<M>,
pub active_supply: AmountPerBlock<M>,
pub vaulted: AmountPerBlock<M>,
pub active: AmountPerBlock<M>,
}

View File

@@ -23,7 +23,7 @@ impl Vecs {
let coindays_destroyed = &all_metrics.activity.coindays_destroyed;
let circulating_supply = &all_metrics.supply.total.btc.height;
self.value_destroyed
self.destroyed
.compute(starting_indexes.height, &window_starts, exit, |vec| {
vec.compute_multiply(
starting_indexes.height,
@@ -34,7 +34,7 @@ impl Vecs {
Ok(())
})?;
self.value_created
self.created
.compute(starting_indexes.height, &window_starts, exit, |vec| {
vec.compute_multiply(
starting_indexes.height,
@@ -45,7 +45,7 @@ impl Vecs {
Ok(())
})?;
self.value_stored
self.stored
.compute(starting_indexes.height, &window_starts, exit, |vec| {
vec.compute_multiply(
starting_indexes.height,

View File

@@ -12,19 +12,19 @@ impl Vecs {
indexes: &indexes::Vecs,
) -> Result<Self> {
Ok(Self {
value_destroyed: ComputedPerBlockCumulativeSum::forced_import(
destroyed: ComputedPerBlockCumulativeSum::forced_import(
db,
"cointime_value_destroyed",
version,
indexes,
)?,
value_created: ComputedPerBlockCumulativeSum::forced_import(
created: ComputedPerBlockCumulativeSum::forced_import(
db,
"cointime_value_created",
version,
indexes,
)?,
value_stored: ComputedPerBlockCumulativeSum::forced_import(
stored: ComputedPerBlockCumulativeSum::forced_import(
db,
"cointime_value_stored",
version,

View File

@@ -6,8 +6,8 @@ use crate::internal::ComputedPerBlockCumulativeSum;
#[derive(Traversable)]
pub struct Vecs<M: StorageMode = Rw> {
pub value_destroyed: ComputedPerBlockCumulativeSum<StoredF64, M>,
pub value_created: ComputedPerBlockCumulativeSum<StoredF64, M>,
pub value_stored: ComputedPerBlockCumulativeSum<StoredF64, M>,
pub destroyed: ComputedPerBlockCumulativeSum<StoredF64, M>,
pub created: ComputedPerBlockCumulativeSum<StoredF64, M>,
pub stored: ComputedPerBlockCumulativeSum<StoredF64, M>,
pub vocdd: ComputedPerBlockCumulativeSum<StoredF64, M>,
}

View File

@@ -15,7 +15,7 @@ pub struct AddressesDataVecs<M: StorageMode = Rw> {
impl AddressesDataVecs {
/// Get minimum stamped height across funded and empty data.
pub(crate) fn min_stamped_height(&self) -> Height {
pub(crate) fn min_stamped_len(&self) -> Height {
Height::from(self.funded.stamp())
.incremented()
.min(Height::from(self.empty.stamp()).incremented())

View File

@@ -39,7 +39,7 @@ macro_rules! define_any_address_indexes_vecs {
}
/// Get minimum stamped height across all address types.
pub(crate) fn min_stamped_height(&self) -> Height {
pub(crate) fn min_stamped_len(&self) -> Height {
[$(Height::from(self.$field.stamp()).incremented()),*]
.into_iter()
.min()

View File

@@ -132,7 +132,7 @@ impl DynCohortVecs for AddressCohortVecs {
state.inner.supply.utxo_count = *self
.metrics
.outputs
.utxo_count
.unspent_count
.height
.collect_one(prev_height)
.unwrap();

View File

@@ -16,7 +16,7 @@ macro_rules! impl_import_state {
state.supply.utxo_count = *self
.metrics
.outputs
.utxo_count
.unspent_count
.height
.collect_one(prev_height)
.unwrap();
@@ -140,7 +140,7 @@ impl<M: CohortMetricsBase + Traversable> DynCohortVecs for UTXOCohortVecs<M> {
state.supply.utxo_count = *self
.metrics
.outputs()
.utxo_count
.unspent_count
.height
.collect_one(prev_height)
.unwrap();

View File

@@ -66,8 +66,8 @@ pub(crate) fn process_blocks(
let height_to_first_txindex = &indexer.vecs.transactions.first_txindex;
let height_to_first_txoutindex = &indexer.vecs.outputs.first_txoutindex;
let height_to_first_txinindex = &indexer.vecs.inputs.first_txinindex;
let height_to_tx_count = &transactions.count.tx_count.raw.height;
let height_to_output_count = &outputs.count.total_count.full.sum;
let height_to_tx_count = &transactions.count.total.raw.height;
let height_to_output_count = &outputs.count.total.full.sum;
let height_to_input_count = &inputs.count.full.sum;
let txindex_to_output_count = &indexes.txindex.output_count;
let txindex_to_input_count = &indexes.txindex.input_count;
@@ -186,9 +186,9 @@ pub(crate) fn process_blocks(
debug!("recovering addr_counts from height {}", starting_height);
let (mut addr_counts, mut empty_addr_counts) = if starting_height > Height::ZERO {
let addr_counts =
AddressTypeToAddressCount::from((&vecs.addr_count.by_addresstype, starting_height));
AddressTypeToAddressCount::from((&vecs.addresses.funded.by_addresstype, starting_height));
let empty_addr_counts = AddressTypeToAddressCount::from((
&vecs.empty_addr_count.by_addresstype,
&vecs.addresses.empty.by_addresstype,
starting_height,
));
(addr_counts, empty_addr_counts)
@@ -436,14 +436,14 @@ pub(crate) fn process_blocks(
vecs.utxo_cohorts.update_fenwick_from_pending();
// Push to height-indexed vectors
vecs.addr_count
vecs.addresses.funded
.truncate_push_height(height, addr_counts.sum(), &addr_counts)?;
vecs.empty_addr_count.truncate_push_height(
vecs.addresses.empty.truncate_push_height(
height,
empty_addr_counts.sum(),
&empty_addr_counts,
)?;
vecs.address_activity
vecs.addresses.activity
.truncate_push_height(height, &activity_counts)?;
let is_last_of_day = is_last_of_day[offset];

View File

@@ -76,9 +76,9 @@ pub(crate) fn write(
vecs.any_address_indexes
.par_iter_mut()
.chain(vecs.addresses_data.par_iter_mut())
.chain(vecs.addr_count.par_iter_height_mut())
.chain(vecs.empty_addr_count.par_iter_height_mut())
.chain(vecs.address_activity.par_iter_height_mut())
.chain(vecs.addresses.funded.par_iter_height_mut())
.chain(vecs.addresses.empty.par_iter_height_mut())
.chain(vecs.addresses.activity.par_iter_height_mut())
.chain(
[
&mut vecs.supply_state as &mut dyn AnyStoredVec,

View File

@@ -37,8 +37,8 @@ pub struct AllCohortMetrics<M: StorageMode = Rw> {
#[traversable(wrap = "supply", rename = "delta")]
pub supply_delta_extended: RollingDeltaExcept1m<Sats, SatsSigned, M>,
#[traversable(wrap = "outputs/utxo_count", rename = "delta")]
pub utxo_count_delta_extended: RollingDeltaExcept1m<StoredU64, StoredI64, M>,
#[traversable(wrap = "outputs/unspent_count", rename = "delta")]
pub unspent_count_delta_extended: RollingDeltaExcept1m<StoredU64, StoredI64, M>,
}
impl CohortMetricsBase for AllCohortMetrics {
@@ -103,7 +103,7 @@ impl AllCohortMetrics {
asopr: Box::new(asopr),
relative: Box::new(relative),
supply_delta_extended: cfg.import("supply_delta", Version::ONE)?,
utxo_count_delta_extended: cfg.import("utxo_count_delta", Version::ONE)?,
unspent_count_delta_extended: cfg.import("utxo_count_delta", Version::ONE)?,
})
}
@@ -152,10 +152,10 @@ impl AllCohortMetrics {
&self.supply.total.sats.height,
exit,
)?;
self.utxo_count_delta_extended.compute(
self.unspent_count_delta_extended.compute(
starting_indexes.height,
&window_starts,
&self.outputs.utxo_count.height,
&self.outputs.unspent_count.height,
exit,
)?;

View File

@@ -33,8 +33,8 @@ pub struct ExtendedCohortMetrics<M: StorageMode = Rw> {
#[traversable(wrap = "supply", rename = "delta")]
pub supply_delta_extended: RollingDeltaExcept1m<Sats, SatsSigned, M>,
#[traversable(wrap = "outputs/utxo_count", rename = "delta")]
pub utxo_count_delta_extended: RollingDeltaExcept1m<StoredU64, StoredI64, M>,
#[traversable(wrap = "outputs/unspent_count", rename = "delta")]
pub unspent_count_delta_extended: RollingDeltaExcept1m<StoredU64, StoredI64, M>,
}
impl CohortMetricsBase for ExtendedCohortMetrics {
@@ -91,7 +91,7 @@ impl ExtendedCohortMetrics {
unrealized: Box::new(unrealized),
relative: Box::new(relative),
supply_delta_extended: cfg.import("supply_delta", Version::ONE)?,
utxo_count_delta_extended: cfg.import("utxo_count_delta", Version::ONE)?,
unspent_count_delta_extended: cfg.import("utxo_count_delta", Version::ONE)?,
})
}
@@ -130,10 +130,10 @@ impl ExtendedCohortMetrics {
&self.supply.total.sats.height,
exit,
)?;
self.utxo_count_delta_extended.compute(
self.unspent_count_delta_extended.compute(
starting_indexes.height,
&window_starts,
&self.outputs.utxo_count.height,
&self.outputs.unspent_count.height,
exit,
)?;

View File

@@ -10,29 +10,29 @@ use crate::distribution::metrics::ImportConfig;
/// Base output metrics: utxo_count only (1 stored vec).
#[derive(Traversable)]
pub struct OutputsBase<M: StorageMode = Rw> {
pub utxo_count: ComputedPerBlock<StoredU64, M>,
pub unspent_count: ComputedPerBlock<StoredU64, M>,
}
impl OutputsBase {
pub(crate) fn forced_import(cfg: &ImportConfig) -> Result<Self> {
Ok(Self {
utxo_count: cfg.import("utxo_count", Version::ZERO)?,
unspent_count: cfg.import("utxo_count", Version::ZERO)?,
})
}
pub(crate) fn min_len(&self) -> usize {
self.utxo_count.height.len()
self.unspent_count.height.len()
}
pub(crate) fn truncate_push(&mut self, height: Height, state: &CohortState<impl RealizedOps, impl CostBasisOps>) -> Result<()> {
self.utxo_count
self.unspent_count
.height
.truncate_push(height, StoredU64::from(state.supply.utxo_count))?;
Ok(())
}
pub(crate) fn collect_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {
vec![&mut self.utxo_count.height as &mut dyn AnyStoredVec]
vec![&mut self.unspent_count.height as &mut dyn AnyStoredVec]
}
pub(crate) fn compute_from_stateful(
@@ -41,11 +41,11 @@ impl OutputsBase {
others: &[&Self],
exit: &Exit,
) -> Result<()> {
self.utxo_count.height.compute_sum_of_others(
self.unspent_count.height.compute_sum_of_others(
starting_indexes.height,
&others
.iter()
.map(|v| &v.utxo_count.height)
.map(|v| &v.unspent_count.height)
.collect::<Vec<_>>(),
exit,
)?;

View File

@@ -18,18 +18,18 @@ pub struct OutputsFull<M: StorageMode = Rw> {
#[traversable(flatten)]
pub base: OutputsBase<M>,
#[traversable(wrap = "utxo_count", rename = "delta")]
pub utxo_count_delta: RollingDelta1m<StoredU64, StoredI64, M>,
#[traversable(wrap = "unspent_count", rename = "delta")]
pub unspent_count_delta: RollingDelta1m<StoredU64, StoredI64, M>,
}
impl OutputsFull {
pub(crate) fn forced_import(cfg: &ImportConfig) -> Result<Self> {
let base = OutputsBase::forced_import(cfg)?;
let utxo_count_delta = cfg.import("utxo_count_delta", Version::ONE)?;
let unspent_count_delta = cfg.import("utxo_count_delta", Version::ONE)?;
Ok(Self {
base,
utxo_count_delta,
unspent_count_delta,
})
}
@@ -53,10 +53,10 @@ impl OutputsFull {
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
self.utxo_count_delta.compute(
self.unspent_count_delta.compute(
starting_indexes.height,
&blocks.lookback._1m,
&self.base.utxo_count.height,
&self.base.unspent_count.height,
exit,
)?;

View File

@@ -36,6 +36,21 @@ use super::{
};
const VERSION: Version = Version::new(22);
#[derive(Traversable)]
pub struct AddressMetricsVecs<M: StorageMode = Rw> {
pub funded: AddrCountsVecs<M>,
pub empty: AddrCountsVecs<M>,
pub activity: AddressActivityVecs<M>,
pub total: TotalAddrCountVecs<M>,
pub new: NewAddrCountVecs<M>,
pub delta: DeltaVecs<M>,
pub funded_index:
LazyVecFrom1<FundedAddressIndex, FundedAddressIndex, FundedAddressIndex, FundedAddressData>,
pub empty_index:
LazyVecFrom1<EmptyAddressIndex, EmptyAddressIndex, EmptyAddressIndex, EmptyAddressData>,
}
#[derive(Traversable)]
pub struct Vecs<M: StorageMode = Rw> {
#[traversable(skip)]
@@ -48,24 +63,8 @@ pub struct Vecs<M: StorageMode = Rw> {
pub addresses_data: AddressesDataVecs<M>,
pub utxo_cohorts: UTXOCohorts<M>,
pub address_cohorts: AddressCohorts<M>,
pub coinblocks_destroyed: ComputedPerBlockCumulative<StoredF64, M>,
pub addr_count: AddrCountsVecs<M>,
pub empty_addr_count: AddrCountsVecs<M>,
pub address_activity: AddressActivityVecs<M>,
/// Total addresses ever seen (addr_count + empty_addr_count) - stored, global + per-type
pub total_addr_count: TotalAddrCountVecs<M>,
/// New addresses per block (delta of total) - stored height + cumulative + rolling, global + per-type
pub new_addr_count: NewAddrCountVecs<M>,
/// Windowed change + growth rate for addr_count, global + per-type
pub delta: DeltaVecs<M>,
pub funded_address_index:
LazyVecFrom1<FundedAddressIndex, FundedAddressIndex, FundedAddressIndex, FundedAddressData>,
pub empty_address_index:
LazyVecFrom1<EmptyAddressIndex, EmptyAddressIndex, EmptyAddressIndex, EmptyAddressData>,
pub addresses: AddressMetricsVecs<M>,
/// In-memory block state for UTXO processing. Persisted via supply_state.
/// Kept across compute() calls to avoid O(n) rebuild on resume.
@@ -151,12 +150,16 @@ impl Vecs {
.with_saved_stamped_changes(SAVED_STAMPED_CHANGES),
)?,
addr_count,
empty_addr_count,
address_activity,
total_addr_count,
new_addr_count,
delta,
addresses: AddressMetricsVecs {
funded: addr_count,
empty: empty_addr_count,
activity: address_activity,
total: total_addr_count,
new: new_addr_count,
delta,
funded_index: funded_address_index,
empty_index: empty_address_index,
},
utxo_cohorts,
address_cohorts,
@@ -173,9 +176,6 @@ impl Vecs {
funded: fundedaddressindex_to_fundedaddressdata,
empty: emptyaddressindex_to_emptyaddressdata,
},
funded_address_index,
empty_address_index,
chain_state: Vec::new(),
txindex_to_height: RangeMap::default(),
@@ -292,9 +292,9 @@ impl Vecs {
// Recover or reuse chain_state
let starting_height = if recovered_height.is_zero() {
self.supply_state.reset()?;
self.addr_count.reset_height()?;
self.empty_addr_count.reset_height()?;
self.address_activity.reset_height()?;
self.addresses.funded.reset_height()?;
self.addresses.empty.reset_height()?;
self.addresses.activity.reset_height()?;
reset_state(
&mut self.any_address_indexes,
&mut self.addresses_data,
@@ -414,32 +414,33 @@ impl Vecs {
)?;
// 6b. Compute address count sum (by addresstype → all)
self.addr_count.compute_rest(starting_indexes, exit)?;
self.empty_addr_count.compute_rest(starting_indexes, exit)?;
self.addresses.funded.compute_rest(starting_indexes, exit)?;
self.addresses.empty.compute_rest(starting_indexes, exit)?;
// 6c. Compute total_addr_count = addr_count + empty_addr_count
self.total_addr_count.compute(
self.addresses.total.compute(
starting_indexes.height,
&self.addr_count,
&self.empty_addr_count,
&self.addresses.funded,
&self.addresses.empty,
exit,
)?;
let window_starts = blocks.lookback.window_starts();
self.address_activity
self.addresses
.activity
.compute_rest(starting_indexes.height, &window_starts, exit)?;
self.new_addr_count.compute(
self.addresses.new.compute(
starting_indexes.height,
&window_starts,
&self.total_addr_count,
&self.addresses.total,
exit,
)?;
self.delta.compute(
self.addresses.delta.compute(
starting_indexes.height,
&window_starts,
&self.addr_count,
&self.addresses.funded,
exit,
)?;
@@ -474,48 +475,16 @@ impl Vecs {
Ok(())
}
/// Get minimum length across all height-indexed stateful vectors.
fn min_stateful_len(&self) -> Height {
debug!("supply_state.len={}", self.supply_state.len());
debug!(
"utxo_cohorts.min={}",
self.utxo_cohorts.min_stateful_len()
);
debug!(
"address_cohorts.min={}",
self.address_cohorts.min_stateful_len()
);
debug!(
"address_indexes.min={}",
self.any_address_indexes.min_stamped_height()
);
debug!(
"addresses_data.min={}",
self.addresses_data.min_stamped_height()
);
debug!("addr_count.min={}", self.addr_count.min_stateful_len());
debug!(
"empty_addr_count.min={}",
self.empty_addr_count.min_stateful_len()
);
debug!(
"address_activity.min={}",
self.address_activity.min_stateful_len()
);
debug!(
"coinblocks_destroyed.raw.height.len={}",
self.coinblocks_destroyed.raw.height.len()
);
self.utxo_cohorts
.min_stateful_len()
.min(self.address_cohorts.min_stateful_len())
.min(Height::from(self.supply_state.len()))
.min(self.any_address_indexes.min_stamped_height())
.min(self.addresses_data.min_stamped_height())
.min(Height::from(self.addr_count.min_stateful_len()))
.min(Height::from(self.empty_addr_count.min_stateful_len()))
.min(Height::from(self.address_activity.min_stateful_len()))
.min(self.any_address_indexes.min_stamped_len())
.min(self.addresses_data.min_stamped_len())
.min(Height::from(self.addresses.funded.min_stateful_len()))
.min(Height::from(self.addresses.empty.min_stateful_len()))
.min(Height::from(self.addresses.activity.min_stateful_len()))
.min(Height::from(self.coinblocks_destroyed.raw.height.len()))
}
}

View File

@@ -124,7 +124,7 @@ impl Vecs {
)?;
// Supply-Adjusted Dormancy = dormancy / circulating_supply_btc
self.dormancy_supply_adjusted
self.dormancy.supply_adjusted
.height
.compute_transform2(
starting_indexes.height,
@@ -161,7 +161,7 @@ impl Vecs {
)?;
// Dormancy Flow: supply_btc / dormancy
self.dormancy_flow.height.compute_transform2(
self.dormancy.flow.height.compute_transform2(
starting_indexes.height,
supply_total_sats,
&all_activity.dormancy.height,

View File

@@ -18,7 +18,7 @@ pub(super) fn compute(
.collect();
let count_vecs: Vec<&_> = amount_range
.iter()
.map(|c| &c.metrics.outputs.utxo_count.height)
.map(|c| &c.metrics.outputs.unspent_count.height)
.collect();
if supply_vecs.is_empty() || supply_vecs.len() != count_vecs.len() {

View File

@@ -30,10 +30,11 @@ impl Vecs {
ComputedPerBlock::forced_import(&db, "coindays_destroyed_supply_adjusted", v, indexes)?;
let coinyears_destroyed_supply_adjusted =
ComputedPerBlock::forced_import(&db, "coinyears_destroyed_supply_adjusted", v, indexes)?;
let dormancy_supply_adjusted =
ComputedPerBlock::forced_import(&db, "dormancy_supply_adjusted", v, indexes)?;
let dormancy = super::vecs::DormancyVecs {
supply_adjusted: ComputedPerBlock::forced_import(&db, "dormancy_supply_adjusted", v, indexes)?,
flow: ComputedPerBlock::forced_import(&db, "dormancy_flow", v, indexes)?,
};
let stock_to_flow = ComputedPerBlock::forced_import(&db, "stock_to_flow", v, indexes)?;
let dormancy_flow = ComputedPerBlock::forced_import(&db, "dormancy_flow", v, indexes)?;
let seller_exhaustion_constant =
ComputedPerBlock::forced_import(&db, "seller_exhaustion_constant", v, indexes)?;
@@ -46,9 +47,8 @@ impl Vecs {
thermocap_multiple,
coindays_destroyed_supply_adjusted,
coinyears_destroyed_supply_adjusted,
dormancy_supply_adjusted,
dormancy,
stock_to_flow,
dormancy_flow,
seller_exhaustion_constant,
};
finalize_db(&this.db, &this)?;

View File

@@ -4,6 +4,12 @@ use vecdb::{Database, Rw, StorageMode};
use crate::internal::{ComputedPerBlock, PercentPerBlock, RatioPerBlock};
#[derive(Traversable)]
pub struct DormancyVecs<M: StorageMode = Rw> {
pub supply_adjusted: ComputedPerBlock<StoredF32, M>,
pub flow: ComputedPerBlock<StoredF32, M>,
}
#[derive(Traversable)]
pub struct Vecs<M: StorageMode = Rw> {
#[traversable(skip)]
@@ -15,8 +21,7 @@ pub struct Vecs<M: StorageMode = Rw> {
pub thermocap_multiple: RatioPerBlock<BasisPoints32, M>,
pub coindays_destroyed_supply_adjusted: ComputedPerBlock<StoredF32, M>,
pub coinyears_destroyed_supply_adjusted: ComputedPerBlock<StoredF32, M>,
pub dormancy_supply_adjusted: ComputedPerBlock<StoredF32, M>,
pub dormancy: DormancyVecs<M>,
pub stock_to_flow: ComputedPerBlock<StoredF32, M>,
pub dormancy_flow: ComputedPerBlock<StoredF32, M>,
pub seller_exhaustion_constant: ComputedPerBlock<StoredF32, M>,
}

View File

@@ -16,7 +16,7 @@ impl Vecs {
) -> Result<()> {
// Compute price returns at height level
for ((returns, _), (lookback_price, _)) in self
.price_return
.periods
.iter_mut_with_days()
.zip(lookback.price_lookback.iter_with_days())
{
@@ -29,8 +29,8 @@ impl Vecs {
}
// CAGR computed from returns at height level (2y+ periods only)
let price_return_dca = self.price_return.as_dca_period();
for (cagr, returns, days) in self.price_cagr.zip_mut_with_period(&price_return_dca) {
let price_return_dca = self.periods.as_dca_period();
for (cagr, returns, days) in self.cagr.zip_mut_with_period(&price_return_dca) {
let years = days as f64 / 365.0;
cagr.bps.height.compute_transform(
starting_indexes.height,
@@ -44,12 +44,12 @@ impl Vecs {
)?;
}
let _24h_price_return_ratio = &self.price_return._24h.ratio.height;
let _24h_price_return_ratio = &self.periods._24h.ratio.height;
for sd in [
&mut self.price_return_24h_sd._1w,
&mut self.price_return_24h_sd._1m,
&mut self.price_return_24h_sd._1y,
&mut self.sd_24h._1w,
&mut self.sd_24h._1m,
&mut self.sd_24h._1y,
] {
sd.compute_all(blocks, starting_indexes, exit, _24h_price_return_ratio)?;
}

View File

@@ -55,9 +55,9 @@ impl Vecs {
};
Ok(Self {
price_return,
price_cagr,
price_return_24h_sd,
periods: price_return,
cagr: price_cagr,
sd_24h: price_return_24h_sd,
})
}
}

View File

@@ -16,7 +16,7 @@ pub struct PriceReturn24hSdVecs<M: StorageMode = Rw> {
#[derive(Traversable)]
pub struct Vecs<M: StorageMode = Rw> {
pub price_return: ByLookbackPeriod<PercentPerBlock<BasisPointsSigned32, M>>,
pub price_cagr: ByDcaCagr<PercentPerBlock<BasisPointsSigned32, M>>,
pub price_return_24h_sd: PriceReturn24hSdVecs<M>,
pub periods: ByLookbackPeriod<PercentPerBlock<BasisPointsSigned32, M>>,
pub cagr: ByDcaCagr<PercentPerBlock<BasisPointsSigned32, M>>,
pub sd_24h: PriceReturn24hSdVecs<M>,
}

View File

@@ -52,10 +52,10 @@ impl Vecs {
// RSI per timeframe
let return_sources = [
&returns.price_return._24h.ratio.height,
&returns.price_return._1w.ratio.height,
&returns.price_return._1m.ratio.height,
&returns.price_return._1y.ratio.height,
&returns.periods._24h.ratio.height,
&returns.periods._1w.ratio.height,
&returns.periods._1m.ratio.height,
&returns.periods._1y.ratio.height,
];
for ((rsi_chain, ret), &m) in self
.rsi

View File

@@ -14,36 +14,36 @@ impl Vecs {
"price_volatility_1w",
version + v2,
returns
.price_return_24h_sd
.sd_24h
._1w
.sd
.height
.read_only_boxed_clone(),
&returns.price_return_24h_sd._1w.sd,
&returns.sd_24h._1w.sd,
);
let _1m = LazyPerBlock::from_computed::<TimesSqrt<Days30>>(
"price_volatility_1m",
version + v2,
returns
.price_return_24h_sd
.sd_24h
._1m
.sd
.height
.read_only_boxed_clone(),
&returns.price_return_24h_sd._1m.sd,
&returns.sd_24h._1m.sd,
);
let _1y = LazyPerBlock::from_computed::<TimesSqrt<Days365>>(
"price_volatility_1y",
version + v2,
returns
.price_return_24h_sd
.sd_24h
._1y
.sd
.height
.read_only_boxed_clone(),
&returns.price_return_24h_sd._1y.sd,
&returns.sd_24h._1y.sd,
);
Ok(Self { _1w, _1m, _1y })

View File

@@ -20,9 +20,9 @@ impl Vecs {
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
self.hash_rate.height.compute_transform2(
self.rate.raw.height.compute_transform2(
starting_indexes.height,
&count_vecs.block_count.sum._24h.height,
&count_vecs.total.sum._24h.height,
&difficulty_vecs.as_hash.height,
|(i, block_count_sum, difficulty_as_hash, ..)| {
(
@@ -36,33 +36,33 @@ impl Vecs {
exit,
)?;
let hash_rate = &self.hash_rate.height;
let hash_rate = &self.rate.raw.height;
for (sma, window) in [
(&mut self.hash_rate_sma._1w.height, &lookback._1w),
(&mut self.hash_rate_sma._1m.height, &lookback._1m),
(&mut self.hash_rate_sma._2m.height, &lookback._2m),
(&mut self.hash_rate_sma._1y.height, &lookback._1y),
(&mut self.rate.sma._1w.height, &lookback._1w),
(&mut self.rate.sma._1m.height, &lookback._1m),
(&mut self.rate.sma._2m.height, &lookback._2m),
(&mut self.rate.sma._1y.height, &lookback._1y),
] {
sma.compute_rolling_average(starting_indexes.height, window, hash_rate, exit)?;
}
self.hash_rate_ath.height.compute_all_time_high(
self.rate.ath.height.compute_all_time_high(
starting_indexes.height,
&self.hash_rate.height,
&self.rate.raw.height,
exit,
)?;
self.hash_rate_drawdown.compute_drawdown(
self.rate.drawdown.compute_drawdown(
starting_indexes.height,
&self.hash_rate.height,
&self.hash_rate_ath.height,
&self.rate.raw.height,
&self.rate.ath.height,
exit,
)?;
self.hash_price.ths.height.compute_transform2(
self.price.ths.height.compute_transform2(
starting_indexes.height,
coinbase_usd_24h_sum,
&self.hash_rate.height,
&self.rate.raw.height,
|(i, coinbase_sum, hashrate, ..)| {
let hashrate_ths = *hashrate / ONE_TERA_HASH;
let price = if hashrate_ths == 0.0 {
@@ -75,17 +75,17 @@ impl Vecs {
exit,
)?;
self.hash_price.phs.height.compute_transform(
self.price.phs.height.compute_transform(
starting_indexes.height,
&self.hash_price.ths.height,
&self.price.ths.height,
|(i, price, ..)| (i, (*price * 1000.0).into()),
exit,
)?;
self.hash_value.ths.height.compute_transform2(
self.value.ths.height.compute_transform2(
starting_indexes.height,
coinbase_sats_24h_sum,
&self.hash_rate.height,
&self.rate.raw.height,
|(i, coinbase_sum, hashrate, ..)| {
let hashrate_ths = *hashrate / ONE_TERA_HASH;
let value = if hashrate_ths == 0.0 {
@@ -98,49 +98,49 @@ impl Vecs {
exit,
)?;
self.hash_value.phs.height.compute_transform(
self.value.phs.height.compute_transform(
starting_indexes.height,
&self.hash_value.ths.height,
&self.value.ths.height,
|(i, value, ..)| (i, (*value * 1000.0).into()),
exit,
)?;
for (min_vec, src_vec) in [
(
&mut self.hash_price.ths_min.height,
&self.hash_price.ths.height,
&mut self.price.ths_min.height,
&self.price.ths.height,
),
(
&mut self.hash_price.phs_min.height,
&self.hash_price.phs.height,
&mut self.price.phs_min.height,
&self.price.phs.height,
),
(
&mut self.hash_value.ths_min.height,
&self.hash_value.ths.height,
&mut self.value.ths_min.height,
&self.value.ths.height,
),
(
&mut self.hash_value.phs_min.height,
&self.hash_value.phs.height,
&mut self.value.phs_min.height,
&self.value.phs.height,
),
] {
min_vec.compute_all_time_low_(starting_indexes.height, src_vec, exit, true)?;
}
self.hash_price
self.price
.rebound
.compute_binary::<StoredF32, StoredF32, RatioDiffF32Bps32>(
starting_indexes.height,
&self.hash_price.phs.height,
&self.hash_price.phs_min.height,
&self.price.phs.height,
&self.price.phs_min.height,
exit,
)?;
self.hash_value
self.value
.rebound
.compute_binary::<StoredF32, StoredF32, RatioDiffF32Bps32>(
starting_indexes.height,
&self.hash_value.phs.height,
&self.hash_value.phs_min.height,
&self.value.phs.height,
&self.value.phs_min.height,
exit,
)?;

View File

@@ -3,7 +3,7 @@ use brk_types::Version;
use vecdb::Database;
use super::{
vecs::{HashPriceValueVecs, HashRateSmaVecs},
vecs::{HashPriceValueVecs, HashRateSmaVecs, RateVecs},
Vecs,
};
use crate::{
@@ -21,46 +21,48 @@ impl Vecs {
let v5 = Version::new(5);
Ok(Self {
hash_rate: ComputedPerBlock::forced_import(db, "hash_rate", version + v5, indexes)?,
hash_rate_sma: HashRateSmaVecs {
_1w: ComputedPerBlock::forced_import(
rate: RateVecs {
raw: ComputedPerBlock::forced_import(db, "hash_rate", version + v5, indexes)?,
sma: HashRateSmaVecs {
_1w: ComputedPerBlock::forced_import(
db,
"hash_rate_sma_1w",
version,
indexes,
)?,
_1m: ComputedPerBlock::forced_import(
db,
"hash_rate_sma_1m",
version,
indexes,
)?,
_2m: ComputedPerBlock::forced_import(
db,
"hash_rate_sma_2m",
version,
indexes,
)?,
_1y: ComputedPerBlock::forced_import(
db,
"hash_rate_sma_1y",
version,
indexes,
)?,
},
ath: ComputedPerBlock::forced_import(
db,
"hash_rate_sma_1w",
"hash_rate_ath",
version,
indexes,
)?,
_1m: ComputedPerBlock::forced_import(
drawdown: PercentPerBlock::forced_import(
db,
"hash_rate_sma_1m",
version,
indexes,
)?,
_2m: ComputedPerBlock::forced_import(
db,
"hash_rate_sma_2m",
version,
indexes,
)?,
_1y: ComputedPerBlock::forced_import(
db,
"hash_rate_sma_1y",
"hash_rate_drawdown",
version,
indexes,
)?,
},
hash_rate_ath: ComputedPerBlock::forced_import(
db,
"hash_rate_ath",
version,
indexes,
)?,
hash_rate_drawdown: PercentPerBlock::forced_import(
db,
"hash_rate_drawdown",
version,
indexes,
)?,
hash_price: HashPriceValueVecs {
price: HashPriceValueVecs {
ths: ComputedPerBlock::forced_import(
db,
"hash_price_ths",
@@ -92,7 +94,7 @@ impl Vecs {
indexes,
)?,
},
hash_value: HashPriceValueVecs {
value: HashPriceValueVecs {
ths: ComputedPerBlock::forced_import(
db,
"hash_value_ths",

View File

@@ -22,11 +22,16 @@ pub struct HashPriceValueVecs<M: StorageMode = Rw> {
}
#[derive(Traversable)]
pub struct Vecs<M: StorageMode = Rw> {
pub hash_rate: ComputedPerBlock<StoredF64, M>,
pub hash_rate_sma: HashRateSmaVecs<M>,
pub hash_rate_ath: ComputedPerBlock<StoredF64, M>,
pub hash_rate_drawdown: PercentPerBlock<BasisPointsSigned16, M>,
pub hash_price: HashPriceValueVecs<M>,
pub hash_value: HashPriceValueVecs<M>,
pub struct RateVecs<M: StorageMode = Rw> {
pub raw: ComputedPerBlock<StoredF64, M>,
pub sma: HashRateSmaVecs<M>,
pub ath: ComputedPerBlock<StoredF64, M>,
pub drawdown: PercentPerBlock<BasisPointsSigned16, M>,
}
#[derive(Traversable)]
pub struct Vecs<M: StorageMode = Rw> {
pub rate: RateVecs<M>,
pub price: HashPriceValueVecs<M>,
pub value: HashPriceValueVecs<M>,
}

View File

@@ -19,7 +19,7 @@ impl Vecs {
exit: &Exit,
) -> Result<()> {
let window_starts = blocks.lookback.window_starts();
self.total_count
self.total
.compute(starting_indexes.height, &window_starts, exit, |full| {
full.compute_with_skip(
starting_indexes.height,
@@ -33,7 +33,7 @@ impl Vecs {
self.utxo_count.height.compute_transform3(
starting_indexes.height,
&self.total_count.full.cumulative,
&self.total.full.cumulative,
&inputs_count.full.cumulative,
&scripts_count.opreturn.cumulative.height,
|(h, output_count, input_count, opreturn_count, ..)| {

View File

@@ -15,7 +15,7 @@ impl Vecs {
indexes: &indexes::Vecs,
) -> Result<Self> {
Ok(Self {
total_count: ComputedPerBlockAggregated::forced_import(
total: ComputedPerBlockAggregated::forced_import(
db,
"output_count",
version,

View File

@@ -6,6 +6,6 @@ use crate::internal::{ComputedPerBlock, ComputedPerBlockAggregated};
#[derive(Traversable)]
pub struct Vecs<M: StorageMode = Rw> {
pub total_count: ComputedPerBlockAggregated<StoredU64, M>,
pub total: ComputedPerBlockAggregated<StoredU64, M>,
pub utxo_count: ComputedPerBlock<StoredU64, M>,
}

View File

@@ -83,7 +83,7 @@ impl Vecs {
self.blocks_mined_sum
.as_array()
.into_iter()
.zip(blocks.count.block_count.sum.as_array()),
.zip(blocks.count.total.sum.as_array()),
) {
dom.compute_binary::<StoredU32, StoredU32, RatioU32Bp16>(
starting_indexes.height,

View File

@@ -76,7 +76,7 @@ impl Vecs {
.compute_binary::<StoredU32, StoredU32, RatioU32Bp16>(
starting_indexes.height,
&self.blocks_mined.cumulative.height,
&blocks.count.block_count.cumulative.height,
&blocks.count.total.cumulative.height,
exit,
)?;

View File

@@ -21,19 +21,19 @@ impl Vecs {
self.compute_prices(indexer, starting_indexes, exit)?;
self.split.open.cents.compute_first(
starting_indexes,
&self.price.cents.height,
&self.spot.cents.height,
indexes,
exit,
)?;
self.split.high.cents.compute_max(
starting_indexes,
&self.price.cents.height,
&self.spot.cents.height,
indexes,
exit,
)?;
self.split.low.cents.compute_min(
starting_indexes,
&self.price.cents.height,
&self.spot.cents.height,
indexes,
exit,
)?;
@@ -60,7 +60,7 @@ impl Vecs {
) -> Result<()> {
let source_version =
indexer.vecs.outputs.value.version() + indexer.vecs.outputs.outputtype.version();
self.price
self.spot
.cents
.height
.validate_computed_version_or_reset(source_version)?;
@@ -78,28 +78,28 @@ impl Vecs {
.height
.len()
.min(starting_indexes.height.to_usize());
self.price.cents.height.truncate_if_needed_at(truncate_to)?;
self.spot.cents.height.truncate_if_needed_at(truncate_to)?;
if self.price.cents.height.len() < START_HEIGHT {
if self.spot.cents.height.len() < START_HEIGHT {
for line in brk_oracle::PRICES
.lines()
.skip(self.price.cents.height.len())
.skip(self.spot.cents.height.len())
{
if self.price.cents.height.len() >= START_HEIGHT {
if self.spot.cents.height.len() >= START_HEIGHT {
break;
}
let dollars: f64 = line.parse().unwrap_or(0.0);
let cents = (dollars * 100.0).round() as u64;
self.price.cents.height.push(Cents::new(cents));
self.spot.cents.height.push(Cents::new(cents));
}
}
if self.price.cents.height.len() >= total_heights {
if self.spot.cents.height.len() >= total_heights {
return Ok(());
}
let config = Config::default();
let committed = self.price.cents.height.len();
let committed = self.spot.cents.height.len();
let prev_cents = self
.price
.cents
@@ -121,7 +121,7 @@ impl Vecs {
let ref_bins = Self::feed_blocks(&mut oracle, indexer, committed..total_heights);
for (i, ref_bin) in ref_bins.into_iter().enumerate() {
self.price
self.spot
.cents
.height
.push(Cents::new(bin_to_cents(ref_bin)));
@@ -134,12 +134,12 @@ impl Vecs {
{
let _lock = exit.lock();
self.price.cents.height.write()?;
self.spot.cents.height.write()?;
}
info!(
"Oracle prices complete: {} committed",
self.price.cents.height.len()
self.spot.cents.height.len()
);
Ok(())
@@ -237,7 +237,7 @@ impl<M: StorageMode> Vecs<M> {
.price
.cents
.height
.collect_one_at(self.price.cents.height.len() - 1)
.collect_one_at(self.spot.cents.height.len() - 1)
.unwrap();
let seed_bin = cents_to_bin(last_cents.inner() as f64);
let window_size = config.window_size;

View File

@@ -29,7 +29,7 @@ pub struct Vecs<M: StorageMode = Rw> {
pub split: SplitByUnit<M>,
pub ohlc: OhlcByUnit<M>,
pub price: PriceByUnit<M>,
pub spot: PriceByUnit<M>,
}
impl Vecs {
@@ -169,7 +169,7 @@ impl Vecs {
sats: ohlc_sats,
};
let price = PriceByUnit {
let spot = PriceByUnit {
cents: price_cents,
usd: price_usd,
sats: price_sats,
@@ -179,7 +179,7 @@ impl Vecs {
db: db.clone(),
split,
ohlc,
price,
spot,
})
}

View File

@@ -39,14 +39,14 @@ impl Vecs {
self.taproot.compute_binary::<_, _, RatioU64Bp16>(
starting_indexes.height,
&count.p2tr.raw.height,
&outputs_count.total_count.full.sum,
&outputs_count.total.full.sum,
exit,
)?;
self.segwit.compute_binary::<_, _, RatioU64Bp16>(
starting_indexes.height,
&count.segwit.raw.height,
&outputs_count.total_count.full.sum,
&outputs_count.total.full.sum,
exit,
)?;

View File

@@ -61,9 +61,9 @@ impl Vecs {
indexes,
)?;
let hodled_or_lost_coins = LazyAmountPerBlock::identity(
let hodled_or_lost = LazyAmountPerBlock::identity(
"hodled_or_lost_coins",
&cointime.supply.vaulted_supply,
&cointime.supply.vaulted,
version,
);
@@ -76,7 +76,7 @@ impl Vecs {
market_cap,
market_cap_delta,
market_minus_realized_cap_growth_rate,
hodled_or_lost_coins,
hodled_or_lost,
};
finalize_db(&this.db, &this)?;
Ok(this)

View File

@@ -20,5 +20,5 @@ pub struct Vecs<M: StorageMode = Rw> {
#[traversable(wrap = "market_cap", rename = "delta")]
pub market_cap_delta: FiatRollingDelta<Cents, CentsSigned, M>,
pub market_minus_realized_cap_growth_rate: RollingWindows<BasisPointsSigned32, M>,
pub hodled_or_lost_coins: LazyAmountPerBlock,
pub hodled_or_lost: LazyAmountPerBlock,
}

View File

@@ -15,7 +15,7 @@ impl Vecs {
exit: &Exit,
) -> Result<()> {
let window_starts = lookback.window_starts();
self.tx_count
self.total
.compute(starting_indexes.height, &window_starts, exit, |height| {
Ok(height.compute_count_from_indexes(
starting_indexes.height,

View File

@@ -26,7 +26,7 @@ impl Vecs {
);
Ok(Self {
tx_count: ComputedPerBlockFull::forced_import(db, "tx_count", version, indexes)?,
total: ComputedPerBlockFull::forced_import(db, "tx_count", version, indexes)?,
is_coinbase: txindex_to_is_coinbase,
})
}

View File

@@ -6,6 +6,6 @@ use crate::internal::ComputedPerBlockFull;
#[derive(Traversable)]
pub struct Vecs<M: StorageMode = Rw> {
pub tx_count: ComputedPerBlockFull<StoredU64, M>,
pub total: ComputedPerBlockFull<StoredU64, M>,
pub is_coinbase: LazyVecFrom2<TxIndex, StoredBool, TxIndex, Height, Height, TxIndex>,
}

View File

@@ -71,7 +71,7 @@ impl Vecs {
.height
.compute_binary::<_, Timestamp, PerSec>(
starting_indexes.height,
&count_vecs.tx_count.raw.height,
&count_vecs.total.raw.height,
&blocks.interval.height,
exit,
)?;
@@ -87,7 +87,7 @@ impl Vecs {
.height
.compute_binary::<_, Timestamp, PerSec>(
starting_indexes.height,
&outputs_count.total_count.full.sum,
&outputs_count.total.full.sum,
&blocks.interval.height,
exit,
)?;