Skip to content
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
12 changes: 12 additions & 0 deletions client/src/client_sync/v17/hidden.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,18 @@
//!
//! See or use the `define_jsonrpc_bitreq_client!` macro to define a `Client`.

/// Implements Bitcoin Core JSON-RPC API method `estimaterawfee`.
#[macro_export]
macro_rules! impl_client_v17__estimate_raw_fee {
() => {
impl Client {
pub fn estimate_raw_fee(&self, conf_target: u32) -> Result<EstimateRawFee> {
self.call("estimaterawfee", &[conf_target.into()])
}
}
};
}

/// Implements Bitcoin Core JSON-RPC API method `waitforblock`.
#[macro_export]
macro_rules! impl_client_v17__wait_for_block {
Expand Down
1 change: 1 addition & 0 deletions client/src/client_sync/v17/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ crate::impl_client_v17__generate!();
crate::impl_client_v17__invalidate_block!();

// == Hidden ==
crate::impl_client_v17__estimate_raw_fee!();
crate::impl_client_v17__wait_for_block!();
crate::impl_client_v17__wait_for_block_height!();
crate::impl_client_v17__wait_for_new_block!();
Expand Down
1 change: 1 addition & 0 deletions client/src/client_sync/v18/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ crate::impl_client_v17__generate!();
crate::impl_client_v17__invalidate_block!();

// == Hidden ==
crate::impl_client_v17__estimate_raw_fee!();
crate::impl_client_v17__wait_for_block!();
crate::impl_client_v17__wait_for_block_height!();
crate::impl_client_v17__wait_for_new_block!();
Expand Down
1 change: 1 addition & 0 deletions client/src/client_sync/v19/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ crate::impl_client_v17__generate_to_address!();
crate::impl_client_v17__invalidate_block!();

// == Hidden ==
crate::impl_client_v17__estimate_raw_fee!();
crate::impl_client_v17__wait_for_block!();
crate::impl_client_v17__wait_for_block_height!();
crate::impl_client_v17__wait_for_new_block!();
Expand Down
1 change: 1 addition & 0 deletions client/src/client_sync/v20/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ crate::impl_client_v20__generate_to_descriptor!();
crate::impl_client_v17__invalidate_block!();

// == Hidden ==
crate::impl_client_v17__estimate_raw_fee!();
crate::impl_client_v17__wait_for_block!();
crate::impl_client_v17__wait_for_block_height!();
crate::impl_client_v17__wait_for_new_block!();
Expand Down
1 change: 1 addition & 0 deletions client/src/client_sync/v21/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ crate::impl_client_v17__invalidate_block!();

// == Hidden ==
crate::impl_client_v21__add_peer_address!();
crate::impl_client_v17__estimate_raw_fee!();
crate::impl_client_v17__wait_for_block!();
crate::impl_client_v17__wait_for_block_height!();
crate::impl_client_v17__wait_for_new_block!();
Expand Down
1 change: 1 addition & 0 deletions client/src/client_sync/v22/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ crate::impl_client_v17__invalidate_block!();

// == Hidden ==
crate::impl_client_v21__add_peer_address!();
crate::impl_client_v17__estimate_raw_fee!();
crate::impl_client_v17__wait_for_block!();
crate::impl_client_v17__wait_for_block_height!();
crate::impl_client_v17__wait_for_new_block!();
Expand Down
1 change: 1 addition & 0 deletions client/src/client_sync/v23/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ crate::impl_client_v17__invalidate_block!();

// == Hidden ==
crate::impl_client_v21__add_peer_address!();
crate::impl_client_v17__estimate_raw_fee!();
crate::impl_client_v17__wait_for_block!();
crate::impl_client_v17__wait_for_block_height!();
crate::impl_client_v17__wait_for_new_block!();
Expand Down
1 change: 1 addition & 0 deletions client/src/client_sync/v24/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ crate::impl_client_v17__invalidate_block!();

// == Hidden ==
crate::impl_client_v21__add_peer_address!();
crate::impl_client_v17__estimate_raw_fee!();
crate::impl_client_v17__wait_for_block!();
crate::impl_client_v17__wait_for_block_height!();
crate::impl_client_v17__wait_for_new_block!();
Expand Down
1 change: 1 addition & 0 deletions client/src/client_sync/v25/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ crate::impl_client_v17__invalidate_block!();

// == Hidden ==
crate::impl_client_v21__add_peer_address!();
crate::impl_client_v17__estimate_raw_fee!();
crate::impl_client_v17__wait_for_block!();
crate::impl_client_v17__wait_for_block_height!();
crate::impl_client_v17__wait_for_new_block!();
Expand Down
1 change: 1 addition & 0 deletions client/src/client_sync/v26/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ crate::impl_client_v17__invalidate_block!();

// == Hidden ==
crate::impl_client_v21__add_peer_address!();
crate::impl_client_v17__estimate_raw_fee!();
crate::impl_client_v17__wait_for_block!();
crate::impl_client_v17__wait_for_block_height!();
crate::impl_client_v17__wait_for_new_block!();
Expand Down
1 change: 1 addition & 0 deletions client/src/client_sync/v27/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ crate::impl_client_v17__invalidate_block!();

// == Hidden ==
crate::impl_client_v21__add_peer_address!();
crate::impl_client_v17__estimate_raw_fee!();
crate::impl_client_v17__wait_for_block!();
crate::impl_client_v17__wait_for_block_height!();
crate::impl_client_v17__wait_for_new_block!();
Expand Down
1 change: 1 addition & 0 deletions client/src/client_sync/v28/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ crate::impl_client_v17__invalidate_block!();

// == Hidden ==
crate::impl_client_v21__add_peer_address!();
crate::impl_client_v17__estimate_raw_fee!();
crate::impl_client_v17__wait_for_block!();
crate::impl_client_v17__wait_for_block_height!();
crate::impl_client_v17__wait_for_new_block!();
Expand Down
1 change: 1 addition & 0 deletions client/src/client_sync/v29/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ crate::impl_client_v17__invalidate_block!();

// == Hidden ==
crate::impl_client_v21__add_peer_address!();
crate::impl_client_v17__estimate_raw_fee!();
crate::impl_client_v17__wait_for_block!();
crate::impl_client_v17__wait_for_block_height!();
crate::impl_client_v17__wait_for_new_block!();
Expand Down
1 change: 1 addition & 0 deletions client/src/client_sync/v30/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ crate::impl_client_v23__save_mempool!();
crate::impl_client_v25__scan_blocks!();
crate::impl_client_v17__verify_chain!();
crate::impl_client_v17__verify_tx_out_proof!();
crate::impl_client_v17__estimate_raw_fee!();
crate::impl_client_v17__wait_for_block!();
crate::impl_client_v17__wait_for_block_height!();
crate::impl_client_v17__wait_for_new_block!();
Expand Down
30 changes: 30 additions & 0 deletions integration_test/tests/hidden.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// SPDX-License-Identifier: CC0-1.0

//! Tests for methods that are `== Hidden ==` and not in the API docs of Bitcoin Core.

#![allow(non_snake_case)] // Test names intentionally use double underscore.

use integration_test::{Node, NodeExt as _, Wallet};
use node::mtype;
use node::vtype::*; // All the version specific types.

#[test]
fn hidden__estimate_raw_fee__modelled() {
let node = Node::with_wallet(Wallet::Default, &[]);
node.fund_wallet();

// Give the fee estimator some confirmation history.
for _ in 0..10 {
node.create_mined_transaction();
}

let json: EstimateRawFee = node.client.estimate_raw_fee(2).expect("estimaterawfee");
let json_range: &RawFeeRange = json.long.fail.as_ref().unwrap();

assert!(json_range.total_confirmed > 0.0);

let model: Result<mtype::EstimateRawFee, EstimateRawFeeError> = json.into_model();
let estimate = model.unwrap();

assert!(estimate.long.scale > 0);
}
54 changes: 54 additions & 0 deletions types/src/model/hidden.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// SPDX-License-Identifier: CC0-1.0

//! Types for methods that are `== Hidden ==` and not in the API docs of Bitcoin Core.
//!
//! These structs model the types returned by the JSON-RPC API but have concrete types
//! and are not specific to a specific version of Bitcoin Core.

use bitcoin::FeeRate;
use serde::{Deserialize, Serialize};

/// Models the result of JSON-RPC method `estimaterawfee`.
#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
pub struct EstimateRawFee {
/// Estimate for short time horizon.
pub short: Option<RawFeeDetail>,
/// Estimate for medium time horizon.
pub medium: Option<RawFeeDetail>,
/// Estimate for long time horizon.
pub long: RawFeeDetail,
}

/// Estimate for a time horizon. Part of `estimaterawfee`.
#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
pub struct RawFeeDetail {
/// Estimate fee rate in BTC/kB.
pub fee_rate: Option<FeeRate>,
/// Exponential decay (per block) for historical moving average of confirmation data.
pub decay: f64,
/// The resolution of confirmation targets at this time horizon.
pub scale: u32,
/// Information about the lowest range of feerates to succeed in meeting the threshold.
pub pass: Option<RawFeeRange>,
/// Information about the highest range of feerates to fail to meet the threshold.
pub fail: Option<RawFeeRange>,
/// Errors encountered during processing.
pub errors: Option<Vec<String>>,
}

/// Information about a feerate range. Part of `estimaterawfee`.
#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
pub struct RawFeeRange {
/// Start of feerate range.
pub start_range: Option<FeeRate>,
/// End of feerate range.
pub end_range: Option<FeeRate>,
/// Number of txs over history horizon in the feerate range that were confirmed within target.
pub within_target: f64,
/// Number of txs over history horizon in the feerate range that were confirmed at any point.
pub total_confirmed: f64,
/// Current number of txs in mempool in the feerate range unconfirmed for at least target blocks.
pub in_mempool: f64,
/// Number of txs over history horizon in the feerate range that left mempool unconfirmed after target.
pub left_mempool: f64,
}
2 changes: 2 additions & 0 deletions types/src/model/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
mod blockchain;
mod control;
mod generating;
mod hidden;
mod mining;
mod network;
mod raw_transactions;
Expand Down Expand Up @@ -38,6 +39,7 @@ pub use self::{
WaitForBlockHeight, WaitForNewBlock,
},
generating::{Generate, GenerateBlock, GenerateToAddress, GenerateToDescriptor},
hidden::{EstimateRawFee, RawFeeDetail, RawFeeRange},
mining::{
BlockTemplateTransaction, GetBlockTemplate, GetMiningInfo, GetPrioritisedTransactions,
NextBlockInfo, PrioritisedTransaction,
Expand Down
25 changes: 25 additions & 0 deletions types/src/v17/hidden/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,36 @@

use core::fmt;

use bitcoin::amount::ParseAmountError;
use bitcoin::hex;

use crate::error::write_err;
use crate::NumericError;

/// Error when converting an `EstimateRawFee` type into the model type.
#[derive(Debug)]
pub enum EstimateRawFeeError {
/// Conversion of the `feerate` field failed.
FeeRate(ParseAmountError),
}

impl fmt::Display for EstimateRawFeeError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Self::FeeRate(ref e) => write_err!(f, "conversion of the `feerate` field failed"; e),
}
}
}

