@@ -1920,7 +1920,7 @@ where
1920
1920
pub feerate_sat_per_kw : u32 ,
1921
1921
pub is_initiator : bool ,
1922
1922
pub funding_tx_locktime : AbsoluteLockTime ,
1923
- pub inputs_to_contribute : Vec < ( TxIn , Transaction ) > ,
1923
+ pub inputs_to_contribute : Vec < FundingTxInput > ,
1924
1924
pub shared_funding_input : Option < SharedOwnedInput > ,
1925
1925
pub shared_funding_output : SharedOwnedOutput ,
1926
1926
pub outputs_to_contribute : Vec < TxOut > ,
@@ -1959,21 +1959,14 @@ impl InteractiveTxConstructor {
1959
1959
shared_funding_output. clone ( ) ,
1960
1960
) ;
1961
1961
1962
- // Check for the existence of prevouts'
1963
- for ( txin, tx) in inputs_to_contribute. iter ( ) {
1964
- let vout = txin. previous_output . vout as usize ;
1965
- if tx. output . get ( vout) . is_none ( ) {
1966
- return Err ( AbortReason :: PrevTxOutInvalid ) ;
1967
- }
1968
- }
1969
1962
let mut inputs_to_contribute: Vec < ( SerialId , InputOwned ) > = inputs_to_contribute
1970
1963
. into_iter ( )
1971
- . map ( |( txin , tx ) | {
1964
+ . map ( |FundingTxInput { utxo , sequence , prevtx : prev_tx } | {
1972
1965
let serial_id = generate_holder_serial_id ( entropy_source, is_initiator) ;
1973
- let vout = txin . previous_output . vout as usize ;
1974
- let prev_output = tx . output . get ( vout ) . unwrap ( ) . clone ( ) ; // checked above
1966
+ let txin = TxIn { previous_output : utxo . outpoint , sequence , .. Default :: default ( ) } ;
1967
+ let prev_output = utxo . output ;
1975
1968
let input =
1976
- InputOwned :: Single ( SingleOwnedInput { input : txin, prev_tx : tx , prev_output } ) ;
1969
+ InputOwned :: Single ( SingleOwnedInput { input : txin, prev_tx, prev_output } ) ;
1977
1970
( serial_id, input)
1978
1971
} )
1979
1972
. collect ( ) ;
@@ -2283,12 +2276,12 @@ mod tests {
2283
2276
2284
2277
struct TestSession {
2285
2278
description : & ' static str ,
2286
- inputs_a : Vec < ( TxIn , Transaction ) > ,
2279
+ inputs_a : Vec < FundingTxInput > ,
2287
2280
a_shared_input : Option < ( OutPoint , TxOut , u64 ) > ,
2288
2281
/// The funding output, with the value contributed
2289
2282
shared_output_a : ( TxOut , u64 ) ,
2290
2283
outputs_a : Vec < TxOut > ,
2291
- inputs_b : Vec < ( TxIn , Transaction ) > ,
2284
+ inputs_b : Vec < FundingTxInput > ,
2292
2285
b_shared_input : Option < ( OutPoint , TxOut , u64 ) > ,
2293
2286
/// The funding output, with the value contributed
2294
2287
shared_output_b : ( TxOut , u64 ) ,
@@ -2558,20 +2551,22 @@ mod tests {
2558
2551
}
2559
2552
}
2560
2553
2561
- fn generate_inputs ( outputs : & [ TestOutput ] ) -> Vec < ( TxIn , Transaction ) > {
2554
+ fn generate_inputs ( outputs : & [ TestOutput ] ) -> Vec < FundingTxInput > {
2562
2555
let tx = generate_tx ( outputs) ;
2563
- let txid = tx. compute_txid ( ) ;
2564
- tx. output
2556
+ outputs
2565
2557
. iter ( )
2566
2558
. enumerate ( )
2567
- . map ( |( idx, _) | {
2568
- let txin = TxIn {
2569
- previous_output : OutPoint { txid, vout : idx as u32 } ,
2570
- script_sig : Default :: default ( ) ,
2571
- sequence : Sequence :: ENABLE_RBF_NO_LOCKTIME ,
2572
- witness : Default :: default ( ) ,
2573
- } ;
2574
- ( txin, tx. clone ( ) )
2559
+ . map ( |( idx, output) | match output {
2560
+ TestOutput :: P2WPKH ( _) => {
2561
+ FundingTxInput :: new_p2wpkh ( tx. clone ( ) , idx as u32 ) . unwrap ( )
2562
+ } ,
2563
+ TestOutput :: P2WSH ( _) => {
2564
+ FundingTxInput :: new_p2wsh ( tx. clone ( ) , idx as u32 , Weight :: from_wu ( 42 ) ) . unwrap ( )
2565
+ } ,
2566
+ TestOutput :: P2TR ( _) => {
2567
+ FundingTxInput :: new_p2tr_key_spend ( tx. clone ( ) , idx as u32 ) . unwrap ( )
2568
+ } ,
2569
+ TestOutput :: P2PKH ( _) => FundingTxInput :: new_p2pkh ( tx. clone ( ) , idx as u32 ) . unwrap ( ) ,
2575
2570
} )
2576
2571
. collect ( )
2577
2572
}
@@ -2619,37 +2614,26 @@ mod tests {
2619
2614
( generate_txout ( & TestOutput :: P2WSH ( value) ) , local_value)
2620
2615
}
2621
2616
2622
- fn generate_fixed_number_of_inputs ( count : u16 ) -> Vec < ( TxIn , Transaction ) > {
2617
+ fn generate_fixed_number_of_inputs ( count : u16 ) -> Vec < FundingTxInput > {
2623
2618
// Generate transactions with a total `count` number of outputs such that no transaction has a
2624
2619
// serialized length greater than u16::MAX.
2625
2620
let max_outputs_per_prevtx = 1_500 ;
2626
2621
let mut remaining = count;
2627
- let mut inputs: Vec < ( TxIn , Transaction ) > = Vec :: with_capacity ( count as usize ) ;
2622
+ let mut inputs: Vec < FundingTxInput > = Vec :: with_capacity ( count as usize ) ;
2628
2623
2629
2624
while remaining > 0 {
2630
2625
let tx_output_count = remaining. min ( max_outputs_per_prevtx) ;
2631
2626
remaining -= tx_output_count;
2632
2627
2628
+ let outputs = vec ! [ TestOutput :: P2WPKH ( 1_000_000 ) ; tx_output_count as usize ] ;
2629
+
2633
2630
// Use unique locktime for each tx so outpoints are different across transactions
2634
- let tx = generate_tx_with_locktime (
2635
- & vec ! [ TestOutput :: P2WPKH ( 1_000_000 ) ; tx_output_count as usize ] ,
2636
- ( 1337 + remaining) . into ( ) ,
2637
- ) ;
2638
- let txid = tx. compute_txid ( ) ;
2631
+ let tx = generate_tx_with_locktime ( & outputs, ( 1337 + remaining) . into ( ) ) ;
2639
2632
2640
- let mut temp: Vec < ( TxIn , Transaction ) > = tx
2641
- . output
2633
+ let mut temp: Vec < FundingTxInput > = outputs
2642
2634
. iter ( )
2643
2635
. enumerate ( )
2644
- . map ( |( idx, _) | {
2645
- let input = TxIn {
2646
- previous_output : OutPoint { txid, vout : idx as u32 } ,
2647
- script_sig : Default :: default ( ) ,
2648
- sequence : Sequence :: ENABLE_RBF_NO_LOCKTIME ,
2649
- witness : Default :: default ( ) ,
2650
- } ;
2651
- ( input, tx. clone ( ) )
2652
- } )
2636
+ . map ( |( idx, _) | FundingTxInput :: new_p2wpkh ( tx. clone ( ) , idx as u32 ) . unwrap ( ) )
2653
2637
. collect ( ) ;
2654
2638
2655
2639
inputs. append ( & mut temp) ;
@@ -2860,13 +2844,11 @@ mod tests {
2860
2844
} ) ;
2861
2845
2862
2846
let tx = generate_tx ( & [ TestOutput :: P2WPKH ( 1_000_000 ) ] ) ;
2863
- let invalid_sequence_input = TxIn {
2864
- previous_output : OutPoint { txid : tx. compute_txid ( ) , vout : 0 } ,
2865
- ..Default :: default ( )
2866
- } ;
2847
+ let mut invalid_sequence_input = FundingTxInput :: new_p2wpkh ( tx. clone ( ) , 0 ) . unwrap ( ) ;
2848
+ invalid_sequence_input. set_sequence ( Default :: default ( ) ) ;
2867
2849
do_test_interactive_tx_constructor ( TestSession {
2868
2850
description : "Invalid input sequence from initiator" ,
2869
- inputs_a : vec ! [ ( invalid_sequence_input, tx . clone ( ) ) ] ,
2851
+ inputs_a : vec ! [ invalid_sequence_input] ,
2870
2852
a_shared_input : None ,
2871
2853
shared_output_a : generate_funding_txout ( 1_000_000 , 1_000_000 ) ,
2872
2854
outputs_a : vec ! [ ] ,
@@ -2876,14 +2858,10 @@ mod tests {
2876
2858
outputs_b : vec ! [ ] ,
2877
2859
expect_error : Some ( ( AbortReason :: IncorrectInputSequenceValue , ErrorCulprit :: NodeA ) ) ,
2878
2860
} ) ;
2879
- let duplicate_input = TxIn {
2880
- previous_output : OutPoint { txid : tx. compute_txid ( ) , vout : 0 } ,
2881
- sequence : Sequence :: ENABLE_RBF_NO_LOCKTIME ,
2882
- ..Default :: default ( )
2883
- } ;
2861
+ let duplicate_input = FundingTxInput :: new_p2wpkh ( tx. clone ( ) , 0 ) . unwrap ( ) ;
2884
2862
do_test_interactive_tx_constructor ( TestSession {
2885
2863
description : "Duplicate prevout from initiator" ,
2886
- inputs_a : vec ! [ ( duplicate_input. clone( ) , tx . clone ( ) ) , ( duplicate_input, tx . clone ( ) ) ] ,
2864
+ inputs_a : vec ! [ duplicate_input. clone( ) , duplicate_input] ,
2887
2865
a_shared_input : None ,
2888
2866
shared_output_a : generate_funding_txout ( 1_000_000 , 1_000_000 ) ,
2889
2867
outputs_a : vec ! [ ] ,
@@ -2894,35 +2872,27 @@ mod tests {
2894
2872
expect_error : Some ( ( AbortReason :: PrevTxOutInvalid , ErrorCulprit :: NodeB ) ) ,
2895
2873
} ) ;
2896
2874
// Non-initiator uses same prevout as initiator.
2897
- let duplicate_input = TxIn {
2898
- previous_output : OutPoint { txid : tx. compute_txid ( ) , vout : 0 } ,
2899
- sequence : Sequence :: ENABLE_RBF_NO_LOCKTIME ,
2900
- ..Default :: default ( )
2901
- } ;
2875
+ let duplicate_input = FundingTxInput :: new_p2wpkh ( tx. clone ( ) , 0 ) . unwrap ( ) ;
2902
2876
do_test_interactive_tx_constructor ( TestSession {
2903
2877
description : "Non-initiator uses same prevout as initiator" ,
2904
- inputs_a : vec ! [ ( duplicate_input. clone( ) , tx . clone ( ) ) ] ,
2878
+ inputs_a : vec ! [ duplicate_input. clone( ) ] ,
2905
2879
a_shared_input : None ,
2906
2880
shared_output_a : generate_funding_txout ( 1_000_000 , 905_000 ) ,
2907
2881
outputs_a : vec ! [ ] ,
2908
- inputs_b : vec ! [ ( duplicate_input. clone ( ) , tx . clone ( ) ) ] ,
2882
+ inputs_b : vec ! [ duplicate_input] ,
2909
2883
b_shared_input : None ,
2910
2884
shared_output_b : generate_funding_txout ( 1_000_000 , 95_000 ) ,
2911
2885
outputs_b : vec ! [ ] ,
2912
2886
expect_error : Some ( ( AbortReason :: PrevTxOutInvalid , ErrorCulprit :: NodeA ) ) ,
2913
2887
} ) ;
2914
- let duplicate_input = TxIn {
2915
- previous_output : OutPoint { txid : tx. compute_txid ( ) , vout : 0 } ,
2916
- sequence : Sequence :: ENABLE_RBF_NO_LOCKTIME ,
2917
- ..Default :: default ( )
2918
- } ;
2888
+ let duplicate_input = FundingTxInput :: new_p2wpkh ( tx. clone ( ) , 0 ) . unwrap ( ) ;
2919
2889
do_test_interactive_tx_constructor ( TestSession {
2920
2890
description : "Non-initiator uses same prevout as initiator" ,
2921
- inputs_a : vec ! [ ( duplicate_input. clone( ) , tx . clone ( ) ) ] ,
2891
+ inputs_a : vec ! [ duplicate_input. clone( ) ] ,
2922
2892
a_shared_input : None ,
2923
2893
shared_output_a : generate_funding_txout ( 1_000_000 , 1_000_000 ) ,
2924
2894
outputs_a : vec ! [ ] ,
2925
- inputs_b : vec ! [ ( duplicate_input. clone ( ) , tx . clone ( ) ) ] ,
2895
+ inputs_b : vec ! [ duplicate_input] ,
2926
2896
b_shared_input : None ,
2927
2897
shared_output_b : generate_funding_txout ( 1_000_000 , 0 ) ,
2928
2898
outputs_b : vec ! [ ] ,
0 commit comments