mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-05-20 06:44:47 -07:00
global: sigops
This commit is contained in:
@@ -25,6 +25,7 @@ serde = { workspace = true }
|
||||
tracing = { workspace = true }
|
||||
rayon = { workspace = true }
|
||||
rustc-hash = { workspace = true }
|
||||
smallvec = { workspace = true }
|
||||
vecdb = { workspace = true }
|
||||
|
||||
[dev-dependencies]
|
||||
|
||||
@@ -309,10 +309,13 @@ impl Indexer {
|
||||
|
||||
processor.check_txid_collisions(&txs)?;
|
||||
|
||||
let sigops = processor.compute_sigops(&txins);
|
||||
|
||||
processor.finalize_and_store_metadata(
|
||||
txs,
|
||||
txouts,
|
||||
txins,
|
||||
sigops,
|
||||
&buffers.same_block_spent,
|
||||
&mut buffers.already_added_addrs,
|
||||
&mut buffers.same_block_output_info,
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
mod metadata;
|
||||
mod sigops;
|
||||
mod tx;
|
||||
mod txin;
|
||||
mod txout;
|
||||
@@ -8,7 +9,9 @@ pub use types::*;
|
||||
|
||||
use brk_cohort::ByAddrType;
|
||||
use brk_error::Result;
|
||||
use brk_types::{AddrHash, Block, Height, OutPoint, TxInIndex, TxIndex, TxOutIndex, TypeIndex};
|
||||
use brk_types::{
|
||||
AddrHash, Block, Height, OutPoint, SigOps, TxInIndex, TxIndex, TxOutIndex, TypeIndex,
|
||||
};
|
||||
use rustc_hash::{FxHashMap, FxHashSet};
|
||||
|
||||
use crate::{Indexes, Readers, Stores, Vecs};
|
||||
@@ -39,6 +42,7 @@ impl BlockProcessor<'_> {
|
||||
txs: Vec<ComputedTx>,
|
||||
txouts: Vec<ProcessedOutput>,
|
||||
txins: Vec<(TxInIndex, InputSource)>,
|
||||
sigops: Vec<SigOps>,
|
||||
same_block_spent_outpoints: &FxHashSet<OutPoint>,
|
||||
already_added: &mut ByAddrType<FxHashMap<AddrHash, TypeIndex>>,
|
||||
same_block_info: &mut FxHashMap<OutPoint, SameBlockOutputInfo>,
|
||||
@@ -84,7 +88,7 @@ impl BlockProcessor<'_> {
|
||||
same_block_info,
|
||||
)
|
||||
},
|
||||
|| tx::store_tx_metadata(txs, txid_prefix_store, &mut tx_metadata),
|
||||
|| tx::store_tx_metadata(txs, sigops, txid_prefix_store, &mut tx_metadata),
|
||||
);
|
||||
|
||||
finalize_result?;
|
||||
|
||||
58
crates/brk_indexer/src/processor/sigops.rs
Normal file
58
crates/brk_indexer/src/processor/sigops.rs
Normal file
@@ -0,0 +1,58 @@
|
||||
use brk_types::{OutputType, SigOps, TxInIndex};
|
||||
use rayon::prelude::*;
|
||||
use smallvec::SmallVec;
|
||||
|
||||
use super::{BlockProcessor, InputSource};
|
||||
|
||||
impl BlockProcessor<'_> {
|
||||
/// BIP-141 sigop cost per tx in the block. Uses each input's prevout
|
||||
/// `OutputType` (already resolved by `process_inputs` for the
|
||||
/// previous-block case, looked up from `block.txdata` for the
|
||||
/// same-block case) to feed canonical-shaped synthetic prevouts into
|
||||
/// `bitcoin::Transaction::total_sigop_cost`.
|
||||
pub fn compute_sigops(&self, txins: &[(TxInIndex, InputSource)]) -> Vec<SigOps> {
|
||||
let txdata = &self.block.txdata;
|
||||
let base_tx_index = u32::from(self.indexes.tx_index);
|
||||
|
||||
let mut tx_input_offsets = Vec::with_capacity(txdata.len());
|
||||
let mut offset = 0usize;
|
||||
for tx in txdata {
|
||||
tx_input_offsets.push(offset);
|
||||
offset += tx.input.len();
|
||||
}
|
||||
|
||||
txdata
|
||||
.par_iter()
|
||||
.enumerate()
|
||||
.map(|(i, tx)| {
|
||||
if tx.is_coinbase() {
|
||||
return SigOps::ZERO;
|
||||
}
|
||||
let start = tx_input_offsets[i];
|
||||
let tx_inputs = &txins[start..start + tx.input.len()];
|
||||
|
||||
let kinds: SmallVec<[(bitcoin::OutPoint, OutputType); 4]> = tx
|
||||
.input
|
||||
.iter()
|
||||
.zip(tx_inputs.iter())
|
||||
.map(|(txin, (_, source))| {
|
||||
let kind = match source {
|
||||
InputSource::PreviousBlock { output_type, .. } => *output_type,
|
||||
InputSource::SameBlock { outpoint, .. } => {
|
||||
let local =
|
||||
(u32::from(outpoint.tx_index()) - base_tx_index) as usize;
|
||||
let vout = u32::from(outpoint.vout()) as usize;
|
||||
OutputType::from(&txdata[local].output[vout].script_pubkey)
|
||||
}
|
||||
};
|
||||
(txin.previous_output, kind)
|
||||
})
|
||||
.collect();
|
||||
|
||||
SigOps::of_bitcoin_tx_with_kinds(tx, |op| {
|
||||
kinds.iter().find(|(o, _)| o == op).map(|(_, k)| *k)
|
||||
})
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
use brk_error::{Error, Result};
|
||||
use brk_store::Store;
|
||||
use brk_types::{StoredBool, TxIndex, Txid, TxidPrefix};
|
||||
use brk_types::{SigOps, StoredBool, TxIndex, Txid, TxidPrefix};
|
||||
use rayon::prelude::*;
|
||||
use tracing::error;
|
||||
use vecdb::{AnyVec, WritableVec, likely};
|
||||
@@ -90,10 +90,12 @@ impl<'a> BlockProcessor<'a> {
|
||||
|
||||
pub(super) fn store_tx_metadata(
|
||||
txs: Vec<ComputedTx>,
|
||||
sigops: Vec<SigOps>,
|
||||
store: &mut Store<TxidPrefix, TxIndex>,
|
||||
md: &mut TxMetadataVecs<'_>,
|
||||
) -> Result<()> {
|
||||
for ct in txs {
|
||||
debug_assert_eq!(txs.len(), sigops.len());
|
||||
for (ct, sigops) in txs.into_iter().zip(sigops) {
|
||||
if ct.prev_tx_index_opt.is_none() {
|
||||
store.insert(ct.txid_prefix, ct.tx_index);
|
||||
}
|
||||
@@ -106,6 +108,7 @@ pub(super) fn store_tx_metadata(
|
||||
.checked_push(ct.tx_index, ct.base_size.into())?;
|
||||
md.total_size
|
||||
.checked_push(ct.tx_index, ct.total_size.into())?;
|
||||
md.total_sigop_cost.checked_push(ct.tx_index, sigops)?;
|
||||
md.is_explicitly_rbf
|
||||
.checked_push(ct.tx_index, StoredBool::from(ct.tx.is_explicitly_rbf()))?;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
use brk_error::Result;
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::{
|
||||
BlkPosition, Height, RawLockTime, StoredBool, StoredU32, TxInIndex, TxIndex, TxOutIndex,
|
||||
TxVersion, Txid, Version,
|
||||
BlkPosition, Height, RawLockTime, SigOps, StoredBool, StoredU32, TxInIndex, TxIndex,
|
||||
TxOutIndex, TxVersion, Txid, Version,
|
||||
};
|
||||
use rayon::prelude::*;
|
||||
use vecdb::{
|
||||
@@ -19,6 +19,7 @@ pub struct TransactionsVecs<M: StorageMode = Rw> {
|
||||
pub raw_locktime: M::Stored<PcoVec<TxIndex, RawLockTime>>,
|
||||
pub base_size: M::Stored<PcoVec<TxIndex, StoredU32>>,
|
||||
pub total_size: M::Stored<PcoVec<TxIndex, StoredU32>>,
|
||||
pub total_sigop_cost: M::Stored<PcoVec<TxIndex, SigOps>>,
|
||||
pub is_explicitly_rbf: M::Stored<PcoVec<TxIndex, StoredBool>>,
|
||||
pub first_txin_index: M::Stored<PcoVec<TxIndex, TxInIndex>>,
|
||||
pub first_txout_index: M::Stored<BytesVec<TxIndex, TxOutIndex>>,
|
||||
@@ -32,6 +33,7 @@ pub struct TxMetadataVecs<'a> {
|
||||
pub raw_locktime: &'a mut PcoVec<TxIndex, RawLockTime>,
|
||||
pub base_size: &'a mut PcoVec<TxIndex, StoredU32>,
|
||||
pub total_size: &'a mut PcoVec<TxIndex, StoredU32>,
|
||||
pub total_sigop_cost: &'a mut PcoVec<TxIndex, SigOps>,
|
||||
pub is_explicitly_rbf: &'a mut PcoVec<TxIndex, StoredBool>,
|
||||
}
|
||||
|
||||
@@ -52,6 +54,7 @@ impl TransactionsVecs {
|
||||
raw_locktime: &mut self.raw_locktime,
|
||||
base_size: &mut self.base_size,
|
||||
total_size: &mut self.total_size,
|
||||
total_sigop_cost: &mut self.total_sigop_cost,
|
||||
is_explicitly_rbf: &mut self.is_explicitly_rbf,
|
||||
},
|
||||
)
|
||||
@@ -65,6 +68,7 @@ impl TransactionsVecs {
|
||||
raw_locktime,
|
||||
base_size,
|
||||
total_size,
|
||||
total_sigop_cost,
|
||||
is_explicitly_rbf,
|
||||
first_txin_index,
|
||||
first_txout_index,
|
||||
@@ -76,6 +80,7 @@ impl TransactionsVecs {
|
||||
raw_locktime = PcoVec::forced_import(db, "raw_locktime", version),
|
||||
base_size = PcoVec::forced_import(db, "base_size", version),
|
||||
total_size = PcoVec::forced_import(db, "total_size", version),
|
||||
total_sigop_cost = PcoVec::forced_import(db, "total_sigop_cost", version),
|
||||
is_explicitly_rbf = PcoVec::forced_import(db, "is_explicitly_rbf", version),
|
||||
first_txin_index = PcoVec::forced_import(db, "first_txin_index", version),
|
||||
first_txout_index = BytesVec::forced_import(db, "first_txout_index", version),
|
||||
@@ -88,6 +93,7 @@ impl TransactionsVecs {
|
||||
raw_locktime,
|
||||
base_size,
|
||||
total_size,
|
||||
total_sigop_cost,
|
||||
is_explicitly_rbf,
|
||||
first_txin_index,
|
||||
first_txout_index,
|
||||
@@ -107,6 +113,8 @@ impl TransactionsVecs {
|
||||
.truncate_if_needed_with_stamp(tx_index, stamp)?;
|
||||
self.total_size
|
||||
.truncate_if_needed_with_stamp(tx_index, stamp)?;
|
||||
self.total_sigop_cost
|
||||
.truncate_if_needed_with_stamp(tx_index, stamp)?;
|
||||
self.is_explicitly_rbf
|
||||
.truncate_if_needed_with_stamp(tx_index, stamp)?;
|
||||
self.first_txin_index
|
||||
@@ -126,6 +134,7 @@ impl TransactionsVecs {
|
||||
&mut self.raw_locktime,
|
||||
&mut self.base_size,
|
||||
&mut self.total_size,
|
||||
&mut self.total_sigop_cost,
|
||||
&mut self.is_explicitly_rbf,
|
||||
&mut self.first_txin_index,
|
||||
&mut self.first_txout_index,
|
||||
|
||||
Reference in New Issue
Block a user