#[cfg(feature = "std")]
impl std::error::Error for EstimateRawFeeError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match *self {
Self::FeeRate(ref e) => Some(e),
}
}
}

/// Error when converting a `WaitForBlock` type into the model type.
#[derive(Debug)]
pub enum WaitForBlockError {
Expand Down
52 changes: 51 additions & 1 deletion types/src/v17/hidden/into.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,61 @@
use bitcoin::BlockHash;

use super::{
WaitForBlock, WaitForBlockError, WaitForBlockHeight, WaitForBlockHeightError, WaitForNewBlock,
EstimateRawFee, EstimateRawFeeError, RawFeeDetail, RawFeeRange, WaitForBlock,
WaitForBlockError, WaitForBlockHeight, WaitForBlockHeightError, WaitForNewBlock,
WaitForNewBlockError,
};
use crate::model;

impl EstimateRawFee {
/// Converts version specific type to a version nonspecific, more strongly typed type.
pub fn into_model(self) -> Result<model::EstimateRawFee, EstimateRawFeeError> {
let short = self.short.map(|d| d.into_model()).transpose()?;
let medium = self.medium.map(|d| d.into_model()).transpose()?;
let long = self.long.into_model()?;

Ok(model::EstimateRawFee { short, medium, long })
}
}

impl RawFeeDetail {
/// Converts version specific type to a version nonspecific, more strongly typed type.
pub fn into_model(self) -> Result<model::RawFeeDetail, EstimateRawFeeError> {
use EstimateRawFeeError as E;

let fee_rate =
self.fee_rate.map(crate::btc_per_kb).transpose().map_err(E::FeeRate)?.flatten();
let pass = self.pass.map(|p| p.into_model()).transpose()?;
let fail = self.fail.map(|p| p.into_model()).transpose()?;

Ok(model::RawFeeDetail {
fee_rate,
decay: self.decay,
scale: self.scale,
pass,
fail,
errors: self.errors,
})
}
}

impl RawFeeRange {
/// Converts version specific type to a version nonspecific, more strongly typed type.
pub fn into_model(self) -> Result<model::RawFeeRange, EstimateRawFeeError> {
let start_range = crate::btc_per_kb(self.start_range).ok().flatten();
let end_range = crate::btc_per_kb(self.end_range).ok().flatten();

Ok(model::RawFeeRange {
start_range,
end_range,
within_target: self.within_target,
total_confirmed: self.total_confirmed,
in_mempool: self.in_mempool,
left_mempool: self.left_mempool,
})
}
}

impl WaitForBlock {
/// Converts version specific type to a version nonspecific, more strongly typed type.
pub fn into_model(self) -> Result<model::WaitForBlock, WaitForBlockError> {
Expand Down
Loading