mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-04-24 06:39:58 -07:00
global: snapshot
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -100,8 +100,10 @@ impl<R: RealizedOps> CohortState<R> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn reset_single_iteration_values(&mut self) {
|
pub(crate) fn reset_single_iteration_values(&mut self) {
|
||||||
|
if R::TRACK_ACTIVITY {
|
||||||
self.sent = Sats::ZERO;
|
self.sent = Sats::ZERO;
|
||||||
self.satdays_destroyed = Sats::ZERO;
|
self.satdays_destroyed = Sats::ZERO;
|
||||||
|
}
|
||||||
self.realized.reset_single_iteration_values();
|
self.realized.reset_single_iteration_values();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -198,8 +200,10 @@ impl<R: RealizedOps> CohortState<R> {
|
|||||||
pre: &SendPrecomputed,
|
pre: &SendPrecomputed,
|
||||||
) {
|
) {
|
||||||
self.supply -= supply;
|
self.supply -= supply;
|
||||||
|
if R::TRACK_ACTIVITY {
|
||||||
self.sent += pre.sats;
|
self.sent += pre.sats;
|
||||||
self.satdays_destroyed += pre.age.satdays_destroyed(pre.sats);
|
self.satdays_destroyed += pre.age.satdays_destroyed(pre.sats);
|
||||||
|
}
|
||||||
|
|
||||||
self.realized
|
self.realized
|
||||||
.send(pre.sats, pre.current_ps, pre.prev_ps, pre.ath_ps, pre.prev_investor_cap);
|
.send(pre.sats, pre.current_ps, pre.prev_ps, pre.ath_ps, pre.prev_investor_cap);
|
||||||
@@ -241,8 +245,10 @@ impl<R: RealizedOps> CohortState<R> {
|
|||||||
self.supply -= supply;
|
self.supply -= supply;
|
||||||
|
|
||||||
if supply.value > Sats::ZERO {
|
if supply.value > Sats::ZERO {
|
||||||
|
if R::TRACK_ACTIVITY {
|
||||||
self.sent += supply.value;
|
self.sent += supply.value;
|
||||||
self.satdays_destroyed += age.satdays_destroyed(supply.value);
|
self.satdays_destroyed += age.satdays_destroyed(supply.value);
|
||||||
|
}
|
||||||
|
|
||||||
let sats = supply.value;
|
let sats = supply.value;
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ use brk_types::{Cents, CentsSats, CentsSquaredSats, Sats};
|
|||||||
|
|
||||||
/// Trait for realized state operations, implemented by Minimal, Core, and Full variants.
|
/// Trait for realized state operations, implemented by Minimal, Core, and Full variants.
|
||||||
pub trait RealizedOps: Default + Clone + Send + Sync + 'static {
|
pub trait RealizedOps: Default + Clone + Send + Sync + 'static {
|
||||||
|
const TRACK_ACTIVITY: bool = false;
|
||||||
fn cap(&self) -> Cents;
|
fn cap(&self) -> Cents;
|
||||||
fn profit(&self) -> Cents;
|
fn profit(&self) -> Cents;
|
||||||
fn loss(&self) -> Cents;
|
fn loss(&self) -> Cents;
|
||||||
@@ -159,6 +160,8 @@ pub struct CoreRealizedState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl RealizedOps for CoreRealizedState {
|
impl RealizedOps for CoreRealizedState {
|
||||||
|
const TRACK_ACTIVITY: bool = true;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn cap(&self) -> Cents {
|
fn cap(&self) -> Cents {
|
||||||
self.minimal.cap()
|
self.minimal.cap()
|
||||||
@@ -273,6 +276,8 @@ pub struct RealizedState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl RealizedOps for RealizedState {
|
impl RealizedOps for RealizedState {
|
||||||
|
const TRACK_ACTIVITY: bool = true;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn cap(&self) -> Cents {
|
fn cap(&self) -> Cents {
|
||||||
self.core.cap()
|
self.core.cap()
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ use brk_types::{Bitcoin, Cents, Dollars, Height, Sats, Version};
|
|||||||
use derive_more::{Deref, DerefMut};
|
use derive_more::{Deref, DerefMut};
|
||||||
use vecdb::UnaryTransform;
|
use vecdb::UnaryTransform;
|
||||||
|
|
||||||
use crate::internal::{AmountPerBlock, LazyAmount, LazyAmountDerivedResolutions};
|
use crate::internal::{AmountPerBlock, Identity, LazyAmount, LazyAmountDerivedResolutions, SatsToBitcoin};
|
||||||
|
|
||||||
/// Lazy value wrapper with height + all derived last transforms from AmountPerBlock.
|
/// Lazy value wrapper with height + all derived last transforms from AmountPerBlock.
|
||||||
#[derive(Clone, Deref, DerefMut, Traversable)]
|
#[derive(Clone, Deref, DerefMut, Traversable)]
|
||||||
@@ -55,4 +55,10 @@ impl LazyAmountPerBlock {
|
|||||||
resolutions: Box::new(resolutions),
|
resolutions: Box::new(resolutions),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn identity(name: &str, source: &AmountPerBlock, version: Version) -> Self {
|
||||||
|
Self::from_block_source::<Identity<Sats>, SatsToBitcoin, Identity<Cents>, Identity<Dollars>>(
|
||||||
|
name, source, version,
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
use brk_error::Result;
|
use brk_error::Result;
|
||||||
use brk_traversable::Traversable;
|
use brk_traversable::Traversable;
|
||||||
use brk_types::Version;
|
use brk_types::{Height, Version};
|
||||||
use derive_more::{Deref, DerefMut};
|
use derive_more::{Deref, DerefMut};
|
||||||
use vecdb::{Database, Rw, StorageMode};
|
use vecdb::{BinaryTransform, Database, Exit, ReadableVec, Rw, StorageMode, VecValue};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
indexes,
|
indexes,
|
||||||
@@ -28,4 +28,30 @@ impl<B: BpsType> PercentRollingWindows<B> {
|
|||||||
PercentPerBlock::forced_import(db, &format!("{name}_{suffix}"), version, indexes)
|
PercentPerBlock::forced_import(db, &format!("{name}_{suffix}"), version, indexes)
|
||||||
})?))
|
})?))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn compute_binary<S1T, S2T, F, R1, R2>(
|
||||||
|
&mut self,
|
||||||
|
max_from: Height,
|
||||||
|
sources1: [&R1; 4],
|
||||||
|
sources2: [&R2; 4],
|
||||||
|
exit: &Exit,
|
||||||
|
) -> Result<()>
|
||||||
|
where
|
||||||
|
S1T: VecValue,
|
||||||
|
S2T: VecValue,
|
||||||
|
R1: ReadableVec<Height, S1T>,
|
||||||
|
R2: ReadableVec<Height, S2T>,
|
||||||
|
F: BinaryTransform<S1T, S2T, B>,
|
||||||
|
{
|
||||||
|
for ((target, s1), s2) in self
|
||||||
|
.0
|
||||||
|
.as_mut_array()
|
||||||
|
.into_iter()
|
||||||
|
.zip(sources1)
|
||||||
|
.zip(sources2)
|
||||||
|
{
|
||||||
|
target.compute_binary::<S1T, S2T, F>(max_from, s1, s2, exit)?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,9 +3,11 @@ mod extended;
|
|||||||
mod percentiles;
|
mod percentiles;
|
||||||
mod price_extended;
|
mod price_extended;
|
||||||
mod std_dev_bands;
|
mod std_dev_bands;
|
||||||
|
mod windows;
|
||||||
|
|
||||||
pub use base::*;
|
pub use base::*;
|
||||||
pub use extended::*;
|
pub use extended::*;
|
||||||
pub use percentiles::*;
|
pub use percentiles::*;
|
||||||
pub use price_extended::*;
|
pub use price_extended::*;
|
||||||
pub use std_dev_bands::*;
|
pub use std_dev_bands::*;
|
||||||
|
pub use windows::*;
|
||||||
|
|||||||
57
crates/brk_computer/src/internal/per_block/ratio/windows.rs
Normal file
57
crates/brk_computer/src/internal/per_block/ratio/windows.rs
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
use brk_error::Result;
|
||||||
|
use brk_traversable::Traversable;
|
||||||
|
use brk_types::{Height, Version};
|
||||||
|
use derive_more::{Deref, DerefMut};
|
||||||
|
use vecdb::{BinaryTransform, Database, Exit, ReadableVec, Rw, StorageMode, VecValue};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
indexes,
|
||||||
|
internal::{BpsType, RatioPerBlock, Windows},
|
||||||
|
};
|
||||||
|
|
||||||
|
/// 4 rolling window vecs (24h, 1w, 1m, 1y), each storing basis points
|
||||||
|
/// with a lazy ratio float view.
|
||||||
|
#[derive(Deref, DerefMut, Traversable)]
|
||||||
|
#[traversable(transparent)]
|
||||||
|
pub struct RatioRollingWindows<B: BpsType, M: StorageMode = Rw>(
|
||||||
|
pub Windows<RatioPerBlock<B, M>>,
|
||||||
|
);
|
||||||
|
|
||||||
|
impl<B: BpsType> RatioRollingWindows<B> {
|
||||||
|
pub(crate) fn forced_import(
|
||||||
|
db: &Database,
|
||||||
|
name: &str,
|
||||||
|
version: Version,
|
||||||
|
indexes: &indexes::Vecs,
|
||||||
|
) -> Result<Self> {
|
||||||
|
Ok(Self(Windows::try_from_fn(|suffix| {
|
||||||
|
RatioPerBlock::forced_import_raw(db, &format!("{name}_{suffix}"), version, indexes)
|
||||||
|
})?))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn compute_binary<S1T, S2T, F, R1, R2>(
|
||||||
|
&mut self,
|
||||||
|
max_from: Height,
|
||||||
|
sources1: [&R1; 4],
|
||||||
|
sources2: [&R2; 4],
|
||||||
|
exit: &Exit,
|
||||||
|
) -> Result<()>
|
||||||
|
where
|
||||||
|
S1T: VecValue,
|
||||||
|
S2T: VecValue,
|
||||||
|
R1: ReadableVec<Height, S1T>,
|
||||||
|
R2: ReadableVec<Height, S2T>,
|
||||||
|
F: BinaryTransform<S1T, S2T, B>,
|
||||||
|
{
|
||||||
|
for ((target, s1), s2) in self
|
||||||
|
.0
|
||||||
|
.as_mut_array()
|
||||||
|
.into_iter()
|
||||||
|
.zip(sources1)
|
||||||
|
.zip(sources2)
|
||||||
|
{
|
||||||
|
target.bps.compute_binary::<S1T, S2T, F>(max_from, s1, s2, exit)?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -215,6 +215,7 @@ impl Computer {
|
|||||||
VERSION,
|
VERSION,
|
||||||
&indexes,
|
&indexes,
|
||||||
&distribution,
|
&distribution,
|
||||||
|
&cointime,
|
||||||
)?))
|
)?))
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
use brk_error::Result;
|
use brk_error::Result;
|
||||||
use brk_indexer::Indexer;
|
use brk_indexer::Indexer;
|
||||||
use brk_types::{BasisPoints16, CheckedSub, Halving, Indexes, Sats};
|
use brk_types::{BasisPoints16, CheckedSub, Dollars, Halving, Indexes, Sats};
|
||||||
use vecdb::{Exit, ReadableVec, VecIndex};
|
use vecdb::{Exit, ReadableVec, VecIndex};
|
||||||
|
|
||||||
use super::Vecs;
|
use super::Vecs;
|
||||||
use crate::{blocks, indexes, internal::RatioSatsBp16, prices, transactions};
|
use crate::{blocks, indexes, internal::{RatioDollarsBp32, RatioSatsBp16}, prices, transactions};
|
||||||
|
|
||||||
impl Vecs {
|
impl Vecs {
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
@@ -122,20 +122,13 @@ impl Vecs {
|
|||||||
)?;
|
)?;
|
||||||
|
|
||||||
// Rolling fee dominance = sum(fees) / sum(coinbase)
|
// Rolling fee dominance = sum(fees) / sum(coinbase)
|
||||||
for ((fee_dom, fees_w), coinbase_w) in self
|
self.fee_dominance_rolling
|
||||||
.fee_dominance_rolling
|
.compute_binary::<Sats, Sats, RatioSatsBp16, _, _>(
|
||||||
.as_mut_array()
|
|
||||||
.into_iter()
|
|
||||||
.zip(self.fees.rolling.as_array())
|
|
||||||
.zip(self.coinbase.sum.as_array())
|
|
||||||
{
|
|
||||||
fee_dom.compute_binary::<Sats, Sats, RatioSatsBp16>(
|
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&fees_w.sum.sats.height,
|
self.fees.rolling.as_array().map(|w| &w.sum.sats.height),
|
||||||
&coinbase_w.sats.height,
|
self.coinbase.sum.as_array().map(|w| &w.sats.height),
|
||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
}
|
|
||||||
|
|
||||||
// All-time cumulative subsidy dominance
|
// All-time cumulative subsidy dominance
|
||||||
self.subsidy_dominance
|
self.subsidy_dominance
|
||||||
@@ -168,6 +161,15 @@ impl Vecs {
|
|||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
// Fee Ratio Multiple: sum(coinbase) / sum(fees) per rolling window
|
||||||
|
self.fee_ratio_multiple
|
||||||
|
.compute_binary::<Dollars, Dollars, RatioDollarsBp32, _, _>(
|
||||||
|
starting_indexes.height,
|
||||||
|
self.coinbase.sum.as_array().map(|w| &w.usd.height),
|
||||||
|
self.fees.rolling.as_array().map(|w| &w.sum.usd.height),
|
||||||
|
exit,
|
||||||
|
)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ use crate::{
|
|||||||
indexes,
|
indexes,
|
||||||
internal::{
|
internal::{
|
||||||
AmountPerBlockCumulative, AmountPerBlockCumulativeSum, AmountPerBlockFull,
|
AmountPerBlockCumulative, AmountPerBlockCumulativeSum, AmountPerBlockFull,
|
||||||
FiatPerBlock, PercentPerBlock, PercentRollingWindows,
|
FiatPerBlock, PercentPerBlock, PercentRollingWindows, RatioRollingWindows,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -49,6 +49,12 @@ impl Vecs {
|
|||||||
indexes,
|
indexes,
|
||||||
)?,
|
)?,
|
||||||
subsidy_sma_1y: FiatPerBlock::forced_import(db, "subsidy_sma_1y", version, indexes)?,
|
subsidy_sma_1y: FiatPerBlock::forced_import(db, "subsidy_sma_1y", version, indexes)?,
|
||||||
|
fee_ratio_multiple: RatioRollingWindows::forced_import(
|
||||||
|
db,
|
||||||
|
"fee_ratio_multiple",
|
||||||
|
version,
|
||||||
|
indexes,
|
||||||
|
)?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
use brk_traversable::Traversable;
|
use brk_traversable::Traversable;
|
||||||
use brk_types::{BasisPoints16, Cents};
|
use brk_types::{BasisPoints16, BasisPoints32, Cents};
|
||||||
use vecdb::{Rw, StorageMode};
|
use vecdb::{Rw, StorageMode};
|
||||||
|
|
||||||
use crate::internal::{
|
use crate::internal::{
|
||||||
AmountPerBlockCumulative, AmountPerBlockCumulativeSum, AmountPerBlockFull,
|
AmountPerBlockCumulative, AmountPerBlockCumulativeSum, AmountPerBlockFull,
|
||||||
FiatPerBlock, PercentPerBlock, PercentRollingWindows,
|
FiatPerBlock, PercentPerBlock, PercentRollingWindows, RatioRollingWindows,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Traversable)]
|
#[derive(Traversable)]
|
||||||
@@ -20,4 +20,5 @@ pub struct Vecs<M: StorageMode = Rw> {
|
|||||||
#[traversable(rename = "subsidy_dominance")]
|
#[traversable(rename = "subsidy_dominance")]
|
||||||
pub subsidy_dominance_rolling: PercentRollingWindows<BasisPoints16, M>,
|
pub subsidy_dominance_rolling: PercentRollingWindows<BasisPoints16, M>,
|
||||||
pub subsidy_sma_1y: FiatPerBlock<Cents, M>,
|
pub subsidy_sma_1y: FiatPerBlock<Cents, M>,
|
||||||
|
pub fee_ratio_multiple: RatioRollingWindows<BasisPoints32, M>,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
use brk_error::Result;
|
use brk_error::Result;
|
||||||
use brk_types::{Cents, Dollars, Sats, Version};
|
use brk_types::Version;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
distribution, indexes,
|
cointime, distribution, indexes,
|
||||||
internal::{
|
internal::{
|
||||||
FiatRollingDelta, Identity, LazyFiatPerBlock, LazyAmountPerBlock, PercentPerBlock,
|
FiatRollingDelta, LazyFiatPerBlock, LazyAmountPerBlock, PercentPerBlock,
|
||||||
RollingWindows, SatsToBitcoin, finalize_db, open_db,
|
RollingWindows, finalize_db, open_db,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -21,6 +21,7 @@ impl Vecs {
|
|||||||
parent_version: Version,
|
parent_version: Version,
|
||||||
indexes: &indexes::Vecs,
|
indexes: &indexes::Vecs,
|
||||||
distribution: &distribution::Vecs,
|
distribution: &distribution::Vecs,
|
||||||
|
cointime: &cointime::Vecs,
|
||||||
) -> Result<Self> {
|
) -> Result<Self> {
|
||||||
let db = open_db(parent, super::DB_NAME, 10_000_000)?;
|
let db = open_db(parent, super::DB_NAME, 10_000_000)?;
|
||||||
|
|
||||||
@@ -28,12 +29,8 @@ impl Vecs {
|
|||||||
let supply_metrics = &distribution.utxo_cohorts.all.metrics.supply;
|
let supply_metrics = &distribution.utxo_cohorts.all.metrics.supply;
|
||||||
|
|
||||||
// Circulating supply - lazy refs to distribution
|
// Circulating supply - lazy refs to distribution
|
||||||
let circulating = LazyAmountPerBlock::from_block_source::<
|
let circulating =
|
||||||
Identity<Sats>,
|
LazyAmountPerBlock::identity("circulating_supply", &supply_metrics.total, version);
|
||||||
SatsToBitcoin,
|
|
||||||
Identity<Cents>,
|
|
||||||
Identity<Dollars>,
|
|
||||||
>("circulating_supply", &supply_metrics.total, version);
|
|
||||||
|
|
||||||
// Burned/unspendable supply - computed from scripts
|
// Burned/unspendable supply - computed from scripts
|
||||||
let burned = super::burned::Vecs::forced_import(&db, version, indexes)?;
|
let burned = super::burned::Vecs::forced_import(&db, version, indexes)?;
|
||||||
@@ -64,6 +61,12 @@ impl Vecs {
|
|||||||
indexes,
|
indexes,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
let hodled_or_lost_coins = LazyAmountPerBlock::identity(
|
||||||
|
"hodled_or_lost_coins",
|
||||||
|
&cointime.supply.vaulted_supply,
|
||||||
|
version,
|
||||||
|
);
|
||||||
|
|
||||||
let this = Self {
|
let this = Self {
|
||||||
db,
|
db,
|
||||||
circulating,
|
circulating,
|
||||||
@@ -73,6 +76,7 @@ impl Vecs {
|
|||||||
market_cap,
|
market_cap,
|
||||||
market_cap_delta,
|
market_cap_delta,
|
||||||
market_minus_realized_cap_growth_rate,
|
market_minus_realized_cap_growth_rate,
|
||||||
|
hodled_or_lost_coins,
|
||||||
};
|
};
|
||||||
finalize_db(&this.db, &this)?;
|
finalize_db(&this.db, &this)?;
|
||||||
Ok(this)
|
Ok(this)
|
||||||
|
|||||||
@@ -19,4 +19,5 @@ pub struct Vecs<M: StorageMode = Rw> {
|
|||||||
pub market_cap: LazyFiatPerBlock<Cents>,
|
pub market_cap: LazyFiatPerBlock<Cents>,
|
||||||
pub market_cap_delta: FiatRollingDelta<Cents, CentsSigned, M>,
|
pub market_cap_delta: FiatRollingDelta<Cents, CentsSigned, M>,
|
||||||
pub market_minus_realized_cap_growth_rate: RollingWindows<BasisPointsSigned32, M>,
|
pub market_minus_realized_cap_growth_rate: RollingWindows<BasisPointsSigned32, M>,
|
||||||
|
pub hodled_or_lost_coins: LazyAmountPerBlock,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ impl Query {
|
|||||||
|
|
||||||
let coinbase_vec = &computer.mining.rewards.coinbase.base.sats.height;
|
let coinbase_vec = &computer.mining.rewards.coinbase.base.sats.height;
|
||||||
let fee_vec = &computer.mining.rewards.fees.base.sats.height;
|
let fee_vec = &computer.mining.rewards.fees.base.sats.height;
|
||||||
let tx_count_vec = &computer.transactions.count.tx_count.height;
|
let tx_count_vec = &computer.transactions.count.tx_count.raw.height;
|
||||||
|
|
||||||
let start = start_block.to_usize();
|
let start = start_block.to_usize();
|
||||||
let end = end_block.to_usize() + 1;
|
let end = end_block.to_usize() + 1;
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user