global: snapshot

This commit is contained in:
nym21
2025-05-28 15:42:55 +02:00
parent 93e01902e3
commit 9bbf3a027f
17 changed files with 1201 additions and 624 deletions
@@ -62,7 +62,7 @@ impl<T> Outputs<T> {
}
}
impl Outputs<(OutputFilter, vecs::utxos::cohort::Vecs)> {
impl Outputs<(OutputFilter, vecs::statefull::cohort::Vecs)> {
pub fn tick_tock_next_block(&mut self, chain_state: &[BlockState], timestamp: Timestamp) {
if chain_state.is_empty() {
return;
+6 -6
View File
@@ -13,12 +13,12 @@ pub mod grouped;
pub mod indexes;
pub mod market;
pub mod mining;
pub mod statefull;
pub mod transactions;
pub mod utxos;
pub use indexes::Indexes;
const VERSION: Version = Version::ZERO;
const VERSION: Version = Version::ONE;
#[derive(Clone)]
pub struct Vecs {
@@ -28,7 +28,7 @@ pub struct Vecs {
pub mining: mining::Vecs,
pub market: market::Vecs,
pub transactions: transactions::Vecs,
pub utxos: utxos::Vecs,
pub statefull: statefull::Vecs,
pub fetched: Option<fetched::Vecs>,
}
@@ -86,7 +86,7 @@ impl Vecs {
computation,
compressed,
)?,
utxos: utxos::Vecs::forced_import(
statefull: statefull::Vecs::forced_import(
path,
version + VERSION + Version::ZERO,
computation,
@@ -154,7 +154,7 @@ impl Vecs {
)?;
}
self.utxos.compute(
self.statefull.compute(
indexer,
&self.indexes,
&self.transactions,
@@ -174,7 +174,7 @@ impl Vecs {
self.mining.vecs(),
self.market.vecs(),
self.transactions.vecs(),
self.utxos.vecs(),
self.statefull.vecs(),
self.fetched.as_ref().map_or(vec![], |v| v.vecs()),
]
.into_iter()
@@ -1,6 +1,8 @@
use std::{fs, path::Path};
use brk_core::{CheckedSub, Dollars, Height, Result, Sats, StoredUsize, Version};
use brk_core::{
CheckedSub, DateIndex, Dollars, Height, Result, Sats, StoredF32, StoredUsize, Version,
};
use brk_exit::Exit;
use brk_indexer::Indexer;
use brk_vec::{AnyCollectableVec, AnyVec, Compressed, Computation, EagerVec, VecIterator};
@@ -24,27 +26,34 @@ pub struct Vecs {
pub state: CohortState,
pub height_to_realized_cap: Option<EagerVec<Height, Dollars>>,
pub indexes_to_realized_cap: Option<ComputedVecsFromHeight<Dollars>>,
pub height_to_supply: EagerVec<Height, Sats>,
pub indexes_to_supply: ComputedValueVecsFromHeight,
pub height_to_utxo_count: EagerVec<Height, StoredUsize>,
pub indexes_to_utxo_count: ComputedVecsFromHeight<StoredUsize>,
pub height_to_realized_profit: Option<EagerVec<Height, Dollars>>,
pub indexes_to_realized_profit: Option<ComputedVecsFromHeight<Dollars>>,
pub height_to_realized_loss: Option<EagerVec<Height, Dollars>>,
pub indexes_to_realized_loss: Option<ComputedVecsFromHeight<Dollars>>,
pub height_to_value_created: Option<EagerVec<Height, Dollars>>,
pub indexes_to_value_created: Option<ComputedVecsFromHeight<Dollars>>,
pub height_to_adjusted_value_created: Option<EagerVec<Height, Dollars>>,
pub indexes_to_adjusted_value_created: Option<ComputedVecsFromHeight<Dollars>>,
pub height_to_value_destroyed: Option<EagerVec<Height, Dollars>>,
pub indexes_to_value_destroyed: Option<ComputedVecsFromHeight<Dollars>>,
pub height_to_adjusted_value_destroyed: Option<EagerVec<Height, Dollars>>,
pub indexes_to_adjusted_value_destroyed: Option<ComputedVecsFromHeight<Dollars>>,
pub dateindex_to_adjusted_spent_output_profit_ratio: Option<EagerVec<DateIndex, StoredF32>>,
pub dateindex_to_realized_cap_30d_change: Option<EagerVec<DateIndex, Dollars>>,
pub dateindex_to_sell_side_risk_ratio: Option<EagerVec<DateIndex, StoredF32>>,
pub dateindex_to_spent_output_profit_ratio: Option<EagerVec<DateIndex, StoredF32>>,
pub indexes_to_adjusted_value_created: Option<ComputedVecsFromHeight<Dollars>>,
pub indexes_to_adjusted_value_destroyed: Option<ComputedVecsFromHeight<Dollars>>,
pub indexes_to_negative_realized_loss: Option<ComputedVecsFromHeight<Dollars>>,
pub indexes_to_net_realized_profit_and_loss: Option<ComputedVecsFromHeight<Dollars>>,
pub indexes_to_realized_cap: Option<ComputedVecsFromHeight<Dollars>>,
pub indexes_to_realized_loss: Option<ComputedVecsFromHeight<Dollars>>,
pub indexes_to_realized_price: Option<ComputedVecsFromHeight<Dollars>>,
pub indexes_to_realized_price_extra: Option<ComputedRatioVecsFromDateIndex>,
pub indexes_to_realized_profit: Option<ComputedVecsFromHeight<Dollars>>,
pub indexes_to_realized_value: Option<ComputedVecsFromHeight<Dollars>>,
pub indexes_to_supply: ComputedValueVecsFromHeight,
pub indexes_to_utxo_count: ComputedVecsFromHeight<StoredUsize>,
pub indexes_to_value_created: Option<ComputedVecsFromHeight<Dollars>>,
pub indexes_to_value_destroyed: Option<ComputedVecsFromHeight<Dollars>>,
}
impl Vecs {
@@ -161,9 +170,7 @@ impl Vecs {
false,
version + VERSION + Version::ZERO,
compressed,
StorableVecGeneatorOptions::default()
.add_sum()
.add_cumulative(),
StorableVecGeneatorOptions::default().add_sum(),
)
.unwrap()
}),
@@ -183,9 +190,18 @@ impl Vecs {
false,
version + VERSION + Version::ZERO,
compressed,
StorableVecGeneatorOptions::default()
.add_sum()
.add_cumulative(),
StorableVecGeneatorOptions::default().add_sum(),
)
.unwrap()
}),
indexes_to_negative_realized_loss: compute_dollars.then(|| {
ComputedVecsFromHeight::forced_import(
path,
&suffix("negative_realized_loss"),
true,
version + VERSION + Version::ZERO,
compressed,
StorableVecGeneatorOptions::default().add_sum(),
)
.unwrap()
}),
@@ -209,6 +225,17 @@ impl Vecs {
)
.unwrap()
}),
indexes_to_realized_value: compute_dollars.then(|| {
ComputedVecsFromHeight::forced_import(
path,
&suffix("realized_value"),
false,
version + VERSION + Version::ZERO,
compressed,
StorableVecGeneatorOptions::default().add_sum(),
)
.unwrap()
}),
height_to_adjusted_value_created: compute_dollars.then(|| {
EagerVec::forced_import(
path,
@@ -269,6 +296,53 @@ impl Vecs {
)
.unwrap()
}),
dateindex_to_realized_cap_30d_change: compute_dollars.then(|| {
EagerVec::forced_import(
path,
&suffix("realized_cap_30d_change"),
version + VERSION + Version::ZERO,
compressed,
)
.unwrap()
}),
indexes_to_net_realized_profit_and_loss: compute_dollars.then(|| {
ComputedVecsFromHeight::forced_import(
path,
&suffix("net_realized_profit_and_loss"),
true,
version + VERSION + Version::ZERO,
compressed,
StorableVecGeneatorOptions::default().add_sum(),
)
.unwrap()
}),
dateindex_to_sell_side_risk_ratio: compute_dollars.then(|| {
EagerVec::forced_import(
path,
&suffix("sell_side_risk_ratio"),
version + VERSION + Version::ZERO,
compressed,
)
.unwrap()
}),
dateindex_to_spent_output_profit_ratio: compute_dollars.then(|| {
EagerVec::forced_import(
path,
&suffix("spent_output_profit_ratio"),
version + VERSION + Version::ZERO,
compressed,
)
.unwrap()
}),
dateindex_to_adjusted_spent_output_profit_ratio: compute_dollars.then(|| {
EagerVec::forced_import(
path,
&suffix("adjusted_spent_output_profit_ratio"),
version + VERSION + Version::ZERO,
compressed,
)
.unwrap()
}),
})
}
@@ -590,6 +664,24 @@ impl Vecs {
Some(self.height_to_realized_loss.as_ref().unwrap()),
)?;
self.indexes_to_negative_realized_loss
.as_mut()
.unwrap()
.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|vec, _, _, starting_indexes, exit| {
vec.compute_transform(
starting_indexes.height,
self.height_to_realized_loss.as_ref().unwrap(),
|(i, v, ..)| (i, v * -1.0),
exit,
)
},
)?;
self.indexes_to_value_created
.as_mut()
.unwrap()
@@ -629,6 +721,110 @@ impl Vecs {
exit,
Some(self.height_to_adjusted_value_destroyed.as_ref().unwrap()),
)?;
self.dateindex_to_realized_cap_30d_change
.as_mut()
.unwrap()
.compute_change(
starting_indexes.dateindex,
self.indexes_to_realized_cap
.as_ref()
.unwrap()
.dateindex
.unwrap_last(),
30,
exit,
)?;
self.indexes_to_net_realized_profit_and_loss
.as_mut()
.unwrap()
.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|vec, _, _, starting_indexes, exit| {
vec.compute_subtract(
starting_indexes.height,
self.height_to_realized_profit.as_ref().unwrap(),
self.height_to_realized_loss.as_ref().unwrap(),
exit,
)
},
)?;
self.indexes_to_realized_value
.as_mut()
.unwrap()
.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|vec, _, _, starting_indexes, exit| {
vec.compute_add(
starting_indexes.height,
self.height_to_realized_profit.as_ref().unwrap(),
self.height_to_realized_loss.as_ref().unwrap(),
exit,
)
},
)?;
self.dateindex_to_spent_output_profit_ratio
.as_mut()
.unwrap()
.compute_divide(
starting_indexes.dateindex,
self.indexes_to_value_created
.as_ref()
.unwrap()
.dateindex
.unwrap_sum(),
self.indexes_to_value_destroyed
.as_ref()
.unwrap()
.dateindex
.unwrap_sum(),
exit,
)?;
self.dateindex_to_adjusted_spent_output_profit_ratio
.as_mut()
.unwrap()
.compute_divide(
starting_indexes.dateindex,
self.indexes_to_adjusted_value_created
.as_ref()
.unwrap()
.dateindex
.unwrap_sum(),
self.indexes_to_adjusted_value_destroyed
.as_ref()
.unwrap()
.dateindex
.unwrap_sum(),
exit,
)?;
self.dateindex_to_sell_side_risk_ratio
.as_mut()
.unwrap()
.compute_divide(
starting_indexes.dateindex,
self.indexes_to_realized_value
.as_ref()
.unwrap()
.dateindex
.unwrap_sum(),
self.indexes_to_realized_cap
.as_ref()
.unwrap()
.dateindex
.unwrap_last(),
exit,
)?;
}
Ok(())
@@ -651,6 +847,9 @@ impl Vecs {
self.indexes_to_realized_price
.as_ref()
.map_or(vec![], |v| v.vecs()),
self.indexes_to_realized_value
.as_ref()
.map_or(vec![], |v| v.vecs()),
self.indexes_to_realized_price_extra
.as_ref()
.map_or(vec![], |v| v.vecs()),
@@ -666,6 +865,9 @@ impl Vecs {
self.indexes_to_realized_loss
.as_ref()
.map_or(vec![], |v| v.vecs()),
self.indexes_to_negative_realized_loss
.as_ref()
.map_or(vec![], |v| v.vecs()),
self.height_to_value_created
.as_ref()
.map_or(vec![], |v| vec![v as &dyn AnyCollectableVec]),
@@ -681,6 +883,12 @@ impl Vecs {
self.height_to_value_destroyed
.as_ref()
.map_or(vec![], |v| vec![v as &dyn AnyCollectableVec]),
self.dateindex_to_spent_output_profit_ratio
.as_ref()
.map_or(vec![], |v| vec![v as &dyn AnyCollectableVec]),
self.dateindex_to_adjusted_spent_output_profit_ratio
.as_ref()
.map_or(vec![], |v| vec![v as &dyn AnyCollectableVec]),
self.indexes_to_value_destroyed
.as_ref()
.map_or(vec![], |v| v.vecs()),
@@ -690,6 +898,15 @@ impl Vecs {
self.indexes_to_adjusted_value_destroyed
.as_ref()
.map_or(vec![], |v| v.vecs()),
self.dateindex_to_realized_cap_30d_change
.as_ref()
.map_or(vec![], |v| vec![v]),
self.indexes_to_net_realized_profit_and_loss
.as_ref()
.map_or(vec![], |v| v.vecs()),
self.dateindex_to_sell_side_risk_ratio
.as_ref()
.map_or(vec![], |v| vec![v]),
]
.into_iter()
.flatten()
@@ -714,6 +931,7 @@ impl Clone for Vecs {
indexes_to_realized_profit: self.indexes_to_realized_profit.clone(),
height_to_realized_loss: self.height_to_realized_loss.clone(),
indexes_to_realized_loss: self.indexes_to_realized_loss.clone(),
indexes_to_negative_realized_loss: self.indexes_to_negative_realized_loss.clone(),
height_to_value_created: self.height_to_value_created.clone(),
indexes_to_value_created: self.indexes_to_value_created.clone(),
height_to_adjusted_value_created: self.height_to_adjusted_value_created.clone(),
@@ -722,9 +940,21 @@ impl Clone for Vecs {
indexes_to_value_destroyed: self.indexes_to_value_destroyed.clone(),
height_to_adjusted_value_destroyed: self.height_to_adjusted_value_destroyed.clone(),
indexes_to_adjusted_value_destroyed: self.indexes_to_adjusted_value_destroyed.clone(),
dateindex_to_realized_cap_30d_change: self.dateindex_to_realized_cap_30d_change.clone(),
indexes_to_realized_value: self.indexes_to_realized_value.clone(),
indexes_to_net_realized_profit_and_loss: self
.indexes_to_net_realized_profit_and_loss
.clone(),
indexes_to_realized_price: self.indexes_to_realized_price.clone(),
dateindex_to_sell_side_risk_ratio: self.dateindex_to_sell_side_risk_ratio.clone(),
indexes_to_realized_price_extra: self.indexes_to_realized_price_extra.clone(),
dateindex_to_spent_output_profit_ratio: self
.dateindex_to_spent_output_profit_ratio
.clone(),
dateindex_to_adjusted_spent_output_profit_ratio: self
.dateindex_to_adjusted_spent_output_profit_ratio
.clone(),
}
}
}
+33 -9
View File
@@ -22,11 +22,11 @@ use super::Dollars;
KnownLayout,
Serialize,
)]
pub struct Cents(u64);
pub struct Cents(i64);
impl From<Dollars> for Cents {
fn from(value: Dollars) -> Self {
Self((*value * 100.0).round() as u64)
Self((*value * 100.0).round() as i64)
}
}
@@ -36,15 +36,36 @@ impl From<Cents> for f64 {
}
}
impl From<i64> for Cents {
fn from(value: i64) -> Self {
Self(value)
}
}
impl From<u64> for Cents {
fn from(value: u64) -> Self {
Self(value)
Self(value as i64)
}
}
impl From<usize> for Cents {
fn from(value: usize) -> Self {
Self(value as i64)
}
}
impl From<Cents> for i64 {
fn from(value: Cents) -> Self {
value.0
}
}
impl From<Cents> for u64 {
fn from(value: Cents) -> Self {
value.0
if value.0 < 0 {
panic!("Shouldn't convert neg cents to u64")
}
value.0 as u64
}
}
@@ -58,21 +79,24 @@ impl Add for Cents {
impl Div<usize> for Cents {
type Output = Self;
fn div(self, rhs: usize) -> Self::Output {
Self(self.0 / rhs as u64)
Self(self.0 / rhs as i64)
}
}
impl From<u128> for Cents {
fn from(value: u128) -> Self {
if value > u64::MAX as u128 {
panic!("u128 bigger than u64")
if value > i64::MAX as u128 {
panic!("u128 bigger than i64")
}
Self(value as u64)
Self(value as i64)
}
}
impl From<Cents> for u128 {
fn from(value: Cents) -> Self {
if value.0 < 0 {
panic!("Shouldn't convert neg cents to u128")
}
value.0 as u128
}
}
@@ -87,7 +111,7 @@ impl Mul<Cents> for Cents {
impl Mul<usize> for Cents {
type Output = Cents;
fn mul(self, rhs: usize) -> Self::Output {
Self(self.0 * rhs as u64)
Self(self.0 * rhs as i64)
}
}
+11 -2
View File
@@ -147,10 +147,17 @@ impl Mul<Bitcoin> for Dollars {
impl Mul<StoredF32> for Dollars {
type Output = Self;
fn mul(self, rhs: StoredF32) -> Self::Output {
self * *rhs as f64
}
}
impl Mul<f64> for Dollars {
type Output = Self;
fn mul(self, rhs: f64) -> Self::Output {
if rhs.is_nan() {
self
} else {
Self::from(Cents::from(Self::from(self.0 * *rhs as f64)))
Self::from(Cents::from(self) * Cents::from(Dollars::from(rhs)))
}
}
}
@@ -204,7 +211,9 @@ impl CheckedSub for Dollars {
impl CheckedSub<usize> for Dollars {
fn checked_sub(self, rhs: usize) -> Option<Self> {
Some(Self(self.0 - rhs as f64))
Some(Dollars::from(
Cents::from(self).checked_sub(Cents::from(rhs)).unwrap(),
))
}
}
+10
View File
@@ -1,3 +1,4 @@
use core::panic;
use std::{
cmp::Ordering,
ops::{Add, Div, Mul, Sub},
@@ -24,10 +25,19 @@ impl From<f32> for StoredF32 {
impl From<f64> for StoredF32 {
fn from(value: f64) -> Self {
if value > f32::MAX as f64 {
panic!("f64 is too big")
}
Self(value as f32)
}
}
impl From<StoredF32> for f64 {
fn from(value: StoredF32) -> Self {
value.0 as f64
}
}
impl From<StoredF64> for StoredF32 {
fn from(value: StoredF64) -> Self {
Self(*value as f32)
+1 -1
View File
@@ -24,7 +24,7 @@ color-eyre = { workspace = true }
jiff = { workspace = true }
log = { workspace = true }
minreq = { workspace = true }
oxc = { version = "0.72.0", features = ["codegen", "minifier"] }
oxc = { version = "0.72.1", features = ["codegen", "minifier"] }
serde = { workspace = true }
tokio = { workspace = true }
tower-http = { version = "0.6.4", features = ["compression-full", "trace"] }
+86
View File
@@ -194,6 +194,61 @@ where
self.safe_flush(exit)
}
pub fn compute_add(
&mut self,
max_from: I,
added: &impl AnyIterableVec<I, T>,
adder: &impl AnyIterableVec<I, T>,
exit: &Exit,
) -> Result<()>
where
T: Add<Output = T>,
{
self.validate_computed_version_or_reset_file(
Version::ZERO + self.inner.version() + added.version() + adder.version(),
)?;
let index = max_from.min(I::from(self.len()));
let mut added_iter = adder.iter();
added.iter_at(index).try_for_each(|(i, v)| {
let v = v.into_inner() + added_iter.unwrap_get_inner(i);
self.forced_push_at(i, v, exit)
})?;
self.safe_flush(exit)
}
pub fn compute_subtract(
&mut self,
max_from: I,
subtracted: &impl AnyIterableVec<I, T>,
subtracter: &impl AnyIterableVec<I, T>,
exit: &Exit,
) -> Result<()>
where
T: CheckedSub,
{
self.validate_computed_version_or_reset_file(
Version::ZERO + self.inner.version() + subtracted.version() + subtracter.version(),
)?;
let index = max_from.min(I::from(self.len()));
let mut subtracted_iter = subtracter.iter();
subtracted.iter_at(index).try_for_each(|(i, v)| {
let v = v
.into_inner()
.checked_sub(subtracted_iter.unwrap_get_inner(i))
.unwrap();
self.forced_push_at(i, v, exit)
})?;
self.safe_flush(exit)
}
pub fn compute_divide<T2, T3, T4>(
&mut self,
max_from: I,
@@ -610,6 +665,37 @@ where
self.safe_flush(exit)
}
pub fn compute_change(
&mut self,
max_from: I,
source: &impl AnyIterableVec<I, T>,
len: usize,
exit: &Exit,
) -> Result<()>
where
I: CheckedSub,
T: CheckedSub + Default,
{
self.validate_computed_version_or_reset_file(
Version::ZERO + self.inner.version() + source.version(),
)?;
let index = max_from.min(I::from(self.len()));
let mut source_iter = source.iter();
source.iter_at(index).try_for_each(|(i, current)| {
let current = current.into_inner();
let prev = i
.checked_sub(I::from(len))
.map(|prev_i| source_iter.unwrap_get_inner(prev_i))
.unwrap_or_default();
self.forced_push_at(i, current.checked_sub(prev).unwrap(), exit)
})?;
self.safe_flush(exit)
}
pub fn compute_percentage_change<T2>(
&mut self,
max_from: I,