Skip to content

Commit

Permalink
rbf: add utils function for tx size
Browse files Browse the repository at this point in the history
  • Loading branch information
jp1ac4 committed Nov 24, 2023
1 parent bb90d82 commit 908c03b
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 21 deletions.
29 changes: 9 additions & 20 deletions src/commands/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ pub use crate::database::{CoinStatus, LabelItem};
use bdk_coin_select::InsufficientFunds;
use utils::{
deser_addr_assume_checked, deser_amount_from_sats, deser_fromstr, deser_hex,
select_coins_for_spend, ser_amount, ser_hex, ser_to_string,
select_coins_for_spend, ser_amount, ser_hex, ser_to_string, unsigned_tx_max_vbytes,
};

use std::{
Expand Down Expand Up @@ -1111,6 +1111,12 @@ impl DaemonControl {
if !is_cancel {
candidate_coins.extend(&confirmed_cands);
}
let max_sat_weight: u64 = self
.config
.main_descriptor
.max_sat_weight()
.try_into()
.expect("it must fit");
// Try with increasing feerate until fee paid by replacement transaction is high enough.
// Replacement fee must be at least:
// sum of fees paid by original transactions + incremental feerate * replacement size.
Expand Down Expand Up @@ -1145,25 +1151,8 @@ impl DaemonControl {
return Err(e);
}
};
rbf_vsize = {
// TODO: Make this a function (can be used also in `sanity_check`).
let witness_factor: u64 =
descriptors::WITNESS_FACTOR.try_into().expect("it must fit");
let max_sat_weight: u64 = self
.config
.main_descriptor
.max_sat_weight()
.try_into()
.expect("it must fit");
let num_inputs: u64 = rbf_psbt.psbt.inputs.len().try_into().expect("it must fit");
let rbf_weight =
rbf_psbt.psbt.unsigned_tx.weight().to_wu() + (max_sat_weight * num_inputs);
rbf_weight
.checked_add(witness_factor - 1)
.unwrap()
.checked_div(witness_factor)
.unwrap()
};
rbf_vsize = unsigned_tx_max_vbytes(&rbf_psbt.psbt.unsigned_tx, max_sat_weight);

println!("replacement vsize estimated at {}", rbf_vsize);
if rbf_psbt
.psbt
Expand Down
25 changes: 24 additions & 1 deletion src/commands/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use bdk_coin_select::{
use log::warn;
use std::{convert::TryInto, str::FromStr};

use miniscript::bitcoin::{self, consensus, hashes::hex::FromHex};
use miniscript::bitcoin::{self, consensus, constants::WITNESS_SCALE_FACTOR, hashes::hex::FromHex};
use serde::{de, Deserialize, Deserializer, Serializer};

use crate::database::Coin;
Expand Down Expand Up @@ -244,3 +244,26 @@ pub fn select_coins_for_spend(
change_amount,
))
}

/// An unsigned transaction's maximum possible size in vbytes after satisfaction.
///
/// This assumes all inputs are internal (or have the same `max_sat_weight` value).
///
/// `tx` is the unsigned transaction.
///
/// `max_sat_weight` is the maximum weight difference of an input in the
/// transaction before and after satisfaction. Must be in weight units.
pub fn unsigned_tx_max_vbytes(tx: &bitcoin::Transaction, max_sat_weight: u64) -> u64 {
let witness_factor: u64 = WITNESS_SCALE_FACTOR.try_into().unwrap();
let num_inputs: u64 = tx.input.len().try_into().unwrap();
let tx_wu: u64 = tx
.weight()
.to_wu()
.checked_add(max_sat_weight.checked_mul(num_inputs).unwrap())
.unwrap();
tx_wu
.checked_add(witness_factor.checked_sub(1).unwrap())
.unwrap()
.checked_div(witness_factor)
.unwrap()
}

0 comments on commit 908c03b

Please sign in to comment.