global: snapshot

This commit is contained in:
nym21
2025-03-01 15:22:34 +01:00
parent 1b93ccf608
commit 6d7ff38cf2
40 changed files with 936 additions and 768 deletions

View File

@@ -14,7 +14,7 @@ Vecs are used sparingly instead of stores for multiple reasons:
Storage wise, the expected overhead should be around 30% of the chain itself.
Peaks at 11-13 GB of RAM
Peaks at 5 GB of RAM
## Outputs
@@ -27,3 +27,12 @@ Stores: `src/storage/stores/mod.rs`
Rust: `src/main.rs`
Python: `../python/parse.py`
## Benchmark
Indexing `0..885_835` took `11 hours 6 min 50 s` on a Macbook Pro M3 Pro with 36 GB of RAM
`footprint` report:
- Peak memory: `5115 MB`
- Memory while waiting for a new block: `890 MB`
- Reclaimable memory: `6478 MB`

View File

@@ -4,7 +4,6 @@ use brk_core::{
P2SHindex, P2TRindex, P2WPKHindex, P2WSHindex, Pushonlyindex, Txindex, Txinindex, Txoutindex, Unknownindex,
};
use brk_parser::NUMBER_OF_UNSAFE_BLOCKS;
use brk_vec::CACHED_GETS;
use color_eyre::eyre::ContextCompat;
use crate::{Stores, Vecs};
@@ -31,7 +30,7 @@ pub struct Indexes {
}
impl Indexes {
pub fn push_if_needed(&self, vecs: &mut Vecs<CACHED_GETS>) -> brk_vec::Result<()> {
pub fn push_if_needed(&self, vecs: &mut Vecs) -> brk_vec::Result<()> {
let height = self.height;
vecs.height_to_first_txindex.push_if_needed(height, self.txindex)?;
vecs.height_to_first_txinindex.push_if_needed(height, self.txinindex)?;
@@ -64,7 +63,7 @@ impl Indexes {
Ok(())
}
pub fn push_future_if_needed(&mut self, vecs: &mut Vecs<CACHED_GETS>) -> brk_vec::Result<()> {
pub fn push_future_if_needed(&mut self, vecs: &mut Vecs) -> brk_vec::Result<()> {
self.height.increment();
self.push_if_needed(vecs)?;
self.height.decrement();
@@ -72,9 +71,9 @@ impl Indexes {
}
}
impl TryFrom<(&mut Vecs<CACHED_GETS>, &Stores, &Client)> for Indexes {
impl TryFrom<(&mut Vecs, &Stores, &Client)> for Indexes {
type Error = color_eyre::Report;
fn try_from((vecs, stores, rpc): (&mut Vecs<CACHED_GETS>, &Stores, &Client)) -> color_eyre::Result<Self> {
fn try_from((vecs, stores, rpc): (&mut Vecs, &Stores, &Client)) -> color_eyre::Result<Self> {
// Height at which we wanna start: min last saved + 1 or 0
let starting_height = vecs.starting_height().min(stores.starting_height());

View File

@@ -1,4 +1,7 @@
#![doc = include_str!("../README.md")]
#![doc = "\n## Example\n\n```rust"]
#![doc = include_str!("main.rs")]
#![doc = "```"]
use std::{
collections::BTreeMap,
@@ -15,7 +18,6 @@ pub use brk_parser::*;
use bitcoin::{Transaction, TxIn, TxOut};
use brk_exit::Exit;
use brk_vec::CACHED_GETS;
use color_eyre::eyre::{ContextCompat, eyre};
use log::info;
use rayon::prelude::*;
@@ -29,12 +31,13 @@ pub use vecs::*;
const SNAPSHOT_BLOCK_RANGE: usize = 1000;
pub struct Indexer<const MODE: u8> {
pub vecs: Vecs<MODE>,
#[derive(Clone)]
pub struct Indexer {
pub vecs: Vecs,
pub stores: Stores,
}
impl<const MODE: u8> Indexer<MODE> {
impl Indexer {
pub fn import(indexes_dir: &Path) -> color_eyre::Result<Self> {
setrlimit()?;
@@ -42,13 +45,11 @@ impl<const MODE: u8> Indexer<MODE> {
let vecs = Vecs::import(&indexes_dir.join("vecs"))?;
let stores = Stores::import(&indexes_dir.join("fjall"))?;
let stores = Stores::import(&indexes_dir.join("stores"))?;
Ok(Self { vecs, stores })
}
}
impl Indexer<CACHED_GETS> {
pub fn index(&mut self, parser: &Parser, rpc: &'static rpc::Client, exit: &Exit) -> color_eyre::Result<Indexes> {
let check_collisions = true;
@@ -63,35 +64,35 @@ impl Indexer<CACHED_GETS> {
self.vecs.rollback_if_needed(&starting_indexes)?;
exit.release();
let export_if_needed = |stores: &mut Stores,
vecs: &mut Vecs<CACHED_GETS>,
height: Height,
rem: bool,
exit: &Exit|
-> color_eyre::Result<()> {
if height == 0 || (height % SNAPSHOT_BLOCK_RANGE != 0) != rem || exit.triggered() {
return Ok(());
}
let export_if_needed =
|stores: &mut Stores, vecs: &mut Vecs, height: Height, rem: bool, exit: &Exit| -> color_eyre::Result<()> {
if height == 0 || (height % SNAPSHOT_BLOCK_RANGE != 0) != rem || exit.triggered() {
return Ok(());
}
info!("Exporting...");
exit.block();
stores.commit(height)?;
vecs.flush(height)?;
exit.release();
Ok(())
};
info!("Exporting...");
exit.block();
stores.commit(height)?;
vecs.flush(height)?;
exit.release();
Ok(())
};
let vecs = &mut self.vecs;
let stores = &mut self.stores;
if starting_indexes.height > Height::try_from(rpc)? {
let mut idxs = starting_indexes.clone();
let start = Some(idxs.height);
let end = None; //Some(Height::new(400_000));
if starting_indexes.height > Height::try_from(rpc)? || end.is_some_and(|end| starting_indexes.height > end) {
return Ok(starting_indexes);
}
info!("Started indexing...");
let mut idxs = starting_indexes.clone();
parser.parse(Some(idxs.height), None).iter().try_for_each(
parser.parse(start, None).iter().try_for_each(
|(height, block, blockhash)| -> color_eyre::Result<()> {
info!("Indexing block {height}...");
@@ -634,6 +635,8 @@ impl Indexer<CACHED_GETS> {
export_if_needed(stores, vecs, idxs.height, true, exit)?;
stores.rotate_memtables();
Ok(starting_indexes)
}
}

View File

@@ -6,7 +6,6 @@ use brk_parser::{
Parser,
rpc::{self},
};
use brk_vec::CACHED_GETS;
use log::info;
fn main() -> color_eyre::Result<()> {
@@ -23,13 +22,13 @@ fn main() -> color_eyre::Result<()> {
let parser = Parser::new(data_dir, rpc);
let mut indexer: Indexer<CACHED_GETS> = Indexer::import(Path::new("../../_outputs/indexes"))?;
loop {
let block_count = rpc.get_block_count()?;
info!("{block_count} blocks found.");
let mut indexer = Indexer::import(Path::new("../../_outputs/indexed"))?;
indexer.index(&parser, rpc, &exit)?;
info!("Waiting for new blocks...");

View File

@@ -136,6 +136,10 @@ where
Ok(())
}
pub fn rotate_memtable(&self) {
let _ = self.part.inner().rotate_memtable();
}
pub fn height(&self) -> Option<Height> {
self.meta.height()
}
@@ -155,7 +159,9 @@ where
}
fn open_keyspace(path: &Path) -> Result<TransactionalKeyspace> {
fjall::Config::new(path.join("fjall")).open_transactional()
fjall::Config::new(path.join("fjall"))
.max_write_buffer_size(32 * 1024 * 1024)
.open_transactional()
}
fn open_partition_handle(keyspace: &TransactionalKeyspace) -> Result<TransactionalPartitionHandle> {
@@ -163,6 +169,7 @@ where
"partition",
PartitionCreateOptions::default()
.bloom_filter_bits(Some(5))
.max_memtable_size(8 * 1024 * 1024)
.manual_journal_persist(true),
)
}

View File

@@ -1,7 +1,7 @@
use std::{path::Path, thread};
use brk_core::{AddressHash, Addressbytes, Addressindex, Addresstype, BlockHashPrefix, Height, TxidPrefix, Txindex};
use brk_vec::{CACHED_GETS, Value, Version};
use brk_vec::{Value, Version};
use crate::Indexes;
@@ -38,14 +38,9 @@ impl Stores {
})
}
pub fn rollback_if_needed(
&mut self,
vecs: &Vecs<CACHED_GETS>,
starting_indexes: &Indexes,
) -> color_eyre::Result<()> {
pub fn rollback_if_needed(&mut self, vecs: &Vecs, starting_indexes: &Indexes) -> color_eyre::Result<()> {
vecs.height_to_blockhash
.iter_from(starting_indexes.height, |(_, blockhash)| {
let blockhash = blockhash.as_ref();
let blockhash_prefix = BlockHashPrefix::from(blockhash);
self.blockhash_prefix_to_height.remove(blockhash_prefix);
Ok(())
@@ -53,7 +48,6 @@ impl Stores {
vecs.txindex_to_txid
.iter_from(starting_indexes.txindex, |(_txindex, txid)| {
let txid = txid.as_ref();
let txid_prefix = TxidPrefix::from(txid);
self.txid_prefix_to_txindex.remove(txid_prefix);
Ok(())
@@ -173,4 +167,10 @@ impl Stores {
Ok(())
})
}
pub fn rotate_memtables(&self) {
self.addresshash_to_addressindex.rotate_memtable();
self.blockhash_prefix_to_height.rotate_memtable();
self.txid_prefix_to_txindex.rotate_memtable();
}
}

View File

@@ -5,25 +5,29 @@ use std::{
path::{Path, PathBuf},
};
use brk_vec::{CACHED_GETS, StoredIndex, StoredType, Version};
use brk_vec::{StoredIndex, StoredType, Version};
use super::Height;
#[derive(Debug)]
pub struct StorableVec<I, T, const MODE: u8> {
pub struct StorableVec<I, T> {
height: Option<Height>,
vec: brk_vec::StorableVec<I, T, MODE>,
vec: brk_vec::StorableVec<I, T>,
}
impl<I, T, const MODE: u8> StorableVec<I, T, MODE>
impl<I, T> StorableVec<I, T>
where
I: StoredIndex,
T: StoredType,
{
pub fn import(path: &Path, version: Version) -> brk_vec::Result<Self> {
let mut vec = brk_vec::StorableVec::forced_import(path, version)?;
vec.reset_mmaps()?;
Ok(Self {
height: Height::try_from(Self::path_height_(path).as_path()).ok(),
vec: brk_vec::StorableVec::forced_import(path, version)?,
vec,
})
}
@@ -43,37 +47,44 @@ where
fn path_height_(path: &Path) -> PathBuf {
path.join("height")
}
}
impl<I, T> StorableVec<I, T, CACHED_GETS>
where
I: StoredIndex,
T: StoredType,
{
pub fn flush(&mut self, height: Height) -> io::Result<()> {
height.write(&self.path_height())?;
self.vec.flush()
self.vec.flush()?;
self.vec.reset_mmaps()
}
}
impl<I, T, const MODE: u8> Deref for StorableVec<I, T, MODE> {
type Target = brk_vec::StorableVec<I, T, MODE>;
impl<I, T> Deref for StorableVec<I, T> {
type Target = brk_vec::StorableVec<I, T>;
fn deref(&self) -> &Self::Target {
&self.vec
}
}
impl<I, T, const MODE: u8> DerefMut for StorableVec<I, T, MODE> {
impl<I, T> DerefMut for StorableVec<I, T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.vec
}
}
impl<I, T> Clone for StorableVec<I, T>
where
I: StoredIndex,
T: StoredType,
{
fn clone(&self) -> Self {
Self {
height: self.height,
vec: self.vec.clone(),
}
}
}
pub trait AnyStorableVec: Send + Sync {
pub trait AnyIndexedVec: Send + Sync {
fn height(&self) -> brk_core::Result<Height>;
fn flush(&mut self, height: Height) -> io::Result<()>;
}
impl<I, T> AnyStorableVec for StorableVec<I, T, CACHED_GETS>
impl<I, T> AnyIndexedVec for StorableVec<I, T>
where
I: StoredIndex,
T: StoredType,

View File

@@ -6,7 +6,7 @@ use brk_core::{
P2SHAddressBytes, P2SHindex, P2TRAddressBytes, P2TRindex, P2WPKHAddressBytes, P2WPKHindex, P2WSHAddressBytes,
P2WSHindex, Pushonlyindex, Sats, Timestamp, TxVersion, Txid, Txindex, Txinindex, Txoutindex, Unknownindex, Weight,
};
use brk_vec::{AnyJsonStorableVec, CACHED_GETS, Version};
use brk_vec::{AnyStorableVec, Version};
use rayon::prelude::*;
use crate::Indexes;
@@ -15,53 +15,54 @@ mod base;
pub use base::*;
pub struct Vecs<const MODE: u8> {
pub addressindex_to_addresstype: StorableVec<Addressindex, Addresstype, MODE>,
pub addressindex_to_addresstypeindex: StorableVec<Addressindex, Addresstypeindex, MODE>,
pub addressindex_to_height: StorableVec<Addressindex, Height, MODE>,
pub height_to_blockhash: StorableVec<Height, BlockHash, MODE>,
pub height_to_difficulty: StorableVec<Height, f64, MODE>,
pub height_to_first_addressindex: StorableVec<Height, Addressindex, MODE>,
pub height_to_first_emptyindex: StorableVec<Height, Emptyindex, MODE>,
pub height_to_first_multisigindex: StorableVec<Height, Multisigindex, MODE>,
pub height_to_first_opreturnindex: StorableVec<Height, Opreturnindex, MODE>,
pub height_to_first_pushonlyindex: StorableVec<Height, Pushonlyindex, MODE>,
pub height_to_first_txindex: StorableVec<Height, Txindex, MODE>,
pub height_to_first_txinindex: StorableVec<Height, Txinindex, MODE>,
pub height_to_first_txoutindex: StorableVec<Height, Txoutindex, MODE>,
pub height_to_first_unknownindex: StorableVec<Height, Unknownindex, MODE>,
pub height_to_first_p2pk33index: StorableVec<Height, P2PK33index, MODE>,
pub height_to_first_p2pk65index: StorableVec<Height, P2PK65index, MODE>,
pub height_to_first_p2pkhindex: StorableVec<Height, P2PKHindex, MODE>,
pub height_to_first_p2shindex: StorableVec<Height, P2SHindex, MODE>,
pub height_to_first_p2trindex: StorableVec<Height, P2TRindex, MODE>,
pub height_to_first_p2wpkhindex: StorableVec<Height, P2WPKHindex, MODE>,
pub height_to_first_p2wshindex: StorableVec<Height, P2WSHindex, MODE>,
pub height_to_size: StorableVec<Height, usize, MODE>,
pub height_to_timestamp: StorableVec<Height, Timestamp, MODE>,
pub height_to_weight: StorableVec<Height, Weight, MODE>,
pub p2pk33index_to_p2pk33addressbytes: StorableVec<P2PK33index, P2PK33AddressBytes, MODE>,
pub p2pk65index_to_p2pk65addressbytes: StorableVec<P2PK65index, P2PK65AddressBytes, MODE>,
pub p2pkhindex_to_p2pkhaddressbytes: StorableVec<P2PKHindex, P2PKHAddressBytes, MODE>,
pub p2shindex_to_p2shaddressbytes: StorableVec<P2SHindex, P2SHAddressBytes, MODE>,
pub p2trindex_to_p2traddressbytes: StorableVec<P2TRindex, P2TRAddressBytes, MODE>,
pub p2wpkhindex_to_p2wpkhaddressbytes: StorableVec<P2WPKHindex, P2WPKHAddressBytes, MODE>,
pub p2wshindex_to_p2wshaddressbytes: StorableVec<P2WSHindex, P2WSHAddressBytes, MODE>,
pub txindex_to_first_txinindex: StorableVec<Txindex, Txinindex, MODE>,
pub txindex_to_first_txoutindex: StorableVec<Txindex, Txoutindex, MODE>,
pub txindex_to_height: StorableVec<Txindex, Height, MODE>,
pub txindex_to_locktime: StorableVec<Txindex, LockTime, MODE>,
pub txindex_to_txid: StorableVec<Txindex, Txid, MODE>,
pub txindex_to_base_size: StorableVec<Txindex, usize, MODE>,
pub txindex_to_total_size: StorableVec<Txindex, usize, MODE>,
pub txindex_to_is_explicitly_rbf: StorableVec<Txindex, bool, MODE>,
pub txindex_to_txversion: StorableVec<Txindex, TxVersion, MODE>,
pub txinindex_to_txoutindex: StorableVec<Txinindex, Txoutindex, MODE>,
pub txoutindex_to_addressindex: StorableVec<Txoutindex, Addressindex, MODE>,
pub txoutindex_to_value: StorableVec<Txoutindex, Sats, MODE>,
#[derive(Clone)]
pub struct Vecs {
pub addressindex_to_addresstype: StorableVec<Addressindex, Addresstype>,
pub addressindex_to_addresstypeindex: StorableVec<Addressindex, Addresstypeindex>,
pub addressindex_to_height: StorableVec<Addressindex, Height>,
pub height_to_blockhash: StorableVec<Height, BlockHash>,
pub height_to_difficulty: StorableVec<Height, f64>,
pub height_to_first_addressindex: StorableVec<Height, Addressindex>,
pub height_to_first_emptyindex: StorableVec<Height, Emptyindex>,
pub height_to_first_multisigindex: StorableVec<Height, Multisigindex>,
pub height_to_first_opreturnindex: StorableVec<Height, Opreturnindex>,
pub height_to_first_pushonlyindex: StorableVec<Height, Pushonlyindex>,
pub height_to_first_txindex: StorableVec<Height, Txindex>,
pub height_to_first_txinindex: StorableVec<Height, Txinindex>,
pub height_to_first_txoutindex: StorableVec<Height, Txoutindex>,
pub height_to_first_unknownindex: StorableVec<Height, Unknownindex>,
pub height_to_first_p2pk33index: StorableVec<Height, P2PK33index>,
pub height_to_first_p2pk65index: StorableVec<Height, P2PK65index>,
pub height_to_first_p2pkhindex: StorableVec<Height, P2PKHindex>,
pub height_to_first_p2shindex: StorableVec<Height, P2SHindex>,
pub height_to_first_p2trindex: StorableVec<Height, P2TRindex>,
pub height_to_first_p2wpkhindex: StorableVec<Height, P2WPKHindex>,
pub height_to_first_p2wshindex: StorableVec<Height, P2WSHindex>,
pub height_to_size: StorableVec<Height, usize>,
pub height_to_timestamp: StorableVec<Height, Timestamp>,
pub height_to_weight: StorableVec<Height, Weight>,
pub p2pk33index_to_p2pk33addressbytes: StorableVec<P2PK33index, P2PK33AddressBytes>,
pub p2pk65index_to_p2pk65addressbytes: StorableVec<P2PK65index, P2PK65AddressBytes>,
pub p2pkhindex_to_p2pkhaddressbytes: StorableVec<P2PKHindex, P2PKHAddressBytes>,
pub p2shindex_to_p2shaddressbytes: StorableVec<P2SHindex, P2SHAddressBytes>,
pub p2trindex_to_p2traddressbytes: StorableVec<P2TRindex, P2TRAddressBytes>,
pub p2wpkhindex_to_p2wpkhaddressbytes: StorableVec<P2WPKHindex, P2WPKHAddressBytes>,
pub p2wshindex_to_p2wshaddressbytes: StorableVec<P2WSHindex, P2WSHAddressBytes>,
pub txindex_to_first_txinindex: StorableVec<Txindex, Txinindex>,
pub txindex_to_first_txoutindex: StorableVec<Txindex, Txoutindex>,
pub txindex_to_height: StorableVec<Txindex, Height>,
pub txindex_to_locktime: StorableVec<Txindex, LockTime>,
pub txindex_to_txid: StorableVec<Txindex, Txid>,
pub txindex_to_base_size: StorableVec<Txindex, usize>,
pub txindex_to_total_size: StorableVec<Txindex, usize>,
pub txindex_to_is_explicitly_rbf: StorableVec<Txindex, bool>,
pub txindex_to_txversion: StorableVec<Txindex, TxVersion>,
pub txinindex_to_txoutindex: StorableVec<Txinindex, Txoutindex>,
pub txoutindex_to_addressindex: StorableVec<Txoutindex, Addressindex>,
pub txoutindex_to_value: StorableVec<Txoutindex, Sats>,
}
impl<const MODE: u8> Vecs<MODE> {
impl Vecs {
pub fn import(path: &Path) -> color_eyre::Result<Self> {
fs::create_dir_all(path)?;
@@ -293,56 +294,6 @@ impl<const MODE: u8> Vecs<MODE> {
Ok(())
}
pub fn as_any_json_vecs(&self) -> Vec<&dyn AnyJsonStorableVec> {
vec![
&*self.addressindex_to_addresstype as &dyn AnyJsonStorableVec,
&*self.addressindex_to_addresstypeindex,
&*self.addressindex_to_height,
&*self.height_to_blockhash,
&*self.height_to_difficulty,
&*self.height_to_first_addressindex,
&*self.height_to_first_emptyindex,
&*self.height_to_first_multisigindex,
&*self.height_to_first_opreturnindex,
&*self.height_to_first_pushonlyindex,
&*self.height_to_first_txindex,
&*self.height_to_first_txinindex,
&*self.height_to_first_txoutindex,
&*self.height_to_first_unknownindex,
&*self.height_to_first_p2pk33index,
&*self.height_to_first_p2pk65index,
&*self.height_to_first_p2pkhindex,
&*self.height_to_first_p2shindex,
&*self.height_to_first_p2trindex,
&*self.height_to_first_p2wpkhindex,
&*self.height_to_first_p2wshindex,
&*self.height_to_size,
&*self.height_to_timestamp,
&*self.height_to_weight,
&*self.p2pk33index_to_p2pk33addressbytes,
&*self.p2pk65index_to_p2pk65addressbytes,
&*self.p2pkhindex_to_p2pkhaddressbytes,
&*self.p2shindex_to_p2shaddressbytes,
&*self.p2trindex_to_p2traddressbytes,
&*self.p2wpkhindex_to_p2wpkhaddressbytes,
&*self.p2wshindex_to_p2wshaddressbytes,
&*self.txindex_to_first_txinindex,
&*self.txindex_to_first_txoutindex,
&*self.txindex_to_height,
&*self.txindex_to_locktime,
&*self.txindex_to_txid,
&*self.txindex_to_base_size,
&*self.txindex_to_total_size,
&*self.txindex_to_is_explicitly_rbf,
&*self.txindex_to_txversion,
&*self.txinindex_to_txoutindex,
&*self.txoutindex_to_addressindex,
&*self.txoutindex_to_value,
]
}
}
impl Vecs<CACHED_GETS> {
pub fn get_addressbytes(
&self,
addresstype: Addresstype,
@@ -424,9 +375,57 @@ impl Vecs<CACHED_GETS> {
.unwrap()
}
fn as_mut_any_vecs(&mut self) -> Vec<&mut dyn AnyStorableVec> {
pub fn as_any_vecs(&self) -> Vec<&dyn AnyStorableVec> {
vec![
&mut self.addressindex_to_addresstype as &mut dyn AnyStorableVec,
&*self.addressindex_to_addresstype as &dyn AnyStorableVec,
&*self.addressindex_to_addresstypeindex,
&*self.addressindex_to_height,
&*self.height_to_blockhash,
&*self.height_to_difficulty,
&*self.height_to_first_addressindex,
&*self.height_to_first_emptyindex,
&*self.height_to_first_multisigindex,
&*self.height_to_first_opreturnindex,
&*self.height_to_first_pushonlyindex,
&*self.height_to_first_txindex,
&*self.height_to_first_txinindex,
&*self.height_to_first_txoutindex,
&*self.height_to_first_unknownindex,
&*self.height_to_first_p2pk33index,
&*self.height_to_first_p2pk65index,
&*self.height_to_first_p2pkhindex,
&*self.height_to_first_p2shindex,
&*self.height_to_first_p2trindex,
&*self.height_to_first_p2wpkhindex,
&*self.height_to_first_p2wshindex,
&*self.height_to_size,
&*self.height_to_timestamp,
&*self.height_to_weight,
&*self.p2pk33index_to_p2pk33addressbytes,
&*self.p2pk65index_to_p2pk65addressbytes,
&*self.p2pkhindex_to_p2pkhaddressbytes,
&*self.p2shindex_to_p2shaddressbytes,
&*self.p2trindex_to_p2traddressbytes,
&*self.p2wpkhindex_to_p2wpkhaddressbytes,
&*self.p2wshindex_to_p2wshaddressbytes,
&*self.txindex_to_first_txinindex,
&*self.txindex_to_first_txoutindex,
&*self.txindex_to_height,
&*self.txindex_to_locktime,
&*self.txindex_to_txid,
&*self.txindex_to_base_size,
&*self.txindex_to_total_size,
&*self.txindex_to_is_explicitly_rbf,
&*self.txindex_to_txversion,
&*self.txinindex_to_txoutindex,
&*self.txoutindex_to_addressindex,
&*self.txoutindex_to_value,
]
}
fn as_mut_any_vecs(&mut self) -> Vec<&mut dyn AnyIndexedVec> {
vec![
&mut self.addressindex_to_addresstype as &mut dyn AnyIndexedVec,
&mut self.addressindex_to_addresstypeindex,
&mut self.addressindex_to_height,
&mut self.height_to_blockhash,