mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-07-28 11:18:17 -07:00
global: renames part 2
This commit is contained in:
+15
-15
@@ -37,14 +37,14 @@ impl AddressCache {
|
||||
|
||||
/// Check if address is in cache (either funded or empty).
|
||||
#[inline]
|
||||
pub(crate) fn contains(&self, address_type: OutputType, typeindex: TypeIndex) -> bool {
|
||||
pub(crate) fn contains(&self, address_type: OutputType, type_index: TypeIndex) -> bool {
|
||||
self.funded
|
||||
.get(address_type)
|
||||
.is_some_and(|m| m.contains_key(&typeindex))
|
||||
.is_some_and(|m| m.contains_key(&type_index))
|
||||
|| self
|
||||
.empty
|
||||
.get(address_type)
|
||||
.is_some_and(|m| m.contains_key(&typeindex))
|
||||
.is_some_and(|m| m.contains_key(&type_index))
|
||||
}
|
||||
|
||||
/// Merge address data into funded cache.
|
||||
@@ -68,9 +68,9 @@ impl AddressCache {
|
||||
/// Update transaction counts for addresses.
|
||||
pub(crate) fn update_tx_counts(
|
||||
&mut self,
|
||||
txindex_vecs: AddressTypeToTypeIndexMap<SmallVec<[TxIndex; 4]>>,
|
||||
tx_index_vecs: AddressTypeToTypeIndexMap<SmallVec<[TxIndex; 4]>>,
|
||||
) {
|
||||
update_tx_counts(&mut self.funded, &mut self.empty, txindex_vecs);
|
||||
update_tx_counts(&mut self.funded, &mut self.empty, tx_index_vecs);
|
||||
}
|
||||
|
||||
/// Take the cache contents for flushing, leaving empty caches.
|
||||
@@ -93,33 +93,33 @@ impl AddressCache {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub(crate) fn load_uncached_address_data(
|
||||
address_type: OutputType,
|
||||
typeindex: TypeIndex,
|
||||
first_addressindexes: &ByAddressType<TypeIndex>,
|
||||
type_index: TypeIndex,
|
||||
first_address_indexes: &ByAddressType<TypeIndex>,
|
||||
cache: &AddressCache,
|
||||
vr: &VecsReaders,
|
||||
any_address_indexes: &AnyAddressIndexesVecs,
|
||||
addresses_data: &AddressesDataVecs,
|
||||
) -> Result<Option<WithAddressDataSource<FundedAddressData>>> {
|
||||
// Check if this is a new address (typeindex >= first for this height)
|
||||
let first = *first_addressindexes.get(address_type).unwrap();
|
||||
if first <= typeindex {
|
||||
// Check if this is a new address (type_index >= first for this height)
|
||||
let first = *first_address_indexes.get(address_type).unwrap();
|
||||
if first <= type_index {
|
||||
return Ok(Some(WithAddressDataSource::New(
|
||||
FundedAddressData::default(),
|
||||
)));
|
||||
}
|
||||
|
||||
// Skip if already in cache
|
||||
if cache.contains(address_type, typeindex) {
|
||||
if cache.contains(address_type, type_index) {
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
// Read from storage
|
||||
let reader = vr.address_reader(address_type);
|
||||
let anyaddressindex = any_address_indexes.get(address_type, typeindex, reader)?;
|
||||
let any_address_index = any_address_indexes.get(address_type, type_index, reader)?;
|
||||
|
||||
Ok(Some(match anyaddressindex.to_enum() {
|
||||
Ok(Some(match any_address_index.to_enum() {
|
||||
AnyAddressDataIndexEnum::Funded(funded_index) => {
|
||||
let reader = &vr.anyaddressindex_to_anyaddressdata.funded;
|
||||
let reader = &vr.any_address_index_to_any_address_data.funded;
|
||||
let funded_data = addresses_data
|
||||
.funded
|
||||
.get_any_or_read_at(funded_index.into(), reader)?
|
||||
@@ -127,7 +127,7 @@ pub(crate) fn load_uncached_address_data(
|
||||
WithAddressDataSource::FromFunded(funded_index, funded_data)
|
||||
}
|
||||
AnyAddressDataIndexEnum::Empty(empty_index) => {
|
||||
let reader = &vr.anyaddressindex_to_anyaddressdata.empty;
|
||||
let reader = &vr.any_address_index_to_any_address_data.empty;
|
||||
let empty_data = addresses_data
|
||||
.empty
|
||||
.get_any_or_read_at(empty_index.into(), reader)?
|
||||
|
||||
@@ -26,17 +26,17 @@ pub(crate) fn process_funded_addresses(
|
||||
let mut pushes: Vec<(OutputType, TypeIndex, FundedAddressData)> = Vec::with_capacity(total);
|
||||
|
||||
for (address_type, items) in funded_updates.into_iter() {
|
||||
for (typeindex, source) in items {
|
||||
for (type_index, source) in items {
|
||||
match source {
|
||||
WithAddressDataSource::New(data) => {
|
||||
pushes.push((address_type, typeindex, data));
|
||||
pushes.push((address_type, type_index, data));
|
||||
}
|
||||
WithAddressDataSource::FromFunded(index, data) => {
|
||||
updates.push((index, data));
|
||||
}
|
||||
WithAddressDataSource::FromEmpty(empty_index, data) => {
|
||||
deletes.push(empty_index);
|
||||
pushes.push((address_type, typeindex, data));
|
||||
pushes.push((address_type, type_index, data));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -57,21 +57,21 @@ pub(crate) fn process_funded_addresses(
|
||||
let holes_count = addresses_data.funded.holes().len();
|
||||
let mut pushes_iter = pushes.into_iter();
|
||||
|
||||
for (address_type, typeindex, data) in pushes_iter.by_ref().take(holes_count) {
|
||||
for (address_type, type_index, data) in pushes_iter.by_ref().take(holes_count) {
|
||||
let index = addresses_data.funded.fill_first_hole_or_push(data)?;
|
||||
result
|
||||
.get_mut(address_type)
|
||||
.unwrap()
|
||||
.insert(typeindex, AnyAddressIndex::from(index));
|
||||
.insert(type_index, AnyAddressIndex::from(index));
|
||||
}
|
||||
|
||||
// Pure pushes - no holes remain
|
||||
addresses_data.funded.reserve_pushed(pushes_iter.len());
|
||||
let mut next_index = addresses_data.funded.len();
|
||||
for (address_type, typeindex, data) in pushes_iter {
|
||||
for (address_type, type_index, data) in pushes_iter {
|
||||
addresses_data.funded.push(data);
|
||||
result.get_mut(address_type).unwrap().insert(
|
||||
typeindex,
|
||||
type_index,
|
||||
AnyAddressIndex::from(FundedAddressIndex::from(next_index)),
|
||||
);
|
||||
next_index += 1;
|
||||
@@ -97,17 +97,17 @@ pub(crate) fn process_empty_addresses(
|
||||
let mut pushes: Vec<(OutputType, TypeIndex, EmptyAddressData)> = Vec::with_capacity(total);
|
||||
|
||||
for (address_type, items) in empty_updates.into_iter() {
|
||||
for (typeindex, source) in items {
|
||||
for (type_index, source) in items {
|
||||
match source {
|
||||
WithAddressDataSource::New(data) => {
|
||||
pushes.push((address_type, typeindex, data));
|
||||
pushes.push((address_type, type_index, data));
|
||||
}
|
||||
WithAddressDataSource::FromEmpty(index, data) => {
|
||||
updates.push((index, data));
|
||||
}
|
||||
WithAddressDataSource::FromFunded(funded_index, data) => {
|
||||
deletes.push(funded_index);
|
||||
pushes.push((address_type, typeindex, data));
|
||||
pushes.push((address_type, type_index, data));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -128,21 +128,21 @@ pub(crate) fn process_empty_addresses(
|
||||
let holes_count = addresses_data.empty.holes().len();
|
||||
let mut pushes_iter = pushes.into_iter();
|
||||
|
||||
for (address_type, typeindex, data) in pushes_iter.by_ref().take(holes_count) {
|
||||
for (address_type, type_index, data) in pushes_iter.by_ref().take(holes_count) {
|
||||
let index = addresses_data.empty.fill_first_hole_or_push(data)?;
|
||||
result
|
||||
.get_mut(address_type)
|
||||
.unwrap()
|
||||
.insert(typeindex, AnyAddressIndex::from(index));
|
||||
.insert(type_index, AnyAddressIndex::from(index));
|
||||
}
|
||||
|
||||
// Pure pushes - no holes remain
|
||||
addresses_data.empty.reserve_pushed(pushes_iter.len());
|
||||
let mut next_index = addresses_data.empty.len();
|
||||
for (address_type, typeindex, data) in pushes_iter {
|
||||
for (address_type, type_index, data) in pushes_iter {
|
||||
addresses_data.empty.push(data);
|
||||
result.get_mut(address_type).unwrap().insert(
|
||||
typeindex,
|
||||
type_index,
|
||||
AnyAddressIndex::from(EmptyAddressIndex::from(next_index)),
|
||||
);
|
||||
next_index += 1;
|
||||
|
||||
@@ -16,35 +16,35 @@ use super::with_source::WithAddressDataSource;
|
||||
pub(crate) fn update_tx_counts(
|
||||
funded_cache: &mut AddressTypeToTypeIndexMap<WithAddressDataSource<FundedAddressData>>,
|
||||
empty_cache: &mut AddressTypeToTypeIndexMap<WithAddressDataSource<EmptyAddressData>>,
|
||||
mut txindex_vecs: AddressTypeToTypeIndexMap<SmallVec<[TxIndex; 4]>>,
|
||||
mut tx_index_vecs: AddressTypeToTypeIndexMap<SmallVec<[TxIndex; 4]>>,
|
||||
) {
|
||||
// First, deduplicate txindex_vecs for addresses that appear multiple times in a block
|
||||
for (_, map) in txindex_vecs.iter_mut() {
|
||||
for (_, txindex_vec) in map.iter_mut() {
|
||||
if txindex_vec.len() > 1 {
|
||||
txindex_vec.sort_unstable();
|
||||
txindex_vec.dedup();
|
||||
// First, deduplicate tx_index_vecs for addresses that appear multiple times in a block
|
||||
for (_, map) in tx_index_vecs.iter_mut() {
|
||||
for (_, tx_index_vec) in map.iter_mut() {
|
||||
if tx_index_vec.len() > 1 {
|
||||
tx_index_vec.sort_unstable();
|
||||
tx_index_vec.dedup();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update tx_count on address data
|
||||
for (address_type, typeindex, txindex_vec) in txindex_vecs
|
||||
for (address_type, type_index, tx_index_vec) in tx_index_vecs
|
||||
.into_iter()
|
||||
.flat_map(|(t, m)| m.into_iter().map(move |(i, v)| (t, i, v)))
|
||||
{
|
||||
let tx_count = txindex_vec.len() as u32;
|
||||
let tx_count = tx_index_vec.len() as u32;
|
||||
|
||||
if let Some(addr_data) = funded_cache
|
||||
.get_mut(address_type)
|
||||
.unwrap()
|
||||
.get_mut(&typeindex)
|
||||
.get_mut(&type_index)
|
||||
{
|
||||
addr_data.tx_count += tx_count;
|
||||
} else if let Some(addr_data) = empty_cache
|
||||
.get_mut(address_type)
|
||||
.unwrap()
|
||||
.get_mut(&typeindex)
|
||||
.get_mut(&type_index)
|
||||
{
|
||||
addr_data.tx_count += tx_count;
|
||||
}
|
||||
|
||||
@@ -22,20 +22,20 @@ use super::super::{
|
||||
pub struct InputsResult {
|
||||
/// Map from UTXO creation height -> aggregated sent supply.
|
||||
pub height_to_sent: FxHashMap<Height, Transacted>,
|
||||
/// Per-height, per-address-type sent data: (typeindex, value) for each address.
|
||||
/// Per-height, per-address-type sent data: (type_index, value) for each address.
|
||||
pub sent_data: HeightToAddressTypeToVec<(TypeIndex, Sats)>,
|
||||
/// Address data looked up during processing, keyed by (address_type, typeindex).
|
||||
/// Address data looked up during processing, keyed by (address_type, type_index).
|
||||
pub address_data: AddressTypeToTypeIndexMap<WithAddressDataSource<FundedAddressData>>,
|
||||
/// Transaction indexes per address for tx_count tracking.
|
||||
pub txindex_vecs: AddressTypeToTypeIndexMap<SmallVec<[TxIndex; 4]>>,
|
||||
pub tx_index_vecs: AddressTypeToTypeIndexMap<SmallVec<[TxIndex; 4]>>,
|
||||
}
|
||||
|
||||
/// Process inputs (spent UTXOs) for a block.
|
||||
///
|
||||
/// For each input:
|
||||
/// 1. Use pre-collected outpoint (from reusable iterator, avoids PcoVec re-decompression)
|
||||
/// 2. Resolve outpoint to txoutindex
|
||||
/// 3. Get the creation height from txoutindex_to_height map
|
||||
/// 2. Resolve outpoint to txout_index
|
||||
/// 3. Get the creation height from txout_index_to_height map
|
||||
/// 4. Read value and type from the referenced output (random access via mmap)
|
||||
/// 5. Look up address data if input references an address type
|
||||
/// 6. Accumulate into height_to_sent map
|
||||
@@ -46,35 +46,35 @@ pub struct InputsResult {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub(crate) fn process_inputs(
|
||||
input_count: usize,
|
||||
txinindex_to_txindex: &[TxIndex],
|
||||
txinindex_to_value: &[Sats],
|
||||
txinindex_to_outputtype: &[OutputType],
|
||||
txinindex_to_typeindex: &[TypeIndex],
|
||||
txinindex_to_prev_height: &[Height],
|
||||
first_addressindexes: &ByAddressType<TypeIndex>,
|
||||
txin_index_to_tx_index: &[TxIndex],
|
||||
txin_index_to_value: &[Sats],
|
||||
txin_index_to_output_type: &[OutputType],
|
||||
txin_index_to_type_index: &[TypeIndex],
|
||||
txin_index_to_prev_height: &[Height],
|
||||
first_address_indexes: &ByAddressType<TypeIndex>,
|
||||
cache: &AddressCache,
|
||||
vr: &VecsReaders,
|
||||
any_address_indexes: &AnyAddressIndexesVecs,
|
||||
addresses_data: &AddressesDataVecs,
|
||||
) -> Result<InputsResult> {
|
||||
let map_fn = |local_idx: usize| -> Result<_> {
|
||||
let txindex = txinindex_to_txindex[local_idx];
|
||||
let tx_index = txin_index_to_tx_index[local_idx];
|
||||
|
||||
let prev_height = txinindex_to_prev_height[local_idx];
|
||||
let value = txinindex_to_value[local_idx];
|
||||
let input_type = txinindex_to_outputtype[local_idx];
|
||||
let prev_height = txin_index_to_prev_height[local_idx];
|
||||
let value = txin_index_to_value[local_idx];
|
||||
let input_type = txin_index_to_output_type[local_idx];
|
||||
|
||||
if input_type.is_not_address() {
|
||||
return Ok((prev_height, value, input_type, None));
|
||||
}
|
||||
|
||||
let typeindex = txinindex_to_typeindex[local_idx];
|
||||
let type_index = txin_index_to_type_index[local_idx];
|
||||
|
||||
// Look up address data
|
||||
let addr_data_opt = load_uncached_address_data(
|
||||
input_type,
|
||||
typeindex,
|
||||
first_addressindexes,
|
||||
type_index,
|
||||
first_address_indexes,
|
||||
cache,
|
||||
vr,
|
||||
any_address_indexes,
|
||||
@@ -85,7 +85,7 @@ pub(crate) fn process_inputs(
|
||||
prev_height,
|
||||
value,
|
||||
input_type,
|
||||
Some((typeindex, txindex, value, addr_data_opt)),
|
||||
Some((type_index, tx_index, value, addr_data_opt)),
|
||||
))
|
||||
};
|
||||
|
||||
@@ -113,7 +113,7 @@ pub(crate) fn process_inputs(
|
||||
AddressTypeToTypeIndexMap::<WithAddressDataSource<FundedAddressData>>::with_capacity(
|
||||
estimated_per_type,
|
||||
);
|
||||
let mut txindex_vecs =
|
||||
let mut tx_index_vecs =
|
||||
AddressTypeToTypeIndexMap::<SmallVec<[TxIndex; 4]>>::with_capacity(estimated_per_type);
|
||||
|
||||
for (prev_height, value, output_type, addr_info) in items {
|
||||
@@ -122,24 +122,24 @@ pub(crate) fn process_inputs(
|
||||
.or_default()
|
||||
.iterate(value, output_type);
|
||||
|
||||
if let Some((typeindex, txindex, value, addr_data_opt)) = addr_info {
|
||||
if let Some((type_index, tx_index, value, addr_data_opt)) = addr_info {
|
||||
sent_data
|
||||
.entry(prev_height)
|
||||
.or_default()
|
||||
.get_mut(output_type)
|
||||
.unwrap()
|
||||
.push((typeindex, value));
|
||||
.push((type_index, value));
|
||||
|
||||
if let Some(addr_data) = addr_data_opt {
|
||||
address_data.insert_for_type(output_type, typeindex, addr_data);
|
||||
address_data.insert_for_type(output_type, type_index, addr_data);
|
||||
}
|
||||
|
||||
txindex_vecs
|
||||
tx_index_vecs
|
||||
.get_mut(output_type)
|
||||
.unwrap()
|
||||
.entry(typeindex)
|
||||
.entry(type_index)
|
||||
.or_default()
|
||||
.push(txindex);
|
||||
.push(tx_index);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -147,6 +147,6 @@ pub(crate) fn process_inputs(
|
||||
height_to_sent,
|
||||
sent_data,
|
||||
address_data,
|
||||
txindex_vecs,
|
||||
tx_index_vecs,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -21,50 +21,50 @@ use super::super::{
|
||||
pub struct OutputsResult {
|
||||
/// Aggregated supply transacted in this block.
|
||||
pub transacted: Transacted,
|
||||
/// Per-address-type received data: (typeindex, value) for each address.
|
||||
/// Per-address-type received data: (type_index, value) for each address.
|
||||
pub received_data: AddressTypeToVec<(TypeIndex, Sats)>,
|
||||
/// Address data looked up during processing, keyed by (address_type, typeindex).
|
||||
/// Address data looked up during processing, keyed by (address_type, type_index).
|
||||
pub address_data: AddressTypeToTypeIndexMap<WithAddressDataSource<FundedAddressData>>,
|
||||
/// Transaction indexes per address for tx_count tracking.
|
||||
pub txindex_vecs: AddressTypeToTypeIndexMap<SmallVec<[TxIndex; 4]>>,
|
||||
pub tx_index_vecs: AddressTypeToTypeIndexMap<SmallVec<[TxIndex; 4]>>,
|
||||
}
|
||||
|
||||
/// Process outputs (new UTXOs) for a block.
|
||||
///
|
||||
/// For each output:
|
||||
/// 1. Read pre-collected value, output type, and typeindex
|
||||
/// 1. Read pre-collected value, output type, and type_index
|
||||
/// 2. Accumulate into Transacted by type and amount
|
||||
/// 3. Look up address data if output is an address type
|
||||
/// 4. Track address-specific data for address cohort processing
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub(crate) fn process_outputs(
|
||||
txoutindex_to_txindex: &[TxIndex],
|
||||
txoutdata_vec: &[TxOutData],
|
||||
first_addressindexes: &ByAddressType<TypeIndex>,
|
||||
txout_index_to_tx_index: &[TxIndex],
|
||||
txout_data_vec: &[TxOutData],
|
||||
first_address_indexes: &ByAddressType<TypeIndex>,
|
||||
cache: &AddressCache,
|
||||
vr: &VecsReaders,
|
||||
any_address_indexes: &AnyAddressIndexesVecs,
|
||||
addresses_data: &AddressesDataVecs,
|
||||
) -> Result<OutputsResult> {
|
||||
let output_count = txoutdata_vec.len();
|
||||
let output_count = txout_data_vec.len();
|
||||
|
||||
// Phase 1: Address lookups (mmap reads) — parallel for large blocks, sequential for small
|
||||
let map_fn = |local_idx: usize| -> Result<_> {
|
||||
let txoutdata = &txoutdata_vec[local_idx];
|
||||
let value = txoutdata.value;
|
||||
let output_type = txoutdata.outputtype;
|
||||
let txout_data = &txout_data_vec[local_idx];
|
||||
let value = txout_data.value;
|
||||
let output_type = txout_data.output_type;
|
||||
|
||||
if output_type.is_not_address() {
|
||||
return Ok((value, output_type, None));
|
||||
}
|
||||
|
||||
let typeindex = txoutdata.typeindex;
|
||||
let txindex = txoutindex_to_txindex[local_idx];
|
||||
let type_index = txout_data.type_index;
|
||||
let tx_index = txout_index_to_tx_index[local_idx];
|
||||
|
||||
let addr_data_opt = load_uncached_address_data(
|
||||
output_type,
|
||||
typeindex,
|
||||
first_addressindexes,
|
||||
type_index,
|
||||
first_address_indexes,
|
||||
cache,
|
||||
vr,
|
||||
any_address_indexes,
|
||||
@@ -74,7 +74,7 @@ pub(crate) fn process_outputs(
|
||||
Ok((
|
||||
value,
|
||||
output_type,
|
||||
Some((typeindex, txindex, value, addr_data_opt)),
|
||||
Some((type_index, tx_index, value, addr_data_opt)),
|
||||
))
|
||||
};
|
||||
|
||||
@@ -97,28 +97,28 @@ pub(crate) fn process_outputs(
|
||||
AddressTypeToTypeIndexMap::<WithAddressDataSource<FundedAddressData>>::with_capacity(
|
||||
estimated_per_type,
|
||||
);
|
||||
let mut txindex_vecs =
|
||||
let mut tx_index_vecs =
|
||||
AddressTypeToTypeIndexMap::<SmallVec<[TxIndex; 4]>>::with_capacity(estimated_per_type);
|
||||
|
||||
for (value, output_type, addr_info) in items {
|
||||
transacted.iterate(value, output_type);
|
||||
|
||||
if let Some((typeindex, txindex, value, addr_data_opt)) = addr_info {
|
||||
if let Some((type_index, tx_index, value, addr_data_opt)) = addr_info {
|
||||
received_data
|
||||
.get_mut(output_type)
|
||||
.unwrap()
|
||||
.push((typeindex, value));
|
||||
.push((type_index, value));
|
||||
|
||||
if let Some(addr_data) = addr_data_opt {
|
||||
address_data.insert_for_type(output_type, typeindex, addr_data);
|
||||
address_data.insert_for_type(output_type, type_index, addr_data);
|
||||
}
|
||||
|
||||
txindex_vecs
|
||||
tx_index_vecs
|
||||
.get_mut(output_type)
|
||||
.unwrap()
|
||||
.entry(typeindex)
|
||||
.entry(type_index)
|
||||
.or_default()
|
||||
.push(txindex);
|
||||
.push(tx_index);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,6 +126,6 @@ pub(crate) fn process_outputs(
|
||||
transacted,
|
||||
received_data,
|
||||
address_data,
|
||||
txindex_vecs,
|
||||
tx_index_vecs,
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user