global: snapshot

This commit is contained in:
nym21
2026-03-05 16:11:25 +01:00
parent 6f2a87be4f
commit eedb8d22c1
61 changed files with 2035 additions and 2757 deletions

View File

@@ -185,7 +185,11 @@ impl CohortState {
let sats = supply.value;
let current_ps = CentsSats::from_price_sats(current_price, sats);
let prev_ps = CentsSats::from_price_sats(prev_price, sats);
let ath_ps = CentsSats::from_price_sats(ath, sats);
let ath_ps = if ath == current_price {
current_ps
} else {
CentsSats::from_price_sats(ath, sats)
};
let prev_investor_cap = prev_ps.to_investor_cap(prev_price);
Some(SendPrecomputed {
sats,
@@ -287,6 +291,10 @@ impl CohortState {
self.cost_basis_data.compute_percentiles()
}
pub(crate) fn cached_percentiles(&self) -> Option<Percentiles> {
self.cost_basis_data.cached_percentiles()
}
pub(crate) fn compute_unrealized_state(&mut self, height_price: Cents) -> UnrealizedState {
self.cost_basis_data.compute_unrealized_state(height_price)
}

View File

@@ -83,7 +83,7 @@ impl CostBasisData {
}
fn assert_pending_empty(&self) {
assert!(
debug_assert!(
self.pending.is_empty() && self.pending_raw_is_zero(),
"CostBasisData: pending not empty, call apply_pending first"
);
@@ -180,7 +180,7 @@ impl CostBasisData {
}
pub(crate) fn apply_pending(&mut self) {
if self.pending.is_empty() && self.pending_raw_is_zero() {
if self.pending.is_empty() {
return;
}
self.generation = self.generation.wrapping_add(1);
@@ -277,6 +277,10 @@ impl CostBasisData {
self.cached_percentiles = None;
}
pub(crate) fn cached_percentiles(&self) -> Option<Percentiles> {
self.cached_percentiles
}
pub(crate) fn compute_percentiles(&mut self) -> Option<Percentiles> {
self.assert_pending_empty();
if !self.percentiles_dirty {

View File

@@ -35,6 +35,9 @@ impl RealizedState {
/// Get realized cap as CentsUnsigned (divides by ONE_BTC).
#[inline]
pub(crate) fn cap(&self) -> Cents {
if self.cap_raw == 0 {
return Cents::ZERO;
}
Cents::new((self.cap_raw / Sats::ONE_BTC_U128) as u64)
}
@@ -76,18 +79,27 @@ impl RealizedState {
/// Get realized profit as CentsUnsigned.
#[inline]
pub(crate) fn profit(&self) -> Cents {
if self.profit_raw == 0 {
return Cents::ZERO;
}
Cents::new((self.profit_raw / Sats::ONE_BTC_U128) as u64)
}
/// Get realized loss as CentsUnsigned.
#[inline]
pub(crate) fn loss(&self) -> Cents {
if self.loss_raw == 0 {
return Cents::ZERO;
}
Cents::new((self.loss_raw / Sats::ONE_BTC_U128) as u64)
}
/// Get profit value created as CentsUnsigned (sell_price × sats for profit cases).
#[inline]
pub(crate) fn profit_value_created(&self) -> Cents {
if self.profit_value_created_raw == 0 {
return Cents::ZERO;
}
Cents::new((self.profit_value_created_raw / Sats::ONE_BTC_U128) as u64)
}
@@ -95,12 +107,18 @@ impl RealizedState {
/// This is also known as profit_flow.
#[inline]
pub(crate) fn profit_value_destroyed(&self) -> Cents {
if self.profit_value_destroyed_raw == 0 {
return Cents::ZERO;
}
Cents::new((self.profit_value_destroyed_raw / Sats::ONE_BTC_U128) as u64)
}
/// Get loss value created as CentsUnsigned (sell_price × sats for loss cases).
#[inline]
pub(crate) fn loss_value_created(&self) -> Cents {
if self.loss_value_created_raw == 0 {
return Cents::ZERO;
}
Cents::new((self.loss_value_created_raw / Sats::ONE_BTC_U128) as u64)
}
@@ -108,6 +126,9 @@ impl RealizedState {
/// This is also known as capitulation_flow.
#[inline]
pub(crate) fn loss_value_destroyed(&self) -> Cents {
if self.loss_value_destroyed_raw == 0 {
return Cents::ZERO;
}
Cents::new((self.loss_value_destroyed_raw / Sats::ONE_BTC_U128) as u64)
}
@@ -116,6 +137,9 @@ impl RealizedState {
/// by selling at peak instead of when actually sold.
#[inline]
pub(crate) fn peak_regret(&self) -> Cents {
if self.peak_regret_raw == 0 {
return Cents::ZERO;
}
Cents::new((self.peak_regret_raw / Sats::ONE_BTC_U128) as u64)
}

View File

@@ -61,17 +61,22 @@ struct CachedStateRaw {
impl CachedStateRaw {
/// Convert raw values to final output by dividing by ONE_BTC.
fn to_output(&self) -> UnrealizedState {
#[inline(always)]
fn div_btc(raw: u128) -> Cents {
if raw == 0 {
Cents::ZERO
} else {
Cents::new((raw / Sats::ONE_BTC_U128) as u64)
}
}
UnrealizedState {
supply_in_profit: self.supply_in_profit,
supply_in_loss: self.supply_in_loss,
unrealized_profit: Cents::new((self.unrealized_profit / Sats::ONE_BTC_U128) as u64),
unrealized_loss: Cents::new((self.unrealized_loss / Sats::ONE_BTC_U128) as u64),
invested_capital_in_profit: Cents::new(
(self.invested_capital_in_profit / Sats::ONE_BTC_U128) as u64,
),
invested_capital_in_loss: Cents::new(
(self.invested_capital_in_loss / Sats::ONE_BTC_U128) as u64,
),
unrealized_profit: div_btc(self.unrealized_profit),
unrealized_loss: div_btc(self.unrealized_loss),
invested_capital_in_profit: div_btc(self.invested_capital_in_profit),
invested_capital_in_loss: div_btc(self.invested_capital_in_loss),
investor_cap_in_profit_raw: self.investor_cap_in_profit,
investor_cap_in_loss_raw: self.investor_cap_in_loss,
invested_capital_in_profit_raw: self.invested_capital_in_profit,

View File

@@ -2,6 +2,7 @@ use std::ops::{Add, AddAssign};
use brk_cohort::{ByAmountRange, GroupedByType};
use brk_types::{OutputType, Sats, SupplyState};
use vecdb::unlikely;
#[derive(Default, Debug)]
pub struct Transacted {
@@ -20,7 +21,7 @@ impl Transacted {
*self.by_type.get_mut(_type) += &supply;
if _type.is_unspendable() {
if unlikely(_type.is_unspendable()) {
return;
}