mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-07-30 12:18:11 -07:00
computer: snapshot
This commit is contained in:
+1016
-1003
File diff suppressed because it is too large
Load Diff
@@ -67,8 +67,8 @@ pub(crate) fn process_blocks(
|
|||||||
|
|
||||||
// From transactions and inputs/outputs (via .height or .height.sum_cumulative.sum patterns):
|
// From transactions and inputs/outputs (via .height or .height.sum_cumulative.sum patterns):
|
||||||
let height_to_tx_count = &transactions.count.tx_count.height;
|
let height_to_tx_count = &transactions.count.tx_count.height;
|
||||||
let height_to_output_count = &outputs.count.total_count.height.sum_cumulative.sum.0;
|
let height_to_output_count = &outputs.count.total_count.full.sum_cumulative.sum.0;
|
||||||
let height_to_input_count = &inputs.count.height.sum_cumulative.sum.0;
|
let height_to_input_count = &inputs.count.full.sum_cumulative.sum.0;
|
||||||
// From blocks:
|
// From blocks:
|
||||||
let height_to_timestamp = &blocks.time.timestamp_monotonic;
|
let height_to_timestamp = &blocks.time.timestamp_monotonic;
|
||||||
let height_to_date = &blocks.time.date;
|
let height_to_date = &blocks.time.date;
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ use super::{CostBasisBase, CostBasisExtended};
|
|||||||
|
|
||||||
/// Cost basis metrics with guaranteed extended (no Option).
|
/// Cost basis metrics with guaranteed extended (no Option).
|
||||||
#[derive(Deref, DerefMut, Traversable)]
|
#[derive(Deref, DerefMut, Traversable)]
|
||||||
#[traversable(merge)]
|
|
||||||
pub struct CostBasisWithExtended<M: StorageMode = Rw> {
|
pub struct CostBasisWithExtended<M: StorageMode = Rw> {
|
||||||
#[deref]
|
#[deref]
|
||||||
#[deref_mut]
|
#[deref_mut]
|
||||||
@@ -31,5 +30,4 @@ impl CostBasisWithExtended {
|
|||||||
pub(crate) fn validate_computed_versions(&mut self, base_version: Version) -> Result<()> {
|
pub(crate) fn validate_computed_versions(&mut self, base_version: Version) -> Result<()> {
|
||||||
self.extended.validate_computed_versions(base_version)
|
self.extended.validate_computed_versions(base_version)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ use super::{RealizedAdjusted, RealizedBase};
|
|||||||
|
|
||||||
/// Realized metrics with guaranteed adjusted (no Option).
|
/// Realized metrics with guaranteed adjusted (no Option).
|
||||||
#[derive(Deref, DerefMut, Traversable)]
|
#[derive(Deref, DerefMut, Traversable)]
|
||||||
#[traversable(merge)]
|
|
||||||
pub struct RealizedWithAdjusted<M: StorageMode = Rw> {
|
pub struct RealizedWithAdjusted<M: StorageMode = Rw> {
|
||||||
#[deref]
|
#[deref]
|
||||||
#[deref_mut]
|
#[deref_mut]
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ use super::{RealizedBase, RealizedExtended};
|
|||||||
|
|
||||||
/// Realized metrics with guaranteed extended (no Option).
|
/// Realized metrics with guaranteed extended (no Option).
|
||||||
#[derive(Deref, DerefMut, Traversable)]
|
#[derive(Deref, DerefMut, Traversable)]
|
||||||
#[traversable(merge)]
|
|
||||||
pub struct RealizedWithExtended<M: StorageMode = Rw> {
|
pub struct RealizedWithExtended<M: StorageMode = Rw> {
|
||||||
#[deref]
|
#[deref]
|
||||||
#[deref_mut]
|
#[deref_mut]
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ use super::{RealizedAdjusted, RealizedBase, RealizedExtended};
|
|||||||
|
|
||||||
/// Realized metrics with guaranteed extended AND adjusted (no Options).
|
/// Realized metrics with guaranteed extended AND adjusted (no Options).
|
||||||
#[derive(Deref, DerefMut, Traversable)]
|
#[derive(Deref, DerefMut, Traversable)]
|
||||||
#[traversable(merge)]
|
|
||||||
pub struct RealizedWithExtendedAdjusted<M: StorageMode = Rw> {
|
pub struct RealizedWithExtendedAdjusted<M: StorageMode = Rw> {
|
||||||
#[deref]
|
#[deref]
|
||||||
#[deref_mut]
|
#[deref_mut]
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ use super::{RelativeBase, RelativeExtendedOwnPnl, RelativePeakRegret};
|
|||||||
|
|
||||||
/// Relative metrics for the "all" cohort (base + own_pnl + peak_regret, NO rel_to_all).
|
/// Relative metrics for the "all" cohort (base + own_pnl + peak_regret, NO rel_to_all).
|
||||||
#[derive(Deref, DerefMut, Traversable)]
|
#[derive(Deref, DerefMut, Traversable)]
|
||||||
#[traversable(merge)]
|
|
||||||
pub struct RelativeForAll<M: StorageMode = Rw> {
|
pub struct RelativeForAll<M: StorageMode = Rw> {
|
||||||
#[deref]
|
#[deref]
|
||||||
#[deref_mut]
|
#[deref_mut]
|
||||||
|
|||||||
@@ -7,14 +7,13 @@ use vecdb::{Exit, ReadableVec, Rw, StorageMode};
|
|||||||
use crate::distribution::metrics::{ImportConfig, RealizedBase, UnrealizedBase};
|
use crate::distribution::metrics::{ImportConfig, RealizedBase, UnrealizedBase};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
RelativeBase, RelativeExtendedOwnMarketCap, RelativeExtendedOwnPnl,
|
RelativeBase, RelativeExtendedOwnMarketCap, RelativeExtendedOwnPnl, RelativePeakRegret,
|
||||||
RelativePeakRegret, RelativeToAll,
|
RelativeToAll,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Full extended relative metrics (base + rel_to_all + own_market_cap + own_pnl + peak_regret).
|
/// Full extended relative metrics (base + rel_to_all + own_market_cap + own_pnl + peak_regret).
|
||||||
/// Used by: sth, lth, age_range cohorts.
|
/// Used by: sth, lth, age_range cohorts.
|
||||||
#[derive(Deref, DerefMut, Traversable)]
|
#[derive(Deref, DerefMut, Traversable)]
|
||||||
#[traversable(merge)]
|
|
||||||
pub struct RelativeWithExtended<M: StorageMode = Rw> {
|
pub struct RelativeWithExtended<M: StorageMode = Rw> {
|
||||||
#[deref]
|
#[deref]
|
||||||
#[deref_mut]
|
#[deref_mut]
|
||||||
@@ -54,11 +53,26 @@ impl RelativeWithExtended {
|
|||||||
peak_regret_val: &impl ReadableVec<Height, Dollars>,
|
peak_regret_val: &impl ReadableVec<Height, Dollars>,
|
||||||
exit: &Exit,
|
exit: &Exit,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
self.base.compute(max_from, unrealized, realized, supply_total_sats, market_cap, exit)?;
|
self.base.compute(
|
||||||
self.rel_to_all.compute(max_from, unrealized, supply_total_sats, all_supply_sats, exit)?;
|
max_from,
|
||||||
self.extended_own_market_cap.compute(max_from, unrealized, own_market_cap, exit)?;
|
unrealized,
|
||||||
|
realized,
|
||||||
|
supply_total_sats,
|
||||||
|
market_cap,
|
||||||
|
exit,
|
||||||
|
)?;
|
||||||
|
self.rel_to_all.compute(
|
||||||
|
max_from,
|
||||||
|
unrealized,
|
||||||
|
supply_total_sats,
|
||||||
|
all_supply_sats,
|
||||||
|
exit,
|
||||||
|
)?;
|
||||||
|
self.extended_own_market_cap
|
||||||
|
.compute(max_from, unrealized, own_market_cap, exit)?;
|
||||||
self.extended_own_pnl.compute(max_from, unrealized, exit)?;
|
self.extended_own_pnl.compute(max_from, unrealized, exit)?;
|
||||||
self.peak_regret.compute(max_from, peak_regret_val, market_cap, exit)?;
|
self.peak_regret
|
||||||
|
.compute(max_from, peak_regret_val, market_cap, exit)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ use super::{RelativeBase, RelativePeakRegret, RelativeToAll};
|
|||||||
/// Relative metrics with rel_to_all + peak_regret (no extended).
|
/// Relative metrics with rel_to_all + peak_regret (no extended).
|
||||||
/// Used by: max_age, min_age cohorts.
|
/// Used by: max_age, min_age cohorts.
|
||||||
#[derive(Deref, DerefMut, Traversable)]
|
#[derive(Deref, DerefMut, Traversable)]
|
||||||
#[traversable(merge)]
|
|
||||||
pub struct RelativeWithPeakRegret<M: StorageMode = Rw> {
|
pub struct RelativeWithPeakRegret<M: StorageMode = Rw> {
|
||||||
#[deref]
|
#[deref]
|
||||||
#[deref_mut]
|
#[deref_mut]
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ use super::{RelativeBase, RelativeToAll};
|
|||||||
/// Relative metrics with rel_to_all (no extended, no peak_regret).
|
/// Relative metrics with rel_to_all (no extended, no peak_regret).
|
||||||
/// Used by: epoch, year, type, amount, address cohorts.
|
/// Used by: epoch, year, type, amount, address cohorts.
|
||||||
#[derive(Deref, DerefMut, Traversable)]
|
#[derive(Deref, DerefMut, Traversable)]
|
||||||
#[traversable(merge)]
|
|
||||||
pub struct RelativeWithRelToAll<M: StorageMode = Rw> {
|
pub struct RelativeWithRelToAll<M: StorageMode = Rw> {
|
||||||
#[deref]
|
#[deref]
|
||||||
#[deref_mut]
|
#[deref_mut]
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ use super::{UnrealizedBase, UnrealizedPeakRegret};
|
|||||||
|
|
||||||
/// Unrealized metrics with guaranteed peak regret (no Option).
|
/// Unrealized metrics with guaranteed peak regret (no Option).
|
||||||
#[derive(Deref, DerefMut, Traversable)]
|
#[derive(Deref, DerefMut, Traversable)]
|
||||||
#[traversable(merge)]
|
|
||||||
pub struct UnrealizedWithPeakRegret<M: StorageMode = Rw> {
|
pub struct UnrealizedWithPeakRegret<M: StorageMode = Rw> {
|
||||||
#[deref]
|
#[deref]
|
||||||
#[deref_mut]
|
#[deref_mut]
|
||||||
@@ -26,5 +25,4 @@ impl UnrealizedWithPeakRegret {
|
|||||||
peak_regret_ext: UnrealizedPeakRegret::forced_import(cfg)?,
|
peak_regret_ext: UnrealizedPeakRegret::forced_import(cfg)?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,11 +5,9 @@
|
|||||||
use brk_traversable::Traversable;
|
use brk_traversable::Traversable;
|
||||||
|
|
||||||
#[derive(Clone, Traversable)]
|
#[derive(Clone, Traversable)]
|
||||||
#[traversable(merge)]
|
|
||||||
pub struct BlockWindows<A, B = A> {
|
pub struct BlockWindows<A, B = A> {
|
||||||
#[traversable(rename = "1h")]
|
#[traversable(rename = "1h")]
|
||||||
pub _1h: A,
|
pub _1h: A,
|
||||||
#[traversable(rename = "24h")]
|
#[traversable(rename = "24h")]
|
||||||
pub _24h: B,
|
pub _24h: B,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,6 @@
|
|||||||
use brk_traversable::Traversable;
|
use brk_traversable::Traversable;
|
||||||
|
|
||||||
#[derive(Clone, Traversable)]
|
#[derive(Clone, Traversable)]
|
||||||
#[traversable(merge)]
|
|
||||||
pub struct DistributionStats<A, B = A, C = A, D = A, E = A, F = A, G = A, H = A> {
|
pub struct DistributionStats<A, B = A, C = A, D = A, E = A, F = A, G = A, H = A> {
|
||||||
pub average: A,
|
pub average: A,
|
||||||
pub min: B,
|
pub min: B,
|
||||||
|
|||||||
@@ -16,13 +16,11 @@ use crate::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Traversable)]
|
#[derive(Traversable)]
|
||||||
#[traversable(merge)]
|
|
||||||
pub struct ComputedFromHeightCumulative<T, M: StorageMode = Rw>
|
pub struct ComputedFromHeightCumulative<T, M: StorageMode = Rw>
|
||||||
where
|
where
|
||||||
T: NumericValue + JsonSchema,
|
T: NumericValue + JsonSchema,
|
||||||
{
|
{
|
||||||
pub height: M::Stored<EagerVec<PcoVec<Height, T>>>,
|
pub height: M::Stored<EagerVec<PcoVec<Height, T>>>,
|
||||||
#[traversable(flatten)]
|
|
||||||
pub cumulative: ComputedFromHeightLast<T, M>,
|
pub cumulative: ComputedFromHeightLast<T, M>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,15 +17,12 @@ use crate::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Traversable)]
|
#[derive(Traversable)]
|
||||||
#[traversable(merge)]
|
|
||||||
pub struct ComputedFromHeightCumulativeFull<T, M: StorageMode = Rw>
|
pub struct ComputedFromHeightCumulativeFull<T, M: StorageMode = Rw>
|
||||||
where
|
where
|
||||||
T: NumericValue + JsonSchema,
|
T: NumericValue + JsonSchema,
|
||||||
{
|
{
|
||||||
pub height: M::Stored<EagerVec<PcoVec<Height, T>>>,
|
pub height: M::Stored<EagerVec<PcoVec<Height, T>>>,
|
||||||
#[traversable(flatten)]
|
|
||||||
pub cumulative: ComputedFromHeightLast<T, M>,
|
pub cumulative: ComputedFromHeightLast<T, M>,
|
||||||
#[traversable(flatten)]
|
|
||||||
pub rolling: RollingFull<T, M>,
|
pub rolling: RollingFull<T, M>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,15 +18,12 @@ use crate::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Traversable)]
|
#[derive(Traversable)]
|
||||||
#[traversable(merge)]
|
|
||||||
pub struct ComputedFromHeightCumulativeSum<T, M: StorageMode = Rw>
|
pub struct ComputedFromHeightCumulativeSum<T, M: StorageMode = Rw>
|
||||||
where
|
where
|
||||||
T: NumericValue + JsonSchema,
|
T: NumericValue + JsonSchema,
|
||||||
{
|
{
|
||||||
pub height: M::Stored<EagerVec<PcoVec<Height, T>>>,
|
pub height: M::Stored<EagerVec<PcoVec<Height, T>>>,
|
||||||
#[traversable(flatten)]
|
|
||||||
pub cumulative: ComputedFromHeightLast<T, M>,
|
pub cumulative: ComputedFromHeightLast<T, M>,
|
||||||
#[traversable(flatten)]
|
|
||||||
pub rolling: RollingWindows<T, M>,
|
pub rolling: RollingWindows<T, M>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ use crate::indexes;
|
|||||||
use crate::internal::{ComputedVecValue, NumericValue, RollingDistribution, WindowStarts};
|
use crate::internal::{ComputedVecValue, NumericValue, RollingDistribution, WindowStarts};
|
||||||
|
|
||||||
#[derive(Traversable)]
|
#[derive(Traversable)]
|
||||||
#[traversable(merge)]
|
|
||||||
pub struct ComputedFromHeightDistribution<T, M: StorageMode = Rw>
|
pub struct ComputedFromHeightDistribution<T, M: StorageMode = Rw>
|
||||||
where
|
where
|
||||||
T: ComputedVecValue + PartialOrd + JsonSchema,
|
T: ComputedVecValue + PartialOrd + JsonSchema,
|
||||||
|
|||||||
@@ -17,14 +17,12 @@ use crate::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Traversable)]
|
#[derive(Traversable)]
|
||||||
#[traversable(merge)]
|
|
||||||
pub struct ComputedFromHeightFull<T, M: StorageMode = Rw>
|
pub struct ComputedFromHeightFull<T, M: StorageMode = Rw>
|
||||||
where
|
where
|
||||||
T: NumericValue + JsonSchema,
|
T: NumericValue + JsonSchema,
|
||||||
{
|
{
|
||||||
#[traversable(flatten)]
|
#[traversable(flatten)]
|
||||||
pub height: Full<Height, T, M>,
|
pub full: Full<Height, T, M>,
|
||||||
#[traversable(flatten)]
|
|
||||||
pub rolling: RollingFull<T, M>,
|
pub rolling: RollingFull<T, M>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,7 +43,10 @@ where
|
|||||||
let height = Full::forced_import(db, name, v)?;
|
let height = Full::forced_import(db, name, v)?;
|
||||||
let rolling = RollingFull::forced_import(db, name, v, indexes)?;
|
let rolling = RollingFull::forced_import(db, name, v, indexes)?;
|
||||||
|
|
||||||
Ok(Self { height, rolling })
|
Ok(Self {
|
||||||
|
full: height,
|
||||||
|
rolling,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Compute Full stats via closure, then rolling windows from the per-block sum.
|
/// Compute Full stats via closure, then rolling windows from the per-block sum.
|
||||||
@@ -60,11 +61,11 @@ where
|
|||||||
T: From<f64> + Default + SubAssign + Copy + Ord,
|
T: From<f64> + Default + SubAssign + Copy + Ord,
|
||||||
f64: From<T>,
|
f64: From<T>,
|
||||||
{
|
{
|
||||||
compute_full(&mut self.height)?;
|
compute_full(&mut self.full)?;
|
||||||
self.rolling.compute(
|
self.rolling.compute(
|
||||||
max_from,
|
max_from,
|
||||||
windows,
|
windows,
|
||||||
self.height.sum_cumulative.sum.inner(),
|
self.full.sum_cumulative.sum.inner(),
|
||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ const VERSION: Version = Version::ZERO;
|
|||||||
|
|
||||||
/// Block full aggregation with lazy height transform + cumulative + rolling windows.
|
/// Block full aggregation with lazy height transform + cumulative + rolling windows.
|
||||||
#[derive(Deref, DerefMut, Traversable)]
|
#[derive(Deref, DerefMut, Traversable)]
|
||||||
#[traversable(merge)]
|
|
||||||
pub struct LazyComputedFromHeightFull<T, S = T, M: StorageMode = Rw>
|
pub struct LazyComputedFromHeightFull<T, S = T, M: StorageMode = Rw>
|
||||||
where
|
where
|
||||||
T: NumericValue + JsonSchema,
|
T: NumericValue + JsonSchema,
|
||||||
@@ -47,12 +46,7 @@ where
|
|||||||
|
|
||||||
let height = LazyVecFrom1::transformed::<F>(name, v, source.read_only_boxed_clone());
|
let height = LazyVecFrom1::transformed::<F>(name, v, source.read_only_boxed_clone());
|
||||||
|
|
||||||
let rest = ComputedHeightDerivedCumulativeFull::forced_import(
|
let rest = ComputedHeightDerivedCumulativeFull::forced_import(db, name, v, indexes)?;
|
||||||
db,
|
|
||||||
name,
|
|
||||||
v,
|
|
||||||
indexes,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
height,
|
height,
|
||||||
|
|||||||
@@ -17,9 +17,7 @@ use crate::{
|
|||||||
|
|
||||||
/// Generic price metric with both USD and sats representations.
|
/// Generic price metric with both USD and sats representations.
|
||||||
#[derive(Clone, Traversable)]
|
#[derive(Clone, Traversable)]
|
||||||
#[traversable(merge)]
|
|
||||||
pub struct Price<U> {
|
pub struct Price<U> {
|
||||||
#[traversable(flatten)]
|
|
||||||
pub usd: U,
|
pub usd: U,
|
||||||
pub sats: LazyFromHeightLast<SatsFract, Dollars>,
|
pub sats: LazyFromHeightLast<SatsFract, Dollars>,
|
||||||
}
|
}
|
||||||
@@ -65,4 +63,3 @@ where
|
|||||||
Self { usd, sats }
|
Self { usd, sats }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ use crate::{ComputeIndexes, blocks, indexes, prices};
|
|||||||
use super::{ComputedFromHeightRatio, ComputedFromHeightRatioExtension};
|
use super::{ComputedFromHeightRatio, ComputedFromHeightRatioExtension};
|
||||||
|
|
||||||
#[derive(Deref, DerefMut, Traversable)]
|
#[derive(Deref, DerefMut, Traversable)]
|
||||||
#[traversable(merge)]
|
|
||||||
pub struct ComputedFromHeightRatioExtended<M: StorageMode = Rw> {
|
pub struct ComputedFromHeightRatioExtended<M: StorageMode = Rw> {
|
||||||
#[deref]
|
#[deref]
|
||||||
#[deref_mut]
|
#[deref_mut]
|
||||||
@@ -44,12 +43,8 @@ impl ComputedFromHeightRatioExtended {
|
|||||||
let close_price = &prices.usd.price;
|
let close_price = &prices.usd.price;
|
||||||
self.base
|
self.base
|
||||||
.compute_ratio(starting_indexes, close_price, metric_price, exit)?;
|
.compute_ratio(starting_indexes, close_price, metric_price, exit)?;
|
||||||
self.extended.compute_rest(
|
self.extended
|
||||||
blocks,
|
.compute_rest(blocks, starting_indexes, exit, &self.base.ratio.height)?;
|
||||||
starting_indexes,
|
|
||||||
exit,
|
|
||||||
&self.base.ratio.height,
|
|
||||||
)?;
|
|
||||||
self.extended
|
self.extended
|
||||||
.compute_usd_bands(starting_indexes, metric_price, exit)?;
|
.compute_usd_bands(starting_indexes, metric_price, exit)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ use crate::{ComputeIndexes, blocks, indexes, prices};
|
|||||||
use super::ComputedFromHeightRatioExtended;
|
use super::ComputedFromHeightRatioExtended;
|
||||||
|
|
||||||
#[derive(Deref, DerefMut, Traversable)]
|
#[derive(Deref, DerefMut, Traversable)]
|
||||||
#[traversable(merge)]
|
|
||||||
pub struct ComputedFromHeightPriceWithRatioExtended<M: StorageMode = Rw> {
|
pub struct ComputedFromHeightPriceWithRatioExtended<M: StorageMode = Rw> {
|
||||||
#[deref]
|
#[deref]
|
||||||
#[deref_mut]
|
#[deref_mut]
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
use brk_error::Result;
|
use brk_error::Result;
|
||||||
use brk_traversable::Traversable;
|
use brk_traversable::Traversable;
|
||||||
use brk_types::{Dollars, Height, StoredF32, Version};
|
use brk_types::{Dollars, Height, StoredF32, Version};
|
||||||
use vecdb::{AnyStoredVec, AnyVec, Database, EagerVec, Exit, PcoVec, ReadableVec, Rw, StorageMode, VecIndex, WritableVec};
|
use vecdb::{
|
||||||
|
AnyStoredVec, AnyVec, Database, EagerVec, Exit, PcoVec, ReadableVec, Rw, StorageMode, VecIndex,
|
||||||
|
WritableVec,
|
||||||
|
};
|
||||||
|
|
||||||
use crate::{ComputeIndexes, blocks, indexes};
|
use crate::{ComputeIndexes, blocks, indexes};
|
||||||
|
|
||||||
@@ -10,7 +13,6 @@ use crate::internal::{ComputedFromHeightLast, Price};
|
|||||||
use super::ComputedFromHeightStdDev;
|
use super::ComputedFromHeightStdDev;
|
||||||
|
|
||||||
#[derive(Traversable)]
|
#[derive(Traversable)]
|
||||||
#[traversable(merge)]
|
|
||||||
pub struct ComputedFromHeightStdDevExtended<M: StorageMode = Rw> {
|
pub struct ComputedFromHeightStdDevExtended<M: StorageMode = Rw> {
|
||||||
#[traversable(flatten)]
|
#[traversable(flatten)]
|
||||||
pub base: ComputedFromHeightStdDev<M>,
|
pub base: ComputedFromHeightStdDev<M>,
|
||||||
@@ -68,12 +70,7 @@ impl ComputedFromHeightStdDevExtended {
|
|||||||
|
|
||||||
macro_rules! import_usd {
|
macro_rules! import_usd {
|
||||||
($suffix:expr) => {
|
($suffix:expr) => {
|
||||||
Price::forced_import(
|
Price::forced_import(db, &format!("{name}_{}", $suffix), version, indexes)?
|
||||||
db,
|
|
||||||
&format!("{name}_{}", $suffix),
|
|
||||||
version,
|
|
||||||
indexes,
|
|
||||||
)?
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,7 +112,8 @@ impl ComputedFromHeightStdDevExtended {
|
|||||||
exit: &Exit,
|
exit: &Exit,
|
||||||
source: &impl ReadableVec<Height, StoredF32>,
|
source: &impl ReadableVec<Height, StoredF32>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
self.base.compute_all(blocks, starting_indexes, exit, source)?;
|
self.base
|
||||||
|
.compute_all(blocks, starting_indexes, exit, source)?;
|
||||||
|
|
||||||
let sma_opt: Option<&EagerVec<PcoVec<Height, StoredF32>>> = None;
|
let sma_opt: Option<&EagerVec<PcoVec<Height, StoredF32>>> = None;
|
||||||
self.compute_bands(starting_indexes, exit, sma_opt, source)
|
self.compute_bands(starting_indexes, exit, sma_opt, source)
|
||||||
@@ -148,37 +146,54 @@ impl ComputedFromHeightStdDevExtended {
|
|||||||
let source_len = source.len();
|
let source_len = source.len();
|
||||||
let source_data = source.collect_range_at(start, source_len);
|
let source_data = source.collect_range_at(start, source_len);
|
||||||
|
|
||||||
let sma_len = sma_opt.map(|s| s.len()).unwrap_or(self.base.sma.height.len());
|
let sma_len = sma_opt
|
||||||
|
.map(|s| s.len())
|
||||||
|
.unwrap_or(self.base.sma.height.len());
|
||||||
let sma_data: Vec<StoredF32> = if let Some(sma) = sma_opt {
|
let sma_data: Vec<StoredF32> = if let Some(sma) = sma_opt {
|
||||||
sma.collect_range_at(start, sma_len)
|
sma.collect_range_at(start, sma_len)
|
||||||
} else {
|
} else {
|
||||||
self.base.sma.height.collect_range_at(start, sma_len)
|
self.base.sma.height.collect_range_at(start, sma_len)
|
||||||
};
|
};
|
||||||
let sd_data = self.base.sd.height.collect_range_at(start, self.base.sd.height.len());
|
let sd_data = self
|
||||||
|
.base
|
||||||
|
.sd
|
||||||
|
.height
|
||||||
|
.collect_range_at(start, self.base.sd.height.len());
|
||||||
|
|
||||||
for (offset, _ratio) in source_data.into_iter().enumerate() {
|
for (offset, _ratio) in source_data.into_iter().enumerate() {
|
||||||
let index = start + offset;
|
let index = start + offset;
|
||||||
let average = sma_data[offset];
|
let average = sma_data[offset];
|
||||||
let sd = sd_data[offset];
|
let sd = sd_data[offset];
|
||||||
|
|
||||||
self.p0_5sd.height.truncate_push_at(index, average + StoredF32::from(0.5 * *sd))?;
|
self.p0_5sd
|
||||||
|
.height
|
||||||
|
.truncate_push_at(index, average + StoredF32::from(0.5 * *sd))?;
|
||||||
self.p1sd.height.truncate_push_at(index, average + sd)?;
|
self.p1sd.height.truncate_push_at(index, average + sd)?;
|
||||||
self.p1_5sd.height.truncate_push_at(index, average + StoredF32::from(1.5 * *sd))?;
|
self.p1_5sd
|
||||||
|
.height
|
||||||
|
.truncate_push_at(index, average + StoredF32::from(1.5 * *sd))?;
|
||||||
self.p2sd.height.truncate_push_at(index, average + 2 * sd)?;
|
self.p2sd.height.truncate_push_at(index, average + 2 * sd)?;
|
||||||
self.p2_5sd.height.truncate_push_at(index, average + StoredF32::from(2.5 * *sd))?;
|
self.p2_5sd
|
||||||
|
.height
|
||||||
|
.truncate_push_at(index, average + StoredF32::from(2.5 * *sd))?;
|
||||||
self.p3sd.height.truncate_push_at(index, average + 3 * sd)?;
|
self.p3sd.height.truncate_push_at(index, average + 3 * sd)?;
|
||||||
self.m0_5sd.height.truncate_push_at(index, average - StoredF32::from(0.5 * *sd))?;
|
self.m0_5sd
|
||||||
|
.height
|
||||||
|
.truncate_push_at(index, average - StoredF32::from(0.5 * *sd))?;
|
||||||
self.m1sd.height.truncate_push_at(index, average - sd)?;
|
self.m1sd.height.truncate_push_at(index, average - sd)?;
|
||||||
self.m1_5sd.height.truncate_push_at(index, average - StoredF32::from(1.5 * *sd))?;
|
self.m1_5sd
|
||||||
|
.height
|
||||||
|
.truncate_push_at(index, average - StoredF32::from(1.5 * *sd))?;
|
||||||
self.m2sd.height.truncate_push_at(index, average - 2 * sd)?;
|
self.m2sd.height.truncate_push_at(index, average - 2 * sd)?;
|
||||||
self.m2_5sd.height.truncate_push_at(index, average - StoredF32::from(2.5 * *sd))?;
|
self.m2_5sd
|
||||||
|
.height
|
||||||
|
.truncate_push_at(index, average - StoredF32::from(2.5 * *sd))?;
|
||||||
self.m3sd.height.truncate_push_at(index, average - 3 * sd)?;
|
self.m3sd.height.truncate_push_at(index, average - 3 * sd)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
let _lock = exit.lock();
|
let _lock = exit.lock();
|
||||||
self.mut_band_height_vecs()
|
self.mut_band_height_vecs().try_for_each(|v| v.flush())?;
|
||||||
.try_for_each(|v| v.flush())?;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(sma) = sma_opt {
|
if let Some(sma) = sma_opt {
|
||||||
@@ -213,7 +228,8 @@ impl ComputedFromHeightStdDevExtended {
|
|||||||
|
|
||||||
macro_rules! compute_band {
|
macro_rules! compute_band {
|
||||||
($usd_field:ident, $band_source:expr) => {
|
($usd_field:ident, $band_source:expr) => {
|
||||||
self.$usd_field.usd
|
self.$usd_field
|
||||||
|
.usd
|
||||||
.compute_binary::<Dollars, StoredF32, PriceTimesRatio>(
|
.compute_binary::<Dollars, StoredF32, PriceTimesRatio>(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
metric_price,
|
metric_price,
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ use crate::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Deref, DerefMut, Traversable)]
|
#[derive(Deref, DerefMut, Traversable)]
|
||||||
#[traversable(merge)]
|
|
||||||
pub struct ValueFromHeightLastRolling<M: StorageMode = Rw> {
|
pub struct ValueFromHeightLastRolling<M: StorageMode = Rw> {
|
||||||
#[deref]
|
#[deref]
|
||||||
#[deref_mut]
|
#[deref_mut]
|
||||||
|
|||||||
@@ -1,11 +1,14 @@
|
|||||||
//! LazyFromTxDistribution - lazy txindex source + computed distribution.
|
//! ComputedFromTxDistribution - stored per-tx EagerVec + computed distribution.
|
||||||
|
//!
|
||||||
|
//! Like LazyFromTxDistribution, but the per-tx source is eagerly computed
|
||||||
|
//! and stored rather than lazily derived.
|
||||||
|
|
||||||
use brk_error::Result;
|
use brk_error::Result;
|
||||||
use brk_indexer::Indexer;
|
use brk_indexer::Indexer;
|
||||||
use brk_traversable::Traversable;
|
use brk_traversable::Traversable;
|
||||||
use brk_types::TxIndex;
|
use brk_types::TxIndex;
|
||||||
use schemars::JsonSchema;
|
use schemars::JsonSchema;
|
||||||
use vecdb::{Database, Exit, LazyVecFrom2, ReadableVec, Rw, StorageMode, Version};
|
use vecdb::{Database, EagerVec, Exit, ImportableVec, PcoVec, Rw, StorageMode, Version};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
ComputeIndexes, indexes,
|
ComputeIndexes, indexes,
|
||||||
@@ -13,30 +16,21 @@ use crate::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Traversable)]
|
#[derive(Traversable)]
|
||||||
#[traversable(merge)]
|
pub struct ComputedFromTxDistribution<T, M: StorageMode = Rw>
|
||||||
pub struct LazyFromTxDistribution<T, S1, S2, M: StorageMode = Rw>
|
|
||||||
where
|
where
|
||||||
T: ComputedVecValue + PartialOrd + JsonSchema,
|
T: ComputedVecValue + PartialOrd + JsonSchema,
|
||||||
S1: ComputedVecValue,
|
|
||||||
S2: ComputedVecValue,
|
|
||||||
{
|
{
|
||||||
pub txindex: LazyVecFrom2<TxIndex, T, TxIndex, S1, TxIndex, S2>,
|
pub txindex: M::Stored<EagerVec<PcoVec<TxIndex, T>>>,
|
||||||
#[traversable(flatten)]
|
#[traversable(flatten)]
|
||||||
pub distribution: TxDerivedDistribution<T, M>,
|
pub distribution: TxDerivedDistribution<T, M>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, S1, S2> LazyFromTxDistribution<T, S1, S2>
|
impl<T> ComputedFromTxDistribution<T>
|
||||||
where
|
where
|
||||||
T: NumericValue + JsonSchema,
|
T: NumericValue + JsonSchema,
|
||||||
S1: ComputedVecValue + JsonSchema,
|
|
||||||
S2: ComputedVecValue + JsonSchema,
|
|
||||||
{
|
{
|
||||||
pub(crate) fn forced_import(
|
pub(crate) fn forced_import(db: &Database, name: &str, version: Version) -> Result<Self> {
|
||||||
db: &Database,
|
let txindex = EagerVec::forced_import(db, name, version)?;
|
||||||
name: &str,
|
|
||||||
version: Version,
|
|
||||||
txindex: LazyVecFrom2<TxIndex, T, TxIndex, S1, TxIndex, S2>,
|
|
||||||
) -> Result<Self> {
|
|
||||||
let distribution = TxDerivedDistribution::forced_import(db, name, version)?;
|
let distribution = TxDerivedDistribution::forced_import(db, name, version)?;
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
txindex,
|
txindex,
|
||||||
@@ -44,26 +38,28 @@ where
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn derive_from(
|
#[allow(clippy::too_many_arguments)]
|
||||||
|
pub(crate) fn derive_from_with_skip(
|
||||||
&mut self,
|
&mut self,
|
||||||
indexer: &Indexer,
|
indexer: &Indexer,
|
||||||
indexes: &indexes::Vecs,
|
indexes: &indexes::Vecs,
|
||||||
starting_indexes: &ComputeIndexes,
|
starting_indexes: &ComputeIndexes,
|
||||||
block_windows: &BlockWindowStarts<'_>,
|
block_windows: &BlockWindowStarts<'_>,
|
||||||
exit: &Exit,
|
exit: &Exit,
|
||||||
|
skip_count: usize,
|
||||||
) -> Result<()>
|
) -> Result<()>
|
||||||
where
|
where
|
||||||
T: Copy + Ord + From<f64> + Default,
|
T: Copy + Ord + From<f64> + Default,
|
||||||
f64: From<T>,
|
f64: From<T>,
|
||||||
LazyVecFrom2<TxIndex, T, TxIndex, S1, TxIndex, S2>: ReadableVec<TxIndex, T>,
|
|
||||||
{
|
{
|
||||||
self.distribution.derive_from(
|
self.distribution.derive_from_with_skip(
|
||||||
indexer,
|
indexer,
|
||||||
indexes,
|
indexes,
|
||||||
starting_indexes,
|
starting_indexes,
|
||||||
block_windows,
|
block_windows,
|
||||||
&self.txindex,
|
&self.txindex,
|
||||||
exit,
|
exit,
|
||||||
|
skip_count,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,68 @@
|
|||||||
|
//! LazyFromTxDistribution - lazy txindex source + computed distribution.
|
||||||
|
|
||||||
|
use brk_error::Result;
|
||||||
|
use brk_indexer::Indexer;
|
||||||
|
use brk_traversable::Traversable;
|
||||||
|
use brk_types::TxIndex;
|
||||||
|
use schemars::JsonSchema;
|
||||||
|
use vecdb::{Database, Exit, LazyVecFrom2, ReadableVec, Rw, StorageMode, Version};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
ComputeIndexes, indexes,
|
||||||
|
internal::{BlockWindowStarts, ComputedVecValue, NumericValue, TxDerivedDistribution},
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Traversable)]
|
||||||
|
pub struct LazyFromTxDistribution<T, S1, S2, M: StorageMode = Rw>
|
||||||
|
where
|
||||||
|
T: ComputedVecValue + PartialOrd + JsonSchema,
|
||||||
|
S1: ComputedVecValue,
|
||||||
|
S2: ComputedVecValue,
|
||||||
|
{
|
||||||
|
pub txindex: LazyVecFrom2<TxIndex, T, TxIndex, S1, TxIndex, S2>,
|
||||||
|
#[traversable(flatten)]
|
||||||
|
pub distribution: TxDerivedDistribution<T, M>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T, S1, S2> LazyFromTxDistribution<T, S1, S2>
|
||||||
|
where
|
||||||
|
T: NumericValue + JsonSchema,
|
||||||
|
S1: ComputedVecValue + JsonSchema,
|
||||||
|
S2: ComputedVecValue + JsonSchema,
|
||||||
|
{
|
||||||
|
pub(crate) fn forced_import(
|
||||||
|
db: &Database,
|
||||||
|
name: &str,
|
||||||
|
version: Version,
|
||||||
|
txindex: LazyVecFrom2<TxIndex, T, TxIndex, S1, TxIndex, S2>,
|
||||||
|
) -> Result<Self> {
|
||||||
|
let distribution = TxDerivedDistribution::forced_import(db, name, version)?;
|
||||||
|
Ok(Self {
|
||||||
|
txindex,
|
||||||
|
distribution,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn derive_from(
|
||||||
|
&mut self,
|
||||||
|
indexer: &Indexer,
|
||||||
|
indexes: &indexes::Vecs,
|
||||||
|
starting_indexes: &ComputeIndexes,
|
||||||
|
block_windows: &BlockWindowStarts<'_>,
|
||||||
|
exit: &Exit,
|
||||||
|
) -> Result<()>
|
||||||
|
where
|
||||||
|
T: Copy + Ord + From<f64> + Default,
|
||||||
|
f64: From<T>,
|
||||||
|
LazyVecFrom2<TxIndex, T, TxIndex, S1, TxIndex, S2>: ReadableVec<TxIndex, T>,
|
||||||
|
{
|
||||||
|
self.distribution.derive_from(
|
||||||
|
indexer,
|
||||||
|
indexes,
|
||||||
|
starting_indexes,
|
||||||
|
block_windows,
|
||||||
|
&self.txindex,
|
||||||
|
exit,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
mod distribution;
|
mod distribution;
|
||||||
|
mod lazy_distribution;
|
||||||
|
|
||||||
pub use distribution::*;
|
pub use distribution::*;
|
||||||
|
pub use lazy_distribution::*;
|
||||||
|
|||||||
@@ -17,12 +17,10 @@ use crate::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Traversable)]
|
#[derive(Traversable)]
|
||||||
#[traversable(merge)]
|
|
||||||
pub struct ComputedHeightDerivedCumulativeFull<T, M: StorageMode = Rw>
|
pub struct ComputedHeightDerivedCumulativeFull<T, M: StorageMode = Rw>
|
||||||
where
|
where
|
||||||
T: NumericValue + JsonSchema,
|
T: NumericValue + JsonSchema,
|
||||||
{
|
{
|
||||||
#[traversable(flatten)]
|
|
||||||
pub cumulative: ComputedFromHeightLast<T, M>,
|
pub cumulative: ComputedFromHeightLast<T, M>,
|
||||||
#[traversable(flatten)]
|
#[traversable(flatten)]
|
||||||
pub rolling: RollingFull<T, M>,
|
pub rolling: RollingFull<T, M>,
|
||||||
|
|||||||
@@ -13,11 +13,12 @@ use vecdb::{Database, Exit, ReadableVec, Rw, StorageMode, Version};
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
ComputeIndexes, indexes,
|
ComputeIndexes, indexes,
|
||||||
internal::{BlockRollingDistribution, BlockWindowStarts, ComputedVecValue, Distribution, NumericValue},
|
internal::{
|
||||||
|
BlockRollingDistribution, BlockWindowStarts, ComputedVecValue, Distribution, NumericValue,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Traversable)]
|
#[derive(Traversable)]
|
||||||
#[traversable(merge)]
|
|
||||||
pub struct TxDerivedDistribution<T, M: StorageMode = Rw>
|
pub struct TxDerivedDistribution<T, M: StorageMode = Rw>
|
||||||
where
|
where
|
||||||
T: ComputedVecValue + PartialOrd + JsonSchema,
|
T: ComputedVecValue + PartialOrd + JsonSchema,
|
||||||
@@ -31,11 +32,7 @@ impl<T> TxDerivedDistribution<T>
|
|||||||
where
|
where
|
||||||
T: NumericValue + JsonSchema,
|
T: NumericValue + JsonSchema,
|
||||||
{
|
{
|
||||||
pub(crate) fn forced_import(
|
pub(crate) fn forced_import(db: &Database, name: &str, version: Version) -> Result<Self> {
|
||||||
db: &Database,
|
|
||||||
name: &str,
|
|
||||||
version: Version,
|
|
||||||
) -> Result<Self> {
|
|
||||||
let block = Distribution::forced_import(db, name, version)?;
|
let block = Distribution::forced_import(db, name, version)?;
|
||||||
let rolling = BlockRollingDistribution::forced_import(db, name, version)?;
|
let rolling = BlockRollingDistribution::forced_import(db, name, version)?;
|
||||||
|
|
||||||
|
|||||||
@@ -18,12 +18,10 @@ use crate::{
|
|||||||
|
|
||||||
/// Sum (4 windows) + Distribution (8 stats × 4 windows) = 36 stored height vecs.
|
/// Sum (4 windows) + Distribution (8 stats × 4 windows) = 36 stored height vecs.
|
||||||
#[derive(Traversable)]
|
#[derive(Traversable)]
|
||||||
#[traversable(merge)]
|
|
||||||
pub struct RollingFull<T, M: StorageMode = Rw>
|
pub struct RollingFull<T, M: StorageMode = Rw>
|
||||||
where
|
where
|
||||||
T: ComputedVecValue + PartialOrd + JsonSchema,
|
T: ComputedVecValue + PartialOrd + JsonSchema,
|
||||||
{
|
{
|
||||||
#[traversable(flatten)]
|
|
||||||
pub sum: RollingWindows<T, M>,
|
pub sum: RollingWindows<T, M>,
|
||||||
#[traversable(flatten)]
|
#[traversable(flatten)]
|
||||||
pub distribution: RollingDistribution<T, M>,
|
pub distribution: RollingDistribution<T, M>,
|
||||||
|
|||||||
@@ -24,11 +24,6 @@ impl<I: VecIndex, T: ComputedVecValue + JsonSchema> CumulativeVec<I, T> {
|
|||||||
)?))
|
)?))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub(crate) fn inner(&self) -> &EagerVec<PcoVec<I, T>> {
|
|
||||||
&self.0
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn read_only_clone(&self) -> CumulativeVec<I, T, Ro> {
|
pub fn read_only_clone(&self) -> CumulativeVec<I, T, Ro> {
|
||||||
CumulativeVec(StoredVec::read_only_clone(&self.0))
|
CumulativeVec(StoredVec::read_only_clone(&self.0))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,6 @@
|
|||||||
use brk_traversable::Traversable;
|
use brk_traversable::Traversable;
|
||||||
|
|
||||||
#[derive(Clone, Traversable)]
|
#[derive(Clone, Traversable)]
|
||||||
#[traversable(merge)]
|
|
||||||
pub struct Windows<A, B = A, C = A, D = A> {
|
pub struct Windows<A, B = A, C = A, D = A> {
|
||||||
#[traversable(rename = "24h")]
|
#[traversable(rename = "24h")]
|
||||||
pub _24h: A,
|
pub _24h: A,
|
||||||
|
|||||||
@@ -359,7 +359,6 @@ impl Computer {
|
|||||||
&self.blocks,
|
&self.blocks,
|
||||||
&self.prices,
|
&self.prices,
|
||||||
&self.mining,
|
&self.mining,
|
||||||
&self.transactions,
|
|
||||||
&starting_indexes_clone,
|
&starting_indexes_clone,
|
||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
|
|||||||
@@ -28,12 +28,11 @@ impl Vecs {
|
|||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
// Hashrate metrics (disjoint field borrow via coinbase_sum)
|
|
||||||
self.hashrate.compute(
|
self.hashrate.compute(
|
||||||
&blocks.count,
|
&blocks.count,
|
||||||
&blocks.difficulty,
|
&blocks.difficulty,
|
||||||
&self.rewards.coinbase_sum._24h.sats.height,
|
&self.rewards.coinbase.sats.rolling.sum._24h.height,
|
||||||
&self.rewards.coinbase_sum._24h.usd.height,
|
&self.rewards.coinbase.usd.rolling.sum._24h.height,
|
||||||
starting_indexes,
|
starting_indexes,
|
||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
|
|||||||
@@ -20,77 +20,93 @@ impl Vecs {
|
|||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let window_starts = count_vecs.window_starts();
|
let window_starts = count_vecs.window_starts();
|
||||||
|
|
||||||
self.coinbase.compute(starting_indexes.height, &window_starts, prices, exit, |vec| {
|
self.coinbase.compute(
|
||||||
// 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_sum.compute_rolling_sum(
|
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&window_starts,
|
&window_starts,
|
||||||
&self.coinbase.sats.height,
|
prices,
|
||||||
&self.coinbase.usd.height,
|
|
||||||
exit,
|
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(())
|
||||||
|
},
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let fee_sats_source = transactions_fees.fee.height.sum_cumulative.sum.inner();
|
// Coinbase fee is 0, so including it in the sum doesn't affect the result
|
||||||
let fee_usd_source = &transactions_fees.fee_usd_sum;
|
self.fees.compute(
|
||||||
self.fee_sum.compute_rolling_sum(
|
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&window_starts,
|
&window_starts,
|
||||||
fee_sats_source,
|
prices,
|
||||||
fee_usd_source,
|
|
||||||
exit,
|
exit,
|
||||||
|
|vec| {
|
||||||
|
vec.compute_sum_from_indexes(
|
||||||
|
starting_indexes.height,
|
||||||
|
&indexer.vecs.transactions.first_txindex,
|
||||||
|
&indexes.height.txindex_count,
|
||||||
|
&transactions_fees.fee.txindex,
|
||||||
|
exit,
|
||||||
|
)?;
|
||||||
|
Ok(())
|
||||||
|
},
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
self.subsidy.compute(starting_indexes.height, &window_starts, prices, exit, |vec| {
|
self.subsidy.compute(
|
||||||
vec.compute_transform2(
|
starting_indexes.height,
|
||||||
starting_indexes.height,
|
&window_starts,
|
||||||
&self.coinbase.sats.height,
|
prices,
|
||||||
transactions_fees.fee.height.sum_cumulative.sum.inner(),
|
exit,
|
||||||
|(height, coinbase, fees, ..)| {
|
|vec| {
|
||||||
(
|
vec.compute_transform2(
|
||||||
height,
|
starting_indexes.height,
|
||||||
coinbase.checked_sub(fees).unwrap_or_else(|| {
|
&self.coinbase.sats.height,
|
||||||
dbg!(height, coinbase, fees);
|
&self.fees.sats.height,
|
||||||
panic!()
|
|(height, coinbase, fees, ..)| {
|
||||||
}),
|
(
|
||||||
)
|
height,
|
||||||
},
|
coinbase.checked_sub(fees).unwrap_or_else(|| {
|
||||||
exit,
|
dbg!(height, coinbase, fees);
|
||||||
)?;
|
panic!()
|
||||||
Ok(())
|
}),
|
||||||
})?;
|
)
|
||||||
|
},
|
||||||
|
exit,
|
||||||
|
)?;
|
||||||
|
Ok(())
|
||||||
|
},
|
||||||
|
)?;
|
||||||
|
|
||||||
self.unclaimed_rewards
|
self.unclaimed_rewards.compute(
|
||||||
.compute(starting_indexes.height, &window_starts, prices, exit, |vec| {
|
starting_indexes.height,
|
||||||
|
&window_starts,
|
||||||
|
prices,
|
||||||
|
exit,
|
||||||
|
|vec| {
|
||||||
vec.compute_transform(
|
vec.compute_transform(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&self.subsidy.sats.height,
|
&self.subsidy.sats.height,
|
||||||
@@ -102,12 +118,13 @@ impl Vecs {
|
|||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
})?;
|
},
|
||||||
|
)?;
|
||||||
|
|
||||||
// All-time cumulative fee dominance
|
// All-time cumulative fee dominance
|
||||||
self.fee_dominance.height.compute_percentage(
|
self.fee_dominance.height.compute_percentage(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
transactions_fees.fee.height.sum_cumulative.cumulative.inner(),
|
&self.fees.sats.cumulative.height,
|
||||||
&self.coinbase.sats.cumulative.height,
|
&self.coinbase.sats.cumulative.height,
|
||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
@@ -115,26 +132,26 @@ impl Vecs {
|
|||||||
// Rolling fee dominance = sum(fees) / sum(coinbase) * 100
|
// Rolling fee dominance = sum(fees) / sum(coinbase) * 100
|
||||||
self.fee_dominance_24h.height.compute_percentage(
|
self.fee_dominance_24h.height.compute_percentage(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&self.fee_sum._24h.sats.height,
|
&self.fees.sats.rolling.sum._24h.height,
|
||||||
&self.coinbase_sum._24h.sats.height,
|
&self.coinbase.sats.rolling.sum._24h.height,
|
||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
self.fee_dominance_7d.height.compute_percentage(
|
self.fee_dominance_7d.height.compute_percentage(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&self.fee_sum._7d.sats.height,
|
&self.fees.sats.rolling.sum._7d.height,
|
||||||
&self.coinbase_sum._7d.sats.height,
|
&self.coinbase.sats.rolling.sum._7d.height,
|
||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
self.fee_dominance_30d.height.compute_percentage(
|
self.fee_dominance_30d.height.compute_percentage(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&self.fee_sum._30d.sats.height,
|
&self.fees.sats.rolling.sum._30d.height,
|
||||||
&self.coinbase_sum._30d.sats.height,
|
&self.coinbase.sats.rolling.sum._30d.height,
|
||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
self.fee_dominance_1y.height.compute_percentage(
|
self.fee_dominance_1y.height.compute_percentage(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&self.fee_sum._1y.sats.height,
|
&self.fees.sats.rolling.sum._1y.height,
|
||||||
&self.coinbase_sum._1y.sats.height,
|
&self.coinbase.sats.rolling.sum._1y.height,
|
||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,10 @@ use vecdb::Database;
|
|||||||
use super::Vecs;
|
use super::Vecs;
|
||||||
use crate::{
|
use crate::{
|
||||||
indexes,
|
indexes,
|
||||||
internal::{ComputedFromHeightLast, StoredValueRollingWindows, ValueFromHeightFull, ValueFromHeightSumCumulative},
|
internal::{
|
||||||
|
ComputedFromHeightLast, ValueFromHeightFull,
|
||||||
|
ValueFromHeightSumCumulative,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
impl Vecs {
|
impl Vecs {
|
||||||
@@ -15,10 +18,9 @@ impl Vecs {
|
|||||||
indexes: &indexes::Vecs,
|
indexes: &indexes::Vecs,
|
||||||
) -> Result<Self> {
|
) -> Result<Self> {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
coinbase_sum: StoredValueRollingWindows::forced_import(db, "coinbase_sum", version, indexes)?,
|
|
||||||
fee_sum: StoredValueRollingWindows::forced_import(db, "fee_sum", version, indexes)?,
|
|
||||||
coinbase: ValueFromHeightFull::forced_import(db, "coinbase", version, indexes)?,
|
coinbase: ValueFromHeightFull::forced_import(db, "coinbase", version, indexes)?,
|
||||||
subsidy: ValueFromHeightFull::forced_import(db, "subsidy", version, indexes)?,
|
subsidy: ValueFromHeightFull::forced_import(db, "subsidy", version, indexes)?,
|
||||||
|
fees: ValueFromHeightFull::forced_import(db, "fees", version, indexes)?,
|
||||||
unclaimed_rewards: ValueFromHeightSumCumulative::forced_import(
|
unclaimed_rewards: ValueFromHeightSumCumulative::forced_import(
|
||||||
db,
|
db,
|
||||||
"unclaimed_rewards",
|
"unclaimed_rewards",
|
||||||
|
|||||||
@@ -2,15 +2,17 @@ use brk_traversable::Traversable;
|
|||||||
use brk_types::{Dollars, StoredF32};
|
use brk_types::{Dollars, StoredF32};
|
||||||
use vecdb::{Rw, StorageMode};
|
use vecdb::{Rw, StorageMode};
|
||||||
|
|
||||||
use crate::internal::{ComputedFromHeightLast, StoredValueRollingWindows, ValueFromHeightFull, ValueFromHeightSumCumulative};
|
use crate::internal::{
|
||||||
|
ComputedFromHeightLast, ValueFromHeightFull,
|
||||||
|
ValueFromHeightSumCumulative,
|
||||||
|
};
|
||||||
|
|
||||||
/// Coinbase/subsidy/rewards metrics
|
/// Coinbase/subsidy/rewards metrics
|
||||||
#[derive(Traversable)]
|
#[derive(Traversable)]
|
||||||
pub struct Vecs<M: StorageMode = Rw> {
|
pub struct Vecs<M: StorageMode = Rw> {
|
||||||
pub coinbase_sum: StoredValueRollingWindows<M>,
|
|
||||||
pub fee_sum: StoredValueRollingWindows<M>,
|
|
||||||
pub coinbase: ValueFromHeightFull<M>,
|
pub coinbase: ValueFromHeightFull<M>,
|
||||||
pub subsidy: ValueFromHeightFull<M>,
|
pub subsidy: ValueFromHeightFull<M>,
|
||||||
|
pub fees: ValueFromHeightFull<M>,
|
||||||
pub unclaimed_rewards: ValueFromHeightSumCumulative<M>,
|
pub unclaimed_rewards: ValueFromHeightSumCumulative<M>,
|
||||||
pub fee_dominance: ComputedFromHeightLast<StoredF32, M>,
|
pub fee_dominance: ComputedFromHeightLast<StoredF32, M>,
|
||||||
pub fee_dominance_24h: ComputedFromHeightLast<StoredF32, M>,
|
pub fee_dominance_24h: ComputedFromHeightLast<StoredF32, M>,
|
||||||
|
|||||||
@@ -19,11 +19,8 @@ impl Vecs {
|
|||||||
exit: &Exit,
|
exit: &Exit,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let window_starts = blocks.count.window_starts();
|
let window_starts = blocks.count.window_starts();
|
||||||
self.total_count.compute(
|
self.total_count
|
||||||
starting_indexes.height,
|
.compute(starting_indexes.height, &window_starts, exit, |full| {
|
||||||
&window_starts,
|
|
||||||
exit,
|
|
||||||
|full| {
|
|
||||||
full.compute_with_skip(
|
full.compute_with_skip(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&indexes.txindex.output_count,
|
&indexes.txindex.output_count,
|
||||||
@@ -32,13 +29,12 @@ impl Vecs {
|
|||||||
exit,
|
exit,
|
||||||
0,
|
0,
|
||||||
)
|
)
|
||||||
},
|
})?;
|
||||||
)?;
|
|
||||||
|
|
||||||
self.utxo_count.height.compute_transform3(
|
self.utxo_count.height.compute_transform3(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&*self.total_count.height.sum_cumulative.cumulative,
|
&*self.total_count.full.sum_cumulative.cumulative,
|
||||||
&*inputs_count.height.sum_cumulative.cumulative,
|
&*inputs_count.full.sum_cumulative.cumulative,
|
||||||
&scripts_count.opreturn.cumulative.height,
|
&scripts_count.opreturn.cumulative.height,
|
||||||
|(h, output_count, input_count, opreturn_count, ..)| {
|
|(h, output_count, input_count, opreturn_count, ..)| {
|
||||||
let block_count = u64::from(h + 1_usize);
|
let block_count = u64::from(h + 1_usize);
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ mod vecs;
|
|||||||
use crate::{
|
use crate::{
|
||||||
blocks,
|
blocks,
|
||||||
indexes::{self, ComputeIndexes},
|
indexes::{self, ComputeIndexes},
|
||||||
mining, prices, transactions,
|
mining, prices,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const DB_NAME: &str = "pools";
|
pub const DB_NAME: &str = "pools";
|
||||||
@@ -73,7 +73,6 @@ impl Vecs {
|
|||||||
blocks: &blocks::Vecs,
|
blocks: &blocks::Vecs,
|
||||||
prices: &prices::Vecs,
|
prices: &prices::Vecs,
|
||||||
mining: &mining::Vecs,
|
mining: &mining::Vecs,
|
||||||
transactions: &transactions::Vecs,
|
|
||||||
starting_indexes: &ComputeIndexes,
|
starting_indexes: &ComputeIndexes,
|
||||||
exit: &Exit,
|
exit: &Exit,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
@@ -83,7 +82,6 @@ impl Vecs {
|
|||||||
blocks,
|
blocks,
|
||||||
prices,
|
prices,
|
||||||
mining,
|
mining,
|
||||||
transactions,
|
|
||||||
starting_indexes,
|
starting_indexes,
|
||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
@@ -100,7 +98,6 @@ impl Vecs {
|
|||||||
blocks: &blocks::Vecs,
|
blocks: &blocks::Vecs,
|
||||||
prices: &prices::Vecs,
|
prices: &prices::Vecs,
|
||||||
mining: &mining::Vecs,
|
mining: &mining::Vecs,
|
||||||
transactions: &transactions::Vecs,
|
|
||||||
starting_indexes: &ComputeIndexes,
|
starting_indexes: &ComputeIndexes,
|
||||||
exit: &Exit,
|
exit: &Exit,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
@@ -113,7 +110,6 @@ impl Vecs {
|
|||||||
blocks,
|
blocks,
|
||||||
prices,
|
prices,
|
||||||
mining,
|
mining,
|
||||||
transactions,
|
|
||||||
exit,
|
exit,
|
||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ use crate::{
|
|||||||
ComputedFromHeightCumulativeSum, ComputedFromHeightLast, MaskSats, PercentageU32F32,
|
ComputedFromHeightCumulativeSum, ComputedFromHeightLast, MaskSats, PercentageU32F32,
|
||||||
ValueFromHeightSumCumulative,
|
ValueFromHeightSumCumulative,
|
||||||
},
|
},
|
||||||
mining, prices, transactions,
|
mining, prices,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Traversable)]
|
#[derive(Traversable)]
|
||||||
@@ -45,8 +45,12 @@ impl Vecs {
|
|||||||
let suffix = |s: &str| format!("{}_{s}", slug);
|
let suffix = |s: &str| format!("{}_{s}", slug);
|
||||||
let version = parent_version;
|
let version = parent_version;
|
||||||
|
|
||||||
let blocks_mined =
|
let blocks_mined = ComputedFromHeightCumulativeSum::forced_import(
|
||||||
ComputedFromHeightCumulativeSum::forced_import(db, &suffix("blocks_mined"), version, indexes)?;
|
db,
|
||||||
|
&suffix("blocks_mined"),
|
||||||
|
version,
|
||||||
|
indexes,
|
||||||
|
)?;
|
||||||
|
|
||||||
let blocks_mined_24h_sum = ComputedFromHeightLast::forced_import(
|
let blocks_mined_24h_sum = ComputedFromHeightLast::forced_import(
|
||||||
db,
|
db,
|
||||||
@@ -76,7 +80,8 @@ impl Vecs {
|
|||||||
let subsidy =
|
let subsidy =
|
||||||
ValueFromHeightSumCumulative::forced_import(db, &suffix("subsidy"), version, indexes)?;
|
ValueFromHeightSumCumulative::forced_import(db, &suffix("subsidy"), version, indexes)?;
|
||||||
|
|
||||||
let fee = ValueFromHeightSumCumulative::forced_import(db, &suffix("fee"), version, indexes)?;
|
let fee =
|
||||||
|
ValueFromHeightSumCumulative::forced_import(db, &suffix("fee"), version, indexes)?;
|
||||||
|
|
||||||
let coinbase =
|
let coinbase =
|
||||||
ValueFromHeightSumCumulative::forced_import(db, &suffix("coinbase"), version, indexes)?;
|
ValueFromHeightSumCumulative::forced_import(db, &suffix("coinbase"), version, indexes)?;
|
||||||
@@ -130,29 +135,29 @@ impl Vecs {
|
|||||||
blocks: &blocks::Vecs,
|
blocks: &blocks::Vecs,
|
||||||
prices: &prices::Vecs,
|
prices: &prices::Vecs,
|
||||||
mining: &mining::Vecs,
|
mining: &mining::Vecs,
|
||||||
transactions: &transactions::Vecs,
|
|
||||||
exit: &Exit,
|
exit: &Exit,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let window_starts = blocks.count.window_starts();
|
let window_starts = blocks.count.window_starts();
|
||||||
|
|
||||||
self.blocks_mined.compute(starting_indexes.height, &window_starts, exit, |vec| {
|
self.blocks_mined
|
||||||
vec.compute_transform(
|
.compute(starting_indexes.height, &window_starts, exit, |vec| {
|
||||||
starting_indexes.height,
|
vec.compute_transform(
|
||||||
height_to_pool,
|
starting_indexes.height,
|
||||||
|(h, id, ..)| {
|
height_to_pool,
|
||||||
(
|
|(h, id, ..)| {
|
||||||
h,
|
(
|
||||||
if id == self.slug {
|
h,
|
||||||
StoredU32::ONE
|
if id == self.slug {
|
||||||
} else {
|
StoredU32::ONE
|
||||||
StoredU32::ZERO
|
} else {
|
||||||
},
|
StoredU32::ZERO
|
||||||
)
|
},
|
||||||
},
|
)
|
||||||
exit,
|
},
|
||||||
)?;
|
exit,
|
||||||
Ok(())
|
)?;
|
||||||
})?;
|
Ok(())
|
||||||
|
})?;
|
||||||
|
|
||||||
// Compute rolling window blocks mined using the start heights from blocks.count
|
// Compute rolling window blocks mined using the start heights from blocks.count
|
||||||
self.blocks_mined_24h_sum.height.compute_rolling_sum(
|
self.blocks_mined_24h_sum.height.compute_rolling_sum(
|
||||||
@@ -223,8 +228,12 @@ impl Vecs {
|
|||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
self.subsidy
|
self.subsidy.compute(
|
||||||
.compute(starting_indexes.height, &window_starts, prices, exit, |vec| {
|
starting_indexes.height,
|
||||||
|
&window_starts,
|
||||||
|
prices,
|
||||||
|
exit,
|
||||||
|
|vec| {
|
||||||
Ok(vec.compute_transform2(
|
Ok(vec.compute_transform2(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&self.blocks_mined.height,
|
&self.blocks_mined.height,
|
||||||
@@ -232,20 +241,31 @@ impl Vecs {
|
|||||||
|(h, mask, val, ..)| (h, MaskSats::apply(mask, val)),
|
|(h, mask, val, ..)| (h, MaskSats::apply(mask, val)),
|
||||||
exit,
|
exit,
|
||||||
)?)
|
)?)
|
||||||
})?;
|
},
|
||||||
|
)?;
|
||||||
|
|
||||||
self.fee.compute(starting_indexes.height, &window_starts, prices, exit, |vec| {
|
self.fee.compute(
|
||||||
Ok(vec.compute_transform2(
|
starting_indexes.height,
|
||||||
starting_indexes.height,
|
&window_starts,
|
||||||
&self.blocks_mined.height,
|
prices,
|
||||||
&*transactions.fees.fee.height.sum_cumulative.sum,
|
exit,
|
||||||
|(h, mask, val, ..)| (h, MaskSats::apply(mask, val)),
|
|vec| {
|
||||||
exit,
|
Ok(vec.compute_transform2(
|
||||||
)?)
|
starting_indexes.height,
|
||||||
})?;
|
&self.blocks_mined.height,
|
||||||
|
&mining.rewards.fees.sats.height,
|
||||||
|
|(h, mask, val, ..)| (h, MaskSats::apply(mask, val)),
|
||||||
|
exit,
|
||||||
|
)?)
|
||||||
|
},
|
||||||
|
)?;
|
||||||
|
|
||||||
self.coinbase
|
self.coinbase.compute(
|
||||||
.compute(starting_indexes.height, &window_starts, prices, exit, |vec| {
|
starting_indexes.height,
|
||||||
|
&window_starts,
|
||||||
|
prices,
|
||||||
|
exit,
|
||||||
|
|vec| {
|
||||||
Ok(vec.compute_transform2(
|
Ok(vec.compute_transform2(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&self.blocks_mined.height,
|
&self.blocks_mined.height,
|
||||||
@@ -253,7 +273,8 @@ impl Vecs {
|
|||||||
|(h, mask, val, ..)| (h, MaskSats::apply(mask, val)),
|
|(h, mask, val, ..)| (h, MaskSats::apply(mask, val)),
|
||||||
exit,
|
exit,
|
||||||
)?)
|
)?)
|
||||||
})?;
|
},
|
||||||
|
)?;
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut prev = StoredU32::ZERO;
|
let mut prev = StoredU32::ZERO;
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ use brk_types::StoredU64;
|
|||||||
use vecdb::Exit;
|
use vecdb::Exit;
|
||||||
|
|
||||||
use super::Vecs;
|
use super::Vecs;
|
||||||
use crate::{blocks, outputs, ComputeIndexes};
|
use crate::{ComputeIndexes, blocks, outputs};
|
||||||
|
|
||||||
impl Vecs {
|
impl Vecs {
|
||||||
pub(crate) fn compute(
|
pub(crate) fn compute(
|
||||||
@@ -18,133 +18,144 @@ impl Vecs {
|
|||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let window_starts = count_vecs.window_starts();
|
let window_starts = count_vecs.window_starts();
|
||||||
|
|
||||||
self.p2a.compute(starting_indexes.height, &window_starts, exit, |v| {
|
self.p2a
|
||||||
Ok(v.compute_count_from_indexes(
|
.compute(starting_indexes.height, &window_starts, exit, |v| {
|
||||||
starting_indexes.height,
|
Ok(v.compute_count_from_indexes(
|
||||||
&indexer.vecs.addresses.first_p2aaddressindex,
|
starting_indexes.height,
|
||||||
&indexer.vecs.addresses.p2abytes,
|
&indexer.vecs.addresses.first_p2aaddressindex,
|
||||||
exit,
|
&indexer.vecs.addresses.p2abytes,
|
||||||
)?)
|
exit,
|
||||||
})?;
|
)?)
|
||||||
|
})?;
|
||||||
|
|
||||||
self.p2ms.compute(starting_indexes.height, &window_starts, exit, |v| {
|
self.p2ms
|
||||||
Ok(v.compute_count_from_indexes(
|
.compute(starting_indexes.height, &window_starts, exit, |v| {
|
||||||
starting_indexes.height,
|
Ok(v.compute_count_from_indexes(
|
||||||
&indexer.vecs.scripts.first_p2msoutputindex,
|
starting_indexes.height,
|
||||||
&indexer.vecs.scripts.p2ms_to_txindex,
|
&indexer.vecs.scripts.first_p2msoutputindex,
|
||||||
exit,
|
&indexer.vecs.scripts.p2ms_to_txindex,
|
||||||
)?)
|
exit,
|
||||||
})?;
|
)?)
|
||||||
|
})?;
|
||||||
|
|
||||||
self.p2pk33.compute(starting_indexes.height, &window_starts, exit, |v| {
|
self.p2pk33
|
||||||
Ok(v.compute_count_from_indexes(
|
.compute(starting_indexes.height, &window_starts, exit, |v| {
|
||||||
starting_indexes.height,
|
Ok(v.compute_count_from_indexes(
|
||||||
&indexer.vecs.addresses.first_p2pk33addressindex,
|
starting_indexes.height,
|
||||||
&indexer.vecs.addresses.p2pk33bytes,
|
&indexer.vecs.addresses.first_p2pk33addressindex,
|
||||||
exit,
|
&indexer.vecs.addresses.p2pk33bytes,
|
||||||
)?)
|
exit,
|
||||||
})?;
|
)?)
|
||||||
|
})?;
|
||||||
|
|
||||||
self.p2pk65.compute(starting_indexes.height, &window_starts, exit, |v| {
|
self.p2pk65
|
||||||
Ok(v.compute_count_from_indexes(
|
.compute(starting_indexes.height, &window_starts, exit, |v| {
|
||||||
starting_indexes.height,
|
Ok(v.compute_count_from_indexes(
|
||||||
&indexer.vecs.addresses.first_p2pk65addressindex,
|
starting_indexes.height,
|
||||||
&indexer.vecs.addresses.p2pk65bytes,
|
&indexer.vecs.addresses.first_p2pk65addressindex,
|
||||||
exit,
|
&indexer.vecs.addresses.p2pk65bytes,
|
||||||
)?)
|
exit,
|
||||||
})?;
|
)?)
|
||||||
|
})?;
|
||||||
|
|
||||||
self.p2pkh.compute(starting_indexes.height, &window_starts, exit, |v| {
|
self.p2pkh
|
||||||
Ok(v.compute_count_from_indexes(
|
.compute(starting_indexes.height, &window_starts, exit, |v| {
|
||||||
starting_indexes.height,
|
Ok(v.compute_count_from_indexes(
|
||||||
&indexer.vecs.addresses.first_p2pkhaddressindex,
|
starting_indexes.height,
|
||||||
&indexer.vecs.addresses.p2pkhbytes,
|
&indexer.vecs.addresses.first_p2pkhaddressindex,
|
||||||
exit,
|
&indexer.vecs.addresses.p2pkhbytes,
|
||||||
)?)
|
exit,
|
||||||
})?;
|
)?)
|
||||||
|
})?;
|
||||||
|
|
||||||
self.p2sh.compute(starting_indexes.height, &window_starts, exit, |v| {
|
self.p2sh
|
||||||
Ok(v.compute_count_from_indexes(
|
.compute(starting_indexes.height, &window_starts, exit, |v| {
|
||||||
starting_indexes.height,
|
Ok(v.compute_count_from_indexes(
|
||||||
&indexer.vecs.addresses.first_p2shaddressindex,
|
starting_indexes.height,
|
||||||
&indexer.vecs.addresses.p2shbytes,
|
&indexer.vecs.addresses.first_p2shaddressindex,
|
||||||
exit,
|
&indexer.vecs.addresses.p2shbytes,
|
||||||
)?)
|
exit,
|
||||||
})?;
|
)?)
|
||||||
|
})?;
|
||||||
|
|
||||||
self.p2tr.compute(starting_indexes.height, &window_starts, exit, |v| {
|
self.p2tr
|
||||||
Ok(v.compute_count_from_indexes(
|
.compute(starting_indexes.height, &window_starts, exit, |v| {
|
||||||
starting_indexes.height,
|
Ok(v.compute_count_from_indexes(
|
||||||
&indexer.vecs.addresses.first_p2traddressindex,
|
starting_indexes.height,
|
||||||
&indexer.vecs.addresses.p2trbytes,
|
&indexer.vecs.addresses.first_p2traddressindex,
|
||||||
exit,
|
&indexer.vecs.addresses.p2trbytes,
|
||||||
)?)
|
exit,
|
||||||
})?;
|
)?)
|
||||||
|
})?;
|
||||||
|
|
||||||
self.p2wpkh.compute(starting_indexes.height, &window_starts, exit, |v| {
|
self.p2wpkh
|
||||||
Ok(v.compute_count_from_indexes(
|
.compute(starting_indexes.height, &window_starts, exit, |v| {
|
||||||
starting_indexes.height,
|
Ok(v.compute_count_from_indexes(
|
||||||
&indexer.vecs.addresses.first_p2wpkhaddressindex,
|
starting_indexes.height,
|
||||||
&indexer.vecs.addresses.p2wpkhbytes,
|
&indexer.vecs.addresses.first_p2wpkhaddressindex,
|
||||||
exit,
|
&indexer.vecs.addresses.p2wpkhbytes,
|
||||||
)?)
|
exit,
|
||||||
})?;
|
)?)
|
||||||
|
})?;
|
||||||
|
|
||||||
self.p2wsh.compute(starting_indexes.height, &window_starts, exit, |v| {
|
self.p2wsh
|
||||||
Ok(v.compute_count_from_indexes(
|
.compute(starting_indexes.height, &window_starts, exit, |v| {
|
||||||
starting_indexes.height,
|
Ok(v.compute_count_from_indexes(
|
||||||
&indexer.vecs.addresses.first_p2wshaddressindex,
|
starting_indexes.height,
|
||||||
&indexer.vecs.addresses.p2wshbytes,
|
&indexer.vecs.addresses.first_p2wshaddressindex,
|
||||||
exit,
|
&indexer.vecs.addresses.p2wshbytes,
|
||||||
)?)
|
exit,
|
||||||
})?;
|
)?)
|
||||||
|
})?;
|
||||||
|
|
||||||
self.opreturn.compute(starting_indexes.height, &window_starts, exit, |v| {
|
self.opreturn
|
||||||
Ok(v.compute_count_from_indexes(
|
.compute(starting_indexes.height, &window_starts, exit, |v| {
|
||||||
starting_indexes.height,
|
Ok(v.compute_count_from_indexes(
|
||||||
&indexer.vecs.scripts.first_opreturnindex,
|
starting_indexes.height,
|
||||||
&indexer.vecs.scripts.opreturn_to_txindex,
|
&indexer.vecs.scripts.first_opreturnindex,
|
||||||
exit,
|
&indexer.vecs.scripts.opreturn_to_txindex,
|
||||||
)?)
|
exit,
|
||||||
})?;
|
)?)
|
||||||
|
})?;
|
||||||
|
|
||||||
self.unknownoutput.compute(starting_indexes.height, &window_starts, exit, |v| {
|
self.unknownoutput
|
||||||
Ok(v.compute_count_from_indexes(
|
.compute(starting_indexes.height, &window_starts, exit, |v| {
|
||||||
starting_indexes.height,
|
Ok(v.compute_count_from_indexes(
|
||||||
&indexer.vecs.scripts.first_unknownoutputindex,
|
starting_indexes.height,
|
||||||
&indexer.vecs.scripts.unknown_to_txindex,
|
&indexer.vecs.scripts.first_unknownoutputindex,
|
||||||
exit,
|
&indexer.vecs.scripts.unknown_to_txindex,
|
||||||
)?)
|
exit,
|
||||||
})?;
|
)?)
|
||||||
|
})?;
|
||||||
|
|
||||||
self.emptyoutput.compute(starting_indexes.height, &window_starts, exit, |v| {
|
self.emptyoutput
|
||||||
Ok(v.compute_count_from_indexes(
|
.compute(starting_indexes.height, &window_starts, exit, |v| {
|
||||||
starting_indexes.height,
|
Ok(v.compute_count_from_indexes(
|
||||||
&indexer.vecs.scripts.first_emptyoutputindex,
|
starting_indexes.height,
|
||||||
&indexer.vecs.scripts.empty_to_txindex,
|
&indexer.vecs.scripts.first_emptyoutputindex,
|
||||||
exit,
|
&indexer.vecs.scripts.empty_to_txindex,
|
||||||
)?)
|
exit,
|
||||||
})?;
|
)?)
|
||||||
|
})?;
|
||||||
|
|
||||||
// Compute segwit = p2wpkh + p2wsh + p2tr
|
// Compute segwit = p2wpkh + p2wsh + p2tr
|
||||||
self.segwit.compute(starting_indexes.height, &window_starts, exit, |v| {
|
self.segwit
|
||||||
Ok(v.compute_transform3(
|
.compute(starting_indexes.height, &window_starts, exit, |v| {
|
||||||
starting_indexes.height,
|
Ok(v.compute_transform3(
|
||||||
&self.p2wpkh.height,
|
starting_indexes.height,
|
||||||
&self.p2wsh.height,
|
&self.p2wpkh.height,
|
||||||
&self.p2tr.height,
|
&self.p2wsh.height,
|
||||||
|(h, p2wpkh, p2wsh, p2tr, ..)| {
|
&self.p2tr.height,
|
||||||
(h, StoredU64::from(*p2wpkh + *p2wsh + *p2tr))
|
|(h, p2wpkh, p2wsh, p2tr, ..)| (h, StoredU64::from(*p2wpkh + *p2wsh + *p2tr)),
|
||||||
},
|
exit,
|
||||||
exit,
|
)?)
|
||||||
)?)
|
})?;
|
||||||
})?;
|
|
||||||
|
|
||||||
// Adoption ratios: per-block ratio of script type / total outputs
|
// Adoption ratios: per-block ratio of script type / total outputs
|
||||||
self.taproot_adoption.height.compute_transform2(
|
self.taproot_adoption.height.compute_transform2(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&self.p2tr.height,
|
&self.p2tr.height,
|
||||||
&outputs_count.total_count.height.sum_cumulative.sum.0,
|
&outputs_count.total_count.full.sum_cumulative.sum.0,
|
||||||
|(h, p2tr, total, ..)| {
|
|(h, p2tr, total, ..)| {
|
||||||
let ratio = if *total > 0 {
|
let ratio = if *total > 0 {
|
||||||
StoredF32::from(*p2tr as f64 / *total as f64)
|
StoredF32::from(*p2tr as f64 / *total as f64)
|
||||||
@@ -159,7 +170,7 @@ impl Vecs {
|
|||||||
self.segwit_adoption.height.compute_transform2(
|
self.segwit_adoption.height.compute_transform2(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&self.segwit.height,
|
&self.segwit.height,
|
||||||
&outputs_count.total_count.height.sum_cumulative.sum.0,
|
&outputs_count.total_count.full.sum_cumulative.sum.0,
|
||||||
|(h, segwit, total, ..)| {
|
|(h, segwit, total, ..)| {
|
||||||
let ratio = if *total > 0 {
|
let ratio = if *total > 0 {
|
||||||
StoredF32::from(*segwit as f64 / *total as f64)
|
StoredF32::from(*segwit as f64 / *total as f64)
|
||||||
|
|||||||
@@ -31,14 +31,13 @@ impl Vecs {
|
|||||||
self.size
|
self.size
|
||||||
.compute(indexer, indexes, &blocks.count, starting_indexes, exit)?;
|
.compute(indexer, indexes, &blocks.count, starting_indexes, exit)?;
|
||||||
|
|
||||||
// Fees depends on size, blocks (window starts), prices (USD conversion)
|
// Fees depends on size, blocks (window starts)
|
||||||
self.fees.compute(
|
self.fees.compute(
|
||||||
indexer,
|
indexer,
|
||||||
indexes,
|
indexes,
|
||||||
inputs,
|
inputs,
|
||||||
&self.size,
|
&self.size,
|
||||||
blocks,
|
blocks,
|
||||||
prices,
|
|
||||||
starting_indexes,
|
starting_indexes,
|
||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
use brk_error::Result;
|
use brk_error::Result;
|
||||||
use brk_indexer::Indexer;
|
use brk_indexer::Indexer;
|
||||||
use brk_types::{Bitcoin, FeeRate, Sats};
|
use brk_types::{FeeRate, Sats};
|
||||||
use vecdb::{Exit, unlikely};
|
use vecdb::{Exit, unlikely};
|
||||||
|
|
||||||
use super::super::size;
|
use super::super::size;
|
||||||
use super::Vecs;
|
use super::Vecs;
|
||||||
use crate::{blocks, indexes, inputs, prices, ComputeIndexes};
|
use crate::{ComputeIndexes, blocks, indexes, inputs};
|
||||||
|
|
||||||
impl Vecs {
|
impl Vecs {
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
@@ -16,7 +16,6 @@ impl Vecs {
|
|||||||
txins: &inputs::Vecs,
|
txins: &inputs::Vecs,
|
||||||
size_vecs: &size::Vecs,
|
size_vecs: &size::Vecs,
|
||||||
blocks: &blocks::Vecs,
|
blocks: &blocks::Vecs,
|
||||||
prices: &prices::Vecs,
|
|
||||||
starting_indexes: &ComputeIndexes,
|
starting_indexes: &ComputeIndexes,
|
||||||
exit: &Exit,
|
exit: &Exit,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
@@ -36,7 +35,7 @@ impl Vecs {
|
|||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
self.fee_txindex.compute_transform2(
|
self.fee.txindex.compute_transform2(
|
||||||
starting_indexes.txindex,
|
starting_indexes.txindex,
|
||||||
&self.input_value,
|
&self.input_value,
|
||||||
&self.output_value,
|
&self.output_value,
|
||||||
@@ -51,57 +50,34 @@ impl Vecs {
|
|||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
self.fee_rate_txindex.compute_transform2(
|
self.fee_rate.txindex.compute_transform2(
|
||||||
starting_indexes.txindex,
|
starting_indexes.txindex,
|
||||||
&self.fee_txindex,
|
&self.fee.txindex,
|
||||||
&size_vecs.vsize.txindex,
|
&size_vecs.vsize.txindex,
|
||||||
|(txindex, fee, vsize, ..)| (txindex, FeeRate::from((fee, vsize))),
|
|(txindex, fee, vsize, ..)| (txindex, FeeRate::from((fee, vsize))),
|
||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
// Skip coinbase (first tx per block) since it has no fee
|
let block_windows = blocks.count.block_window_starts();
|
||||||
let window_starts = blocks.count.window_starts();
|
|
||||||
self.fee.compute(
|
|
||||||
starting_indexes.height,
|
|
||||||
&window_starts,
|
|
||||||
exit,
|
|
||||||
|full| {
|
|
||||||
full.compute_with_skip(
|
|
||||||
starting_indexes.height,
|
|
||||||
&self.fee_txindex,
|
|
||||||
&indexer.vecs.transactions.first_txindex,
|
|
||||||
&indexes.height.txindex_count,
|
|
||||||
exit,
|
|
||||||
1,
|
|
||||||
)
|
|
||||||
},
|
|
||||||
)?;
|
|
||||||
|
|
||||||
// Skip coinbase (first tx per block) since it has no feerate
|
// Skip coinbase (first tx per block) since it has fee=0
|
||||||
self.fee_rate.compute_with_skip(
|
self.fee.derive_from_with_skip(
|
||||||
starting_indexes.height,
|
indexer,
|
||||||
&self.fee_rate_txindex,
|
indexes,
|
||||||
&indexer.vecs.transactions.first_txindex,
|
starting_indexes,
|
||||||
&indexes.height.txindex_count,
|
&block_windows,
|
||||||
exit,
|
exit,
|
||||||
1,
|
1,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
// Compute fee USD sum per block: price * Bitcoin::from(sats)
|
// Skip coinbase (first tx per block) since it has no feerate
|
||||||
self.fee_usd_sum.compute_transform2(
|
self.fee_rate.derive_from_with_skip(
|
||||||
starting_indexes.height,
|
indexer,
|
||||||
self.fee.height.sum_cumulative.sum.inner(),
|
indexes,
|
||||||
&prices.usd.price,
|
starting_indexes,
|
||||||
|(h, sats, price, ..)| (h, price * Bitcoin::from(sats)),
|
&block_windows,
|
||||||
exit,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
// Rolling fee rate distribution (from per-block average)
|
|
||||||
self.fee_rate_rolling.compute_distribution(
|
|
||||||
starting_indexes.height,
|
|
||||||
&window_starts,
|
|
||||||
&self.fee_rate.average.0,
|
|
||||||
exit,
|
exit,
|
||||||
|
1,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@@ -3,30 +3,19 @@ use brk_types::Version;
|
|||||||
use vecdb::{Database, EagerVec, ImportableVec};
|
use vecdb::{Database, EagerVec, ImportableVec};
|
||||||
|
|
||||||
use super::Vecs;
|
use super::Vecs;
|
||||||
use crate::{
|
use crate::internal::ComputedFromTxDistribution;
|
||||||
indexes,
|
|
||||||
internal::{ComputedFromHeightFull, Distribution, RollingDistribution},
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Bump this when fee/feerate aggregation logic changes (e.g., skip coinbase).
|
/// Bump this when fee/feerate aggregation logic changes (e.g., skip coinbase).
|
||||||
const VERSION: Version = Version::new(2);
|
const VERSION: Version = Version::new(2);
|
||||||
|
|
||||||
impl Vecs {
|
impl Vecs {
|
||||||
pub(crate) fn forced_import(
|
pub(crate) fn forced_import(db: &Database, version: Version) -> Result<Self> {
|
||||||
db: &Database,
|
|
||||||
version: Version,
|
|
||||||
indexes: &indexes::Vecs,
|
|
||||||
) -> Result<Self> {
|
|
||||||
let v = version + VERSION;
|
let v = version + VERSION;
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
input_value: EagerVec::forced_import(db, "input_value", version)?,
|
input_value: EagerVec::forced_import(db, "input_value", version)?,
|
||||||
output_value: EagerVec::forced_import(db, "output_value", version)?,
|
output_value: EagerVec::forced_import(db, "output_value", version)?,
|
||||||
fee_txindex: EagerVec::forced_import(db, "fee", v)?,
|
fee: ComputedFromTxDistribution::forced_import(db, "fee", v)?,
|
||||||
fee: ComputedFromHeightFull::forced_import(db, "fee", v, indexes)?,
|
fee_rate: ComputedFromTxDistribution::forced_import(db, "fee_rate", v)?,
|
||||||
fee_usd_sum: EagerVec::forced_import(db, "fee_usd_sum", v)?,
|
|
||||||
fee_rate_txindex: EagerVec::forced_import(db, "fee_rate", v)?,
|
|
||||||
fee_rate: Distribution::forced_import(db, "fee_rate", v)?,
|
|
||||||
fee_rate_rolling: RollingDistribution::forced_import(db, "fee_rate", v, indexes)?,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,13 @@
|
|||||||
use brk_traversable::Traversable;
|
use brk_traversable::Traversable;
|
||||||
use brk_types::{Dollars, FeeRate, Height, Sats, TxIndex};
|
use brk_types::{FeeRate, Sats, TxIndex};
|
||||||
use vecdb::{EagerVec, PcoVec, Rw, StorageMode};
|
use vecdb::{EagerVec, PcoVec, Rw, StorageMode};
|
||||||
|
|
||||||
use crate::internal::{ComputedFromHeightFull, Distribution, RollingDistribution};
|
use crate::internal::ComputedFromTxDistribution;
|
||||||
|
|
||||||
#[derive(Traversable)]
|
#[derive(Traversable)]
|
||||||
pub struct Vecs<M: StorageMode = Rw> {
|
pub struct Vecs<M: StorageMode = Rw> {
|
||||||
pub input_value: M::Stored<EagerVec<PcoVec<TxIndex, Sats>>>,
|
pub input_value: M::Stored<EagerVec<PcoVec<TxIndex, Sats>>>,
|
||||||
pub output_value: M::Stored<EagerVec<PcoVec<TxIndex, Sats>>>,
|
pub output_value: M::Stored<EagerVec<PcoVec<TxIndex, Sats>>>,
|
||||||
pub fee_txindex: M::Stored<EagerVec<PcoVec<TxIndex, Sats>>>,
|
pub fee: ComputedFromTxDistribution<Sats, M>,
|
||||||
pub fee: ComputedFromHeightFull<Sats, M>,
|
pub fee_rate: ComputedFromTxDistribution<FeeRate, M>,
|
||||||
pub fee_usd_sum: M::Stored<EagerVec<PcoVec<Height, Dollars>>>,
|
|
||||||
pub fee_rate_txindex: M::Stored<EagerVec<PcoVec<TxIndex, FeeRate>>>,
|
|
||||||
pub fee_rate: Distribution<Height, FeeRate, M>,
|
|
||||||
pub fee_rate_rolling: RollingDistribution<FeeRate, M>,
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ impl Vecs {
|
|||||||
|
|
||||||
let count = CountVecs::forced_import(&db, version, indexer, indexes)?;
|
let count = CountVecs::forced_import(&db, version, indexer, indexes)?;
|
||||||
let size = SizeVecs::forced_import(&db, version, indexer)?;
|
let size = SizeVecs::forced_import(&db, version, indexer)?;
|
||||||
let fees = FeesVecs::forced_import(&db, version, indexes)?;
|
let fees = FeesVecs::forced_import(&db, version)?;
|
||||||
let versions = VersionsVecs::forced_import(&db, version, indexes)?;
|
let versions = VersionsVecs::forced_import(&db, version, indexes)?;
|
||||||
let volume = VolumeVecs::forced_import(&db, version, indexes)?;
|
let volume = VolumeVecs::forced_import(&db, version, indexes)?;
|
||||||
|
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ use brk_types::StoredF32;
|
|||||||
use vecdb::Exit;
|
use vecdb::Exit;
|
||||||
|
|
||||||
use super::Vecs;
|
use super::Vecs;
|
||||||
use crate::{blocks, ComputeIndexes, indexes, inputs, outputs, prices};
|
|
||||||
use crate::transactions::{count, fees};
|
use crate::transactions::{count, fees};
|
||||||
|
use crate::{ComputeIndexes, blocks, indexes, inputs, outputs, prices};
|
||||||
|
|
||||||
impl Vecs {
|
impl Vecs {
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
@@ -87,7 +87,7 @@ impl Vecs {
|
|||||||
// inputs_per_sec: per-block input count / block interval
|
// inputs_per_sec: per-block input count / block interval
|
||||||
self.inputs_per_sec.height.compute_transform2(
|
self.inputs_per_sec.height.compute_transform2(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&inputs_count.height.sum_cumulative.sum.0,
|
&inputs_count.full.sum_cumulative.sum.0,
|
||||||
&blocks.interval.height,
|
&blocks.interval.height,
|
||||||
|(h, input_count, interval, ..)| {
|
|(h, input_count, interval, ..)| {
|
||||||
let interval_f64 = f64::from(*interval);
|
let interval_f64 = f64::from(*interval);
|
||||||
@@ -104,7 +104,7 @@ impl Vecs {
|
|||||||
// outputs_per_sec: per-block output count / block interval
|
// outputs_per_sec: per-block output count / block interval
|
||||||
self.outputs_per_sec.height.compute_transform2(
|
self.outputs_per_sec.height.compute_transform2(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&outputs_count.total_count.height.sum_cumulative.sum.0,
|
&outputs_count.total_count.full.sum_cumulative.sum.0,
|
||||||
&blocks.interval.height,
|
&blocks.interval.height,
|
||||||
|(h, output_count, interval, ..)| {
|
|(h, output_count, interval, ..)| {
|
||||||
let interval_f64 = f64::from(*interval);
|
let interval_f64 = f64::from(*interval);
|
||||||
|
|||||||
@@ -9,11 +9,8 @@ use crate::internal::{
|
|||||||
/// Volume metrics
|
/// Volume metrics
|
||||||
#[derive(Traversable)]
|
#[derive(Traversable)]
|
||||||
pub struct Vecs<M: StorageMode = Rw> {
|
pub struct Vecs<M: StorageMode = Rw> {
|
||||||
#[traversable(flatten)]
|
|
||||||
pub sent_sum: ValueFromHeightLastRolling<M>,
|
pub sent_sum: ValueFromHeightLastRolling<M>,
|
||||||
#[traversable(flatten)]
|
|
||||||
pub received_sum: ValueFromHeightLastRolling<M>,
|
pub received_sum: ValueFromHeightLastRolling<M>,
|
||||||
#[traversable(flatten)]
|
|
||||||
pub annualized_volume: ValueFromHeightLast<M>,
|
pub annualized_volume: ValueFromHeightLast<M>,
|
||||||
pub tx_per_sec: ComputedFromHeightLast<StoredF32, M>,
|
pub tx_per_sec: ComputedFromHeightLast<StoredF32, M>,
|
||||||
pub outputs_per_sec: ComputedFromHeightLast<StoredF32, M>,
|
pub outputs_per_sec: ComputedFromHeightLast<StoredF32, M>,
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ impl Query {
|
|||||||
|
|
||||||
let iter = Day1Iter::new(computer, start, current_height.to_usize());
|
let iter = Day1Iter::new(computer, start, current_height.to_usize());
|
||||||
|
|
||||||
let cumulative = &computer.transactions.fees.fee.height.sum_cumulative.cumulative;
|
let cumulative = &computer.mining.rewards.fees.sats.cumulative.height;
|
||||||
let first_height = &computer.indexes.day1.first_height;
|
let first_height = &computer.indexes.day1.first_height;
|
||||||
|
|
||||||
Ok(iter.collect(|di, ts, h| {
|
Ok(iter.collect(|di, ts, h| {
|
||||||
@@ -30,7 +30,9 @@ impl Query {
|
|||||||
|
|
||||||
let cumulative_end = cumulative.collect_one_at(h_end.to_usize() - 1)?;
|
let cumulative_end = cumulative.collect_one_at(h_end.to_usize() - 1)?;
|
||||||
let cumulative_start = if h_start.to_usize() > 0 {
|
let cumulative_start = if h_start.to_usize() > 0 {
|
||||||
cumulative.collect_one_at(h_start.to_usize() - 1).unwrap_or(Sats::ZERO)
|
cumulative
|
||||||
|
.collect_one_at(h_start.to_usize() - 1)
|
||||||
|
.unwrap_or(Sats::ZERO)
|
||||||
} else {
|
} else {
|
||||||
Sats::ZERO
|
Sats::ZERO
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ impl Query {
|
|||||||
let start_block = Height::from(current_height.to_usize().saturating_sub(block_count - 1));
|
let start_block = Height::from(current_height.to_usize().saturating_sub(block_count - 1));
|
||||||
|
|
||||||
let coinbase_vec = &computer.mining.rewards.coinbase.sats.height;
|
let coinbase_vec = &computer.mining.rewards.coinbase.sats.height;
|
||||||
let fee_vec = &computer.transactions.fees.fee.height.sum_cumulative.sum.0;
|
let fee_vec = &computer.mining.rewards.fees.sats.height;
|
||||||
let tx_count_vec = &computer.transactions.count.tx_count.height;
|
let tx_count_vec = &computer.transactions.count.tx_count.height;
|
||||||
|
|
||||||
let start = start_block.to_usize();
|
let start = start_block.to_usize();
|
||||||
|
|||||||
+1015
-1006
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user