use brk_indexer::Indexer;
use brk_types::{Epoch, Height, PartsPerMillionSigned32, StoredF64, StoredU32, Version};
use vecdb::ReadOnlyClone;
use super::Vecs;
use crate::{
indexes,
internal::{
BlocksToDaysF32, DifficultyToHashF64, Identity, LazyPerBlock, LazyPercentPerBlock,
Resolutions,
},
};
const DIFFICULTY_ADJUSTMENT_LOOKBACK: usize = 2016;
fn blocks_left_to_retarget(height: Height, _: Epoch) -> StoredU32 {
StoredU32::from(height.left_before_next_diff_adj())
}
fn difficulty_adjustment(
current: StoredF64,
previous: Option<StoredF64>,
) -> PartsPerMillionSigned32 {
match previous {
Some(previous) => {
PartsPerMillionSigned32::from((f32::from(current) / f32::from(previous)) - 1.0)
}
None => PartsPerMillionSigned32::from(f32::NAN),
}
}
impl Vecs {
pub(crate) fn new(version: Version, indexer: &Indexer, indexes: &indexes::Vecs) -> Self {
let v2 = Version::TWO;
let hashrate = LazyPerBlock::from_height_source::<DifficultyToHashF64, _>(
"difficulty_hashrate",
version,
indexer.vecs.blocks.difficulty.read_only_clone(),
indexes,
);
let epoch = LazyPerBlock::from_height_source::<Identity<Epoch>, _>(
"difficulty_epoch",
version,
indexes.height.epoch.read_only_clone(),
indexes,
);
let blocks_to_retarget = LazyPerBlock::from_indexed_source(
"blocks_to_retarget",
version + v2,
&indexes.height.epoch,
blocks_left_to_retarget,
indexes,
);
let days_to_retarget = LazyPerBlock::from_lazy::<BlocksToDaysF32, StoredU32>(
"days_to_retarget",
version + v2,
&blocks_to_retarget,
);
Self {
value: Resolutions::forced_import(
"difficulty",
indexer.vecs.blocks.difficulty.read_only_clone(),
version,
indexes,
),
hashrate,
adjustment: LazyPercentPerBlock::from_lookback_source(
"difficulty_adjustment",
version + Version::ONE,
&indexer.vecs.blocks.difficulty,
DIFFICULTY_ADJUSTMENT_LOOKBACK,
difficulty_adjustment,
indexes,
),
epoch,
blocks_to_retarget,
days_to_retarget,
}
}
}