Only allow executing a DLC if it is in the Broadcast or Confirmed state (#4185)

* Only allow executing a DLC if it is in the Broadcast or Confirmed state

* Only throw if DLC is setup, not if its already executed
This commit is contained in:
Chris Stewart 2022-03-13 14:08:47 -05:00 committed by GitHub
parent 7ddeae66d2
commit 3f18f7b04c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 36 additions and 2 deletions

View File

@ -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)
}
}

View File

@ -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)