mirror of
https://github.com/bitcoin-s/bitcoin-s.git
synced 2024-11-19 01:40:55 +01:00
Add DLC callback for refunded DLC (#3989)
This commit is contained in:
parent
21c97bba12
commit
8a881b37f4
@ -30,7 +30,6 @@ class DLCWalletCallbackTest extends BitcoinSDualWalletTest {
|
||||
val signedP: Promise[DLCStatus] = Promise()
|
||||
val broadcastP: Promise[DLCStatus] = Promise()
|
||||
|
||||
//not implemented yet
|
||||
val confirmedP: Promise[DLCStatus] = Promise()
|
||||
|
||||
val claimedP: Promise[DLCStatus] = Promise()
|
||||
@ -49,8 +48,8 @@ class DLCWalletCallbackTest extends BitcoinSDualWalletTest {
|
||||
case DLCState.Broadcasted =>
|
||||
//ignore broadcast from this wallet
|
||||
Future.unit
|
||||
case x @ (DLCState.Accepted | DLCState.Confirmed |
|
||||
DLCState.RemoteClaimed | DLCState.Refunded) =>
|
||||
case x @ (DLCState.Accepted | DLCState.RemoteClaimed |
|
||||
DLCState.Refunded) =>
|
||||
sys.error(s"Shouldn't receive state=$x for callback")
|
||||
}
|
||||
|
||||
@ -85,7 +84,7 @@ class DLCWalletCallbackTest extends BitcoinSDualWalletTest {
|
||||
val initF = DLCWalletUtil.initDLC(wallets._1,
|
||||
wallets._2,
|
||||
DLCWalletUtil.sampleContractInfo)
|
||||
val executeF = for {
|
||||
def executeF = for {
|
||||
_ <- initF
|
||||
contractId <- DLCWalletUtil.getContractId(wallets._1.wallet)
|
||||
fundingTx <- walletA.getDLCFundingTx(contractId)
|
||||
@ -111,8 +110,8 @@ class DLCWalletCallbackTest extends BitcoinSDualWalletTest {
|
||||
accept <- acceptP.future
|
||||
sign <- signedP.future
|
||||
broadcast <- broadcastP.future
|
||||
confirmed <- confirmedP.future
|
||||
_ <- executeF
|
||||
confirmed <- confirmedP.future
|
||||
claimed <- claimedP.future
|
||||
remoteClaimed <- remoteClaimedP.future
|
||||
} yield {
|
||||
@ -125,4 +124,87 @@ class DLCWalletCallbackTest extends BitcoinSDualWalletTest {
|
||||
assert(remoteClaimed.state == DLCState.RemoteClaimed)
|
||||
}
|
||||
}
|
||||
|
||||
it must "verify refunded callback is executed" in { wallets =>
|
||||
val walletA: DLCWallet = wallets._1.wallet
|
||||
val walletB: DLCWallet = wallets._2.wallet
|
||||
val offerP: Promise[DLCStatus] = Promise()
|
||||
val acceptP: Promise[DLCStatus] = Promise()
|
||||
val signedP: Promise[DLCStatus] = Promise()
|
||||
val broadcastP: Promise[DLCStatus] = Promise()
|
||||
val refundedP: Promise[DLCStatus] = Promise()
|
||||
|
||||
val walletACallback: OnDLCStateChange = { case status: DLCStatus =>
|
||||
status.state match {
|
||||
case DLCState.Offered =>
|
||||
Future.successful(offerP.success(status))
|
||||
case DLCState.Signed =>
|
||||
Future.successful(signedP.success(status))
|
||||
case DLCState.Broadcasted | DLCState.Confirmed =>
|
||||
//ignore them from this wallet
|
||||
Future.unit
|
||||
case DLCState.Refunded =>
|
||||
Future.successful(refundedP.success(status))
|
||||
case x @ (DLCState.Claimed | DLCState.Accepted |
|
||||
DLCState.RemoteClaimed | DLCState.Refunded) =>
|
||||
sys.error(s"Shouldn't receive state=$x for callback")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
val walletBCallback: OnDLCStateChange = { case status: DLCStatus =>
|
||||
status.state match {
|
||||
case DLCState.Accepted =>
|
||||
Future.successful(acceptP.success(status))
|
||||
case DLCState.Broadcasted =>
|
||||
Future.successful(broadcastP.success(status))
|
||||
case x @ (DLCState.Refunded | DLCState.Offered | DLCState.Signed) =>
|
||||
sys.error(s"Shouldn't receive state=$x for callback")
|
||||
case DLCState.Confirmed | DLCState.Claimed | DLCState.RemoteClaimed =>
|
||||
//do nothing, we are doing assertions for these on walletACallback
|
||||
Future.unit
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
val walletACallbacks = DLCWalletCallbacks.onDLCStateChange(walletACallback)
|
||||
|
||||
val walletBCallbacks = DLCWalletCallbacks.onDLCStateChange(walletBCallback)
|
||||
|
||||
walletA.dlcConfig.addCallbacks(walletACallbacks)
|
||||
walletB.dlcConfig.addCallbacks(walletBCallbacks)
|
||||
|
||||
//run init DLC and make sure we get the callback hit
|
||||
|
||||
val initF = DLCWalletUtil.initDLC(wallets._1,
|
||||
wallets._2,
|
||||
DLCWalletUtil.sampleContractInfo)
|
||||
|
||||
def refundF = for {
|
||||
_ <- initF
|
||||
contractId <- DLCWalletUtil.getContractId(wallets._1.wallet)
|
||||
fundingTx <- walletA.getDLCFundingTx(contractId)
|
||||
_ <- walletA.processTransaction(
|
||||
transaction = fundingTx,
|
||||
blockHashOpt = Some(CryptoGenerators.doubleSha256DigestBE.sample.get))
|
||||
transaction <- walletA.executeDLCRefund(contractId)
|
||||
_ <- walletB.processTransaction(transaction, None)
|
||||
} yield ()
|
||||
|
||||
for {
|
||||
_ <- initF
|
||||
offer <- offerP.future
|
||||
accept <- acceptP.future
|
||||
sign <- signedP.future
|
||||
broadcast <- broadcastP.future
|
||||
_ <- refundF
|
||||
refunded <- refundedP.future
|
||||
} yield {
|
||||
assert(offer.state == DLCState.Offered)
|
||||
assert(accept.state == DLCState.Accepted)
|
||||
assert(sign.state == DLCState.Signed)
|
||||
assert(broadcast.state == DLCState.Broadcasted)
|
||||
assert(refunded.state == DLCState.Refunded)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1413,6 +1413,9 @@ abstract class DLCWallet
|
||||
for {
|
||||
dlcDbOpt <- dlcDAO.findByContractId(contractId)
|
||||
dlcDb = dlcDbOpt.get
|
||||
offerDbOpt <- dlcOfferDAO.findByDLCId(dlcDb.dlcId)
|
||||
_ = require(offerDbOpt.nonEmpty,
|
||||
s"Invalid DLC $dlcDb.dlcId: no offer data")
|
||||
contractData <- contractDataDAO.read(dlcDb.dlcId).map(_.get)
|
||||
|
||||
currentHeight <- chainQueryApi.getBestHashBlockHeight()
|
||||
@ -1446,9 +1449,17 @@ abstract class DLCWallet
|
||||
s"Created DLC refund transaction ${refundTx.txIdBE.hex} for contract ${contractId.toHex}")
|
||||
|
||||
_ <- updateDLCState(contractId, DLCState.Refunded)
|
||||
_ <- updateClosingTxId(contractId, refundTx.txIdBE)
|
||||
updatedDlcDb <- updateClosingTxId(contractId, refundTx.txIdBE)
|
||||
|
||||
_ <- processTransaction(refundTx, blockHashOpt = None)
|
||||
closingTxOpt <- getClosingTxOpt(updatedDlcDb)
|
||||
dlcAcceptOpt <- dlcAcceptDAO.findByDLCId(updatedDlcDb.dlcId)
|
||||
status <- buildDLCStatus(updatedDlcDb,
|
||||
contractData,
|
||||
offerDbOpt.get,
|
||||
dlcAcceptOpt,
|
||||
closingTxOpt)
|
||||
_ <- dlcConfig.walletCallbacks.executeOnDLCStateChange(logger, status.get)
|
||||
} yield refundTx
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user