mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-07-03 23:33:40 -07:00
global: snapshot
This commit is contained in:
@@ -1,8 +1,11 @@
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::{Cents, Dollars, Height, OHLCCents, OHLCDollars, OHLCSats, Sats};
|
||||
use vecdb::{LazyVecFrom1, PcoVec, Rw, StorageMode};
|
||||
use brk_types::{Cents, Dollars, OHLCCents, OHLCDollars, OHLCSats, Sats};
|
||||
use vecdb::{Rw, StorageMode};
|
||||
|
||||
use crate::internal::{ComputedHeightDerivedLast, EagerIndexes, LazyEagerIndexes};
|
||||
use crate::internal::{
|
||||
ComputedFromHeightLast, ComputedHeightDerivedLast, EagerIndexes, LazyEagerIndexes,
|
||||
LazyFromHeightLast,
|
||||
};
|
||||
|
||||
use super::ohlcs::{LazyOhlcVecs, OhlcVecs};
|
||||
|
||||
@@ -43,7 +46,7 @@ pub struct OhlcByUnit<M: StorageMode = Rw> {
|
||||
|
||||
#[derive(Traversable)]
|
||||
pub struct PriceByUnit<M: StorageMode = Rw> {
|
||||
pub cents: M::Stored<PcoVec<Height, Cents>>,
|
||||
pub usd: LazyVecFrom1<Height, Dollars, Height, Cents>,
|
||||
pub sats: LazyVecFrom1<Height, Sats, Height, Cents>,
|
||||
pub cents: ComputedFromHeightLast<Cents, M>,
|
||||
pub usd: LazyFromHeightLast<Dollars, Cents>,
|
||||
pub sats: LazyFromHeightLast<Sats, Cents>,
|
||||
}
|
||||
|
||||
@@ -22,15 +22,15 @@ impl Vecs {
|
||||
self.split
|
||||
.open
|
||||
.cents
|
||||
.compute_first(starting_indexes, &self.price.cents, indexes, exit)?;
|
||||
.compute_first(starting_indexes, &self.price.cents.height, indexes, exit)?;
|
||||
self.split
|
||||
.high
|
||||
.cents
|
||||
.compute_max(starting_indexes, &self.price.cents, indexes, exit)?;
|
||||
.compute_max(starting_indexes, &self.price.cents.height, indexes, exit)?;
|
||||
self.split
|
||||
.low
|
||||
.cents
|
||||
.compute_min(starting_indexes, &self.price.cents, indexes, exit)?;
|
||||
.compute_min(starting_indexes, &self.price.cents.height, indexes, exit)?;
|
||||
self.ohlc.cents.compute_from_split(
|
||||
starting_indexes,
|
||||
&self.split.open.cents,
|
||||
@@ -55,6 +55,7 @@ impl Vecs {
|
||||
indexer.vecs.outputs.value.version() + indexer.vecs.outputs.outputtype.version();
|
||||
self.price
|
||||
.cents
|
||||
.height
|
||||
.validate_computed_version_or_reset(source_version)?;
|
||||
|
||||
let total_heights = indexer.vecs.blocks.timestamp.len();
|
||||
@@ -64,27 +65,32 @@ impl Vecs {
|
||||
}
|
||||
|
||||
// Reorg: truncate to starting_indexes
|
||||
let truncate_to = self.price.cents.len().min(starting_indexes.height.to_usize());
|
||||
self.price.cents.truncate_if_needed_at(truncate_to)?;
|
||||
let truncate_to = self
|
||||
.price
|
||||
.cents
|
||||
.height
|
||||
.len()
|
||||
.min(starting_indexes.height.to_usize());
|
||||
self.price.cents.height.truncate_if_needed_at(truncate_to)?;
|
||||
|
||||
if self.price.cents.len() < START_HEIGHT {
|
||||
for line in brk_oracle::PRICES.lines().skip(self.price.cents.len()) {
|
||||
if self.price.cents.len() >= START_HEIGHT {
|
||||
if self.price.cents.height.len() < START_HEIGHT {
|
||||
for line in brk_oracle::PRICES.lines().skip(self.price.cents.height.len()) {
|
||||
if self.price.cents.height.len() >= START_HEIGHT {
|
||||
break;
|
||||
}
|
||||
let dollars: f64 = line.parse().unwrap_or(0.0);
|
||||
let cents = (dollars * 100.0).round() as u64;
|
||||
self.price.cents.push(Cents::new(cents));
|
||||
self.price.cents.height.push(Cents::new(cents));
|
||||
}
|
||||
}
|
||||
|
||||
if self.price.cents.len() >= total_heights {
|
||||
if self.price.cents.height.len() >= total_heights {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let config = Config::default();
|
||||
let committed = self.price.cents.len();
|
||||
let prev_cents = self.price.cents.collect_one_at(committed - 1).unwrap();
|
||||
let committed = self.price.cents.height.len();
|
||||
let prev_cents = self.price.cents.height.collect_one_at(committed - 1).unwrap();
|
||||
let seed_bin = cents_to_bin(prev_cents.inner() as f64);
|
||||
let warmup = config.window_size.min(committed - START_HEIGHT);
|
||||
let mut oracle = Oracle::from_checkpoint(seed_bin, config, |o| {
|
||||
@@ -100,7 +106,7 @@ impl Vecs {
|
||||
let ref_bins = Self::feed_blocks(&mut oracle, indexer, committed..total_heights);
|
||||
|
||||
for (i, ref_bin) in ref_bins.into_iter().enumerate() {
|
||||
self.price.cents.push(Cents::new(bin_to_cents(ref_bin)));
|
||||
self.price.cents.height.push(Cents::new(bin_to_cents(ref_bin)));
|
||||
|
||||
let progress = ((i + 1) * 100 / num_new) as u8;
|
||||
if i > 0 && progress > ((i * 100 / num_new) as u8) {
|
||||
@@ -110,10 +116,13 @@ impl Vecs {
|
||||
|
||||
{
|
||||
let _lock = exit.lock();
|
||||
self.price.cents.write()?;
|
||||
self.price.cents.height.write()?;
|
||||
}
|
||||
|
||||
info!("Oracle prices complete: {} committed", self.price.cents.len());
|
||||
info!(
|
||||
"Oracle prices complete: {} committed",
|
||||
self.price.cents.height.len()
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -201,7 +210,12 @@ impl<M: StorageMode> Vecs<M> {
|
||||
pub fn live_oracle<IM: StorageMode>(&self, indexer: &Indexer<IM>) -> Result<Oracle> {
|
||||
let config = Config::default();
|
||||
let height = indexer.vecs.blocks.timestamp.len();
|
||||
let last_cents = self.price.cents.collect_one_at(self.price.cents.len() - 1).unwrap();
|
||||
let last_cents = self
|
||||
.price
|
||||
.cents
|
||||
.height
|
||||
.collect_one_at(self.price.cents.height.len() - 1)
|
||||
.unwrap();
|
||||
let seed_bin = cents_to_bin(last_cents.inner() as f64);
|
||||
let window_size = config.window_size;
|
||||
let oracle = Oracle::from_checkpoint(seed_bin, config, |o| {
|
||||
|
||||
@@ -6,16 +6,14 @@ use std::path::Path;
|
||||
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::Version;
|
||||
use vecdb::{
|
||||
Database, ImportableVec, LazyVecFrom1, PcoVec, ReadableCloneableVec, Rw, StorageMode,
|
||||
PAGE_SIZE,
|
||||
};
|
||||
use vecdb::{Database, ReadableCloneableVec, Rw, StorageMode, PAGE_SIZE};
|
||||
|
||||
use crate::{
|
||||
indexes,
|
||||
internal::{
|
||||
CentsUnsignedToDollars, CentsUnsignedToSats, ComputedHeightDerivedLast, EagerIndexes,
|
||||
LazyEagerIndexes, OhlcCentsToDollars, OhlcCentsToSats,
|
||||
CentsUnsignedToDollars, CentsUnsignedToSats, ComputedFromHeightLast,
|
||||
ComputedHeightDerivedLast, EagerIndexes, LazyEagerIndexes, LazyFromHeightLast,
|
||||
OhlcCentsToDollars, OhlcCentsToSats,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -66,7 +64,8 @@ impl Vecs {
|
||||
|
||||
// ── Cents (eager, stored) ───────────────────────────────────
|
||||
|
||||
let price_cents = PcoVec::forced_import(db, "price_cents", version)?;
|
||||
let price_cents =
|
||||
ComputedFromHeightLast::forced_import(db, "price_cents", version, indexes)?;
|
||||
|
||||
let open_cents = EagerIndexes::forced_import(db, "price_open_cents", version)?;
|
||||
let high_cents = EagerIndexes::forced_import(db, "price_high_cents", version)?;
|
||||
@@ -74,7 +73,7 @@ impl Vecs {
|
||||
|
||||
let close_cents = ComputedHeightDerivedLast::forced_import(
|
||||
"price_close_cents",
|
||||
price_cents.read_only_boxed_clone(),
|
||||
price_cents.height.read_only_boxed_clone(),
|
||||
version,
|
||||
indexes,
|
||||
);
|
||||
@@ -83,10 +82,11 @@ impl Vecs {
|
||||
|
||||
// ── USD (lazy from cents) ───────────────────────────────────
|
||||
|
||||
let price_usd = LazyVecFrom1::transformed::<CentsUnsignedToDollars>(
|
||||
let price_usd = LazyFromHeightLast::from_computed::<CentsUnsignedToDollars>(
|
||||
"price",
|
||||
version,
|
||||
price_cents.read_only_boxed_clone(),
|
||||
price_cents.height.read_only_boxed_clone(),
|
||||
&price_cents,
|
||||
);
|
||||
|
||||
let open_usd = LazyEagerIndexes::from_eager_indexes::<CentsUnsignedToDollars>(
|
||||
@@ -107,7 +107,7 @@ impl Vecs {
|
||||
|
||||
let close_usd = ComputedHeightDerivedLast::forced_import(
|
||||
"price_close",
|
||||
price_usd.read_only_boxed_clone(),
|
||||
price_usd.height.read_only_boxed_clone(),
|
||||
version,
|
||||
indexes,
|
||||
);
|
||||
@@ -120,10 +120,11 @@ impl Vecs {
|
||||
|
||||
// ── Sats (lazy from cents, high↔low swapped) ───────────────
|
||||
|
||||
let price_sats = LazyVecFrom1::transformed::<CentsUnsignedToSats>(
|
||||
let price_sats = LazyFromHeightLast::from_computed::<CentsUnsignedToSats>(
|
||||
"price_sats",
|
||||
version,
|
||||
price_cents.read_only_boxed_clone(),
|
||||
price_cents.height.read_only_boxed_clone(),
|
||||
&price_cents,
|
||||
);
|
||||
|
||||
let open_sats = LazyEagerIndexes::from_eager_indexes::<CentsUnsignedToSats>(
|
||||
@@ -145,7 +146,7 @@ impl Vecs {
|
||||
|
||||
let close_sats = ComputedHeightDerivedLast::forced_import(
|
||||
"price_close_sats",
|
||||
price_sats.read_only_boxed_clone(),
|
||||
price_sats.height.read_only_boxed_clone(),
|
||||
version,
|
||||
indexes,
|
||||
);
|
||||
|
||||
@@ -10,7 +10,7 @@ use schemars::JsonSchema;
|
||||
use serde::Serialize;
|
||||
use vecdb::{
|
||||
BytesVec, BytesVecValue, Database, EagerVec, Exit, Formattable, ImportableVec, LazyVecFrom1,
|
||||
ReadableCloneableVec, Rw, StorageMode, UnaryTransform,
|
||||
ReadableCloneableVec, ReadableVec, Rw, StorageMode, UnaryTransform,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
@@ -47,7 +47,7 @@ pub struct OhlcVecs<T, M: StorageMode = Rw>(
|
||||
where
|
||||
T: BytesVecValue + Formattable + Serialize + JsonSchema;
|
||||
|
||||
const EAGER_VERSION: Version = Version::ZERO;
|
||||
const EAGER_VERSION: Version = Version::ONE;
|
||||
|
||||
impl<T> OhlcVecs<T>
|
||||
where
|
||||
@@ -84,14 +84,22 @@ impl OhlcVecs<OHLCCents> {
|
||||
&high.$field,
|
||||
&low.$field,
|
||||
&close.$field,
|
||||
|(idx, o, h, l, c, _)| {
|
||||
|(idx, o, h, l, c, this)| {
|
||||
(
|
||||
idx,
|
||||
OHLCCents {
|
||||
open: Open::new(o),
|
||||
high: High::new(h),
|
||||
low: Low::new(l),
|
||||
close: Close::new(c.unwrap_or_default()),
|
||||
if let Some(c) = c {
|
||||
OHLCCents {
|
||||
open: Open::new(o),
|
||||
high: High::new(h),
|
||||
low: Low::new(l),
|
||||
close: Close::new(c),
|
||||
}
|
||||
} else {
|
||||
// Empty period (no blocks): flat candle at previous close
|
||||
let prev_close = Close::new(
|
||||
this.collect_last().map_or(o, |prev| *prev.close),
|
||||
);
|
||||
OHLCCents::from(prev_close)
|
||||
},
|
||||
)
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user