Skip to content

Commit c807b14

Browse files
author
Gabriel Comte
committed
Add per-field querying for getblockstats
1 parent 1740440 commit c807b14

File tree

3 files changed

+141
-0
lines changed

3 files changed

+141
-0
lines changed

client/src/client.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -466,6 +466,14 @@ pub trait RpcApi: Sized {
466466
self.call("getblockstats", &[height.into()])
467467
}
468468

469+
fn get_block_stats_fields(&self, height: u64, fields: &[json::BlockStatsFields]) -> Result<json::GetBlockStatsResultPartial> {
470+
let fields: Vec<&str> = fields.iter()
471+
.map(|field| field.get_rpc_keyword())
472+
.collect();
473+
474+
self.call("getblockstats", &[height.into(), fields.into()])
475+
}
476+
469477
fn get_raw_transaction(
470478
&self,
471479
txid: &bitcoin::Txid,

integration_test/src/main.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ fn main() {
148148
test_get_block(&cl);
149149
test_get_block_header_get_block_header_info(&cl);
150150
test_get_block_stats(&cl);
151+
test_get_block_stats_fields(&cl);
151152
test_get_address_info(&cl);
152153
test_set_label(&cl);
153154
test_send_to_address(&cl);
@@ -327,6 +328,19 @@ fn test_get_block_stats(cl: &Client) {
327328
assert_eq!(tip, stats.height);
328329
}
329330

331+
fn test_get_block_stats_fields(cl: &Client) {
332+
use json::BlockStatsFields;
333+
let tip = cl.get_block_count().unwrap();
334+
let tip_hash = cl.get_best_block_hash().unwrap();
335+
let header = cl.get_block_header(&tip_hash).unwrap();
336+
let fields = [BlockStatsFields::BlockHash, BlockStatsFields::Height, BlockStatsFields::TotalFee];
337+
let stats = cl.get_block_stats_fields(tip, &fields).unwrap();
338+
assert_eq!(header.block_hash(), stats.block_hash.unwrap());
339+
assert_eq!(tip, stats.height.unwrap());
340+
assert!(stats.total_fee.is_some());
341+
assert!(stats.avg_fee.is_none());
342+
}
343+
330344
fn test_get_address_info(cl: &Client) {
331345
let addr = cl.get_new_address(None, Some(json::AddressType::Legacy)).unwrap();
332346
let info = cl.get_address_info(&addr).unwrap();

json/src/lib.rs

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,57 @@ pub struct GetBlockStatsResult {
276276
pub utxo_size_inc: i32,
277277
}
278278

279+
#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
280+
pub struct GetBlockStatsResultPartial {
281+
#[serde(rename = "avgfee")]
282+
pub avg_fee: Option<u32>,
283+
#[serde(rename = "avgfeerate")]
284+
pub avg_fee_rate: Option<u32>,
285+
#[serde(rename = "avgtxsize")]
286+
pub avg_tx_size: Option<u32>,
287+
#[serde(rename = "blockhash")]
288+
pub block_hash: Option<bitcoin::BlockHash>,
289+
#[serde(rename = "feerate_percentiles")]
290+
pub fee_rate_percentiles: Option<FeeRatePercentiles>,
291+
pub height: Option<u64>,
292+
pub ins: Option<usize>,
293+
#[serde(rename = "maxfee")]
294+
pub max_fee: Option<u64>,
295+
#[serde(rename = "maxfeerate")]
296+
pub max_fee_rate: Option<u32>,
297+
#[serde(rename = "maxtxsize")]
298+
pub max_tx_size: Option<u32>,
299+
#[serde(rename = "medianfee")]
300+
pub median_fee: Option<u32>,
301+
#[serde(rename = "mediantime")]
302+
pub median_time: Option<u32>,
303+
#[serde(rename = "mediantxsize")]
304+
pub median_tx_size: Option<u32>,
305+
#[serde(rename = "minfee")]
306+
pub min_fee: Option<u32>,
307+
#[serde(rename = "minfeerate")]
308+
pub min_fee_rate: Option<u32>,
309+
#[serde(rename = "mintxsize")]
310+
pub min_tx_size: Option<u32>,
311+
pub outs: Option<usize>,
312+
pub subsidy: Option<u32>,
313+
#[serde(rename = "swtotal_size")]
314+
pub sw_total_size: Option<usize>,
315+
#[serde(rename = "swtotal_weight")]
316+
pub sw_total_weight: Option<usize>,
317+
#[serde(rename = "swtxs")]
318+
pub sw_txs: Option<usize>,
319+
pub time: Option<u32>,
320+
pub total_out: Option<usize>,
321+
pub total_size: Option<usize>,
322+
pub total_weight: Option<usize>,
323+
#[serde(rename = "totalfee")]
324+
pub total_fee: Option<u64>,
325+
pub txs: Option<usize>,
326+
pub utxo_increase: Option<i32>,
327+
pub utxo_size_inc: Option<i32>,
328+
}
329+
279330
#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
280331
pub struct FeeRatePercentiles {
281332
pub fr_10th: u32,
@@ -285,6 +336,74 @@ pub struct FeeRatePercentiles {
285336
pub fr_90th: u32,
286337
}
287338

339+
pub enum BlockStatsFields {
340+
AverageFee,
341+
AverageFeeRate,
342+
AverageTxSize,
343+
BlockHash,
344+
FeeRatePercentiles,
345+
Height,
346+
Ins,
347+
MaxFee,
348+
MaxFeeRate,
349+
MaxTxSize,
350+
MedianFee,
351+
MedianTime,
352+
MedianTxSize,
353+
MinFee,
354+
MinFeeRate,
355+
MinTxSize,
356+
Outs,
357+
Subsidy,
358+
SegWitTotalSize,
359+
SegWitTotalWeight,
360+
SegWitTxs,
361+
Time,
362+
TotalOut,
363+
TotalSize,
364+
TotalWeight,
365+
TotalFee,
366+
Txs,
367+
UtxoIncrease,
368+
UtxoSizeIncrease,
369+
}
370+
371+
impl BlockStatsFields {
372+
pub fn get_rpc_keyword(&self) -> &str {
373+
match *self {
374+
BlockStatsFields::AverageFee => "avgfee",
375+
BlockStatsFields::AverageFeeRate => "avgfeerate",
376+
BlockStatsFields::AverageTxSize => "avgtxsize",
377+
BlockStatsFields::BlockHash => "blockhash",
378+
BlockStatsFields::FeeRatePercentiles => "feerate_percentiles",
379+
BlockStatsFields::Height => "height",
380+
BlockStatsFields::Ins => "ins",
381+
BlockStatsFields::MaxFee => "maxfee",
382+
BlockStatsFields::MaxFeeRate => "maxfeerate",
383+
BlockStatsFields::MaxTxSize => "maxtxsize",
384+
BlockStatsFields::MedianFee => "medianfee",
385+
BlockStatsFields::MedianTime => "mediantime",
386+
BlockStatsFields::MedianTxSize => "mediantxsize",
387+
BlockStatsFields::MinFee => "minfee",
388+
BlockStatsFields::MinFeeRate => "minfeerate",
389+
BlockStatsFields::MinTxSize => "minfeerate",
390+
BlockStatsFields::Outs => "outs",
391+
BlockStatsFields::Subsidy => "subsidy",
392+
BlockStatsFields::SegWitTotalSize => "swtotal_size",
393+
BlockStatsFields::SegWitTotalWeight => "swtotal_weight",
394+
BlockStatsFields::SegWitTxs => "swtxs",
395+
BlockStatsFields::Time => "time",
396+
BlockStatsFields::TotalOut => "total_out",
397+
BlockStatsFields::TotalSize => "total_size",
398+
BlockStatsFields::TotalWeight => "total_weight",
399+
BlockStatsFields::TotalFee => "totalfee",
400+
BlockStatsFields::Txs => "txs",
401+
BlockStatsFields::UtxoIncrease => "utxo_increase",
402+
BlockStatsFields::UtxoSizeIncrease => "utxo_size_inc",
403+
}
404+
}
405+
}
406+
288407
#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
289408
#[serde(rename_all = "camelCase")]
290409
pub struct GetMiningInfoResult {

0 commit comments

Comments
 (0)