diff --git a/dlc-wallet-test/src/test/scala/org/bitcoins/dlc/wallet/DLCExecutionTest.scala b/dlc-wallet-test/src/test/scala/org/bitcoins/dlc/wallet/DLCExecutionTest.scala index a9fbc6967d..69ed30ba8f 100644 --- a/dlc-wallet-test/src/test/scala/org/bitcoins/dlc/wallet/DLCExecutionTest.scala +++ b/dlc-wallet-test/src/test/scala/org/bitcoins/dlc/wallet/DLCExecutionTest.scala @@ -1,6 +1,6 @@ package org.bitcoins.dlc.wallet -import org.bitcoins.core.currency.Satoshis +import org.bitcoins.core.currency.{Bitcoins, Satoshis} import org.bitcoins.core.number.UInt32 import org.bitcoins.core.protocol.dlc.models.DLCMessage.DLCOffer import org.bitcoins.core.protocol.dlc.models.DLCStatus.{ @@ -462,4 +462,31 @@ class DLCExecutionTest extends BitcoinSDualWalletTest { recoverToSucceededIf[IllegalArgumentException](resultF) } + + it must "throw an exception when you try to execute a DLC in the SIGNED state" in { + wallets => + val walletA = wallets._1.wallet + val walletB = wallets._2.wallet + val contractOraclePair = DLCWalletUtil.sampleContractOraclePair + val amt = Bitcoins.one + val contractInfo = SingleContractInfo(amt.satoshis, contractOraclePair) + val resultF = for { + offer <- walletA.createDLCOffer( + contractInfo = contractInfo, + collateral = half, + feeRateOpt = Some(SatoshisPerVirtualByte.fromLong(10)), + locktime = dummyTimeouts.contractMaturity.toUInt32, + refundLocktime = dummyTimeouts.contractTimeout.toUInt32, + externalPayoutAddressOpt = None, + externalChangeAddressOpt = None + ) + accept <- walletB.acceptDLCOffer(offer, None, None) + sign <- walletA.signDLC(accept) + contractId = sign.contractId + (_, sig) = DLCWalletUtil.getSigs(contractInfo) + _ <- walletA.executeDLC(contractId, sig) + } yield succeed + + recoverToSucceededIf[RuntimeException](resultF) + } } diff --git a/dlc-wallet/src/main/scala/org/bitcoins/dlc/wallet/DLCWallet.scala b/dlc-wallet/src/main/scala/org/bitcoins/dlc/wallet/DLCWallet.scala index 0126de20ae..a200e944d8 100644 --- a/dlc-wallet/src/main/scala/org/bitcoins/dlc/wallet/DLCWallet.scala +++ b/dlc-wallet/src/main/scala/org/bitcoins/dlc/wallet/DLCWallet.scala @@ -1431,7 +1431,14 @@ abstract class DLCWallet for { dlcDb <- dlcDAO.findByContractId(contractId).map(_.get) - + _ = dlcDb.state match { + case state @ (Offered | AcceptComputingAdaptorSigs | Accepted | + SignComputingAdaptorSigs | Signed) => + sys.error( + s"Cannot execute DLC before the DLC is broadcast to the blockchain, state=$state") + case Broadcasted | Confirmed | _: ClosedState => + //can continue executing, do nothing + } (announcements, announcementData, nonceDbs) <- dlcDataManagement .getDLCAnnouncementDbs(dlcDb.dlcId)