global: big snapshot

This commit is contained in:
nym21
2026-01-09 20:00:20 +01:00
parent cb0abc324e
commit 426d7797a3
442 changed files with 17952 additions and 20071 deletions

View File

@@ -138,7 +138,7 @@ impl Query {
.map(|(key, _)| key.txindex())
.collect();
let mut txindex_to_txid_iter = indexer.vecs.tx.txindex_to_txid.iter()?;
let mut txindex_to_txid_iter = indexer.vecs.transactions.txid.iter()?;
let txids: Vec<Txid> = txindices
.into_iter()
.map(|txindex| txindex_to_txid_iter.get_unwrap(txindex))
@@ -166,12 +166,12 @@ impl Query {
.map(|(key, _): (AddressIndexOutPoint, Unit)| (key.txindex(), key.vout()))
.collect();
let mut txindex_to_txid_iter = vecs.tx.txindex_to_txid.iter()?;
let mut txindex_to_height_iter = vecs.tx.txindex_to_height.iter()?;
let mut txindex_to_first_txoutindex_iter = vecs.tx.txindex_to_first_txoutindex.iter()?;
let mut txoutindex_to_value_iter = vecs.txout.txoutindex_to_value.iter()?;
let mut height_to_blockhash_iter = vecs.block.height_to_blockhash.iter()?;
let mut height_to_timestamp_iter = vecs.block.height_to_timestamp.iter()?;
let mut txindex_to_txid_iter = vecs.transactions.txid.iter()?;
let mut txindex_to_height_iter = vecs.transactions.height.iter()?;
let mut txindex_to_first_txoutindex_iter = vecs.transactions.first_txoutindex.iter()?;
let mut txoutindex_to_value_iter = vecs.outputs.value.iter()?;
let mut height_to_blockhash_iter = vecs.blocks.blockhash.iter()?;
let mut height_to_timestamp_iter = vecs.blocks.timestamp.iter()?;
let utxos: Vec<Utxo> = outpoints
.into_iter()

View File

@@ -20,11 +20,11 @@ impl Query {
return Err(Error::OutOfRange("Block height out of range".into()));
}
let blockhash = indexer.vecs.block.height_to_blockhash.read_once(height)?;
let difficulty = indexer.vecs.block.height_to_difficulty.read_once(height)?;
let timestamp = indexer.vecs.block.height_to_timestamp.read_once(height)?;
let size = indexer.vecs.block.height_to_total_size.read_once(height)?;
let weight = indexer.vecs.block.height_to_weight.read_once(height)?;
let blockhash = indexer.vecs.blocks.blockhash.read_once(height)?;
let difficulty = indexer.vecs.blocks.difficulty.read_once(height)?;
let timestamp = indexer.vecs.blocks.timestamp.read_once(height)?;
let size = indexer.vecs.blocks.total_size.read_once(height)?;
let weight = indexer.vecs.blocks.weight.read_once(height)?;
let tx_count = self.tx_count_at_height(height, max_height)?;
Ok(BlockInfo {
@@ -75,8 +75,8 @@ impl Query {
Height::from(
self.indexer()
.vecs
.block
.height_to_blockhash
.blocks
.blockhash
.len()
.saturating_sub(1),
)
@@ -86,15 +86,15 @@ impl Query {
let indexer = self.indexer();
let computer = self.computer();
let first_txindex = indexer.vecs.tx.height_to_first_txindex.read_once(height)?;
let first_txindex = indexer.vecs.transactions.first_txindex.read_once(height)?;
let next_first_txindex = if height < max_height {
indexer
.vecs
.tx
.height_to_first_txindex
.transactions
.first_txindex
.read_once(height.incremented())?
} else {
TxIndex::from(computer.indexes.transaction.txindex_to_txindex.len())
TxIndex::from(computer.indexes.txindex.identity.len())
};
Ok((next_first_txindex.to_usize() - first_txindex.to_usize()) as u32)

View File

@@ -15,20 +15,13 @@ impl Query {
let computer = self.computer();
let reader = self.reader();
let max_height = Height::from(
indexer
.vecs
.block
.height_to_blockhash
.len()
.saturating_sub(1),
);
let max_height = Height::from(indexer.vecs.blocks.blockhash.len().saturating_sub(1));
if height > max_height {
return Err(Error::OutOfRange("Block height out of range".into()));
}
let position = computer.positions.height_to_position.read_once(height)?;
let size = indexer.vecs.block.height_to_total_size.read_once(height)?;
let position = computer.positions.block_position.read_once(height)?;
let size = indexer.vecs.blocks.total_size.read_once(height)?;
reader.read_raw_bytes(position, *size as usize)
}

View File

@@ -16,8 +16,8 @@ impl Query {
let max_height = Height::from(
indexer
.vecs
.block
.height_to_blockhash
.blocks
.blockhash
.len()
.saturating_sub(1),
);
@@ -30,8 +30,8 @@ impl Query {
Some(
indexer
.vecs
.block
.height_to_blockhash
.blocks
.blockhash
.read_once(height.incremented())?,
)
} else {

View File

@@ -24,15 +24,15 @@ impl Query {
// Get first height of the target date
let first_height_of_day = computer
.indexes
.time
.dateindex_to_first_height
.dateindex
.first_height
.read_once(dateindex)
.unwrap_or(Height::from(0usize));
let start: usize = usize::from(first_height_of_day).min(max_height_usize);
// Use iterator for efficient sequential access
let mut timestamp_iter = indexer.vecs.block.height_to_timestamp.iter()?;
let mut timestamp_iter = indexer.vecs.blocks.timestamp.iter()?;
// Search forward from start to find the last block <= target timestamp
let mut best_height = start;
@@ -62,8 +62,8 @@ impl Query {
let height = Height::from(best_height);
let blockhash = indexer
.vecs
.block
.height_to_blockhash
.blocks
.blockhash
.iter()?
.get_unwrap(height);

View File

@@ -31,13 +31,13 @@ impl Query {
return Err(Error::OutOfRange("Block height out of range".into()));
}
let first_txindex = indexer.vecs.tx.height_to_first_txindex.read_once(height)?;
let first_txindex = indexer.vecs.transactions.first_txindex.read_once(height)?;
let next_first_txindex = indexer
.vecs
.tx
.height_to_first_txindex
.transactions
.first_txindex
.read_once(height.incremented())
.unwrap_or_else(|_| TxIndex::from(indexer.vecs.tx.txindex_to_txid.len()));
.unwrap_or_else(|_| TxIndex::from(indexer.vecs.transactions.txid.len()));
let first: usize = first_txindex.into();
let next: usize = next_first_txindex.into();
@@ -45,8 +45,8 @@ impl Query {
let txids: Vec<Txid> = indexer
.vecs
.tx
.txindex_to_txid
.transactions
.txid
.iter()?
.skip(first)
.take(count)
@@ -67,13 +67,13 @@ impl Query {
return Err(Error::OutOfRange("Block height out of range".into()));
}
let first_txindex = indexer.vecs.tx.height_to_first_txindex.read_once(height)?;
let first_txindex = indexer.vecs.transactions.first_txindex.read_once(height)?;
let next_first_txindex = indexer
.vecs
.tx
.height_to_first_txindex
.transactions
.first_txindex
.read_once(height.incremented())
.unwrap_or_else(|_| TxIndex::from(indexer.vecs.tx.txindex_to_txid.len()));
.unwrap_or_else(|_| TxIndex::from(indexer.vecs.transactions.txid.len()));
let first: usize = first_txindex.into();
let next: usize = next_first_txindex.into();
@@ -104,13 +104,13 @@ impl Query {
return Err(Error::OutOfRange("Block height out of range".into()));
}
let first_txindex = indexer.vecs.tx.height_to_first_txindex.read_once(height)?;
let first_txindex = indexer.vecs.transactions.first_txindex.read_once(height)?;
let next_first_txindex = indexer
.vecs
.tx
.height_to_first_txindex
.transactions
.first_txindex
.read_once(height.incremented())
.unwrap_or_else(|_| TxIndex::from(indexer.vecs.tx.txindex_to_txid.len()));
.unwrap_or_else(|_| TxIndex::from(indexer.vecs.transactions.txid.len()));
let first: usize = first_txindex.into();
let next: usize = next_first_txindex.into();
@@ -121,7 +121,7 @@ impl Query {
}
let txindex = TxIndex::from(first + index);
let txid = indexer.vecs.tx.txindex_to_txid.iter()?.get_unwrap(txindex);
let txid = indexer.vecs.transactions.txid.iter()?.get_unwrap(txindex);
Ok(txid)
}

View File

@@ -15,11 +15,10 @@ impl Query {
let iter = DateIndexIter::new(computer, start, current_height.to_usize());
// KISS: dateindex.average.0 is now a concrete field
let mut fees = computer
.transactions
.fees
.indexes_to_fee
.fee
.sats
.dateindex
.average

View File

@@ -15,12 +15,10 @@ impl Query {
let iter = DateIndexIter::new(computer, start, current_height.to_usize());
// coinbase = subsidy + fees
// KISS: dateindex.distribution.average.0 is now a concrete field
let mut rewards = computer
.blocks
.rewards
.indexes_to_coinbase
.coinbase
.sats
.dateindex
.distribution

View File

@@ -18,7 +18,7 @@ impl Query {
let mut sizes_vec = computer
.blocks
.size
.indexes_to_block_size
.size
.dateindex
.distribution
.average
@@ -27,7 +27,7 @@ impl Query {
let mut weights_vec = computer
.blocks
.weight
.indexes_to_block_weight
.weight
.dateindex
.distribution
.average

View File

@@ -14,14 +14,14 @@ impl<'a> DateIndexIter<'a> {
pub fn new(computer: &'a Computer, start_height: usize, end_height: usize) -> Self {
let start_di = computer
.indexes
.block
.height_to_dateindex
.height
.dateindex
.read_once(Height::from(start_height))
.unwrap_or_default();
let end_di = computer
.indexes
.block
.height_to_dateindex
.height
.dateindex
.read_once(Height::from(end_height))
.unwrap_or_default();
@@ -46,14 +46,8 @@ impl<'a> DateIndexIter<'a> {
.to_usize()
.saturating_sub(self.start_di.to_usize())
+ 1;
let mut timestamps = self
.computer
.blocks
.time
.timeindexes_to_timestamp
.dateindex
.iter();
let mut heights = self.computer.indexes.time.dateindex_to_first_height.iter();
let mut timestamps = self.computer.blocks.time.timestamp.dateindex.iter();
let mut heights = self.computer.indexes.dateindex.first_height.iter();
let mut entries = Vec::with_capacity(total / self.step + 1);
let mut i = self.start_di.to_usize();

View File

@@ -22,16 +22,16 @@ impl Query {
// Get current epoch
let current_epoch = computer
.indexes
.block
.height_to_difficultyepoch
.height
.difficultyepoch
.read_once(current_height)?;
let current_epoch_usize: usize = current_epoch.into();
// Get epoch start height
let epoch_start_height = computer
.indexes
.block
.difficultyepoch_to_first_height
.difficultyepoch
.first_height
.read_once(current_epoch)?;
let epoch_start_u32: u32 = epoch_start_height.into();
@@ -45,12 +45,13 @@ impl Query {
let epoch_start_timestamp = computer
.blocks
.time
.difficultyepoch_to_timestamp
.timestamp
.difficultyepoch
.read_once(current_epoch)?;
let current_timestamp = indexer
.vecs
.block
.height_to_timestamp
.blocks
.timestamp
.read_once(current_height)?;
// Calculate average block time in current epoch
@@ -85,19 +86,19 @@ impl Query {
let prev_epoch = DifficultyEpoch::from(current_epoch_usize - 1);
let prev_epoch_start = computer
.indexes
.block
.difficultyepoch_to_first_height
.difficultyepoch
.first_height
.read_once(prev_epoch)?;
let prev_difficulty = indexer
.vecs
.block
.height_to_difficulty
.blocks
.difficulty
.read_once(prev_epoch_start)?;
let curr_difficulty = indexer
.vecs
.block
.height_to_difficulty
.blocks
.difficulty
.read_once(epoch_start_height)?;
if *prev_difficulty > 0.0 {

View File

@@ -10,29 +10,24 @@ pub fn iter_difficulty_epochs(
) -> Vec<DifficultyAdjustmentEntry> {
let start_epoch = computer
.indexes
.block
.height_to_difficultyepoch
.height
.difficultyepoch
.read_once(Height::from(start_height))
.unwrap_or_default();
let end_epoch = computer
.indexes
.block
.height_to_difficultyepoch
.height
.difficultyepoch
.read_once(Height::from(end_height))
.unwrap_or_default();
let mut epoch_to_height_iter = computer
.indexes
.block
.difficultyepoch_to_first_height
.iter();
let mut epoch_to_timestamp_iter = computer.blocks.time.difficultyepoch_to_timestamp.iter();
let mut epoch_to_difficulty_iter = computer
.blocks
.mining
.indexes_to_difficulty
.difficultyepoch
.first_height
.iter();
let mut epoch_to_timestamp_iter = computer.blocks.time.timestamp.difficultyepoch.iter();
let mut epoch_to_difficulty_iter = computer.blocks.mining.difficulty.difficultyepoch.iter();
let mut results = Vec::with_capacity(end_epoch.to_usize() - start_epoch.to_usize() + 1);
let mut prev_difficulty: Option<f64> = None;

View File

@@ -12,23 +12,19 @@ impl Query {
let current_height = self.height();
// Get current difficulty
let current_difficulty = *indexer
.vecs
.block
.height_to_difficulty
.read_once(current_height)?;
let current_difficulty = *indexer.vecs.blocks.difficulty.read_once(current_height)?;
// Get current hashrate
let current_dateindex = computer
.indexes
.block
.height_to_dateindex
.height
.dateindex
.read_once(current_height)?;
let current_hashrate = *computer
.blocks
.mining
.indexes_to_hash_rate
.hash_rate
.dateindex
.read_once(current_dateindex)? as u128;
@@ -42,8 +38,8 @@ impl Query {
// Get hashrate entries using iterators for efficiency
let start_dateindex = computer
.indexes
.block
.height_to_dateindex
.height
.dateindex
.read_once(Height::from(start))?;
let end_dateindex = current_dateindex;
@@ -55,19 +51,9 @@ impl Query {
let step = (total_days / 200).max(1); // Max ~200 data points
// Create iterators for the loop
let mut hashrate_iter = computer
.blocks
.mining
.indexes_to_hash_rate
.dateindex
.iter();
let mut hashrate_iter = computer.blocks.mining.hash_rate.dateindex.iter();
let mut timestamp_iter = computer
.blocks
.time
.timeindexes_to_timestamp
.dateindex
.iter();
let mut timestamp_iter = computer.blocks.time.timestamp.dateindex.iter();
let mut hashrates = Vec::with_capacity(total_days / step + 1);
let mut di = start_dateindex.to_usize();

View File

@@ -31,7 +31,7 @@ impl Query {
// For each pool, get cumulative count at end and start, subtract to get range count
for (pool_id, pool_vecs) in &computer.pools.vecs {
let mut cumulative = pool_vecs
.indexes_to_blocks_mined
.blocks_mined
.height_cumulative
.inner()
.iter();
@@ -101,7 +101,7 @@ impl Query {
.ok_or_else(|| Error::NotFound("Pool data not found".into()))?;
let mut cumulative = pool_vecs
.indexes_to_blocks_mined
.blocks_mined
.height_cumulative
.inner()
.iter();

View File

@@ -12,31 +12,19 @@ impl Query {
let end_block = current_height;
let start_block = Height::from(current_height.to_usize().saturating_sub(block_count - 1));
// KISS: height is now a concrete field (no Option)
let mut coinbase_iter = computer
.blocks
.rewards
.indexes_to_coinbase
.sats
.height
.iter();
// KISS: height.sum_cum.sum.0 is now a concrete field
let mut coinbase_iter = computer.blocks.rewards.coinbase.sats.height.iter();
let mut fee_iter = computer
.transactions
.fees
.indexes_to_fee
.fee
.sats
.height
.sum_cum
.sum
.0
.iter();
let mut tx_count_iter = computer
.transactions
.count
.indexes_to_tx_count
.height
.iter();
let mut tx_count_iter = computer.transactions.count.tx_count.height.iter();
let mut total_reward = Sats::ZERO;
let mut total_fee = Sats::ZERO;

View File

@@ -55,9 +55,9 @@ impl Query {
};
// Get block info for status
let height = indexer.vecs.tx.txindex_to_height.read_once(txindex)?;
let block_hash = indexer.vecs.block.height_to_blockhash.read_once(height)?;
let block_time = indexer.vecs.block.height_to_timestamp.read_once(height)?;
let height = indexer.vecs.transactions.height.read_once(txindex)?;
let block_hash = indexer.vecs.blocks.blockhash.read_once(height)?;
let block_time = indexer.vecs.blocks.timestamp.read_once(height)?;
Ok(TxStatus {
confirmed: true,
@@ -113,8 +113,8 @@ impl Query {
// Calculate txoutindex
let first_txoutindex = indexer
.vecs
.tx
.txindex_to_first_txoutindex
.transactions
.first_txoutindex
.read_once(txindex)?;
let txoutindex = first_txoutindex + vout;
@@ -123,7 +123,7 @@ impl Query {
let txinindex = computer
.outputs
.spent
.txoutindex_to_txinindex
.txinindex
.read_once(txoutindex)?;
if txinindex == TxInIndex::UNSPENT {
@@ -157,19 +157,20 @@ impl Query {
// Get output range
let first_txoutindex = indexer
.vecs
.tx
.txindex_to_first_txoutindex
.transactions
.first_txoutindex
.read_once(txindex)?;
let next_first_txoutindex = indexer
.vecs
.tx
.txindex_to_first_txoutindex
.transactions
.first_txoutindex
.read_once(txindex.incremented())?;
let output_count = usize::from(next_first_txoutindex) - usize::from(first_txoutindex);
// Get spend status for each output
let computer = self.computer();
let mut txoutindex_to_txinindex_iter = computer.outputs.spent.txoutindex_to_txinindex.iter()?;
let mut txoutindex_to_txinindex_iter =
computer.outputs.spent.txinindex.iter()?;
let mut outspends = Vec::with_capacity(output_count);
for i in 0..output_count {
@@ -194,21 +195,21 @@ impl Query {
let computer = self.computer();
// Get tx metadata using read_once for single lookups
let txid = indexer.vecs.tx.txindex_to_txid.read_once(txindex)?;
let height = indexer.vecs.tx.txindex_to_height.read_once(txindex)?;
let version = indexer.vecs.tx.txindex_to_txversion.read_once(txindex)?;
let lock_time = indexer.vecs.tx.txindex_to_rawlocktime.read_once(txindex)?;
let total_size = indexer.vecs.tx.txindex_to_total_size.read_once(txindex)?;
let txid = indexer.vecs.transactions.txid.read_once(txindex)?;
let height = indexer.vecs.transactions.height.read_once(txindex)?;
let version = indexer.vecs.transactions.txversion.read_once(txindex)?;
let lock_time = indexer.vecs.transactions.rawlocktime.read_once(txindex)?;
let total_size = indexer.vecs.transactions.total_size.read_once(txindex)?;
let first_txinindex = indexer
.vecs
.tx
.txindex_to_first_txinindex
.transactions
.first_txinindex
.read_once(txindex)?;
let position = computer.positions.txindex_to_position.read_once(txindex)?;
let position = computer.positions.tx_position.read_once(txindex)?;
// Get block info for status
let block_hash = indexer.vecs.block.height_to_blockhash.read_once(height)?;
let block_time = indexer.vecs.block.height_to_timestamp.read_once(height)?;
let block_hash = indexer.vecs.blocks.blockhash.read_once(height)?;
let block_time = indexer.vecs.blocks.timestamp.read_once(height)?;
// Read and decode the raw transaction from blk file
let buffer = reader.read_raw_bytes(position, *total_size as usize)?;
@@ -217,11 +218,11 @@ impl Query {
.map_err(|_| Error::Parse("Failed to decode transaction".into()))?;
// For iterating through inputs, we need iterators (multiple lookups)
let mut txindex_to_txid_iter = indexer.vecs.tx.txindex_to_txid.iter()?;
let mut txindex_to_txid_iter = indexer.vecs.transactions.txid.iter()?;
let mut txindex_to_first_txoutindex_iter =
indexer.vecs.tx.txindex_to_first_txoutindex.iter()?;
let mut txinindex_to_outpoint_iter = indexer.vecs.txin.txinindex_to_outpoint.iter()?;
let mut txoutindex_to_value_iter = indexer.vecs.txout.txoutindex_to_value.iter()?;
indexer.vecs.transactions.first_txoutindex.iter()?;
let mut txinindex_to_outpoint_iter = indexer.vecs.inputs.outpoint.iter()?;
let mut txoutindex_to_value_iter = indexer.vecs.outputs.value.iter()?;
// Build inputs with prevout information
let input: Vec<TxIn> = tx
@@ -313,8 +314,8 @@ impl Query {
let reader = self.reader();
let computer = self.computer();
let total_size = indexer.vecs.tx.txindex_to_total_size.read_once(txindex)?;
let position = computer.positions.txindex_to_position.read_once(txindex)?;
let total_size = indexer.vecs.transactions.total_size.read_once(txindex)?;
let position = computer.positions.tx_position.read_once(txindex)?;
let buffer = reader.read_raw_bytes(position, *total_size as usize)?;
@@ -325,41 +326,25 @@ impl Query {
let indexer = self.indexer();
// Look up spending txindex directly
let spending_txindex = indexer
.vecs
.txin
.txinindex_to_txindex
.read_once(txinindex)?;
let spending_txindex = indexer.vecs.inputs.txindex.read_once(txinindex)?;
// Calculate vin
let spending_first_txinindex = indexer
.vecs
.tx
.txindex_to_first_txinindex
.transactions
.first_txinindex
.read_once(spending_txindex)?;
let vin = Vin::from(usize::from(txinindex) - usize::from(spending_first_txinindex));
// Get spending tx details
let spending_txid = indexer
.vecs
.tx
.txindex_to_txid
.read_once(spending_txindex)?;
let spending_txid = indexer.vecs.transactions.txid.read_once(spending_txindex)?;
let spending_height = indexer
.vecs
.tx
.txindex_to_height
.transactions
.height
.read_once(spending_txindex)?;
let block_hash = indexer
.vecs
.block
.height_to_blockhash
.read_once(spending_height)?;
let block_time = indexer
.vecs
.block
.height_to_timestamp
.read_once(spending_height)?;
let block_hash = indexer.vecs.blocks.blockhash.read_once(spending_height)?;
let block_time = indexer.vecs.blocks.timestamp.read_once(spending_height)?;
Ok(TxOutspend {
spent: true,