Skip to content

Commit

Permalink
defer payout publish if published, skip warning log if published
Browse files Browse the repository at this point in the history
  • Loading branch information
woodser authored and nahuhh committed Nov 12, 2024
1 parent 39d5ed6 commit bbb57bf
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 14 deletions.
19 changes: 12 additions & 7 deletions core/src/main/java/haveno/core/trade/Trade.java
Original file line number Diff line number Diff line change
Expand Up @@ -1085,11 +1085,12 @@ public void importMultisigHex() {
} catch (IllegalArgumentException | IllegalStateException e) {
throw e;
} catch (Exception e) {
log.warn("Failed to import multisig hex, tradeId={}, attempt={}/{}, error={}", getShortId(), i + 1, TradeProtocol.MAX_ATTEMPTS, e.getMessage());
handleWalletError(e, sourceConnection);
doPollWallet();
if (isPayoutPublished()) break;
log.warn("Failed to import multisig hex, tradeId={}, attempt={}/{}, error={}", getShortId(), i + 1, TradeProtocol.MAX_ATTEMPTS, e.getMessage());
if (i == TradeProtocol.MAX_ATTEMPTS - 1) throw e;
HavenoUtils.waitFor(TradeProtocol.REPROCESS_DELAY_MS); // wait before retrying
doPollWallet();
}
}
}
Expand Down Expand Up @@ -1205,8 +1206,10 @@ public MoneroTxWallet createPayoutTx() {
} catch (IllegalArgumentException | IllegalStateException e) {
throw e;
} catch (Exception e) {
log.warn("Failed to create payout tx, tradeId={}, attempt={}/{}, error={}", getShortId(), i + 1, TradeProtocol.MAX_ATTEMPTS, e.getMessage());
handleWalletError(e, sourceConnection);
doPollWallet();
if (isPayoutPublished()) break;
log.warn("Failed to create payout tx, tradeId={}, attempt={}/{}, error={}", getShortId(), i + 1, TradeProtocol.MAX_ATTEMPTS, e.getMessage());
if (i == TradeProtocol.MAX_ATTEMPTS - 1) throw e;
HavenoUtils.waitFor(TradeProtocol.REPROCESS_DELAY_MS); // wait before retrying
}
Expand Down Expand Up @@ -1265,11 +1268,12 @@ public MoneroTxWallet createDisputePayoutTx(MoneroTxConfig txConfig) {
throw e;
} catch (Exception e) {
if (e.getMessage().contains("not possible")) throw new IllegalArgumentException("Loser payout is too small to cover the mining fee");
log.warn("Failed to create dispute payout tx, tradeId={}, attempt={}/{}, error={}", getShortId(), i + 1, TradeProtocol.MAX_ATTEMPTS, e.getMessage());
handleWalletError(e, sourceConnection);
doPollWallet();
if (isPayoutPublished()) break;
log.warn("Failed to create dispute payout tx, tradeId={}, attempt={}/{}, error={}", getShortId(), i + 1, TradeProtocol.MAX_ATTEMPTS, e.getMessage());
if (i == TradeProtocol.MAX_ATTEMPTS - 1) throw e;
HavenoUtils.waitFor(TradeProtocol.REPROCESS_DELAY_MS); // wait before retrying
doPollWallet();
}
}
throw new RuntimeException("Failed to create payout tx for " + getClass().getSimpleName() + " " + getId());
Expand All @@ -1295,11 +1299,12 @@ public void processPayoutTx(String payoutTxHex, boolean sign, boolean publish) {
} catch (IllegalArgumentException | IllegalStateException e) {
throw e;
} catch (Exception e) {
log.warn("Failed to process payout tx, tradeId={}, attempt={}/{}, error={}", getShortId(), i + 1, TradeProtocol.MAX_ATTEMPTS, e.getMessage(), e);
handleWalletError(e, sourceConnection);
doPollWallet();
if (isPayoutPublished()) break;
log.warn("Failed to process payout tx, tradeId={}, attempt={}/{}, error={}", getShortId(), i + 1, TradeProtocol.MAX_ATTEMPTS, e.getMessage(), e);
if (i == TradeProtocol.MAX_ATTEMPTS - 1) throw e;
HavenoUtils.waitFor(TradeProtocol.REPROCESS_DELAY_MS); // wait before retrying
doPollWallet();
} finally {
requestSaveWallet();
requestPersistence();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,12 +143,10 @@ private void processPayoutTx(PaymentReceivedMessage message) {
// handle if payout tx not published
if (!trade.isPayoutPublished()) {

// wait to sign and publish payout tx if defer flag set (seller recently saw payout tx arrive at buyer)
boolean isSigned = message.getSignedPayoutTxHex() != null;
boolean deferSignAndPublish = trade instanceof ArbitratorTrade && !isSigned && message.isDeferPublishPayout();
if (deferSignAndPublish) {
log.info("Deferring signing and publishing payout tx for {} {}", trade.getClass().getSimpleName(), trade.getId());
trade.pollWalletNormallyForMs(60000);
// wait to publish payout tx if defer flag set from seller (payout is expected)
if (message.isDeferPublishPayout()) {
log.info("Deferring publishing payout tx for {} {}", trade.getClass().getSimpleName(), trade.getId());
if (trade instanceof ArbitratorTrade) trade.pollWalletNormallyForMs(60000); // stop idling arbitrator
for (int i = 0; i < 5; i++) {
if (trade.isPayoutPublished()) break;
HavenoUtils.waitFor(Trade.DEFER_PUBLISH_MS / 5);
Expand All @@ -159,6 +157,7 @@ private void processPayoutTx(PaymentReceivedMessage message) {
// verify and publish payout tx
if (!trade.isPayoutPublished()) {
try {
boolean isSigned = message.getSignedPayoutTxHex() != null;
if (isSigned) {
log.info("{} {} publishing signed payout tx from seller", trade.getClass().getSimpleName(), trade.getId());
trade.processPayoutTx(message.getSignedPayoutTxHex(), false, true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,14 +103,15 @@ protected TradeMailboxMessage getTradeMailboxMessage(String tradeId) {
// messages where only the one which gets processed by the peer would be removed we use the same uid. All
// other data stays the same when we re-send the message at any time later.
String deterministicId = HavenoUtils.getDeterministicId(trade, PaymentReceivedMessage.class, getReceiverNodeAddress());
boolean deferPublishPayout = trade.isPayoutPublished() || trade.getState().ordinal() >= Trade.State.SELLER_SAW_ARRIVED_PAYMENT_RECEIVED_MSG.ordinal(); // informs receiver to expect payout so delay processing
PaymentReceivedMessage message = new PaymentReceivedMessage(
tradeId,
processModel.getMyNodeAddress(),
deterministicId,
trade.getPayoutTxHex() == null ? trade.getSelf().getUnsignedPayoutTxHex() : null, // unsigned // TODO: phase in after next update to clear old style trades
trade.getPayoutTxHex() == null ? null : trade.getPayoutTxHex(), // signed
trade.getSelf().getUpdatedMultisigHex(),
trade.getState().ordinal() >= Trade.State.SELLER_SAW_ARRIVED_PAYMENT_RECEIVED_MSG.ordinal(), // informs to expect payout
deferPublishPayout,
trade.getTradePeer().getAccountAgeWitness(),
signedWitness,
getReceiver() == trade.getArbitrator() ? trade.getBuyer().getPaymentSentMessage() : null // buyer already has payment sent message
Expand Down

0 comments on commit bbb57bf

Please sign in to comment.