diff --git a/crates/brk_indexer/src/readers.rs b/crates/brk_indexer/src/readers.rs index d0c1ec638..e015ba29b 100644 --- a/crates/brk_indexer/src/readers.rs +++ b/crates/brk_indexer/src/readers.rs @@ -1,8 +1,9 @@ +use bitcoin::ScriptBuf; use brk_types::{ - OutputType, P2AAddressIndex, P2ABytes, P2PK33AddressIndex, P2PK33Bytes, P2PK65AddressIndex, - P2PK65Bytes, P2PKHAddressIndex, P2PKHBytes, P2SHAddressIndex, P2SHBytes, P2TRAddressIndex, - P2TRBytes, P2WPKHAddressIndex, P2WPKHBytes, P2WSHAddressIndex, P2WSHBytes, TxIndex, TxOutIndex, - Txid, TypeIndex, + AddressBytes, OutputType, P2AAddressIndex, P2ABytes, P2PK33AddressIndex, P2PK33Bytes, + P2PK65AddressIndex, P2PK65Bytes, P2PKHAddressIndex, P2PKHBytes, P2SHAddressIndex, P2SHBytes, + P2TRAddressIndex, P2TRBytes, P2WPKHAddressIndex, P2WPKHBytes, P2WSHAddressIndex, P2WSHBytes, + TxIndex, TxOutIndex, Txid, TypeIndex, }; use vecdb::{BytesStrategy, VecReader}; @@ -19,6 +20,24 @@ pub struct AddressReaders { pub p2a: VecReader>, } +impl AddressReaders { + pub fn script_pubkey(&self, outputtype: OutputType, typeindex: TypeIndex) -> ScriptBuf { + let idx = usize::from(typeindex); + let bytes: Option = match outputtype { + OutputType::P2PK65 => self.p2pk65.try_get(idx).map(Into::into), + OutputType::P2PK33 => self.p2pk33.try_get(idx).map(Into::into), + OutputType::P2PKH => self.p2pkh.try_get(idx).map(Into::into), + OutputType::P2SH => self.p2sh.try_get(idx).map(Into::into), + OutputType::P2WPKH => self.p2wpkh.try_get(idx).map(Into::into), + OutputType::P2WSH => self.p2wsh.try_get(idx).map(Into::into), + OutputType::P2TR => self.p2tr.try_get(idx).map(Into::into), + OutputType::P2A => self.p2a.try_get(idx).map(Into::into), + _ => None, + }; + bytes.map(|b| b.to_script_pubkey()).unwrap_or_default() + } +} + /// Readers for vectors that need to be accessed during block processing. /// /// All fields use `VecReader` which caches the mmap base pointer for O(1) @@ -38,16 +57,7 @@ impl Readers { txindex_to_first_txoutindex: vecs.transactions.first_txoutindex.reader(), txoutindex_to_outputtype: vecs.outputs.outputtype.reader(), txoutindex_to_typeindex: vecs.outputs.typeindex.reader(), - addressbytes: AddressReaders { - p2pk65: vecs.addresses.p2pk65.bytes.reader(), - p2pk33: vecs.addresses.p2pk33.bytes.reader(), - p2pkh: vecs.addresses.p2pkh.bytes.reader(), - p2sh: vecs.addresses.p2sh.bytes.reader(), - p2wpkh: vecs.addresses.p2wpkh.bytes.reader(), - p2wsh: vecs.addresses.p2wsh.bytes.reader(), - p2tr: vecs.addresses.p2tr.bytes.reader(), - p2a: vecs.addresses.p2a.bytes.reader(), - }, + addressbytes: vecs.addresses.address_readers(), } } } diff --git a/crates/brk_indexer/src/vecs/addresses.rs b/crates/brk_indexer/src/vecs/addresses.rs index ca4c9775d..12c0d0c8c 100644 --- a/crates/brk_indexer/src/vecs/addresses.rs +++ b/crates/brk_indexer/src/vecs/addresses.rs @@ -9,10 +9,9 @@ use brk_types::{ use rayon::prelude::*; use schemars::JsonSchema; use serde::Serialize; -use bitcoin::ScriptBuf; use vecdb::{ AnyStoredVec, BytesVec, BytesVecValue, Database, Formattable, ImportableVec, PcoVec, - PcoVecValue, ReadableVec, Rw, Stamp, StorageMode, VecIndex, WritableVec, + PcoVecValue, ReadableVec, Ro, Rw, Stamp, StorageMode, VecIndex, WritableVec, }; use crate::parallel_import; @@ -259,19 +258,24 @@ impl AddressesVecs { } } -impl AddressesVecs { - pub fn script_pubkey(&self, outputtype: OutputType, typeindex: TypeIndex) -> ScriptBuf { - let bytes: Option = match outputtype { - OutputType::P2PK65 => self.p2pk65.bytes.collect_one(typeindex.into()).map(Into::into), - OutputType::P2PK33 => self.p2pk33.bytes.collect_one(typeindex.into()).map(Into::into), - OutputType::P2PKH => self.p2pkh.bytes.collect_one(typeindex.into()).map(Into::into), - OutputType::P2SH => self.p2sh.bytes.collect_one(typeindex.into()).map(Into::into), - OutputType::P2WPKH => self.p2wpkh.bytes.collect_one(typeindex.into()).map(Into::into), - OutputType::P2WSH => self.p2wsh.bytes.collect_one(typeindex.into()).map(Into::into), - OutputType::P2TR => self.p2tr.bytes.collect_one(typeindex.into()).map(Into::into), - OutputType::P2A => self.p2a.bytes.collect_one(typeindex.into()).map(Into::into), - _ => None, - }; - bytes.map(|b| b.to_script_pubkey()).unwrap_or_default() - } +macro_rules! impl_address_readers { + ($mode:ty) => { + impl AddressesVecs<$mode> { + pub fn address_readers(&self) -> AddressReaders { + AddressReaders { + p2pk65: self.p2pk65.bytes.reader(), + p2pk33: self.p2pk33.bytes.reader(), + p2pkh: self.p2pkh.bytes.reader(), + p2sh: self.p2sh.bytes.reader(), + p2wpkh: self.p2wpkh.bytes.reader(), + p2wsh: self.p2wsh.bytes.reader(), + p2tr: self.p2tr.bytes.reader(), + p2a: self.p2a.bytes.reader(), + } + } + } + }; } + +impl_address_readers!(Rw); +impl_address_readers!(Ro); diff --git a/crates/brk_query/src/impl/transaction.rs b/crates/brk_query/src/impl/transaction.rs index ca15e6d6f..35b8d0b9e 100644 --- a/crates/brk_query/src/impl/transaction.rs +++ b/crates/brk_query/src/impl/transaction.rs @@ -244,6 +244,7 @@ impl Query { let value_reader = indexer.vecs.outputs.value.reader(); let outputtype_reader = indexer.vecs.outputs.outputtype.reader(); let typeindex_reader = indexer.vecs.outputs.typeindex.reader(); + let address_readers = indexer.vecs.addresses.address_readers(); // Batch-read outpoints for all inputs (avoids per-input PcoVec page decompression) let outpoints: Vec<_> = indexer.vecs.inputs.outpoint.collect_range_at( @@ -278,10 +279,8 @@ impl Query { let prev_outputtype: OutputType = outputtype_reader.get(usize::from(prev_txoutindex)); let prev_typeindex = typeindex_reader.get(usize::from(prev_txoutindex)); - let script_pubkey = indexer - .vecs - .addresses - .script_pubkey(prev_outputtype, prev_typeindex); + let script_pubkey = + address_readers.script_pubkey(prev_outputtype, prev_typeindex); let prevout = Some(TxOut::from((script_pubkey, prev_value)));