mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-07-20 23:48:10 -07:00
global: snapshot
This commit is contained in:
@@ -2,7 +2,6 @@ use brk_core::Dollars;
|
||||
|
||||
use super::{RealizedState, SupplyState};
|
||||
|
||||
// Vecs ? probably
|
||||
#[derive(Debug, Default, Clone)]
|
||||
pub struct CohortState {
|
||||
pub supply: SupplyState,
|
||||
@@ -11,6 +10,12 @@ pub struct CohortState {
|
||||
}
|
||||
|
||||
impl CohortState {
|
||||
pub fn reset_single_iteration_values(&mut self) {
|
||||
if let Some(realized) = self.realized.as_mut() {
|
||||
realized.reset_single_iteration_values();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn increment(&mut self, supply_state: &SupplyState, price: Option<Dollars>) {
|
||||
self.supply += supply_state;
|
||||
if let Some(realized) = self.realized.as_mut() {
|
||||
@@ -25,7 +30,28 @@ impl CohortState {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn send(&mut self, supply_state: &SupplyState, price: Option<Dollars>) {}
|
||||
pub fn receive(&mut self, supply_state: &SupplyState, price: Option<Dollars>) {
|
||||
self.supply += supply_state;
|
||||
if let Some(realized) = self.realized.as_mut() {
|
||||
realized.receive(supply_state, price.unwrap());
|
||||
}
|
||||
}
|
||||
|
||||
pub fn receive(&mut self, supply_state: &SupplyState, price: Option<Dollars>) {}
|
||||
pub fn send(
|
||||
&mut self,
|
||||
supply_state: &SupplyState,
|
||||
current_price: Option<Dollars>,
|
||||
prev_price: Option<Dollars>,
|
||||
older_than_hour: bool,
|
||||
) {
|
||||
self.supply -= supply_state;
|
||||
if let Some(realized) = self.realized.as_mut() {
|
||||
realized.send(
|
||||
supply_state,
|
||||
current_price.unwrap(),
|
||||
prev_price.unwrap(),
|
||||
older_than_hour,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,31 +107,31 @@ impl<T> OutputsBySize<T> {
|
||||
pub fn get_mut(&mut self, group: usize) -> &mut T {
|
||||
if group == 0 {
|
||||
&mut self._0sat
|
||||
} else if group == 10 {
|
||||
} else if group == 1 {
|
||||
&mut self.from_1sat_to_10sats
|
||||
} else if group == 100 {
|
||||
} else if group == 10 {
|
||||
&mut self.from_10sats_to_100sats
|
||||
} else if group == 1_000 {
|
||||
} else if group == 100 {
|
||||
&mut self.from_100sats_to_1_000sats
|
||||
} else if group == 10_000 {
|
||||
} else if group == 1_000 {
|
||||
&mut self.from_1_000sats_to_10_000sats
|
||||
} else if group == 100_000 {
|
||||
} else if group == 10_000 {
|
||||
&mut self.from_10_000sats_to_100_000sats
|
||||
} else if group == 1_000_000 {
|
||||
} else if group == 100_000 {
|
||||
&mut self.from_100_000sats_to_1_000_000sats
|
||||
} else if group == 10_000_000 {
|
||||
} else if group == 1_000_000 {
|
||||
&mut self.from_1_000_000sats_to_10_000_000sats
|
||||
} else if group == 1_00_000_000 {
|
||||
} else if group == 10_000_000 {
|
||||
&mut self.from_10_000_000sats_to_1btc
|
||||
} else if group == 10_00_000_000 {
|
||||
} else if group == 1_00_000_000 {
|
||||
&mut self.from_1btc_to_10btc
|
||||
} else if group == 100_00_000_000 {
|
||||
} else if group == 10_00_000_000 {
|
||||
&mut self.from_10btc_to_100btc
|
||||
} else if group == 1_000_00_000_000 {
|
||||
} else if group == 100_00_000_000 {
|
||||
&mut self.from_100btc_to_1_000btc
|
||||
} else if group == 10_000_00_000_000 {
|
||||
} else if group == 1_000_00_000_000 {
|
||||
&mut self.from_1_000btc_to_10_000btc
|
||||
} else if group == 100_000_00_000_000 {
|
||||
} else if group == 10_000_00_000_000 {
|
||||
&mut self.from_10_000btc_to_100_000btc
|
||||
} else {
|
||||
&mut self.from_100_000btc
|
||||
|
||||
@@ -24,7 +24,7 @@ impl<T> OutputsByType<T> {
|
||||
OutputType::P2A => &self.spendable.p2a,
|
||||
OutputType::Empty => &self.spendable.empty,
|
||||
OutputType::Unknown => &self.spendable.unknown,
|
||||
OutputType::OpReturn => &self.unspendable.op_return,
|
||||
OutputType::OpReturn => &self.unspendable.opreturn,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ impl<T> OutputsByType<T> {
|
||||
OutputType::P2A => &mut self.spendable.p2a,
|
||||
OutputType::Unknown => &mut self.spendable.unknown,
|
||||
OutputType::Empty => &mut self.spendable.empty,
|
||||
OutputType::OpReturn => &mut self.unspendable.op_return,
|
||||
OutputType::OpReturn => &mut self.unspendable.opreturn,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,12 +2,12 @@ use std::ops::{Add, AddAssign};
|
||||
|
||||
#[derive(Default, Clone)]
|
||||
pub struct OutputsByUnspendableType<T> {
|
||||
pub op_return: T,
|
||||
pub opreturn: T,
|
||||
}
|
||||
|
||||
impl<T> OutputsByUnspendableType<T> {
|
||||
pub fn as_vec(&self) -> [&T; 1] {
|
||||
[&self.op_return]
|
||||
[&self.opreturn]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ where
|
||||
type Output = Self;
|
||||
fn add(self, rhs: Self) -> Self::Output {
|
||||
Self {
|
||||
op_return: self.op_return + rhs.op_return,
|
||||
opreturn: self.opreturn + rhs.opreturn,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -28,6 +28,6 @@ where
|
||||
T: AddAssign,
|
||||
{
|
||||
fn add_assign(&mut self, rhs: Self) {
|
||||
self.op_return += rhs.op_return;
|
||||
self.opreturn += rhs.opreturn;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ use brk_vec::StoredIndex;
|
||||
use rayon::prelude::*;
|
||||
use std::{collections::BTreeMap, ops::ControlFlow};
|
||||
|
||||
use brk_core::{Dollars, HalvingEpoch, Height, Timestamp};
|
||||
use brk_core::{CheckedSub, Dollars, HalvingEpoch, Height, Timestamp};
|
||||
|
||||
mod by_epoch;
|
||||
mod by_from;
|
||||
@@ -133,16 +133,27 @@ impl Outputs<(OutputFilter, vecs::utxos::cohort::Vecs)> {
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let last_timestamp = chain_state.last().unwrap().timestamp;
|
||||
let current_price = chain_state.last().unwrap().price;
|
||||
|
||||
height_to_sent.into_iter().for_each(|(height, sent)| {
|
||||
let block_state = chain_state.get(height.unwrap_to_usize()).unwrap();
|
||||
let price = block_state.price;
|
||||
let prev_price = block_state.price;
|
||||
|
||||
let days_old = block_state
|
||||
.timestamp
|
||||
.difference_in_days_between(last_timestamp);
|
||||
|
||||
self.all.1.state.decrement(&sent.spendable_supply, price);
|
||||
let older_than_hour =
|
||||
jiff::Timestamp::from(last_timestamp.checked_sub(block_state.timestamp).unwrap())
|
||||
.as_second()
|
||||
>= 60 * 60;
|
||||
|
||||
self.all.1.state.send(
|
||||
&sent.spendable_supply,
|
||||
current_price,
|
||||
prev_price,
|
||||
older_than_hour,
|
||||
);
|
||||
|
||||
time_based_vecs
|
||||
.iter_mut()
|
||||
@@ -154,25 +165,32 @@ impl Outputs<(OutputFilter, vecs::utxos::cohort::Vecs)> {
|
||||
_ => unreachable!(),
|
||||
})
|
||||
.for_each(|(_, vecs)| {
|
||||
vecs.state.decrement(&sent.spendable_supply, price);
|
||||
vecs.state.send(
|
||||
&sent.spendable_supply,
|
||||
current_price,
|
||||
prev_price,
|
||||
older_than_hour,
|
||||
);
|
||||
});
|
||||
|
||||
sent.by_type.spendable.as_typed_vec().into_iter().for_each(
|
||||
|(output_type, supply_state)| {
|
||||
self.by_type
|
||||
.get_mut(output_type)
|
||||
.1
|
||||
.state
|
||||
.decrement(supply_state, price)
|
||||
self.by_type.get_mut(output_type).1.state.send(
|
||||
supply_state,
|
||||
current_price,
|
||||
prev_price,
|
||||
older_than_hour,
|
||||
)
|
||||
},
|
||||
);
|
||||
|
||||
sent.by_size.into_iter().for_each(|(group, supply_state)| {
|
||||
self.by_size
|
||||
.get_mut(group)
|
||||
.1
|
||||
.state
|
||||
.decrement(&supply_state, price);
|
||||
self.by_size.get_mut(group).1.state.send(
|
||||
&supply_state,
|
||||
current_price,
|
||||
prev_price,
|
||||
older_than_hour,
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -189,7 +207,7 @@ impl Outputs<(OutputFilter, vecs::utxos::cohort::Vecs)> {
|
||||
.into_iter()
|
||||
.chain(self.by_up_to.as_mut_vec().map(|(_, v)| v))
|
||||
.for_each(|v| {
|
||||
v.state.increment(&supply_state, price);
|
||||
v.state.receive(&supply_state, price);
|
||||
});
|
||||
|
||||
self.by_type
|
||||
@@ -200,8 +218,7 @@ impl Outputs<(OutputFilter, vecs::utxos::cohort::Vecs)> {
|
||||
OutputFilter::Type(output_type) => *output_type,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
vecs.state
|
||||
.increment(received.by_type.get(output_type), price)
|
||||
vecs.state.receive(received.by_type.get(output_type), price)
|
||||
});
|
||||
|
||||
received
|
||||
@@ -212,7 +229,7 @@ impl Outputs<(OutputFilter, vecs::utxos::cohort::Vecs)> {
|
||||
.get_mut(group)
|
||||
.1
|
||||
.state
|
||||
.increment(&supply_state, price);
|
||||
.receive(&supply_state, price);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,49 +1,98 @@
|
||||
use std::cmp::Ordering;
|
||||
|
||||
use brk_core::{Bitcoin, CheckedSub, Dollars};
|
||||
|
||||
use super::SupplyState;
|
||||
|
||||
#[derive(Debug, Default, Clone)]
|
||||
pub struct RealizedState {
|
||||
pub realized_cap: Dollars,
|
||||
// pub realized_profit: Dollars, // sent price vs now price
|
||||
// pub realized_loss: Dollars, // sent price vs now price
|
||||
// pub value_created: Dollars, // supply * price now
|
||||
// pub adjusted_value_created: Dollars, // supply - up to 1 hour supply * price now
|
||||
// pub value_destroyed: Dollars, // supply * price then
|
||||
// pub adjusted_value_destroyed: Dollars, // supply - up to 1 hour supply * price then
|
||||
pub cap: Dollars,
|
||||
pub profit: Dollars,
|
||||
pub loss: Dollars,
|
||||
pub value_created: Dollars,
|
||||
pub adj_value_created: Dollars,
|
||||
pub value_destroyed: Dollars,
|
||||
pub adj_value_destroyed: Dollars,
|
||||
}
|
||||
|
||||
impl RealizedState {
|
||||
pub const NAN: Self = Self {
|
||||
realized_cap: Dollars::NAN,
|
||||
// realized_profit: Dollars::NAN,
|
||||
// realized_loss: Dollars::NAN,
|
||||
// value_created: Dollars::NAN,
|
||||
// adjusted_value_created: Dollars::NAN,
|
||||
// value_destroyed: Dollars::NAN,
|
||||
// adjusted_value_destroyed: Dollars::NAN,
|
||||
cap: Dollars::NAN,
|
||||
profit: Dollars::NAN,
|
||||
loss: Dollars::NAN,
|
||||
value_created: Dollars::NAN,
|
||||
adj_value_created: Dollars::NAN,
|
||||
value_destroyed: Dollars::NAN,
|
||||
adj_value_destroyed: Dollars::NAN,
|
||||
};
|
||||
|
||||
pub fn increment(&mut self, supply_state: &SupplyState, price: Dollars) {
|
||||
if supply_state.value.is_not_zero() {
|
||||
if self.realized_cap == Dollars::NAN {
|
||||
self.realized_cap = Dollars::ZERO;
|
||||
// self.realized_profit = Dollars::ZERO;
|
||||
// self.realized_loss = Dollars::ZERO;
|
||||
// self.value_created = Dollars::ZERO;
|
||||
// self.adjusted_value_created = Dollars::ZERO;
|
||||
// self.value_destroyed = Dollars::ZERO;
|
||||
// self.adjusted_value_destroyed = Dollars::ZERO;
|
||||
}
|
||||
|
||||
self.realized_cap += price * Bitcoin::from(supply_state.value);
|
||||
pub fn reset_single_iteration_values(&mut self) {
|
||||
if self.cap != Dollars::NAN {
|
||||
self.profit = Dollars::ZERO;
|
||||
self.loss = Dollars::ZERO;
|
||||
self.value_created = Dollars::ZERO;
|
||||
self.adj_value_created = Dollars::ZERO;
|
||||
self.value_destroyed = Dollars::ZERO;
|
||||
self.adj_value_destroyed = Dollars::ZERO;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn increment(&mut self, supply_state: &SupplyState, price: Dollars) {
|
||||
if supply_state.value.is_zero() {
|
||||
return;
|
||||
}
|
||||
|
||||
if self.cap == Dollars::NAN {
|
||||
self.cap = Dollars::ZERO;
|
||||
self.profit = Dollars::ZERO;
|
||||
self.loss = Dollars::ZERO;
|
||||
self.value_created = Dollars::ZERO;
|
||||
self.adj_value_created = Dollars::ZERO;
|
||||
self.value_destroyed = Dollars::ZERO;
|
||||
self.adj_value_destroyed = Dollars::ZERO;
|
||||
}
|
||||
|
||||
let value = price * Bitcoin::from(supply_state.value);
|
||||
self.cap += value;
|
||||
}
|
||||
|
||||
pub fn decrement(&mut self, supply_state: &SupplyState, price: Dollars) {
|
||||
self.realized_cap = self
|
||||
.realized_cap
|
||||
.checked_sub(price * Bitcoin::from(supply_state.value))
|
||||
.unwrap();
|
||||
let value = price * Bitcoin::from(supply_state.value);
|
||||
self.cap = self.cap.checked_sub(value).unwrap();
|
||||
}
|
||||
|
||||
pub fn receive(&mut self, supply_state: &SupplyState, current_price: Dollars) {
|
||||
self.increment(supply_state, current_price);
|
||||
}
|
||||
|
||||
pub fn send(
|
||||
&mut self,
|
||||
supply_state: &SupplyState,
|
||||
current_price: Dollars,
|
||||
prev_price: Dollars,
|
||||
older_than_hour: bool,
|
||||
) {
|
||||
let current_value = current_price * Bitcoin::from(supply_state.value);
|
||||
let prev_value = prev_price * Bitcoin::from(supply_state.value);
|
||||
|
||||
self.value_created += current_value;
|
||||
self.value_destroyed += prev_value;
|
||||
|
||||
if older_than_hour {
|
||||
self.adj_value_created += current_value;
|
||||
self.adj_value_destroyed += prev_value;
|
||||
}
|
||||
|
||||
match current_price.cmp(&prev_price) {
|
||||
Ordering::Greater => {
|
||||
self.profit += current_value.checked_sub(prev_value).unwrap();
|
||||
}
|
||||
Ordering::Less => {
|
||||
self.loss += prev_value.checked_sub(current_value).unwrap();
|
||||
}
|
||||
Ordering::Equal => {}
|
||||
}
|
||||
|
||||
self.decrement(supply_state, prev_price);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user