mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-07-27 02:38:10 -07:00
general: fixed builds
This commit is contained in:
Generated
+54
@@ -352,7 +352,9 @@ dependencies = [
|
|||||||
"clap",
|
"clap",
|
||||||
"color-eyre",
|
"color-eyre",
|
||||||
"log",
|
"log",
|
||||||
|
"serde",
|
||||||
"tabled",
|
"tabled",
|
||||||
|
"toml",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -2251,6 +2253,15 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_spanned"
|
||||||
|
version = "0.6.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_urlencoded"
|
name = "serde_urlencoded"
|
||||||
version = "0.7.1"
|
version = "0.7.1"
|
||||||
@@ -2493,6 +2504,40 @@ dependencies = [
|
|||||||
"tokio",
|
"tokio",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml"
|
||||||
|
version = "0.8.20"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cd87a5cdd6ffab733b2f74bc4fd7ee5fff6634124999ac278c35fc78c6120148"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
"serde_spanned",
|
||||||
|
"toml_datetime",
|
||||||
|
"toml_edit",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml_datetime"
|
||||||
|
version = "0.6.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml_edit"
|
||||||
|
version = "0.22.24"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "17b4795ff5edd201c7cd6dca065ae59972ce77d1b80fa0a84d94950ece7d1474"
|
||||||
|
dependencies = [
|
||||||
|
"indexmap",
|
||||||
|
"serde",
|
||||||
|
"serde_spanned",
|
||||||
|
"toml_datetime",
|
||||||
|
"winnow",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tower"
|
name = "tower"
|
||||||
version = "0.5.2"
|
version = "0.5.2"
|
||||||
@@ -2762,6 +2807,15 @@ version = "0.52.6"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winnow"
|
||||||
|
version = "0.7.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0e7f4ea97f6f78012141bcdb6a216b2609f0979ada50b20ca5b52dde2eac2bb1"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wit-bindgen-rt"
|
name = "wit-bindgen-rt"
|
||||||
version = "0.33.0"
|
version = "0.33.0"
|
||||||
|
|||||||
+1
-1
@@ -21,7 +21,7 @@ brk_query = { version = "0", path = "crates/brk_query" }
|
|||||||
brk_server = { version = "0", path = "crates/brk_server" }
|
brk_server = { version = "0", path = "crates/brk_server" }
|
||||||
brk_vec = { version = "0", path = "crates/brk_vec" }
|
brk_vec = { version = "0", path = "crates/brk_vec" }
|
||||||
byteview = "0.5.4"
|
byteview = "0.5.4"
|
||||||
clap = { version = "4.5.31", features = ["derive"] }
|
clap = { version = "4.5.31", features = ["derive", "string"] }
|
||||||
color-eyre = "0.6.3"
|
color-eyre = "0.6.3"
|
||||||
derive_deref = "1.1.1"
|
derive_deref = "1.1.1"
|
||||||
fjall = "2.6.7"
|
fjall = "2.6.7"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Bitcoin Research Kit
|
# Bitcoin Research Kit
|
||||||
|
|
||||||
The Bitcoin Research Kit is a suite of tools designed to extract, compute, serve and display data stored on a Bitcoin Core node.
|
The Bitcoin Research Kit is a suite of tools designed to parse, index, compute, serve and display data stored on a Bitcoin Core node.
|
||||||
|
|
||||||
In other words it's an alternative to [Glassnode](https://glassnode.com), [mempool.space](https://mempool.space/) and [electrs](https://github.com/romanz/electrs) all in one package with a particular focus on the self-hosting experience.
|
In other words it's an alternative to [Glassnode](https://glassnode.com), [mempool.space](https://mempool.space/) and [electrs](https://github.com/romanz/electrs) all in one package with a particular focus on the self-hosting experience.
|
||||||
|
|
||||||
|
|||||||
@@ -18,21 +18,27 @@ use storage::{Stores, Vecs};
|
|||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Computer {
|
pub struct Computer {
|
||||||
path: PathBuf,
|
path: PathBuf,
|
||||||
pub vecs: Vecs,
|
vecs: Option<Vecs>,
|
||||||
pub stores: Stores,
|
stores: Option<Stores>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Computer {
|
impl Computer {
|
||||||
pub fn import(computed_dir: &Path) -> color_eyre::Result<Self> {
|
pub fn new(computed_dir: &Path) -> Self {
|
||||||
let vecs = Vecs::import(&computed_dir.join("vecs"))?;
|
Self {
|
||||||
|
|
||||||
let stores = Stores::import(&computed_dir.join("stores"))?;
|
|
||||||
|
|
||||||
Ok(Self {
|
|
||||||
path: computed_dir.to_owned(),
|
path: computed_dir.to_owned(),
|
||||||
vecs,
|
vecs: None,
|
||||||
stores,
|
stores: None,
|
||||||
})
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn import_vecs(&mut self) -> color_eyre::Result<()> {
|
||||||
|
self.vecs = Some(Vecs::import(&self.path.join("vecs"))?);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn import_stores(&mut self) -> color_eyre::Result<()> {
|
||||||
|
self.stores = Some(Stores::import(&self.path.join("stores"))?);
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -40,65 +46,65 @@ impl Computer {
|
|||||||
pub fn compute(&mut self, indexer: &mut Indexer, starting_indexes: Indexes, exit: &Exit) -> color_eyre::Result<()> {
|
pub fn compute(&mut self, indexer: &mut Indexer, starting_indexes: Indexes, exit: &Exit) -> color_eyre::Result<()> {
|
||||||
info!("Computing...");
|
info!("Computing...");
|
||||||
|
|
||||||
let height_count = indexer.vecs.height_to_size.len();
|
let height_count = indexer.vecs().height_to_size.len();
|
||||||
let txindexes_count = indexer.vecs.txindex_to_txid.len();
|
let txindexes_count = indexer.vecs().txindex_to_txid.len();
|
||||||
let txinindexes_count = indexer.vecs.txinindex_to_txoutindex.len();
|
let txinindexes_count = indexer.vecs().txinindex_to_txoutindex.len();
|
||||||
let txoutindexes_count = indexer.vecs.txoutindex_to_addressindex.len();
|
let txoutindexes_count = indexer.vecs().txoutindex_to_addressindex.len();
|
||||||
|
|
||||||
// TODO: Remove all outdated
|
// TODO: Remove all outdated
|
||||||
|
|
||||||
// self.vecs.txindex_to_last_txinindex.compute_last_index_from_first(
|
// self.vecs.txindex_to_last_txinindex.compute_last_index_from_first(
|
||||||
// starting_indexes.txindex,
|
// starting_indexes.txindex,
|
||||||
// &mut indexer.vecs.txindex_to_first_txinindex,
|
// &mut indexer.vecs().txindex_to_first_txinindex,
|
||||||
// txinindexes_count,
|
// txinindexes_count,
|
||||||
// exit,
|
// exit,
|
||||||
// )?;
|
// )?;
|
||||||
|
|
||||||
// self.vecs.txindex_to_inputs_count.compute_count_from_indexes(
|
// self.vecs.txindex_to_inputs_count.compute_count_from_indexes(
|
||||||
// starting_indexes.txindex,
|
// starting_indexes.txindex,
|
||||||
// &mut indexer.vecs.txindex_to_first_txinindex,
|
// &mut indexer.vecs().txindex_to_first_txinindex,
|
||||||
// &mut self.vecs.txindex_to_last_txinindex,
|
// &mut self.vecs.txindex_to_last_txinindex,
|
||||||
// exit,
|
// exit,
|
||||||
// )?;
|
// )?;
|
||||||
|
|
||||||
// self.vecs.txindex_to_last_txoutindex.compute_last_index_from_first(
|
// self.vecs.txindex_to_last_txoutindex.compute_last_index_from_first(
|
||||||
// starting_indexes.txindex,
|
// starting_indexes.txindex,
|
||||||
// &mut indexer.vecs.txindex_to_first_txoutindex,
|
// &mut indexer.vecs().txindex_to_first_txoutindex,
|
||||||
// txoutindexes_count,
|
// txoutindexes_count,
|
||||||
// exit,
|
// exit,
|
||||||
// )?;
|
// )?;
|
||||||
|
|
||||||
// self.vecs.txindex_to_outputs_count.compute_count_from_indexes(
|
// self.vecs.txindex_to_outputs_count.compute_count_from_indexes(
|
||||||
// starting_indexes.txindex,
|
// starting_indexes.txindex,
|
||||||
// &mut indexer.vecs.txindex_to_first_txoutindex,
|
// &mut indexer.vecs().txindex_to_first_txoutindex,
|
||||||
// &mut self.vecs.txindex_to_last_txoutindex,
|
// &mut self.vecs.txindex_to_last_txoutindex,
|
||||||
// exit,
|
// exit,
|
||||||
// )?;
|
// )?;
|
||||||
|
|
||||||
self.vecs.height_to_height.compute_transform(
|
self.mut_vecs().height_to_height.compute_transform(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&mut indexer.vecs.height_to_timestamp,
|
&mut indexer.mut_vecs().height_to_timestamp,
|
||||||
|_, height| height,
|
|_, height| height,
|
||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
self.vecs.height_to_date.compute_transform(
|
self.mut_vecs().height_to_date.compute_transform(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&mut indexer.vecs.height_to_timestamp,
|
&mut indexer.mut_vecs().height_to_timestamp,
|
||||||
|timestamp, _| Date::from(*timestamp),
|
|timestamp, _| Date::from(*timestamp),
|
||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
// self.vecs.height_to_last_txindex.compute_last_index_from_first(
|
// self.vecs.height_to_last_txindex.compute_last_index_from_first(
|
||||||
// starting_indexes.height,
|
// starting_indexes.height,
|
||||||
// &mut indexer.vecs.height_to_first_txindex,
|
// &mut indexer.vecs().height_to_first_txindex,
|
||||||
// height_count,
|
// height_count,
|
||||||
// exit,
|
// exit,
|
||||||
// )?;
|
// )?;
|
||||||
|
|
||||||
// self.vecs.txindex_to_height.compute_inverse_less_to_more(
|
// self.vecs.txindex_to_height.compute_inverse_less_to_more(
|
||||||
// starting_indexes.height,
|
// starting_indexes.height,
|
||||||
// &mut indexer.vecs.height_to_first_txindex,
|
// &mut indexer.vecs().height_to_first_txindex,
|
||||||
// &mut self.vecs.height_to_last_txindex,
|
// &mut self.vecs.height_to_last_txindex,
|
||||||
// exit,
|
// exit,
|
||||||
// )?;
|
// )?;
|
||||||
@@ -106,16 +112,16 @@ impl Computer {
|
|||||||
// self.vecs.txindex_to_is_coinbase.compute_is_first_ordered(
|
// self.vecs.txindex_to_is_coinbase.compute_is_first_ordered(
|
||||||
// starting_indexes.txindex,
|
// starting_indexes.txindex,
|
||||||
// &mut self.vecs.txindex_to_height,
|
// &mut self.vecs.txindex_to_height,
|
||||||
// &mut indexer.vecs.height_to_first_txindex,
|
// &mut indexer.vecs().height_to_first_txindex,
|
||||||
// exit,
|
// exit,
|
||||||
// )?;
|
// )?;
|
||||||
|
|
||||||
// self.vecs.txindex_to_fee.compute_transform(
|
// self.vecs.txindex_to_fee.compute_transform(
|
||||||
// &mut self.vecs.txindex_to_height,
|
// &mut self.vecs.txindex_to_height,
|
||||||
// &mut indexer.vecs.height_to_first_txindex,
|
// &mut indexer.vecs().height_to_first_txindex,
|
||||||
// )?;
|
// )?;
|
||||||
|
|
||||||
let date_count = self.vecs.height_to_date.len();
|
let date_count = self.vecs().height_to_date.len();
|
||||||
|
|
||||||
// self.vecs.height_to_dateindex.compute(...)
|
// self.vecs.height_to_dateindex.compute(...)
|
||||||
|
|
||||||
@@ -144,4 +150,20 @@ impl Computer {
|
|||||||
pub fn path(&self) -> &Path {
|
pub fn path(&self) -> &Path {
|
||||||
&self.path
|
&self.path
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn vecs(&self) -> &Vecs {
|
||||||
|
self.vecs.as_ref().unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn mut_vecs(&mut self) -> &mut Vecs {
|
||||||
|
self.vecs.as_mut().unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn stores(&self) -> &Stores {
|
||||||
|
self.stores.as_ref().unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn mut_stores(&mut self) -> &mut Stores {
|
||||||
|
self.stores.as_mut().unwrap()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,20 +14,24 @@ pub fn main() -> color_eyre::Result<()> {
|
|||||||
|
|
||||||
brk_logger::init(Some(Path::new(".log")));
|
brk_logger::init(Some(Path::new(".log")));
|
||||||
|
|
||||||
let data_dir = Path::new("../../../bitcoin");
|
let bitcoin_dir = Path::new("../../../bitcoin");
|
||||||
let rpc = Box::leak(Box::new(rpc::Client::new(
|
let rpc = Box::leak(Box::new(rpc::Client::new(
|
||||||
"http://localhost:8332",
|
"http://localhost:8332",
|
||||||
rpc::Auth::CookieFile(Path::new(data_dir).join(".cookie")),
|
rpc::Auth::CookieFile(Path::new(bitcoin_dir).join(".cookie")),
|
||||||
)?));
|
)?));
|
||||||
let exit = Exit::new();
|
let exit = Exit::new();
|
||||||
|
|
||||||
let parser = Parser::new(data_dir, rpc);
|
let parser = Parser::new(bitcoin_dir, rpc);
|
||||||
|
|
||||||
let outputs_dir = Path::new("../../_outputs");
|
let outputs_dir = Path::new("../../_outputs");
|
||||||
|
|
||||||
let mut indexer = Indexer::import(&outputs_dir.join("indexed"))?;
|
let mut indexer = Indexer::new(&outputs_dir.join("indexed"))?;
|
||||||
|
indexer.import_stores()?;
|
||||||
|
indexer.import_vecs()?;
|
||||||
|
|
||||||
let mut computer = Computer::import(&outputs_dir.join("computed"))?;
|
let mut computer = Computer::new(&outputs_dir.join("computed"));
|
||||||
|
computer.import_stores()?;
|
||||||
|
computer.import_vecs()?;
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let block_count = rpc.get_block_count()?;
|
let block_count = rpc.get_block_count()?;
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
collections::BTreeMap,
|
collections::BTreeMap,
|
||||||
path::Path,
|
path::{Path, PathBuf},
|
||||||
str::FromStr,
|
str::FromStr,
|
||||||
thread::{self},
|
thread::{self},
|
||||||
};
|
};
|
||||||
@@ -19,7 +19,7 @@ pub use brk_parser::*;
|
|||||||
use bitcoin::{Transaction, TxIn, TxOut};
|
use bitcoin::{Transaction, TxIn, TxOut};
|
||||||
use brk_exit::Exit;
|
use brk_exit::Exit;
|
||||||
use color_eyre::eyre::{ContextCompat, eyre};
|
use color_eyre::eyre::{ContextCompat, eyre};
|
||||||
use log::{debug, info};
|
use log::info;
|
||||||
use rayon::prelude::*;
|
use rayon::prelude::*;
|
||||||
mod indexes;
|
mod indexes;
|
||||||
mod stores;
|
mod stores;
|
||||||
@@ -33,37 +33,63 @@ const SNAPSHOT_BLOCK_RANGE: usize = 1000;
|
|||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Indexer {
|
pub struct Indexer {
|
||||||
pub vecs: Vecs,
|
path: PathBuf,
|
||||||
pub stores: Stores,
|
vecs: Option<Vecs>,
|
||||||
|
stores: Option<Stores>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Indexer {
|
impl Indexer {
|
||||||
pub fn import(indexes_dir: &Path) -> color_eyre::Result<Self> {
|
pub fn new(indexes_dir: &Path) -> color_eyre::Result<Self> {
|
||||||
setrlimit()?;
|
setrlimit()?;
|
||||||
|
Ok(Self {
|
||||||
|
path: indexes_dir.to_owned(),
|
||||||
|
vecs: None,
|
||||||
|
stores: None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
debug!("Importing indexes...");
|
pub fn import_vecs(&mut self) -> color_eyre::Result<()> {
|
||||||
|
self.vecs = Some(Vecs::import(&self.path.join("vecs"))?);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
let vecs = Vecs::import(&indexes_dir.join("vecs"))?;
|
pub fn import_stores(&mut self) -> color_eyre::Result<()> {
|
||||||
|
self.stores = Some(Stores::import(&self.path.join("stores"))?);
|
||||||
let stores = Stores::import(&indexes_dir.join("stores"))?;
|
Ok(())
|
||||||
|
|
||||||
Ok(Self { vecs, stores })
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn index(&mut self, parser: &Parser, rpc: &'static rpc::Client, exit: &Exit) -> color_eyre::Result<Indexes> {
|
pub fn index(&mut self, parser: &Parser, rpc: &'static rpc::Client, exit: &Exit) -> color_eyre::Result<Indexes> {
|
||||||
let check_collisions = true;
|
let check_collisions = true;
|
||||||
|
|
||||||
let starting_indexes = Indexes::try_from((&mut self.vecs, &self.stores, rpc)).unwrap_or_else(|_| {
|
let starting_indexes = Indexes::try_from((self.vecs.as_mut().unwrap(), self.stores.as_ref().unwrap(), rpc))
|
||||||
let indexes = Indexes::default();
|
.unwrap_or_else(|_| {
|
||||||
indexes.push_if_needed(&mut self.vecs).unwrap();
|
let indexes = Indexes::default();
|
||||||
indexes
|
indexes.push_if_needed(self.vecs.as_mut().unwrap()).unwrap();
|
||||||
});
|
indexes
|
||||||
|
});
|
||||||
|
|
||||||
exit.block();
|
exit.block();
|
||||||
self.stores.rollback_if_needed(&self.vecs, &starting_indexes)?;
|
self.stores
|
||||||
self.vecs.rollback_if_needed(&starting_indexes)?;
|
.as_mut()
|
||||||
|
.unwrap()
|
||||||
|
.rollback_if_needed(self.vecs.as_ref().unwrap(), &starting_indexes)?;
|
||||||
|
self.vecs.as_mut().unwrap().rollback_if_needed(&starting_indexes)?;
|
||||||
exit.release();
|
exit.release();
|
||||||
|
|
||||||
|
let vecs = self.vecs.as_mut().unwrap();
|
||||||
|
let stores = self.stores.as_mut().unwrap();
|
||||||
|
|
||||||
|
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 export_if_needed =
|
let export_if_needed =
|
||||||
|stores: &mut Stores, vecs: &mut Vecs, height: Height, rem: bool, exit: &Exit| -> color_eyre::Result<()> {
|
|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() {
|
if height == 0 || (height % SNAPSHOT_BLOCK_RANGE != 0) != rem || exit.triggered() {
|
||||||
@@ -78,20 +104,6 @@ impl Indexer {
|
|||||||
Ok(())
|
Ok(())
|
||||||
};
|
};
|
||||||
|
|
||||||
let vecs = &mut self.vecs;
|
|
||||||
let stores = &mut self.stores;
|
|
||||||
|
|
||||||
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...");
|
|
||||||
|
|
||||||
parser.parse(start, None).iter().try_for_each(
|
parser.parse(start, None).iter().try_for_each(
|
||||||
|(height, block, blockhash)| -> color_eyre::Result<()> {
|
|(height, block, blockhash)| -> color_eyre::Result<()> {
|
||||||
info!("Indexing block {height}...");
|
info!("Indexing block {height}...");
|
||||||
@@ -639,6 +651,26 @@ impl Indexer {
|
|||||||
|
|
||||||
Ok(starting_indexes)
|
Ok(starting_indexes)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn path(&self) -> &Path {
|
||||||
|
&self.path
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn vecs(&self) -> &Vecs {
|
||||||
|
self.vecs.as_ref().unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn mut_vecs(&mut self) -> &mut Vecs {
|
||||||
|
self.vecs.as_mut().unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn stores(&self) -> &Stores {
|
||||||
|
self.stores.as_ref().unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn mut_stores(&mut self) -> &mut Stores {
|
||||||
|
self.stores.as_mut().unwrap()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|||||||
@@ -13,22 +13,24 @@ fn main() -> color_eyre::Result<()> {
|
|||||||
|
|
||||||
brk_logger::init(Some(Path::new(".log")));
|
brk_logger::init(Some(Path::new(".log")));
|
||||||
|
|
||||||
let data_dir = Path::new("../../../bitcoin");
|
let bitcoin_dir = Path::new("../../../bitcoin");
|
||||||
let rpc = Box::leak(Box::new(rpc::Client::new(
|
let rpc = Box::leak(Box::new(rpc::Client::new(
|
||||||
"http://localhost:8332",
|
"http://localhost:8332",
|
||||||
rpc::Auth::CookieFile(Path::new(data_dir).join(".cookie")),
|
rpc::Auth::CookieFile(Path::new(bitcoin_dir).join(".cookie")),
|
||||||
)?));
|
)?));
|
||||||
let exit = Exit::new();
|
let exit = Exit::new();
|
||||||
|
|
||||||
let parser = Parser::new(data_dir, rpc);
|
let parser = Parser::new(bitcoin_dir, rpc);
|
||||||
|
|
||||||
|
let mut indexer = Indexer::new(Path::new("../../_outputs/indexed"))?;
|
||||||
|
indexer.import_stores()?;
|
||||||
|
indexer.import_vecs()?;
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let block_count = rpc.get_block_count()?;
|
let block_count = rpc.get_block_count()?;
|
||||||
|
|
||||||
info!("{block_count} blocks found.");
|
info!("{block_count} blocks found.");
|
||||||
|
|
||||||
let mut indexer = Indexer::import(Path::new("../../_outputs/indexed"))?;
|
|
||||||
|
|
||||||
indexer.index(&parser, rpc, &exit)?;
|
indexer.index(&parser, rpc, &exit)?;
|
||||||
|
|
||||||
info!("Waiting for new blocks...");
|
info!("Waiting for new blocks...");
|
||||||
|
|||||||
@@ -27,16 +27,16 @@ impl StoreMeta {
|
|||||||
Self::reset_(path)?;
|
Self::reset_(path)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let this = Self {
|
let slf = Self {
|
||||||
pathbuf: path.to_owned(),
|
pathbuf: path.to_owned(),
|
||||||
version,
|
version,
|
||||||
height: Height::try_from(Self::path_height_(path).as_path()).ok(),
|
height: Height::try_from(Self::path_height_(path).as_path()).ok(),
|
||||||
len: Self::read_length_(path)?,
|
len: Self::read_length_(path)?,
|
||||||
};
|
};
|
||||||
|
|
||||||
this.version.write(&this.path_version())?;
|
slf.version.write(&slf.path_version())?;
|
||||||
|
|
||||||
Ok(this)
|
Ok(slf)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn len(&self) -> usize {
|
pub fn len(&self) -> usize {
|
||||||
|
|||||||
@@ -13,8 +13,8 @@ const DAT: &str = ".dat";
|
|||||||
pub struct BlkIndexToBlkPath(BTreeMap<u16, PathBuf>);
|
pub struct BlkIndexToBlkPath(BTreeMap<u16, PathBuf>);
|
||||||
|
|
||||||
impl BlkIndexToBlkPath {
|
impl BlkIndexToBlkPath {
|
||||||
pub fn scan(data_dir: &Path) -> Self {
|
pub fn scan(bitcoin_dir: &Path) -> Self {
|
||||||
let blocks_dir = data_dir.join("blocks");
|
let blocks_dir = bitcoin_dir.join("blocks");
|
||||||
|
|
||||||
Self(
|
Self(
|
||||||
fs::read_dir(blocks_dir)
|
fs::read_dir(blocks_dir)
|
||||||
|
|||||||
@@ -14,8 +14,8 @@ pub struct BlkIndexToBlkRecap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl BlkIndexToBlkRecap {
|
impl BlkIndexToBlkRecap {
|
||||||
pub fn import(data_dir: &Path, blk_index_to_blk_path: &BlkIndexToBlkPath, start: Option<Height>) -> (Self, u16) {
|
pub fn import(bitcoin_dir: &Path, blk_index_to_blk_path: &BlkIndexToBlkPath, start: Option<Height>) -> (Self, u16) {
|
||||||
let path = data_dir.join("blk_index_to_blk_recap.json");
|
let path = bitcoin_dir.join("blk_index_to_blk_recap.json");
|
||||||
|
|
||||||
let tree = {
|
let tree = {
|
||||||
if let Ok(file) = File::open(&path) {
|
if let Ok(file) = File::open(&path) {
|
||||||
|
|||||||
@@ -47,14 +47,14 @@ const MAGIC_BYTES: [u8; 4] = [249, 190, 180, 217];
|
|||||||
const BOUND_CAP: usize = 50;
|
const BOUND_CAP: usize = 50;
|
||||||
|
|
||||||
pub struct Parser {
|
pub struct Parser {
|
||||||
data_dir: PathBuf,
|
bitcoin_dir: PathBuf,
|
||||||
rpc: &'static bitcoincore_rpc::Client,
|
rpc: &'static bitcoincore_rpc::Client,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Parser {
|
impl Parser {
|
||||||
pub fn new(data_dir: &Path, rpc: &'static bitcoincore_rpc::Client) -> Self {
|
pub fn new(bitcoin_dir: &Path, rpc: &'static bitcoincore_rpc::Client) -> Self {
|
||||||
Self {
|
Self {
|
||||||
data_dir: data_dir.to_owned(),
|
bitcoin_dir: bitcoin_dir.to_owned(),
|
||||||
rpc,
|
rpc,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -69,19 +69,19 @@ impl Parser {
|
|||||||
/// For an example checkout `./main.rs`
|
/// For an example checkout `./main.rs`
|
||||||
///
|
///
|
||||||
pub fn parse(&self, start: Option<Height>, end: Option<Height>) -> Receiver<(Height, Block, BlockHash)> {
|
pub fn parse(&self, start: Option<Height>, end: Option<Height>) -> Receiver<(Height, Block, BlockHash)> {
|
||||||
let data_dir = self.data_dir.as_path();
|
let bitcoin_dir = self.bitcoin_dir.as_path();
|
||||||
let rpc = self.rpc;
|
let rpc = self.rpc;
|
||||||
|
|
||||||
let (send_bytes, recv_bytes) = bounded(BOUND_CAP);
|
let (send_bytes, recv_bytes) = bounded(BOUND_CAP);
|
||||||
let (send_block, recv_block) = bounded(BOUND_CAP);
|
let (send_block, recv_block) = bounded(BOUND_CAP);
|
||||||
let (send_height_block_hash, recv_height_block_hash) = bounded(BOUND_CAP);
|
let (send_height_block_hash, recv_height_block_hash) = bounded(BOUND_CAP);
|
||||||
|
|
||||||
let blk_index_to_blk_path = BlkIndexToBlkPath::scan(data_dir);
|
let blk_index_to_blk_path = BlkIndexToBlkPath::scan(bitcoin_dir);
|
||||||
|
|
||||||
let (mut blk_index_to_blk_recap, blk_index) =
|
let (mut blk_index_to_blk_recap, blk_index) =
|
||||||
BlkIndexToBlkRecap::import(data_dir, &blk_index_to_blk_path, start);
|
BlkIndexToBlkRecap::import(bitcoin_dir, &blk_index_to_blk_path, start);
|
||||||
|
|
||||||
let xor_bytes = XORBytes::from(data_dir);
|
let xor_bytes = XORBytes::from(bitcoin_dir);
|
||||||
|
|
||||||
thread::spawn(move || {
|
thread::spawn(move || {
|
||||||
let xor_bytes = xor_bytes;
|
let xor_bytes = xor_bytes;
|
||||||
|
|||||||
@@ -7,11 +7,11 @@ use brk_parser::Parser;
|
|||||||
fn main() {
|
fn main() {
|
||||||
let i = std::time::Instant::now();
|
let i = std::time::Instant::now();
|
||||||
|
|
||||||
let data_dir = Path::new("../../../bitcoin");
|
let bitcoin_dir = Path::new("../../../bitcoin");
|
||||||
let rpc = Box::leak(Box::new(
|
let rpc = Box::leak(Box::new(
|
||||||
Client::new(
|
Client::new(
|
||||||
"http://localhost:8332",
|
"http://localhost:8332",
|
||||||
Auth::CookieFile(Path::new(data_dir).join(".cookie")),
|
Auth::CookieFile(Path::new(bitcoin_dir).join(".cookie")),
|
||||||
)
|
)
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
));
|
));
|
||||||
@@ -19,7 +19,7 @@ fn main() {
|
|||||||
let start = None;
|
let start = None;
|
||||||
let end = None;
|
let end = None;
|
||||||
|
|
||||||
let parser = Parser::new(data_dir, rpc);
|
let parser = Parser::new(bitcoin_dir, rpc);
|
||||||
|
|
||||||
parser.parse(start, end).iter().for_each(|(height, _block, hash)| {
|
parser.parse(start, end).iter().for_each(|(height, _block, hash)| {
|
||||||
println!("{height}: {hash}");
|
println!("{height}: {hash}");
|
||||||
|
|||||||
@@ -31,8 +31,17 @@ impl<'a> Query<'a> {
|
|||||||
pub fn build(indexer: &'a Indexer, computer: &'a Computer) -> Self {
|
pub fn build(indexer: &'a Indexer, computer: &'a Computer) -> Self {
|
||||||
let mut vecs = VecIdToIndexToVec::default();
|
let mut vecs = VecIdToIndexToVec::default();
|
||||||
|
|
||||||
indexer.vecs.as_any_vecs().into_iter().for_each(|vec| vecs.insert(vec));
|
indexer
|
||||||
computer.vecs.as_any_vecs().into_iter().for_each(|vec| vecs.insert(vec));
|
.vecs()
|
||||||
|
.as_any_vecs()
|
||||||
|
.into_iter()
|
||||||
|
.for_each(|vec| vecs.insert(vec));
|
||||||
|
|
||||||
|
computer
|
||||||
|
.vecs()
|
||||||
|
.as_any_vecs()
|
||||||
|
.into_iter()
|
||||||
|
.for_each(|vec| vecs.insert(vec));
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
vecid_to_index_to_vec: vecs,
|
vecid_to_index_to_vec: vecs,
|
||||||
|
|||||||
@@ -9,9 +9,11 @@ pub fn main() -> color_eyre::Result<()> {
|
|||||||
|
|
||||||
let outputs_dir = Path::new("../../_outputs");
|
let outputs_dir = Path::new("../../_outputs");
|
||||||
|
|
||||||
let indexer = Indexer::import(&outputs_dir.join("indexed"))?;
|
let mut indexer = Indexer::new(&outputs_dir.join("indexed"))?;
|
||||||
|
indexer.import_vecs()?;
|
||||||
|
|
||||||
let computer = Computer::import(&outputs_dir.join("computed"))?;
|
let mut computer = Computer::new(&outputs_dir.join("computed"));
|
||||||
|
computer.import_vecs()?;
|
||||||
|
|
||||||
let query = Query::build(&indexer, &computer);
|
let query = Query::build(&indexer, &computer);
|
||||||
|
|
||||||
|
|||||||
@@ -14,20 +14,24 @@ pub fn main() -> color_eyre::Result<()> {
|
|||||||
|
|
||||||
brk_logger::init(Some(Path::new(".log")));
|
brk_logger::init(Some(Path::new(".log")));
|
||||||
|
|
||||||
let data_dir = Path::new("../../../bitcoin");
|
let bitcoin_dir = Path::new("../../../bitcoin");
|
||||||
let rpc = Box::leak(Box::new(rpc::Client::new(
|
let rpc = Box::leak(Box::new(rpc::Client::new(
|
||||||
"http://localhost:8332",
|
"http://localhost:8332",
|
||||||
rpc::Auth::CookieFile(Path::new(data_dir).join(".cookie")),
|
rpc::Auth::CookieFile(Path::new(bitcoin_dir).join(".cookie")),
|
||||||
)?));
|
)?));
|
||||||
let exit = Exit::new();
|
let exit = Exit::new();
|
||||||
|
|
||||||
let parser = Parser::new(data_dir, rpc);
|
let parser = Parser::new(bitcoin_dir, rpc);
|
||||||
|
|
||||||
let outputs_dir = Path::new("../../_outputs");
|
let outputs_dir = Path::new("../../_outputs");
|
||||||
|
|
||||||
let mut indexer = Indexer::import(&outputs_dir.join("indexed"))?;
|
let mut indexer = Indexer::new(&outputs_dir.join("indexed"))?;
|
||||||
|
indexer.import_stores()?;
|
||||||
|
indexer.import_vecs()?;
|
||||||
|
|
||||||
let mut computer = Computer::import(&outputs_dir.join("computed"))?;
|
let mut computer = Computer::new(&outputs_dir.join("computed"));
|
||||||
|
computer.import_stores()?;
|
||||||
|
computer.import_vecs()?;
|
||||||
|
|
||||||
tokio::runtime::Builder::new_multi_thread()
|
tokio::runtime::Builder::new_multi_thread()
|
||||||
.enable_all()
|
.enable_all()
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
cargo check
|
||||||
|
|
||||||
cd crates/brk
|
cd crates/brk
|
||||||
|
|
||||||
cd ../brk_core
|
cd ../brk_core
|
||||||
|
|||||||
Reference in New Issue
Block a user