Skip to content

Commit c8fab5f

Browse files
authored
fixes when a deposit transaction does not confirm (#1892)
1 parent 19acab4 commit c8fab5f

File tree

2 files changed

+35
-18
lines changed

2 files changed

+35
-18
lines changed

core/src/main/java/haveno/core/support/dispute/DisputeValidation.java

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,15 @@
4242
public class DisputeValidation {
4343

4444
public static void validatePaymentAccountPayloads(Dispute dispute) throws ValidationException {
45-
if (dispute.getSellerPaymentAccountPayload() == null) throw new ValidationException(dispute, "Seller's payment account payload is null in dispute opened for trade " + dispute.getTradeId());
46-
if (!Arrays.equals(dispute.getSellerPaymentAccountPayload().getHash(), dispute.getContract().getSellerPaymentAccountPayloadHash())) throw new ValidationException(dispute, "Hash of seller's payment account payload does not match contract");
45+
if (dispute.getSellerPaymentAccountPayload() != null) {
46+
if (!Arrays.equals(dispute.getSellerPaymentAccountPayload().getHash(), dispute.getContract().getSellerPaymentAccountPayloadHash())) {
47+
throw new ValidationException(dispute, "Hash of seller's payment account payload does not match contract");
48+
}
49+
}
4750
if (dispute.getBuyerPaymentAccountPayload() != null) {
48-
if (!Arrays.equals(dispute.getBuyerPaymentAccountPayload().getHash(), dispute.getContract().getBuyerPaymentAccountPayloadHash())) throw new ValidationException(dispute, "Hash of buyer's payment account payload does not match contract");
51+
if (!Arrays.equals(dispute.getBuyerPaymentAccountPayload().getHash(), dispute.getContract().getBuyerPaymentAccountPayloadHash())) {
52+
throw new ValidationException(dispute, "Hash of buyer's payment account payload does not match contract");
53+
}
4954
}
5055
}
5156

core/src/main/java/haveno/core/trade/Trade.java

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2727,39 +2727,45 @@ private void doPollWallet() {
27272727
}
27282728
}
27292729
setDepositTxs(txs);
2730-
if (!isPublished(getMaker().getDepositTx()) || (!hasBuyerAsTakerWithoutDeposit() && !isPublished(getTaker().getDepositTx()))) return; // skip if deposit txs not published successfully
2731-
setStateDepositsSeen();
27322730

2733-
// set actual security deposits
2734-
if (getBuyer().getDepositTx() != null) {
2731+
// set actual buyer security deposit
2732+
if (isSeen(getBuyer().getDepositTx())) {
27352733
BigInteger buyerSecurityDeposit = ((MoneroTxWallet) getBuyer().getDepositTx()).getIncomingAmount();
2736-
if (!getBuyer().getSecurityDeposit().equals(BigInteger.ZERO) && !getBuyer().getSecurityDeposit().equals(buyerSecurityDeposit)) {
2734+
if (!getBuyer().getSecurityDeposit().equals(BigInteger.ZERO) && !buyerSecurityDeposit.equals(getBuyer().getSecurityDeposit())) {
27372735
log.warn("Overwriting buyer security deposit for {} {}, old={}, new={}", getClass().getSimpleName(), getShortId(), getBuyer().getSecurityDeposit(), buyerSecurityDeposit);
27382736
}
27392737
getBuyer().setSecurityDeposit(buyerSecurityDeposit);
27402738
}
2741-
if (getSeller().getDepositTx() != null) {
2739+
2740+
// set actual seller security deposit
2741+
if (isSeen(getSeller().getDepositTx())) {
27422742
BigInteger sellerSecurityDeposit = ((MoneroTxWallet) getSeller().getDepositTx()).getIncomingAmount().subtract(getAmount());
2743-
if (!getSeller().getSecurityDeposit().equals(BigInteger.ZERO) && !getSeller().getSecurityDeposit().equals(sellerSecurityDeposit)) {
2743+
if (!getSeller().getSecurityDeposit().equals(BigInteger.ZERO) && !sellerSecurityDeposit.equals(getSeller().getSecurityDeposit())) {
27442744
log.warn("Overwriting seller security deposit for {} {}, old={}, new={}", getClass().getSimpleName(), getShortId(), getSeller().getSecurityDeposit(), sellerSecurityDeposit);
27452745
}
27462746
getSeller().setSecurityDeposit(sellerSecurityDeposit);
27472747
}
27482748

2749-
// check for deposit txs confirmation
2750-
if (getMaker().getDepositTx().isConfirmed() && (hasBuyerAsTakerWithoutDeposit() || getTaker().getDepositTx().isConfirmed())) setStateDepositsConfirmed();
2749+
// handle both deposits seen
2750+
if (isSeen(getMaker().getDepositTx()) && (hasBuyerAsTakerWithoutDeposit() || isSeen(getTaker().getDepositTx()))) {
2751+
setStateDepositsSeen();
2752+
2753+
// check for deposit txs confirmed
2754+
if (getMaker().getDepositTx().isConfirmed() && (hasBuyerAsTakerWithoutDeposit() || getTaker().getDepositTx().isConfirmed())) setStateDepositsConfirmed();
27512755

2752-
// check for deposit txs unlocked
2753-
if (getMaker().getDepositTx().getNumConfirmations() >= XmrWalletService.NUM_BLOCKS_UNLOCK && (hasBuyerAsTakerWithoutDeposit() || getTaker().getDepositTx().getNumConfirmations() >= XmrWalletService.NUM_BLOCKS_UNLOCK)) {
2754-
setStateDepositsUnlocked();
2756+
// check for deposit txs unlocked
2757+
if (getMaker().getDepositTx().getNumConfirmations() >= XmrWalletService.NUM_BLOCKS_UNLOCK && (hasBuyerAsTakerWithoutDeposit() || getTaker().getDepositTx().getNumConfirmations() >= XmrWalletService.NUM_BLOCKS_UNLOCK)) {
2758+
setStateDepositsUnlocked();
2759+
}
27552760
}
27562761
}
27572762

27582763
// check for payout tx
2759-
if (isDepositsUnlocked()) {
2764+
boolean hasUnlockedDeposit = isUnlocked(getMaker().getDepositTx()) || isUnlocked(getTaker().getDepositTx());
2765+
if (isDepositsUnlocked() || hasUnlockedDeposit) { // arbitrator idles so these may not be the same
27602766

27612767
// determine if payout tx expected
2762-
boolean isPayoutExpected = isPaymentReceived() || hasPaymentReceivedMessage() || hasDisputeClosedMessage() || disputeState.ordinal() >= DisputeState.ARBITRATOR_SENT_DISPUTE_CLOSED_MSG.ordinal();
2768+
boolean isPayoutExpected = isDepositsUnlocked() && isPaymentReceived() || hasPaymentReceivedMessage() || hasDisputeClosedMessage() || disputeState.ordinal() >= DisputeState.ARBITRATOR_SENT_DISPUTE_CLOSED_MSG.ordinal();
27632769

27642770
// sync wallet if payout expected or payout is published
27652771
if (isPayoutExpected || isPayoutPublished()) syncWalletIfBehind();
@@ -2837,13 +2843,19 @@ else if (hasFailedTx && isPayoutPublished()) {
28372843
}
28382844
}
28392845

2840-
private static boolean isPublished(MoneroTx tx) {
2846+
private static boolean isSeen(MoneroTx tx) {
28412847
if (tx == null) return false;
28422848
if (Boolean.TRUE.equals(tx.isFailed())) return false;
28432849
if (!Boolean.TRUE.equals(tx.inTxPool()) && !Boolean.TRUE.equals(tx.isConfirmed())) return false;
28442850
return true;
28452851
}
28462852

2853+
private static boolean isUnlocked(MoneroTx tx) {
2854+
if (tx == null) return false;
2855+
if (tx.getNumConfirmations() == null || tx.getNumConfirmations() < XmrWalletService.NUM_BLOCKS_UNLOCK) return false;
2856+
return true;
2857+
}
2858+
28472859
private void syncWalletIfBehind() {
28482860
synchronized (walletLock) {
28492861
if (isWalletBehind()) {

0 commit comments

Comments
 (0)