mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-04-26 07:39:59 -07:00
global: big snapshot
This commit is contained in:
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user