Skip to content

Commit

Permalink
Calculate cooperative tx sizes (#89)
Browse files Browse the repository at this point in the history
* Calculate cooperative tx sizes

* Use a stub preimage

* Fix witness stub
  • Loading branch information
dangeross authored Feb 7, 2025
1 parent 1989f43 commit 12c9e54
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 23 deletions.
12 changes: 6 additions & 6 deletions src/swaps/bitcoin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1200,21 +1200,21 @@ impl BtcSwapTx {
let mut witness = Witness::new();
// Stub because we don't want to create cooperative signatures here
// but still be able to have an accurate size estimation
witness.push([0, 64]);
witness.push([0; 64]);
witness
}

/// Calculate the size of a transaction.
/// Use this before calling drain to help calculate the absolute fees.
/// Multiply the size by the fee_rate to get the absolute fees.
pub fn size(&self, keys: &Keypair, preimage: &Preimage) -> Result<usize, Error> {
let dummy_abs_fee = 0;
// Can only calculate non-coperative claims
pub fn size(&self, keys: &Keypair, is_cooperative: bool) -> Result<usize, Error> {
let dummy_abs_fee = 1;
let tx = match self.kind {
SwapTxKind::Claim => {
self.sign_claim(keys, preimage, Fee::Absolute(dummy_abs_fee), None)?
let preimage = Preimage::from_vec([0; 32].to_vec())?;
self.create_claim(keys, &preimage, dummy_abs_fee, is_cooperative)?
}
SwapTxKind::Refund => self.sign_refund(keys, Fee::Absolute(dummy_abs_fee), None)?,
SwapTxKind::Refund => self.create_refund(keys, dummy_abs_fee, is_cooperative)?,
};
Ok(tx.vsize())
}
Expand Down
19 changes: 7 additions & 12 deletions src/swaps/liquid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1251,7 +1251,7 @@ impl LBtcSwapTx {
let mut witness = Witness::new();
// Stub because we don't want to create cooperative signatures here
// but still be able to have an accurate size estimation
witness.push([0, 64]);
witness.push([0; 64]);

TxInWitness {
amount_rangeproof: None,
Expand All @@ -1267,21 +1267,16 @@ impl LBtcSwapTx {
pub fn size(
&self,
keys: &Keypair,
preimage: &Preimage,
is_cooperative: bool,
is_discount_ct: bool,
) -> Result<usize, Error> {
let dummy_abs_fee = 0;
let dummy_abs_fee = 1;
let tx = match self.kind {
SwapTxKind::Claim => self.sign_claim(
keys,
preimage,
Fee::Absolute(dummy_abs_fee),
None,
is_discount_ct,
)?,
SwapTxKind::Refund => {
self.sign_refund(keys, Fee::Absolute(dummy_abs_fee), None, is_discount_ct)?
SwapTxKind::Claim => {
let preimage = Preimage::from_vec([0; 32].to_vec())?;
self.create_claim(keys, &preimage, dummy_abs_fee, is_cooperative)?
}
SwapTxKind::Refund => self.create_refund(keys, dummy_abs_fee, is_cooperative)?,
};
Ok(tx_size(&tx, is_discount_ct))
}
Expand Down
64 changes: 59 additions & 5 deletions tests/regtest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use bitcoin::key::rand::thread_rng;
use bitcoin::key::{Keypair, PublicKey};
use bitcoin::secp256k1::Secp256k1;
use bitcoin::{Amount, OutPoint, TxOut};
use bitcoind::bitcoincore_rpc::json::ScanTxOutRequest;
use bitcoind::bitcoincore_rpc::json::{AddressType, ScanTxOutRequest};
use bitcoind::bitcoincore_rpc::RpcApi;
use boltz_client::boltz::{SwapTxKind, SwapType};
use boltz_client::fees::Fee;
Expand Down Expand Up @@ -86,7 +86,7 @@ fn prepare_btc_claim() -> (

let test_wallet = test_framework.get_test_wallet();
let refund_addrs = test_wallet
.get_new_address(None, None)
.get_new_address(None, Some(AddressType::P2shSegwit))
.unwrap()
.assume_checked();

Expand All @@ -107,6 +107,18 @@ fn prepare_btc_claim() -> (
)
}

#[test]
fn btc_reverse_claim_size() {
let (_test_framework, _scan_request, swap_tx, _preimage, recvr_keypair, _utxos) =
prepare_btc_claim();

let coop_claim_tx_size = swap_tx.size(&recvr_keypair, true).unwrap();
assert_eq!(coop_claim_tx_size, 100);

let non_coop_claim_tx_size = swap_tx.size(&recvr_keypair, false).unwrap();
assert_eq!(non_coop_claim_tx_size, 141);
}

#[test]
fn btc_reverse_claim() {
let (test_framework, scan_request, swap_tx, preimage, recvr_keypair, utxos) =
Expand Down Expand Up @@ -158,7 +170,7 @@ fn btc_reverse_claim_relative_fee() {
.fold(0, |acc, (_, out)| acc + out.value.to_sat())
- claim_tx.output[0].value.to_sat();
assert_eq!(relative_fee, claim_tx_fee as f64 / claim_tx.vsize() as f64);
assert_eq!(claim_tx_fee, 140);
assert_eq!(claim_tx_fee, 141);

test_framework
.as_ref()
Expand Down Expand Up @@ -245,7 +257,7 @@ fn prepare_btc_refund() -> (

let test_wallet = test_framework.get_test_wallet();
let refund_addrs = test_wallet
.get_new_address(None, None)
.get_new_address(None, Some(AddressType::P2shSegwit))
.unwrap()
.assume_checked();

Expand All @@ -259,6 +271,17 @@ fn prepare_btc_refund() -> (
(test_framework, scan_request, swap_tx, sender_keypair, utxos)
}

#[test]
fn btc_submarine_refund_size() {
let (_test_framework, _scan_request, swap_tx, sender_keypair, _utxos) = prepare_btc_refund();

let coop_refund_tx_size = swap_tx.size(&sender_keypair, true).unwrap();
assert_eq!(coop_refund_tx_size, 100);

let non_coop_refund_tx_size = swap_tx.size(&sender_keypair, false).unwrap();
assert_eq!(non_coop_refund_tx_size, 127);
}

#[test]
fn btc_submarine_refund() {
let (test_framework, scan_request, swap_tx, sender_keypair, utxos) = prepare_btc_refund();
Expand Down Expand Up @@ -317,7 +340,7 @@ fn btc_submarine_refund_relative_fee() {
relative_fee,
refund_tx_fee as f64 / refund_tx.vsize() as f64
);
assert_eq!(refund_tx_fee, 126);
assert_eq!(refund_tx_fee, 127);

// Make the timelock matured and broadcast the spend
test_framework.generate_blocks(100);
Expand Down Expand Up @@ -414,6 +437,25 @@ fn prepare_lbtc_claim() -> (
)
}

#[test]
fn lbtc_reverse_claim_size() {
let (
_test_framework,
swap_tx,
_preimage,
recvr_keypair,
_blinding_keypair,
_swap_addrs,
_utxos,
) = prepare_lbtc_claim();

let coop_claim_tx_size = swap_tx.size(&recvr_keypair, true, true).unwrap();
assert_eq!(coop_claim_tx_size, 181);

let non_coop_claim_tx_size = swap_tx.size(&recvr_keypair, false, true).unwrap();
assert_eq!(non_coop_claim_tx_size, 221);
}

#[test]
fn lbtc_reverse_claim() {
let (test_framework, swap_tx, preimage, recvr_keypair, blinding_keypair, swap_addrs, utxo) =
Expand Down Expand Up @@ -544,6 +586,18 @@ fn prepare_lbtc_refund() -> (
)
}

#[test]
fn lbtc_submarine_refund_size() {
let (_test_framework, swap_tx, sender_keypair, _blinding_keypair, _swap_addrs, _utxos) =
prepare_lbtc_refund();

let coop_refund_tx_size = swap_tx.size(&sender_keypair, true, true).unwrap();
assert_eq!(coop_refund_tx_size, 181);

let non_coop_refund_tx_size = swap_tx.size(&sender_keypair, false, true).unwrap();
assert_eq!(non_coop_refund_tx_size, 207);
}

#[test]
fn lbtc_submarine_refund() {
let (test_framework, swap_tx, sender_keypair, blinding_keypair, swap_addrs, utxo) =
Expand Down

0 comments on commit 12c9e54

Please sign in to comment.