mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-07-30 12:18:11 -07:00
global: MASSIVE snapshot
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
use brk_error::Result;
|
||||
use brk_indexer::Indexer;
|
||||
use vecdb::Exit;
|
||||
|
||||
use super::Vecs;
|
||||
use crate::{ComputeIndexes, blocks, indexes, transactions};
|
||||
|
||||
impl Vecs {
|
||||
pub(crate) fn compute(
|
||||
&mut self,
|
||||
indexer: &Indexer,
|
||||
indexes: &indexes::Vecs,
|
||||
blocks: &blocks::Vecs,
|
||||
transactions: &transactions::Vecs,
|
||||
starting_indexes: &ComputeIndexes,
|
||||
exit: &Exit,
|
||||
) -> Result<()> {
|
||||
// Block rewards (coinbase, subsidy, fee_dominance, etc.)
|
||||
self.rewards.compute(
|
||||
indexer,
|
||||
indexes,
|
||||
&blocks.count,
|
||||
&transactions.fees,
|
||||
starting_indexes,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
// Hashrate metrics (uses rewards.coinbase_24h_sum — disjoint field borrow)
|
||||
self.hashrate.compute(
|
||||
&blocks.count,
|
||||
&blocks.difficulty,
|
||||
&self.rewards.coinbase_24h_sum,
|
||||
starting_indexes,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
let _lock = exit.lock();
|
||||
self.db.compact()?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,173 @@
|
||||
use brk_error::Result;
|
||||
use brk_types::{StoredF32, StoredF64};
|
||||
use vecdb::Exit;
|
||||
|
||||
use super::Vecs;
|
||||
use crate::{
|
||||
blocks::{self, ONE_TERA_HASH, TARGET_BLOCKS_PER_DAY_F64},
|
||||
internal::StoredValueFromHeightLast,
|
||||
ComputeIndexes,
|
||||
traits::ComputeDrawdown,
|
||||
};
|
||||
|
||||
impl Vecs {
|
||||
pub(crate) fn compute(
|
||||
&mut self,
|
||||
count_vecs: &blocks::CountVecs,
|
||||
difficulty_vecs: &blocks::DifficultyVecs,
|
||||
coinbase_sum_24h: &StoredValueFromHeightLast,
|
||||
starting_indexes: &ComputeIndexes,
|
||||
exit: &Exit,
|
||||
) -> Result<()> {
|
||||
self.hash_rate.height.compute_transform2(
|
||||
starting_indexes.height,
|
||||
&count_vecs.block_count_24h_sum.height,
|
||||
&difficulty_vecs.as_hash.height,
|
||||
|(i, block_count_sum, difficulty_as_hash, ..)| {
|
||||
(
|
||||
i,
|
||||
StoredF64::from(
|
||||
(f64::from(block_count_sum) / TARGET_BLOCKS_PER_DAY_F64)
|
||||
* f64::from(difficulty_as_hash),
|
||||
),
|
||||
)
|
||||
},
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.hash_rate_1w_sma.height.compute_rolling_average(
|
||||
starting_indexes.height,
|
||||
&count_vecs.height_1w_ago,
|
||||
&self.hash_rate.height,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.hash_rate_1m_sma.height.compute_rolling_average(
|
||||
starting_indexes.height,
|
||||
&count_vecs.height_1m_ago,
|
||||
&self.hash_rate.height,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.hash_rate_2m_sma.height.compute_rolling_average(
|
||||
starting_indexes.height,
|
||||
&count_vecs.height_2m_ago,
|
||||
&self.hash_rate.height,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.hash_rate_1y_sma.height.compute_rolling_average(
|
||||
starting_indexes.height,
|
||||
&count_vecs.height_1y_ago,
|
||||
&self.hash_rate.height,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.hash_rate_ath.height.compute_all_time_high(
|
||||
starting_indexes.height,
|
||||
&self.hash_rate.height,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.hash_rate_drawdown.height.compute_drawdown(
|
||||
starting_indexes.height,
|
||||
&self.hash_rate.height,
|
||||
&self.hash_rate_ath.height,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.hash_price_ths.height.compute_transform2(
|
||||
starting_indexes.height,
|
||||
&coinbase_sum_24h.usd.height,
|
||||
&self.hash_rate.height,
|
||||
|(i, coinbase_sum, hashrate, ..)| {
|
||||
let hashrate_ths = *hashrate / ONE_TERA_HASH;
|
||||
let price = if hashrate_ths == 0.0 {
|
||||
StoredF32::NAN
|
||||
} else {
|
||||
(*coinbase_sum / hashrate_ths).into()
|
||||
};
|
||||
(i, price)
|
||||
},
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.hash_price_phs.height.compute_transform(
|
||||
starting_indexes.height,
|
||||
&self.hash_price_ths.height,
|
||||
|(i, price, ..)| (i, (*price * 1000.0).into()),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.hash_value_ths.height.compute_transform2(
|
||||
starting_indexes.height,
|
||||
&coinbase_sum_24h.sats.height,
|
||||
&self.hash_rate.height,
|
||||
|(i, coinbase_sum, hashrate, ..)| {
|
||||
let hashrate_ths = *hashrate / ONE_TERA_HASH;
|
||||
let value = if hashrate_ths == 0.0 {
|
||||
StoredF32::NAN
|
||||
} else {
|
||||
StoredF32::from(*coinbase_sum as f64 / hashrate_ths)
|
||||
};
|
||||
(i, value)
|
||||
},
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.hash_value_phs.height.compute_transform(
|
||||
starting_indexes.height,
|
||||
&self.hash_value_ths.height,
|
||||
|(i, value, ..)| (i, (*value * 1000.0).into()),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.hash_price_ths_min.height.compute_all_time_low_(
|
||||
starting_indexes.height,
|
||||
&self.hash_price_ths.height,
|
||||
exit,
|
||||
true,
|
||||
)?;
|
||||
|
||||
self.hash_price_phs_min.height.compute_all_time_low_(
|
||||
starting_indexes.height,
|
||||
&self.hash_price_phs.height,
|
||||
exit,
|
||||
true,
|
||||
)?;
|
||||
|
||||
self.hash_value_ths_min.height.compute_all_time_low_(
|
||||
starting_indexes.height,
|
||||
&self.hash_value_ths.height,
|
||||
exit,
|
||||
true,
|
||||
)?;
|
||||
|
||||
self.hash_value_phs_min.height.compute_all_time_low_(
|
||||
starting_indexes.height,
|
||||
&self.hash_value_phs.height,
|
||||
exit,
|
||||
true,
|
||||
)?;
|
||||
|
||||
self.hash_price_rebound
|
||||
.height
|
||||
.compute_percentage_difference(
|
||||
starting_indexes.height,
|
||||
&self.hash_price_phs.height,
|
||||
&self.hash_price_phs_min.height,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.hash_value_rebound
|
||||
.height
|
||||
.compute_percentage_difference(
|
||||
starting_indexes.height,
|
||||
&self.hash_value_phs.height,
|
||||
&self.hash_value_phs_min.height,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
use brk_error::Result;
|
||||
use brk_types::Version;
|
||||
use vecdb::Database;
|
||||
|
||||
use super::Vecs;
|
||||
use crate::{
|
||||
indexes,
|
||||
internal::ComputedFromHeightLast,
|
||||
};
|
||||
|
||||
impl Vecs {
|
||||
pub(crate) fn forced_import(
|
||||
db: &Database,
|
||||
version: Version,
|
||||
indexes: &indexes::Vecs,
|
||||
) -> Result<Self> {
|
||||
let v4 = Version::new(4);
|
||||
let v5 = Version::new(5);
|
||||
|
||||
Ok(Self {
|
||||
hash_rate: ComputedFromHeightLast::forced_import(db, "hash_rate", version + v5, indexes)?,
|
||||
hash_rate_1w_sma: ComputedFromHeightLast::forced_import(
|
||||
db,
|
||||
"hash_rate_1w_sma",
|
||||
version,
|
||||
indexes,
|
||||
)?,
|
||||
hash_rate_1m_sma: ComputedFromHeightLast::forced_import(
|
||||
db,
|
||||
"hash_rate_1m_sma",
|
||||
version,
|
||||
indexes,
|
||||
)?,
|
||||
hash_rate_2m_sma: ComputedFromHeightLast::forced_import(
|
||||
db,
|
||||
"hash_rate_2m_sma",
|
||||
version,
|
||||
indexes,
|
||||
)?,
|
||||
hash_rate_1y_sma: ComputedFromHeightLast::forced_import(
|
||||
db,
|
||||
"hash_rate_1y_sma",
|
||||
version,
|
||||
indexes,
|
||||
)?,
|
||||
hash_rate_ath: ComputedFromHeightLast::forced_import(
|
||||
db,
|
||||
"hash_rate_ath",
|
||||
version,
|
||||
indexes,
|
||||
)?,
|
||||
hash_rate_drawdown: ComputedFromHeightLast::forced_import(
|
||||
db,
|
||||
"hash_rate_drawdown",
|
||||
version,
|
||||
indexes,
|
||||
)?,
|
||||
hash_price_ths: ComputedFromHeightLast::forced_import(
|
||||
db,
|
||||
"hash_price_ths",
|
||||
version + v4,
|
||||
indexes,
|
||||
)?,
|
||||
hash_price_ths_min: ComputedFromHeightLast::forced_import(
|
||||
db,
|
||||
"hash_price_ths_min",
|
||||
version + v4,
|
||||
indexes,
|
||||
)?,
|
||||
hash_price_phs: ComputedFromHeightLast::forced_import(
|
||||
db,
|
||||
"hash_price_phs",
|
||||
version + v4,
|
||||
indexes,
|
||||
)?,
|
||||
hash_price_phs_min: ComputedFromHeightLast::forced_import(
|
||||
db,
|
||||
"hash_price_phs_min",
|
||||
version + v4,
|
||||
indexes,
|
||||
)?,
|
||||
hash_price_rebound: ComputedFromHeightLast::forced_import(
|
||||
db,
|
||||
"hash_price_rebound",
|
||||
version + v4,
|
||||
indexes,
|
||||
)?,
|
||||
hash_value_ths: ComputedFromHeightLast::forced_import(
|
||||
db,
|
||||
"hash_value_ths",
|
||||
version + v4,
|
||||
indexes,
|
||||
)?,
|
||||
hash_value_ths_min: ComputedFromHeightLast::forced_import(
|
||||
db,
|
||||
"hash_value_ths_min",
|
||||
version + v4,
|
||||
indexes,
|
||||
)?,
|
||||
hash_value_phs: ComputedFromHeightLast::forced_import(
|
||||
db,
|
||||
"hash_value_phs",
|
||||
version + v4,
|
||||
indexes,
|
||||
)?,
|
||||
hash_value_phs_min: ComputedFromHeightLast::forced_import(
|
||||
db,
|
||||
"hash_value_phs_min",
|
||||
version + v4,
|
||||
indexes,
|
||||
)?,
|
||||
hash_value_rebound: ComputedFromHeightLast::forced_import(
|
||||
db,
|
||||
"hash_value_rebound",
|
||||
version + v4,
|
||||
indexes,
|
||||
)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
mod compute;
|
||||
mod import;
|
||||
mod vecs;
|
||||
|
||||
pub use vecs::Vecs;
|
||||
@@ -0,0 +1,27 @@
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::{StoredF32, StoredF64};
|
||||
use vecdb::{Rw, StorageMode};
|
||||
|
||||
use crate::internal::ComputedFromHeightLast;
|
||||
|
||||
/// Mining-related metrics: hash rate, hash price, hash value
|
||||
#[derive(Traversable)]
|
||||
pub struct Vecs<M: StorageMode = Rw> {
|
||||
pub hash_rate: ComputedFromHeightLast<StoredF64, M>,
|
||||
pub hash_rate_1w_sma: ComputedFromHeightLast<StoredF64, M>,
|
||||
pub hash_rate_1m_sma: ComputedFromHeightLast<StoredF32, M>,
|
||||
pub hash_rate_2m_sma: ComputedFromHeightLast<StoredF32, M>,
|
||||
pub hash_rate_1y_sma: ComputedFromHeightLast<StoredF32, M>,
|
||||
pub hash_rate_ath: ComputedFromHeightLast<StoredF64, M>,
|
||||
pub hash_rate_drawdown: ComputedFromHeightLast<StoredF32, M>,
|
||||
pub hash_price_ths: ComputedFromHeightLast<StoredF32, M>,
|
||||
pub hash_price_ths_min: ComputedFromHeightLast<StoredF32, M>,
|
||||
pub hash_price_phs: ComputedFromHeightLast<StoredF32, M>,
|
||||
pub hash_price_phs_min: ComputedFromHeightLast<StoredF32, M>,
|
||||
pub hash_price_rebound: ComputedFromHeightLast<StoredF32, M>,
|
||||
pub hash_value_ths: ComputedFromHeightLast<StoredF32, M>,
|
||||
pub hash_value_ths_min: ComputedFromHeightLast<StoredF32, M>,
|
||||
pub hash_value_phs: ComputedFromHeightLast<StoredF32, M>,
|
||||
pub hash_value_phs_min: ComputedFromHeightLast<StoredF32, M>,
|
||||
pub hash_value_rebound: ComputedFromHeightLast<StoredF32, M>,
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
use std::path::Path;
|
||||
|
||||
use brk_error::Result;
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::Version;
|
||||
use vecdb::{Database, PAGE_SIZE};
|
||||
|
||||
use crate::{indexes, prices};
|
||||
|
||||
use super::{HashrateVecs, RewardsVecs, Vecs};
|
||||
|
||||
impl Vecs {
|
||||
pub(crate) fn forced_import(
|
||||
parent_path: &Path,
|
||||
parent_version: Version,
|
||||
indexes: &indexes::Vecs,
|
||||
prices: &prices::Vecs,
|
||||
) -> Result<Self> {
|
||||
let db = Database::open(&parent_path.join(super::DB_NAME))?;
|
||||
db.set_min_len(PAGE_SIZE * 50_000_000)?;
|
||||
|
||||
let version = parent_version;
|
||||
|
||||
let rewards = RewardsVecs::forced_import(&db, version, indexes, prices)?;
|
||||
let hashrate = HashrateVecs::forced_import(&db, version, indexes)?;
|
||||
|
||||
let this = Self {
|
||||
db,
|
||||
rewards,
|
||||
hashrate,
|
||||
};
|
||||
|
||||
this.db.retain_regions(
|
||||
this.iter_any_exportable()
|
||||
.flat_map(|v| v.region_names())
|
||||
.collect(),
|
||||
)?;
|
||||
this.db.compact()?;
|
||||
|
||||
Ok(this)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
pub mod hashrate;
|
||||
pub mod rewards;
|
||||
|
||||
mod compute;
|
||||
mod import;
|
||||
|
||||
use brk_traversable::Traversable;
|
||||
use vecdb::{Database, Rw, StorageMode};
|
||||
|
||||
pub use hashrate::Vecs as HashrateVecs;
|
||||
pub use rewards::Vecs as RewardsVecs;
|
||||
|
||||
pub const DB_NAME: &str = "mining";
|
||||
|
||||
#[derive(Traversable)]
|
||||
pub struct Vecs<M: StorageMode = Rw> {
|
||||
#[traversable(skip)]
|
||||
pub(crate) db: Database,
|
||||
|
||||
pub rewards: RewardsVecs<M>,
|
||||
pub hashrate: HashrateVecs<M>,
|
||||
}
|
||||
@@ -0,0 +1,223 @@
|
||||
use brk_error::Result;
|
||||
use brk_indexer::Indexer;
|
||||
use brk_types::{CheckedSub, HalvingEpoch, Sats, StoredF32};
|
||||
use vecdb::{Exit, ReadableVec, VecIndex};
|
||||
|
||||
use super::Vecs;
|
||||
use crate::{ComputeIndexes, blocks, indexes, transactions};
|
||||
|
||||
impl Vecs {
|
||||
pub(crate) fn compute(
|
||||
&mut self,
|
||||
indexer: &Indexer,
|
||||
indexes: &indexes::Vecs,
|
||||
count_vecs: &blocks::CountVecs,
|
||||
transactions_fees: &transactions::FeesVecs,
|
||||
starting_indexes: &ComputeIndexes,
|
||||
exit: &Exit,
|
||||
) -> Result<()> {
|
||||
self.coinbase.compute(starting_indexes, exit, |vec| {
|
||||
// Cursors avoid per-height PcoVec page decompression for the
|
||||
// tx-indexed lookups. Coinbase txindex values are strictly
|
||||
// increasing, so the cursors only advance forward.
|
||||
let mut txout_cursor = indexer.vecs.transactions.first_txoutindex.cursor();
|
||||
let mut count_cursor = indexes.txindex.output_count.cursor();
|
||||
|
||||
vec.compute_transform(
|
||||
starting_indexes.height,
|
||||
&indexer.vecs.transactions.first_txindex,
|
||||
|(height, txindex, ..)| {
|
||||
let ti = txindex.to_usize();
|
||||
|
||||
txout_cursor.advance(ti - txout_cursor.position());
|
||||
let first_txoutindex = txout_cursor.next().unwrap().to_usize();
|
||||
|
||||
count_cursor.advance(ti - count_cursor.position());
|
||||
let output_count: usize = count_cursor.next().unwrap().into();
|
||||
|
||||
let sats = indexer.vecs.outputs.value.fold_range_at(
|
||||
first_txoutindex,
|
||||
first_txoutindex + output_count,
|
||||
Sats::ZERO,
|
||||
|acc, v| acc + v,
|
||||
);
|
||||
(height, sats)
|
||||
},
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
self.coinbase_24h_sum.compute_rolling_sum(
|
||||
starting_indexes.height,
|
||||
&count_vecs.height_24h_ago,
|
||||
&self.coinbase.sats.height,
|
||||
&self.coinbase.usd.height,
|
||||
exit,
|
||||
)?;
|
||||
self.coinbase_7d_sum.compute_rolling_sum(
|
||||
starting_indexes.height,
|
||||
&count_vecs.height_1w_ago,
|
||||
&self.coinbase.sats.height,
|
||||
&self.coinbase.usd.height,
|
||||
exit,
|
||||
)?;
|
||||
self.coinbase_30d_sum.compute_rolling_sum(
|
||||
starting_indexes.height,
|
||||
&count_vecs.height_1m_ago,
|
||||
&self.coinbase.sats.height,
|
||||
&self.coinbase.usd.height,
|
||||
exit,
|
||||
)?;
|
||||
self.coinbase_1y_sum.compute_rolling_sum(
|
||||
starting_indexes.height,
|
||||
&count_vecs.height_1y_ago,
|
||||
&self.coinbase.sats.height,
|
||||
&self.coinbase.usd.height,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
let fee_sats_source = transactions_fees.fee.sats.height.sum_cum.sum.inner();
|
||||
let fee_usd_source = &transactions_fees.fee.usd.height.sum;
|
||||
self.fee_24h_sum.compute_rolling_sum(
|
||||
starting_indexes.height,
|
||||
&count_vecs.height_24h_ago,
|
||||
fee_sats_source,
|
||||
fee_usd_source,
|
||||
exit,
|
||||
)?;
|
||||
self.fee_7d_sum.compute_rolling_sum(
|
||||
starting_indexes.height,
|
||||
&count_vecs.height_1w_ago,
|
||||
fee_sats_source,
|
||||
fee_usd_source,
|
||||
exit,
|
||||
)?;
|
||||
self.fee_30d_sum.compute_rolling_sum(
|
||||
starting_indexes.height,
|
||||
&count_vecs.height_1m_ago,
|
||||
fee_sats_source,
|
||||
fee_usd_source,
|
||||
exit,
|
||||
)?;
|
||||
self.fee_1y_sum.compute_rolling_sum(
|
||||
starting_indexes.height,
|
||||
&count_vecs.height_1y_ago,
|
||||
fee_sats_source,
|
||||
fee_usd_source,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.subsidy.compute(starting_indexes, exit, |vec| {
|
||||
vec.compute_transform2(
|
||||
starting_indexes.height,
|
||||
&self.coinbase.sats.height,
|
||||
transactions_fees.fee.sats.height.sum_cum.sum.inner(),
|
||||
|(height, coinbase, fees, ..)| {
|
||||
(
|
||||
height,
|
||||
coinbase.checked_sub(fees).unwrap_or_else(|| {
|
||||
dbg!(height, coinbase, fees);
|
||||
panic!()
|
||||
}),
|
||||
)
|
||||
},
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
self.unclaimed_rewards
|
||||
.compute(starting_indexes, exit, |vec| {
|
||||
vec.compute_transform(
|
||||
starting_indexes.height,
|
||||
&self.subsidy.sats.height,
|
||||
|(height, subsidy, ..)| {
|
||||
let halving = HalvingEpoch::from(height);
|
||||
let expected = Sats::FIFTY_BTC / 2_usize.pow(halving.to_usize() as u32);
|
||||
(height, expected.checked_sub(subsidy).unwrap())
|
||||
},
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
// All-time cumulative fee dominance
|
||||
self.fee_dominance.height.compute_percentage(
|
||||
starting_indexes.height,
|
||||
transactions_fees.fee.sats.height.sum_cum.cumulative.inner(),
|
||||
self.coinbase.sats.rest.height_cumulative.inner(),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
// Rolling fee dominance = sum(fees) / sum(coinbase) * 100
|
||||
self.fee_dominance_24h.height.compute_percentage(
|
||||
starting_indexes.height,
|
||||
&self.fee_24h_sum.sats.height,
|
||||
&self.coinbase_24h_sum.sats.height,
|
||||
exit,
|
||||
)?;
|
||||
self.fee_dominance_7d.height.compute_percentage(
|
||||
starting_indexes.height,
|
||||
&self.fee_7d_sum.sats.height,
|
||||
&self.coinbase_7d_sum.sats.height,
|
||||
exit,
|
||||
)?;
|
||||
self.fee_dominance_30d.height.compute_percentage(
|
||||
starting_indexes.height,
|
||||
&self.fee_30d_sum.sats.height,
|
||||
&self.coinbase_30d_sum.sats.height,
|
||||
exit,
|
||||
)?;
|
||||
self.fee_dominance_1y.height.compute_percentage(
|
||||
starting_indexes.height,
|
||||
&self.fee_1y_sum.sats.height,
|
||||
&self.coinbase_1y_sum.sats.height,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
// All-time cumulative subsidy dominance
|
||||
self.subsidy_dominance.height.compute_percentage(
|
||||
starting_indexes.height,
|
||||
self.subsidy.sats.rest.height_cumulative.inner(),
|
||||
self.coinbase.sats.rest.height_cumulative.inner(),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
// Rolling subsidy dominance = 100 - fee_dominance
|
||||
let hundred = StoredF32::from(100u8);
|
||||
self.subsidy_dominance_24h.height.compute_transform(
|
||||
starting_indexes.height,
|
||||
&self.fee_dominance_24h.height,
|
||||
|(height, fee_dom, _)| (height, hundred - fee_dom),
|
||||
exit,
|
||||
)?;
|
||||
self.subsidy_dominance_7d.height.compute_transform(
|
||||
starting_indexes.height,
|
||||
&self.fee_dominance_7d.height,
|
||||
|(height, fee_dom, _)| (height, hundred - fee_dom),
|
||||
exit,
|
||||
)?;
|
||||
self.subsidy_dominance_30d.height.compute_transform(
|
||||
starting_indexes.height,
|
||||
&self.fee_dominance_30d.height,
|
||||
|(height, fee_dom, _)| (height, hundred - fee_dom),
|
||||
exit,
|
||||
)?;
|
||||
self.subsidy_dominance_1y.height.compute_transform(
|
||||
starting_indexes.height,
|
||||
&self.fee_dominance_1y.height,
|
||||
|(height, fee_dom, _)| (height, hundred - fee_dom),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.subsidy_usd_1y_sma.height.compute_rolling_average(
|
||||
starting_indexes.height,
|
||||
&count_vecs.height_1y_ago,
|
||||
&self.coinbase.usd.height,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
use brk_error::Result;
|
||||
use brk_types::Version;
|
||||
use vecdb::Database;
|
||||
|
||||
use super::Vecs;
|
||||
use crate::{
|
||||
indexes,
|
||||
internal::{ComputedFromHeightLast, StoredValueFromHeightLast, ValueFromHeightFull, ValueFromHeightSumCum},
|
||||
prices,
|
||||
};
|
||||
|
||||
impl Vecs {
|
||||
pub(crate) fn forced_import(
|
||||
db: &Database,
|
||||
version: Version,
|
||||
indexes: &indexes::Vecs,
|
||||
prices: &prices::Vecs,
|
||||
) -> Result<Self> {
|
||||
Ok(Self {
|
||||
coinbase_24h_sum: StoredValueFromHeightLast::forced_import(db, "coinbase_24h_sum", version, indexes)?,
|
||||
coinbase_7d_sum: StoredValueFromHeightLast::forced_import(db, "coinbase_7d_sum", version, indexes)?,
|
||||
coinbase_30d_sum: StoredValueFromHeightLast::forced_import(db, "coinbase_30d_sum", version, indexes)?,
|
||||
coinbase_1y_sum: StoredValueFromHeightLast::forced_import(db, "coinbase_1y_sum", version, indexes)?,
|
||||
fee_24h_sum: StoredValueFromHeightLast::forced_import(db, "fee_24h_sum", version, indexes)?,
|
||||
fee_7d_sum: StoredValueFromHeightLast::forced_import(db, "fee_7d_sum", version, indexes)?,
|
||||
fee_30d_sum: StoredValueFromHeightLast::forced_import(db, "fee_30d_sum", version, indexes)?,
|
||||
fee_1y_sum: StoredValueFromHeightLast::forced_import(db, "fee_1y_sum", version, indexes)?,
|
||||
coinbase: ValueFromHeightFull::forced_import(db, "coinbase", version, indexes, prices)?,
|
||||
subsidy: ValueFromHeightFull::forced_import(db, "subsidy", version, indexes, prices)?,
|
||||
unclaimed_rewards: ValueFromHeightSumCum::forced_import(
|
||||
db,
|
||||
"unclaimed_rewards",
|
||||
version,
|
||||
indexes,
|
||||
prices,
|
||||
)?,
|
||||
fee_dominance: ComputedFromHeightLast::forced_import(
|
||||
db,
|
||||
"fee_dominance",
|
||||
version,
|
||||
indexes,
|
||||
)?,
|
||||
fee_dominance_24h: ComputedFromHeightLast::forced_import(
|
||||
db,
|
||||
"fee_dominance_24h",
|
||||
version,
|
||||
indexes,
|
||||
)?,
|
||||
fee_dominance_7d: ComputedFromHeightLast::forced_import(
|
||||
db,
|
||||
"fee_dominance_7d",
|
||||
version,
|
||||
indexes,
|
||||
)?,
|
||||
fee_dominance_30d: ComputedFromHeightLast::forced_import(
|
||||
db,
|
||||
"fee_dominance_30d",
|
||||
version,
|
||||
indexes,
|
||||
)?,
|
||||
fee_dominance_1y: ComputedFromHeightLast::forced_import(
|
||||
db,
|
||||
"fee_dominance_1y",
|
||||
version,
|
||||
indexes,
|
||||
)?,
|
||||
subsidy_dominance: ComputedFromHeightLast::forced_import(
|
||||
db,
|
||||
"subsidy_dominance",
|
||||
version,
|
||||
indexes,
|
||||
)?,
|
||||
subsidy_dominance_24h: ComputedFromHeightLast::forced_import(
|
||||
db,
|
||||
"subsidy_dominance_24h",
|
||||
version,
|
||||
indexes,
|
||||
)?,
|
||||
subsidy_dominance_7d: ComputedFromHeightLast::forced_import(
|
||||
db,
|
||||
"subsidy_dominance_7d",
|
||||
version,
|
||||
indexes,
|
||||
)?,
|
||||
subsidy_dominance_30d: ComputedFromHeightLast::forced_import(
|
||||
db,
|
||||
"subsidy_dominance_30d",
|
||||
version,
|
||||
indexes,
|
||||
)?,
|
||||
subsidy_dominance_1y: ComputedFromHeightLast::forced_import(
|
||||
db,
|
||||
"subsidy_dominance_1y",
|
||||
version,
|
||||
indexes,
|
||||
)?,
|
||||
subsidy_usd_1y_sma: ComputedFromHeightLast::forced_import(
|
||||
db,
|
||||
"subsidy_usd_1y_sma",
|
||||
version,
|
||||
indexes,
|
||||
)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
mod compute;
|
||||
mod import;
|
||||
mod vecs;
|
||||
|
||||
pub use vecs::Vecs;
|
||||
@@ -0,0 +1,32 @@
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::{Dollars, StoredF32};
|
||||
use vecdb::{Rw, StorageMode};
|
||||
|
||||
use crate::internal::{ComputedFromHeightLast, StoredValueFromHeightLast, ValueFromHeightFull, ValueFromHeightSumCum};
|
||||
|
||||
/// Coinbase/subsidy/rewards metrics
|
||||
#[derive(Traversable)]
|
||||
pub struct Vecs<M: StorageMode = Rw> {
|
||||
pub coinbase_24h_sum: StoredValueFromHeightLast<M>,
|
||||
pub coinbase_7d_sum: StoredValueFromHeightLast<M>,
|
||||
pub coinbase_30d_sum: StoredValueFromHeightLast<M>,
|
||||
pub coinbase_1y_sum: StoredValueFromHeightLast<M>,
|
||||
pub fee_24h_sum: StoredValueFromHeightLast<M>,
|
||||
pub fee_7d_sum: StoredValueFromHeightLast<M>,
|
||||
pub fee_30d_sum: StoredValueFromHeightLast<M>,
|
||||
pub fee_1y_sum: StoredValueFromHeightLast<M>,
|
||||
pub coinbase: ValueFromHeightFull<M>,
|
||||
pub subsidy: ValueFromHeightFull<M>,
|
||||
pub unclaimed_rewards: ValueFromHeightSumCum<M>,
|
||||
pub fee_dominance: ComputedFromHeightLast<StoredF32, M>,
|
||||
pub fee_dominance_24h: ComputedFromHeightLast<StoredF32, M>,
|
||||
pub fee_dominance_7d: ComputedFromHeightLast<StoredF32, M>,
|
||||
pub fee_dominance_30d: ComputedFromHeightLast<StoredF32, M>,
|
||||
pub fee_dominance_1y: ComputedFromHeightLast<StoredF32, M>,
|
||||
pub subsidy_dominance: ComputedFromHeightLast<StoredF32, M>,
|
||||
pub subsidy_dominance_24h: ComputedFromHeightLast<StoredF32, M>,
|
||||
pub subsidy_dominance_7d: ComputedFromHeightLast<StoredF32, M>,
|
||||
pub subsidy_dominance_30d: ComputedFromHeightLast<StoredF32, M>,
|
||||
pub subsidy_dominance_1y: ComputedFromHeightLast<StoredF32, M>,
|
||||
pub subsidy_usd_1y_sma: ComputedFromHeightLast<Dollars, M>,
|
||||
}
|
||||
Reference in New Issue
Block a user