brk: metric trimming part X

This commit is contained in:
nym21
2026-07-29 23:40:07 +02:00
parent 1c51e9fe56
commit e236669f87
45 changed files with 772 additions and 630 deletions
+65 -85
View File
@@ -2062,8 +2062,8 @@ pub struct AverageBlockCumulativeInSumPattern {
pub average: _1m1w1y24hPattern3,
pub block: BtcCentsSatsUsdPattern3,
pub cumulative: BtcCentsSatsUsdPattern,
pub in_loss: AverageBlockCumulativeSumPattern3,
pub in_profit: AverageBlockCumulativeSumPattern3,
pub in_loss: AverageBlockCumulativeSumPattern2,
pub in_profit: AverageBlockCumulativeSumPattern2,
pub sum: _1m1w1y24hPattern4,
}
@@ -2074,8 +2074,8 @@ impl AverageBlockCumulativeInSumPattern {
average: _1m1w1y24hPattern3::new(client.clone(), _m(&acc, "average")),
block: BtcCentsSatsUsdPattern3::new(client.clone(), acc.clone()),
cumulative: BtcCentsSatsUsdPattern::new(client.clone(), _m(&acc, "cumulative")),
in_loss: AverageBlockCumulativeSumPattern3::new(client.clone(), _m(&acc, "in_loss")),
in_profit: AverageBlockCumulativeSumPattern3::new(client.clone(), _m(&acc, "in_profit")),
in_loss: AverageBlockCumulativeSumPattern2::new(client.clone(), _m(&acc, "in_loss")),
in_profit: AverageBlockCumulativeSumPattern2::new(client.clone(), _m(&acc, "in_profit")),
sum: _1m1w1y24hPattern4::new(client.clone(), _m(&acc, "sum")),
}
}
@@ -2641,33 +2641,13 @@ impl _1m1w1y24hPattern8 {
/// Pattern struct for repeated tree structure.
pub struct AverageBlockCumulativeSumPattern2 {
pub average: _1m1w1y24hPattern<StoredF32>,
pub block: SeriesPattern18<StoredU32>,
pub cumulative: SeriesPattern1<StoredU64>,
pub sum: _1m1w1y24hPattern<StoredU64>,
}
impl AverageBlockCumulativeSumPattern2 {
/// Create a new pattern node with accumulated series name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
average: _1m1w1y24hPattern::new(client.clone(), _m(&acc, "average")),
block: SeriesPattern18::new(client.clone(), acc.clone()),
cumulative: SeriesPattern1::new(client.clone(), _m(&acc, "cumulative")),
sum: _1m1w1y24hPattern::new(client.clone(), _m(&acc, "sum")),
}
}
}
/// Pattern struct for repeated tree structure.
pub struct AverageBlockCumulativeSumPattern3 {
pub average: _1m1w1y24hPattern3,
pub block: BtcCentsSatsUsdPattern3,
pub cumulative: BtcCentsSatsUsdPattern,
pub sum: _1m1w1y24hPattern4,
}
impl AverageBlockCumulativeSumPattern3 {
impl AverageBlockCumulativeSumPattern2 {
/// Create a new pattern node with accumulated series name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
@@ -2977,18 +2957,18 @@ impl BlockCumulativeSumPattern {
/// Pattern struct for repeated tree structure.
pub struct BlocksDominanceRewardsPattern {
pub blocks_mined: AverageBlockCumulativeSumPattern2,
pub blocks_mined: AverageBlockCumulativeSumPattern<StoredU64>,
pub dominance: _1m1w1y24hPercentPpmRatioPattern,
pub rewards: AverageBlockCumulativeSumPattern3,
pub rewards: AverageBlockCumulativeSumPattern2,
}
impl BlocksDominanceRewardsPattern {
/// Create a new pattern node with accumulated series name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
blocks_mined: AverageBlockCumulativeSumPattern2::new(client.clone(), _m(&acc, "blocks_mined")),
blocks_mined: AverageBlockCumulativeSumPattern::new(client.clone(), _m(&acc, "blocks_mined")),
dominance: _1m1w1y24hPercentPpmRatioPattern::new(client.clone(), _m(&acc, "dominance")),
rewards: AverageBlockCumulativeSumPattern3::new(client.clone(), _m(&acc, "rewards")),
rewards: AverageBlockCumulativeSumPattern2::new(client.clone(), _m(&acc, "rewards")),
}
}
}
@@ -3272,7 +3252,7 @@ impl RsiStochPattern {
/// Pattern struct for repeated tree structure.
pub struct SpentUnspentUtxoPattern {
pub spent_count: AverageBlockCumulativeSumPattern2,
pub spent_count: AverageBlockCumulativeSumPattern<StoredU64>,
pub unspent_count: BaseDeltaPattern,
pub utxo_turnover_1y: SeriesPattern1<StoredF32>,
}
@@ -3281,7 +3261,7 @@ impl SpentUnspentUtxoPattern {
/// Create a new pattern node with accumulated series name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
spent_count: AverageBlockCumulativeSumPattern2::new(client.clone(), _m(&acc, "spent_utxo_count")),
spent_count: AverageBlockCumulativeSumPattern::new(client.clone(), _m(&acc, "spent_utxo_count")),
unspent_count: BaseDeltaPattern::new(client.clone(), _m(&acc, "utxo_count")),
utxo_turnover_1y: SeriesPattern1::new(client.clone(), _m(&acc, "utxo_turnover_1y")),
}
@@ -3468,7 +3448,7 @@ impl BlockCumulativePattern {
/// Pattern struct for repeated tree structure.
pub struct BlocksDominancePattern {
pub blocks_mined: AverageBlockCumulativeSumPattern2,
pub blocks_mined: AverageBlockCumulativeSumPattern<StoredU64>,
pub dominance: PercentPpmRatioPattern2,
}
@@ -3476,7 +3456,7 @@ impl BlocksDominancePattern {
/// Create a new pattern node with accumulated series name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
blocks_mined: AverageBlockCumulativeSumPattern2::new(client.clone(), _m(&acc, "blocks_mined")),
blocks_mined: AverageBlockCumulativeSumPattern::new(client.clone(), _m(&acc, "blocks_mined")),
dominance: PercentPpmRatioPattern2::new(client.clone(), _m(&acc, "dominance")),
}
}
@@ -3860,14 +3840,14 @@ impl SupplyPattern {
/// Pattern struct for repeated tree structure.
pub struct TransferPattern {
pub transfer_volume: AverageBlockCumulativeSumPattern3,
pub transfer_volume: AverageBlockCumulativeSumPattern2,
}
impl TransferPattern {
/// Create a new pattern node with accumulated series name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
transfer_volume: AverageBlockCumulativeSumPattern3::new(client.clone(), acc.clone()),
transfer_volume: AverageBlockCumulativeSumPattern2::new(client.clone(), acc.clone()),
}
}
}
@@ -4038,14 +4018,14 @@ impl SeriesTree_Blocks_Size {
/// Series tree node.
pub struct SeriesTree_Blocks_Count {
pub target: _1m1w1y24hPattern<StoredU64>,
pub total: AverageBlockCumulativeSumPattern2,
pub total: AverageBlockCumulativeSumPattern<StoredU64>,
}
impl SeriesTree_Blocks_Count {
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
Self {
target: _1m1w1y24hPattern::new(client.clone(), "block_count_target".to_string()),
total: AverageBlockCumulativeSumPattern2::new(client.clone(), "block_count".to_string()),
total: AverageBlockCumulativeSumPattern::new(client.clone(), "block_count".to_string()),
}
}
}
@@ -4558,14 +4538,14 @@ impl SeriesTree_Transactions_Versions {
/// Series tree node.
pub struct SeriesTree_Transactions_Volume {
pub transfer_volume: AverageBlockCumulativeSumPattern3,
pub transfer_volume: AverageBlockCumulativeSumPattern2,
pub tx_per_sec: _1m1w1y24hPattern<StoredF32>,
}
impl SeriesTree_Transactions_Volume {
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
Self {
transfer_volume: AverageBlockCumulativeSumPattern3::new(client.clone(), "transfer_volume_bis".to_string()),
transfer_volume: AverageBlockCumulativeSumPattern2::new(client.clone(), "transfer_volume_bis".to_string()),
tx_per_sec: _1m1w1y24hPattern::new(client.clone(), "tx_per_sec".to_string()),
}
}
@@ -5704,7 +5684,7 @@ impl SeriesTree_Mining {
/// Series tree node.
pub struct SeriesTree_Mining_Rewards {
pub coinbase: AverageBlockCumulativeSumPattern3,
pub coinbase: AverageBlockCumulativeSumPattern2,
pub subsidy: SeriesTree_Mining_Rewards_Subsidy,
pub fees: SeriesTree_Mining_Rewards_Fees,
pub output_volume: SeriesPattern18<Sats>,
@@ -5714,7 +5694,7 @@ pub struct SeriesTree_Mining_Rewards {
impl SeriesTree_Mining_Rewards {
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
Self {
coinbase: AverageBlockCumulativeSumPattern3::new(client.clone(), "coinbase".to_string()),
coinbase: AverageBlockCumulativeSumPattern2::new(client.clone(), "coinbase".to_string()),
subsidy: SeriesTree_Mining_Rewards_Subsidy::new(client.clone(), format!("{base_path}_subsidy")),
fees: SeriesTree_Mining_Rewards_Fees::new(client.clone(), format!("{base_path}_fees")),
output_volume: SeriesPattern18::new(client.clone(), "output_volume".to_string()),
@@ -8248,7 +8228,7 @@ impl SeriesTree_Cohorts_Utxo_All {
/// Series tree node.
pub struct SeriesTree_Cohorts_Utxo_All_Outputs {
pub unspent_count: BaseDeltaPattern,
pub spent_count: AverageBlockCumulativeSumPattern2,
pub spent_count: AverageBlockCumulativeSumPattern<StoredU64>,
pub utxo_turnover_1y: SeriesPattern1<StoredF32>,
}
@@ -8256,7 +8236,7 @@ impl SeriesTree_Cohorts_Utxo_All_Outputs {
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
Self {
unspent_count: BaseDeltaPattern::new(client.clone(), "utxo_count".to_string()),
spent_count: AverageBlockCumulativeSumPattern2::new(client.clone(), "spent_utxo_count".to_string()),
spent_count: AverageBlockCumulativeSumPattern::new(client.clone(), "spent_utxo_count".to_string()),
utxo_turnover_1y: SeriesPattern1::new(client.clone(), "utxo_turnover_1y".to_string()),
}
}
@@ -9029,53 +9009,53 @@ impl SeriesTree_Cohorts_Utxo_Profitability_Loss {
/// Series tree node.
pub struct SeriesTree_Cohorts_Utxo_Matured {
pub under_1h: AverageBlockCumulativeSumPattern3,
pub _1h_to_1d: AverageBlockCumulativeSumPattern3,
pub _1d_to_1w: AverageBlockCumulativeSumPattern3,
pub _1w_to_1m: AverageBlockCumulativeSumPattern3,
pub _1m_to_2m: AverageBlockCumulativeSumPattern3,
pub _2m_to_3m: AverageBlockCumulativeSumPattern3,
pub _3m_to_4m: AverageBlockCumulativeSumPattern3,
pub _4m_to_5m: AverageBlockCumulativeSumPattern3,
pub _5m_to_6m: AverageBlockCumulativeSumPattern3,
pub _6m_to_1y: AverageBlockCumulativeSumPattern3,
pub _1y_to_2y: AverageBlockCumulativeSumPattern3,
pub _2y_to_3y: AverageBlockCumulativeSumPattern3,
pub _3y_to_4y: AverageBlockCumulativeSumPattern3,
pub _4y_to_5y: AverageBlockCumulativeSumPattern3,
pub _5y_to_6y: AverageBlockCumulativeSumPattern3,
pub _6y_to_7y: AverageBlockCumulativeSumPattern3,
pub _7y_to_8y: AverageBlockCumulativeSumPattern3,
pub _8y_to_10y: AverageBlockCumulativeSumPattern3,
pub _10y_to_12y: AverageBlockCumulativeSumPattern3,
pub _12y_to_15y: AverageBlockCumulativeSumPattern3,
pub over_15y: AverageBlockCumulativeSumPattern3,
pub under_1h: AverageBlockCumulativeSumPattern2,
pub _1h_to_1d: AverageBlockCumulativeSumPattern2,
pub _1d_to_1w: AverageBlockCumulativeSumPattern2,
pub _1w_to_1m: AverageBlockCumulativeSumPattern2,
pub _1m_to_2m: AverageBlockCumulativeSumPattern2,
pub _2m_to_3m: AverageBlockCumulativeSumPattern2,
pub _3m_to_4m: AverageBlockCumulativeSumPattern2,
pub _4m_to_5m: AverageBlockCumulativeSumPattern2,
pub _5m_to_6m: AverageBlockCumulativeSumPattern2,
pub _6m_to_1y: AverageBlockCumulativeSumPattern2,
pub _1y_to_2y: AverageBlockCumulativeSumPattern2,
pub _2y_to_3y: AverageBlockCumulativeSumPattern2,
pub _3y_to_4y: AverageBlockCumulativeSumPattern2,
pub _4y_to_5y: AverageBlockCumulativeSumPattern2,
pub _5y_to_6y: AverageBlockCumulativeSumPattern2,
pub _6y_to_7y: AverageBlockCumulativeSumPattern2,
pub _7y_to_8y: AverageBlockCumulativeSumPattern2,
pub _8y_to_10y: AverageBlockCumulativeSumPattern2,
pub _10y_to_12y: AverageBlockCumulativeSumPattern2,
pub _12y_to_15y: AverageBlockCumulativeSumPattern2,
pub over_15y: AverageBlockCumulativeSumPattern2,
}
impl SeriesTree_Cohorts_Utxo_Matured {
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
Self {
under_1h: AverageBlockCumulativeSumPattern3::new(client.clone(), "utxos_under_1h_old_matured_supply".to_string()),
_1h_to_1d: AverageBlockCumulativeSumPattern3::new(client.clone(), "utxos_1h_to_1d_old_matured_supply".to_string()),
_1d_to_1w: AverageBlockCumulativeSumPattern3::new(client.clone(), "utxos_1d_to_1w_old_matured_supply".to_string()),
_1w_to_1m: AverageBlockCumulativeSumPattern3::new(client.clone(), "utxos_1w_to_1m_old_matured_supply".to_string()),
_1m_to_2m: AverageBlockCumulativeSumPattern3::new(client.clone(), "utxos_1m_to_2m_old_matured_supply".to_string()),
_2m_to_3m: AverageBlockCumulativeSumPattern3::new(client.clone(), "utxos_2m_to_3m_old_matured_supply".to_string()),
_3m_to_4m: AverageBlockCumulativeSumPattern3::new(client.clone(), "utxos_3m_to_4m_old_matured_supply".to_string()),
_4m_to_5m: AverageBlockCumulativeSumPattern3::new(client.clone(), "utxos_4m_to_5m_old_matured_supply".to_string()),
_5m_to_6m: AverageBlockCumulativeSumPattern3::new(client.clone(), "utxos_5m_to_6m_old_matured_supply".to_string()),
_6m_to_1y: AverageBlockCumulativeSumPattern3::new(client.clone(), "utxos_6m_to_1y_old_matured_supply".to_string()),
_1y_to_2y: AverageBlockCumulativeSumPattern3::new(client.clone(), "utxos_1y_to_2y_old_matured_supply".to_string()),
_2y_to_3y: AverageBlockCumulativeSumPattern3::new(client.clone(), "utxos_2y_to_3y_old_matured_supply".to_string()),
_3y_to_4y: AverageBlockCumulativeSumPattern3::new(client.clone(), "utxos_3y_to_4y_old_matured_supply".to_string()),
_4y_to_5y: AverageBlockCumulativeSumPattern3::new(client.clone(), "utxos_4y_to_5y_old_matured_supply".to_string()),
_5y_to_6y: AverageBlockCumulativeSumPattern3::new(client.clone(), "utxos_5y_to_6y_old_matured_supply".to_string()),
_6y_to_7y: AverageBlockCumulativeSumPattern3::new(client.clone(), "utxos_6y_to_7y_old_matured_supply".to_string()),
_7y_to_8y: AverageBlockCumulativeSumPattern3::new(client.clone(), "utxos_7y_to_8y_old_matured_supply".to_string()),
_8y_to_10y: AverageBlockCumulativeSumPattern3::new(client.clone(), "utxos_8y_to_10y_old_matured_supply".to_string()),
_10y_to_12y: AverageBlockCumulativeSumPattern3::new(client.clone(), "utxos_10y_to_12y_old_matured_supply".to_string()),
_12y_to_15y: AverageBlockCumulativeSumPattern3::new(client.clone(), "utxos_12y_to_15y_old_matured_supply".to_string()),
over_15y: AverageBlockCumulativeSumPattern3::new(client.clone(), "utxos_over_15y_old_matured_supply".to_string()),
under_1h: AverageBlockCumulativeSumPattern2::new(client.clone(), "utxos_under_1h_old_matured_supply".to_string()),
_1h_to_1d: AverageBlockCumulativeSumPattern2::new(client.clone(), "utxos_1h_to_1d_old_matured_supply".to_string()),
_1d_to_1w: AverageBlockCumulativeSumPattern2::new(client.clone(), "utxos_1d_to_1w_old_matured_supply".to_string()),
_1w_to_1m: AverageBlockCumulativeSumPattern2::new(client.clone(), "utxos_1w_to_1m_old_matured_supply".to_string()),
_1m_to_2m: AverageBlockCumulativeSumPattern2::new(client.clone(), "utxos_1m_to_2m_old_matured_supply".to_string()),
_2m_to_3m: AverageBlockCumulativeSumPattern2::new(client.clone(), "utxos_2m_to_3m_old_matured_supply".to_string()),
_3m_to_4m: AverageBlockCumulativeSumPattern2::new(client.clone(), "utxos_3m_to_4m_old_matured_supply".to_string()),
_4m_to_5m: AverageBlockCumulativeSumPattern2::new(client.clone(), "utxos_4m_to_5m_old_matured_supply".to_string()),
_5m_to_6m: AverageBlockCumulativeSumPattern2::new(client.clone(), "utxos_5m_to_6m_old_matured_supply".to_string()),
_6m_to_1y: AverageBlockCumulativeSumPattern2::new(client.clone(), "utxos_6m_to_1y_old_matured_supply".to_string()),
_1y_to_2y: AverageBlockCumulativeSumPattern2::new(client.clone(), "utxos_1y_to_2y_old_matured_supply".to_string()),
_2y_to_3y: AverageBlockCumulativeSumPattern2::new(client.clone(), "utxos_2y_to_3y_old_matured_supply".to_string()),
_3y_to_4y: AverageBlockCumulativeSumPattern2::new(client.clone(), "utxos_3y_to_4y_old_matured_supply".to_string()),
_4y_to_5y: AverageBlockCumulativeSumPattern2::new(client.clone(), "utxos_4y_to_5y_old_matured_supply".to_string()),
_5y_to_6y: AverageBlockCumulativeSumPattern2::new(client.clone(), "utxos_5y_to_6y_old_matured_supply".to_string()),
_6y_to_7y: AverageBlockCumulativeSumPattern2::new(client.clone(), "utxos_6y_to_7y_old_matured_supply".to_string()),
_7y_to_8y: AverageBlockCumulativeSumPattern2::new(client.clone(), "utxos_7y_to_8y_old_matured_supply".to_string()),
_8y_to_10y: AverageBlockCumulativeSumPattern2::new(client.clone(), "utxos_8y_to_10y_old_matured_supply".to_string()),
_10y_to_12y: AverageBlockCumulativeSumPattern2::new(client.clone(), "utxos_10y_to_12y_old_matured_supply".to_string()),
_12y_to_15y: AverageBlockCumulativeSumPattern2::new(client.clone(), "utxos_12y_to_15y_old_matured_supply".to_string()),
over_15y: AverageBlockCumulativeSumPattern2::new(client.clone(), "utxos_over_15y_old_matured_supply".to_string()),
}
}
}
@@ -1,6 +1,5 @@
use brk_error::Result;
use brk_indexer::Indexer;
use brk_types::StoredU32;
use vecdb::Exit;
use super::Vecs;
@@ -8,13 +7,12 @@ use super::Vecs;
impl Vecs {
pub(crate) fn compute(&mut self, indexer: &Indexer, exit: &Exit) -> Result<()> {
let starting_height = indexer.safe_lengths().height;
self.total.block.compute_range(
self.total.cumulative.height.compute_cumulative_count(
starting_height,
&indexer.vecs.blocks.weight,
|h| (h, StoredU32::from(1_u32)),
|_| true,
exit,
)?;
self.total.compute_rest(starting_height, exit)?;
Ok(())
}
+2 -2
View File
@@ -1,5 +1,5 @@
use brk_traversable::Traversable;
use brk_types::{StoredU32, StoredU64};
use brk_types::StoredU64;
use vecdb::{Rw, StorageMode};
use crate::internal::{ConstantVecs, PerBlockCumulativeRolling, Windows};
@@ -7,5 +7,5 @@ use crate::internal::{ConstantVecs, PerBlockCumulativeRolling, Windows};
#[derive(Traversable)]
pub struct Vecs<M: StorageMode = Rw> {
pub target: Windows<ConstantVecs<StoredU64>>,
pub total: PerBlockCumulativeRolling<StoredU32, StoredU64, M>,
pub total: PerBlockCumulativeRolling<StoredU64, M>,
}
@@ -14,7 +14,7 @@ use super::TotalAddrCountVecs;
/// New address count per block (global + per-type).
#[derive(Deref, DerefMut, Traversable)]
pub struct NewAddrCountVecs<M: StorageMode = Rw>(
#[traversable(flatten)] pub WithAddrTypes<PerBlockCumulativeRolling<StoredU64, StoredU64, M>>,
#[traversable(flatten)] pub WithAddrTypes<PerBlockCumulativeRolling<StoredU64, M>>,
);
impl NewAddrCountVecs {
@@ -24,15 +24,15 @@ impl NewAddrCountVecs {
indexes: &indexes::Vecs,
cached_starts: &Windows<&WindowStartVec>,
) -> Result<Self> {
Ok(Self(WithAddrTypes::<
PerBlockCumulativeRolling<StoredU64, StoredU64>,
>::forced_import(
db,
"new_addr_count",
version,
indexes,
cached_starts,
)?))
Ok(Self(
WithAddrTypes::<PerBlockCumulativeRolling<StoredU64>>::forced_import(
db,
"new_addr_count",
version,
indexes,
cached_starts,
)?,
))
}
pub(crate) fn compute(
@@ -41,9 +41,12 @@ impl NewAddrCountVecs {
total_addr_count: &TotalAddrCountVecs,
exit: &Exit,
) -> Result<()> {
self.0.all.compute(max_from, exit, |height_vec| {
Ok(height_vec.compute_change(max_from, &total_addr_count.all.height, 1, exit)?)
})?;
self.0.all.cumulative.height.compute_transform(
max_from,
&total_addr_count.all.height,
|(height, total, ..)| (height, StoredU64::from(total)),
exit,
)?;
for ((_, new), (_, total)) in self
.0
@@ -51,9 +54,12 @@ impl NewAddrCountVecs {
.iter_mut()
.zip(total_addr_count.by_addr_type.iter())
{
new.compute(max_from, exit, |height_vec| {
Ok(height_vec.compute_change(max_from, &total.height, 1, exit)?)
})?;
new.cumulative.height.compute_transform(
max_from,
&total.height,
|(height, total, ..)| (height, StoredU64::from(total)),
exit,
)?;
}
Ok(())
@@ -65,12 +65,10 @@ use super::state::AddrTypeToAddrEventCount;
/// address can appear in multiple blocks.
#[derive(Traversable)]
pub struct AddrEventsVecs<M: StorageMode = Rw> {
pub output_to_reused_addr_count:
WithAddrTypes<PerBlockCumulativeRolling<StoredU64, StoredU64, M>>,
pub output_to_reused_addr_count: WithAddrTypes<PerBlockCumulativeRolling<StoredU64, M>>,
pub output_to_reused_addr_share: WithAddrTypes<PercentCumulativeRolling<PartsPerMillion32, M>>,
pub spendable_output_to_reused_addr_share: PercentCumulativeRolling<PartsPerMillion32, M>,
pub input_from_reused_addr_count:
WithAddrTypes<PerBlockCumulativeRolling<StoredU64, StoredU64, M>>,
pub input_from_reused_addr_count: WithAddrTypes<PerBlockCumulativeRolling<StoredU64, M>>,
pub input_from_reused_addr_share: WithAddrTypes<PercentCumulativeRolling<PartsPerMillion32, M>>,
pub active_reused_addr_count: PerBlockRollingAverage<StoredU32, StoredU64, M>,
pub active_reused_addr_share: PerBlockRollingAverage<StoredF32, StoredF32, M>,
@@ -85,7 +83,7 @@ impl AddrEventsVecs {
cached_starts: &Windows<&WindowStartVec>,
) -> Result<Self> {
let import_count = |name: &str| {
WithAddrTypes::<PerBlockCumulativeRolling<StoredU64, StoredU64>>::forced_import(
WithAddrTypes::<PerBlockCumulativeRolling<StoredU64>>::forced_import(
db,
name,
version,
@@ -211,10 +209,6 @@ impl AddrEventsVecs {
inputs_by_type: &inputs::ByTypeVecs,
exit: &Exit,
) -> Result<()> {
self.output_to_reused_addr_count
.compute_rest(starting_lengths.height, exit)?;
self.input_from_reused_addr_count
.compute_rest(starting_lengths.height, exit)?;
self.active_reused_addr_count
.compute_rest(starting_lengths.height, exit)?;
self.active_reused_addr_share
@@ -613,7 +613,8 @@ impl UTXOCohorts<Rw> {
.realized
.sopr
.value_destroyed
.block
.cumulative
.height
.read_only_clone();
// "all" cohort computed first (no all_supply_sats needed).
@@ -7,7 +7,7 @@ use brk_types::{
use rayon::prelude::*;
use rustc_hash::FxHashSet;
use tracing::{debug, info};
use vecdb::{AnyStoredVec, AnyVec, Exit, ReadableVec, VecIndex, WritableVec, unlikely};
use vecdb::{AnyVec, Exit, ReadableVec, VecIndex, unlikely};
use crate::{
distribution::{
@@ -213,9 +213,7 @@ pub(crate) fn process_blocks(
.par_iter_vecs_mut()
.chain(vecs.addr_cohorts.par_iter_vecs_mut())
.chain(vecs.addrs.par_iter_height_mut())
.chain(rayon::iter::once(
&mut vecs.coinblocks_destroyed.block as &mut dyn AnyStoredVec,
))
.chain(rayon::iter::once(vecs.coinblocks_destroyed.stored_mut()))
.try_for_each(|v| v.any_truncate_if_needed_at(start))?;
}
@@ -394,7 +392,7 @@ pub(crate) fn process_blocks(
blocks_old as u128 * u64::from(sent.spendable_supply.value) as u128
})
.sum();
vecs.coinblocks_destroyed.block.push(StoredF64::from(
vecs.coinblocks_destroyed.push_block(StoredF64::from(
total_satblocks as f64 / Sats::ONE_BTC_U128 as f64,
));
}
@@ -80,7 +80,7 @@ pub(crate) fn write(
.chain(
[
&mut vecs.supply_state as &mut dyn AnyStoredVec,
&mut vecs.coinblocks_destroyed.block,
vecs.coinblocks_destroyed.stored_mut(),
]
.into_par_iter(),
)
@@ -23,7 +23,7 @@ pub struct ActivityCore<M: StorageMode = Rw> {
#[traversable(flatten)]
pub minimal: ActivityMinimal<M>,
pub coindays_destroyed: PerBlockCumulativeRolling<StoredF64, StoredF64, M>,
pub coindays_destroyed: PerBlockCumulativeRolling<StoredF64, M>,
#[traversable(wrap = "transfer_volume", rename = "in_profit")]
pub transfer_volume_in_profit: ValuePerBlockCumulativeRolling<M>,
#[traversable(wrap = "transfer_volume", rename = "in_loss")]
@@ -53,8 +53,7 @@ impl ActivityCore {
pub(crate) fn push_state(&mut self, state: &CohortState<impl RealizedOps, impl CostBasisOps>) {
self.minimal.push_state(state);
self.coindays_destroyed
.block
.push(StoredF64::from(Bitcoin::from(state.satdays_destroyed)));
.push_block(StoredF64::from(Bitcoin::from(state.satdays_destroyed)));
self.transfer_volume_in_profit
.block
.sats
@@ -67,7 +66,7 @@ impl ActivityCore {
pub(crate) fn collect_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {
let mut vecs = self.minimal.collect_vecs_mut();
vecs.push(&mut self.coindays_destroyed.block);
vecs.push(self.coindays_destroyed.stored_mut());
vecs.push(&mut self.transfer_volume_in_profit.inner.block.sats);
vecs.push(&mut self.transfer_volume_in_profit.inner.block.cents);
vecs.push(&mut self.transfer_volume_in_loss.inner.block.sats);
@@ -89,7 +88,7 @@ impl ActivityCore {
self.minimal
.compute_from_stateful(starting_lengths, &minimal_refs, exit)?;
sum_others!(self, starting_lengths, others, exit; coindays_destroyed.block);
sum_others!(self, starting_lengths, others, exit; coindays_destroyed.cumulative.height);
sum_others!(self, starting_lengths, others, exit; transfer_volume_in_profit.block.sats);
sum_others!(self, starting_lengths, others, exit; transfer_volume_in_loss.block.sats);
@@ -104,8 +103,6 @@ impl ActivityCore {
) -> Result<()> {
self.minimal
.compute_rest_part1(prices, starting_lengths, exit)?;
self.coindays_destroyed
.compute_rest(starting_lengths.height, exit)?;
self.transfer_volume_in_profit
.compute_rest(starting_lengths.height, prices, exit)?;
self.transfer_volume_in_loss
@@ -123,8 +123,8 @@ impl AllCohortMetrics {
self.asopr.compute_rest_part2(
starting_lengths,
&self.activity.transfer_volume.block.cents,
&self.realized.core.sopr.value_destroyed.block,
&self.activity.transfer_volume.inner.cumulative.cents.height,
&self.realized.core.sopr.value_destroyed.cumulative.height,
under_1h_value_created,
under_1h_value_destroyed,
exit,
@@ -80,8 +80,22 @@ impl ExtendedAdjustedCohortMetrics {
self.asopr.compute_rest_part2(
starting_lengths,
&self.inner.activity.transfer_volume.block.cents,
&self.inner.realized.core.sopr.value_destroyed.block,
&self
.inner
.activity
.transfer_volume
.inner
.cumulative
.cents
.height,
&self
.inner
.realized
.core
.sopr
.value_destroyed
.cumulative
.height,
under_1h_value_created,
under_1h_value_destroyed,
exit,
@@ -54,10 +54,9 @@ impl<T: NumericValue + JsonSchema> ConfigImport for PerBlock<T> {
Self::forced_import(cfg.db, &cfg.name(suffix), cfg.version + offset, cfg.indexes)
}
}
impl<T, C> ConfigImport for PerBlockCumulativeRolling<T, C>
impl<T> ConfigImport for PerBlockCumulativeRolling<T>
where
T: NumericValue + JsonSchema + Into<C>,
C: NumericValue + JsonSchema,
T: NumericValue + JsonSchema,
{
fn config_import(cfg: &ImportConfig, suffix: &str, offset: Version) -> Result<Self> {
Self::forced_import(
@@ -1,9 +1,7 @@
use brk_error::Result;
use brk_indexer::Lengths;
use brk_traversable::Traversable;
use brk_types::{
Height, PartsPerMillionSigned64, StoredF32, StoredI64, StoredU32, StoredU64, Version,
};
use brk_types::{Height, PartsPerMillionSigned64, StoredF32, StoredI64, StoredU64, Version};
use vecdb::{AnyStoredVec, AnyVec, Exit, ReadableVec, Rw, StorageMode, WritableVec};
use crate::{
@@ -18,7 +16,7 @@ use crate::{
#[derive(Traversable)]
pub struct OutputsBase<M: StorageMode = Rw> {
pub unspent_count: PerBlockWithDeltas<StoredU64, StoredI64, PartsPerMillionSigned64, M>,
pub spent_count: PerBlockCumulativeRolling<StoredU32, StoredU64, M>,
pub spent_count: PerBlockCumulativeRolling<StoredU64, M>,
pub utxo_turnover_1y: PerBlock<StoredF32, M>,
}
@@ -52,19 +50,18 @@ impl OutputsBase {
.height
.push(StoredU64::from(state.supply.utxo_count));
self.spent_count
.block
.push(StoredU32::from(state.spent_utxo_count));
.push_block(StoredU64::from(state.spent_utxo_count));
}
pub(crate) fn collect_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {
vec![
&mut self.unspent_count.height as &mut dyn AnyStoredVec,
&mut self.spent_count.block,
self.spent_count.stored_mut(),
]
}
pub(crate) fn compute_rest(&mut self, max_from: Height, exit: &Exit) -> Result<()> {
self.spent_count.compute_rest(max_from, exit)
pub(crate) fn compute_rest(&mut self, _max_from: Height, _exit: &Exit) -> Result<()> {
Ok(())
}
pub(crate) fn compute_part2(
@@ -96,7 +93,7 @@ impl OutputsBase {
.collect::<Vec<_>>(),
exit,
)?;
sum_others!(self, starting_lengths, others, exit; spent_count.block);
sum_others!(self, starting_lengths, others, exit; spent_count.cumulative.height);
Ok(())
}
}
@@ -12,8 +12,8 @@ use crate::{
#[derive(Traversable)]
pub struct AdjustedSopr<M: StorageMode = Rw> {
pub ratio: RollingWindows<StoredF64, M>,
pub transfer_volume: PerBlockCumulativeRolling<Cents, Cents, M>,
pub value_destroyed: PerBlockCumulativeRolling<Cents, Cents, M>,
pub transfer_volume: PerBlockCumulativeRolling<Cents, M>,
pub value_destroyed: PerBlockCumulativeRolling<Cents, M>,
}
impl AdjustedSopr {
@@ -35,24 +35,19 @@ impl AdjustedSopr {
under_1h_value_destroyed: &impl ReadableVec<Height, Cents>,
exit: &Exit,
) -> Result<()> {
self.transfer_volume.block.compute_subtract(
self.transfer_volume.cumulative.height.compute_subtract(
starting_lengths.height,
base_transfer_volume,
under_1h_transfer_volume,
exit,
)?;
self.value_destroyed.block.compute_subtract(
self.value_destroyed.cumulative.height.compute_subtract(
starting_lengths.height,
base_value_destroyed,
under_1h_value_destroyed,
exit,
)?;
self.transfer_volume
.compute_rest(starting_lengths.height, exit)?;
self.value_destroyed
.compute_rest(starting_lengths.height, exit)?;
for ((sopr, tv), vd) in self
.ratio
.as_mut_array()
@@ -5,10 +5,7 @@ use brk_types::{
Bitcoin, Cents, CentsSigned, Dollars, Height, PartsPerMillionSigned64, StoredF64, Version,
};
use derive_more::{Deref, DerefMut};
use vecdb::{
AnyStoredVec, Exit, LazyVecFrom1, ReadableCloneableVec, ReadableVec, Rw, StorageMode,
WritableVec,
};
use vecdb::{AnyStoredVec, Exit, LazyVecFrom1, ReadableCloneableVec, ReadableVec, Rw, StorageMode};
use crate::{
distribution::state::{CohortState, CostBasisOps, RealizedOps},
@@ -32,7 +29,7 @@ pub struct NegRealizedLoss {
#[derive(Traversable)]
pub struct RealizedSoprCore<M: StorageMode = Rw> {
pub value_destroyed: PerBlockCumulativeRolling<Cents, Cents, M>,
pub value_destroyed: PerBlockCumulativeRolling<Cents, M>,
pub ratio: RollingWindow24hPerBlock<StoredF64, M>,
}
@@ -117,13 +114,12 @@ impl RealizedCore {
self.minimal.push_state(state);
self.sopr
.value_destroyed
.block
.push(state.realized.value_destroyed());
.push_block(state.realized.value_destroyed());
}
pub(crate) fn collect_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {
let mut vecs = self.minimal.collect_vecs_mut();
vecs.push(&mut self.sopr.value_destroyed.block);
vecs.push(self.sopr.value_destroyed.stored_mut());
vecs
}
@@ -137,7 +133,7 @@ impl RealizedCore {
self.minimal
.compute_from_stateful(starting_lengths, &minimal_refs, exit)?;
sum_others!(self, starting_lengths, others, exit; sopr.value_destroyed.block);
sum_others!(self, starting_lengths, others, exit; sopr.value_destroyed.cumulative.height);
Ok(())
}
@@ -148,10 +144,6 @@ impl RealizedCore {
) -> Result<()> {
self.minimal.compute_rest_part1(starting_lengths, exit)?;
self.sopr
.value_destroyed
.compute_rest(starting_lengths.height, exit)?;
self.net_pnl.block.cents.compute_transform2(
starting_lengths.height,
&self.minimal.profit.block.cents,
+1 -5
View File
@@ -144,7 +144,7 @@ pub struct Vecs<M: StorageMode = Rw> {
#[traversable(wrap = "cohorts", rename = "addr")]
pub addr_cohorts: AddrCohorts<M>,
#[traversable(wrap = "cointime/activity")]
pub coinblocks_destroyed: PerBlockCumulativeRolling<StoredF64, StoredF64, M>,
pub coinblocks_destroyed: PerBlockCumulativeRolling<StoredF64, M>,
pub addrs: AddrMetricsVecs<M>,
/// In-memory state that does NOT survive rollback.
@@ -552,10 +552,6 @@ impl Vecs {
r2?;
}
// 5b. Compute coinblocks_destroyed cumulative from raw
self.coinblocks_destroyed
.compute_rest(starting_lengths.height, exit)?;
// 6. Compute rest part1 (day1 mappings)
info!("Computing rest part 1...");
{
@@ -8,16 +8,18 @@ use crate::{distribution, internal::PerBlockCumulativeRolling};
pub(crate) fn compute_rest(
starting_height: brk_types::Height,
created: &PerBlockCumulativeRolling<StoredF64, StoredF64>,
consumed: &PerBlockCumulativeRolling<StoredF64, StoredF64>,
stored: &mut PerBlockCumulativeRolling<StoredF64, StoredF64>,
created: &PerBlockCumulativeRolling<StoredF64>,
consumed: &PerBlockCumulativeRolling<StoredF64>,
stored: &mut PerBlockCumulativeRolling<StoredF64>,
derived: &mut DerivedVecs,
exit: &Exit,
) -> Result<()> {
stored.compute(starting_height, exit, |vec| {
vec.compute_subtract(starting_height, &created.block, &consumed.block, exit)?;
Ok(())
})?;
stored.cumulative.height.compute_subtract(
starting_height,
&created.cumulative.height,
&consumed.cumulative.height,
exit,
)?;
derived.liveliness.height.compute_divide(
starting_height,
@@ -47,16 +49,12 @@ impl Vecs {
let all_metrics = &distribution.utxo_cohorts.all.metrics;
let circulating_supply = &all_metrics.supply.total.sats.height;
self.coinblocks_created
.compute(starting_height, exit, |vec| {
vec.compute_transform(
starting_height,
circulating_supply,
|(i, v, ..)| (i, StoredF64::from(Bitcoin::from(v))),
exit,
)?;
Ok(())
})?;
self.coinblocks_created.compute_cumulative_transformed(
starting_height,
circulating_supply,
|value| StoredF64::from(Bitcoin::from(value)),
exit,
)?;
compute_rest(
starting_height,
@@ -14,8 +14,8 @@ pub struct DerivedVecs<M: StorageMode = Rw> {
#[derive(Deref, DerefMut, Traversable)]
pub struct Vecs<M: StorageMode = Rw> {
pub coinblocks_created: PerBlockCumulativeRolling<StoredF64, StoredF64, M>,
pub coinblocks_stored: PerBlockCumulativeRolling<StoredF64, StoredF64, M>,
pub coinblocks_created: PerBlockCumulativeRolling<StoredF64, M>,
pub coinblocks_stored: PerBlockCumulativeRolling<StoredF64, M>,
#[deref]
#[deref_mut]
#[traversable(flatten)]
@@ -2,7 +2,7 @@ use brk_cohort::AGE_RANGE_BOUNDS;
use brk_error::Result;
use brk_indexer::Indexer;
use brk_types::{Bitcoin, Height, ONE_DAY_IN_SEC_F64, Sats, StoredF64, Timestamp, Version};
use vecdb::{AnyStoredVec, AnyVec, Exit, ReadableVec, WritableVec};
use vecdb::{AnyVec, Exit, ReadableVec};
use super::super::activity;
use super::{CohortVecs, Vecs};
@@ -72,19 +72,18 @@ impl Vecs {
for cohort in cohorts.iter_mut() {
cohort
.coindays_created
.block
.validate_computed_version_or_reset(created_version)?;
}
let start = cohorts
.iter()
.map(|cohort| cohort.coindays_created.block.len())
.map(|cohort| cohort.coindays_created.cumulative.height.len())
.min()
.unwrap_or_default()
.min(usize::from(starting_height));
for cohort in cohorts.iter_mut() {
cohort.coindays_created.block.truncate_if_needed_at(start)?;
cohort.coindays_created.truncate_if_needed_at(start)?;
}
let source_end = supplies
@@ -109,7 +108,7 @@ impl Vecs {
monotonic_interval_seconds(&timestamp_batch, chunk_start, offset);
for (index, cohort) in cohorts.iter_mut().enumerate() {
cohort.coindays_created.block.push(coindays_created(
cohort.coindays_created.push_block(coindays_created(
supply_batches[index][offset],
interval_seconds,
));
@@ -119,18 +118,12 @@ impl Vecs {
{
let _lock = exit.lock();
for cohort in cohorts.iter_mut() {
cohort.coindays_created.block.write()?;
cohort.coindays_created.write()?;
}
}
chunk_start = chunk_end;
}
for cohort in cohorts {
cohort
.coindays_created
.compute_rest(starting_height, exit)?;
}
Ok(())
}
@@ -158,22 +151,18 @@ impl Vecs {
for cohort in cohorts.iter_mut() {
cohort
.coindays_consumed
.block
.validate_computed_version_or_reset(destroyed_version)?;
}
let start = cohorts
.iter()
.map(|cohort| cohort.coindays_consumed.block.len())
.map(|cohort| cohort.coindays_consumed.cumulative.height.len())
.min()
.unwrap_or_default()
.min(usize::from(starting_height));
for cohort in cohorts.iter_mut() {
cohort
.coindays_consumed
.block
.truncate_if_needed_at(start)?;
cohort.coindays_consumed.truncate_if_needed_at(start)?;
}
let source_end = transfer_volumes
@@ -207,26 +196,19 @@ impl Vecs {
for (index, cohort) in cohorts.iter_mut().enumerate() {
cohort
.coindays_consumed
.block
.push(StoredF64::from(consumed[index]));
.push_block(StoredF64::from(consumed[index]));
}
}
{
let _lock = exit.lock();
for cohort in cohorts.iter_mut() {
cohort.coindays_consumed.block.write()?;
cohort.coindays_consumed.write()?;
}
}
chunk_start = chunk_end;
}
for cohort in cohorts {
cohort
.coindays_consumed
.compute_rest(starting_height, exit)?;
}
Ok(())
}
@@ -10,9 +10,9 @@ use super::super::{SupplyBaseVecs, activity::DerivedVecs as ActivityDerivedVecs}
#[derive(Deref, DerefMut, Traversable)]
pub struct CohortVecs<M: StorageMode = Rw> {
pub coindays_created: PerBlockCumulativeRolling<StoredF64, StoredF64, M>,
pub coindays_consumed: PerBlockCumulativeRolling<StoredF64, StoredF64, M>,
pub coindays_stored: PerBlockCumulativeRolling<StoredF64, StoredF64, M>,
pub coindays_created: PerBlockCumulativeRolling<StoredF64, M>,
pub coindays_consumed: PerBlockCumulativeRolling<StoredF64, M>,
pub coindays_stored: PerBlockCumulativeRolling<StoredF64, M>,
#[deref]
#[deref_mut]
#[traversable(flatten)]
@@ -1,7 +1,7 @@
use brk_error::Result;
use brk_indexer::Indexer;
use brk_types::{Bitcoin, Dollars, StoredF64};
use vecdb::Exit;
use vecdb::{Exit, ReadableVec};
use super::super::activity;
use super::Vecs;
@@ -22,59 +22,66 @@ impl Vecs {
let coindays_destroyed = &all_metrics.activity.coindays_destroyed;
let circulating_supply = &all_metrics.supply.total.btc.height;
self.destroyed.compute(starting_height, exit, |vec| {
vec.compute_multiply(
self.destroyed
.cumulative
.height
.compute_cumulative_transformed_binary(
starting_height,
&prices.spot.usd.height,
&coinblocks_destroyed.block,
|price, value| StoredF64::from(f64::from(price) * f64::from(value)),
exit,
)?;
Ok(())
})?;
self.created.compute(starting_height, exit, |vec| {
vec.compute_multiply(
self.created
.cumulative
.height
.compute_cumulative_transformed_binary(
starting_height,
&prices.spot.usd.height,
&activity.coinblocks_created.block,
|price, value| StoredF64::from(f64::from(price) * f64::from(value)),
exit,
)?;
Ok(())
})?;
self.stored.compute(starting_height, exit, |vec| {
vec.compute_multiply(
self.stored
.cumulative
.height
.compute_cumulative_transformed_binary(
starting_height,
&prices.spot.usd.height,
&activity.coinblocks_stored.block,
|price, value| StoredF64::from(f64::from(price) * f64::from(value)),
exit,
)?;
Ok(())
})?;
// VOCDD: Value of Coin Days Destroyed = price × (CDD / circulating_supply)
// Supply-adjusted to account for growing supply over time
// This is a key input for Reserve Risk / HODL Bank calculation
self.vocdd.compute(starting_height, exit, |vec| {
vec.compute_transform3(
starting_height,
&prices.spot.usd.height,
&coindays_destroyed.block,
circulating_supply,
|(i, price, cdd, supply, _): (_, Dollars, StoredF64, Bitcoin, _)| {
let supply_f64 = f64::from(supply);
if supply_f64 == 0.0 {
(i, StoredF64::from(0.0))
} else {
// VOCDD = price × (CDD / supply)
let vocdd = f64::from(price) * f64::from(cdd) / supply_f64;
(i, StoredF64::from(vocdd))
}
},
exit,
)?;
Ok(())
})?;
let mut cumulative = None;
self.vocdd.cumulative.height.compute_transform3(
starting_height,
&prices.spot.usd.height,
&coindays_destroyed.block,
circulating_supply,
|(i, price, cdd, supply, this): (_, Dollars, StoredF64, Bitcoin, _)| {
let cumulative = cumulative.get_or_insert_with(|| {
i.decremented()
.and_then(|height| this.collect_one(height))
.unwrap_or_default()
});
let supply_f64 = f64::from(supply);
let value = if supply_f64 == 0.0 {
StoredF64::from(0.0)
} else {
// VOCDD = price × (CDD / supply)
StoredF64::from(f64::from(price) * f64::from(cdd) / supply_f64)
};
*cumulative += value;
(i, *cumulative)
},
exit,
)?;
Ok(())
}
@@ -6,8 +6,8 @@ use crate::internal::PerBlockCumulativeRolling;
#[derive(Traversable)]
pub struct Vecs<M: StorageMode = Rw> {
pub destroyed: PerBlockCumulativeRolling<StoredF64, StoredF64, M>,
pub created: PerBlockCumulativeRolling<StoredF64, StoredF64, M>,
pub stored: PerBlockCumulativeRolling<StoredF64, StoredF64, M>,
pub vocdd: PerBlockCumulativeRolling<StoredF64, StoredF64, M>,
pub destroyed: PerBlockCumulativeRolling<StoredF64, M>,
pub created: PerBlockCumulativeRolling<StoredF64, M>,
pub stored: PerBlockCumulativeRolling<StoredF64, M>,
pub vocdd: PerBlockCumulativeRolling<StoredF64, M>,
}
@@ -1,7 +1,7 @@
use brk_error::{OptionData, Result};
use brk_indexer::Indexer;
use brk_types::StoredU64;
use vecdb::{AnyVec, Exit, ReadableVec, VecIndex, WritableVec};
use vecdb::{AnyVec, Exit, ReadableVec, VecIndex};
use super::{Vecs, WithInputTypes};
use crate::internal::{CoinbasePolicy, PerBlockCumulativeRolling, walk_blocks};
@@ -85,10 +85,6 @@ impl Vecs {
}
}
self.input_count
.compute_rest(starting_lengths.height, exit)?;
self.tx_count.compute_rest(starting_lengths.height, exit)?;
for (otype, source) in self.input_count.by_type.iter_typed() {
self.input_share.get_mut(otype).compute_count_ratio(
source,
@@ -112,12 +108,12 @@ impl Vecs {
#[inline]
fn push_block(
metric: &mut WithInputTypes<PerBlockCumulativeRolling<StoredU64, StoredU64>>,
metric: &mut WithInputTypes<PerBlockCumulativeRolling<StoredU64>>,
total: u64,
per_type: &[u64; 12],
) {
metric.all.block.push(StoredU64::from(total));
metric.all.push_block(StoredU64::from(total));
for (otype, vec) in metric.by_type.iter_typed_mut() {
vec.block.push(StoredU64::from(per_type[otype as usize]));
vec.push_block(StoredU64::from(per_type[otype as usize]));
}
}
@@ -17,7 +17,7 @@ impl Vecs {
cached_starts: &Windows<&WindowStartVec>,
) -> Result<Self> {
let input_count =
WithInputTypes::<PerBlockCumulativeRolling<StoredU64, StoredU64>>::forced_import_with(
WithInputTypes::<PerBlockCumulativeRolling<StoredU64>>::forced_import_with(
db,
"input_count_bis",
|t| format!("{t}_prevout_count"),
@@ -25,15 +25,14 @@ impl Vecs {
indexes,
cached_starts,
)?;
let tx_count =
WithInputTypes::<PerBlockCumulativeRolling<StoredU64, StoredU64>>::forced_import_with(
db,
"non_coinbase_tx_count",
|t| format!("tx_count_with_{t}_prevout"),
version,
indexes,
cached_starts,
)?;
let tx_count = WithInputTypes::<PerBlockCumulativeRolling<StoredU64>>::forced_import_with(
db,
"non_coinbase_tx_count",
|t| format!("tx_count_with_{t}_prevout"),
version,
indexes,
cached_starts,
)?;
let input_share = SpendableType::try_new(|_, name| {
PercentCumulativeRolling::forced_import(
@@ -8,8 +8,8 @@ use crate::internal::{PerBlockCumulativeRolling, PercentCumulativeRolling};
#[derive(Traversable)]
pub struct Vecs<M: StorageMode = Rw> {
pub input_count: WithInputTypes<PerBlockCumulativeRolling<StoredU64, StoredU64, M>>,
pub input_count: WithInputTypes<PerBlockCumulativeRolling<StoredU64, M>>,
pub input_share: SpendableType<PercentCumulativeRolling<PartsPerMillion32, M>>,
pub tx_count: WithInputTypes<PerBlockCumulativeRolling<StoredU64, StoredU64, M>>,
pub tx_count: WithInputTypes<PerBlockCumulativeRolling<StoredU64, M>>,
pub tx_share: SpendableType<PercentCumulativeRolling<PartsPerMillion32, M>>,
}
@@ -7,7 +7,7 @@ use brk_error::Result;
use brk_traversable::Traversable;
use brk_types::{Height, Version};
use schemars::JsonSchema;
use vecdb::{AnyStoredVec, AnyVec, Database, Exit, WritableVec};
use vecdb::{AnyStoredVec, AnyVec, Database, WritableVec};
use crate::{
indexes,
@@ -24,10 +24,9 @@ pub struct WithInputTypes<T> {
pub by_type: SpendableType<T>,
}
impl<T, C> WithInputTypes<PerBlockCumulativeRolling<T, C>>
impl<T> WithInputTypes<PerBlockCumulativeRolling<T>>
where
T: NumericValue + JsonSchema + Into<C>,
C: NumericValue + JsonSchema,
T: NumericValue + JsonSchema,
{
pub(crate) fn forced_import_with(
db: &Database,
@@ -49,16 +48,16 @@ where
pub(crate) fn min_stateful_len(&self) -> usize {
self.by_type
.iter()
.map(|v| v.block.len())
.map(|v| v.cumulative.height.len())
.min()
.unwrap()
.min(self.all.block.len())
.min(self.all.cumulative.height.len())
}
pub(crate) fn write(&mut self) -> Result<()> {
self.all.block.write()?;
self.all.cumulative.height.write()?;
for v in self.by_type.iter_mut() {
v.block.write()?;
v.cumulative.height.write()?;
}
Ok(())
}
@@ -69,26 +68,21 @@ where
at_height: Height,
) -> Result<()> {
self.all
.block
.cumulative
.height
.validate_and_truncate(dep_version, at_height)?;
for v in self.by_type.iter_mut() {
v.block.validate_and_truncate(dep_version, at_height)?;
v.cumulative
.height
.validate_and_truncate(dep_version, at_height)?;
}
Ok(())
}
pub(crate) fn truncate_if_needed_at(&mut self, len: usize) -> Result<()> {
self.all.block.truncate_if_needed_at(len)?;
self.all.cumulative.height.truncate_if_needed_at(len)?;
for v in self.by_type.iter_mut() {
v.block.truncate_if_needed_at(len)?;
}
Ok(())
}
pub(crate) fn compute_rest(&mut self, max_from: Height, exit: &Exit) -> Result<()> {
self.all.compute_rest(max_from, exit)?;
for v in self.by_type.iter_mut() {
v.compute_rest(max_from, exit)?;
v.cumulative.height.truncate_if_needed_at(len)?;
}
Ok(())
}
@@ -1,44 +1,41 @@
//! PerBlockCumulativeRolling - base EagerVec + cumulative PerBlock + lazy rolling sums.
//! PerBlockCumulativeRolling - stored cumulative + lazy block and rolling views.
//!
//! Rolling sums are derived lazily from the cumulative vec via LazyDeltaVec.
//! No rolling sum vecs are stored on disk.
//!
//! Type parameters:
//! - `T`: per-block value type (e.g., `StoredU32` for tx counts)
//! - `M`: storage mode (`Rw` or `Ro`)
//! - `C`: cumulative type, defaults to `T`. Use a wider type (e.g., `StoredU64`)
//! when the prefix sum of `T` values could overflow `T`.
//! The cumulative vector is the sole stored source of truth. Per-block values
//! and rolling sums/averages are all derived lazily from it.
use brk_error::Result;
use brk_traversable::Traversable;
use brk_types::{Height, Version};
use schemars::JsonSchema;
use vecdb::{Database, EagerVec, Exit, ImportableVec, PcoVec, Rw, StorageMode};
use vecdb::{
AnyStoredVec, AnyVec, Database, Exit, ReadableCloneableVec, ReadableVec, Rw, StorageMode,
VecValue, WritableVec,
};
use crate::{
indexes,
internal::{
LazyRollingAvgsFromHeight, LazyRollingSumsFromHeight, NumericValue, PerBlock,
WindowStartVec, Windows,
LazyPreviousDeltaVec, LazyRollingAvgsFromHeight, LazyRollingSumsFromHeight, NumericValue,
PerBlock, WindowStartVec, Windows,
},
};
#[derive(Traversable)]
pub struct PerBlockCumulativeRolling<T, C, M: StorageMode = Rw>
pub struct PerBlockCumulativeRolling<T, M: StorageMode = Rw>
where
T: NumericValue + JsonSchema,
C: NumericValue + JsonSchema,
{
pub block: M::Stored<EagerVec<PcoVec<Height, T>>>,
pub cumulative: PerBlock<C, M>,
pub sum: LazyRollingSumsFromHeight<C>,
pub average: LazyRollingAvgsFromHeight<C>,
pub block: LazyPreviousDeltaVec<Height, T>,
pub cumulative: PerBlock<T, M>,
pub sum: LazyRollingSumsFromHeight<T>,
pub average: LazyRollingAvgsFromHeight<T>,
#[traversable(skip)]
last_cumulative: Option<(usize, T)>,
}
impl<T, C> PerBlockCumulativeRolling<T, C>
impl<T> PerBlockCumulativeRolling<T>
where
T: NumericValue + JsonSchema + Into<C>,
C: NumericValue + JsonSchema,
T: NumericValue + JsonSchema,
{
pub(crate) fn forced_import(
db: &Database,
@@ -47,9 +44,14 @@ where
indexes: &indexes::Vecs,
cached_starts: &Windows<&WindowStartVec>,
) -> Result<Self> {
let block = EagerVec::forced_import(db, name, version)?;
let cumulative =
PerBlock::forced_import(db, &format!("{name}_cumulative"), version, indexes)?;
let last_cumulative = cumulative
.height
.collect_last()
.map(|value| (cumulative.height.len(), value));
let cumulative_source = cumulative.height.read_only_boxed_clone();
let block = LazyPreviousDeltaVec::new(name, version, cumulative_source);
let sum = LazyRollingSumsFromHeight::new(
&format!("{name}_sum"),
version,
@@ -70,31 +72,141 @@ where
cumulative,
sum,
average,
last_cumulative,
})
}
/// Compute base data via closure, then cumulative. Rolling sums are lazy.
pub(crate) fn compute(
&mut self,
max_from: Height,
exit: &Exit,
compute_base: impl FnOnce(&mut EagerVec<PcoVec<Height, T>>) -> Result<()>,
) -> Result<()>
#[inline(always)]
pub(crate) fn push_block(&mut self, value: T)
where
C: Default,
T: Copy,
{
compute_base(&mut self.block)?;
self.compute_rest(max_from, exit)
let len = self.cumulative.height.len();
let mut cumulative = match self.last_cumulative {
Some((cached_len, value)) if cached_len == len => value,
_ => self.cumulative.height.collect_last().unwrap_or_default(),
};
cumulative += value;
self.cumulative.height.push(cumulative);
self.last_cumulative = Some((len + 1, cumulative));
}
/// Compute cumulative from already-populated base data. Rolling sums are lazy.
pub(crate) fn compute_rest(&mut self, max_from: Height, exit: &Exit) -> Result<()>
pub(crate) fn compute_cumulative<S>(
&mut self,
max_from: Height,
source: &impl ReadableVec<Height, S>,
exit: &Exit,
) -> Result<()>
where
C: Default,
S: VecValue + Into<T>,
T: Copy,
{
Ok(self
.cumulative
.height
.compute_cumulative(max_from, source, exit)?)
}
pub(crate) fn compute_cumulative_transformed<S>(
&mut self,
max_from: Height,
source: &impl ReadableVec<Height, S>,
mut transform: impl FnMut(S) -> T,
exit: &Exit,
) -> Result<()>
where
S: VecValue,
T: Copy,
{
let mut cumulative = None;
Ok(self.cumulative.height.compute_transform(
max_from,
source,
|(height, value, this)| {
let cumulative = cumulative.get_or_insert_with(|| {
height
.decremented()
.and_then(|height| this.collect_one(height))
.unwrap_or_default()
});
*cumulative += transform(value);
(height, *cumulative)
},
exit,
)?)
}
pub(crate) fn validate_computed_version_or_reset(&mut self, version: Version) -> Result<()> {
self.cumulative
.height
.compute_cumulative(max_from, &self.block, exit)?;
.validate_computed_version_or_reset(version)?;
Ok(())
}
pub(crate) fn validate_and_truncate(&mut self, version: Version, height: Height) -> Result<()> {
Ok(self
.cumulative
.height
.validate_and_truncate(version, height)?)
}
pub(crate) fn truncate_if_needed_at(&mut self, len: usize) -> Result<()> {
Ok(self.cumulative.height.truncate_if_needed_at(len)?)
}
pub(crate) fn write(&mut self) -> Result<()> {
self.cumulative.height.write()?;
Ok(())
}
pub(crate) fn stored_mut(&mut self) -> &mut dyn AnyStoredVec {
&mut self.cumulative.height
}
}
#[cfg(test)]
mod tests {
use brk_types::{Height, StoredU64, Version};
use vecdb::{
AnyStoredVec, Database, EagerVec, ImportableVec, PcoVec, ReadableCloneableVec, ReadableVec,
WritableVec,
};
use crate::internal::LazyPreviousDeltaVec;
#[test]
fn lazy_block_is_the_delta_of_cumulative() {
let suffix = std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap()
.as_nanos();
let path = std::env::temp_dir().join(format!(
"brk-lazy-block-cumulative-{}-{suffix}",
std::process::id()
));
let db = Database::open(&path).unwrap();
let mut cumulative: EagerVec<PcoVec<Height, StoredU64>> =
EagerVec::forced_import(&db, "cumulative", Version::ONE).unwrap();
for value in [1_u64, 3, 6] {
cumulative.push(StoredU64::from(value));
}
cumulative.write().unwrap();
let block = LazyPreviousDeltaVec::<Height, StoredU64>::new(
"block",
Version::ONE,
cumulative.read_only_boxed_clone(),
);
assert_eq!(
block.collect_range_at(0, 3),
[1_u64, 2, 3].map(StoredU64::from)
);
drop(block);
drop(cumulative);
drop(db);
std::fs::remove_dir_all(path).unwrap();
}
}
@@ -1,9 +1,11 @@
mod base;
mod derived_resolutions;
mod map_option;
mod previous_delta;
mod transform_last;
pub use base::*;
pub use derived_resolutions::*;
pub use map_option::*;
pub use previous_delta::*;
pub use transform_last::*;
@@ -0,0 +1,185 @@
use std::sync::Arc;
use brk_traversable::{Traversable, TreeNode, make_leaf};
use schemars::JsonSchema;
use serde::Serialize;
use vecdb::{
AnyExportableVec, AnyVec, CheckedSub, Formattable, ReadableBoxedVec, ReadableVec, TypedVec,
VecIndex, VecValue, Version, short_type_name,
};
/// Lazy `source[index] - source[index - 1]`, with zero before the first value.
///
/// This is a single-source view: it follows source growth automatically and
/// stores nothing on disk.
pub struct LazyPreviousDeltaVec<I, T>
where
I: VecIndex,
T: VecValue,
{
name: Arc<str>,
base_version: Version,
source: ReadableBoxedVec<I, T>,
}
impl<I, T> LazyPreviousDeltaVec<I, T>
where
I: VecIndex,
T: VecValue,
{
pub fn new(name: &str, version: Version, source: ReadableBoxedVec<I, T>) -> Self {
Self {
name: Arc::from(name),
base_version: version,
source,
}
}
}
impl<I, T> Clone for LazyPreviousDeltaVec<I, T>
where
I: VecIndex,
T: VecValue,
{
fn clone(&self) -> Self {
Self {
name: Arc::clone(&self.name),
base_version: self.base_version,
source: self.source.clone(),
}
}
}
impl<I, T> AnyVec for LazyPreviousDeltaVec<I, T>
where
I: VecIndex,
T: VecValue,
{
fn version(&self) -> Version {
self.base_version + self.source.version()
}
fn name(&self) -> &str {
&self.name
}
fn len(&self) -> usize {
self.source.len()
}
fn index_type_to_string(&self) -> &'static str {
I::to_string()
}
fn region_names(&self) -> Vec<String> {
Vec::new()
}
fn value_type_to_size_of(&self) -> usize {
size_of::<T>()
}
fn value_type_to_string(&self) -> &'static str {
short_type_name::<T>()
}
}
impl<I, T> TypedVec for LazyPreviousDeltaVec<I, T>
where
I: VecIndex,
T: VecValue,
{
type I = I;
type T = T;
}
impl<I, T> LazyPreviousDeltaVec<I, T>
where
I: VecIndex,
T: VecValue + CheckedSub + Default,
{
fn for_each_delta(&self, from: usize, to: usize, mut each: impl FnMut(T)) {
let to = to.min(self.len());
if from >= to {
return;
}
let read_from = from.saturating_sub(1);
let values = self.source.collect_range_dyn(read_from, to);
let mut values = values.into_iter();
let mut previous = if from == 0 {
T::default()
} else {
values.next().unwrap()
};
for current in values {
each(current.clone().checked_sub(previous).unwrap_or_default());
previous = current;
}
}
}
impl<I, T> ReadableVec<I, T> for LazyPreviousDeltaVec<I, T>
where
I: VecIndex,
T: VecValue + CheckedSub + Default,
{
fn read_into_at(&self, from: usize, to: usize, buf: &mut Vec<T>) {
buf.reserve(to.saturating_sub(from));
self.for_each_delta(from, to, |value| buf.push(value));
}
fn for_each_range_dyn_at(&self, from: usize, to: usize, f: &mut dyn FnMut(T)) {
self.for_each_delta(from, to, f);
}
fn fold_range_at<B, F: FnMut(B, T) -> B>(&self, from: usize, to: usize, init: B, f: F) -> B {
let mut values = Vec::with_capacity(to.saturating_sub(from));
self.read_into_at(from, to, &mut values);
values.into_iter().fold(init, f)
}
fn try_fold_range_at<B, E, F: FnMut(B, T) -> Result<B, E>>(
&self,
from: usize,
to: usize,
init: B,
f: F,
) -> Result<B, E> {
let mut values = Vec::with_capacity(to.saturating_sub(from));
self.read_into_at(from, to, &mut values);
values.into_iter().try_fold(init, f)
}
fn collect_one_at(&self, index: usize) -> Option<T> {
let current = self.source.collect_one_at(index)?;
let previous = index
.checked_sub(1)
.and_then(|index| self.source.collect_one_at(index))
.unwrap_or_default();
Some(current.checked_sub(previous).unwrap_or_default())
}
fn read_sorted_into_at(&self, indices: &[usize], out: &mut Vec<T>) {
out.reserve(indices.len());
indices
.iter()
.filter_map(|&index| self.collect_one_at(index))
.for_each(|value| out.push(value));
}
}
impl<I, T> Traversable for LazyPreviousDeltaVec<I, T>
where
I: VecIndex,
T: VecValue + CheckedSub + Default + Formattable + Serialize + JsonSchema,
{
fn iter_any_exportable(&self) -> impl Iterator<Item = &dyn AnyExportableVec> {
std::iter::once(self as &dyn AnyExportableVec)
}
fn to_tree_node(&self) -> TreeNode {
make_leaf::<I, T, _>(self)
}
}
@@ -80,8 +80,8 @@ impl PercentCumulativeRolling<PartsPerMillion32> {
#[inline]
pub(crate) fn compute_count_ratio(
&mut self,
numerator: &PerBlockCumulativeRolling<StoredU64, StoredU64>,
denominator: &PerBlockCumulativeRolling<StoredU64, StoredU64>,
numerator: &PerBlockCumulativeRolling<StoredU64>,
denominator: &PerBlockCumulativeRolling<StoredU64>,
starting_height: Height,
exit: &Exit,
) -> Result<()> {
@@ -64,6 +64,17 @@ impl BinaryTransform<StoredU32, Sats, Sats> for MaskSats {
}
}
impl BinaryTransform<StoredU64, Sats, Sats> for MaskSats {
#[inline]
fn apply(mask: StoredU64, value: Sats) -> Sats {
if u64::from(mask) != 0 {
value
} else {
Sats::ZERO
}
}
}
pub struct ReturnF32Tenths<const V: u16>;
impl<S, const V: u16> UnaryTransform<S, StoredF32> for ReturnF32Tenths<V> {
@@ -94,10 +94,9 @@ where
}
}
impl<T, C> WithAddrTypes<PerBlockCumulativeRolling<T, C>>
impl<T> WithAddrTypes<PerBlockCumulativeRolling<T>>
where
T: NumericValue + JsonSchema + Into<C>,
C: NumericValue + JsonSchema,
T: NumericValue + JsonSchema,
{
pub(crate) fn forced_import(
db: &Database,
@@ -123,26 +122,26 @@ where
pub(crate) fn min_stateful_len(&self) -> usize {
self.by_addr_type
.values()
.map(|v| v.block.len())
.map(|v| v.cumulative.height.len())
.min()
.unwrap()
.min(self.all.block.len())
.min(self.all.cumulative.height.len())
}
pub(crate) fn par_iter_height_mut(
&mut self,
) -> impl ParallelIterator<Item = &mut dyn AnyStoredVec> {
rayon::iter::once(&mut self.all.block as &mut dyn AnyStoredVec).chain(
rayon::iter::once(&mut self.all.cumulative.height as &mut dyn AnyStoredVec).chain(
self.by_addr_type
.par_values_mut()
.map(|v| &mut v.block as &mut dyn AnyStoredVec),
.map(|v| &mut v.cumulative.height as &mut dyn AnyStoredVec),
)
}
pub(crate) fn reset_height(&mut self) -> Result<()> {
self.all.block.reset()?;
self.all.cumulative.height.reset()?;
for v in self.by_addr_type.values_mut() {
v.block.reset()?;
v.cumulative.height.reset()?;
}
Ok(())
}
@@ -152,20 +151,11 @@ where
where
U: Into<T>,
{
self.all.block.push(total.into());
self.all.push_block(total.into());
for (v, value) in self.by_addr_type.values_mut().zip(per_type) {
v.block.push(value.into());
v.push_block(value.into());
}
}
/// Finalize `cumulative` / `sum` / `average` for `all` and every per-type vec.
pub(crate) fn compute_rest(&mut self, max_from: Height, exit: &Exit) -> Result<()> {
self.all.compute_rest(max_from, exit)?;
for v in self.by_addr_type.values_mut() {
v.compute_rest(max_from, exit)?;
}
Ok(())
}
}
impl WithAddrTypes<ValuePerBlock> {
+1 -2
View File
@@ -150,7 +150,6 @@ impl Vecs {
self.write()?;
}
self.compute_cumulative(starting_lengths.height, exit)?;
let block_size = &blocks.size.size.cumulative.height;
compute_data_share(
starting_lengths.height,
@@ -226,7 +225,7 @@ impl Vecs {
fn compute_fee_share(
max_from: Height,
target: &mut PercentCumulativeRolling<PartsPerMillion32>,
numerator: &PerBlockCumulativeRolling<Sats, Sats>,
numerator: &PerBlockCumulativeRolling<Sats>,
denominator: &ValuePerBlockCumulativeRolling,
exit: &Exit,
) -> Result<()> {
+22 -51
View File
@@ -2,7 +2,7 @@ use brk_error::Result;
use brk_traversable::Traversable;
use brk_types::{Height, PartsPerMillion32, Sats, StoredU64, VSize, Version};
use derive_more::{Deref, DerefMut};
use vecdb::{AnyStoredVec, AnyVec, Database, Exit, Rw, StorageMode, WritableVec};
use vecdb::{AnyVec, Database, Rw, StorageMode};
use super::ByKind;
use crate::{
@@ -13,7 +13,7 @@ use crate::{
},
};
pub type Series<T, M = Rw> = PerBlockCumulativeRolling<T, T, M>;
pub type Series<T, M = Rw> = PerBlockCumulativeRolling<T, M>;
#[derive(Clone, Copy, Default)]
pub(super) struct Totals {
@@ -84,43 +84,33 @@ impl TotalMetrics {
}
pub(super) fn push(&mut self, block: Totals) {
self.data_bytes.block.push(block.data_bytes.into());
self.tx_count.block.push(block.tx_count.into());
self.tx_vsize.block.push(block.tx_vsize);
self.fees.block.push(block.fees);
self.data_bytes.push_block(block.data_bytes.into());
self.tx_count.push_block(block.tx_count.into());
self.tx_vsize.push_block(block.tx_vsize);
self.fees.push_block(block.fees);
}
fn validate_and_truncate(&mut self, version: Version, height: Height) -> Result<()> {
self.data_bytes
.block
.validate_and_truncate(version, height)?;
self.tx_count.block.validate_and_truncate(version, height)?;
self.tx_vsize.block.validate_and_truncate(version, height)?;
self.fees.block.validate_and_truncate(version, height)?;
self.data_bytes.validate_and_truncate(version, height)?;
self.tx_count.validate_and_truncate(version, height)?;
self.tx_vsize.validate_and_truncate(version, height)?;
self.fees.validate_and_truncate(version, height)?;
Ok(())
}
fn truncate_if_needed_at(&mut self, len: usize) -> Result<()> {
self.data_bytes.block.truncate_if_needed_at(len)?;
self.tx_count.block.truncate_if_needed_at(len)?;
self.tx_vsize.block.truncate_if_needed_at(len)?;
self.fees.block.truncate_if_needed_at(len)?;
self.data_bytes.truncate_if_needed_at(len)?;
self.tx_count.truncate_if_needed_at(len)?;
self.tx_vsize.truncate_if_needed_at(len)?;
self.fees.truncate_if_needed_at(len)?;
Ok(())
}
fn write(&mut self) -> Result<()> {
self.data_bytes.block.write()?;
self.tx_count.block.write()?;
self.tx_vsize.block.write()?;
self.fees.block.write()?;
Ok(())
}
fn compute_cumulative(&mut self, max_from: Height, exit: &Exit) -> Result<()> {
self.data_bytes.compute_rest(max_from, exit)?;
self.tx_count.compute_rest(max_from, exit)?;
self.tx_vsize.compute_rest(max_from, exit)?;
self.fees.compute_rest(max_from, exit)?;
self.data_bytes.write()?;
self.tx_count.write()?;
self.tx_vsize.write()?;
self.fees.write()?;
Ok(())
}
}
@@ -194,35 +184,27 @@ impl Metrics {
}
pub(super) fn push(&mut self, block: Totals) {
self.output_count.block.push(block.output_count.into());
self.output_count.push_block(block.output_count.into());
self.total.push(block);
}
fn validate_and_truncate(&mut self, version: Version, height: Height) -> Result<()> {
self.output_count
.block
.validate_and_truncate(version, height)?;
self.output_count.validate_and_truncate(version, height)?;
self.total.validate_and_truncate(version, height)?;
Ok(())
}
fn truncate_if_needed_at(&mut self, len: usize) -> Result<()> {
self.output_count.block.truncate_if_needed_at(len)?;
self.output_count.truncate_if_needed_at(len)?;
self.total.truncate_if_needed_at(len)?;
Ok(())
}
fn write(&mut self) -> Result<()> {
self.output_count.block.write()?;
self.output_count.write()?;
self.total.write()?;
Ok(())
}
fn compute_cumulative(&mut self, max_from: Height, exit: &Exit) -> Result<()> {
self.output_count.compute_rest(max_from, exit)?;
self.total.compute_cumulative(max_from, exit)?;
Ok(())
}
}
#[derive(Deref, DerefMut, Traversable)]
@@ -377,15 +359,4 @@ impl Vecs {
}
Ok(())
}
pub(crate) fn compute_cumulative(&mut self, max_from: Height, exit: &Exit) -> Result<()> {
self.total.compute_cumulative(max_from, exit)?;
for metrics in self.by_kind.iter_mut() {
metrics.compute_cumulative(max_from, exit)?;
}
for metrics in self.policy.iter_mut() {
metrics.compute_cumulative(max_from, exit)?;
}
Ok(())
}
}
@@ -1,7 +1,7 @@
use brk_error::{OptionData, Result};
use brk_indexer::Indexer;
use brk_types::{OutputType, StoredU64};
use vecdb::{AnyStoredVec, AnyVec, Exit, ReadableVec, VecIndex, WritableVec};
use vecdb::{AnyVec, Exit, ReadableVec, VecIndex};
use super::{Vecs, WithOutputTypes};
use crate::internal::{CoinbasePolicy, PerBlockCumulativeRolling, walk_blocks};
@@ -20,7 +20,6 @@ impl Vecs {
self.output_count
.validate_and_truncate(dep_version, starting_lengths.height)?;
self.spendable_output_count
.block
.validate_and_truncate(dep_version, starting_lengths.height)?;
self.tx_count
.validate_and_truncate(dep_version, starting_lengths.height)?;
@@ -35,9 +34,7 @@ impl Vecs {
let end = first_tx_index.len();
if skip < end {
self.output_count.truncate_if_needed_at(skip)?;
self.spendable_output_count
.block
.truncate_if_needed_at(skip)?;
self.spendable_output_count.truncate_if_needed_at(skip)?;
self.tx_count.truncate_if_needed_at(skip)?;
let fi_batch = first_tx_index.collect_range_at(skip, end);
@@ -77,14 +74,13 @@ impl Vecs {
let spendable_total =
agg.entries_all - agg.entries_per_type[OutputType::OpReturn as usize];
self.spendable_output_count
.block
.push(StoredU64::from(spendable_total));
.push_block(StoredU64::from(spendable_total));
height += 1;
if height.is_multiple_of(WRITE_INTERVAL) {
let _lock = exit.lock();
self.output_count.write()?;
self.spendable_output_count.block.write()?;
self.spendable_output_count.write()?;
self.tx_count.write()?;
}
Ok(())
@@ -94,17 +90,11 @@ impl Vecs {
{
let _lock = exit.lock();
self.output_count.write()?;
self.spendable_output_count.block.write()?;
self.spendable_output_count.write()?;
self.tx_count.write()?;
}
}
self.output_count
.compute_rest(starting_lengths.height, exit)?;
self.spendable_output_count
.compute_rest(starting_lengths.height, exit)?;
self.tx_count.compute_rest(starting_lengths.height, exit)?;
for (otype, source) in self.output_count.by_type.iter_typed() {
self.output_share.get_mut(otype).compute_count_ratio(
source,
@@ -128,12 +118,12 @@ impl Vecs {
#[inline]
fn push_block(
metric: &mut WithOutputTypes<PerBlockCumulativeRolling<StoredU64, StoredU64>>,
metric: &mut WithOutputTypes<PerBlockCumulativeRolling<StoredU64>>,
total: u64,
per_type: &[u64; 12],
) {
metric.all.block.push(StoredU64::from(total));
metric.all.push_block(StoredU64::from(total));
for (otype, vec) in metric.by_type.iter_typed_mut() {
vec.block.push(StoredU64::from(per_type[otype as usize]));
vec.push_block(StoredU64::from(per_type[otype as usize]));
}
}
@@ -17,7 +17,7 @@ impl Vecs {
cached_starts: &Windows<&WindowStartVec>,
) -> Result<Self> {
let output_count =
WithOutputTypes::<PerBlockCumulativeRolling<StoredU64, StoredU64>>::forced_import_with(
WithOutputTypes::<PerBlockCumulativeRolling<StoredU64>>::forced_import_with(
db,
"output_count_bis",
|t| format!("{t}_output_count"),
@@ -25,15 +25,14 @@ impl Vecs {
indexes,
cached_starts,
)?;
let tx_count =
WithOutputTypes::<PerBlockCumulativeRolling<StoredU64, StoredU64>>::forced_import_with(
db,
"tx_count_bis",
|t| format!("tx_count_with_{t}_output"),
version,
indexes,
cached_starts,
)?;
let tx_count = WithOutputTypes::<PerBlockCumulativeRolling<StoredU64>>::forced_import_with(
db,
"tx_count_bis",
|t| format!("tx_count_with_{t}_output"),
version,
indexes,
cached_starts,
)?;
let spendable_output_count = PerBlockCumulativeRolling::forced_import(
db,
@@ -8,9 +8,9 @@ use crate::internal::{PerBlockCumulativeRolling, PercentCumulativeRolling};
#[derive(Traversable)]
pub struct Vecs<M: StorageMode = Rw> {
pub output_count: WithOutputTypes<PerBlockCumulativeRolling<StoredU64, StoredU64, M>>,
pub spendable_output_count: PerBlockCumulativeRolling<StoredU64, StoredU64, M>,
pub output_count: WithOutputTypes<PerBlockCumulativeRolling<StoredU64, M>>,
pub spendable_output_count: PerBlockCumulativeRolling<StoredU64, M>,
pub output_share: ByType<PercentCumulativeRolling<PartsPerMillion32, M>>,
pub tx_count: WithOutputTypes<PerBlockCumulativeRolling<StoredU64, StoredU64, M>>,
pub tx_count: WithOutputTypes<PerBlockCumulativeRolling<StoredU64, M>>,
pub tx_share: ByType<PercentCumulativeRolling<PartsPerMillion32, M>>,
}
@@ -7,7 +7,7 @@ use brk_error::Result;
use brk_traversable::Traversable;
use brk_types::{Height, Version};
use schemars::JsonSchema;
use vecdb::{AnyStoredVec, AnyVec, Database, Exit, WritableVec};
use vecdb::{AnyStoredVec, AnyVec, Database, WritableVec};
use crate::{
indexes,
@@ -23,10 +23,9 @@ pub struct WithOutputTypes<T> {
pub by_type: ByType<T>,
}
impl<T, C> WithOutputTypes<PerBlockCumulativeRolling<T, C>>
impl<T> WithOutputTypes<PerBlockCumulativeRolling<T>>
where
T: NumericValue + JsonSchema + Into<C>,
C: NumericValue + JsonSchema,
T: NumericValue + JsonSchema,
{
pub(crate) fn forced_import_with(
db: &Database,
@@ -48,16 +47,16 @@ where
pub(crate) fn min_stateful_len(&self) -> usize {
self.by_type
.iter()
.map(|v| v.block.len())
.map(|v| v.cumulative.height.len())
.min()
.unwrap()
.min(self.all.block.len())
.min(self.all.cumulative.height.len())
}
pub(crate) fn write(&mut self) -> Result<()> {
self.all.block.write()?;
self.all.cumulative.height.write()?;
for v in self.by_type.iter_mut() {
v.block.write()?;
v.cumulative.height.write()?;
}
Ok(())
}
@@ -68,26 +67,21 @@ where
at_height: Height,
) -> Result<()> {
self.all
.block
.cumulative
.height
.validate_and_truncate(dep_version, at_height)?;
for v in self.by_type.iter_mut() {
v.block.validate_and_truncate(dep_version, at_height)?;
v.cumulative
.height
.validate_and_truncate(dep_version, at_height)?;
}
Ok(())
}
pub(crate) fn truncate_if_needed_at(&mut self, len: usize) -> Result<()> {
self.all.block.truncate_if_needed_at(len)?;
self.all.cumulative.height.truncate_if_needed_at(len)?;
for v in self.by_type.iter_mut() {
v.block.truncate_if_needed_at(len)?;
}
Ok(())
}
pub(crate) fn compute_rest(&mut self, max_from: Height, exit: &Exit) -> Result<()> {
self.all.compute_rest(max_from, exit)?;
for v in self.by_type.iter_mut() {
v.compute_rest(max_from, exit)?;
v.cumulative.height.truncate_if_needed_at(len)?;
}
Ok(())
}
@@ -19,7 +19,7 @@ impl Vecs {
starting_lengths: &Lengths,
exit: &Exit,
) -> Result<()> {
let op_return: &PerBlockCumulativeRolling<StoredU64, StoredU64> =
let op_return: &PerBlockCumulativeRolling<StoredU64> =
&by_type.output_count.by_type.unspendable.op_return;
self.count.height.compute_transform3(
+6 -20
View File
@@ -1,7 +1,7 @@
use brk_error::Result;
use brk_indexer::Indexer;
use brk_traversable::Traversable;
use brk_types::{Height, PartsPerMillion32, PoolSlug, StoredU32, StoredU64};
use brk_types::{Height, PartsPerMillion32, PoolSlug, StoredU64};
use vecdb::{Database, Exit, ReadableVec, Rw, StorageMode, Version};
use crate::{
@@ -14,7 +14,7 @@ pub struct Vecs<M: StorageMode = Rw> {
#[traversable(skip)]
slug: PoolSlug,
pub blocks_mined: PerBlockCumulativeRolling<StoredU32, StoredU64, M>,
pub blocks_mined: PerBlockCumulativeRolling<StoredU64, M>,
pub dominance: PercentPerBlock<PartsPerMillion32, M>,
}
@@ -54,24 +54,10 @@ impl Vecs {
) -> Result<()> {
let starting_height = indexer.safe_lengths().height;
self.blocks_mined.compute(starting_height, exit, |vec| {
vec.compute_transform(
starting_height,
pool,
|(h, id, ..)| {
(
h,
if id == self.slug {
StoredU32::ONE
} else {
StoredU32::ZERO
},
)
},
exit,
)?;
Ok(())
})?;
self.blocks_mined
.cumulative
.height
.compute_cumulative_count(starting_height, pool, |id| *id == self.slug, exit)?;
self.dominance
.compute_binary::<StoredU64, StoredU64, RatioU64<PartsPerMillion32>>(
@@ -16,14 +16,7 @@ impl Vecs {
(&mut self.v3, &counts.v3),
(&mut self.other, &counts.other_version),
] {
metrics.compute(starting_height, exit, |block| {
Ok(block.compute_transform(
starting_height,
source,
|(height, count, ..)| (height, count),
exit,
)?)
})?;
metrics.compute_cumulative(starting_height, source, exit)?;
}
Ok(())
@@ -6,8 +6,8 @@ use crate::internal::PerBlockCumulativeRolling;
#[derive(Traversable)]
pub struct Vecs<M: StorageMode = Rw> {
pub v1: PerBlockCumulativeRolling<StoredU64, StoredU64, M>,
pub v2: PerBlockCumulativeRolling<StoredU64, StoredU64, M>,
pub v3: PerBlockCumulativeRolling<StoredU64, StoredU64, M>,
pub other: PerBlockCumulativeRolling<StoredU64, StoredU64, M>,
pub v1: PerBlockCumulativeRolling<StoredU64, M>,
pub v2: PerBlockCumulativeRolling<StoredU64, M>,
pub v3: PerBlockCumulativeRolling<StoredU64, M>,
pub other: PerBlockCumulativeRolling<StoredU64, M>,
}
+2 -2
View File
@@ -24,8 +24,8 @@ pub trait Traversable {
}
}
/// Helper to create a SeriesLeafWithSchema from a vec
fn make_leaf<I: VecIndex, T: JsonSchema, V: AnyVec>(vec: &V) -> TreeNode {
/// Creates a series leaf, including its value schema, from a vector.
pub fn make_leaf<I: VecIndex, T: JsonSchema, V: AnyVec>(vec: &V) -> TreeNode {
let index_str = I::to_string();
let index = Index::try_from(index_str).ok();
let indexes = index.into_iter().collect();
+68 -91
View File
@@ -3561,8 +3561,8 @@ function createActivityAddrOutputsRealizedSupplyUnrealizedPattern(client, acc) {
* @property {_1m1w1y24hPattern3} average
* @property {BtcCentsSatsUsdPattern3} block
* @property {BtcCentsSatsUsdPattern} cumulative
* @property {AverageBlockCumulativeSumPattern3} inLoss
* @property {AverageBlockCumulativeSumPattern3} inProfit
* @property {AverageBlockCumulativeSumPattern2} inLoss
* @property {AverageBlockCumulativeSumPattern2} inProfit
* @property {_1m1w1y24hPattern4} sum
*/
@@ -3577,8 +3577,8 @@ function createAverageBlockCumulativeInSumPattern(client, acc) {
average: create_1m1w1y24hPattern3(client, _m(acc, 'average')),
block: createBtcCentsSatsUsdPattern3(client, acc),
cumulative: createBtcCentsSatsUsdPattern(client, _m(acc, 'cumulative')),
inLoss: createAverageBlockCumulativeSumPattern3(client, _m(acc, 'in_loss')),
inProfit: createAverageBlockCumulativeSumPattern3(client, _m(acc, 'in_profit')),
inLoss: createAverageBlockCumulativeSumPattern2(client, _m(acc, 'in_loss')),
inProfit: createAverageBlockCumulativeSumPattern2(client, _m(acc, 'in_profit')),
sum: create_1m1w1y24hPattern4(client, _m(acc, 'sum')),
};
}
@@ -4220,10 +4220,10 @@ function create_1m1w1y24hPattern8(client, acc) {
/**
* @typedef {Object} AverageBlockCumulativeSumPattern2
* @property {_1m1w1y24hPattern<StoredF32>} average
* @property {SeriesPattern18<StoredU32>} block
* @property {SeriesPattern1<StoredU64>} cumulative
* @property {_1m1w1y24hPattern<StoredU64>} sum
* @property {_1m1w1y24hPattern3} average
* @property {BtcCentsSatsUsdPattern3} block
* @property {BtcCentsSatsUsdPattern} cumulative
* @property {_1m1w1y24hPattern4} sum
*/
/**
@@ -4233,29 +4233,6 @@ function create_1m1w1y24hPattern8(client, acc) {
* @returns {AverageBlockCumulativeSumPattern2}
*/
function createAverageBlockCumulativeSumPattern2(client, acc) {
return {
average: create_1m1w1y24hPattern(client, _m(acc, 'average')),
block: createSeriesPattern18(client, acc),
cumulative: createSeriesPattern1(client, _m(acc, 'cumulative')),
sum: create_1m1w1y24hPattern(client, _m(acc, 'sum')),
};
}
/**
* @typedef {Object} AverageBlockCumulativeSumPattern3
* @property {_1m1w1y24hPattern3} average
* @property {BtcCentsSatsUsdPattern3} block
* @property {BtcCentsSatsUsdPattern} cumulative
* @property {_1m1w1y24hPattern4} sum
*/
/**
* Create a AverageBlockCumulativeSumPattern3 pattern node
* @param {BrkClient} client
* @param {string} acc - Accumulated series name
* @returns {AverageBlockCumulativeSumPattern3}
*/
function createAverageBlockCumulativeSumPattern3(client, acc) {
return {
average: create_1m1w1y24hPattern3(client, _m(acc, 'average')),
block: createBtcCentsSatsUsdPattern3(client, acc),
@@ -4611,9 +4588,9 @@ function createBlockCumulativeSumPattern(client, acc) {
/**
* @typedef {Object} BlocksDominanceRewardsPattern
* @property {AverageBlockCumulativeSumPattern2} blocksMined
* @property {AverageBlockCumulativeSumPattern<StoredU64>} blocksMined
* @property {_1m1w1y24hPercentPpmRatioPattern} dominance
* @property {AverageBlockCumulativeSumPattern3} rewards
* @property {AverageBlockCumulativeSumPattern2} rewards
*/
/**
@@ -4624,9 +4601,9 @@ function createBlockCumulativeSumPattern(client, acc) {
*/
function createBlocksDominanceRewardsPattern(client, acc) {
return {
blocksMined: createAverageBlockCumulativeSumPattern2(client, _m(acc, 'blocks_mined')),
blocksMined: createAverageBlockCumulativeSumPattern(client, _m(acc, 'blocks_mined')),
dominance: create_1m1w1y24hPercentPpmRatioPattern(client, _m(acc, 'dominance')),
rewards: createAverageBlockCumulativeSumPattern3(client, _m(acc, 'rewards')),
rewards: createAverageBlockCumulativeSumPattern2(client, _m(acc, 'rewards')),
};
}
@@ -4956,7 +4933,7 @@ function createRsiStochPattern(client, acc, disc) {
/**
* @typedef {Object} SpentUnspentUtxoPattern
* @property {AverageBlockCumulativeSumPattern2} spentCount
* @property {AverageBlockCumulativeSumPattern<StoredU64>} spentCount
* @property {BaseDeltaPattern} unspentCount
* @property {SeriesPattern1<StoredF32>} utxoTurnover1y
*/
@@ -4969,7 +4946,7 @@ function createRsiStochPattern(client, acc, disc) {
*/
function createSpentUnspentUtxoPattern(client, acc) {
return {
spentCount: createAverageBlockCumulativeSumPattern2(client, _m(acc, 'spent_utxo_count')),
spentCount: createAverageBlockCumulativeSumPattern(client, _m(acc, 'spent_utxo_count')),
unspentCount: createBaseDeltaPattern(client, _m(acc, 'utxo_count')),
utxoTurnover1y: createSeriesPattern1(client, _m(acc, 'utxo_turnover_1y')),
};
@@ -5191,7 +5168,7 @@ function createBlockCumulativePattern(client, acc) {
/**
* @typedef {Object} BlocksDominancePattern
* @property {AverageBlockCumulativeSumPattern2} blocksMined
* @property {AverageBlockCumulativeSumPattern<StoredU64>} blocksMined
* @property {PercentPpmRatioPattern2} dominance
*/
@@ -5203,7 +5180,7 @@ function createBlockCumulativePattern(client, acc) {
*/
function createBlocksDominancePattern(client, acc) {
return {
blocksMined: createAverageBlockCumulativeSumPattern2(client, _m(acc, 'blocks_mined')),
blocksMined: createAverageBlockCumulativeSumPattern(client, _m(acc, 'blocks_mined')),
dominance: createPercentPpmRatioPattern2(client, _m(acc, 'dominance')),
};
}
@@ -5658,7 +5635,7 @@ function createSupplyPattern(client, acc) {
/**
* @typedef {Object} TransferPattern
* @property {AverageBlockCumulativeSumPattern3} transferVolume
* @property {AverageBlockCumulativeSumPattern2} transferVolume
*/
/**
@@ -5669,7 +5646,7 @@ function createSupplyPattern(client, acc) {
*/
function createTransferPattern(client, acc) {
return {
transferVolume: createAverageBlockCumulativeSumPattern3(client, acc),
transferVolume: createAverageBlockCumulativeSumPattern2(client, acc),
};
}
@@ -5751,7 +5728,7 @@ function createTransferPattern(client, acc) {
/**
* @typedef {Object} SeriesTree_Blocks_Count
* @property {_1m1w1y24hPattern<StoredU64>} target
* @property {AverageBlockCumulativeSumPattern2} total
* @property {AverageBlockCumulativeSumPattern<StoredU64>} total
*/
/**
@@ -5982,7 +5959,7 @@ function createTransferPattern(client, acc) {
/**
* @typedef {Object} SeriesTree_Transactions_Volume
* @property {AverageBlockCumulativeSumPattern3} transferVolume
* @property {AverageBlockCumulativeSumPattern2} transferVolume
* @property {_1m1w1y24hPattern<StoredF32>} txPerSec
*/
@@ -6477,7 +6454,7 @@ function createTransferPattern(client, acc) {
/**
* @typedef {Object} SeriesTree_Mining_Rewards
* @property {AverageBlockCumulativeSumPattern3} coinbase
* @property {AverageBlockCumulativeSumPattern2} coinbase
* @property {SeriesTree_Mining_Rewards_Subsidy} subsidy
* @property {SeriesTree_Mining_Rewards_Fees} fees
* @property {SeriesPattern18<Sats>} outputVolume
@@ -7595,7 +7572,7 @@ function createTransferPattern(client, acc) {
/**
* @typedef {Object} SeriesTree_Cohorts_Utxo_All_Outputs
* @property {BaseDeltaPattern} unspentCount
* @property {AverageBlockCumulativeSumPattern2} spentCount
* @property {AverageBlockCumulativeSumPattern<StoredU64>} spentCount
* @property {SeriesPattern1<StoredF32>} utxoTurnover1y
*/
@@ -7946,27 +7923,27 @@ function createTransferPattern(client, acc) {
/**
* @typedef {Object} SeriesTree_Cohorts_Utxo_Matured
* @property {AverageBlockCumulativeSumPattern3} under1h
* @property {AverageBlockCumulativeSumPattern3} _1hTo1d
* @property {AverageBlockCumulativeSumPattern3} _1dTo1w
* @property {AverageBlockCumulativeSumPattern3} _1wTo1m
* @property {AverageBlockCumulativeSumPattern3} _1mTo2m
* @property {AverageBlockCumulativeSumPattern3} _2mTo3m
* @property {AverageBlockCumulativeSumPattern3} _3mTo4m
* @property {AverageBlockCumulativeSumPattern3} _4mTo5m
* @property {AverageBlockCumulativeSumPattern3} _5mTo6m
* @property {AverageBlockCumulativeSumPattern3} _6mTo1y
* @property {AverageBlockCumulativeSumPattern3} _1yTo2y
* @property {AverageBlockCumulativeSumPattern3} _2yTo3y
* @property {AverageBlockCumulativeSumPattern3} _3yTo4y
* @property {AverageBlockCumulativeSumPattern3} _4yTo5y
* @property {AverageBlockCumulativeSumPattern3} _5yTo6y
* @property {AverageBlockCumulativeSumPattern3} _6yTo7y
* @property {AverageBlockCumulativeSumPattern3} _7yTo8y
* @property {AverageBlockCumulativeSumPattern3} _8yTo10y
* @property {AverageBlockCumulativeSumPattern3} _10yTo12y
* @property {AverageBlockCumulativeSumPattern3} _12yTo15y
* @property {AverageBlockCumulativeSumPattern3} over15y
* @property {AverageBlockCumulativeSumPattern2} under1h
* @property {AverageBlockCumulativeSumPattern2} _1hTo1d
* @property {AverageBlockCumulativeSumPattern2} _1dTo1w
* @property {AverageBlockCumulativeSumPattern2} _1wTo1m
* @property {AverageBlockCumulativeSumPattern2} _1mTo2m
* @property {AverageBlockCumulativeSumPattern2} _2mTo3m
* @property {AverageBlockCumulativeSumPattern2} _3mTo4m
* @property {AverageBlockCumulativeSumPattern2} _4mTo5m
* @property {AverageBlockCumulativeSumPattern2} _5mTo6m
* @property {AverageBlockCumulativeSumPattern2} _6mTo1y
* @property {AverageBlockCumulativeSumPattern2} _1yTo2y
* @property {AverageBlockCumulativeSumPattern2} _2yTo3y
* @property {AverageBlockCumulativeSumPattern2} _3yTo4y
* @property {AverageBlockCumulativeSumPattern2} _4yTo5y
* @property {AverageBlockCumulativeSumPattern2} _5yTo6y
* @property {AverageBlockCumulativeSumPattern2} _6yTo7y
* @property {AverageBlockCumulativeSumPattern2} _7yTo8y
* @property {AverageBlockCumulativeSumPattern2} _8yTo10y
* @property {AverageBlockCumulativeSumPattern2} _10yTo12y
* @property {AverageBlockCumulativeSumPattern2} _12yTo15y
* @property {AverageBlockCumulativeSumPattern2} over15y
*/
/**
@@ -9296,7 +9273,7 @@ class BrkClient extends BrkClientBase {
segwitWeight: createSeriesPattern18(this, 'segwit_weight'),
count: {
target: create_1m1w1y24hPattern(this, 'block_count_target'),
total: createAverageBlockCumulativeSumPattern2(this, 'block_count'),
total: createAverageBlockCumulativeSumPattern(this, 'block_count'),
},
lookback: {
_1h: createSeriesPattern18(this, 'height_1h_ago'),
@@ -9476,7 +9453,7 @@ class BrkClient extends BrkClientBase {
other: createAverageBlockCumulativeSumPattern(this, 'tx_other_version'),
},
volume: {
transferVolume: createAverageBlockCumulativeSumPattern3(this, 'transfer_volume_bis'),
transferVolume: createAverageBlockCumulativeSumPattern2(this, 'transfer_volume_bis'),
txPerSec: create_1m1w1y24hPattern(this, 'tx_per_sec'),
},
},
@@ -9820,7 +9797,7 @@ class BrkClient extends BrkClientBase {
},
mining: {
rewards: {
coinbase: createAverageBlockCumulativeSumPattern3(this, 'coinbase'),
coinbase: createAverageBlockCumulativeSumPattern2(this, 'coinbase'),
subsidy: {
block: createBtcCentsSatsUsdPattern3(this, 'subsidy'),
cumulative: createBtcCentsSatsUsdPattern(this, 'subsidy_cumulative'),
@@ -10620,7 +10597,7 @@ class BrkClient extends BrkClientBase {
supply: createDeltaDominanceHalfInTotalPattern2(this, 'supply'),
outputs: {
unspentCount: createBaseDeltaPattern(this, 'utxo_count'),
spentCount: createAverageBlockCumulativeSumPattern2(this, 'spent_utxo_count'),
spentCount: createAverageBlockCumulativeSumPattern(this, 'spent_utxo_count'),
utxoTurnover1y: createSeriesPattern1(this, 'utxo_turnover_1y'),
},
activity: {
@@ -10913,27 +10890,27 @@ class BrkClient extends BrkClientBase {
},
},
matured: {
under1h: createAverageBlockCumulativeSumPattern3(this, 'utxos_under_1h_old_matured_supply'),
_1hTo1d: createAverageBlockCumulativeSumPattern3(this, 'utxos_1h_to_1d_old_matured_supply'),
_1dTo1w: createAverageBlockCumulativeSumPattern3(this, 'utxos_1d_to_1w_old_matured_supply'),
_1wTo1m: createAverageBlockCumulativeSumPattern3(this, 'utxos_1w_to_1m_old_matured_supply'),
_1mTo2m: createAverageBlockCumulativeSumPattern3(this, 'utxos_1m_to_2m_old_matured_supply'),
_2mTo3m: createAverageBlockCumulativeSumPattern3(this, 'utxos_2m_to_3m_old_matured_supply'),
_3mTo4m: createAverageBlockCumulativeSumPattern3(this, 'utxos_3m_to_4m_old_matured_supply'),
_4mTo5m: createAverageBlockCumulativeSumPattern3(this, 'utxos_4m_to_5m_old_matured_supply'),
_5mTo6m: createAverageBlockCumulativeSumPattern3(this, 'utxos_5m_to_6m_old_matured_supply'),
_6mTo1y: createAverageBlockCumulativeSumPattern3(this, 'utxos_6m_to_1y_old_matured_supply'),
_1yTo2y: createAverageBlockCumulativeSumPattern3(this, 'utxos_1y_to_2y_old_matured_supply'),
_2yTo3y: createAverageBlockCumulativeSumPattern3(this, 'utxos_2y_to_3y_old_matured_supply'),
_3yTo4y: createAverageBlockCumulativeSumPattern3(this, 'utxos_3y_to_4y_old_matured_supply'),
_4yTo5y: createAverageBlockCumulativeSumPattern3(this, 'utxos_4y_to_5y_old_matured_supply'),
_5yTo6y: createAverageBlockCumulativeSumPattern3(this, 'utxos_5y_to_6y_old_matured_supply'),
_6yTo7y: createAverageBlockCumulativeSumPattern3(this, 'utxos_6y_to_7y_old_matured_supply'),
_7yTo8y: createAverageBlockCumulativeSumPattern3(this, 'utxos_7y_to_8y_old_matured_supply'),
_8yTo10y: createAverageBlockCumulativeSumPattern3(this, 'utxos_8y_to_10y_old_matured_supply'),
_10yTo12y: createAverageBlockCumulativeSumPattern3(this, 'utxos_10y_to_12y_old_matured_supply'),
_12yTo15y: createAverageBlockCumulativeSumPattern3(this, 'utxos_12y_to_15y_old_matured_supply'),
over15y: createAverageBlockCumulativeSumPattern3(this, 'utxos_over_15y_old_matured_supply'),
under1h: createAverageBlockCumulativeSumPattern2(this, 'utxos_under_1h_old_matured_supply'),
_1hTo1d: createAverageBlockCumulativeSumPattern2(this, 'utxos_1h_to_1d_old_matured_supply'),
_1dTo1w: createAverageBlockCumulativeSumPattern2(this, 'utxos_1d_to_1w_old_matured_supply'),
_1wTo1m: createAverageBlockCumulativeSumPattern2(this, 'utxos_1w_to_1m_old_matured_supply'),
_1mTo2m: createAverageBlockCumulativeSumPattern2(this, 'utxos_1m_to_2m_old_matured_supply'),
_2mTo3m: createAverageBlockCumulativeSumPattern2(this, 'utxos_2m_to_3m_old_matured_supply'),
_3mTo4m: createAverageBlockCumulativeSumPattern2(this, 'utxos_3m_to_4m_old_matured_supply'),
_4mTo5m: createAverageBlockCumulativeSumPattern2(this, 'utxos_4m_to_5m_old_matured_supply'),
_5mTo6m: createAverageBlockCumulativeSumPattern2(this, 'utxos_5m_to_6m_old_matured_supply'),
_6mTo1y: createAverageBlockCumulativeSumPattern2(this, 'utxos_6m_to_1y_old_matured_supply'),
_1yTo2y: createAverageBlockCumulativeSumPattern2(this, 'utxos_1y_to_2y_old_matured_supply'),
_2yTo3y: createAverageBlockCumulativeSumPattern2(this, 'utxos_2y_to_3y_old_matured_supply'),
_3yTo4y: createAverageBlockCumulativeSumPattern2(this, 'utxos_3y_to_4y_old_matured_supply'),
_4yTo5y: createAverageBlockCumulativeSumPattern2(this, 'utxos_4y_to_5y_old_matured_supply'),
_5yTo6y: createAverageBlockCumulativeSumPattern2(this, 'utxos_5y_to_6y_old_matured_supply'),
_6yTo7y: createAverageBlockCumulativeSumPattern2(this, 'utxos_6y_to_7y_old_matured_supply'),
_7yTo8y: createAverageBlockCumulativeSumPattern2(this, 'utxos_7y_to_8y_old_matured_supply'),
_8yTo10y: createAverageBlockCumulativeSumPattern2(this, 'utxos_8y_to_10y_old_matured_supply'),
_10yTo12y: createAverageBlockCumulativeSumPattern2(this, 'utxos_10y_to_12y_old_matured_supply'),
_12yTo15y: createAverageBlockCumulativeSumPattern2(this, 'utxos_12y_to_15y_old_matured_supply'),
over15y: createAverageBlockCumulativeSumPattern2(this, 'utxos_over_15y_old_matured_supply'),
},
},
addr: {
+32 -42
View File
@@ -3491,8 +3491,8 @@ class AverageBlockCumulativeInSumPattern:
self.average: _1m1w1y24hPattern3 = _1m1w1y24hPattern3(client, _m(acc, 'average'))
self.block: BtcCentsSatsUsdPattern3 = BtcCentsSatsUsdPattern3(client, acc)
self.cumulative: BtcCentsSatsUsdPattern = BtcCentsSatsUsdPattern(client, _m(acc, 'cumulative'))
self.in_loss: AverageBlockCumulativeSumPattern3 = AverageBlockCumulativeSumPattern3(client, _m(acc, 'in_loss'))
self.in_profit: AverageBlockCumulativeSumPattern3 = AverageBlockCumulativeSumPattern3(client, _m(acc, 'in_profit'))
self.in_loss: AverageBlockCumulativeSumPattern2 = AverageBlockCumulativeSumPattern2(client, _m(acc, 'in_loss'))
self.in_profit: AverageBlockCumulativeSumPattern2 = AverageBlockCumulativeSumPattern2(client, _m(acc, 'in_profit'))
self.sum: _1m1w1y24hPattern4 = _1m1w1y24hPattern4(client, _m(acc, 'sum'))
class CentsNegativeToUsdPattern2:
@@ -3776,16 +3776,6 @@ class _1m1w1y24hPattern8:
class AverageBlockCumulativeSumPattern2:
"""Pattern struct for repeated tree structure."""
def __init__(self, client: BrkClient, acc: str):
"""Create pattern node with accumulated series name."""
self.average: _1m1w1y24hPattern[StoredF32] = _1m1w1y24hPattern(client, _m(acc, 'average'))
self.block: SeriesPattern18[StoredU32] = SeriesPattern18(client, acc)
self.cumulative: SeriesPattern1[StoredU64] = SeriesPattern1(client, _m(acc, 'cumulative'))
self.sum: _1m1w1y24hPattern[StoredU64] = _1m1w1y24hPattern(client, _m(acc, 'sum'))
class AverageBlockCumulativeSumPattern3:
"""Pattern struct for repeated tree structure."""
def __init__(self, client: BrkClient, acc: str):
"""Create pattern node with accumulated series name."""
self.average: _1m1w1y24hPattern3 = _1m1w1y24hPattern3(client, _m(acc, 'average'))
@@ -3946,9 +3936,9 @@ class BlocksDominanceRewardsPattern:
def __init__(self, client: BrkClient, acc: str):
"""Create pattern node with accumulated series name."""
self.blocks_mined: AverageBlockCumulativeSumPattern2 = AverageBlockCumulativeSumPattern2(client, _m(acc, 'blocks_mined'))
self.blocks_mined: AverageBlockCumulativeSumPattern[StoredU64] = AverageBlockCumulativeSumPattern(client, _m(acc, 'blocks_mined'))
self.dominance: _1m1w1y24hPercentPpmRatioPattern = _1m1w1y24hPercentPpmRatioPattern(client, _m(acc, 'dominance'))
self.rewards: AverageBlockCumulativeSumPattern3 = AverageBlockCumulativeSumPattern3(client, _m(acc, 'rewards'))
self.rewards: AverageBlockCumulativeSumPattern2 = AverageBlockCumulativeSumPattern2(client, _m(acc, 'rewards'))
class CentsSatsUsdPattern3:
"""Pattern struct for repeated tree structure."""
@@ -4094,7 +4084,7 @@ class SpentUnspentUtxoPattern:
def __init__(self, client: BrkClient, acc: str):
"""Create pattern node with accumulated series name."""
self.spent_count: AverageBlockCumulativeSumPattern2 = AverageBlockCumulativeSumPattern2(client, _m(acc, 'spent_utxo_count'))
self.spent_count: AverageBlockCumulativeSumPattern[StoredU64] = AverageBlockCumulativeSumPattern(client, _m(acc, 'spent_utxo_count'))
self.unspent_count: BaseDeltaPattern = BaseDeltaPattern(client, _m(acc, 'utxo_count'))
self.utxo_turnover_1y: SeriesPattern1[StoredF32] = SeriesPattern1(client, _m(acc, 'utxo_turnover_1y'))
@@ -4192,7 +4182,7 @@ class BlocksDominancePattern:
def __init__(self, client: BrkClient, acc: str):
"""Create pattern node with accumulated series name."""
self.blocks_mined: AverageBlockCumulativeSumPattern2 = AverageBlockCumulativeSumPattern2(client, _m(acc, 'blocks_mined'))
self.blocks_mined: AverageBlockCumulativeSumPattern[StoredU64] = AverageBlockCumulativeSumPattern(client, _m(acc, 'blocks_mined'))
self.dominance: PercentPpmRatioPattern2 = PercentPpmRatioPattern2(client, _m(acc, 'dominance'))
class BtcSatsPattern:
@@ -4389,7 +4379,7 @@ class TransferPattern:
def __init__(self, client: BrkClient, acc: str):
"""Create pattern node with accumulated series name."""
self.transfer_volume: AverageBlockCumulativeSumPattern3 = AverageBlockCumulativeSumPattern3(client, acc)
self.transfer_volume: AverageBlockCumulativeSumPattern2 = AverageBlockCumulativeSumPattern2(client, acc)
# Series tree classes
@@ -4431,7 +4421,7 @@ class SeriesTree_Blocks_Count:
def __init__(self, client: BrkClient, base_path: str = ''):
self.target: _1m1w1y24hPattern[StoredU64] = _1m1w1y24hPattern(client, 'block_count_target')
self.total: AverageBlockCumulativeSumPattern2 = AverageBlockCumulativeSumPattern2(client, 'block_count')
self.total: AverageBlockCumulativeSumPattern[StoredU64] = AverageBlockCumulativeSumPattern(client, 'block_count')
class SeriesTree_Blocks_Lookback:
"""Series tree node."""
@@ -4687,7 +4677,7 @@ class SeriesTree_Transactions_Volume:
"""Series tree node."""
def __init__(self, client: BrkClient, base_path: str = ''):
self.transfer_volume: AverageBlockCumulativeSumPattern3 = AverageBlockCumulativeSumPattern3(client, 'transfer_volume_bis')
self.transfer_volume: AverageBlockCumulativeSumPattern2 = AverageBlockCumulativeSumPattern2(client, 'transfer_volume_bis')
self.tx_per_sec: _1m1w1y24hPattern[StoredF32] = _1m1w1y24hPattern(client, 'tx_per_sec')
class SeriesTree_Transactions:
@@ -5278,7 +5268,7 @@ class SeriesTree_Mining_Rewards:
"""Series tree node."""
def __init__(self, client: BrkClient, base_path: str = ''):
self.coinbase: AverageBlockCumulativeSumPattern3 = AverageBlockCumulativeSumPattern3(client, 'coinbase')
self.coinbase: AverageBlockCumulativeSumPattern2 = AverageBlockCumulativeSumPattern2(client, 'coinbase')
self.subsidy: SeriesTree_Mining_Rewards_Subsidy = SeriesTree_Mining_Rewards_Subsidy(client)
self.fees: SeriesTree_Mining_Rewards_Fees = SeriesTree_Mining_Rewards_Fees(client)
self.output_volume: SeriesPattern18[Sats] = SeriesPattern18(client, 'output_volume')
@@ -6430,7 +6420,7 @@ class SeriesTree_Cohorts_Utxo_All_Outputs:
def __init__(self, client: BrkClient, base_path: str = ''):
self.unspent_count: BaseDeltaPattern = BaseDeltaPattern(client, 'utxo_count')
self.spent_count: AverageBlockCumulativeSumPattern2 = AverageBlockCumulativeSumPattern2(client, 'spent_utxo_count')
self.spent_count: AverageBlockCumulativeSumPattern[StoredU64] = AverageBlockCumulativeSumPattern(client, 'spent_utxo_count')
self.utxo_turnover_1y: SeriesPattern1[StoredF32] = SeriesPattern1(client, 'utxo_turnover_1y')
class SeriesTree_Cohorts_Utxo_All_Activity:
@@ -6819,27 +6809,27 @@ class SeriesTree_Cohorts_Utxo_Matured:
"""Series tree node."""
def __init__(self, client: BrkClient, base_path: str = ''):
self.under_1h: AverageBlockCumulativeSumPattern3 = AverageBlockCumulativeSumPattern3(client, 'utxos_under_1h_old_matured_supply')
self._1h_to_1d: AverageBlockCumulativeSumPattern3 = AverageBlockCumulativeSumPattern3(client, 'utxos_1h_to_1d_old_matured_supply')
self._1d_to_1w: AverageBlockCumulativeSumPattern3 = AverageBlockCumulativeSumPattern3(client, 'utxos_1d_to_1w_old_matured_supply')
self._1w_to_1m: AverageBlockCumulativeSumPattern3 = AverageBlockCumulativeSumPattern3(client, 'utxos_1w_to_1m_old_matured_supply')
self._1m_to_2m: AverageBlockCumulativeSumPattern3 = AverageBlockCumulativeSumPattern3(client, 'utxos_1m_to_2m_old_matured_supply')
self._2m_to_3m: AverageBlockCumulativeSumPattern3 = AverageBlockCumulativeSumPattern3(client, 'utxos_2m_to_3m_old_matured_supply')
self._3m_to_4m: AverageBlockCumulativeSumPattern3 = AverageBlockCumulativeSumPattern3(client, 'utxos_3m_to_4m_old_matured_supply')
self._4m_to_5m: AverageBlockCumulativeSumPattern3 = AverageBlockCumulativeSumPattern3(client, 'utxos_4m_to_5m_old_matured_supply')
self._5m_to_6m: AverageBlockCumulativeSumPattern3 = AverageBlockCumulativeSumPattern3(client, 'utxos_5m_to_6m_old_matured_supply')
self._6m_to_1y: AverageBlockCumulativeSumPattern3 = AverageBlockCumulativeSumPattern3(client, 'utxos_6m_to_1y_old_matured_supply')
self._1y_to_2y: AverageBlockCumulativeSumPattern3 = AverageBlockCumulativeSumPattern3(client, 'utxos_1y_to_2y_old_matured_supply')
self._2y_to_3y: AverageBlockCumulativeSumPattern3 = AverageBlockCumulativeSumPattern3(client, 'utxos_2y_to_3y_old_matured_supply')
self._3y_to_4y: AverageBlockCumulativeSumPattern3 = AverageBlockCumulativeSumPattern3(client, 'utxos_3y_to_4y_old_matured_supply')
self._4y_to_5y: AverageBlockCumulativeSumPattern3 = AverageBlockCumulativeSumPattern3(client, 'utxos_4y_to_5y_old_matured_supply')
self._5y_to_6y: AverageBlockCumulativeSumPattern3 = AverageBlockCumulativeSumPattern3(client, 'utxos_5y_to_6y_old_matured_supply')
self._6y_to_7y: AverageBlockCumulativeSumPattern3 = AverageBlockCumulativeSumPattern3(client, 'utxos_6y_to_7y_old_matured_supply')
self._7y_to_8y: AverageBlockCumulativeSumPattern3 = AverageBlockCumulativeSumPattern3(client, 'utxos_7y_to_8y_old_matured_supply')
self._8y_to_10y: AverageBlockCumulativeSumPattern3 = AverageBlockCumulativeSumPattern3(client, 'utxos_8y_to_10y_old_matured_supply')
self._10y_to_12y: AverageBlockCumulativeSumPattern3 = AverageBlockCumulativeSumPattern3(client, 'utxos_10y_to_12y_old_matured_supply')
self._12y_to_15y: AverageBlockCumulativeSumPattern3 = AverageBlockCumulativeSumPattern3(client, 'utxos_12y_to_15y_old_matured_supply')
self.over_15y: AverageBlockCumulativeSumPattern3 = AverageBlockCumulativeSumPattern3(client, 'utxos_over_15y_old_matured_supply')
self.under_1h: AverageBlockCumulativeSumPattern2 = AverageBlockCumulativeSumPattern2(client, 'utxos_under_1h_old_matured_supply')
self._1h_to_1d: AverageBlockCumulativeSumPattern2 = AverageBlockCumulativeSumPattern2(client, 'utxos_1h_to_1d_old_matured_supply')
self._1d_to_1w: AverageBlockCumulativeSumPattern2 = AverageBlockCumulativeSumPattern2(client, 'utxos_1d_to_1w_old_matured_supply')
self._1w_to_1m: AverageBlockCumulativeSumPattern2 = AverageBlockCumulativeSumPattern2(client, 'utxos_1w_to_1m_old_matured_supply')
self._1m_to_2m: AverageBlockCumulativeSumPattern2 = AverageBlockCumulativeSumPattern2(client, 'utxos_1m_to_2m_old_matured_supply')
self._2m_to_3m: AverageBlockCumulativeSumPattern2 = AverageBlockCumulativeSumPattern2(client, 'utxos_2m_to_3m_old_matured_supply')
self._3m_to_4m: AverageBlockCumulativeSumPattern2 = AverageBlockCumulativeSumPattern2(client, 'utxos_3m_to_4m_old_matured_supply')
self._4m_to_5m: AverageBlockCumulativeSumPattern2 = AverageBlockCumulativeSumPattern2(client, 'utxos_4m_to_5m_old_matured_supply')
self._5m_to_6m: AverageBlockCumulativeSumPattern2 = AverageBlockCumulativeSumPattern2(client, 'utxos_5m_to_6m_old_matured_supply')
self._6m_to_1y: AverageBlockCumulativeSumPattern2 = AverageBlockCumulativeSumPattern2(client, 'utxos_6m_to_1y_old_matured_supply')
self._1y_to_2y: AverageBlockCumulativeSumPattern2 = AverageBlockCumulativeSumPattern2(client, 'utxos_1y_to_2y_old_matured_supply')
self._2y_to_3y: AverageBlockCumulativeSumPattern2 = AverageBlockCumulativeSumPattern2(client, 'utxos_2y_to_3y_old_matured_supply')
self._3y_to_4y: AverageBlockCumulativeSumPattern2 = AverageBlockCumulativeSumPattern2(client, 'utxos_3y_to_4y_old_matured_supply')
self._4y_to_5y: AverageBlockCumulativeSumPattern2 = AverageBlockCumulativeSumPattern2(client, 'utxos_4y_to_5y_old_matured_supply')
self._5y_to_6y: AverageBlockCumulativeSumPattern2 = AverageBlockCumulativeSumPattern2(client, 'utxos_5y_to_6y_old_matured_supply')
self._6y_to_7y: AverageBlockCumulativeSumPattern2 = AverageBlockCumulativeSumPattern2(client, 'utxos_6y_to_7y_old_matured_supply')
self._7y_to_8y: AverageBlockCumulativeSumPattern2 = AverageBlockCumulativeSumPattern2(client, 'utxos_7y_to_8y_old_matured_supply')
self._8y_to_10y: AverageBlockCumulativeSumPattern2 = AverageBlockCumulativeSumPattern2(client, 'utxos_8y_to_10y_old_matured_supply')
self._10y_to_12y: AverageBlockCumulativeSumPattern2 = AverageBlockCumulativeSumPattern2(client, 'utxos_10y_to_12y_old_matured_supply')
self._12y_to_15y: AverageBlockCumulativeSumPattern2 = AverageBlockCumulativeSumPattern2(client, 'utxos_12y_to_15y_old_matured_supply')
self.over_15y: AverageBlockCumulativeSumPattern2 = AverageBlockCumulativeSumPattern2(client, 'utxos_over_15y_old_matured_supply')
class SeriesTree_Cohorts_Utxo:
"""Series tree node."""