Skip to content

Commit e77628a

Browse files
committed
Add support for maxfeerate and maxburnamount to sendrawtransaction
1 parent 06a6c15 commit e77628a

File tree

2 files changed

+43
-9
lines changed

2 files changed

+43
-9
lines changed

client/src/client.rs

Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ use crate::bitcoin::address::{NetworkUnchecked, NetworkChecked};
2626
use crate::bitcoin::hashes::hex::FromHex;
2727
use crate::bitcoin::secp256k1::ecdsa::Signature;
2828
use crate::bitcoin::{
29-
Address, Amount, Block, OutPoint, PrivateKey, PublicKey, Script, Transaction,
29+
Address, Amount, Block, OutPoint, PrivateKey, PublicKey, Script, Transaction, FeeRate,
3030
};
3131
use log::Level::{Debug, Trace, Warn};
3232

@@ -1076,8 +1076,42 @@ pub trait RpcApi: Sized {
10761076
self.call("ping", &[])
10771077
}
10781078

1079-
fn send_raw_transaction<R: RawTx>(&self, tx: R) -> Result<bitcoin::Txid> {
1080-
self.call("sendrawtransaction", &[tx.raw_hex().into()])
1079+
// Submit a raw transaction to local node and network.
1080+
//
1081+
// # Arguments
1082+
//
1083+
// 1. `tx`: Transaction to submit
1084+
// 2. `maxfeerate`: Reject transaction whose fee rate is higher than the
1085+
// specified value Available in Bitcoin Core 0.19.0 and later.
1086+
// 3. `maxburnamount`: Reject transactions with provably unspendable
1087+
// outputs (e.g. 'datacarrier' outputs that use the OP_RETURN opcode)
1088+
// greater than the specified value, expressed in BTC. If burning funds
1089+
// through unspendable outputs is desired, increase this value. This
1090+
// check is based on heuristics and does not guarantee spendability of
1091+
// outputs. Available in Bitcoin Core 25.0.0 and later.
1092+
fn send_raw_transaction<R: RawTx>(
1093+
&self,
1094+
tx: R,
1095+
maxfeerate: Option<FeeRate>,
1096+
maxburnamount: Option<Amount>,
1097+
) -> Result<bitcoin::Txid> {
1098+
fn fee_rate_to_btc_per_kvb(fee_rate: FeeRate) -> f64 {
1099+
let sat_per_kwu = fee_rate.to_sat_per_kwu() as f64;
1100+
let sat_per_kvb = sat_per_kwu * 4.0;
1101+
let btc_per_kvb = sat_per_kvb / Amount::ONE_BTC.to_sat() as f64;
1102+
btc_per_kvb
1103+
}
1104+
1105+
let mut args = [
1106+
into_json(tx.raw_hex())?,
1107+
opt_into_json(maxfeerate.map(fee_rate_to_btc_per_kvb))?,
1108+
opt_into_json(maxburnamount.map(|amount| amount.to_btc()))?,
1109+
];
1110+
1111+
self.call(
1112+
"sendrawtransaction",
1113+
handle_defaults(&mut args, &[null(), null(), null()]),
1114+
)
10811115
}
10821116

10831117
fn estimate_smart_fee(
@@ -1360,10 +1394,10 @@ mod tests {
13601394
let client = Client::new("http://localhost/".into(), Auth::None).unwrap();
13611395
let tx: bitcoin::Transaction = encode::deserialize(&Vec::<u8>::from_hex("0200000001586bd02815cf5faabfec986a4e50d25dbee089bd2758621e61c5fab06c334af0000000006b483045022100e85425f6d7c589972ee061413bcf08dc8c8e589ce37b217535a42af924f0e4d602205c9ba9cb14ef15513c9d946fa1c4b797883e748e8c32171bdf6166583946e35c012103dae30a4d7870cd87b45dd53e6012f71318fdd059c1c2623b8cc73f8af287bb2dfeffffff021dc4260c010000001976a914f602e88b2b5901d8aab15ebe4a97cf92ec6e03b388ac00e1f505000000001976a914687ffeffe8cf4e4c038da46a9b1d37db385a472d88acfd211500").unwrap()).unwrap();
13621396

1363-
assert!(client.send_raw_transaction(&tx).is_err());
1364-
assert!(client.send_raw_transaction(&encode::serialize(&tx)).is_err());
1365-
assert!(client.send_raw_transaction("deadbeef").is_err());
1366-
assert!(client.send_raw_transaction("deadbeef".to_owned()).is_err());
1397+
assert!(client.send_raw_transaction(&tx, None, None).is_err());
1398+
assert!(client.send_raw_transaction(&encode::serialize(&tx), None, None).is_err());
1399+
assert!(client.send_raw_transaction("deadbeef", None, None).is_err());
1400+
assert!(client.send_raw_transaction("deadbeef".to_owned(), None, None).is_err());
13671401
}
13681402

13691403
fn test_handle_defaults_inner() -> Result<()> {

integration_test/src/main.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -613,7 +613,7 @@ fn test_sign_raw_transaction_with_send_raw_transaction(cl: &Client) {
613613
};
614614
let res = cl.sign_raw_transaction_with_wallet(&tx, Some(&[input]), None).unwrap();
615615
assert!(res.complete);
616-
let txid = cl.send_raw_transaction(&res.transaction().unwrap()).unwrap();
616+
let txid = cl.send_raw_transaction(&res.transaction().unwrap(), None, None).unwrap();
617617

618618
let tx = Transaction {
619619
version: transaction::Version::ONE,
@@ -637,7 +637,7 @@ fn test_sign_raw_transaction_with_send_raw_transaction(cl: &Client) {
637637
.sign_raw_transaction_with_key(&tx, &[sk], None, Some(sighash::EcdsaSighashType::All.into()))
638638
.unwrap();
639639
assert!(res.complete);
640-
let _ = cl.send_raw_transaction(&res.transaction().unwrap()).unwrap();
640+
let _ = cl.send_raw_transaction(&res.transaction().unwrap(), None, None).unwrap();
641641
}
642642

643643
fn test_invalidate_block_reconsider_block(cl: &Client) {

0 commit comments

Comments
 (0)