mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-04-24 06:39:58 -07:00
global: snapshot
This commit is contained in:
@@ -5,15 +5,15 @@ use brk_types::{LoadedAddressData, OutputType, TypeIndex};
|
||||
use super::super::address::AddressTypeToTypeIndexMap;
|
||||
use super::{EmptyAddressDataWithSource, LoadedAddressDataWithSource, WithAddressDataSource};
|
||||
|
||||
/// Source of an address in lookup - reports where the data came from.
|
||||
/// Tracking status of an address - determines cohort update strategy.
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum AddressSource {
|
||||
pub enum TrackingStatus {
|
||||
/// Brand new address (never seen before)
|
||||
New,
|
||||
/// Loaded from disk (has existing balance)
|
||||
Loaded,
|
||||
/// Was empty (zero balance), now receiving
|
||||
FromEmpty,
|
||||
/// Already tracked in a cohort (has existing balance)
|
||||
Tracked,
|
||||
/// Was in empty cache, now rejoining a cohort
|
||||
WasEmpty,
|
||||
}
|
||||
|
||||
/// Context for looking up and storing address data during block processing.
|
||||
@@ -27,7 +27,7 @@ impl<'a> AddressLookup<'a> {
|
||||
&mut self,
|
||||
output_type: OutputType,
|
||||
type_index: TypeIndex,
|
||||
) -> (&mut LoadedAddressDataWithSource, AddressSource) {
|
||||
) -> (&mut LoadedAddressDataWithSource, TrackingStatus) {
|
||||
use std::collections::hash_map::Entry;
|
||||
|
||||
let map = self.loaded.get_mut(output_type).unwrap();
|
||||
@@ -40,36 +40,38 @@ impl<'a> AddressLookup<'a> {
|
||||
// - If wrapper is New AND funded_txo_count == 0: hasn't received yet,
|
||||
// was just created in process_outputs this block → New
|
||||
// - If wrapper is New AND funded_txo_count > 0: received in previous
|
||||
// block but still in cache (no flush) → Loaded
|
||||
// - If wrapper is FromLoaded/FromEmpty: loaded from storage → use wrapper
|
||||
let source = match entry.get() {
|
||||
// block but still in cache (no flush) → Tracked
|
||||
// - If wrapper is FromLoaded: loaded from storage → Tracked
|
||||
// - If wrapper is FromEmpty AND utxo_count == 0: still empty → WasEmpty
|
||||
// - If wrapper is FromEmpty AND utxo_count > 0: already received → Tracked
|
||||
let status = match entry.get() {
|
||||
WithAddressDataSource::New(data) => {
|
||||
if data.funded_txo_count == 0 {
|
||||
AddressSource::New
|
||||
TrackingStatus::New
|
||||
} else {
|
||||
AddressSource::Loaded
|
||||
TrackingStatus::Tracked
|
||||
}
|
||||
}
|
||||
WithAddressDataSource::FromLoaded(..) => AddressSource::Loaded,
|
||||
WithAddressDataSource::FromLoaded(..) => TrackingStatus::Tracked,
|
||||
WithAddressDataSource::FromEmpty(_, data) => {
|
||||
if data.utxo_count() == 0 {
|
||||
AddressSource::FromEmpty
|
||||
TrackingStatus::WasEmpty
|
||||
} else {
|
||||
AddressSource::Loaded
|
||||
TrackingStatus::Tracked
|
||||
}
|
||||
}
|
||||
};
|
||||
(entry.into_mut(), source)
|
||||
(entry.into_mut(), status)
|
||||
}
|
||||
Entry::Vacant(entry) => {
|
||||
if let Some(empty_data) =
|
||||
self.empty.get_mut(output_type).unwrap().remove(&type_index)
|
||||
{
|
||||
return (entry.insert(empty_data.into()), AddressSource::FromEmpty);
|
||||
return (entry.insert(empty_data.into()), TrackingStatus::WasEmpty);
|
||||
}
|
||||
(
|
||||
entry.insert(WithAddressDataSource::New(LoadedAddressData::default())),
|
||||
AddressSource::New,
|
||||
TrackingStatus::New,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ use rustc_hash::FxHashMap;
|
||||
|
||||
use super::super::address::AddressTypeToVec;
|
||||
use super::super::cohorts::AddressCohorts;
|
||||
use super::lookup::{AddressLookup, AddressSource};
|
||||
use super::lookup::{AddressLookup, TrackingStatus};
|
||||
|
||||
pub fn process_received(
|
||||
received_data: AddressTypeToVec<(TypeIndex, Sats)>,
|
||||
@@ -31,23 +31,23 @@ pub fn process_received(
|
||||
}
|
||||
|
||||
for (type_index, (total_value, output_count)) in aggregated {
|
||||
let (addr_data, source) = lookup.get_or_create_for_receive(output_type, type_index);
|
||||
let (addr_data, status) = lookup.get_or_create_for_receive(output_type, type_index);
|
||||
|
||||
match source {
|
||||
AddressSource::New => {
|
||||
match status {
|
||||
TrackingStatus::New => {
|
||||
*addr_count.get_mut(output_type).unwrap() += 1;
|
||||
}
|
||||
AddressSource::FromEmpty => {
|
||||
TrackingStatus::WasEmpty => {
|
||||
*addr_count.get_mut(output_type).unwrap() += 1;
|
||||
*empty_addr_count.get_mut(output_type).unwrap() -= 1;
|
||||
}
|
||||
AddressSource::Loaded => {}
|
||||
TrackingStatus::Tracked => {}
|
||||
}
|
||||
|
||||
let is_new_entry = matches!(source, AddressSource::New | AddressSource::FromEmpty);
|
||||
let is_new_entry = matches!(status, TrackingStatus::New | TrackingStatus::WasEmpty);
|
||||
|
||||
if is_new_entry {
|
||||
// New/from-empty address - just add to cohort
|
||||
// New/was-empty address - just add to cohort
|
||||
addr_data.receive_outputs(total_value, price, output_count);
|
||||
cohorts
|
||||
.amount_range
|
||||
|
||||
Reference in New Issue
Block a user