mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-07-14 20:48:12 -07:00
indexer: improved rollback; global: snapshot
This commit is contained in:
@@ -1,4 +1,8 @@
|
||||
use std::{collections::BTreeMap, error, mem, path::Path};
|
||||
use std::{
|
||||
collections::{BTreeMap, BTreeSet},
|
||||
error, mem,
|
||||
path::Path,
|
||||
};
|
||||
|
||||
use fjall::{
|
||||
PartitionCreateOptions, PersistMode, ReadTransaction, Result, Slice, TransactionalKeyspace,
|
||||
@@ -17,8 +21,11 @@ pub struct Store<Key, Value> {
|
||||
part: TransactionalPartitionHandle,
|
||||
rtx: ReadTransaction,
|
||||
puts: BTreeMap<Key, Value>,
|
||||
dels: BTreeSet<Key>,
|
||||
}
|
||||
|
||||
const CHECK_COLLISISONS: bool = true;
|
||||
|
||||
impl<K, V> Store<K, V>
|
||||
where
|
||||
K: Into<Slice> + Ord + Immutable + IntoBytes,
|
||||
@@ -48,6 +55,7 @@ where
|
||||
part,
|
||||
rtx,
|
||||
puts: BTreeMap::new(),
|
||||
dels: BTreeSet::new(),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -63,21 +71,44 @@ where
|
||||
|
||||
pub fn insert_if_needed(&mut self, key: K, value: V, height: Height) {
|
||||
if self.needs(height) {
|
||||
if !self.dels.is_empty() {
|
||||
unreachable!("Shouldn't reach this");
|
||||
// self.dels.remove(&key);
|
||||
}
|
||||
self.puts.insert(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn remove(&mut self, key: K) {
|
||||
if !self.puts.is_empty() {
|
||||
unreachable!("Shouldn't reach this");
|
||||
// self.puts.remove(&key);
|
||||
}
|
||||
self.dels.insert(key);
|
||||
}
|
||||
|
||||
pub fn commit(&mut self, height: Height) -> Result<()> {
|
||||
if self.has(height) && self.puts.is_empty() {
|
||||
if self.has(height) && self.puts.is_empty() && self.dels.is_empty() {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
self.meta.export(self.len(), height)?;
|
||||
|
||||
let mut wtx = self.keyspace.write_tx();
|
||||
mem::take(&mut self.puts)
|
||||
|
||||
mem::take(&mut self.dels)
|
||||
.into_iter()
|
||||
.for_each(|(key, value)| wtx.insert(&self.part, key, value));
|
||||
.for_each(|key| wtx.remove(&self.part, key));
|
||||
|
||||
mem::take(&mut self.puts).into_iter().for_each(|(key, value)| {
|
||||
if CHECK_COLLISISONS {
|
||||
if let Ok(Some(value)) = wtx.get(&self.part, key.as_bytes()) {
|
||||
dbg!(value);
|
||||
unreachable!();
|
||||
}
|
||||
}
|
||||
wtx.insert(&self.part, key, value)
|
||||
});
|
||||
|
||||
wtx.commit()?;
|
||||
|
||||
@@ -88,12 +119,12 @@ where
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn height(&self) -> Option<&Height> {
|
||||
pub fn height(&self) -> Option<Height> {
|
||||
self.meta.height()
|
||||
}
|
||||
|
||||
pub fn len(&self) -> usize {
|
||||
self.meta.len() + self.puts.len()
|
||||
self.meta.len() + self.puts.len() - self.dels.len()
|
||||
}
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.len() == 0
|
||||
|
||||
@@ -67,8 +67,8 @@ impl StoreMeta {
|
||||
path.join("version")
|
||||
}
|
||||
|
||||
pub fn height(&self) -> Option<&Height> {
|
||||
self.height.as_ref()
|
||||
pub fn height(&self) -> Option<Height> {
|
||||
self.height
|
||||
}
|
||||
pub fn needs(&self, height: Height) -> bool {
|
||||
self.height.is_none_or(|self_height| height > self_height)
|
||||
|
||||
+117
-132
@@ -1,16 +1,19 @@
|
||||
use std::{path::Path, thread};
|
||||
|
||||
use storable_vec::Version;
|
||||
use storable_vec::{Value, Version, CACHED_GETS};
|
||||
|
||||
use crate::{AddressHash, Addressindex, BlockHashPrefix, Height, TxidPrefix, Txindex};
|
||||
use crate::{
|
||||
AddressHash, Addressbytes, Addressindex, Addresstype, BlockHashPrefix, Height, Indexes, TxidPrefix, Txindex,
|
||||
};
|
||||
|
||||
mod base;
|
||||
mod meta;
|
||||
// mod version;
|
||||
|
||||
pub use base::*;
|
||||
pub use meta::*;
|
||||
|
||||
use super::StorableVecs;
|
||||
|
||||
pub struct Fjalls {
|
||||
pub addresshash_to_addressindex: Store<AddressHash, Addressindex>,
|
||||
pub blockhash_prefix_to_height: Store<BlockHashPrefix, Height>,
|
||||
@@ -30,135 +33,135 @@ impl Fjalls {
|
||||
})
|
||||
}
|
||||
|
||||
// pub fn rollback_from(
|
||||
// &mut self,
|
||||
// _wtx: &mut WriteTransaction,
|
||||
// _height: Height,
|
||||
// _exit: &Exit,
|
||||
// ) -> color_eyre::Result<()> {
|
||||
// panic!();
|
||||
// let mut txindex = None;
|
||||
pub fn rollback(&mut self, vecs: &StorableVecs<CACHED_GETS>, 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(())
|
||||
})?;
|
||||
|
||||
// wtx.range(self.height_to_blockhash.data(), Slice::from(height)..)
|
||||
// .try_for_each(|slice| -> color_eyre::Result<()> {
|
||||
// let (height_slice, slice_blockhash) = slice?;
|
||||
// let blockhash = BlockHash::from_slice(&slice_blockhash)?;
|
||||
vecs.txindex_to_txid.iter_from(starting_indexes.txindex, |(_, txid)| {
|
||||
let txid = txid.as_ref();
|
||||
let txid_prefix = TxidPrefix::from(txid);
|
||||
self.txid_prefix_to_txindex.remove(txid_prefix);
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
// wtx.remove(self.height_to_blockhash.data(), height_slice);
|
||||
vecs.height_to_first_p2pk65index
|
||||
.iter_from(starting_indexes.height, |(_, index)| {
|
||||
if let Some(typedbytes) = vecs
|
||||
.p2pk65index_to_p2pk65addressbytes
|
||||
.get(index.into_inner())?
|
||||
.map(Value::into_inner)
|
||||
{
|
||||
let bytes = Addressbytes::from(typedbytes);
|
||||
let hash = AddressHash::from((&bytes, Addresstype::P2PK65));
|
||||
self.addresshash_to_addressindex.remove(hash);
|
||||
}
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
// wtx.remove(self.blockhash_prefix_to_height.data(), blockhash.prefix());
|
||||
vecs.height_to_first_p2pk33index
|
||||
.iter_from(starting_indexes.height, |(_, index)| {
|
||||
if let Some(typedbytes) = vecs
|
||||
.p2pk33index_to_p2pk33addressbytes
|
||||
.get(index.into_inner())?
|
||||
.map(Value::into_inner)
|
||||
{
|
||||
let bytes = Addressbytes::from(typedbytes);
|
||||
let hash = AddressHash::from((&bytes, Addresstype::P2PK33));
|
||||
self.addresshash_to_addressindex.remove(hash);
|
||||
}
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
// if txindex.is_none() {
|
||||
// txindex.replace(
|
||||
// wtx.get(self.height_to_first_txindex.data(), height_slice)?
|
||||
// .context("for height to have first txindex")?,
|
||||
// );
|
||||
// }
|
||||
// wtx.remove(self.height_to_first_txindex.data(), height_slice);
|
||||
// wtx.remove(self.height_to_last_txindex.data(), height_slice);
|
||||
vecs.height_to_first_p2pkhindex
|
||||
.iter_from(starting_indexes.height, |(_, index)| {
|
||||
if let Some(typedbytes) = vecs
|
||||
.p2pkhindex_to_p2pkhaddressbytes
|
||||
.get(index.into_inner())?
|
||||
.map(Value::into_inner)
|
||||
{
|
||||
let bytes = Addressbytes::from(typedbytes);
|
||||
let hash = AddressHash::from((&bytes, Addresstype::P2PKH));
|
||||
self.addresshash_to_addressindex.remove(hash);
|
||||
}
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
// Ok(())
|
||||
// })?;
|
||||
vecs.height_to_first_p2shindex
|
||||
.iter_from(starting_indexes.height, |(_, index)| {
|
||||
if let Some(typedbytes) = vecs
|
||||
.p2shindex_to_p2shaddressbytes
|
||||
.get(index.into_inner())?
|
||||
.map(Value::into_inner)
|
||||
{
|
||||
let bytes = Addressbytes::from(typedbytes);
|
||||
let hash = AddressHash::from((&bytes, Addresstype::P2SH));
|
||||
self.addresshash_to_addressindex.remove(hash);
|
||||
}
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
// let txindex = txindex.context("txindex to not be none by now")?;
|
||||
vecs.height_to_first_p2trindex
|
||||
.iter_from(starting_indexes.height, |(_, index)| {
|
||||
if let Some(typedbytes) = vecs
|
||||
.p2trindex_to_p2traddressbytes
|
||||
.get(index.into_inner())?
|
||||
.map(Value::into_inner)
|
||||
{
|
||||
let bytes = Addressbytes::from(typedbytes);
|
||||
let hash = AddressHash::from((&bytes, Addresstype::P2TR));
|
||||
self.addresshash_to_addressindex.remove(hash);
|
||||
}
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
// wtx.range(self.txindex_to_txid.data(), Slice::from(txindex)..)
|
||||
// .try_for_each(|slice| -> color_eyre::Result<()> {
|
||||
// let (slice_txindex, slice_txid) = slice?;
|
||||
// let txindex = Txindex::from(slice_txindex);
|
||||
// let txid = Txid::from_slice(&slice_txid)?;
|
||||
vecs.height_to_first_p2wpkhindex
|
||||
.iter_from(starting_indexes.height, |(_, index)| {
|
||||
if let Some(typedbytes) = vecs
|
||||
.p2wpkhindex_to_p2wpkhaddressbytes
|
||||
.get(index.into_inner())?
|
||||
.map(Value::into_inner)
|
||||
{
|
||||
let bytes = Addressbytes::from(typedbytes);
|
||||
let hash = AddressHash::from((&bytes, Addresstype::P2WPKH));
|
||||
self.addresshash_to_addressindex.remove(hash);
|
||||
}
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
// wtx.remove(self.txindex_to_txid.data(), Slice::from(txindex));
|
||||
// wtx.remove(self.txindex_to_height.data(), Slice::from(txindex));
|
||||
// wtx.remove(self.txid_prefix_to_txindex.data(), txid.prefix());
|
||||
vecs.height_to_first_p2wshindex
|
||||
.iter_from(starting_indexes.height, |(_, index)| {
|
||||
if let Some(typedbytes) = vecs
|
||||
.p2wshindex_to_p2wshaddressbytes
|
||||
.get(index.into_inner())?
|
||||
.map(Value::into_inner)
|
||||
{
|
||||
let bytes = Addressbytes::from(typedbytes);
|
||||
let hash = AddressHash::from((&bytes, Addresstype::P2WSH));
|
||||
self.addresshash_to_addressindex.remove(hash);
|
||||
}
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
// Ok(())
|
||||
// })?;
|
||||
self.commit(starting_indexes.height.decremented())?;
|
||||
|
||||
// let txoutindex = Txoutindex::from(txindex);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// let mut addressindexes = BTreeSet::new();
|
||||
|
||||
// wtx.range(self.txoutindex_to_amount.data(), Slice::from(txoutindex)..)
|
||||
// .try_for_each(|slice| -> color_eyre::Result<()> {
|
||||
// let (txoutindex_slice, _) = slice?;
|
||||
|
||||
// wtx.remove(self.txoutindex_to_amount.data(), txoutindex_slice);
|
||||
|
||||
// if let Some(addressindex_slice) =
|
||||
// wtx.get(self.txoutindex_to_addressindex.data(), txoutindex_slice)?
|
||||
// {
|
||||
// wtx.remove(self.txoutindex_to_addressindex.data(), txoutindex_slice);
|
||||
|
||||
// let addressindex = Addressindex::from(addressindex_slice);
|
||||
// addressindexes.insert(addressindex);
|
||||
|
||||
// let txoutindex = Txoutindex::from(txoutindex_slice);
|
||||
// let addresstxoutindex = Addresstxoutindex::from((addressindex, txoutindex));
|
||||
|
||||
// wtx.remove(
|
||||
// self.addressindex_to_txoutindexes.data(),
|
||||
// Slice::from(addresstxoutindex),
|
||||
// );
|
||||
// }
|
||||
|
||||
// Ok(())
|
||||
// })?;
|
||||
|
||||
// addressindexes
|
||||
// .into_iter()
|
||||
// .filter(|addressindex| {
|
||||
// let is_empty = wtx
|
||||
// .prefix(
|
||||
// self.addressindex_to_txoutindexes.data(),
|
||||
// Slice::from(*addressindex),
|
||||
// )
|
||||
// .next()
|
||||
// .is_none();
|
||||
// is_empty
|
||||
// })
|
||||
// .try_for_each(|addressindex| -> color_eyre::Result<()> {
|
||||
// let addressindex_slice = Slice::from(addressindex);
|
||||
|
||||
// let addressbytes = Addressbytes::from(
|
||||
// wtx.get(
|
||||
// self.addressindex_to_addressbytes.data(),
|
||||
// &addressindex_slice,
|
||||
// )?
|
||||
// .context("addressindex_to_address to have value")?,
|
||||
// );
|
||||
// wtx.remove(
|
||||
// self.addressbytes_prefix_to_addressindex.data(),
|
||||
// addressbytes.prefix(),
|
||||
// );
|
||||
// wtx.remove(
|
||||
// self.addressindex_to_addressbytes.data(),
|
||||
// &addressindex_slice,
|
||||
// );
|
||||
// wtx.remove(self.addressindex_to_addresstype.data(), &addressindex_slice);
|
||||
|
||||
// Ok(())
|
||||
// })?;
|
||||
//
|
||||
|
||||
// todo!("clear addresstxoutindexes_out")
|
||||
// todo!("clear addresstxoutindexes_in")
|
||||
// todo!("clear zero_txoutindexes")
|
||||
// todo!("clear txindexvout_to_txoutindex")
|
||||
|
||||
// Ok(())
|
||||
// }
|
||||
|
||||
pub fn min_height(&self) -> Option<Height> {
|
||||
pub fn starting_height(&self) -> Height {
|
||||
[
|
||||
self.addresshash_to_addressindex.height(),
|
||||
self.blockhash_prefix_to_height.height(),
|
||||
self.txid_prefix_to_txindex.height(),
|
||||
]
|
||||
.into_iter()
|
||||
.map(|height| height.map(Height::incremented).unwrap_or_default())
|
||||
.min()
|
||||
.flatten()
|
||||
.cloned()
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
pub fn commit(&mut self, height: Height) -> fjall::Result<()> {
|
||||
@@ -176,22 +179,4 @@ impl Fjalls {
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
||||
// pub fn udpate_meta(&self, wtx: &mut WriteTransaction, height: Height) {
|
||||
// self.addressbytes_prefix_to_addressindex.update_meta(wtx, height);
|
||||
// self.blockhash_prefix_to_height.update_meta(wtx, height);
|
||||
// self.txid_prefix_to_txindex.update_meta(wtx, height);
|
||||
// }
|
||||
|
||||
// pub fn export(self, height: Height) -> Result<(), snkrj::Error> {
|
||||
// thread::scope(|scope| {
|
||||
// vec![
|
||||
// scope.spawn(|| self.addressbytes_prefix_to_addressindex.export(height)),
|
||||
// scope.spawn(|| self.blockhash_prefix_to_height.export(height)),
|
||||
// scope.spawn(|| self.txid_prefix_to_txindex.export(height)),
|
||||
// ]
|
||||
// .into_iter()
|
||||
// .try_for_each(|handle| -> Result<(), snkrj::Error> { handle.join().unwrap() })
|
||||
// })
|
||||
// }
|
||||
}
|
||||
|
||||
@@ -28,14 +28,14 @@ where
|
||||
}
|
||||
|
||||
pub fn flush(&mut self, height: Height) -> io::Result<()> {
|
||||
if self.needs(height) {
|
||||
height.write(&self.path_height())?;
|
||||
}
|
||||
height.write(&self.path_height())?;
|
||||
self.vec.flush()
|
||||
}
|
||||
|
||||
pub fn truncate_if_needed(&mut self, index: I, height: Height) -> storable_vec::Result<Option<T>> {
|
||||
height.write(&self.path_height())?;
|
||||
if self.height.is_none_or(|self_height| self_height != height) {
|
||||
height.write(&self.path_height())?;
|
||||
}
|
||||
self.vec.truncate_if_needed(index)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,14 +1,17 @@
|
||||
use std::{collections::BTreeMap, fs, io, path::Path};
|
||||
use std::{fs, io, path::Path};
|
||||
|
||||
use exit::Exit;
|
||||
use rayon::prelude::*;
|
||||
use storable_vec::{AnyJsonStorableVec, Version, CACHED_GETS};
|
||||
|
||||
use crate::structs::{
|
||||
Addressbytes, Addressindex, Addresstype, Addresstypeindex, BlockHash, Emptyindex, Height, LockTime, Multisigindex,
|
||||
Opreturnindex, P2PK33AddressBytes, P2PK33index, P2PK65AddressBytes, P2PK65index, P2PKHAddressBytes, P2PKHindex,
|
||||
P2SHAddressBytes, P2SHindex, P2TRAddressBytes, P2TRindex, P2WPKHAddressBytes, P2WPKHindex, P2WSHAddressBytes,
|
||||
P2WSHindex, Pushonlyindex, Sats, Timestamp, TxVersion, Txid, Txindex, Txinindex, Txoutindex, Unknownindex, Weight,
|
||||
use crate::{
|
||||
structs::{
|
||||
Addressbytes, Addressindex, Addresstype, Addresstypeindex, BlockHash, Emptyindex, Height, LockTime,
|
||||
Multisigindex, Opreturnindex, P2PK33AddressBytes, P2PK33index, P2PK65AddressBytes, P2PK65index,
|
||||
P2PKHAddressBytes, P2PKHindex, P2SHAddressBytes, P2SHindex, P2TRAddressBytes, P2TRindex, P2WPKHAddressBytes,
|
||||
P2WPKHindex, P2WSHAddressBytes, P2WSHindex, Pushonlyindex, Sats, Timestamp, TxVersion, Txid, Txindex,
|
||||
Txinindex, Txoutindex, Unknownindex, Weight,
|
||||
},
|
||||
Indexes,
|
||||
};
|
||||
|
||||
mod base;
|
||||
@@ -58,8 +61,6 @@ pub struct StorableVecs<const MODE: u8> {
|
||||
pub txoutindex_to_value: StorableVec<Txoutindex, Sats, MODE>,
|
||||
}
|
||||
|
||||
// const UNSAFE_BLOCKS: usize = 1000;
|
||||
|
||||
impl<const MODE: u8> StorableVecs<MODE> {
|
||||
pub fn import(path: &Path) -> color_eyre::Result<Self> {
|
||||
fs::create_dir_all(path)?;
|
||||
@@ -180,113 +181,104 @@ impl<const MODE: u8> StorableVecs<MODE> {
|
||||
})
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
pub fn rollback_from(&mut self, height: Height, exit: &Exit) -> storable_vec::Result<()> {
|
||||
let prev_height = height.decremented();
|
||||
pub fn rollback(&mut self, starting_indexes: &Indexes) -> storable_vec::Result<()> {
|
||||
let saved_height = starting_indexes.height.decremented();
|
||||
|
||||
let mut truncated_indexes: BTreeMap<String, Option<usize>> = BTreeMap::new();
|
||||
// We don't want to override the starting indexes so we cut from n + 1
|
||||
let height = starting_indexes.height.incremented();
|
||||
|
||||
let addressindex = self
|
||||
.height_to_first_addressindex
|
||||
.truncate_if_needed(height, prev_height)?;
|
||||
let txindex = self.height_to_first_txindex.truncate_if_needed(height, prev_height)?;
|
||||
let txinindex = self.height_to_first_txinindex.truncate_if_needed(height, prev_height)?;
|
||||
let txoutindex = self
|
||||
.height_to_first_txoutindex
|
||||
.truncate_if_needed(height, prev_height)?;
|
||||
let p2pk33index = self
|
||||
.height_to_first_p2pk33index
|
||||
.truncate_if_needed(height, prev_height)?;
|
||||
let p2pk65index = self
|
||||
.height_to_first_p2pk65index
|
||||
.truncate_if_needed(height, prev_height)?;
|
||||
let p2pkhindex = self
|
||||
.height_to_first_p2pkhindex
|
||||
.truncate_if_needed(height, prev_height)?;
|
||||
let p2shindex = self.height_to_first_p2shindex.truncate_if_needed(height, prev_height)?;
|
||||
let p2trindex = self.height_to_first_p2trindex.truncate_if_needed(height, prev_height)?;
|
||||
let p2wpkhindex = self
|
||||
.height_to_first_p2wpkhindex
|
||||
.truncate_if_needed(height, prev_height)?;
|
||||
let p2wshindex = self
|
||||
.height_to_first_p2wshindex
|
||||
.truncate_if_needed(height, prev_height)?;
|
||||
|
||||
self.height_to_blockhash.truncate_if_needed(height, prev_height)?;
|
||||
self.height_to_difficulty.truncate_if_needed(height, prev_height)?;
|
||||
self.height_to_first_addressindex
|
||||
.truncate_if_needed(height, saved_height)?;
|
||||
self.height_to_first_emptyindex
|
||||
.truncate_if_needed(height, prev_height)?;
|
||||
.truncate_if_needed(height, saved_height)?;
|
||||
self.height_to_first_multisigindex
|
||||
.truncate_if_needed(height, prev_height)?;
|
||||
.truncate_if_needed(height, saved_height)?;
|
||||
self.height_to_first_opreturnindex
|
||||
.truncate_if_needed(height, prev_height)?;
|
||||
.truncate_if_needed(height, saved_height)?;
|
||||
self.height_to_first_p2pk33index
|
||||
.truncate_if_needed(height, saved_height)?;
|
||||
self.height_to_first_p2pk65index
|
||||
.truncate_if_needed(height, saved_height)?;
|
||||
self.height_to_first_p2pkhindex
|
||||
.truncate_if_needed(height, saved_height)?;
|
||||
self.height_to_first_p2shindex
|
||||
.truncate_if_needed(height, saved_height)?;
|
||||
self.height_to_first_p2trindex
|
||||
.truncate_if_needed(height, saved_height)?;
|
||||
self.height_to_first_p2wpkhindex
|
||||
.truncate_if_needed(height, saved_height)?;
|
||||
self.height_to_first_p2wshindex
|
||||
.truncate_if_needed(height, saved_height)?;
|
||||
self.height_to_first_pushonlyindex
|
||||
.truncate_if_needed(height, prev_height)?;
|
||||
.truncate_if_needed(height, saved_height)?;
|
||||
self.height_to_first_txindex.truncate_if_needed(height, saved_height)?;
|
||||
self.height_to_first_txinindex
|
||||
.truncate_if_needed(height, saved_height)?;
|
||||
self.height_to_first_txoutindex
|
||||
.truncate_if_needed(height, saved_height)?;
|
||||
self.height_to_first_unknownindex
|
||||
.truncate_if_needed(height, prev_height)?;
|
||||
self.height_to_size.truncate_if_needed(height, prev_height)?;
|
||||
self.height_to_timestamp.truncate_if_needed(height, prev_height)?;
|
||||
self.height_to_weight.truncate_if_needed(height, prev_height)?;
|
||||
.truncate_if_needed(height, saved_height)?;
|
||||
|
||||
if let Some(addressindex) = addressindex {
|
||||
self.addressindex_to_addresstype
|
||||
.truncate_if_needed(addressindex, prev_height)?;
|
||||
self.addressindex_to_addresstypeindex
|
||||
.truncate_if_needed(addressindex, prev_height)?;
|
||||
self.addressindex_to_height
|
||||
.truncate_if_needed(addressindex, prev_height)?;
|
||||
}
|
||||
// Now we can cut everything that's out of date
|
||||
let &Indexes {
|
||||
addressindex,
|
||||
height,
|
||||
p2pk33index,
|
||||
p2pk65index,
|
||||
p2pkhindex,
|
||||
p2shindex,
|
||||
p2trindex,
|
||||
p2wpkhindex,
|
||||
p2wshindex,
|
||||
txindex,
|
||||
txinindex,
|
||||
txoutindex,
|
||||
..
|
||||
} = starting_indexes;
|
||||
|
||||
if let Some(p2pk33index) = p2pk33index {
|
||||
self.p2pk33index_to_p2pk33addressbytes
|
||||
.truncate_if_needed(p2pk33index, prev_height)?;
|
||||
}
|
||||
if let Some(p2pk65index) = p2pk65index {
|
||||
self.p2pk65index_to_p2pk65addressbytes
|
||||
.truncate_if_needed(p2pk65index, prev_height)?;
|
||||
}
|
||||
if let Some(p2pkhindex) = p2pkhindex {
|
||||
self.p2pkhindex_to_p2pkhaddressbytes
|
||||
.truncate_if_needed(p2pkhindex, prev_height)?;
|
||||
}
|
||||
if let Some(p2shindex) = p2shindex {
|
||||
self.p2shindex_to_p2shaddressbytes
|
||||
.truncate_if_needed(p2shindex, prev_height)?;
|
||||
}
|
||||
if let Some(p2trindex) = p2trindex {
|
||||
self.p2trindex_to_p2traddressbytes
|
||||
.truncate_if_needed(p2trindex, prev_height)?;
|
||||
}
|
||||
if let Some(p2wpkhindex) = p2wpkhindex {
|
||||
self.p2wpkhindex_to_p2wpkhaddressbytes
|
||||
.truncate_if_needed(p2wpkhindex, prev_height)?;
|
||||
}
|
||||
if let Some(p2wshindex) = p2wshindex {
|
||||
self.p2wshindex_to_p2wshaddressbytes
|
||||
.truncate_if_needed(p2wshindex, prev_height);
|
||||
}
|
||||
self.height_to_blockhash.truncate_if_needed(height, saved_height)?;
|
||||
self.height_to_difficulty.truncate_if_needed(height, saved_height)?;
|
||||
self.height_to_size.truncate_if_needed(height, saved_height)?;
|
||||
self.height_to_timestamp.truncate_if_needed(height, saved_height)?;
|
||||
self.height_to_weight.truncate_if_needed(height, saved_height)?;
|
||||
|
||||
if let Some(txindex) = txindex {
|
||||
self.txindex_to_first_txinindex
|
||||
.truncate_if_needed(txindex, prev_height)?;
|
||||
self.txindex_to_first_txoutindex
|
||||
.truncate_if_needed(txindex, prev_height)?;
|
||||
self.txindex_to_height.truncate_if_needed(txindex, prev_height)?;
|
||||
self.txindex_to_locktime.truncate_if_needed(txindex, prev_height)?;
|
||||
self.txindex_to_txid.truncate_if_needed(txindex, prev_height)?;
|
||||
self.txindex_to_txversion.truncate_if_needed(txindex, prev_height)?;
|
||||
}
|
||||
self.addressindex_to_addresstype
|
||||
.truncate_if_needed(addressindex, saved_height)?;
|
||||
self.addressindex_to_addresstypeindex
|
||||
.truncate_if_needed(addressindex, saved_height)?;
|
||||
self.addressindex_to_height
|
||||
.truncate_if_needed(addressindex, saved_height)?;
|
||||
|
||||
if let Some(txinindex) = txinindex {
|
||||
self.txinindex_to_txoutindex
|
||||
.truncate_if_needed(txinindex, prev_height)?;
|
||||
}
|
||||
self.p2pk33index_to_p2pk33addressbytes
|
||||
.truncate_if_needed(p2pk33index, saved_height)?;
|
||||
self.p2pk65index_to_p2pk65addressbytes
|
||||
.truncate_if_needed(p2pk65index, saved_height)?;
|
||||
self.p2pkhindex_to_p2pkhaddressbytes
|
||||
.truncate_if_needed(p2pkhindex, saved_height)?;
|
||||
self.p2shindex_to_p2shaddressbytes
|
||||
.truncate_if_needed(p2shindex, saved_height)?;
|
||||
self.p2trindex_to_p2traddressbytes
|
||||
.truncate_if_needed(p2trindex, saved_height)?;
|
||||
self.p2wpkhindex_to_p2wpkhaddressbytes
|
||||
.truncate_if_needed(p2wpkhindex, saved_height)?;
|
||||
self.p2wshindex_to_p2wshaddressbytes
|
||||
.truncate_if_needed(p2wshindex, saved_height)?;
|
||||
|
||||
if let Some(txoutindex) = txoutindex {
|
||||
self.txoutindex_to_addressindex
|
||||
.truncate_if_needed(txoutindex, prev_height)?;
|
||||
self.txoutindex_to_value.truncate_if_needed(txoutindex, prev_height)?;
|
||||
}
|
||||
self.txindex_to_first_txinindex
|
||||
.truncate_if_needed(txindex, saved_height)?;
|
||||
self.txindex_to_first_txoutindex
|
||||
.truncate_if_needed(txindex, saved_height)?;
|
||||
self.txindex_to_height.truncate_if_needed(txindex, saved_height)?;
|
||||
self.txindex_to_locktime.truncate_if_needed(txindex, saved_height)?;
|
||||
self.txindex_to_txid.truncate_if_needed(txindex, saved_height)?;
|
||||
self.txindex_to_txversion.truncate_if_needed(txindex, saved_height)?;
|
||||
|
||||
self.txinindex_to_txoutindex
|
||||
.truncate_if_needed(txinindex, saved_height)?;
|
||||
|
||||
self.txoutindex_to_addressindex
|
||||
.truncate_if_needed(txoutindex, saved_height)?;
|
||||
self.txoutindex_to_value.truncate_if_needed(txoutindex, saved_height)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -297,12 +289,12 @@ impl<const MODE: u8> StorableVecs<MODE> {
|
||||
.try_for_each(|vec| vec.flush(height))
|
||||
}
|
||||
|
||||
pub fn min_height(&mut self) -> color_eyre::Result<Option<Height>> {
|
||||
Ok(self
|
||||
.as_mut_any_vec_slice()
|
||||
pub fn starting_height(&mut self) -> Height {
|
||||
self.as_mut_any_vec_slice()
|
||||
.into_iter()
|
||||
.map(|vec| vec.height().unwrap_or_default())
|
||||
.min())
|
||||
.map(|vec| vec.height().map(Height::incremented).unwrap_or_default())
|
||||
.min()
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
pub fn as_any_json_vec_slice(&self) -> [&dyn AnyJsonStorableVec; 40] {
|
||||
|
||||
Reference in New Issue
Block a user