mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-04-24 06:39:58 -07:00
global: snapshot
This commit is contained in:
@@ -11,7 +11,7 @@ use brk_exit::Exit;
|
||||
use brk_fetcher::Fetcher;
|
||||
use brk_indexer::Indexer;
|
||||
use brk_parser::rpc::{self, Auth, Client, RpcApi};
|
||||
use brk_server::{Frontend, Server, tokio};
|
||||
use brk_server::{Server, Website, tokio};
|
||||
use clap::{Parser, ValueEnum};
|
||||
use color_eyre::eyre::eyre;
|
||||
use log::info;
|
||||
@@ -46,7 +46,7 @@ pub fn run(config: RunConfig) -> color_eyre::Result<()> {
|
||||
let served_indexer = indexer.clone();
|
||||
let served_computer = computer.clone();
|
||||
|
||||
let server = Server::new(served_indexer, served_computer, config.frontend())?;
|
||||
let server = Server::new(served_indexer, served_computer, config.website())?;
|
||||
|
||||
Some(tokio::spawn(async move {
|
||||
server.serve().await.unwrap();
|
||||
@@ -107,9 +107,9 @@ pub struct RunConfig {
|
||||
#[arg(short, long, value_name = "BOOL")]
|
||||
fetch: Option<bool>,
|
||||
|
||||
/// Frontend served by the server (if active), default: none, saved
|
||||
#[arg(short = 'F', long)]
|
||||
frontend: Option<Frontend>,
|
||||
/// Website served by the server (if active), default: none, saved
|
||||
#[arg(short, long)]
|
||||
website: Option<Website>,
|
||||
|
||||
/// Bitcoin RPC ip, default: localhost, saved
|
||||
#[arg(long, value_name = "IP")]
|
||||
@@ -167,8 +167,8 @@ impl RunConfig {
|
||||
config_saved.fetch = Some(fetch);
|
||||
}
|
||||
|
||||
if let Some(frontend) = config_args.frontend.take() {
|
||||
config_saved.frontend = Some(frontend);
|
||||
if let Some(website) = config_args.website.take() {
|
||||
config_saved.website = Some(website);
|
||||
}
|
||||
|
||||
if let Some(rpcconnect) = config_args.rpcconnect.take() {
|
||||
@@ -211,7 +211,7 @@ impl RunConfig {
|
||||
// info!(" bitcoindir: {:?}", config.bitcoindir);
|
||||
// info!(" brkdir: {:?}", config.brkdir);
|
||||
// info!(" mode: {:?}", config.mode);
|
||||
// info!(" frontend: {:?}", config.frontend);
|
||||
// info!(" website: {:?}", config.website);
|
||||
// info!(" rpcconnect: {:?}", config.rpcconnect);
|
||||
// info!(" rpcport: {:?}", config.rpcport);
|
||||
// info!(" rpccookiefile: {:?}", config.rpccookiefile);
|
||||
@@ -371,8 +371,8 @@ impl RunConfig {
|
||||
fix("~").unwrap_or_else(|| fix("$HOME").unwrap_or_else(|| PathBuf::from(&path)))
|
||||
}
|
||||
|
||||
pub fn frontend(&self) -> Frontend {
|
||||
self.frontend.unwrap_or_default()
|
||||
pub fn website(&self) -> Website {
|
||||
self.website.unwrap_or_default()
|
||||
}
|
||||
|
||||
pub fn fetch(&self) -> bool {
|
||||
|
||||
@@ -1,20 +1,25 @@
|
||||
use std::{fs, ops::Deref, path::Path};
|
||||
|
||||
use brk_core::{Date, Dateindex, Height};
|
||||
use brk_core::{Date, Dateindex, Height, Txindex, Txinindex, Txoutindex};
|
||||
use brk_exit::Exit;
|
||||
use brk_indexer::Indexer;
|
||||
use brk_vec::{AnyStorableVec, StorableVec, Value, Version};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Vecs {
|
||||
// pub height_to_last_addressindex: StorableVec<Height, Addressindex>,
|
||||
// pub height_to_last_txoutindex: StorableVec<Height, Txoutindex>,
|
||||
pub dateindex_to_date: StorableVec<Dateindex, Date>,
|
||||
pub dateindex_to_dateindex: StorableVec<Dateindex, Dateindex>,
|
||||
pub dateindex_to_first_height: StorableVec<Dateindex, Height>,
|
||||
pub dateindex_to_last_height: StorableVec<Dateindex, Height>,
|
||||
pub height_to_real_date: StorableVec<Height, Date>,
|
||||
pub height_to_dateindex: StorableVec<Height, Dateindex>,
|
||||
pub height_to_fixed_date: StorableVec<Height, Date>,
|
||||
pub height_to_height: StorableVec<Height, Height>,
|
||||
pub height_to_dateindex: StorableVec<Height, Dateindex>,
|
||||
pub height_to_last_txindex: StorableVec<Height, Txindex>,
|
||||
pub height_to_real_date: StorableVec<Height, Date>,
|
||||
pub txindex_to_last_txinindex: StorableVec<Txindex, Txinindex>,
|
||||
pub txindex_to_last_txoutindex: StorableVec<Txindex, Txoutindex>,
|
||||
}
|
||||
|
||||
impl Vecs {
|
||||
@@ -54,6 +59,19 @@ impl Vecs {
|
||||
&path.join("height_to_height"),
|
||||
Version::from(1),
|
||||
)?,
|
||||
height_to_last_txindex: StorableVec::forced_import(
|
||||
&path.join("height_to_last_txindex"),
|
||||
Version::from(1),
|
||||
)?,
|
||||
|
||||
txindex_to_last_txinindex: StorableVec::forced_import(
|
||||
&path.join("txindex_to_last_txinindex"),
|
||||
Version::from(1),
|
||||
)?,
|
||||
txindex_to_last_txoutindex: StorableVec::forced_import(
|
||||
&path.join("txindex_to_last_txoutindex"),
|
||||
Version::from(1),
|
||||
)?,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -63,16 +81,23 @@ impl Vecs {
|
||||
starting_indexes: brk_indexer::Indexes,
|
||||
exit: &Exit,
|
||||
) -> color_eyre::Result<Indexes> {
|
||||
let indexer_vecs = indexer.mut_vecs();
|
||||
|
||||
let height_count = indexer_vecs.height_to_size.len();
|
||||
let txindexes_count = indexer_vecs.txindex_to_txid.len();
|
||||
let txinindexes_count = indexer_vecs.txinindex_to_txoutindex.len();
|
||||
let txoutindexes_count = indexer_vecs.txoutindex_to_addressindex.len();
|
||||
|
||||
self.height_to_height.compute_transform(
|
||||
starting_indexes.height,
|
||||
&mut indexer.mut_vecs().height_to_timestamp,
|
||||
&mut indexer_vecs.height_to_timestamp,
|
||||
|(h, ..)| (h, h),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.height_to_real_date.compute_transform(
|
||||
starting_indexes.height,
|
||||
&mut indexer.mut_vecs().height_to_timestamp,
|
||||
&mut indexer_vecs.height_to_timestamp,
|
||||
|(h, t, ..)| (h, Date::from(*t)),
|
||||
exit,
|
||||
)?;
|
||||
@@ -111,12 +136,11 @@ impl Vecs {
|
||||
exit,
|
||||
)?;
|
||||
|
||||
let date_len = self.dateindex_to_first_height.len();
|
||||
self.dateindex_to_last_height
|
||||
.compute_last_index_from_first(
|
||||
starting_dateindex,
|
||||
&mut self.dateindex_to_first_height,
|
||||
date_len,
|
||||
height_count,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
@@ -134,96 +158,45 @@ impl Vecs {
|
||||
exit,
|
||||
)?;
|
||||
|
||||
// let height_count = indexer.vecs().height_to_size.len();
|
||||
// let txindexes_count = indexer.vecs().txindex_to_txid.len();
|
||||
// let txinindexes_count = indexer.vecs().txinindex_to_txoutindex.len();
|
||||
// let txoutindexes_count = indexer.vecs().txoutindex_to_addressindex.len();
|
||||
// let date_count = self.vecs().height_to_date.len();
|
||||
self.txindex_to_last_txinindex
|
||||
.compute_last_index_from_first(
|
||||
starting_indexes.txindex,
|
||||
&mut indexer_vecs.txindex_to_first_txinindex,
|
||||
txinindexes_count,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
// self.vecs.txindex_to_last_txinindex.compute_last_index_from_first(
|
||||
// starting_indexes.txindex,
|
||||
// &mut indexer.vecs().txindex_to_first_txinindex,
|
||||
// txinindexes_count,
|
||||
// exit,
|
||||
// )?;
|
||||
self.txindex_to_last_txoutindex
|
||||
.compute_last_index_from_first(
|
||||
starting_indexes.txindex,
|
||||
&mut indexer_vecs.txindex_to_first_txoutindex,
|
||||
txoutindexes_count,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
// self.vecs.txindex_to_inputs_count.compute_count_from_indexes(
|
||||
// starting_indexes.txindex,
|
||||
// &mut indexer.vecs().txindex_to_first_txinindex,
|
||||
// &mut self.vecs.txindex_to_last_txinindex,
|
||||
// exit,
|
||||
// )?;
|
||||
|
||||
// self.vecs.txindex_to_last_txoutindex.compute_last_index_from_first(
|
||||
// starting_indexes.txindex,
|
||||
// &mut indexer.vecs().txindex_to_first_txoutindex,
|
||||
// txoutindexes_count,
|
||||
// exit,
|
||||
// )?;
|
||||
|
||||
// self.vecs.txindex_to_outputs_count.compute_count_from_indexes(
|
||||
// starting_indexes.txindex,
|
||||
// &mut indexer.vecs().txindex_to_first_txoutindex,
|
||||
// &mut self.vecs.txindex_to_last_txoutindex,
|
||||
// exit,
|
||||
// )?;
|
||||
|
||||
// self.vecs.height_to_last_txindex.compute_last_index_from_first(
|
||||
// starting_indexes.height,
|
||||
// &mut indexer.vecs().height_to_first_txindex,
|
||||
// height_count,
|
||||
// exit,
|
||||
// )?;
|
||||
|
||||
// self.vecs.txindex_to_height.compute_inverse_less_to_more(
|
||||
// starting_indexes.height,
|
||||
// &mut indexer.vecs().height_to_first_txindex,
|
||||
// &mut self.vecs.height_to_last_txindex,
|
||||
// exit,
|
||||
// )?;
|
||||
|
||||
// self.vecs.txindex_to_is_coinbase.compute_is_first_ordered(
|
||||
// starting_indexes.txindex,
|
||||
// &mut self.vecs.txindex_to_height,
|
||||
// &mut indexer.vecs().height_to_first_txindex,
|
||||
// exit,
|
||||
// )?;
|
||||
|
||||
// self.vecs.txindex_to_fee.compute_transform(
|
||||
// &mut self.vecs.txindex_to_height,
|
||||
// &mut indexer.vecs().height_to_first_txindex,
|
||||
// )?;
|
||||
|
||||
// self.vecs.height_to_dateindex.compute(...)
|
||||
|
||||
// ---
|
||||
// Date to X
|
||||
// ---
|
||||
// ...
|
||||
|
||||
// ---
|
||||
// Month to X
|
||||
// ---
|
||||
// ...
|
||||
|
||||
// ---
|
||||
// Year to X
|
||||
// ---
|
||||
// ...
|
||||
self.height_to_last_txindex.compute_last_index_from_first(
|
||||
starting_indexes.height,
|
||||
&mut indexer_vecs.height_to_first_txindex,
|
||||
txindexes_count,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
Ok(Indexes::from((starting_indexes, starting_dateindex)))
|
||||
}
|
||||
|
||||
pub fn as_any_vecs(&self) -> Vec<&dyn AnyStorableVec> {
|
||||
vec![
|
||||
&self.dateindex_to_date as &dyn AnyStorableVec,
|
||||
&self.dateindex_to_date,
|
||||
&self.dateindex_to_dateindex,
|
||||
&self.dateindex_to_first_height,
|
||||
&self.dateindex_to_last_height,
|
||||
&self.height_to_real_date,
|
||||
&self.height_to_dateindex,
|
||||
&self.height_to_fixed_date,
|
||||
&self.height_to_height,
|
||||
&self.height_to_dateindex,
|
||||
&self.height_to_last_txindex,
|
||||
&self.height_to_real_date,
|
||||
&self.txindex_to_last_txinindex,
|
||||
&self.txindex_to_last_txoutindex,
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,13 +121,15 @@ impl Vecs {
|
||||
&mut self,
|
||||
indexer: &mut Indexer,
|
||||
indexes: &mut indexes::Vecs,
|
||||
starting_indexes: Indexes,
|
||||
starting_indexes: &Indexes,
|
||||
fetcher: &mut Fetcher,
|
||||
exit: &Exit,
|
||||
) -> color_eyre::Result<()> {
|
||||
let indexer_vecs = indexer.mut_vecs();
|
||||
|
||||
self.height_to_ohlc_in_cents.compute_transform(
|
||||
starting_indexes.height,
|
||||
&mut indexer.mut_vecs().height_to_timestamp,
|
||||
&mut indexer_vecs.height_to_timestamp,
|
||||
|(h, t, _, height_to_timestamp)| {
|
||||
let ohlc = fetcher
|
||||
.get_height(
|
||||
@@ -302,7 +304,7 @@ impl Vecs {
|
||||
|
||||
pub fn as_any_vecs(&self) -> Vec<&dyn AnyStorableVec> {
|
||||
vec![
|
||||
&self.dateindex_to_close as &dyn AnyStorableVec,
|
||||
&self.dateindex_to_close,
|
||||
&self.dateindex_to_close_in_cents,
|
||||
&self.dateindex_to_high,
|
||||
&self.dateindex_to_high_in_cents,
|
||||
|
||||
@@ -1,41 +1,19 @@
|
||||
use std::{fs, path::Path};
|
||||
|
||||
use brk_core::{Height, Sats, Txindex, Txinindex, Txoutindex};
|
||||
use brk_exit::Exit;
|
||||
use brk_fetcher::Fetcher;
|
||||
use brk_indexer::Indexer;
|
||||
use brk_vec::{AnyStorableVec, StorableVec, Version};
|
||||
use brk_vec::AnyStorableVec;
|
||||
|
||||
mod indexes;
|
||||
mod marketprice;
|
||||
mod transactions;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Vecs {
|
||||
pub indexes: indexes::Vecs,
|
||||
pub transactions: transactions::Vecs,
|
||||
pub marketprice: Option<marketprice::Vecs>,
|
||||
// pub height_to_block_interval: StorableVec<Height, Timestamp>,
|
||||
// pub height_to_fee: StorableVec<Txindex, Amount>,
|
||||
// pub height_to_inputcount: StorableVec<Height, u32>,
|
||||
// pub height_to_last_addressindex: StorableVec<Height, Addressindex>,
|
||||
pub height_to_last_txindex: StorableVec<Height, Txindex>,
|
||||
// pub height_to_last_txoutindex: StorableVec<Height, Txoutindex>,
|
||||
// pub height_to_maxfeerate: StorableVec<Height, Feerate>,
|
||||
// pub height_to_medianfeerate: StorableVec<Height, Feerate>,
|
||||
// pub height_to_minfeerate: StorableVec<Height, Feerate>,
|
||||
// pub height_to_outputcount: StorableVec<Height, u32>,
|
||||
// pub height_to_subsidy: StorableVec<Height, u32>,
|
||||
// pub height_to_totalfees: StorableVec<Height, Amount>,
|
||||
// pub height_to_txcount: StorableVec<Height, u32>,
|
||||
pub txindex_to_fee: StorableVec<Txindex, Sats>,
|
||||
pub txindex_to_height: StorableVec<Txindex, Height>,
|
||||
pub txindex_to_is_coinbase: StorableVec<Txindex, bool>,
|
||||
// pub txindex_to_feerate: StorableVec<Txindex, Feerate>,
|
||||
pub txindex_to_inputs_count: StorableVec<Txindex, u32>,
|
||||
pub txindex_to_inputs_sum: StorableVec<Txindex, Sats>,
|
||||
pub txindex_to_last_txinindex: StorableVec<Txindex, Txinindex>,
|
||||
pub txindex_to_last_txoutindex: StorableVec<Txindex, Txoutindex>,
|
||||
pub txindex_to_outputs_count: StorableVec<Txindex, u32>,
|
||||
pub txindex_to_outputs_sum: StorableVec<Txindex, Sats>,
|
||||
}
|
||||
|
||||
impl Vecs {
|
||||
@@ -43,64 +21,9 @@ impl Vecs {
|
||||
fs::create_dir_all(path)?;
|
||||
|
||||
Ok(Self {
|
||||
// height_to_block_interval: StorableVec::forced_import(&path.join("height_to_block_interval"), Version::from(1))?,
|
||||
indexes: indexes::Vecs::import(path)?,
|
||||
transactions: transactions::Vecs::import(path)?,
|
||||
marketprice: fetch.then(|| marketprice::Vecs::import(path).unwrap()),
|
||||
// height_to_fee: StorableVec::forced_import(&path.join("height_to_fee"), Version::from(1))?,
|
||||
// height_to_inputcount: StorableVec::forced_import(&path.join("height_to_inputcount"), Version::from(1))?,
|
||||
// height_to_last_addressindex: StorableVec::forced_import(
|
||||
// &path.join("height_to_last_addressindex"),
|
||||
// Version::from(1),
|
||||
// )?,
|
||||
height_to_last_txindex: StorableVec::forced_import(
|
||||
&path.join("height_to_last_txindex"),
|
||||
Version::from(1),
|
||||
)?,
|
||||
// height_to_last_txoutindex: StorableVec::forced_import(&path.join("height_to_last_txoutindex"), Version::from(1))?,
|
||||
// height_to_maxfeerate: StorableVec::forced_import(&path.join("height_to_maxfeerate"), Version::from(1))?,
|
||||
// height_to_medianfeerate: StorableVec::forced_import(&path.join("height_to_medianfeerate"), Version::from(1))?,
|
||||
// height_to_minfeerate: StorableVec::forced_import(&path.join("height_to_minfeerate"), Version::from(1))?,
|
||||
// height_to_outputcount: StorableVec::forced_import(&path.join("height_to_outputcount"), Version::from(1))?,
|
||||
// height_to_subsidy: StorableVec::forced_import(&path.join("height_to_subsidy"), Version::from(1))?,
|
||||
// height_to_totalfees: StorableVec::forced_import(&path.join("height_to_totalfees"), Version::from(1))?,
|
||||
// height_to_txcount: StorableVec::forced_import(&path.join("height_to_txcount"), Version::from(1))?,
|
||||
txindex_to_fee: StorableVec::forced_import(
|
||||
&path.join("txindex_to_fee"),
|
||||
Version::from(1),
|
||||
)?,
|
||||
txindex_to_height: StorableVec::forced_import(
|
||||
&path.join("txindex_to_height"),
|
||||
Version::from(1),
|
||||
)?,
|
||||
txindex_to_is_coinbase: StorableVec::forced_import(
|
||||
&path.join("txindex_to_is_coinbase"),
|
||||
Version::from(1),
|
||||
)?,
|
||||
// txindex_to_feerate: StorableVec::forced_import(&path.join("txindex_to_feerate"), Version::from(1))?,
|
||||
txindex_to_inputs_count: StorableVec::forced_import(
|
||||
&path.join("txindex_to_inputs_count"),
|
||||
Version::from(1),
|
||||
)?,
|
||||
txindex_to_inputs_sum: StorableVec::forced_import(
|
||||
&path.join("txindex_to_inputs_sum"),
|
||||
Version::from(1),
|
||||
)?,
|
||||
txindex_to_last_txinindex: StorableVec::forced_import(
|
||||
&path.join("txindex_to_last_txinindex"),
|
||||
Version::from(1),
|
||||
)?,
|
||||
txindex_to_last_txoutindex: StorableVec::forced_import(
|
||||
&path.join("txindex_to_last_txoutindex"),
|
||||
Version::from(1),
|
||||
)?,
|
||||
txindex_to_outputs_count: StorableVec::forced_import(
|
||||
&path.join("txindex_to_outputs_count"),
|
||||
Version::from(1),
|
||||
)?,
|
||||
txindex_to_outputs_sum: StorableVec::forced_import(
|
||||
&path.join("txindex_to_outputs_sum"),
|
||||
Version::from(1),
|
||||
)?,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -113,101 +36,26 @@ impl Vecs {
|
||||
) -> color_eyre::Result<()> {
|
||||
let starting_indexes = self.indexes.compute(indexer, starting_indexes, exit)?;
|
||||
|
||||
self.transactions
|
||||
.compute(indexer, &mut self.indexes, &starting_indexes, exit)?;
|
||||
|
||||
if let Some(marketprice) = self.marketprice.as_mut() {
|
||||
marketprice.compute(
|
||||
indexer,
|
||||
&mut self.indexes,
|
||||
starting_indexes,
|
||||
&starting_indexes,
|
||||
fetcher.unwrap(),
|
||||
exit,
|
||||
)?;
|
||||
}
|
||||
|
||||
// self.mut_vecs().height_to_ohlc
|
||||
|
||||
// let height_count = indexer.vecs().height_to_size.len();
|
||||
// let txindexes_count = indexer.vecs().txindex_to_txid.len();
|
||||
// let txinindexes_count = indexer.vecs().txinindex_to_txoutindex.len();
|
||||
// let txoutindexes_count = indexer.vecs().txoutindex_to_addressindex.len();
|
||||
// let date_count = self.vecs().height_to_date.len();
|
||||
|
||||
// self.vecs.txindex_to_last_txinindex.compute_last_index_from_first(
|
||||
// starting_indexes.txindex,
|
||||
// &mut indexer.vecs().txindex_to_first_txinindex,
|
||||
// txinindexes_count,
|
||||
// exit,
|
||||
// )?;
|
||||
|
||||
// self.vecs.txindex_to_inputs_count.compute_count_from_indexes(
|
||||
// starting_indexes.txindex,
|
||||
// &mut indexer.vecs().txindex_to_first_txinindex,
|
||||
// &mut self.vecs.txindex_to_last_txinindex,
|
||||
// exit,
|
||||
// )?;
|
||||
|
||||
// self.vecs.txindex_to_last_txoutindex.compute_last_index_from_first(
|
||||
// starting_indexes.txindex,
|
||||
// &mut indexer.vecs().txindex_to_first_txoutindex,
|
||||
// txoutindexes_count,
|
||||
// exit,
|
||||
// )?;
|
||||
|
||||
// self.vecs.txindex_to_outputs_count.compute_count_from_indexes(
|
||||
// starting_indexes.txindex,
|
||||
// &mut indexer.vecs().txindex_to_first_txoutindex,
|
||||
// &mut self.vecs.txindex_to_last_txoutindex,
|
||||
// exit,
|
||||
// )?;
|
||||
|
||||
// self.vecs.height_to_last_txindex.compute_last_index_from_first(
|
||||
// starting_indexes.height,
|
||||
// &mut indexer.vecs().height_to_first_txindex,
|
||||
// height_count,
|
||||
// exit,
|
||||
// )?;
|
||||
|
||||
// self.vecs.txindex_to_height.compute_inverse_less_to_more(
|
||||
// starting_indexes.height,
|
||||
// &mut indexer.vecs().height_to_first_txindex,
|
||||
// &mut self.vecs.height_to_last_txindex,
|
||||
// exit,
|
||||
// )?;
|
||||
|
||||
// self.vecs.txindex_to_is_coinbase.compute_is_first_ordered(
|
||||
// starting_indexes.txindex,
|
||||
// &mut self.vecs.txindex_to_height,
|
||||
// &mut indexer.vecs().height_to_first_txindex,
|
||||
// exit,
|
||||
// )?;
|
||||
|
||||
// self.vecs.txindex_to_fee.compute_transform(
|
||||
// &mut self.vecs.txindex_to_height,
|
||||
// &mut indexer.vecs().height_to_first_txindex,
|
||||
// )?;
|
||||
|
||||
// self.vecs.height_to_dateindex.compute(...)
|
||||
|
||||
// ---
|
||||
// Date to X
|
||||
// ---
|
||||
// ...
|
||||
|
||||
// ---
|
||||
// Month to X
|
||||
// ---
|
||||
// ...
|
||||
|
||||
// ---
|
||||
// Year to X
|
||||
// ---
|
||||
// ...
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn as_any_vecs(&self) -> Vec<&dyn AnyStorableVec> {
|
||||
[
|
||||
self.indexes.as_any_vecs(),
|
||||
self.transactions.as_any_vecs(),
|
||||
self.marketprice
|
||||
.as_ref()
|
||||
.map_or(vec![], |v| v.as_any_vecs()),
|
||||
|
||||
132
crates/brk_computer/src/storage/vecs/transactions.rs
Normal file
132
crates/brk_computer/src/storage/vecs/transactions.rs
Normal file
@@ -0,0 +1,132 @@
|
||||
use std::{fs, path::Path};
|
||||
|
||||
use brk_core::Txindex;
|
||||
use brk_exit::Exit;
|
||||
use brk_indexer::Indexer;
|
||||
use brk_vec::{AnyStorableVec, StorableVec, Version};
|
||||
|
||||
use super::indexes::{self, Indexes};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Vecs {
|
||||
// pub height_to_block_interval: StorableVec<Height, Timestamp>,
|
||||
// pub height_to_fee: StorableVec<Txindex, Sats>,
|
||||
// pub height_to_inputcount: StorableVec<Height, u32>,
|
||||
// pub height_to_maxfeerate: StorableVec<Height, Feerate>,
|
||||
// pub height_to_medianfeerate: StorableVec<Height, Feerate>,
|
||||
// pub height_to_minfeerate: StorableVec<Height, Feerate>,
|
||||
// pub height_to_outputcount: StorableVec<Height, u32>,
|
||||
// pub height_to_subsidy: StorableVec<Height, u32>,
|
||||
// pub height_to_totalfees: StorableVec<Height, Sats>,
|
||||
// pub height_to_txcount: StorableVec<Height, u32>,
|
||||
// pub txindex_to_fee: StorableVec<Txindex, Sats>,
|
||||
pub txindex_to_is_coinbase: StorableVec<Txindex, bool>,
|
||||
// pub txindex_to_feerate: StorableVec<Txindex, Feerate>,
|
||||
// pub txindex_to_inputs_count: StorableVec<Txindex, u32>,
|
||||
// pub txindex_to_inputs_sum: StorableVec<Txindex, Sats>,
|
||||
// pub txindex_to_outputs_count: StorableVec<Txindex, u32>,
|
||||
// pub txindex_to_outputs_sum: StorableVec<Txindex, Sats>,
|
||||
}
|
||||
|
||||
impl Vecs {
|
||||
pub fn import(path: &Path) -> color_eyre::Result<Self> {
|
||||
fs::create_dir_all(path)?;
|
||||
|
||||
Ok(Self {
|
||||
// height_to_block_interval: StorableVec::forced_import(&path.join("height_to_block_interval"), Version::from(1))?,
|
||||
// height_to_fee: StorableVec::forced_import(&path.join("height_to_fee"), Version::from(1))?,
|
||||
// height_to_inputcount: StorableVec::forced_import(&path.join("height_to_inputcount"), Version::from(1))?,
|
||||
// height_to_maxfeerate: StorableVec::forced_import(&path.join("height_to_maxfeerate"), Version::from(1))?,
|
||||
// height_to_medianfeerate: StorableVec::forced_import(&path.join("height_to_medianfeerate"), Version::from(1))?,
|
||||
// height_to_minfeerate: StorableVec::forced_import(&path.join("height_to_minfeerate"), Version::from(1))?,
|
||||
// height_to_outputcount: StorableVec::forced_import(&path.join("height_to_outputcount"), Version::from(1))?,
|
||||
// height_to_subsidy: StorableVec::forced_import(&path.join("height_to_subsidy"), Version::from(1))?,
|
||||
// height_to_totalfees: StorableVec::forced_import(&path.join("height_to_totalfees"), Version::from(1))?,
|
||||
// height_to_txcount: StorableVec::forced_import(&path.join("height_to_txcount"), Version::from(1))?,
|
||||
// txindex_to_fee: StorableVec::forced_import(
|
||||
// &path.join("txindex_to_fee"),
|
||||
// Version::from(1),
|
||||
// )?,
|
||||
txindex_to_is_coinbase: StorableVec::forced_import(
|
||||
&path.join("txindex_to_is_coinbase"),
|
||||
Version::from(1),
|
||||
)?,
|
||||
// txindex_to_feerate: StorableVec::forced_import(&path.join("txindex_to_feerate"), Version::from(1))?,
|
||||
// txindex_to_inputs_count: StorableVec::forced_import(
|
||||
// &path.join("txindex_to_inputs_count"),
|
||||
// Version::from(1),
|
||||
// )?,
|
||||
// txindex_to_inputs_sum: StorableVec::forced_import(
|
||||
// &path.join("txindex_to_inputs_sum"),
|
||||
// Version::from(1),
|
||||
// )?,
|
||||
// txindex_to_outputs_count: StorableVec::forced_import(
|
||||
// &path.join("txindex_to_outputs_count"),
|
||||
// Version::from(1),
|
||||
// )?,
|
||||
// txindex_to_outputs_sum: StorableVec::forced_import(
|
||||
// &path.join("txindex_to_outputs_sum"),
|
||||
// Version::from(1),
|
||||
// )?,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn compute(
|
||||
&mut self,
|
||||
indexer: &mut Indexer,
|
||||
indexes: &mut indexes::Vecs,
|
||||
starting_indexes: &Indexes,
|
||||
exit: &Exit,
|
||||
) -> color_eyre::Result<()> {
|
||||
let indexer_vecs = indexer.mut_vecs();
|
||||
|
||||
// self.vecs.txindex_to_inputs_count.compute_count_from_indexes(
|
||||
// starting_indexes.txindex,
|
||||
// &mut indexer.vecs().txindex_to_first_txinindex,
|
||||
// &mut self.vecs.txindex_to_last_txinindex,
|
||||
// exit,
|
||||
// )?;
|
||||
|
||||
// self.vecs.txindex_to_outputs_count.compute_count_from_indexes(
|
||||
// starting_indexes.txindex,
|
||||
// &mut indexer.vecs().txindex_to_first_txoutindex,
|
||||
// &mut self.vecs.txindex_to_last_txoutindex,
|
||||
// exit,
|
||||
// )?;
|
||||
|
||||
self.txindex_to_is_coinbase.compute_is_first_ordered(
|
||||
starting_indexes.txindex,
|
||||
&mut indexer_vecs.txindex_to_height,
|
||||
&mut indexer_vecs.height_to_first_txindex,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
// self.vecs.txindex_to_fee.compute_transform(
|
||||
// &mut self.vecs.txindex_to_height,
|
||||
// &mut indexer.vecs().height_to_first_txindex,
|
||||
// )?;
|
||||
|
||||
// self.vecs.height_to_dateindex.compute(...)
|
||||
|
||||
// ---
|
||||
// Date to X
|
||||
// ---
|
||||
// ...
|
||||
|
||||
// ---
|
||||
// Month to X
|
||||
// ---
|
||||
// ...
|
||||
|
||||
// ---
|
||||
// Year to X
|
||||
// ---
|
||||
// ...
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn as_any_vecs(&self) -> Vec<&dyn AnyStorableVec> {
|
||||
vec![&self.txindex_to_is_coinbase]
|
||||
}
|
||||
}
|
||||
@@ -1,2 +1,5 @@
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
use serde::Serialize;
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
#[derive(Debug, Clone, Copy, Serialize, FromBytes, Immutable, IntoBytes, KnownLayout)]
|
||||
pub struct Feerate(f32);
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
use std::{
|
||||
iter::Sum,
|
||||
ops::{Add, AddAssign, Div, Mul, Sub, SubAssign},
|
||||
ops::{Add, AddAssign, Div, Mul, SubAssign},
|
||||
};
|
||||
|
||||
use bitcoin::Amount;
|
||||
use serde::Serialize;
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use crate::CheckedSub;
|
||||
|
||||
use super::{Bitcoin, Dollars, Height};
|
||||
|
||||
#[derive(
|
||||
@@ -48,16 +50,15 @@ impl AddAssign for Sats {
|
||||
}
|
||||
}
|
||||
|
||||
impl Sub for Sats {
|
||||
type Output = Sats;
|
||||
fn sub(self, rhs: Sats) -> Self::Output {
|
||||
Sats::from(self.0 - rhs.0)
|
||||
impl CheckedSub<Sats> for Sats {
|
||||
fn checked_sub(self, rhs: Sats) -> Option<Self> {
|
||||
self.0.checked_sub(rhs.0).map(Sats::from)
|
||||
}
|
||||
}
|
||||
|
||||
impl SubAssign for Sats {
|
||||
fn sub_assign(&mut self, rhs: Self) {
|
||||
*self = *self - rhs;
|
||||
*self = self.checked_sub(rhs).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
use std::ops::{Add, AddAssign, Sub};
|
||||
use std::ops::{Add, AddAssign};
|
||||
|
||||
use byteview::ByteView;
|
||||
use derive_deref::{Deref, DerefMut};
|
||||
use serde::Serialize;
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use crate::Error;
|
||||
use crate::{CheckedSub, Error};
|
||||
|
||||
#[derive(
|
||||
Debug,
|
||||
@@ -52,10 +52,9 @@ impl AddAssign<Txindex> for Txindex {
|
||||
}
|
||||
}
|
||||
|
||||
impl Sub<Txindex> for Txindex {
|
||||
type Output = Txindex;
|
||||
fn sub(self, rhs: Txindex) -> Self::Output {
|
||||
Self::from(*self - *rhs)
|
||||
impl CheckedSub<Txindex> for Txindex {
|
||||
fn checked_sub(self, rhs: Txindex) -> Option<Self> {
|
||||
self.0.checked_sub(rhs.0).map(Txindex::from)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
use std::ops::{Add, AddAssign, Sub};
|
||||
use std::ops::{Add, AddAssign};
|
||||
|
||||
use derive_deref::{Deref, DerefMut};
|
||||
use serde::Serialize;
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use crate::CheckedSub;
|
||||
|
||||
use super::Vin;
|
||||
|
||||
#[derive(
|
||||
@@ -58,10 +60,9 @@ impl AddAssign<Txinindex> for Txinindex {
|
||||
}
|
||||
}
|
||||
|
||||
impl Sub<Txinindex> for Txinindex {
|
||||
type Output = Self;
|
||||
fn sub(self, rhs: Txinindex) -> Self::Output {
|
||||
Self(self.0 - rhs.0)
|
||||
impl CheckedSub<Txinindex> for Txinindex {
|
||||
fn checked_sub(self, rhs: Txinindex) -> Option<Self> {
|
||||
self.0.checked_sub(rhs.0).map(Txinindex::from)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
use std::ops::{Add, AddAssign, Sub};
|
||||
use std::ops::{Add, AddAssign};
|
||||
|
||||
use derive_deref::{Deref, DerefMut};
|
||||
use serde::Serialize;
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use crate::CheckedSub;
|
||||
|
||||
use super::Vout;
|
||||
|
||||
#[derive(
|
||||
@@ -64,10 +66,9 @@ impl AddAssign<Txoutindex> for Txoutindex {
|
||||
}
|
||||
}
|
||||
|
||||
impl Sub<Txoutindex> for Txoutindex {
|
||||
type Output = Self;
|
||||
fn sub(self, rhs: Txoutindex) -> Self::Output {
|
||||
Self(self.0 - rhs.0)
|
||||
impl CheckedSub<Txoutindex> for Txoutindex {
|
||||
fn checked_sub(self, rhs: Txoutindex) -> Option<Self> {
|
||||
self.0.checked_sub(rhs.0).map(Txoutindex::from)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -447,7 +447,7 @@ impl Vecs {
|
||||
|
||||
pub fn as_any_vecs(&self) -> Vec<&dyn AnyStorableVec> {
|
||||
vec![
|
||||
&*self.addressindex_to_addresstype as &dyn AnyStorableVec,
|
||||
&*self.addressindex_to_addresstype,
|
||||
&*self.addressindex_to_addresstypeindex,
|
||||
&*self.addressindex_to_height,
|
||||
&*self.height_to_blockhash,
|
||||
@@ -495,7 +495,7 @@ impl Vecs {
|
||||
|
||||
fn as_mut_any_vecs(&mut self) -> Vec<&mut dyn AnyIndexedVec> {
|
||||
vec![
|
||||
&mut self.addressindex_to_addresstype as &mut dyn AnyIndexedVec,
|
||||
&mut self.addressindex_to_addresstype,
|
||||
&mut self.addressindex_to_addresstypeindex,
|
||||
&mut self.addressindex_to_height,
|
||||
&mut self.height_to_blockhash,
|
||||
|
||||
@@ -16,10 +16,15 @@ impl<'a> VecIdToIndexToVec<'a> {
|
||||
if split.len() != 2 {
|
||||
panic!();
|
||||
}
|
||||
let str = vec.index_type_to_string().split("::").last().unwrap().to_lowercase();
|
||||
let str = vec
|
||||
.index_type_to_string()
|
||||
.split("::")
|
||||
.last()
|
||||
.unwrap()
|
||||
.to_lowercase();
|
||||
let index = Index::try_from(str.as_str())
|
||||
.inspect_err(|_| {
|
||||
dbg!(str);
|
||||
dbg!(&str);
|
||||
})
|
||||
.unwrap();
|
||||
if split[0] != index.to_string().to_lowercase() {
|
||||
@@ -27,8 +32,9 @@ impl<'a> VecIdToIndexToVec<'a> {
|
||||
panic!();
|
||||
}
|
||||
let key = split[1].to_string().replace("_", "-");
|
||||
let prev = self.entry(key).or_default().insert(index, vec);
|
||||
let prev = self.entry(key.clone()).or_default().insert(index, vec);
|
||||
if prev.is_some() {
|
||||
dbg!(&key, str, file_name);
|
||||
panic!()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ use brk_parser::{
|
||||
Parser,
|
||||
rpc::{self, RpcApi},
|
||||
};
|
||||
use brk_server::{Frontend, Server};
|
||||
use brk_server::{Server, Website};
|
||||
use log::info;
|
||||
|
||||
pub fn main() -> color_eyre::Result<()> {
|
||||
@@ -48,7 +48,7 @@ pub fn main() -> color_eyre::Result<()> {
|
||||
let served_indexer = indexer.clone();
|
||||
let served_computer = computer.clone();
|
||||
|
||||
let server = Server::new(served_indexer, served_computer, Frontend::KiboMoney)?;
|
||||
let server = Server::new(served_indexer, served_computer, Website::KiboMoney)?;
|
||||
|
||||
let server = tokio::spawn(async move {
|
||||
server.serve().await.unwrap();
|
||||
|
||||
@@ -2,23 +2,23 @@ use std::{fs, io, path::Path};
|
||||
|
||||
use brk_query::{Index, Query};
|
||||
|
||||
use crate::Frontend;
|
||||
use crate::Website;
|
||||
|
||||
const SCRIPTS: &str = "scripts";
|
||||
const TPYES: &str = "types";
|
||||
|
||||
#[allow(clippy::upper_case_acronyms)]
|
||||
pub trait DTS {
|
||||
fn generate_dts_file(&self, frontend: Frontend, websites_path: &Path) -> io::Result<()>;
|
||||
fn generate_dts_file(&self, website: Website, websites_path: &Path) -> io::Result<()>;
|
||||
}
|
||||
|
||||
impl DTS for Query<'static> {
|
||||
fn generate_dts_file(&self, frontend: Frontend, websites_path: &Path) -> io::Result<()> {
|
||||
if frontend.is_none() {
|
||||
fn generate_dts_file(&self, website: Website, websites_path: &Path) -> io::Result<()> {
|
||||
if website.is_none() {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let path = websites_path.join(frontend.to_folder_name());
|
||||
let path = websites_path.join(website.to_folder_name());
|
||||
|
||||
if !fs::exists(&path)? {
|
||||
return Ok(());
|
||||
|
||||
@@ -46,7 +46,7 @@ fn any_handler(
|
||||
.websites_path
|
||||
.as_ref()
|
||||
.expect("Should never reach here is websites_path is None")
|
||||
.join(app_state.frontend.to_folder_name());
|
||||
.join(app_state.website.to_folder_name());
|
||||
|
||||
let instant = Instant::now();
|
||||
|
||||
|
||||
@@ -3,19 +3,19 @@ use axum::{Router, routing::get};
|
||||
use super::AppState;
|
||||
|
||||
mod file;
|
||||
mod frontend;
|
||||
mod minify;
|
||||
mod website;
|
||||
|
||||
use file::{file_handler, index_handler};
|
||||
pub use frontend::Frontend;
|
||||
pub use website::Website;
|
||||
|
||||
pub trait FilesRoutes {
|
||||
fn add_website_routes(self, frontend: Frontend) -> Self;
|
||||
fn add_website_routes(self, website: Website) -> Self;
|
||||
}
|
||||
|
||||
impl FilesRoutes for Router<AppState> {
|
||||
fn add_website_routes(self, frontend: Frontend) -> Self {
|
||||
if frontend.is_some() {
|
||||
fn add_website_routes(self, website: Website) -> Self {
|
||||
if website.is_some() {
|
||||
self.route("/{*path}", get(file_handler))
|
||||
.route("/", get(index_handler))
|
||||
} else {
|
||||
|
||||
@@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize};
|
||||
#[derive(
|
||||
Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Deserialize, Serialize, ValueEnum,
|
||||
)]
|
||||
pub enum Frontend {
|
||||
pub enum Website {
|
||||
#[default]
|
||||
None,
|
||||
#[value(name = "kibo.money")]
|
||||
@@ -12,7 +12,7 @@ pub enum Frontend {
|
||||
Custom,
|
||||
}
|
||||
|
||||
impl Frontend {
|
||||
impl Website {
|
||||
pub fn is_none(&self) -> bool {
|
||||
self == &Self::None
|
||||
}
|
||||
@@ -32,14 +32,14 @@ mod api;
|
||||
mod files;
|
||||
mod traits;
|
||||
|
||||
pub use files::Frontend;
|
||||
pub use files::Website;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct AppState {
|
||||
// indexer: &'static Indexer,
|
||||
// computer: &'static Computer,
|
||||
query: &'static Query<'static>,
|
||||
frontend: Frontend,
|
||||
website: Website,
|
||||
websites_path: Option<PathBuf>,
|
||||
}
|
||||
|
||||
@@ -51,16 +51,12 @@ const WEBSITES: &str = "websites";
|
||||
pub struct Server(AppState);
|
||||
|
||||
impl Server {
|
||||
pub fn new(
|
||||
indexer: Indexer,
|
||||
computer: Computer,
|
||||
frontend: Frontend,
|
||||
) -> color_eyre::Result<Self> {
|
||||
pub fn new(indexer: Indexer, computer: Computer, website: Website) -> color_eyre::Result<Self> {
|
||||
let indexer = Box::leak(Box::new(indexer));
|
||||
let computer = Box::leak(Box::new(computer));
|
||||
let query = Box::leak(Box::new(Query::build(indexer, computer)));
|
||||
|
||||
let websites_path = if frontend.is_some() {
|
||||
let websites_path = if website.is_some() {
|
||||
let websites_dev_path = Path::new(DEV_PATH).join(WEBSITES);
|
||||
|
||||
let websites_path = if fs::exists(&websites_dev_path)? {
|
||||
@@ -90,7 +86,7 @@ impl Server {
|
||||
downloaded_websites_path
|
||||
};
|
||||
|
||||
query.generate_dts_file(frontend, websites_path.as_path())?;
|
||||
query.generate_dts_file(website, websites_path.as_path())?;
|
||||
|
||||
Some(websites_path)
|
||||
} else {
|
||||
@@ -99,7 +95,7 @@ impl Server {
|
||||
|
||||
Ok(Self(AppState {
|
||||
query,
|
||||
frontend,
|
||||
website,
|
||||
websites_path,
|
||||
}))
|
||||
}
|
||||
@@ -115,7 +111,7 @@ impl Server {
|
||||
|
||||
let router = Router::new()
|
||||
.add_api_routes()
|
||||
.add_website_routes(state.frontend)
|
||||
.add_website_routes(state.website)
|
||||
.route("/version", get(Json(env!("CARGO_PKG_VERSION"))))
|
||||
.with_state(state)
|
||||
.layer(compression_layer);
|
||||
|
||||
@@ -52,18 +52,12 @@ pub struct StorableVec<I, T> {
|
||||
buf: Vec<u8>,
|
||||
mmaps: Vec<OnceLock<Box<memmap2::Mmap>>>, // Boxed Mmap to reduce the size of the Lock (from 24 to 16)
|
||||
pushed: Vec<T>,
|
||||
// updated: BTreeMap<usize, T>,
|
||||
// inserted: BTreeMap<usize, T>,
|
||||
// removed: BTreeSet<usize>,
|
||||
// min: AtomicUsize,
|
||||
// opened_mmaps: AtomicUsize,
|
||||
phantom: PhantomData<I>,
|
||||
}
|
||||
|
||||
/// In bytes
|
||||
const MAX_PAGE_SIZE: usize = 4 * 4096;
|
||||
const ONE_MB: usize = 1024 * 1024;
|
||||
// const MAX_CACHE_SIZE: usize = usize::MAX;
|
||||
const MAX_CACHE_SIZE: usize = 100 * ONE_MB;
|
||||
const FLUSH_EVERY: usize = 10_000;
|
||||
|
||||
@@ -112,12 +106,7 @@ where
|
||||
buf: Self::create_buffer(),
|
||||
mmaps: vec![],
|
||||
pushed: vec![],
|
||||
// updated: BTreeMap::new(),
|
||||
// inserted: BTreeMap::new(),
|
||||
// removed: BTreeSet::new(),
|
||||
phantom: PhantomData,
|
||||
// min: AtomicUsize::new(usize::MAX),
|
||||
// opened_mmaps: AtomicUsize::new(0),
|
||||
};
|
||||
|
||||
slf.reset_file_metadata()?;
|
||||
@@ -674,7 +663,7 @@ where
|
||||
let one = T::from(1);
|
||||
let mut prev_index: Option<I> = None;
|
||||
first_indexes.iter_from(index, |(i, v, ..)| {
|
||||
if let Some(prev_index) = prev_index {
|
||||
if let Some(prev_index) = prev_index.take() {
|
||||
self.push_and_flush_if_needed(prev_index, v.checked_sub(one).unwrap(), exit)?;
|
||||
}
|
||||
prev_index.replace(i);
|
||||
|
||||
Reference in New Issue
Block a user