bitbase: pre-rayon snapshot

This commit is contained in:
nym21
2025-01-07 12:15:58 +01:00
parent bf31ee5fd6
commit 5b1735db2b
7 changed files with 336 additions and 214 deletions
+1
View File
@@ -0,0 +1 @@
max_width = 120
+277 -111
View File
@@ -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<Slice>))> {
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<usize, (Txid, Option<Slice>)> { BTreeMap::default() },
|mut map, tuple| -> color_eyre::Result<BTreeMap<usize, (Txid, Option<Slice>)>> {
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<Addresstxoutindex> { vec![] },
// |mut vec, txin| -> color_eyre::Result<Vec<Addresstxoutindex>> {
// 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<Addresstxoutindex> { vec![] },
|mut vec, txin| -> color_eyre::Result<Vec<Addresstxoutindex>> {
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());
+26 -32
View File
@@ -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<Self, Self::Error> {
let (script, addresstype, addressindex) = tuple;
fn try_from(tuple: (&ScriptBuf, Addresstype)) -> Result<Self, Self::Error> {
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")),
}
}
}
@@ -18,9 +18,9 @@ impl From<(Addressindex, Txoutindex)> for Addresstxoutindex {
impl From<Addresstxoutindex> 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<Slice> for Addresstxoutindex {
+4
View File
@@ -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<u64> for Amount {
+4 -18
View File
@@ -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<Self> {
pub fn import(keyspace: &TransactionalKeyspace, name: &str, version: Version, exit: &Exit) -> Result<Self> {
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<TransactionalPartitionHandle> {
fn open_data(keyspace: &TransactionalKeyspace, name: &str) -> Result<TransactionalPartitionHandle> {
keyspace.open_partition(&format!("{name}-data"), Self::create_options())
}
fn open_meta(
keyspace: &TransactionalKeyspace,
name: &str,
) -> Result<TransactionalPartitionHandle> {
fn open_meta(keyspace: &TransactionalKeyspace, name: &str) -> Result<TransactionalPartitionHandle> {
keyspace.open_partition(&format!("{name}-meta"), Self::create_options())
}
+21 -50
View File
@@ -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,
]
}
}