@@ -235,6 +235,131 @@ fn test_create_tx_custom_version() {
235235 assert_eq ! ( psbt. unsigned_tx. version. 0 , 42 ) ;
236236}
237237
238+ #[ test]
239+ fn test_create_tx_non_v3_excludes_unconfirmed_v3_utxos ( ) {
240+ let ( descriptor, change_descriptor) = get_test_wpkh_and_change_desc ( ) ;
241+ let mut wallet = Wallet :: create ( descriptor, change_descriptor)
242+ . network ( Network :: Regtest )
243+ . create_wallet_no_persist ( )
244+ . expect ( "wallet" ) ;
245+
246+ insert_checkpoint (
247+ & mut wallet,
248+ BlockId {
249+ height : 1 ,
250+ hash : BlockHash :: all_zeros ( ) ,
251+ } ,
252+ ) ;
253+
254+ let confirmed_tx = Transaction {
255+ version : transaction:: Version :: ONE ,
256+ lock_time : absolute:: LockTime :: ZERO ,
257+ input : vec ! [ ] ,
258+ output : vec ! [ TxOut {
259+ script_pubkey: wallet
260+ . next_unused_address( KeychainKind :: External )
261+ . script_pubkey( ) ,
262+ value: Amount :: from_sat( 10_000 ) ,
263+ } ] ,
264+ } ;
265+ let confirmed_txid = confirmed_tx. compute_txid ( ) ;
266+ insert_tx ( & mut wallet, confirmed_tx) ;
267+ let block_id = wallet. latest_checkpoint ( ) . block_id ( ) ;
268+ insert_anchor (
269+ & mut wallet,
270+ confirmed_txid,
271+ ConfirmationBlockTime {
272+ block_id,
273+ confirmation_time : 1 ,
274+ } ,
275+ ) ;
276+
277+ let truc_tx = Transaction {
278+ version : transaction:: Version ( 3 ) ,
279+ lock_time : absolute:: LockTime :: ZERO ,
280+ input : vec ! [ ] ,
281+ output : vec ! [ TxOut {
282+ script_pubkey: wallet
283+ . next_unused_address( KeychainKind :: External )
284+ . script_pubkey( ) ,
285+ value: Amount :: from_sat( 30_000 ) ,
286+ } ] ,
287+ } ;
288+ let truc_txid = truc_tx. compute_txid ( ) ;
289+ insert_tx ( & mut wallet, truc_tx) ;
290+
291+ let recipient = wallet. next_unused_address ( KeychainKind :: External ) ;
292+
293+ let mut builder = wallet. build_tx ( ) ;
294+ builder
295+ . fee_rate ( FeeRate :: ZERO )
296+ . add_recipient ( recipient. script_pubkey ( ) , Amount :: from_sat ( 20_000 ) ) ;
297+ assert_matches ! (
298+ builder. finish( ) ,
299+ Err ( CreateTxError :: CoinSelection (
300+ coin_selection:: InsufficientFunds { .. }
301+ ) )
302+ ) ;
303+
304+ let mut builder = wallet. build_tx ( ) ;
305+ builder
306+ . fee_rate ( FeeRate :: ZERO )
307+ . version ( 3 )
308+ . add_recipient ( recipient. script_pubkey ( ) , Amount :: from_sat ( 20_000 ) ) ;
309+ let psbt = builder
310+ . finish ( )
311+ . expect ( "v3 transaction should be buildable" ) ;
312+
313+ assert_eq ! ( psbt. unsigned_tx. version, transaction:: Version ( 3 ) ) ;
314+ assert ! (
315+ psbt. unsigned_tx
316+ . input
317+ . iter( )
318+ . any( |input| input. previous_output. txid == truc_txid) ,
319+ "version=3 transaction should be able to spend the unconfirmed v3 output"
320+ ) ;
321+ }
322+
323+ #[ test]
324+ fn test_create_tx_non_v3_allows_unconfirmed_non_v3_utxos ( ) {
325+ let ( descriptor, change_descriptor) = get_test_wpkh_and_change_desc ( ) ;
326+ let mut wallet = Wallet :: create ( descriptor, change_descriptor)
327+ . network ( Network :: Regtest )
328+ . create_wallet_no_persist ( )
329+ . expect ( "wallet" ) ;
330+
331+ let unconfirmed_tx = Transaction {
332+ version : transaction:: Version :: ONE ,
333+ lock_time : absolute:: LockTime :: ZERO ,
334+ input : vec ! [ ] ,
335+ output : vec ! [ TxOut {
336+ script_pubkey: wallet
337+ . next_unused_address( KeychainKind :: External )
338+ . script_pubkey( ) ,
339+ value: Amount :: from_sat( 30_000 ) ,
340+ } ] ,
341+ } ;
342+ let unconfirmed_txid = unconfirmed_tx. compute_txid ( ) ;
343+ insert_tx ( & mut wallet, unconfirmed_tx) ;
344+
345+ let recipient = wallet. next_unused_address ( KeychainKind :: External ) ;
346+ let mut builder = wallet. build_tx ( ) ;
347+ builder
348+ . fee_rate ( FeeRate :: ZERO )
349+ . add_recipient ( recipient. script_pubkey ( ) , Amount :: from_sat ( 20_000 ) ) ;
350+ let psbt = builder
351+ . finish ( )
352+ . expect ( "non-v3 unconfirmed outputs should remain spendable" ) ;
353+
354+ assert ! (
355+ psbt. unsigned_tx
356+ . input
357+ . iter( )
358+ . any( |input| input. previous_output. txid == unconfirmed_txid) ,
359+ "expected the unconfirmed non-v3 output to be available for selection"
360+ ) ;
361+ }
362+
238363#[ test]
239364fn test_create_tx_default_locktime_is_last_sync_height ( ) {
240365 let ( mut wallet, _) = get_funded_wallet_wpkh ( ) ;
0 commit comments