From 0441c072637fb5f22e9c75e042e48213f60d4e5a Mon Sep 17 00:00:00 2001 From: Mariusz Reichert Date: Fri, 20 Sep 2024 12:15:50 +0200 Subject: [PATCH] Instrumenting functions --- src/bin/electrs.rs | 6 +++- src/config.rs | 2 +- src/daemon.rs | 34 ++++++++++++++++++++ src/electrum/server.rs | 21 +++++++++++++ src/lib.rs | 1 + src/new_index/db.rs | 5 +++ src/new_index/fetch.rs | 7 +++++ src/new_index/mempool.rs | 23 ++++++++++++++ src/new_index/precache.rs | 4 +++ src/new_index/query.rs | 20 ++++++++++++ src/new_index/schema.rs | 63 +++++++++++++++++++++++++++++++++++-- src/rest.rs | 4 +++ src/util/block.rs | 6 ++++ src/util/electrum_merkle.rs | 6 +++- src/util/fees.rs | 2 ++ 15 files changed, 199 insertions(+), 5 deletions(-) diff --git a/src/bin/electrs.rs b/src/bin/electrs.rs index fb25e68a8..4835a1362 100644 --- a/src/bin/electrs.rs +++ b/src/bin/electrs.rs @@ -16,6 +16,7 @@ use electrs::{ errors::*, metrics::Metrics, new_index::{precache, ChainQuery, FetchFrom, Indexer, Mempool, Query, Store}, + otlp_trace, rest, signal::Waiter, }; @@ -147,7 +148,10 @@ fn run_server(config: Arc) -> Result<()> { Ok(()) } -fn main() { +#[tokio::main] +async fn main() { + let _tracing_guard = otlp_trace::init_tracing("electrs"); + let config = Arc::new(Config::from_args()); if let Err(e) = run_server(config) { error!("server failed: {}", e.display_chain()); diff --git a/src/config.rs b/src/config.rs index 8696ecf8f..8874b2044 100644 --- a/src/config.rs +++ b/src/config.rs @@ -378,7 +378,7 @@ impl Config { } else { stderrlog::Timestamp::Off }); - log.init().expect("logging initialization failed"); + let config = Config { log, network_type, diff --git a/src/daemon.rs b/src/daemon.rs index 457bf4230..2367dd7aa 100644 --- a/src/daemon.rs +++ b/src/daemon.rs @@ -16,6 +16,7 @@ use serde_json::{from_str, from_value, Value}; use bitcoin::consensus::encode::{deserialize, serialize_hex}; #[cfg(feature = "liquid")] use elements::encode::{deserialize, serialize_hex}; +use tracing::instrument; use crate::chain::{Block, BlockHash, BlockHeader, Network, Transaction, Txid}; use crate::metrics::{HistogramOpts, HistogramVec, Metrics}; @@ -36,6 +37,7 @@ lazy_static! { ); } +#[instrument(skip_all, name="Daemon::parse_hash")] fn parse_hash(value: &Value) -> Result where T: FromStr, @@ -49,6 +51,7 @@ where .chain_err(|| format!("non-hex value: {}", value))?) } +#[instrument(skip_all, name="Daemon::header_from_value")] fn header_from_value(value: Value) -> Result { let header_hex = value .as_str() @@ -140,6 +143,7 @@ struct Connection { signal: Waiter, } +#[instrument(skip_all, name="Daemon::tcp_connect")] fn tcp_connect(addr: SocketAddr, signal: &Waiter) -> Result { loop { match TcpStream::connect_timeout(&addr, *DAEMON_CONNECTION_TIMEOUT) { @@ -162,6 +166,7 @@ fn tcp_connect(addr: SocketAddr, signal: &Waiter) -> Result { } impl Connection { + #[instrument(skip_all, name="Daemon::Connection::new")] fn new( addr: SocketAddr, cookie_getter: Arc, @@ -181,10 +186,12 @@ impl Connection { }) } + #[instrument(skip(self))] fn reconnect(&self) -> Result { Connection::new(self.addr, self.cookie_getter.clone(), self.signal.clone()) } + #[instrument(skip_all, name="Daemon::Connection::send")] fn send(&mut self, request: &str) -> Result<()> { let cookie = &self.cookie_getter.get()?; let msg = format!( @@ -198,6 +205,8 @@ impl Connection { }) } + + #[instrument(skip_all, name="Daemon::Connection::recv")] fn recv(&mut self) -> Result { // TODO: use proper HTTP parser. let mut in_header = true; @@ -353,6 +362,7 @@ impl Daemon { Ok(daemon) } + #[instrument(skip(self))] pub fn reconnect(&self) -> Result { Ok(Daemon { daemon_dir: self.daemon_dir.clone(), @@ -366,6 +376,7 @@ impl Daemon { }) } + #[instrument(skip_all, name="Daemon::list_blk_files")] pub fn list_blk_files(&self) -> Result> { let path = self.blocks_dir.join("blk*.dat"); debug!("listing block files at {:?}", path); @@ -381,6 +392,7 @@ impl Daemon { self.network.magic() } + #[instrument(skip_all, name="Daemon::call_jsonrpc")] fn call_jsonrpc(&self, method: &str, request: &Value) -> Result { let mut conn = self.conn.lock().unwrap(); let timer = self.latency.with_label_values(&[method]).start_timer(); @@ -398,6 +410,7 @@ impl Daemon { Ok(result) } + #[instrument(skip_all, name="Daemon::handle_request_batch")] fn handle_request_batch(&self, method: &str, params_list: &[Value]) -> Result> { let id = self.message_id.next(); let chunks = params_list @@ -420,6 +433,7 @@ impl Daemon { Ok(results) } + #[instrument(skip_all, name="Daemon::retry_request_batch")] fn retry_request_batch(&self, method: &str, params_list: &[Value]) -> Result> { loop { match self.handle_request_batch(method, params_list) { @@ -435,36 +449,43 @@ impl Daemon { } } + #[instrument(skip_all, name="Daemon::request")] fn request(&self, method: &str, params: Value) -> Result { let mut values = self.retry_request_batch(method, &[params])?; assert_eq!(values.len(), 1); Ok(values.remove(0)) } + #[instrument(skip_all, name="Daemon::requests")] fn requests(&self, method: &str, params_list: &[Value]) -> Result> { self.retry_request_batch(method, params_list) } // bitcoind JSONRPC API: + #[instrument(skip_all, name="Daemon::getblockchaininfo")] pub fn getblockchaininfo(&self) -> Result { let info: Value = self.request("getblockchaininfo", json!([]))?; Ok(from_value(info).chain_err(|| "invalid blockchain info")?) } + #[instrument(skip_all, name="Daemon::getnetworkinfo")] fn getnetworkinfo(&self) -> Result { let info: Value = self.request("getnetworkinfo", json!([]))?; Ok(from_value(info).chain_err(|| "invalid network info")?) } + #[instrument(skip_all, name="Daemon::getbestblockhash")] pub fn getbestblockhash(&self) -> Result { parse_hash(&self.request("getbestblockhash", json!([]))?) } + #[instrument(skip_all, name="Daemon::getblockheader")] pub fn getblockheader(&self, blockhash: &BlockHash) -> Result { header_from_value(self.request("getblockheader", json!([blockhash, /*verbose=*/ false]))?) } + #[instrument(skip_all, name="Daemon::getblockheaders")] pub fn getblockheaders(&self, heights: &[usize]) -> Result> { let heights: Vec = heights.iter().map(|height| json!([height])).collect(); let params_list: Vec = self @@ -479,6 +500,7 @@ impl Daemon { Ok(result) } + #[instrument(skip_all, name="Daemon::getblock")] pub fn getblock(&self, blockhash: &BlockHash) -> Result { let block = block_from_value(self.request("getblock", json!([blockhash, /*verbose=*/ false]))?)?; @@ -486,10 +508,12 @@ impl Daemon { Ok(block) } + #[instrument(skip_all, name="Daemon::getblock_raw")] pub fn getblock_raw(&self, blockhash: &BlockHash, verbose: u32) -> Result { self.request("getblock", json!([blockhash, verbose])) } + #[instrument(skip_all, name="Daemon::getblocks")] pub fn getblocks(&self, blockhashes: &[BlockHash]) -> Result> { let params_list: Vec = blockhashes .iter() @@ -503,6 +527,7 @@ impl Daemon { Ok(blocks) } + #[instrument(skip_all, name="Daemon::gettransactions")] pub fn gettransactions(&self, txhashes: &[&Txid]) -> Result> { let params_list: Vec = txhashes .iter() @@ -518,6 +543,7 @@ impl Daemon { Ok(txs) } + #[instrument(skip_all, name="Daemon::gettransaction_raw")] pub fn gettransaction_raw( &self, txid: &Txid, @@ -527,20 +553,24 @@ impl Daemon { self.request("getrawtransaction", json!([txid, verbose, blockhash])) } + #[instrument(skip_all, name="getmempooltx")] pub fn getmempooltx(&self, txhash: &Txid) -> Result { let value = self.request("getrawtransaction", json!([txhash, /*verbose=*/ false]))?; tx_from_value(value) } + #[instrument(skip_all, name="getmempooltxids")] pub fn getmempooltxids(&self) -> Result> { let res = self.request("getrawmempool", json!([/*verbose=*/ false]))?; Ok(serde_json::from_value(res).chain_err(|| "invalid getrawmempool reply")?) } + #[instrument(skip_all, name="broadcast")] pub fn broadcast(&self, tx: &Transaction) -> Result { self.broadcast_raw(&serialize_hex(tx)) } + #[instrument(skip_all, name="broadcast_raw")] pub fn broadcast_raw(&self, txhex: &str) -> Result { let txid = self.request("sendrawtransaction", json!([txhex]))?; Ok( @@ -552,6 +582,7 @@ impl Daemon { // Get estimated feerates for the provided confirmation targets using a batch RPC request // Missing estimates are logged but do not cause a failure, whatever is available is returned #[allow(clippy::float_cmp)] + #[instrument(skip_all, name="Daemon::estimatesmartfee_batch")] pub fn estimatesmartfee_batch(&self, conf_targets: &[u16]) -> Result> { let params_list: Vec = conf_targets.iter().map(|t| json!([t, "ECONOMICAL"])).collect(); @@ -583,6 +614,7 @@ impl Daemon { .collect()) } + #[instrument(skip_all, name="Daemon::get_all_headers")] fn get_all_headers(&self, tip: &BlockHash) -> Result> { let info: Value = self.request("getblockheader", json!([tip]))?; let tip_height = info @@ -610,6 +642,7 @@ impl Daemon { } // Returns a list of BlockHeaders in ascending height (i.e. the tip is last). + #[instrument(skip_all, name="Daemon::get_new_headers")] pub fn get_new_headers( &self, indexed_headers: &HeaderList, @@ -642,6 +675,7 @@ impl Daemon { Ok(new_headers) } + #[instrument(skip_all, name="Daemon::get_relayfee")] pub fn get_relayfee(&self) -> Result { let relayfee = self.getnetworkinfo()?.relayfee; diff --git a/src/electrum/server.rs b/src/electrum/server.rs index 6129cbbe8..d42cad163 100644 --- a/src/electrum/server.rs +++ b/src/electrum/server.rs @@ -13,6 +13,8 @@ use error_chain::ChainedError; use hex::{self, DisplayHex}; use serde_json::{from_str, Value}; +use tracing::instrument; + #[cfg(not(feature = "liquid"))] use bitcoin::consensus::encode::serialize_hex; #[cfg(feature = "liquid")] @@ -69,6 +71,7 @@ fn bool_from_value_or(val: Option<&Value>, name: &str, default: bool) -> Result< } // TODO: implement caching and delta updates +#[instrument(skip_all, name="electrum::server::get_status_hash")] fn get_status_hash(txs: Vec<(Txid, Option)>, query: &Query) -> Option { if txs.is_empty() { None @@ -203,6 +206,7 @@ impl Connection { Ok(json!(&self.query.mempool().backlog_stats().fee_histogram)) } + #[instrument(skip_all, name="electrum::server::blockchain_block_header")] fn blockchain_block_header(&self, params: &[Value]) -> Result { let height = usize_from_value(params.get(0), "height")?; let cp_height = usize_from_value_or(params.get(1), "cp_height", 0)?; @@ -226,6 +230,7 @@ impl Connection { })) } + #[instrument(skip_all, name="electrum::serer::blockchain_block_headers")] fn blockchain_block_headers(&self, params: &[Value]) -> Result { let start_height = usize_from_value(params.get(0), "start_height")?; let count = MAX_HEADERS.min(usize_from_value(params.get(1), "count")?); @@ -261,6 +266,7 @@ impl Connection { })) } + #[instrument(skip_all, name="electrum::server::blockchain_estimatefee")] fn blockchain_estimatefee(&self, params: &[Value]) -> Result { let conf_target = usize_from_value(params.get(0), "blocks_count")?; let fee_rate = self @@ -271,12 +277,14 @@ impl Connection { Ok(json!(fee_rate / 100_000f64)) } + #[instrument(skip_all, name="electrum::server::blockchain_relayfee")] fn blockchain_relayfee(&self) -> Result { let relayfee = self.query.get_relayfee()?; // convert from sat/b to BTC/kB, as expected by Electrum clients Ok(json!(relayfee / 100_000f64)) } + #[instrument(skip_all, name="electrum::server::blockchain_scripthash_subscribe")] fn blockchain_scripthash_subscribe(&mut self, params: &[Value]) -> Result { let script_hash = hash_from_value(params.get(0)).chain_err(|| "bad script_hash")?; @@ -291,6 +299,7 @@ impl Connection { } #[cfg(not(feature = "liquid"))] + #[instrument(skip_all, name="electrum::server::blockchain_scripthash_get_balance")] fn blockchain_scripthash_get_balance(&self, params: &[Value]) -> Result { let script_hash = hash_from_value(params.get(0)).chain_err(|| "bad script_hash")?; let (chain_stats, mempool_stats) = self.query.stats(&script_hash[..]); @@ -301,6 +310,7 @@ impl Connection { })) } + #[instrument(skip_all, name="electrum::server::blockchain_scripthash_get_history")] fn blockchain_scripthash_get_history(&self, params: &[Value]) -> Result { let script_hash = hash_from_value(params.get(0)).chain_err(|| "bad script_hash")?; let history_txids = get_history(&self.query, &script_hash[..], self.txs_limit)?; @@ -319,6 +329,7 @@ impl Connection { .collect::>())) } + #[instrument(skip_all, name="electrum::server::blockchain_scripthash_listunspent")] fn blockchain_scripthash_listunspent(&self, params: &[Value]) -> Result { let script_hash = hash_from_value(params.get(0)).chain_err(|| "bad script_hash")?; let utxos = self.query.utxo(&script_hash[..])?; @@ -347,6 +358,7 @@ impl Connection { ))) } + #[instrument(skip_all, name="electrum::server::blockchain_transaction_broadcast")] fn blockchain_transaction_broadcast(&self, params: &[Value]) -> Result { let tx = params.get(0).chain_err(|| "missing tx")?; let tx = tx.as_str().chain_err(|| "non-string tx")?.to_string(); @@ -357,6 +369,7 @@ impl Connection { Ok(json!(txid)) } + #[instrument(skip_all, name="electrum::server::blockchain_transaction_get")] fn blockchain_transaction_get(&self, params: &[Value]) -> Result { let tx_hash = Txid::from(hash_from_value(params.get(0)).chain_err(|| "bad tx_hash")?); let verbose = match params.get(1) { @@ -376,6 +389,7 @@ impl Connection { Ok(json!(rawtx.to_lower_hex_string())) } + #[instrument(skip_all, name="electrum::server::blockchain_transaction_get_merkle")] fn blockchain_transaction_get_merkle(&self, params: &[Value]) -> Result { let txid = Txid::from(hash_from_value(params.get(0)).chain_err(|| "bad tx_hash")?); let height = usize_from_value(params.get(1), "height")?; @@ -396,6 +410,7 @@ impl Connection { })) } + #[instrument(skip_all, name="electrum::server::blockchain_transaction_id_from_pos")] fn blockchain_transaction_id_from_pos(&self, params: &[Value]) -> Result { let height = usize_from_value(params.get(0), "height")?; let tx_pos = usize_from_value(params.get(1), "tx_pos")?; @@ -413,6 +428,7 @@ impl Connection { })) } + #[instrument(skip(self, params, id), name="electrum::server::handle_command")] fn handle_command(&mut self, method: &str, params: &[Value], id: &Value) -> Result { let timer = self .stats @@ -467,6 +483,7 @@ impl Connection { }) } + #[instrument(skip_all, name="electrum::server::update_subscriptions")] fn update_subscriptions(&mut self) -> Result> { let timer = self .stats @@ -524,6 +541,7 @@ impl Connection { Ok(()) } + #[instrument(skip_all, name="electrum::server::handle_replies")] fn handle_replies(&mut self, receiver: Receiver) -> Result<()> { let empty_params = json!([]); loop { @@ -588,6 +606,8 @@ impl Connection { } } + + #[instrument(skip_all, name="electrum::server::parse_requests")] fn parse_requests(mut reader: BufReader, tx: &SyncSender) -> Result<()> { loop { let mut line = Vec::::new(); @@ -650,6 +670,7 @@ impl Connection { } } +#[instrument(skip_all, name="electrum::server::get_history")] fn get_history( query: &Query, scripthash: &[u8], diff --git a/src/lib.rs b/src/lib.rs index 9dbc58153..ee0aa1698 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -35,3 +35,4 @@ pub mod util; #[cfg(feature = "liquid")] pub mod elements; +pub mod otlp_trace; diff --git a/src/new_index/db.rs b/src/new_index/db.rs index 8d895050d..e6e26fa94 100644 --- a/src/new_index/db.rs +++ b/src/new_index/db.rs @@ -1,6 +1,7 @@ use rocksdb; use std::path::Path; +use tracing::instrument; use crate::config::Config; use crate::util::{bincode, Bytes}; @@ -106,6 +107,7 @@ impl DB { db } + #[instrument(skip(self))] pub fn full_compaction(&self) { // TODO: make sure this doesn't fail silently debug!("starting full compaction on {:?}", self.db); @@ -113,6 +115,7 @@ impl DB { debug!("finished full compaction on {:?}", self.db); } + #[instrument(skip(self))] pub fn enable_auto_compaction(&self) { let opts = [("disable_auto_compactions", "false")]; self.db.set_options(&opts).unwrap(); @@ -178,6 +181,7 @@ impl DB { self.db.write_opt(batch, &opts).unwrap(); } + #[instrument(skip(self))] pub fn flush(&self) { self.db.flush().unwrap(); } @@ -186,6 +190,7 @@ impl DB { self.db.put(key, value).unwrap(); } + #[instrument(skip(self, key, value))] pub fn put_sync(&self, key: &[u8], value: &[u8]) { let mut opts = rocksdb::WriteOptions::new(); opts.set_sync(true); diff --git a/src/new_index/fetch.rs b/src/new_index/fetch.rs index 54369b5e5..9fa79e50c 100644 --- a/src/new_index/fetch.rs +++ b/src/new_index/fetch.rs @@ -13,6 +13,7 @@ use std::io::Cursor; use std::path::PathBuf; use std::sync::mpsc::Receiver; use std::thread; +use tracing::instrument; use crate::chain::{Block, BlockHash}; use crate::daemon::Daemon; @@ -25,6 +26,7 @@ pub enum FetchFrom { BlkFiles, } +#[instrument(skip(from, daemon, new_headers))] pub fn start_fetcher( from: FetchFrom, daemon: &Daemon, @@ -66,6 +68,7 @@ impl Fetcher { } } +#[instrument(skip_all, name="fetch::bitcoind_fetcher")] fn bitcoind_fetcher( daemon: &Daemon, new_headers: Vec, @@ -103,6 +106,7 @@ fn bitcoind_fetcher( )) } +#[instrument(skip_all, name="fetch::blkfiles_fetcher")] fn blkfiles_fetcher( daemon: &Daemon, new_headers: Vec, @@ -149,6 +153,7 @@ fn blkfiles_fetcher( )) } +#[instrument(skip_all, name="fetch::blkfiles_reader")] fn blkfiles_reader(blk_files: Vec) -> Fetcher> { let chan = SyncChannel::new(1); let sender = chan.sender(); @@ -168,6 +173,7 @@ fn blkfiles_reader(blk_files: Vec) -> Fetcher> { ) } +#[instrument(skip_all, name="fetch::blkfiles_parser")] fn blkfiles_parser(blobs: Fetcher>, magic: u32) -> Fetcher> { let chan = SyncChannel::new(1); let sender = chan.sender(); @@ -186,6 +192,7 @@ fn blkfiles_parser(blobs: Fetcher>, magic: u32) -> Fetcher, magic: u32) -> Result> { let mut cursor = Cursor::new(&blob); let mut slices = vec![]; diff --git a/src/new_index/mempool.rs b/src/new_index/mempool.rs index 179829fd2..01e4b7cf4 100644 --- a/src/new_index/mempool.rs +++ b/src/new_index/mempool.rs @@ -10,6 +10,7 @@ use std::collections::{BTreeSet, HashMap, HashSet}; use std::iter::FromIterator; use std::sync::{Arc, RwLock}; use std::time::{Duration, Instant}; +use tracing::instrument; use crate::chain::{deserialize, Network, OutPoint, Transaction, TxOut, Txid}; use crate::config::Config; @@ -107,6 +108,7 @@ impl Mempool { self.txstore.get(txid).map(serialize) } + #[instrument(skip_all, name="Mempool::lookup_spend")] pub fn lookup_spend(&self, outpoint: &OutPoint) -> Option { self.edges.get(outpoint).map(|(txid, vin)| SpendingInput { txid: *txid, @@ -123,6 +125,7 @@ impl Mempool { Some(self.feeinfo.get(txid)?.fee) } + #[instrument(skip_all, name="Mempool::has_unconfirmed_parents")] pub fn has_unconfirmed_parents(&self, txid: &Txid) -> bool { let tx = match self.txstore.get(txid) { Some(tx) => tx, @@ -133,6 +136,7 @@ impl Mempool { .any(|txin| self.txstore.contains_key(&txin.previous_output.txid)) } + #[instrument(skip_all, name="Mempool::history")] pub fn history(&self, scripthash: &[u8], limit: usize) -> Vec { let _timer = self.latency.with_label_values(&["history"]).start_timer(); self.history @@ -140,6 +144,7 @@ impl Mempool { .map_or_else(|| vec![], |entries| self._history(entries, limit)) } + #[instrument(skip_all, name="Mempool::_history")] fn _history(&self, entries: &[TxHistoryInfo], limit: usize) -> Vec { entries .iter() @@ -151,6 +156,7 @@ impl Mempool { .collect() } + #[instrument(skip_all, name="Mempool::history_txids")] pub fn history_txids(&self, scripthash: &[u8], limit: usize) -> Vec { let _timer = self .latency @@ -167,6 +173,7 @@ impl Mempool { } } + #[instrument(skip_all, name="Mempool::utxo")] pub fn utxo(&self, scripthash: &[u8]) -> Vec { let _timer = self.latency.with_label_values(&["utxo"]).start_timer(); let entries = match self.history.get(scripthash) { @@ -209,6 +216,7 @@ impl Mempool { .collect() } + #[instrument(skip_all, name="Mempool::stats")] // @XXX avoid code duplication with ChainQuery::stats()? pub fn stats(&self, scripthash: &[u8]) -> ScriptStats { let _timer = self.latency.with_label_values(&["stats"]).start_timer(); @@ -258,12 +266,14 @@ impl Mempool { stats } + #[instrument(skip_all, name="Mempool::txids")] // Get all txids in the mempool pub fn txids(&self) -> Vec<&Txid> { let _timer = self.latency.with_label_values(&["txids"]).start_timer(); self.txstore.keys().collect() } + #[instrument(skip_all, name="Mempool::recent_txs_overview")] // Get an overview of the most recent transactions pub fn recent_txs_overview(&self) -> Vec<&TxOverview> { // We don't bother ever deleting elements from the recent list. @@ -272,14 +282,18 @@ impl Mempool { self.recent.iter().collect() } + #[instrument(skip_all, name="Mempool::backlog_stats")] pub fn backlog_stats(&self) -> &BacklogStats { &self.backlog_stats.0 } + + #[instrument(skip_all, name="Mempool::old_txids")] pub fn old_txids(&self) -> HashSet { return HashSet::from_iter(self.txstore.keys().cloned()); } + #[instrument(skip_all, name="Mempool::update_backlog_stats")] pub fn update_backlog_stats(&mut self) { let _timer = self .latency @@ -288,6 +302,7 @@ impl Mempool { self.backlog_stats = (BacklogStats::new(&self.feeinfo), Instant::now()); } + #[instrument(skip_all, name="Mempool::add_by_txid")] pub fn add_by_txid(&mut self, daemon: &Daemon, txid: &Txid) { if self.txstore.get(txid).is_none() { if let Ok(tx) = daemon.getmempooltx(&txid) { @@ -296,6 +311,7 @@ impl Mempool { } } + #[instrument(skip_all, name="Mempool::add")] fn add(&mut self, txs: Vec) { self.delta .with_label_values(&["add"]) @@ -397,12 +413,14 @@ impl Mempool { } } + #[instrument(skip_all, name="Mempool::lookup_txo")] pub fn lookup_txo(&self, outpoint: &OutPoint) -> Result { let mut outpoints = BTreeSet::new(); outpoints.insert(*outpoint); Ok(self.lookup_txos(&outpoints)?.remove(outpoint).unwrap()) } + #[instrument(skip_all, name="Mempool::lookup_txos")] pub fn lookup_txos(&self, outpoints: &BTreeSet) -> Result> { let _timer = self .latency @@ -428,6 +446,7 @@ impl Mempool { Ok(txos) } + #[instrument(skip_all, name="Mempool::get_prevous")] fn get_prevouts(&self, txids: &[Txid]) -> BTreeSet { let _timer = self .latency @@ -446,6 +465,7 @@ impl Mempool { .collect() } + #[instrument(skip_all, name="Mempool::remove")] fn remove(&mut self, to_remove: HashSet<&Txid>) { self.delta .with_label_values(&["remove"]) @@ -481,6 +501,7 @@ impl Mempool { } #[cfg(feature = "liquid")] + #[instrument(skip_all, name="Mempool::remove")] pub fn asset_history(&self, asset_id: &AssetId, limit: usize) -> Vec { let _timer = self .latency @@ -491,6 +512,7 @@ impl Mempool { .map_or_else(|| vec![], |entries| self._history(entries, limit)) } + #[instrument(skip_all, name="Mempool::update")] pub fn update(mempool: &Arc>, daemon: &Daemon) -> Result<()> { let _timer = mempool.read().unwrap().latency.with_label_values(&["update"]).start_timer(); @@ -550,6 +572,7 @@ impl BacklogStats { } } + #[instrument(skip_all, name="Mempool::new")] fn new(feeinfo: &HashMap) -> Self { let (count, vsize, total_fee) = feeinfo .values() diff --git a/src/new_index/precache.rs b/src/new_index/precache.rs index 4db40c27d..8e309ca73 100644 --- a/src/new_index/precache.rs +++ b/src/new_index/precache.rs @@ -13,6 +13,9 @@ use std::io; use std::io::prelude::*; use std::str::FromStr; +use tracing::instrument; + +#[instrument(skip_all, name="precache::precache")] pub fn precache(chain: &ChainQuery, scripthashes: Vec) { let total = scripthashes.len(); info!("Pre-caching stats and utxo set for {} scripthashes", total); @@ -36,6 +39,7 @@ pub fn precache(chain: &ChainQuery, scripthashes: Vec) { }); } +#[instrument(skip_all, name="precache::scripthashes_from_file")] pub fn scripthashes_from_file(path: String) -> Result> { let reader = io::BufReader::new(File::open(path).chain_err(|| "cannot open precache scripthash file")?); diff --git a/src/new_index/query.rs b/src/new_index/query.rs index 1e621ac0d..1b11775f1 100644 --- a/src/new_index/query.rs +++ b/src/new_index/query.rs @@ -11,6 +11,8 @@ use crate::errors::*; use crate::new_index::{ChainQuery, Mempool, ScriptStats, SpendingInput, Utxo}; use crate::util::{is_spendable, BlockId, Bytes, TransactionStatus}; +use tracing::instrument; + #[cfg(feature = "liquid")] use crate::{ chain::AssetId, @@ -69,6 +71,7 @@ impl Query { self.mempool.read().unwrap() } + #[instrument(skip_all, name="query::Query::broadcast_raw")] pub fn broadcast_raw(&self, txhex: &str) -> Result { let txid = self.daemon.broadcast_raw(txhex)?; self.mempool @@ -78,6 +81,7 @@ impl Query { Ok(txid) } + #[instrument(skip_all, name="query::Query::utxo")] pub fn utxo(&self, scripthash: &[u8]) -> Result> { let mut utxos = self.chain.utxo(scripthash, self.config.utxos_limit)?; let mempool = self.mempool(); @@ -86,6 +90,7 @@ impl Query { Ok(utxos) } + #[instrument(skip_all, name="query::Query::history_txids")] pub fn history_txids(&self, scripthash: &[u8], limit: usize) -> Vec<(Txid, Option)> { let confirmed_txids = self.chain.history_txids(scripthash, limit); let confirmed_len = confirmed_txids.len(); @@ -107,17 +112,21 @@ impl Query { ) } + #[instrument(skip_all, name="query::Query::lookup_txn")] pub fn lookup_txn(&self, txid: &Txid) -> Option { self.chain .lookup_txn(txid, None) .or_else(|| self.mempool().lookup_txn(txid)) } + + #[instrument(skip_all, name="query::Query::lookup_raw_txn")] pub fn lookup_raw_txn(&self, txid: &Txid) -> Option { self.chain .lookup_raw_txn(txid, None) .or_else(|| self.mempool().lookup_raw_txn(txid)) } + #[instrument(skip_all, name="query::Query::lookup_txos")] pub fn lookup_txos(&self, outpoints: &BTreeSet) -> HashMap { // the mempool lookup_txos() internally looks up confirmed txos as well self.mempool() @@ -125,12 +134,14 @@ impl Query { .expect("failed loading txos") } + #[instrument(skip_all, name="query::Query::lookup_spend")] pub fn lookup_spend(&self, outpoint: &OutPoint) -> Option { self.chain .lookup_spend(outpoint) .or_else(|| self.mempool().lookup_spend(outpoint)) } + #[instrument(skip_all, name="query::Query::lookup_tx_spends")] pub fn lookup_tx_spends(&self, tx: Transaction) -> Vec> { let txid = tx.txid(); @@ -150,18 +161,22 @@ impl Query { .collect() } + #[instrument(skip_all, name="query::Query::get_tx_status")] pub fn get_tx_status(&self, txid: &Txid) -> TransactionStatus { TransactionStatus::from(self.chain.tx_confirming_block(txid)) } + #[instrument(skip_all, name="query::Query::get_mempool_tx_fee")] pub fn get_mempool_tx_fee(&self, txid: &Txid) -> Option { self.mempool().get_tx_fee(txid) } + #[instrument(skip_all, name="query::Query::has_unconfirmed_parents")] pub fn has_unconfirmed_parents(&self, txid: &Txid) -> bool { self.mempool().has_unconfirmed_parents(txid) } + #[instrument(skip_all, name="query::Query::estimate_fee")] pub fn estimate_fee(&self, conf_target: u16) -> Option { if self.config.network_type.is_regtest() { return self.get_relayfee().ok(); @@ -181,6 +196,7 @@ impl Query { .copied() } + #[instrument(skip_all, name="query::Query::estimate_fee_map")] pub fn estimate_fee_map(&self) -> HashMap { if let (ref cache, Some(cache_time)) = *self.cached_estimates.read().unwrap() { if cache_time.elapsed() < Duration::from_secs(FEE_ESTIMATES_TTL) { @@ -192,6 +208,7 @@ impl Query { self.cached_estimates.read().unwrap().0.clone() } + #[instrument(skip_all, name="query::Query::update_fee_estimates")] fn update_fee_estimates(&self) { match self.daemon.estimatesmartfee_batch(&CONF_TARGETS) { Ok(estimates) => { @@ -203,6 +220,7 @@ impl Query { } } + #[instrument(skip_all, name="query::Query::get_relayfee")] pub fn get_relayfee(&self) -> Result { if let Some(cached) = *self.cached_relayfee.read().unwrap() { return Ok(cached); @@ -233,11 +251,13 @@ impl Query { } #[cfg(feature = "liquid")] + #[instrument(skip_all, name="query::Query::lookup_asset")] pub fn lookup_asset(&self, asset_id: &AssetId) -> Result> { lookup_asset(&self, self.asset_db.as_ref(), asset_id, None) } #[cfg(feature = "liquid")] + #[instrument(skip_all, name="query::Query::list_registry_assets")] pub fn list_registry_assets( &self, start_index: usize, diff --git a/src/new_index/schema.rs b/src/new_index/schema.rs index d5eba9a51..1f9919944 100644 --- a/src/new_index/schema.rs +++ b/src/new_index/schema.rs @@ -20,6 +20,7 @@ use elements::{ use std::collections::{BTreeSet, HashMap, HashSet}; use std::path::Path; use std::sync::{Arc, RwLock}; +use tracing::instrument; use crate::chain::{ BlockHash, BlockHeader, Network, OutPoint, Script, Transaction, TxOut, Txid, Value, @@ -220,6 +221,7 @@ impl Indexer { self.duration.with_label_values(&[name]).start_timer() } + #[instrument(skip_all, name="schema::Indexer::headers_to_add")] fn headers_to_add(&self, new_headers: &[HeaderEntry]) -> Vec { let added_blockhashes = self.store.added_blockhashes.read().unwrap(); new_headers @@ -229,6 +231,7 @@ impl Indexer { .collect() } + #[instrument(skip_all, name="schema::Indexer::headers_to_index")] fn headers_to_index(&self, new_headers: &[HeaderEntry]) -> Vec { let indexed_blockhashes = self.store.indexed_blockhashes.read().unwrap(); new_headers @@ -238,6 +241,7 @@ impl Indexer { .collect() } + #[instrument(skip_all, name="schema::start_auto_compactions")] fn start_auto_compactions(&self, db: &DB) { let key = b"F".to_vec(); if db.get(&key).is_none() { @@ -248,6 +252,7 @@ impl Indexer { db.enable_auto_compaction(); } + #[instrument(skip_all, name="schema::get_new_headers")] fn get_new_headers(&self, daemon: &Daemon, tip: &BlockHash) -> Result> { let headers = self.store.indexed_headers.read().unwrap(); let new_headers = daemon.get_new_headers(&headers, &tip)?; @@ -259,6 +264,7 @@ impl Indexer { Ok(result) } + #[instrument(skip_all, name="schema::update")] pub fn update(&mut self, daemon: &Daemon) -> Result { let daemon = daemon.reconnect()?; let tip = daemon.getbestblockhash()?; @@ -306,6 +312,7 @@ impl Indexer { Ok(tip) } + #[instrument(skip_all, name="schema::add")] fn add(&self, blocks: &[BlockEntry]) { // TODO: skip orphaned blocks? let rows = { @@ -324,6 +331,7 @@ impl Indexer { .extend(blocks.iter().map(|b| b.entry.hash())); } + #[instrument(skip_all, name="schema::index")] fn index(&self, blocks: &[BlockEntry]) { let previous_txos_map = { let _timer = self.start_timer("index_lookup"); @@ -375,9 +383,8 @@ impl ChainQuery { self.duration.with_label_values(&[name]).start_timer() } + #[instrument(skip_all, name="sdchema::Indexer::get_block_txids")] pub fn get_block_txids(&self, hash: &BlockHash) -> Option> { - let _timer = self.start_timer("get_block_txids"); - if self.light_mode { // TODO fetch block as binary from REST API instead of as hex let mut blockinfo = self.daemon.getblock_raw(hash, 1).ok()?; @@ -390,6 +397,7 @@ impl ChainQuery { } } + #[instrument(skip_all, name="schema::ChainQuery::get_block_meta")] pub fn get_block_meta(&self, hash: &BlockHash) -> Option { let _timer = self.start_timer("get_block_meta"); @@ -404,6 +412,7 @@ impl ChainQuery { } } + #[instrument(skip_all, name="schema::ChainQuery::get_block_raw")] pub fn get_block_raw(&self, hash: &BlockHash) -> Option> { let _timer = self.start_timer("get_block_raw"); @@ -432,16 +441,19 @@ impl ChainQuery { } } + #[instrument(skip_all, name="schema::ChainQuery::get_block_header")] pub fn get_block_header(&self, hash: &BlockHash) -> Option { let _timer = self.start_timer("get_block_header"); Some(self.header_by_hash(hash)?.header().clone()) } + #[instrument(skip_all, name="schema::ChainQuery::get_mtp")] pub fn get_mtp(&self, height: usize) -> u32 { let _timer = self.start_timer("get_block_mtp"); self.store.indexed_headers.read().unwrap().get_mtp(height) } + #[instrument(skip_all, name="schema::ChainQuery::get_block_with_meta")] pub fn get_block_with_meta(&self, hash: &BlockHash) -> Option { let _timer = self.start_timer("get_block_with_meta"); let header_entry = self.header_by_hash(hash)?; @@ -452,12 +464,15 @@ impl ChainQuery { }) } + #[instrument(skip_all, name="schema::ChainQuery::history_iter_scan")] pub fn history_iter_scan(&self, code: u8, hash: &[u8], start_height: usize) -> ScanIterator { self.store.history_db.iter_scan_from( &TxHistoryRow::filter(code, &hash[..]), &TxHistoryRow::prefix_height(code, &hash[..], start_height as u32), ) } + + #[instrument(skip_all, name="schema::ChainQuery::history_iter_scan_reverse")] fn history_iter_scan_reverse(&self, code: u8, hash: &[u8]) -> ReverseScanIterator { self.store.history_db.iter_scan_reverse( &TxHistoryRow::filter(code, &hash[..]), @@ -465,6 +480,7 @@ impl ChainQuery { ) } + #[instrument(skip_all, name="schema::ChainQuery::history")] pub fn history( &self, scripthash: &[u8], @@ -475,6 +491,7 @@ impl ChainQuery { self._history(b'H', scripthash, last_seen_txid, limit) } + #[instrument(skip_all, name="schema::ChainQuery::_history")] fn _history( &self, code: u8, @@ -509,11 +526,13 @@ impl ChainQuery { .collect() } + #[instrument(skip_all, name="schema::ChainQuery::history_txids")] pub fn history_txids(&self, scripthash: &[u8], limit: usize) -> Vec<(Txid, BlockId)> { // scripthash lookup self._history_txids(b'H', scripthash, limit) } + #[instrument(skip_all, name="schema::ChainQuery::_history_txids")] fn _history_txids(&self, code: u8, hash: &[u8], limit: usize) -> Vec<(Txid, BlockId)> { let _timer = self.start_timer("history_txids"); self.history_iter_scan(code, hash, 0) @@ -525,6 +544,7 @@ impl ChainQuery { } // TODO: avoid duplication with stats/stats_delta? + #[instrument(skip_all, name="schema::ChainQuery::utxo")] pub fn utxo(&self, scripthash: &[u8], limit: usize) -> Result> { let _timer = self.start_timer("utxo"); @@ -585,6 +605,7 @@ impl ChainQuery { .collect()) } + #[instrument(skip_all, name="schema::ChainQuery::utxo_delta")] fn utxo_delta( &self, scripthash: &[u8], @@ -630,6 +651,7 @@ impl ChainQuery { Ok((utxos, lastblock, processed_items)) } + #[instrument(skip_all, name="schema::ChainQuery::stats")] pub fn stats(&self, scripthash: &[u8]) -> ScriptStats { let _timer = self.start_timer("stats"); @@ -664,6 +686,7 @@ impl ChainQuery { newstats } + #[instrument(skip_all, name="schema::ChainQuery::stats_delta")] fn stats_delta( &self, scripthash: &[u8], @@ -731,6 +754,7 @@ impl ChainQuery { (stats, lastblock) } + #[instrument(skip_all, name="schema::ChainQuery::address_search")] pub fn address_search(&self, prefix: &str, limit: usize) -> Vec { let _timer_scan = self.start_timer("address_search"); self.store @@ -741,6 +765,7 @@ impl ChainQuery { .collect() } + #[instrument(skip_all, name="schema::ChainQuery::header_by_hash")] fn header_by_hash(&self, hash: &BlockHash) -> Option { self.store .indexed_headers @@ -750,6 +775,7 @@ impl ChainQuery { .cloned() } + #[instrument(skip_all, name="schema::ChainQuery::height_by_hash")] // Get the height of a blockhash, only if its part of the best chain pub fn height_by_hash(&self, hash: &BlockHash) -> Option { self.store @@ -760,6 +786,7 @@ impl ChainQuery { .map(|header| header.height()) } + #[instrument(skip_all, name="schema::ChainQuery::header_by_height")] pub fn header_by_height(&self, height: usize) -> Option { self.store .indexed_headers @@ -769,6 +796,7 @@ impl ChainQuery { .cloned() } + #[instrument(skip_all, name="schema::ChainQuery::hash_by_height")] pub fn hash_by_height(&self, height: usize) -> Option { self.store .indexed_headers @@ -778,6 +806,7 @@ impl ChainQuery { .map(|entry| *entry.hash()) } + #[instrument(skip_all, name="schema::ChainQuery::blockid_by_height")] pub fn blockid_by_height(&self, height: usize) -> Option { self.store .indexed_headers @@ -787,6 +816,7 @@ impl ChainQuery { .map(BlockId::from) } + #[instrument(skip_all, name="schema::ChainQuery::blockid_by_hash")] // returns None for orphaned blocks pub fn blockid_by_hash(&self, hash: &BlockHash) -> Option { self.store @@ -797,14 +827,18 @@ impl ChainQuery { .map(BlockId::from) } + + #[instrument(skip_all, name="schema::ChainQuery::bests_height")] pub fn best_height(&self) -> usize { self.store.indexed_headers.read().unwrap().len() - 1 } + #[instrument(skip_all, name="schema::ChainQuery::best_hash")] pub fn best_hash(&self) -> BlockHash { *self.store.indexed_headers.read().unwrap().tip() } + #[instrument(skip_all, name="schema::ChainQuery::best_header")] pub fn best_header(&self) -> HeaderEntry { let headers = self.store.indexed_headers.read().unwrap(); headers @@ -815,6 +849,7 @@ impl ChainQuery { // TODO: can we pass txids as a "generic iterable"? // TODO: should also use a custom ThreadPoolBuilder? + #[instrument(skip_all, name="schema::ChainQuery::lookup_txns")] pub fn lookup_txns(&self, txids: &[(Txid, BlockId)]) -> Result> { let _timer = self.start_timer("lookup_txns"); txids @@ -826,6 +861,7 @@ impl ChainQuery { .collect::>>() } + #[instrument(skip_all, name="schema::ChainQuery::lookup_txn")] pub fn lookup_txn(&self, txid: &Txid, blockhash: Option<&BlockHash>) -> Option { let _timer = self.start_timer("lookup_txn"); self.lookup_raw_txn(txid, blockhash).map(|rawtx| { @@ -835,6 +871,7 @@ impl ChainQuery { }) } + #[instrument(skip_all, name="schema::ChainQuery::lookup_raw_txn")] pub fn lookup_raw_txn(&self, txid: &Txid, blockhash: Option<&BlockHash>) -> Option { let _timer = self.start_timer("lookup_raw_txn"); @@ -854,21 +891,25 @@ impl ChainQuery { } } + #[instrument(skip_all, name="schema::ChainQuery::lookup_txo")] pub fn lookup_txo(&self, outpoint: &OutPoint) -> Option { let _timer = self.start_timer("lookup_txo"); lookup_txo(&self.store.txstore_db, outpoint) } + #[instrument(skip_all, name="schema::ChainQuery::lookup_txos")] pub fn lookup_txos(&self, outpoints: &BTreeSet) -> HashMap { let _timer = self.start_timer("lookup_txos"); lookup_txos(&self.store.txstore_db, outpoints, false) } + #[instrument(skip_all, name="schema::ChainQuery::lookup_avail_txos")] pub fn lookup_avail_txos(&self, outpoints: &BTreeSet) -> HashMap { let _timer = self.start_timer("lookup_available_txos"); lookup_txos(&self.store.txstore_db, outpoints, true) } + #[instrument(skip_all, name="schema::ChainQuery::lookup_spend")] pub fn lookup_spend(&self, outpoint: &OutPoint) -> Option { let _timer = self.start_timer("lookup_spend"); self.store @@ -884,6 +925,8 @@ impl ChainQuery { }) }) } + + #[instrument(skip_all, name="schema::ChainQuery::tx_confirming_blocks")] pub fn tx_confirming_block(&self, txid: &Txid) -> Option { let _timer = self.start_timer("tx_confirming_block"); let headers = self.store.indexed_headers.read().unwrap(); @@ -900,6 +943,7 @@ impl ChainQuery { .map(BlockId::from) } + #[instrument(skip_all, name="schema::ChainQuery::get_block_status")] pub fn get_block_status(&self, hash: &BlockHash) -> BlockStatus { // TODO differentiate orphaned and non-existing blocks? telling them apart requires // an additional db read. @@ -921,6 +965,7 @@ impl ChainQuery { } #[cfg(not(feature = "liquid"))] + #[instrument(skip_all, name="schema::ChainQuery::get_merkleblock_proof")] pub fn get_merkleblock_proof(&self, txid: &Txid) -> Option { let _timer = self.start_timer("get_merkleblock_proof"); let blockid = self.tx_confirming_block(txid)?; @@ -935,6 +980,7 @@ impl ChainQuery { } #[cfg(feature = "liquid")] + #[instrument(skip_all, name="schema::ChainQuery::asset_history")] pub fn asset_history( &self, asset_id: &AssetId, @@ -945,11 +991,13 @@ impl ChainQuery { } #[cfg(feature = "liquid")] + #[instrument(skip_all, name="schema::ChainQuery::assets_history_txids")] pub fn asset_history_txids(&self, asset_id: &AssetId, limit: usize) -> Vec<(Txid, BlockId)> { self._history_txids(b'I', &asset_id.into_inner()[..], limit) } } +#[instrument(skip_all, name="schema::ChainQuery::load_blockhashes")] fn load_blockhashes(db: &DB, prefix: &[u8]) -> HashSet { db.iter_scan(prefix) .map(BlockRow::from_row) @@ -957,6 +1005,7 @@ fn load_blockhashes(db: &DB, prefix: &[u8]) -> HashSet { .collect() } +#[instrument(skip_all, name="schema::ChainQuery::load_blockheaders")] fn load_blockheaders(db: &DB) -> HashMap { db.iter_scan(&BlockRow::header_filter()) .map(BlockRow::from_row) @@ -968,6 +1017,7 @@ fn load_blockheaders(db: &DB) -> HashMap { .collect() } +#[instrument(skip_all, name="schema::add_blocks")] fn add_blocks(block_entries: &[BlockEntry], iconfig: &IndexerConfig) -> Vec { // persist individual transactions: // T{txid} → {rawtx} @@ -1000,6 +1050,7 @@ fn add_blocks(block_entries: &[BlockEntry], iconfig: &IndexerConfig) -> Vec BTreeSet { block_entries .iter() @@ -1033,6 +1085,7 @@ fn get_previous_txos(block_entries: &[BlockEntry]) -> BTreeSet { .collect() } +#[instrument(skip_all, name = "schema::lookup_txos")] fn lookup_txos( txstore_db: &DB, outpoints: &BTreeSet, @@ -1066,6 +1119,7 @@ fn lookup_txo(txstore_db: &DB, outpoint: &OutPoint) -> Option { .map(|val| deserialize(&val).expect("failed to parse TxOut")) } +#[instrument(skip_all, name="schema::index_blocks")] fn index_blocks( block_entries: &[BlockEntry], previous_txos_map: &HashMap, @@ -1086,7 +1140,9 @@ fn index_blocks( .collect() } + // TODO: return an iterator? +#[instrument(skip_all, name="schema::index_transaction")] fn index_transaction( tx: &Transaction, confirmed_height: u32, @@ -1161,6 +1217,7 @@ fn index_transaction( ); } +#[instrument(skip_all, name="schema::addr_search_row")] fn addr_search_row(spk: &Script, network: Network) -> Option { spk.to_address_str(network).map(|address| DBRow { key: [b"a", address.as_bytes()].concat(), @@ -1615,6 +1672,7 @@ impl UtxoCacheRow { } } +#[instrument(skip_all, name="schema::make_utxo_cache")] // keep utxo cache with just the block height (the hash/timestamp are read later from the headers to reconstruct BlockId) // and use a (txid,vout) tuple instead of OutPoints (they don't play nicely with bincode serialization) fn make_utxo_cache(utxos: &UtxoMap) -> CachedUtxoMap { @@ -1629,6 +1687,7 @@ fn make_utxo_cache(utxos: &UtxoMap) -> CachedUtxoMap { .collect() } +#[instrument(skip_all, name="schema::from_utxo_cache")] fn from_utxo_cache(utxos_cache: CachedUtxoMap, chain: &ChainQuery) -> UtxoMap { utxos_cache .into_iter() diff --git a/src/rest.rs b/src/rest.rs index 336c43f4a..e98eef054 100644 --- a/src/rest.rs +++ b/src/rest.rs @@ -24,6 +24,8 @@ use tokio::sync::oneshot; use std::fs; use std::str::FromStr; +use tracing::instrument; + #[cfg(feature = "liquid")] use { crate::elements::{ebcompact::*, peg::PegoutValue, AssetSorting, IssuanceValue}, @@ -579,6 +581,7 @@ impl Handle { } } +#[instrument(skip_all, name="rest::handle_request")] fn handle_request( method: Method, uri: hyper::Uri, @@ -1154,6 +1157,7 @@ fn json_response(value: T, ttl: u32) -> Result, Htt .unwrap()) } +#[instrument(skip_all, name="rest::blocks")] fn blocks(query: &Query, start_height: Option) -> Result, HttpError> { let mut values = Vec::new(); let mut current_hash = match start_height { diff --git a/src/util/block.rs b/src/util/block.rs index 18dc91c27..3b4e69be6 100644 --- a/src/util/block.rs +++ b/src/util/block.rs @@ -8,6 +8,7 @@ use std::iter::FromIterator; use std::slice; use time::format_description::well_known::Rfc3339; use time::OffsetDateTime as DateTime; +use tracing::instrument; const MTP_SPAN: usize = 11; @@ -84,6 +85,7 @@ impl HeaderList { } } + #[instrument(skip_all, name="block::new")] pub fn new( mut headers_map: HashMap, tip_hash: BlockHash, @@ -121,6 +123,7 @@ impl HeaderList { headers } + #[instrument(skip_all, name="block::HeaderList::order")] pub fn order(&self, new_headers: Vec) -> Vec { // header[i] -> header[i-1] (i.e. header.last() is the tip) struct HashedHeader { @@ -160,6 +163,7 @@ impl HeaderList { .collect() } + #[instrument(skip_all, name="block::HeaderList::apply")] pub fn apply(&mut self, new_headers: Vec) { // new_headers[i] -> new_headers[i - 1] (i.e. new_headers.last() is the tip) for i in 1..new_headers.len() { @@ -197,6 +201,7 @@ impl HeaderList { } } + #[instrument(skip_all, name="block::HeaderList::header_by_blockhash")] pub fn header_by_blockhash(&self, blockhash: &BlockHash) -> Option<&HeaderEntry> { let height = self.heights.get(blockhash)?; let header = self.headers.get(*height)?; @@ -207,6 +212,7 @@ impl HeaderList { } } + #[instrument(skip_all, name="block::HeaderList::header_by_height")] pub fn header_by_height(&self, height: usize) -> Option<&HeaderEntry> { self.headers.get(height).map(|entry| { assert_eq!(entry.height(), height); diff --git a/src/util/electrum_merkle.rs b/src/util/electrum_merkle.rs index 954782a7d..4b5401209 100644 --- a/src/util/electrum_merkle.rs +++ b/src/util/electrum_merkle.rs @@ -3,6 +3,9 @@ use crate::errors::*; use crate::new_index::ChainQuery; use bitcoin::hashes::{sha256d::Hash as Sha256dHash, Hash}; +use tracing::instrument; + +#[instrument(skip_all, name="electrum_merkle::get_tx_merkleproof")] pub fn get_tx_merkle_proof( chain: &ChainQuery, tx_hash: &Txid, @@ -21,6 +24,7 @@ pub fn get_tx_merkle_proof( Ok((branch, pos)) } +#[instrument(skip_all, name="electrum_merkle::get_header_merkle_proof")] pub fn get_header_merkle_proof( chain: &ChainQuery, height: usize, @@ -49,7 +53,7 @@ pub fn get_header_merkle_proof( let header_hashes = header_hashes.into_iter().map(Sha256dHash::from).collect(); Ok(create_merkle_branch_and_root(header_hashes, height)) } - +#[instrument(skip_all, name="electrum_merkle::get_id_from_pos")] pub fn get_id_from_pos( chain: &ChainQuery, height: usize, diff --git a/src/util/fees.rs b/src/util/fees.rs index 9cbe6c1d7..fa9cbee9e 100644 --- a/src/util/fees.rs +++ b/src/util/fees.rs @@ -1,5 +1,6 @@ use crate::chain::{Network, Transaction, TxOut}; use std::collections::HashMap; +use tracing::instrument; const VSIZE_BIN_WIDTH: u64 = 50_000; // in vbytes @@ -46,6 +47,7 @@ pub fn get_tx_fee(tx: &Transaction, _prevouts: &HashMap, network: N tx.fee_in(*network.native_asset()) } +#[instrument(skip_all, name="fees::make_fee_histogram")] pub fn make_fee_histogram(mut entries: Vec<&TxFeeInfo>) -> Vec<(f64, u64)> { entries.sort_unstable_by(|e1, e2| e1.fee_per_vbyte.partial_cmp(&e2.fee_per_vbyte).unwrap());