From 31e83245228d207f9c5a3f2d230c9397c6fe1e34 Mon Sep 17 00:00:00 2001 From: Chris Stewart Date: Thu, 11 Nov 2021 15:22:45 -0600 Subject: [PATCH] Make sure exception is caught by Future inside of UtxoHandling.unmarkUTXOsAsReserved() (#3816) --- .../dlc/wallet/MultiWalletDLCTest.scala | 27 +++++++++++++++++++ .../wallet/internal/UtxoHandling.scala | 17 ++++++++---- 2 files changed, 39 insertions(+), 5 deletions(-) diff --git a/dlc-wallet-test/src/test/scala/org/bitcoins/dlc/wallet/MultiWalletDLCTest.scala b/dlc-wallet-test/src/test/scala/org/bitcoins/dlc/wallet/MultiWalletDLCTest.scala index 530d2af00c..43cb09f352 100644 --- a/dlc-wallet-test/src/test/scala/org/bitcoins/dlc/wallet/MultiWalletDLCTest.scala +++ b/dlc-wallet-test/src/test/scala/org/bitcoins/dlc/wallet/MultiWalletDLCTest.scala @@ -3,6 +3,7 @@ package org.bitcoins.dlc.wallet import com.typesafe.config.ConfigFactory import org.bitcoins.core.number.UInt32 import org.bitcoins.core.wallet.fee.SatoshisPerVirtualByte +import org.bitcoins.core.wallet.utxo.TxoState import org.bitcoins.server.BitcoinSAppConfig import org.bitcoins.testkit.BitcoinSTestAppConfig import org.bitcoins.testkit.keymanager.KeyManagerTestUtil.bip39PasswordOpt @@ -61,4 +62,30 @@ class MultiWalletDLCTest extends BitcoinSWalletTest { assert(dlcsA != dlcsB) } } + + it must "create an offer, out of band unreserve the utxo, and then cancel the offer" in { + fundedWallet: FundedDLCWallet => + //see: https://github.com/bitcoin-s/bitcoin-s/issues/3813#issue-1051117559 + val wallet = fundedWallet.wallet + val offerF = wallet.createDLCOffer(contractInfo = sampleContractInfo, + collateral = half, + feeRateOpt = + Some(SatoshisPerVirtualByte.one), + locktime = UInt32.zero, + refundLocktime = UInt32.one) + + //now unreserve the utxo + val reservedUtxoF = for { + _ <- offerF + utxos <- wallet.listUtxos(TxoState.Reserved) + _ <- wallet.unmarkUTXOsAsReserved(utxos) + } yield () + + //now cancel the offer + for { + offer <- offerF + _ <- reservedUtxoF + _ <- wallet.cancelDLC(offer.dlcId) + } yield succeed + } } diff --git a/wallet/src/main/scala/org/bitcoins/wallet/internal/UtxoHandling.scala b/wallet/src/main/scala/org/bitcoins/wallet/internal/UtxoHandling.scala index 6d8ea5ce90..ce433a51fc 100644 --- a/wallet/src/main/scala/org/bitcoins/wallet/internal/UtxoHandling.scala +++ b/wallet/src/main/scala/org/bitcoins/wallet/internal/UtxoHandling.scala @@ -334,14 +334,21 @@ private[wallet] trait UtxoHandling extends WalletLogger { override def unmarkUTXOsAsReserved( utxos: Vector[SpendingInfoDb]): Future[Vector[SpendingInfoDb]] = { - val unreserved = utxos.filterNot(_.state == TxoState.Reserved) - require(unreserved.isEmpty, s"Some utxos are not reserved, got $unreserved") + val updatedUtxosF = Future { + //make sure exception isn't thrown outside of a future to fix + //see: https://github.com/bitcoin-s/bitcoin-s/issues/3813 + val unreserved = utxos.filterNot(_.state == TxoState.Reserved) + require(unreserved.isEmpty, + s"Some utxos are not reserved, got $unreserved") - // unmark all utxos are reserved - val updatedUtxos = utxos - .map(_.copyWithState(TxoState.PendingConfirmationsReceived)) + // unmark all utxos are reserved + val updatedUtxos = utxos + .map(_.copyWithState(TxoState.PendingConfirmationsReceived)) + updatedUtxos + } for { + updatedUtxos <- updatedUtxosF // update the confirmed utxos updatedConfirmed <- updateUtxoConfirmedStates(updatedUtxos)