Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Add getblockstats RPC call #2

Open
wants to merge 19 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions client/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,22 @@ pub trait RpcApi: Sized {
self.call("getblockheader", &[into_json(hash)?, true.into()]).await
}

/// Compute per block statistics for a given window. All amounts are in satoshis.
/// https://developer.bitcoin.org/reference/rpc/getblockstats.html
async fn get_block_stats(
&self,
block_hash: Option<&bitcoin::BlockHash>,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

might make more sense to do param hash_or_height: HashOrHeight and define a custom enum to get rid of the panic branch.

block_height: Option<usize>,
) -> Result<json::GetBlockStatsResult> {
if let Some(hash) = block_hash {
self.call("getblockstats", &[into_json(hash)?]).await
} else if let Some(height) = block_height {
self.call("getblockstats", &[into_json(height)?]).await
} else {
panic!("TODO: Which error to use?")
}
}

async fn get_mining_info(&self) -> Result<json::GetMiningInfoResult> {
self.call("getmininginfo", &[]).await
}
Expand Down
102 changes: 100 additions & 2 deletions json/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,8 @@
//! This is a client library for the Bitcoin Core JSON-RPC API.
//!


use std::collections::HashMap;
pub use bitcoin;
use std::collections::HashMap;

use bitcoin::consensus::encode;
use bitcoin::hashes::hex::{FromHex, ToHex};
Expand Down Expand Up @@ -212,6 +211,105 @@ pub struct GetBlockHeaderResult {
pub next_block_hash: Option<bitcoin::BlockHash>,
}

/// `getblockstats` RPC call.
/// https://developer.bitcoin.org/reference/rpc/getblockstats.html
#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct GetBlockStatsResult {
/// Average fee in the block
#[serde(rename = "avgfee")]
#[serde(with = "bitcoin::util::amount::serde::as_btc")]
pub avg_fee: Amount,
/// Average feerate (in satoshis per virtual byte)
#[serde(rename = "avgfeerate")]
#[serde(with = "bitcoin::util::amount::serde::as_btc")]
pub avg_fee_rate: Amount,
/// Average transaction size
#[serde(rename = "avgtxsize")]
pub avg_tx_size: u32,
/// The block hash (to check for potential reorgs)
#[serde(rename = "blockhash")]
pub block_hash: bitcoin::BlockHash,
/// Feerates at the 10th, 25th, 50th, 75th, and 90th percentile weight unit (in satoshis per
/// virtual byte)
#[serde(rename = "feerate_percentiles")]
pub fee_rate_percentiles: [u8; 5],
/// The height of the block
pub height: u64,
/// The number of inputs (excluding coinbase)
pub ins: usize,
/// Maximum fee in the block
#[serde(rename = "maxfee")]
#[serde(with = "bitcoin::util::amount::serde::as_btc")]
pub max_fee: Amount,
/// Maximum feerate (in satoshis per virtual byte)
#[serde(rename = "maxfeerate")]
#[serde(with = "bitcoin::util::amount::serde::as_btc")]
pub max_fee_rate: Amount,
/// Maximum transaction size
#[serde(rename = "maxtxsize")]
pub max_tx_size: u32,
/// Truncated median fee in the block
#[serde(rename = "medianfee")]
#[serde(with = "bitcoin::util::amount::serde::as_btc")]
pub median_fee: Amount,
/// The block median time past
#[serde(rename = "mediantime")]
pub median_time: u64,
/// Truncated median transaction size
#[serde(rename = "mediantxsize")]
pub median_tx_size: u32,
/// Minimum fee in the block
#[serde(rename = "minfee")]
#[serde(with = "bitcoin::util::amount::serde::as_btc")]
pub min_fee: Amount,
/// Minimum feerate (in satoshis per virtual byte)
#[serde(rename = "minfeerate")]
#[serde(with = "bitcoin::util::amount::serde::as_btc")]
pub min_fee_rate: Amount,
/// Minimum transaction size
#[serde(rename = "mintxsize")]
pub min_tx_size: u32,
/// The number of outputs
pub outs: usize,
/// The block subsidy
#[serde(with = "bitcoin::util::amount::serde::as_btc")]
pub subsidy: Amount,
/// Total size of all segwit transactions
#[serde(rename = "swtotal_size")]
pub sw_total_size: usize,
/// Total weight of all segwit transactions
#[serde(rename = "swtotal_weight")]
pub sw_total_weight: usize,
/// The number of segwit transactions
#[serde(rename = "swtxs")]
pub sw_txs: usize,
/// The block time
pub time: u64,
/// Total amount in all outputs (excluding coinbase and thus reward [ie subsidy + totalfee])
#[serde(rename = "total_out")]
// #[serde(with = "bitcoin::util::amount::serde::as_btc")]
pub total_out: usize,
/// Total size of all non-coinbase transactions
#[serde(rename = "total_size")]
pub total_size: usize,
/// Total weight of all non-coinbase transactions
#[serde(rename = "total_weight")]
pub total_weight: usize,
/// The fee total
#[serde(rename = "totalfee")]
#[serde(with = "bitcoin::util::amount::serde::as_btc")]
pub total_fee: Amount,
/// The number of transactions (including coinbase)
pub txs: usize,
/// The increase/decrease in the number of unspent outputs
#[serde(rename = "utxo_increase")]
pub utxo_increase: i32,
/// The increase/decrease in size for the
#[serde(rename = "utxo_size_inc")]
pub utxo_size_inc: i32,
}

#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct GetMiningInfoResult {
Expand Down