use brk_error::Result;
use brk_indexer::Indexer;
use brk_traversable::Traversable;
use brk_types::{PartsPerMillion32, PoolSlug};
use derive_more::{Deref, DerefMut};
use vecdb::{BinaryTransform, Database, Exit, Rw, StorageMode, Version};
use crate::{
indexes,
internal::{
CachedWindowStartVec, LazyPercentRollingWindows, MaskSats, ValuePerBlockCumulativeRolling,
Windows,
},
mining, price,
};
use super::minor;
#[derive(Deref, DerefMut, Traversable)]
pub struct Vecs<M: StorageMode = Rw> {
#[deref]
#[deref_mut]
#[traversable(flatten)]
pub base: minor::Vecs,
pub rewards: ValuePerBlockCumulativeRolling<M>,
#[traversable(rename = "dominance")]
pub dominance_rolling: LazyPercentRollingWindows<PartsPerMillion32>,
}
impl Vecs {
pub(crate) fn forced_import(
db: &Database,
slug: PoolSlug,
pool_heights: super::PoolHeights,
version: Version,
indexes: &indexes::Vecs,
cached_starts: &Windows<&CachedWindowStartVec>,
) -> Result<Self> {
let suffix = |s: &str| format!("{}_{s}", slug);
let base = minor::Vecs::forced_import(slug, pool_heights, version, indexes, cached_starts);
let rewards = ValuePerBlockCumulativeRolling::forced_import(
db,
&suffix("rewards"),
version,
indexes,
cached_starts,
)?;
let dominance_rolling = LazyPercentRollingWindows::from_uncached_cumulative_average(
&suffix("dominance"),
version,
&base.blocks_mined.cumulative.height,
cached_starts,
indexes,
);
Ok(Self {
base,
rewards,
dominance_rolling,
})
}
pub(crate) fn compute(
&mut self,
indexer: &Indexer,
prices: &price::Vecs,
mining: &mining::Vecs,
exit: &Exit,
) -> Result<()> {
let starting_height = indexer.safe_lengths().height;
self.rewards.compute_from_pair(
starting_height,
prices,
&self.base.blocks_mined.block,
&mining.rewards.coinbase.block.sats,
|_, mask, value| MaskSats::apply(mask, value),
exit,
)?;
Ok(())
}
}