From 5b1735db2b8b0f774983b36c6e5129a58c9e9cda Mon Sep 17 00:00:00 2001 From: nym21 Date: Tue, 7 Jan 2025 12:15:58 +0100 Subject: [PATCH] bitbase: pre-rayon snapshot --- src/crates/bitbase/rustfmt.toml | 1 + src/crates/bitbase/src/main.rs | 388 +++++++++++++----- .../bitbase/src/structs/addressbytes.rs | 58 ++- .../bitbase/src/structs/addresstxoutindex.rs | 6 +- src/crates/bitbase/src/structs/amount.rs | 4 + src/crates/bitbase/src/structs/partition.rs | 22 +- src/crates/bitbase/src/structs/partitions.rs | 71 +--- 7 files changed, 336 insertions(+), 214 deletions(-) create mode 100644 src/crates/bitbase/rustfmt.toml diff --git a/src/crates/bitbase/rustfmt.toml b/src/crates/bitbase/rustfmt.toml new file mode 100644 index 000000000..753065179 --- /dev/null +++ b/src/crates/bitbase/rustfmt.toml @@ -0,0 +1 @@ +max_width = 120 diff --git a/src/crates/bitbase/src/main.rs b/src/crates/bitbase/src/main.rs index 8ad47a7e7..a1ece1c0f 100644 --- a/src/crates/bitbase/src/main.rs +++ b/src/crates/bitbase/src/main.rs @@ -1,4 +1,4 @@ -use std::{path::Path, str::FromStr}; +use std::{collections::BTreeMap, path::Path, str::FromStr}; use biter::{ bitcoin::{hashes::Hash, Txid}, @@ -9,9 +9,10 @@ mod structs; use color_eyre::eyre::{eyre, ContextCompat}; use fjall::{PersistMode, Slice, TransactionalKeyspace, WriteTransaction}; +use rayon::prelude::*; use structs::{ - Addressbytes, Addressindex, Addresstxoutindex, Addresstype, Amount, Exit, Height, Partitions, - Prefix, SliceExtended, Txindex, Txoutindex, + Addressbytes, Addressindex, Addresstxoutindex, Addresstype, Amount, Exit, Height, Partitions, Prefix, + SliceExtended, Txindex, Txoutindex, }; // https://github.com/fjall-rs/fjall/discussions/72 @@ -19,6 +20,7 @@ use structs::{ const DAILY_BLOCK_TARGET: usize = 144; const MONTHLY_BLOCK_TARGET: usize = DAILY_BLOCK_TARGET * 30; +const U16MAX: usize = u16::MAX as usize; fn main() -> color_eyre::Result<()> { let i = std::time::Instant::now(); @@ -38,18 +40,13 @@ fn main() -> color_eyre::Result<()> { let mut height = parts.start_height(); let mut txindex = wtx - .get(parts.height_to_last_txindex.data(), Slice::from(height))? + .get(parts.height_to_first_txindex.data(), Slice::from(height))? .map(Txindex::from) - .map(Txindex::incremented) .unwrap_or(Txindex::default()); let mut addressindex = wtx - .get( - parts.height_to_last_addressindex.data(), - Slice::from(height), - )? + .get(parts.height_to_first_addressindex.data(), Slice::from(height))? .map(Addressindex::from) - .map(Addressindex::incremented) .unwrap_or(Addressindex::default()); let export = |keyspace: &TransactionalKeyspace, @@ -72,37 +69,35 @@ fn main() -> color_eyre::Result<()> { biter::new(data_dir, Some(height.into()), None, rpc) .iter() .try_for_each(|(_height, block, blockhash)| -> color_eyre::Result<()> { - let mut wtx = wtx_opt.take().context("option should've wtx")?; - println!("Processing block {_height}..."); height = Height::from(_height); - let has_different_blockhash = wtx - .get(parts.height_to_blockhash.data(), Slice::from(height))? - .is_some_and(|saved_blockhash_slice| blockhash[..] != saved_blockhash_slice[..]); + let mut wtx = wtx_opt.take().context("option should have wtx")?; - if has_different_blockhash { - parts.rollback_from(&mut wtx, height, &exit)?; + let saved_blockhash_slice_opt = wtx.get(parts.height_to_blockhash.data(), Slice::from(height))?; + if let Some(saved_blockhash_slice) = saved_blockhash_slice_opt { + if blockhash[..] != saved_blockhash_slice[..] { + parts.rollback_from(&mut wtx, height, &exit)?; + } else { + wtx_opt.replace(wtx); + return Ok(()); + } } if parts.blockhash_prefix_to_height.needs(height) { - if let Some(prev) = wtx.fetch_update( - parts.blockhash_prefix_to_height.data(), - blockhash.prefix(), - |_| Some(Slice::from(height)), - )? { - dbg!(prev); - return Err(eyre!("Expect none")); + if let Some(prev_height_slice) = + wtx.fetch_update(parts.blockhash_prefix_to_height.data(), blockhash.prefix(), |_| { + Some(Slice::from(height)) + })? + { + dbg!(blockhash, Height::from(prev_height_slice)); + return Err(eyre!("Collision, expect prefix to need be set yet")); } } if parts.height_to_blockhash.needs(height) { - wtx.insert( - parts.height_to_blockhash.data(), - Slice::from(height), - blockhash, - ); + wtx.insert(parts.height_to_blockhash.data(), Slice::from(height), blockhash); } if parts.height_to_first_addressindex.needs(height) { @@ -116,8 +111,99 @@ fn main() -> color_eyre::Result<()> { let txlen = block.txdata.len(); let last_txi = txlen - 1; - block.txdata.into_iter().enumerate().try_for_each( - |(txi, tx)| -> color_eyre::Result<()> { + let mut txi_to_txid_and_prev_txindex_slice_opt = block + .txdata + .par_iter() + .enumerate() + .map(|(txi, tx)| -> color_eyre::Result<(usize, (Txid, Option))> { + let txid = tx.compute_txid(); + + let prev_txindex_slice_opt = wtx.get(parts.txid_prefix_to_txindex.data(), txid.prefix())?; + + Ok((txi, (txid, prev_txindex_slice_opt))) + }) + .try_fold( + || -> BTreeMap)> { BTreeMap::default() }, + |mut map, tuple| -> color_eyre::Result)>> { + let (txi, tuple) = tuple?; + map.insert(txi, tuple); + Ok(map) + }, + ) + .try_reduce(BTreeMap::default, |mut map, mut map2| { + if map.len() > map2.len() { + map.append(&mut map2); + Ok(map) + } else { + map2.append(&mut map); + Ok(map2) + } + })?; + + // let addresstxoutindexes_out = block + // .txdata + // .par_iter() + // .filter(|tx| !tx.is_coinbase()) + // .flat_map(|tx| &tx.input) + // .try_fold( + // || -> Vec { vec![] }, + // |mut vec, txin| -> color_eyre::Result> { + // let outpoint = txin.previous_output; + // let txid_prefix = outpoint.txid.prefix(); + // let vout = outpoint.vout as u16; + + // let txindex = Txindex::from( + // wtx.get(parts.txid_prefix_to_txindex.data(), txid_prefix)? + // .context("Expect txid to be saved")?, + // ); + + // let txoutindex = Txoutindex::from((txindex, vout)); + + // let addressindex = Addressindex::from( + // wtx.get(parts.txoutindex_to_addressindex.data(), Slice::from(txoutindex))? + // .context("Expect addressindex to not be none") + // .inspect_err(|_| { + // let height = Height::from( + // wtx.get(parts.txindex_to_height.data(), Slice::from(txindex)) + // .expect("txindex_to_height get not fail") + // .expect("Expect height for txindex"), + // ); + // dbg!(outpoint.txid, txindex, vout, txoutindex, height); + // })?, + // ); + + // if parts.addresstxoutindexes_out.needs(height) { + // vec.push(Addresstxoutindex::from((addressindex, txoutindex))); + // } + + // Ok(vec) + // }, + // ) + // .try_reduce(Vec::new, |mut v, mut v2| { + // if v.len() > v2.len() { + // v.append(&mut v2); + // Ok(v) + // } else { + // v2.append(&mut v); + // Ok(v2) + // } + // })?; + + // addresstxoutindexes_out.into_iter().for_each(|addresstxoutindex| { + // wtx.insert( + // parts.addresstxoutindexes_out.data(), + // Slice::from(addresstxoutindex), + // Slice::default(), + // ); + // }); + + block + .txdata + .into_iter() + .enumerate() + .try_for_each(|(txi, tx)| -> color_eyre::Result<()> { + let is_coinbase = tx.is_coinbase(); + if txi == 0 && parts.height_to_first_txindex.needs(height) { wtx.insert( parts.height_to_first_txindex.data(), @@ -133,44 +219,47 @@ fn main() -> color_eyre::Result<()> { ); } - if parts.txindex_to_txid.needs(height) - || parts.txid_prefix_to_txindex.needs(height) - { - let txid = tx.compute_txid(); + let mut bad_tx = false; - if parts.txindex_to_txid.needs(height) { - wtx.insert(parts.txindex_to_txid.data(), Slice::from(txindex), txid); + let (txid, prev_txindex_slice_opt) = txi_to_txid_and_prev_txindex_slice_opt + .remove(&txi) + .context("Par compute of tx should have worked") + .inspect_err(|_| { + dbg!(&txi_to_txid_and_prev_txindex_slice_opt, &txi, tx.compute_txid()); + })?; + + if parts.txindex_to_txid.needs(height) { + wtx.insert(parts.txindex_to_txid.data(), Slice::from(txindex), txid); + } + + match prev_txindex_slice_opt { + None => { + if parts.txid_prefix_to_txindex.needs(height) { + wtx.insert(parts.txid_prefix_to_txindex.data(), txid.prefix(), Slice::from(txindex)); + } } + Some(prev_txindex_slice) => { + let prev_txid = Txid::from_slice( + &wtx.get(parts.txindex_to_txid.data(), &prev_txindex_slice)? + .expect("To have txid for txindex"), + )?; - if parts.txid_prefix_to_txindex.needs(height) { - if let Some(prev) = wtx.fetch_update( - parts.txid_prefix_to_txindex.data(), - txid.prefix(), - |_| Some(Slice::from(txindex)), - )? { - let prev_txid = Txid::from_slice(&wtx - .get(parts.txindex_to_txid.data(), &prev)?.expect("To have txid for txindex"))?; + let only_known_dup_txids = [ + Txid::from_str("d5d27987d2a3dfc724e359870c6644b40e497bdc0589a033220fe15429d88599")?, + Txid::from_str("e3bf3d07d4b0375638d5f1db5255fe07ba2c4cb067cd81b84ee974b6585fb468")?, + ]; - let only_known_dup_txids = [Txid::from_str("d5d27987d2a3dfc724e359870c6644b40e497bdc0589a033220fe15429d88599")?, Txid::from_str("e3bf3d07d4b0375638d5f1db5255fe07ba2c4cb067cd81b84ee974b6585fb468")?]; + let is_dup = only_known_dup_txids.contains(&prev_txid); + bad_tx = is_dup; - // TODO - // link txindex to txid - // txid_prefix should point to the first vout so no override - // do not add vout as they're invalid - - if !only_known_dup_txids.contains(&prev_txid) { - let prev_height = Height::from(wtx.get(parts.txindex_to_height.data(), &prev)?.expect("To have height")); - let prev_txindex = Txindex::from(prev); - dbg!( - height, - txid, - txindex, - prev_height, - prev_txid, - prev_txindex, - ); - return Err(eyre!("Expect none")); - } + if !is_dup { + let prev_height = Height::from( + wtx.get(parts.txindex_to_height.data(), &prev_txindex_slice)? + .expect("To have height"), + ); + let prev_txindex = Txindex::from(prev_txindex_slice); + dbg!(height, txid, txindex, prev_height, prev_txid, prev_txindex,); + return Err(eyre!("Expect none")); } } } @@ -183,15 +272,90 @@ fn main() -> color_eyre::Result<()> { ); } - txindex.increment(); + tx.input + .par_iter() + // .into_par_iter() + .try_fold( + || -> Vec { vec![] }, + |mut vec, txin| -> color_eyre::Result> { + if is_coinbase { + return Ok(vec); + } + + let outpoint = txin.previous_output; + let txid_prefix = outpoint.txid.prefix(); + let vout = outpoint.vout as u16; + + let txindex = Txindex::from( + wtx.get(parts.txid_prefix_to_txindex.data(), txid_prefix)? + .context("Expect txid to be saved")?, + ); + + let txoutindex = Txoutindex::from((txindex, vout)); + + let addressindex = Addressindex::from( + wtx.get(parts.txoutindex_to_addressindex.data(), Slice::from(txoutindex))? + .context("Expect addressindex to not be none") + .inspect_err(|_| { + let height = Height::from( + wtx.get(parts.txindex_to_height.data(), Slice::from(txindex)) + .expect("txindex_to_height get not fail") + .expect("Expect height for txindex"), + ); + dbg!(txid, outpoint.txid, txindex, vout, txoutindex, height); + })?, + ); + + if bad_tx { + dbg!(tx.compute_txid(), outpoint); + panic!("bad tx in input") + } + if !bad_tx && parts.addresstxoutindexes_out.needs(height) { + vec.push(Addresstxoutindex::from((addressindex, txoutindex))); + } + + Ok(vec) + }, + ) + .try_reduce(Vec::new, |mut v, mut v2| { + if v.len() > v2.len() { + v.append(&mut v2); + Ok(v) + } else { + v2.append(&mut v); + Ok(v2) + } + })? + .into_iter() + .for_each(|addresstxoutindex| { + wtx.insert( + parts.addresstxoutindexes_out.data(), + Slice::from(addresstxoutindex), + Slice::default(), + ); + }); + + tx.output + .into_iter() + .enumerate() + .try_for_each(|(vout, txout)| -> color_eyre::Result<()> { + if vout > U16MAX { + return Err(eyre!("vout bigger than u16::MAX")); + } - tx.output.iter().enumerate().try_for_each( - |(vout, txout)| -> color_eyre::Result<()> { let vout = vout as u16; let txoutindex = Txoutindex::from((txindex, vout)); let amount = Amount::from(txout.value); - if parts.txoutindex_to_amount.needs(height) { + if amount.is_zero() { + if parts.zero_txoutindexes.needs(height) { + wtx.insert( + parts.zero_txoutindexes.data(), + Slice::from(txoutindex), + Slice::default(), + ); + } + } else if parts.txoutindex_to_amount.needs(height) { wtx.insert( parts.txoutindex_to_amount.data(), Slice::from(txoutindex), @@ -201,40 +365,24 @@ fn main() -> color_eyre::Result<()> { let script = &txout.script_pubkey; - let addresstype = Addresstype::from(script); - let addressbytes = - Addressbytes::try_from((script, addresstype, addressindex)) - .inspect_err(|_| { - dbg!(&txout, height, txi, &tx.compute_txid()); - })?; - let mut addressindex_local = addressindex; - if let Some(addressindex_slice) = wtx.get( - parts.addressbytes_prefix_to_addressindex.data(), - Slice::from(&addressbytes), - )? { + let addresstype = Addresstype::from(script); + + let addressbytes = Addressbytes::try_from((script, addresstype)).inspect_err(|_| { + // dbg!(&txout, height, txi, &tx.compute_txid()); + }); + + if let Some(addressindex_slice) = addressbytes.as_ref().ok().and_then(|addressbytes| { + wtx.get( + parts.addressbytes_prefix_to_addressindex.data(), + Slice::from(addressbytes), + ) + .ok() + .and_then(|s| s) + }) { addressindex_local = addressindex_slice.into() } else { - if parts.addressbytes_prefix_to_addressindex.needs(height) { - if let Some(prev) = wtx.fetch_update( - parts.addressbytes_prefix_to_addressindex.data(), - Slice::from(&addressbytes), - |_| Some(Slice::from(addressindex_local)), - )? { - dbg!(prev); - return Err(eyre!("Expect none")); - } - } - - if parts.addressindex_to_addressbytes.needs(height) { - wtx.insert( - parts.addressindex_to_addressbytes.data(), - Slice::from(addressindex_local), - Slice::from(&addressbytes), - ); - } - if parts.addressindex_to_addresstype.needs(height) { wtx.insert( parts.addressindex_to_addresstype.data(), @@ -243,6 +391,27 @@ fn main() -> color_eyre::Result<()> { ); } + if let Ok(addressbytes) = addressbytes { + if parts.addressbytes_prefix_to_addressindex.needs(height) { + if let Some(prev) = wtx.fetch_update( + parts.addressbytes_prefix_to_addressindex.data(), + Slice::from(&addressbytes), + |_| Some(Slice::from(addressindex_local)), + )? { + dbg!(prev); + return Err(eyre!("Expect none")); + } + } + + if parts.addressindex_to_addressbytes.needs(height) { + wtx.insert( + parts.addressindex_to_addressbytes.data(), + Slice::from(addressindex_local), + Slice::from(&addressbytes), + ); + } + } + addressindex.increment(); } @@ -254,24 +423,23 @@ fn main() -> color_eyre::Result<()> { ); } - if parts.addresstxoutindexes.needs(height) { + let addresstxoutindex = Addresstxoutindex::from((addressindex_local, txoutindex)); + + if !bad_tx && parts.addresstxoutindexes_in.needs(height) { wtx.insert( - parts.addresstxoutindexes.data(), - Slice::from(Addresstxoutindex::from(( - addressindex_local, - txoutindex, - ))), + parts.addresstxoutindexes_in.data(), + Slice::from(addresstxoutindex), Slice::default(), ); } Ok(()) - }, - )?; + })?; + + txindex.increment(); Ok(()) - }, - )?; + })?; if parts.height_to_last_addressindex.needs(height) { wtx.insert( @@ -292,9 +460,7 @@ fn main() -> color_eyre::Result<()> { Ok(()) })?; - let wtx = wtx_opt - .take() - .context("option should have WriteTransaction")?; + let wtx = wtx_opt.take().context("option should have WriteTransaction")?; export(&keyspace, wtx, &parts, height)?; dbg!(i.elapsed()); diff --git a/src/crates/bitbase/src/structs/addressbytes.rs b/src/crates/bitbase/src/structs/addressbytes.rs index e51952e27..f4db632ee 100644 --- a/src/crates/bitbase/src/structs/addressbytes.rs +++ b/src/crates/bitbase/src/structs/addressbytes.rs @@ -3,60 +3,54 @@ use color_eyre::eyre::eyre; use derive_deref::{Deref, DerefMut}; use fjall::Slice; -use super::{Addressindex, Addresstype}; +use super::Addresstype; #[derive(Debug, Deref, DerefMut)] pub struct Addressbytes(Slice); -impl TryFrom<(&ScriptBuf, Addresstype, Addressindex)> for Addressbytes { +impl TryFrom<(&ScriptBuf, Addresstype)> for Addressbytes { type Error = color_eyre::Report; - fn try_from(tuple: (&ScriptBuf, Addresstype, Addressindex)) -> Result { - let (script, addresstype, addressindex) = tuple; + fn try_from(tuple: (&ScriptBuf, Addresstype)) -> Result { + let (script, addresstype) = tuple; match addresstype { Addresstype::P2PK => { let bytes = script.as_bytes(); let bytes = match bytes.len() { - 67 => &script.as_bytes()[1..66], - 35 => &script.as_bytes()[1..34], + 67 => &bytes[1..66], + 35 => &bytes[1..34], _ => { dbg!(bytes); return Err(eyre!("Wrong len")); } }; - - if bytes[0] != 4 { - dbg!(bytes); - return Err(eyre!("Doesn't start with a 4")); - } - Ok(Self(bytes.into())) } Addresstype::P2PKH => { let bytes = &script.as_bytes()[3..23]; Ok(Self(bytes.into())) } - _ => { - if script.is_p2sh() { - Err(eyre!("p2sh address type")) - } else if script.is_p2wpkh() { - Err(eyre!("p2wpkh address type")) - } else if script.is_p2wsh() { - Err(eyre!("p2wsh address type")) - } else if script.is_p2tr() { - Err(eyre!("p2tr address type")) - } else if script.is_empty() { - Err(eyre!("empty address type")) - } else if script.is_op_return() { - Err(eyre!("op_return address type")) - } else if script.is_multisig() { - Err(eyre!("multisig address type")) - } else if script.is_push_only() { - Err(eyre!("push only address type")) - } else { - Ok(Self(addressindex.into())) - } + Addresstype::P2SH => { + let bytes = &script.as_bytes()[2..22]; + Ok(Self(bytes.into())) } + Addresstype::P2WPKH => { + let bytes = &script.as_bytes()[2..]; + Ok(Self(bytes.into())) + } + Addresstype::P2WSH => { + let bytes = &script.as_bytes()[2..]; + Ok(Self(bytes.into())) + } + Addresstype::P2TR => { + let bytes = &script.as_bytes()[2..]; + Ok(Self(bytes.into())) + } + Addresstype::Multisig => Err(eyre!("multisig address type")), + Addresstype::PushOnly => Err(eyre!("push_only address type")), + Addresstype::Unknown => Err(eyre!("unknown address type")), + Addresstype::Empty => Err(eyre!("empty address type")), + Addresstype::OpReturn => Err(eyre!("op_return address type")), } } } diff --git a/src/crates/bitbase/src/structs/addresstxoutindex.rs b/src/crates/bitbase/src/structs/addresstxoutindex.rs index b83cde83e..02a5d0d82 100644 --- a/src/crates/bitbase/src/structs/addresstxoutindex.rs +++ b/src/crates/bitbase/src/structs/addresstxoutindex.rs @@ -18,9 +18,9 @@ impl From<(Addressindex, Txoutindex)> for Addresstxoutindex { impl From for Slice { fn from(value: Addresstxoutindex) -> Self { - let txindex_slice = Self::from(value.addressindex); - let vout_slice = Self::from(value.txoutindex); - Self::from([txindex_slice, vout_slice].concat()) + let addressindex_slice = Self::from(value.addressindex); + let txoutindex_slice = Self::from(value.txoutindex); + Self::from([addressindex_slice, txoutindex_slice].concat()) } } impl From for Addresstxoutindex { diff --git a/src/crates/bitbase/src/structs/amount.rs b/src/crates/bitbase/src/structs/amount.rs index 0219842d7..515ea29da 100644 --- a/src/crates/bitbase/src/structs/amount.rs +++ b/src/crates/bitbase/src/structs/amount.rs @@ -16,6 +16,10 @@ impl Amount { pub const ZERO: Self = Self(bitcoin::Amount::ZERO); pub const ONE_BTC_F32: f32 = 100_000_000.0; pub const ONE_BTC_F64: f64 = 100_000_000.0; + + pub fn is_zero(&self) -> bool { + *self == Self::ZERO + } } impl From for Amount { diff --git a/src/crates/bitbase/src/structs/partition.rs b/src/crates/bitbase/src/structs/partition.rs index bd913f22c..4f184442f 100644 --- a/src/crates/bitbase/src/structs/partition.rs +++ b/src/crates/bitbase/src/structs/partition.rs @@ -1,7 +1,4 @@ -pub use fjall::{ - PartitionCreateOptions, PersistMode, Result, TransactionalKeyspace, - TransactionalPartitionHandle, -}; +pub use fjall::{PartitionCreateOptions, PersistMode, Result, TransactionalKeyspace, TransactionalPartitionHandle}; use crate::structs::{Height, Version}; @@ -18,12 +15,7 @@ impl Partition { pub const VERSION: &str = "version"; pub const HEIGHT: &str = "height"; - pub fn import( - keyspace: &TransactionalKeyspace, - name: &str, - version: Version, - exit: &Exit, - ) -> Result { + pub fn import(keyspace: &TransactionalKeyspace, name: &str, version: Version, exit: &Exit) -> Result { let data = Self::open_data(keyspace, name)?; let meta = Self::open_meta(keyspace, name)?; @@ -43,17 +35,11 @@ impl Partition { Ok(this) } - fn open_data( - keyspace: &TransactionalKeyspace, - name: &str, - ) -> Result { + fn open_data(keyspace: &TransactionalKeyspace, name: &str) -> Result { keyspace.open_partition(&format!("{name}-data"), Self::create_options()) } - fn open_meta( - keyspace: &TransactionalKeyspace, - name: &str, - ) -> Result { + fn open_meta(keyspace: &TransactionalKeyspace, name: &str) -> Result { keyspace.open_partition(&format!("{name}-meta"), Self::create_options()) } diff --git a/src/crates/bitbase/src/structs/partitions.rs b/src/crates/bitbase/src/structs/partitions.rs index ebacd93c6..1b08c8c1e 100644 --- a/src/crates/bitbase/src/structs/partitions.rs +++ b/src/crates/bitbase/src/structs/partitions.rs @@ -8,7 +8,8 @@ pub struct Partitions { pub addressbytes_prefix_to_addressindex: Partition, pub addressindex_to_addressbytes: Partition, pub addressindex_to_addresstype: Partition, - pub addresstxoutindexes: Partition, + pub addresstxoutindexes_in: Partition, + pub addresstxoutindexes_out: Partition, pub blockhash_prefix_to_height: Partition, pub height_to_blockhash: Partition, pub height_to_first_addressindex: Partition, @@ -20,6 +21,7 @@ pub struct Partitions { pub txindex_to_txid: Partition, pub txoutindex_to_addressindex: Partition, pub txoutindex_to_amount: Partition, + pub zero_txoutindexes: Partition, } const UNSAFE_BLOCKS: usize = 100; @@ -45,78 +47,40 @@ impl Partitions { Version::from(1), exit, )?, - addresstxoutindexes: Partition::import( - keyspace, - "addresstxoutindexes", - Version::from(1), - exit, - )?, + addresstxoutindexes_in: Partition::import(keyspace, "addresstxoutindexes_in", Version::from(1), exit)?, + addresstxoutindexes_out: Partition::import(keyspace, "addresstxoutindexes_out", Version::from(1), exit)?, blockhash_prefix_to_height: Partition::import( keyspace, "blockhash_prefix_to_height", Version::from(1), exit, )?, - height_to_blockhash: Partition::import( - keyspace, - "height_to_blockhash", - Version::from(1), - exit, - )?, + height_to_blockhash: Partition::import(keyspace, "height_to_blockhash", Version::from(1), exit)?, height_to_first_addressindex: Partition::import( keyspace, "height_to_first_addressindex", Version::from(1), exit, )?, - height_to_first_txindex: Partition::import( - keyspace, - "height_to_first_txindex", - Version::from(1), - exit, - )?, + height_to_first_txindex: Partition::import(keyspace, "height_to_first_txindex", Version::from(1), exit)?, height_to_last_addressindex: Partition::import( keyspace, "height_to_last_addressindex", Version::from(1), exit, )?, - height_to_last_txindex: Partition::import( - keyspace, - "height_to_last_txindex", - Version::from(1), - exit, - )?, - txid_prefix_to_txindex: Partition::import( - keyspace, - "txid_prefix_to_txindex", - Version::from(1), - exit, - )?, - txindex_to_height: Partition::import( - keyspace, - "txindex_to_height", - Version::from(1), - exit, - )?, - txindex_to_txid: Partition::import( - keyspace, - "txindex_to_txid", - Version::from(1), - exit, - )?, + height_to_last_txindex: Partition::import(keyspace, "height_to_last_txindex", Version::from(1), exit)?, + txid_prefix_to_txindex: Partition::import(keyspace, "txid_prefix_to_txindex", Version::from(1), exit)?, + txindex_to_height: Partition::import(keyspace, "txindex_to_height", Version::from(1), exit)?, + txindex_to_txid: Partition::import(keyspace, "txindex_to_txid", Version::from(1), exit)?, txoutindex_to_addressindex: Partition::import( keyspace, "txoutindex_to_addressindex", Version::from(1), exit, )?, - txoutindex_to_amount: Partition::import( - keyspace, - "txoutindex_to_amount", - Version::from(1), - exit, - )?, + txoutindex_to_amount: Partition::import(keyspace, "txoutindex_to_amount", Version::from(1), exit)?, + zero_txoutindexes: Partition::import(keyspace, "zero_txoutindexes", Version::from(1), exit)?, }) } @@ -252,6 +216,11 @@ impl Partitions { // Ok(()) // })?; + // + + // todo!("clear addresstxoutindexes_out") + // todo!("clear addresstxoutindexes_in") + // todo!("clear zero_txoutindexes") // Ok(()) } @@ -261,7 +230,8 @@ impl Partitions { &self.addressbytes_prefix_to_addressindex, &self.addressindex_to_addressbytes, &self.addressindex_to_addresstype, - &self.addresstxoutindexes, + &self.addresstxoutindexes_in, + &self.addresstxoutindexes_out, &self.blockhash_prefix_to_height, &self.height_to_blockhash, &self.height_to_first_addressindex, @@ -273,6 +243,7 @@ impl Partitions { &self.txindex_to_txid, &self.txoutindex_to_addressindex, &self.txoutindex_to_amount, + &self.zero_txoutindexes, ] } }