@@ -4,8 +4,8 @@ mod integration {
4
4
use std:: env;
5
5
use std:: str:: FromStr ;
6
6
7
- use bitcoin:: psbt:: Psbt ;
8
7
use bitcoin:: policy:: DEFAULT_MIN_RELAY_TX_FEE ;
8
+ use bitcoin:: psbt:: Psbt ;
9
9
use bitcoin:: { Amount , FeeRate , OutPoint , Weight } ;
10
10
use bitcoind:: bitcoincore_rpc:: json:: { AddressType , WalletProcessPsbtResult } ;
11
11
use bitcoind:: bitcoincore_rpc:: { self , RpcApi } ;
@@ -22,14 +22,6 @@ mod integration {
22
22
static EXAMPLE_URL : Lazy < Url > =
23
23
Lazy :: new ( || Url :: parse ( "https://example.com" ) . expect ( "Invalid Url" ) ) ;
24
24
25
- // See https://jlopp.github.io/bitcoin-transaction-size-calculator/
26
- // Base weight of an empty transaction (no inputs, no outputs)
27
- static BASE_WEIGHT : Weight = Weight :: from_vb_unchecked ( 11 ) ;
28
- // Per-input weight for P2WPKH inputs
29
- static INPUT_WEIGHT : Weight = Weight :: from_vb_unchecked ( 68 ) ;
30
- // Per-output weight for P2WPKH inputs
31
- static OUTPUT_WEIGHT : Weight = Weight :: from_vb_unchecked ( 31 ) ;
32
-
33
25
#[ cfg( not( feature = "v2" ) ) ]
34
26
mod v1 {
35
27
use log:: debug;
@@ -77,12 +69,9 @@ mod integration {
77
69
sender. send_raw_transaction ( & payjoin_tx) ?;
78
70
79
71
// Check resulting transaction and balances
80
- let input_count = payjoin_tx. input . len ( ) as u64 ;
81
- let output_count = payjoin_tx. output . len ( ) as u64 ;
82
- let tx_weight = BASE_WEIGHT + input_count * INPUT_WEIGHT + output_count * OUTPUT_WEIGHT ;
83
- let network_fees = tx_weight * FeeRate :: BROADCAST_MIN ;
84
- assert_eq ! ( input_count, 2 ) ;
85
- assert_eq ! ( output_count, 2 ) ;
72
+ let network_fees = predicted_tx_weight ( & payjoin_tx) * FeeRate :: BROADCAST_MIN ;
73
+ assert_eq ! ( payjoin_tx. input. len( ) , 2 ) ;
74
+ assert_eq ! ( payjoin_tx. output. len( ) , 2 ) ;
86
75
assert_eq ! ( receiver. get_balances( ) ?. mine. untrusted_pending, Amount :: from_btc( 51.0 ) ?) ;
87
76
assert_eq ! (
88
77
sender. get_balances( ) ?. mine. untrusted_pending,
@@ -335,17 +324,13 @@ mod integration {
335
324
log:: info!( "sent" ) ;
336
325
337
326
// Check resulting transaction and balances
338
- let input_count = payjoin_tx. input . len ( ) as u64 ;
339
- let output_count = payjoin_tx. output . len ( ) as u64 ;
340
- let tx_weight =
341
- BASE_WEIGHT + input_count * INPUT_WEIGHT + output_count * OUTPUT_WEIGHT ;
342
327
// NOTE: No one is contributing fees for the receiver input because the sender has
343
- // no change output and the receiver doesn't contribute fees
344
- let network_fees =
345
- ( tx_weight - 1 * INPUT_WEIGHT ) * FeeRate :: from_sat_per_vb_unchecked ( 2 ) ;
328
+ // no change output and the receiver doesn't contribute fees. Temporary workaround
329
+ // is to ensure the sender overpays in the original psbt for the receiver's input.
330
+ let network_fees = psbt . fee ( ) ? ;
346
331
// Sender sent the entire value of their utxo to receiver (minus fees)
347
- assert_eq ! ( input_count , 2 ) ;
348
- assert_eq ! ( output_count , 1 ) ;
332
+ assert_eq ! ( payjoin_tx . input . len ( ) , 2 ) ;
333
+ assert_eq ! ( payjoin_tx . output . len ( ) , 1 ) ;
349
334
assert_eq ! (
350
335
receiver. get_balances( ) ?. mine. untrusted_pending,
351
336
Amount :: from_btc( 100.0 ) ? - network_fees
@@ -394,12 +379,9 @@ mod integration {
394
379
sender. send_raw_transaction ( & payjoin_tx) ?;
395
380
396
381
// Check resulting transaction and balances
397
- let input_count = payjoin_tx. input . len ( ) as u64 ;
398
- let output_count = payjoin_tx. output . len ( ) as u64 ;
399
- let tx_weight = BASE_WEIGHT + input_count * INPUT_WEIGHT + output_count * OUTPUT_WEIGHT ;
400
- let network_fees = tx_weight * FeeRate :: BROADCAST_MIN ;
401
- assert_eq ! ( input_count, 2 ) ;
402
- assert_eq ! ( output_count, 2 ) ;
382
+ let network_fees = predicted_tx_weight ( & payjoin_tx) * FeeRate :: BROADCAST_MIN ;
383
+ assert_eq ! ( payjoin_tx. input. len( ) , 2 ) ;
384
+ assert_eq ! ( payjoin_tx. output. len( ) , 2 ) ;
403
385
assert_eq ! ( receiver. get_balances( ) ?. mine. untrusted_pending, Amount :: from_btc( 51.0 ) ?) ;
404
386
assert_eq ! (
405
387
sender. get_balances( ) ?. mine. untrusted_pending,
@@ -532,13 +514,9 @@ mod integration {
532
514
) ;
533
515
534
516
// Check resulting transaction and balances
535
- let input_count = payjoin_tx. input . len ( ) as u64 ;
536
- let output_count = payjoin_tx. output . len ( ) as u64 ;
537
- let tx_weight =
538
- BASE_WEIGHT + input_count * INPUT_WEIGHT + output_count * OUTPUT_WEIGHT ;
539
- let network_fees = tx_weight * FeeRate :: BROADCAST_MIN ;
540
- assert_eq ! ( input_count, 2 ) ;
541
- assert_eq ! ( output_count, 2 ) ;
517
+ let network_fees = predicted_tx_weight ( & payjoin_tx) * FeeRate :: BROADCAST_MIN ;
518
+ assert_eq ! ( payjoin_tx. input. len( ) , 2 ) ;
519
+ assert_eq ! ( payjoin_tx. output. len( ) , 2 ) ;
542
520
assert_eq ! (
543
521
receiver. get_balances( ) ?. mine. untrusted_pending,
544
522
Amount :: from_btc( 51.0 ) ?
@@ -954,6 +932,13 @@ mod integration {
954
932
Ok ( payjoin_psbt. extract_tx ( ) ?)
955
933
}
956
934
935
+ fn predicted_tx_weight ( tx : & bitcoin:: Transaction ) -> Weight {
936
+ bitcoin:: transaction:: predict_weight (
937
+ vec ! [ bitcoin:: transaction:: InputWeightPrediction :: P2WPKH_MAX ; tx. input. len( ) ] ,
938
+ tx. script_pubkey_lens ( ) ,
939
+ )
940
+ }
941
+
957
942
struct HeaderMock ( HashMap < String , String > ) ;
958
943
959
944
impl payjoin:: receive:: Headers for HeaderMock {
0 commit comments