mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-05-12 20:38:36 -07:00
global: snapshot
This commit is contained in:
@@ -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`
|
||||
|
||||
@@ -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());
|
||||
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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...");
|
||||
|
||||
@@ -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),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user