Skip to content

relay_fee result should be strongly typed #164

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

Open
wants to merge 1 commit into
base: master
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
6 changes: 3 additions & 3 deletions src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use std::borrow::Borrow;
use std::convert::TryInto;

use bitcoin::consensus::encode::{deserialize, serialize};
use bitcoin::{block, Script, Transaction, Txid};
use bitcoin::{block, Amount, Script, Transaction, Txid};

use crate::batch::Batch;
use crate::types::*;
Expand Down Expand Up @@ -97,8 +97,8 @@ pub trait ElectrumApi {
/// Estimates the fee required in **Bitcoin per kilobyte** to confirm a transaction in `number` blocks.
fn estimate_fee(&self, number: usize) -> Result<f64, Error>;

/// Returns the minimum accepted fee by the server's node in **Bitcoin, not Satoshi**.
fn relay_fee(&self) -> Result<f64, Error>;
/// Returns the minimum accepted fee by the server's node.
fn relay_fee(&self) -> Result<Amount, Error>;
Comment on lines +100 to +101
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
/// Returns the minimum accepted fee by the server's node.
fn relay_fee(&self) -> Result<Amount, Error>;
/// Returns the minimum accepted fee by the server's node per kvB.
fn relay_fee(&self) -> Result<Amount, Error>;


/// Subscribes to notifications for activity on a specific *scriptPubKey*.
///
Expand Down
4 changes: 2 additions & 2 deletions src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use std::{borrow::Borrow, sync::RwLock};

use log::{info, warn};

use bitcoin::{Script, Txid};
use bitcoin::{Amount, Script, Txid};

use crate::api::ElectrumApi;
use crate::batch::Batch;
Expand Down Expand Up @@ -212,7 +212,7 @@ impl ElectrumApi for Client {
}

#[inline]
fn relay_fee(&self) -> Result<f64, Error> {
fn relay_fee(&self) -> Result<Amount, Error> {
impl_inner_call!(self, relay_fee)
}

Expand Down
11 changes: 6 additions & 5 deletions src/raw_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use log::{debug, error, info, trace, warn};

use bitcoin::consensus::encode::deserialize;
use bitcoin::hex::{DisplayHex, FromHex};
use bitcoin::{Script, Txid};
use bitcoin::{Amount, Script, Txid};

#[cfg(feature = "use-openssl")]
use openssl::ssl::{SslConnector, SslMethod, SslStream, SslVerifyMode};
Expand Down Expand Up @@ -879,17 +879,18 @@ impl<T: Read + Write> ElectrumApi for RawClient<T> {
.ok_or_else(|| Error::InvalidResponse(result.clone()))
}

fn relay_fee(&self) -> Result<f64, Error> {
fn relay_fee(&self) -> Result<Amount, Error> {
Copy link
Contributor

Choose a reason for hiding this comment

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

I know the docs aren't clear in this regard but I think it would make sense for this to return a FeeRate which I believe was the approach in #136 also.

Copy link
Author

@rustaceanrob rustaceanrob Feb 9, 2025

Choose a reason for hiding this comment

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

I don't know the electrum protocol, my interpretation of the docs was this is an absolute fee that a transaction must have, so an Amount is the fee required to broadcast with that node.

If this is actually a fee rate in bitcoin per vbyte then the docs should be updated accordingly before any attempt at a PR to return FeeRate

Copy link
Collaborator

Choose a reason for hiding this comment

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

I also interpret the docs as this one being an absolute fee, but some validation on electrum code besides documentation is needed.

Copy link
Contributor

Choose a reason for hiding this comment

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

To be clear I'm referring to "relay fee" as described in getnetworkinfo RPC if indeed that's what this method refers to. https://bitcoincore.org/en/doc/28.0.0/rpc/network/getnetworkinfo/

I agree that the value can be parsed as an amount in BTC (same for estimate_fee), but that still leaves #136 unresolved where the user has to interpret the value as a useful feerate.

this is an absolute fee that a transaction must have, so an Amount is the fee required to broadcast with that node

If you consider test_relay_fee below, that would be saying that the blockstream server refuses to relay anything that pays less than 1000 sats in fees which I don't think is the case.

Copy link
Collaborator

Choose a reason for hiding this comment

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

At least it seems both romanz/electrs and blockstream/electrs rely on the RPC you mentioned, basically propagating the Amount/f64, maybe a FeeRate really does fit it better.

let req = Request::new_id(
self.last_id.fetch_add(1, Ordering::SeqCst),
"blockchain.relayfee",
vec![],
);
let result = self.call(req)?;

result
let amount_float = result
.as_f64()
.ok_or_else(|| Error::InvalidResponse(result.clone()))
.ok_or_else(|| Error::InvalidResponse(result.clone()))?;
Amount::from_btc(amount_float).map_err(|_| Error::InvalidResponse(result.clone()))
}

fn script_subscribe(&self, script: &Script) -> Result<Option<ScriptStatus>, Error> {
Expand Down Expand Up @@ -1195,7 +1196,7 @@ mod test {
let client = RawClient::new(get_test_server(), None).unwrap();

let resp = client.relay_fee().unwrap();
assert_eq!(resp, 0.00001);
assert_eq!(resp, bitcoin::Amount::from_btc(0.00001).unwrap());
}

#[test]
Expand Down
Loading