@@ -375,28 +375,31 @@ impl<'a, Cs> TxBuilder<'a, Cs> {
375375 satisfaction_weight : Weight ,
376376 sequence : Sequence ,
377377 ) -> Result < & mut Self , AddForeignUtxoError > {
378+ let script_pubkey = if let Some ( ref txout) = psbt_input. witness_utxo {
379+ txout. script_pubkey . clone ( )
380+ } else if let Some ( tx) = psbt_input. non_witness_utxo . as_ref ( ) {
381+ if tx. compute_txid ( ) != outpoint. txid {
382+ return Err ( AddForeignUtxoError :: InvalidTxid {
383+ input_txid : tx. compute_txid ( ) ,
384+ foreign_utxo : outpoint,
385+ } ) ;
386+ }
387+
388+ if let Ok ( txout) = tx. tx_out ( outpoint. vout as usize ) {
389+ txout. script_pubkey . clone ( )
390+ } else {
391+ return Err ( AddForeignUtxoError :: InvalidOutpoint ( outpoint) ) ;
392+ }
393+ } else {
394+ return Err ( AddForeignUtxoError :: MissingUtxo ) ;
395+ } ;
396+
378397 // Avoid the inclusion of local utxos as foreign utxos
379- if self . wallet . tx_graph ( ) . get_txout ( outpoint) . is_some ( ) {
380- return Err ( AddForeignUtxoError :: NotForeignUtxo ) ;
398+ if self . wallet . is_mine ( script_pubkey) {
399+ // TODO(2.0.0): return Err(AddForeignUtxoError::NotForeignUtxo);
400+ // No-op to avoid breaking changes until next major release
401+ return Ok ( self ) ;
381402 } ;
382- if psbt_input. witness_utxo . is_none ( ) {
383- match psbt_input. non_witness_utxo . as_ref ( ) {
384- Some ( tx) => {
385- if tx. compute_txid ( ) != outpoint. txid {
386- return Err ( AddForeignUtxoError :: InvalidTxid {
387- input_txid : tx. compute_txid ( ) ,
388- foreign_utxo : outpoint,
389- } ) ;
390- }
391- if tx. output . len ( ) <= outpoint. vout as usize {
392- return Err ( AddForeignUtxoError :: InvalidOutpoint ( outpoint) ) ;
393- }
394- }
395- None => {
396- return Err ( AddForeignUtxoError :: MissingUtxo ) ;
397- }
398- }
399- }
400403
401404 self . params . utxos . push ( WeightedUtxo {
402405 satisfaction_weight,
@@ -716,8 +719,8 @@ pub enum AddForeignUtxoError {
716719 InvalidOutpoint ( OutPoint ) ,
717720 /// Foreign utxo missing witness_utxo or non_witness_utxo
718721 MissingUtxo ,
719- /// UTxO is owned by wallet
720- NotForeignUtxo ,
722+ // Avoid breaking changes until next major release
723+ // TODO(2.0.0): NotForeignUtxo,
721724}
722725
723726impl fmt:: Display for AddForeignUtxoError {
@@ -737,7 +740,8 @@ impl fmt::Display for AddForeignUtxoError {
737740 outpoint. txid, outpoint. vout,
738741 ) ,
739742 Self :: MissingUtxo => write ! ( f, "Foreign utxo missing witness_utxo or non_witness_utxo" ) ,
740- Self :: NotForeignUtxo => write ! ( f, "UTxO is owned by wallet" ) ,
743+ // Avoid breaking changes until next major release
744+ // TODO(2.0.0): Self::NotForeignUtxo => write!(f, "UTxO is owned by wallet"),
741745 }
742746 }
743747}
@@ -1106,4 +1110,21 @@ mod test {
11061110 builder. fee_rate ( FeeRate :: from_sat_per_kwu ( feerate + 250 ) ) ;
11071111 let _ = builder. finish ( ) . unwrap ( ) ;
11081112 }
1113+
1114+ #[ test]
1115+ fn test_add_foreign_utxo_fails_when_utxo_is_owned_by_wallet ( ) {
1116+ use crate :: test_utils:: get_funded_wallet_wpkh;
1117+ let ( mut wallet, _) = get_funded_wallet_wpkh ( ) ;
1118+ let outpoint = wallet. list_unspent ( ) . next ( ) . expect ( "must exist" ) . outpoint ;
1119+ let foreign_utxo_satisfaction = wallet
1120+ . public_descriptor ( KeychainKind :: External )
1121+ . max_weight_to_satisfy ( )
1122+ . unwrap ( ) ;
1123+
1124+ let mut builder = wallet. build_tx ( ) ;
1125+ let _ =
1126+ builder. add_foreign_utxo ( outpoint, psbt:: Input :: default ( ) , foreign_utxo_satisfaction) ;
1127+ // TODO(2.0.0): assert!(matches!(result, Err(AddForeignUtxoError::NotForeignUtxo)));
1128+ assert ! ( builder. params. utxos. is_empty( ) ) ;
1129+ }
11091130}
0 commit comments