mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-04-26 15:49:58 -07:00
computer: snapshot
This commit is contained in:
@@ -29,7 +29,7 @@ where
|
||||
S1T: ComputedVecValue,
|
||||
S2T: ComputedVecValue,
|
||||
{
|
||||
#[traversable(wrap = "sum")]
|
||||
#[traversable(rename = "sum")]
|
||||
pub height: LazyVecFrom2<Height, T, Height, S1T, Height, S2T>,
|
||||
#[deref]
|
||||
#[deref_mut]
|
||||
|
||||
@@ -21,7 +21,7 @@ pub struct ComputedBlockSumCum<T>
|
||||
where
|
||||
T: ComputedVecValue + PartialOrd + JsonSchema,
|
||||
{
|
||||
#[traversable(wrap = "sum")]
|
||||
#[traversable(rename = "sum")]
|
||||
pub height: EagerVec<PcoVec<Height, T>>,
|
||||
#[deref]
|
||||
#[deref_mut]
|
||||
|
||||
@@ -20,7 +20,7 @@ where
|
||||
S1T: ComputedVecValue,
|
||||
S2T: ComputedVecValue,
|
||||
{
|
||||
#[traversable(wrap = "sum")]
|
||||
#[traversable(rename = "sum")]
|
||||
pub height: LazyVecFrom2<Height, T, Height, S1T, Height, S2T>,
|
||||
#[deref]
|
||||
#[deref_mut]
|
||||
|
||||
@@ -21,7 +21,7 @@ where
|
||||
S1T: ComputedVecValue,
|
||||
S2T: ComputedVecValue,
|
||||
{
|
||||
#[traversable(wrap = "sum")]
|
||||
#[traversable(rename = "sum")]
|
||||
pub height: LazyVecFrom2<Height, T, Height, S1T, Height, S2T>,
|
||||
#[traversable(rename = "cumulative")]
|
||||
pub height_cumulative: LazyVecFrom2<Height, T, Height, S1T, Height, S2T>,
|
||||
|
||||
@@ -18,7 +18,7 @@ where
|
||||
T: ComputedVecValue + PartialOrd + JsonSchema,
|
||||
S1T: ComputedVecValue,
|
||||
{
|
||||
#[traversable(wrap = "sum")]
|
||||
#[traversable(rename = "sum")]
|
||||
pub height: LazyVecFrom1<Height, T, Height, S1T>,
|
||||
#[deref]
|
||||
#[deref_mut]
|
||||
|
||||
@@ -11,7 +11,7 @@ use vecdb::{
|
||||
use crate::internal::{ComputedVecValue, LastVec, LazyLast};
|
||||
|
||||
#[derive(Clone, Deref, DerefMut, Traversable)]
|
||||
#[traversable(wrap = "last")]
|
||||
#[traversable(transparent)]
|
||||
pub struct LazyTransformLast<I, T, S1T = T>(pub LazyVecFrom1<I, T, I, S1T>)
|
||||
where
|
||||
I: VecIndex,
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
//! Lazy binary value wrapper combining height (with price) + difficultyepoch + date last transforms.
|
||||
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::{Bitcoin, Close, Dollars, Sats, Version};
|
||||
use derive_more::{Deref, DerefMut};
|
||||
use vecdb::{BinaryTransform, IterableCloneableVec, UnaryTransform};
|
||||
|
||||
use super::{LazyBlockValue, LazyTransformedValueDifficultyEpoch};
|
||||
use crate::internal::LazyValueDateLast;
|
||||
use crate::{internal::ValueBlockLast, price};
|
||||
|
||||
const VERSION: Version = Version::ZERO;
|
||||
|
||||
/// Lazy binary value wrapper with height (using price binary transform) + difficultyepoch + date last transforms.
|
||||
///
|
||||
/// Use this when the height-level dollars need a binary transform (e.g., price × sats)
|
||||
/// rather than a unary transform from existing dollars.
|
||||
///
|
||||
/// No merge at this level - denominations (sats, bitcoin, dollars) stay as separate branches.
|
||||
/// Each inner field has merge which combines indexes within each denomination.
|
||||
#[derive(Clone, Deref, DerefMut, Traversable)]
|
||||
pub struct LazyBinaryLastBlockValue {
|
||||
#[traversable(flatten)]
|
||||
pub height: LazyBlockValue,
|
||||
#[traversable(flatten)]
|
||||
pub difficultyepoch: LazyTransformedValueDifficultyEpoch,
|
||||
#[deref]
|
||||
#[deref_mut]
|
||||
#[traversable(flatten)]
|
||||
pub dates: LazyValueDateLast,
|
||||
}
|
||||
|
||||
impl LazyBinaryLastBlockValue {
|
||||
pub fn from_block_source<SatsTransform, BitcoinTransform, HeightDollarsTransform, DateDollarsTransform>(
|
||||
name: &str,
|
||||
source: &ValueBlockLast,
|
||||
price: Option<&price::Vecs>,
|
||||
version: Version,
|
||||
) -> Self
|
||||
where
|
||||
SatsTransform: UnaryTransform<Sats, Sats>,
|
||||
BitcoinTransform: UnaryTransform<Sats, Bitcoin>,
|
||||
HeightDollarsTransform: BinaryTransform<Close<Dollars>, Sats, Dollars>,
|
||||
DateDollarsTransform: UnaryTransform<Dollars, Dollars>,
|
||||
{
|
||||
let v = version + VERSION;
|
||||
|
||||
let price_source = price.map(|p| p.usd.split.close.height.boxed_clone());
|
||||
|
||||
let height = LazyBlockValue::from_sources::<SatsTransform, BitcoinTransform, HeightDollarsTransform>(
|
||||
name,
|
||||
source.sats.height.boxed_clone(),
|
||||
price_source,
|
||||
v,
|
||||
);
|
||||
|
||||
let difficultyepoch = LazyTransformedValueDifficultyEpoch::from_block_source::<
|
||||
SatsTransform,
|
||||
BitcoinTransform,
|
||||
HeightDollarsTransform,
|
||||
>(name, source, price, v);
|
||||
|
||||
let dates = LazyValueDateLast::from_block_source::<SatsTransform, BitcoinTransform, DateDollarsTransform>(
|
||||
name, source, v,
|
||||
);
|
||||
|
||||
Self { height, difficultyepoch, dates }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
//! Fully lazy value types for DifficultyEpoch indexing.
|
||||
//!
|
||||
//! Two variants exist for different source patterns:
|
||||
//! - `LazyValueDifficultyEpochFromHeight`: For sources without dollars (computes from price × sats)
|
||||
//! - `LazyTransformedValueDifficultyEpoch`: For transformed views (e.g., halved supply)
|
||||
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::{Bitcoin, Close, DifficultyEpoch, Dollars, Height, Sats, Version};
|
||||
use vecdb::{BinaryTransform, IterableBoxedVec, IterableCloneableVec, LazyVecFrom1, LazyVecFrom2, UnaryTransform};
|
||||
|
||||
use crate::internal::{ClosePriceTimesSats, LazyLast, SatsToBitcoin};
|
||||
use crate::price;
|
||||
|
||||
const VERSION: Version = Version::ZERO;
|
||||
|
||||
/// Lazy value type at difficultyepoch level - computed from height sats + price.
|
||||
///
|
||||
/// Use this when the source only has height-indexed sats (e.g., ValueBlockDateLast).
|
||||
/// Dollars are computed via price × sats binary transform.
|
||||
#[derive(Clone, Traversable)]
|
||||
pub struct LazyValueDifficultyEpochFromHeight {
|
||||
pub sats: LazyLast<DifficultyEpoch, Sats, Height, DifficultyEpoch>,
|
||||
pub bitcoin: LazyVecFrom1<DifficultyEpoch, Bitcoin, DifficultyEpoch, Sats>,
|
||||
pub dollars: Option<LazyVecFrom2<DifficultyEpoch, Dollars, DifficultyEpoch, Close<Dollars>, DifficultyEpoch, Sats>>,
|
||||
}
|
||||
|
||||
impl LazyValueDifficultyEpochFromHeight {
|
||||
/// Create from height sats source and difficultyepoch identity.
|
||||
/// Bitcoin is derived from sats. Dollars are computed from price × sats.
|
||||
pub fn from_height_source(
|
||||
name: &str,
|
||||
height_sats: IterableBoxedVec<Height, Sats>,
|
||||
difficultyepoch_identity: IterableBoxedVec<DifficultyEpoch, DifficultyEpoch>,
|
||||
price: Option<&price::Vecs>,
|
||||
version: Version,
|
||||
) -> Self {
|
||||
let v = version + VERSION;
|
||||
|
||||
let sats = LazyLast::from_source(name, v, height_sats, difficultyepoch_identity);
|
||||
|
||||
let bitcoin = LazyVecFrom1::transformed::<SatsToBitcoin>(
|
||||
&format!("{name}_btc"),
|
||||
v,
|
||||
sats.boxed_clone(),
|
||||
);
|
||||
|
||||
let dollars = price.map(|p| {
|
||||
LazyVecFrom2::transformed::<ClosePriceTimesSats>(
|
||||
&format!("{name}_usd"),
|
||||
v,
|
||||
p.usd.split.close.difficultyepoch.boxed_clone(),
|
||||
sats.boxed_clone(),
|
||||
)
|
||||
});
|
||||
|
||||
Self { sats, bitcoin, dollars }
|
||||
}
|
||||
}
|
||||
|
||||
/// Lazy value type at difficultyepoch level - transformed from existing difficultyepoch sources.
|
||||
///
|
||||
/// Use this when creating transformed views (e.g., halved supply) from sources that
|
||||
/// already have difficultyepoch aggregations. Applies transforms to the existing aggregations.
|
||||
#[derive(Clone, Traversable)]
|
||||
pub struct LazyTransformedValueDifficultyEpoch {
|
||||
pub sats: LazyVecFrom1<DifficultyEpoch, Sats, DifficultyEpoch, Sats>,
|
||||
pub bitcoin: LazyVecFrom1<DifficultyEpoch, Bitcoin, DifficultyEpoch, Sats>,
|
||||
pub dollars: Option<LazyVecFrom2<DifficultyEpoch, Dollars, DifficultyEpoch, Close<Dollars>, DifficultyEpoch, Sats>>,
|
||||
}
|
||||
|
||||
impl LazyTransformedValueDifficultyEpoch {
|
||||
/// Create transformed difficultyepoch values from a ValueBlockLast source.
|
||||
/// SatsTransform is applied to the source's difficultyepoch sats.
|
||||
/// BitcoinTransform converts source sats to bitcoin (should combine sats transform + conversion).
|
||||
/// Dollars are computed from price × transformed sats.
|
||||
pub fn from_block_source<SatsTransform, BitcoinTransform, DollarsTransform>(
|
||||
name: &str,
|
||||
source: &super::ValueBlockLast,
|
||||
price: Option<&price::Vecs>,
|
||||
version: Version,
|
||||
) -> Self
|
||||
where
|
||||
SatsTransform: UnaryTransform<Sats, Sats>,
|
||||
BitcoinTransform: UnaryTransform<Sats, Bitcoin>,
|
||||
DollarsTransform: BinaryTransform<Close<Dollars>, Sats, Dollars>,
|
||||
{
|
||||
let v = version + VERSION;
|
||||
|
||||
let sats = LazyVecFrom1::transformed::<SatsTransform>(
|
||||
name,
|
||||
v,
|
||||
source.sats.rest.difficultyepoch.boxed_clone(),
|
||||
);
|
||||
|
||||
let bitcoin = LazyVecFrom1::transformed::<BitcoinTransform>(
|
||||
&format!("{name}_btc"),
|
||||
v,
|
||||
source.sats.rest.difficultyepoch.boxed_clone(),
|
||||
);
|
||||
|
||||
let dollars = price.map(|p| {
|
||||
LazyVecFrom2::transformed::<DollarsTransform>(
|
||||
&format!("{name}_usd"),
|
||||
v,
|
||||
p.usd.split.close.difficultyepoch.boxed_clone(),
|
||||
source.sats.rest.difficultyepoch.boxed_clone(),
|
||||
)
|
||||
});
|
||||
|
||||
Self { sats, bitcoin, dollars }
|
||||
}
|
||||
}
|
||||
@@ -3,8 +3,10 @@ mod full;
|
||||
mod height;
|
||||
mod last;
|
||||
mod lazy;
|
||||
mod lazy_binary_last;
|
||||
mod lazy_computed_sum_cum;
|
||||
mod lazy_derived;
|
||||
mod lazy_difficultyepoch;
|
||||
mod lazy_height;
|
||||
mod lazy_last;
|
||||
mod lazy_sum_cum;
|
||||
@@ -16,8 +18,10 @@ pub use full::*;
|
||||
pub use height::*;
|
||||
pub use last::*;
|
||||
pub use lazy::*;
|
||||
pub use lazy_binary_last::*;
|
||||
pub use lazy_computed_sum_cum::*;
|
||||
pub use lazy_derived::*;
|
||||
pub use lazy_difficultyepoch::*;
|
||||
pub use lazy_height::*;
|
||||
pub use lazy_last::*;
|
||||
pub use lazy_sum_cum::*;
|
||||
|
||||
@@ -5,26 +5,26 @@
|
||||
|
||||
use brk_error::Result;
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::{DifficultyEpoch, Height, Sats, Version};
|
||||
use brk_types::{Height, Sats, Version};
|
||||
use derive_more::{Deref, DerefMut};
|
||||
use vecdb::{Database, EagerVec, Exit, ImportableVec, IterableCloneableVec, PcoVec};
|
||||
|
||||
use crate::{ComputeIndexes, indexes, price};
|
||||
|
||||
use super::super::block::LazyDerivedBlockValue;
|
||||
use super::super::block::{LazyDerivedBlockValue, LazyValueDifficultyEpochFromHeight};
|
||||
use super::ValueDateLast;
|
||||
use crate::internal::LazyLast;
|
||||
|
||||
/// Value type where both height and dateindex are stored independently.
|
||||
/// Dateindex values cannot be derived from height (e.g., unrealized P&L).
|
||||
#[derive(Clone, Deref, DerefMut, Traversable)]
|
||||
#[traversable(merge)]
|
||||
pub struct ValueBlockDateLast {
|
||||
#[traversable(wrap = "sats")]
|
||||
#[traversable(rename = "sats")]
|
||||
pub height: EagerVec<PcoVec<Height, Sats>>,
|
||||
#[traversable(flatten)]
|
||||
pub height_value: LazyDerivedBlockValue,
|
||||
pub difficultyepoch: LazyLast<DifficultyEpoch, Sats, Height, DifficultyEpoch>,
|
||||
#[traversable(flatten)]
|
||||
pub difficultyepoch: LazyValueDifficultyEpochFromHeight,
|
||||
#[deref]
|
||||
#[deref_mut]
|
||||
#[traversable(flatten)]
|
||||
@@ -51,11 +51,12 @@ impl ValueBlockDateLast {
|
||||
let height_value =
|
||||
LazyDerivedBlockValue::from_source(name, height.boxed_clone(), v, price_source);
|
||||
|
||||
let difficultyepoch = LazyLast::from_source(
|
||||
let difficultyepoch = LazyValueDifficultyEpochFromHeight::from_height_source(
|
||||
name,
|
||||
v,
|
||||
height.boxed_clone(),
|
||||
indexes.difficultyepoch.identity.boxed_clone(),
|
||||
price,
|
||||
v,
|
||||
);
|
||||
|
||||
let indexes = ValueDateLast::forced_import(db, name, v, compute_dollars, indexes)?;
|
||||
|
||||
@@ -14,9 +14,8 @@ use super::ValueDerivedTxFull;
|
||||
const VERSION: Version = Version::ZERO;
|
||||
|
||||
#[derive(Clone, Deref, DerefMut, Traversable)]
|
||||
#[traversable(merge)]
|
||||
pub struct ValueTxFull {
|
||||
#[traversable(wrap = "sats")]
|
||||
#[traversable(rename = "txindex")]
|
||||
pub base: EagerVec<PcoVec<TxIndex, Sats>>,
|
||||
#[deref]
|
||||
#[deref_mut]
|
||||
|
||||
Reference in New Issue
Block a user