Return actual mempool fee histogram from RPC

Also, add this to the CLI tracker tool and improve logging.
This commit is contained in:
Roman Zeyde 2018-05-17 13:45:58 +03:00
parent b6d664c580
commit 30f892d76d
No known key found for this signature in database
GPG Key ID: 87CAE5FA46917CBB
4 changed files with 52 additions and 22 deletions

View File

@ -5,7 +5,7 @@ extern crate log;
use indexrs::{daemon, mempool};
use std::thread;
use std::time::{Duration, Instant};
use std::time::Duration;
fn main() {
use simplelog::*;
@ -18,14 +18,23 @@ fn main() {
let daemon = daemon::Daemon::new("localhost:8332");
let mut tracker = mempool::Tracker::new();
loop {
let t = Instant::now();
tracker.update(&daemon).unwrap();
let dt = t.elapsed();
let h = tracker.fee_histogram();
let mut total_vsize = 0;
let mut limit = 0;
for (fee, vsize) in h {
total_vsize += vsize;
let new_limit = total_vsize as usize / 1_000_000;
if limit != new_limit {
limit = new_limit;
info!(
"update took {:.3} ms",
(dt.as_secs() as f64 + 1e-9f64 * dt.subsec_nanos() as f64) * 1e3
"{:.2}MB has fee >= {:.1} sat/vbyte",
total_vsize as f32 / 1e6,
fee
);
info!("histogram: {:?}", tracker.fee_histogram());
thread::sleep(Duration::from_secs(1));
}
}
info!("{:.2}MB total size", total_vsize as f32 / 1e6);
thread::sleep(Duration::from_secs(10));
}
}

View File

@ -1,8 +1,10 @@
use bitcoin::blockdata::transaction::Transaction;
use bitcoin::util::hash::Sha256dHash;
use daemon::{Daemon, MempoolEntry};
use std::collections::{HashMap, HashSet};
use std::iter::FromIterator;
use std::time::{Duration, Instant};
error_chain!{}
@ -23,6 +25,16 @@ pub struct Tracker {
stats: HashMap<Sha256dHash, Stats>,
}
trait InSeconds {
fn in_seconds(&self) -> f64;
}
impl InSeconds for Duration {
fn in_seconds(&self) -> f64 {
self.as_secs() as f64 + (self.subsec_nanos() as f64) * 1e-9f64
}
}
impl Tracker {
pub fn new() -> Tracker {
Tracker {
@ -56,31 +68,36 @@ impl Tracker {
.getmempooltxids()
.chain_err(|| "failed to update mempool from daemon")?);
let old_txids = HashSet::from_iter(self.stats.keys().cloned());
let mut to_add = Vec::new();
let t = Instant::now();
for &txid in new_txids.difference(&old_txids) {
let tx = match daemon.gettransaction(&txid) {
Ok(tx) => tx,
Err(err) => {
warn!("missing tx {}: {}", txid, err);
continue;
}
};
let entry = match daemon.getmempoolentry(&txid) {
Ok(entry) => entry,
Err(err) => {
// e.g. new block or RBF
warn!("no mempool entry {}: {}", txid, err);
continue;
}
};
trace!("new tx: {}, {:.3}", txid, entry.fee_per_vbyte(),);
to_add.push((txid, Stats::new(tx, entry)));
let tx = match daemon.gettransaction(&txid) {
Ok(tx) => tx,
Err(err) => {
// e.g. new block or RBF
warn!("missing tx {}: {}", txid, err);
continue;
}
};
trace!("new tx: {}, {:.3}", txid, entry.fee_per_vbyte(),);
self.stats.insert(txid, Stats::new(tx, entry));
}
self.stats.extend(to_add);
for txid in old_txids.difference(&new_txids) {
self.stats.remove(txid);
}
assert_eq!(new_txids, HashSet::from_iter(self.stats.keys().cloned()));
let dt = t.elapsed();
debug!(
"mempool update took {:.1} ms ({} txns)",
dt.in_seconds() * 1e3,
self.stats.len()
);
Ok(())
}
}

View File

@ -216,4 +216,8 @@ impl<'a> Query<'a> {
.update(self.daemon)
.chain_err(|| "failed to update mempool")
}
pub fn get_fee_histogram(&self) -> Vec<(f32, u32)> {
self.tracker.read().unwrap().fee_histogram()
}
}

View File

@ -107,7 +107,7 @@ impl<'a> Handler<'a> {
}
fn mempool_get_fee_histogram(&self) -> Result<Value> {
Ok(json!([])) // TODO: consult with actual mempool
Ok(json!(self.query.get_fee_histogram()))
}
fn blockchain_block_get_chunk(&self, params: &[Value]) -> Result<Value> {