From 6db4812f0663f947deba11773638b7a730500b6c Mon Sep 17 00:00:00 2001 From: woodser Date: Fri, 25 Oct 2024 11:35:55 -0400 Subject: [PATCH] synchronize on lock to prepare payment sent or received --- .../tasks/BuyerPreparePaymentSentMessage.java | 23 +++++--- .../SellerPreparePaymentReceivedMessage.java | 53 +++++++++++-------- 2 files changed, 45 insertions(+), 31 deletions(-) diff --git a/core/src/main/java/haveno/core/trade/protocol/tasks/BuyerPreparePaymentSentMessage.java b/core/src/main/java/haveno/core/trade/protocol/tasks/BuyerPreparePaymentSentMessage.java index 2cd4376c..8b739011 100644 --- a/core/src/main/java/haveno/core/trade/protocol/tasks/BuyerPreparePaymentSentMessage.java +++ b/core/src/main/java/haveno/core/trade/protocol/tasks/BuyerPreparePaymentSentMessage.java @@ -36,6 +36,7 @@ package haveno.core.trade.protocol.tasks; import com.google.common.base.Preconditions; import haveno.common.taskrunner.TaskRunner; +import haveno.core.trade.HavenoUtils; import haveno.core.trade.Trade; import lombok.extern.slf4j.Slf4j; import monero.wallet.MoneroWallet; @@ -79,15 +80,21 @@ public class BuyerPreparePaymentSentMessage extends TradeTask { // create payout tx if we have seller's updated multisig hex if (trade.getSeller().getUpdatedMultisigHex() != null) { - // import multisig hex - trade.importMultisigHex(); + // synchronize on lock for wallet operations + synchronized (trade.getWalletLock()) { + synchronized (HavenoUtils.getWalletFunctionLock()) { - // create payout tx - log.info("Buyer creating unsigned payout tx for {} {} ", trade.getClass().getSimpleName(), trade.getShortId()); - MoneroTxWallet payoutTx = trade.createPayoutTx(); - trade.updatePayout(payoutTx); - trade.getSelf().setUnsignedPayoutTxHex(payoutTx.getTxSet().getMultisigTxHex()); - trade.requestPersistence(); + // import multisig hex + trade.importMultisigHex(); + + // create payout tx + log.info("Buyer creating unsigned payout tx for {} {} ", trade.getClass().getSimpleName(), trade.getShortId()); + MoneroTxWallet payoutTx = trade.createPayoutTx(); + trade.updatePayout(payoutTx); + trade.getSelf().setUnsignedPayoutTxHex(payoutTx.getTxSet().getMultisigTxHex()); + trade.requestPersistence(); + } + } } complete(); diff --git a/core/src/main/java/haveno/core/trade/protocol/tasks/SellerPreparePaymentReceivedMessage.java b/core/src/main/java/haveno/core/trade/protocol/tasks/SellerPreparePaymentReceivedMessage.java index a483026a..1452104e 100644 --- a/core/src/main/java/haveno/core/trade/protocol/tasks/SellerPreparePaymentReceivedMessage.java +++ b/core/src/main/java/haveno/core/trade/protocol/tasks/SellerPreparePaymentReceivedMessage.java @@ -19,6 +19,7 @@ package haveno.core.trade.protocol.tasks; import haveno.common.taskrunner.TaskRunner; import haveno.core.support.dispute.Dispute; +import haveno.core.trade.HavenoUtils; import haveno.core.trade.Trade; import lombok.extern.slf4j.Slf4j; import monero.wallet.model.MoneroTxWallet; @@ -49,34 +50,40 @@ public class SellerPreparePaymentReceivedMessage extends TradeTask { trade.setPayoutTxHex(null); } - // import multisig hex unless already signed - if (trade.getPayoutTxHex() == null) { - trade.importMultisigHex(); - } + // synchronize on lock for wallet operations + synchronized (trade.getWalletLock()) { + synchronized (HavenoUtils.getWalletFunctionLock()) { - // verify, sign, and publish payout tx if given - if (trade.getBuyer().getPaymentSentMessage().getPayoutTxHex() != null) { - try { + // import multisig hex unless already signed if (trade.getPayoutTxHex() == null) { - log.info("Seller verifying, signing, and publishing payout tx for trade {}", trade.getId()); - trade.processPayoutTx(trade.getBuyer().getPaymentSentMessage().getPayoutTxHex(), true, true); - } else { - log.warn("Seller publishing previously signed payout tx for trade {}", trade.getId()); - trade.processPayoutTx(trade.getPayoutTxHex(), false, true); + trade.importMultisigHex(); + } + + // verify, sign, and publish payout tx if given + if (trade.getBuyer().getPaymentSentMessage().getPayoutTxHex() != null) { + try { + if (trade.getPayoutTxHex() == null) { + log.info("Seller verifying, signing, and publishing payout tx for trade {}", trade.getId()); + trade.processPayoutTx(trade.getBuyer().getPaymentSentMessage().getPayoutTxHex(), true, true); + } else { + log.warn("Seller publishing previously signed payout tx for trade {}", trade.getId()); + trade.processPayoutTx(trade.getPayoutTxHex(), false, true); + } + } catch (IllegalArgumentException | IllegalStateException e) { + log.warn("Illegal state or argument verifying, signing, and publishing payout tx for {} {}. Creating new unsigned payout tx. error={}. ", trade.getClass().getSimpleName(), trade.getId(), e.getMessage(), e); + createUnsignedPayoutTx(); + } catch (Exception e) { + log.warn("Error verifying, signing, and publishing payout tx for trade {}: {}", trade.getId(), e.getMessage(), e); + throw e; + } + } + + // otherwise create unsigned payout tx + else if (trade.getSelf().getUnsignedPayoutTxHex() == null) { + createUnsignedPayoutTx(); } - } catch (IllegalArgumentException | IllegalStateException e) { - log.warn("Illegal state or argument verifying, signing, and publishing payout tx for {} {}: {}. Creating new unsigned payout tx", trade.getClass().getSimpleName(), trade.getId(), e.getMessage(), e); - createUnsignedPayoutTx(); - } catch (Exception e) { - log.warn("Error verifying, signing, and publishing payout tx for trade {}: {}", trade.getId(), e.getMessage(), e); - throw e; } } - - // otherwise create unsigned payout tx - else if (trade.getSelf().getUnsignedPayoutTxHex() == null) { - createUnsignedPayoutTx(); - } } else if (trade.getArbitrator().getPaymentReceivedMessage().getSignedPayoutTxHex() != null && !trade.isPayoutPublished()) { // republish payout tx from previous message