request connection switch every other attempt

This commit is contained in:
woodser 2025-07-26 11:18:35 -04:00 committed by woodser
parent d575f384ef
commit 40aacf4672
8 changed files with 15 additions and 13 deletions

View file

@ -1358,7 +1358,7 @@ public class OpenOfferManager implements PeerManager.Listener, DecryptedDirectMe
} catch (Exception e) {
if (e.getMessage().contains("not enough")) throw e; // do not retry if not enough funds
log.warn("Error creating split output tx to fund offer, offerId={}, subaddress={}, attempt={}/{}, error={}", openOffer.getShortId(), entry.getSubaddressIndex(), i + 1, TradeProtocol.MAX_ATTEMPTS, e.getMessage());
xmrWalletService.handleWalletError(e, sourceConnection);
xmrWalletService.handleWalletError(e, sourceConnection, i + 1);
if (stopped || i == TradeProtocol.MAX_ATTEMPTS - 1) throw e;
HavenoUtils.waitFor(TradeProtocol.REPROCESS_DELAY_MS); // wait before retrying
}

View file

@ -100,7 +100,7 @@ public class MakerReserveOfferFunds extends Task<PlaceOfferModel> {
throw e;
} catch (Exception e) {
log.warn("Error creating reserve tx, offerId={}, attempt={}/{}, error={}", openOffer.getShortId(), i + 1, TradeProtocol.MAX_ATTEMPTS, e.getMessage());
model.getXmrWalletService().handleWalletError(e, sourceConnection);
model.getXmrWalletService().handleWalletError(e, sourceConnection, i + 1);
verifyPending();
if (i == TradeProtocol.MAX_ATTEMPTS - 1) throw e;
model.getProtocol().startTimeoutTimer(); // reset protocol timeout

View file

@ -1152,7 +1152,7 @@ public abstract class Trade extends XmrWalletBase implements Tradable, Model {
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);
handleWalletError(e, sourceConnection, i + 1);
doPollWallet();
if (isPayoutPublished()) break;
if (i == TradeProtocol.MAX_ATTEMPTS - 1) throw e;
@ -1237,9 +1237,9 @@ public abstract class Trade extends XmrWalletBase implements Tradable, Model {
log.info("Done importing multisig hexes for {} {} in {} ms, count={}", getClass().getSimpleName(), getShortId(), System.currentTimeMillis() - startTime, multisigHexes.size());
}
private void handleWalletError(Exception e, MoneroRpcConnection sourceConnection) {
private void handleWalletError(Exception e, MoneroRpcConnection sourceConnection, int numAttempts) {
if (HavenoUtils.isUnresponsive(e)) forceCloseWallet(); // wallet can be stuck a while
if (!HavenoUtils.isIllegal(e) && xmrConnectionService.isConnected()) requestSwitchToNextBestConnection(sourceConnection);
if (numAttempts % TradeProtocol.REQUEST_CONNECTION_SWITCH_EVERY_NUM_ATTEMPTS == 0 && !HavenoUtils.isIllegal(e) && xmrConnectionService.isConnected()) requestSwitchToNextBestConnection(sourceConnection); // request connection switch every n attempts
getWallet(); // re-open wallet
}
@ -1275,7 +1275,7 @@ public abstract class Trade extends XmrWalletBase implements Tradable, Model {
} catch (IllegalArgumentException | IllegalStateException e) {
throw e;
} catch (Exception e) {
handleWalletError(e, sourceConnection);
handleWalletError(e, sourceConnection, i + 1);
doPollWallet();
if (isPayoutPublished()) break;
log.warn("Failed to create payout tx, tradeId={}, attempt={}/{}, error={}", getShortId(), i + 1, TradeProtocol.MAX_ATTEMPTS, e.getMessage());
@ -1337,7 +1337,7 @@ public abstract class Trade extends XmrWalletBase implements Tradable, Model {
throw e;
} catch (Exception e) {
if (e.getMessage().contains("not possible")) throw new IllegalArgumentException("Loser payout is too small to cover the mining fee");
handleWalletError(e, sourceConnection);
handleWalletError(e, sourceConnection, i + 1);
doPollWallet();
if (isPayoutPublished()) break;
log.warn("Failed to create dispute payout tx, tradeId={}, attempt={}/{}, error={}", getShortId(), i + 1, TradeProtocol.MAX_ATTEMPTS, e.getMessage());
@ -1368,7 +1368,7 @@ public abstract class Trade extends XmrWalletBase implements Tradable, Model {
} catch (IllegalArgumentException | IllegalStateException e) {
throw e;
} catch (Exception e) {
handleWalletError(e, sourceConnection);
handleWalletError(e, sourceConnection, i + 1);
doPollWallet();
if (isPayoutPublished()) break;
log.warn("Failed to process payout tx, tradeId={}, attempt={}/{}, error={}", getShortId(), i + 1, TradeProtocol.MAX_ATTEMPTS, e.getMessage(), e);

View file

@ -101,6 +101,7 @@ public abstract class TradeProtocol implements DecryptedDirectMessageListener, D
public static final int TRADE_STEP_TIMEOUT_SECONDS = Config.baseCurrencyNetwork().isTestnet() ? 60 : 180;
private static final String TIMEOUT_REACHED = "Timeout reached.";
public static final int MAX_ATTEMPTS = 5; // max attempts to create txs and other wallet functions
public static final int REQUEST_CONNECTION_SWITCH_EVERY_NUM_ATTEMPTS = 2; // request connection switch on even attempts
public static final long REPROCESS_DELAY_MS = 5000;
public static final String LOG_HIGHLIGHT = ""; // TODO: how to highlight some logs with cyan? ("\u001B[36m")? coloring works in the terminal but prints character literals to .log files

View file

@ -98,7 +98,7 @@ public class MakerRecreateReserveTx extends TradeTask {
throw e;
} catch (Exception e) {
log.warn("Error creating reserve tx, tradeId={}, attempt={}/{}, error={}", trade.getShortId(), i + 1, TradeProtocol.MAX_ATTEMPTS, e.getMessage());
trade.getXmrWalletService().handleWalletError(e, sourceConnection);
trade.getXmrWalletService().handleWalletError(e, sourceConnection, i + 1);
if (isTimedOut()) throw new RuntimeException("Trade protocol has timed out while creating reserve tx, tradeId=" + trade.getShortId());
if (i == TradeProtocol.MAX_ATTEMPTS - 1) throw e;
HavenoUtils.waitFor(TradeProtocol.REPROCESS_DELAY_MS); // wait before retrying

View file

@ -113,7 +113,7 @@ public class MaybeSendSignContractRequest extends TradeTask {
depositTx = trade.getXmrWalletService().createDepositTx(trade, reserveExactAmount, subaddressIndex);
} catch (Exception e) {
log.warn("Error creating deposit tx, tradeId={}, attempt={}/{}, error={}", trade.getShortId(), i + 1, TradeProtocol.MAX_ATTEMPTS, e.getMessage());
trade.getXmrWalletService().handleWalletError(e, sourceConnection);
trade.getXmrWalletService().handleWalletError(e, sourceConnection, i + 1);
if (isTimedOut()) throw new RuntimeException("Trade protocol has timed out while creating deposit tx, tradeId=" + trade.getShortId());
if (i == TradeProtocol.MAX_ATTEMPTS - 1) throw e;
HavenoUtils.waitFor(TradeProtocol.REPROCESS_DELAY_MS); // wait before retrying

View file

@ -75,7 +75,7 @@ public class TakerReserveTradeFunds extends TradeTask {
throw e;
} catch (Exception e) {
log.warn("Error creating reserve tx, tradeId={}, attempt={}/{}, error={}", trade.getShortId(), i + 1, TradeProtocol.MAX_ATTEMPTS, e.getMessage());
trade.getXmrWalletService().handleWalletError(e, sourceConnection);
trade.getXmrWalletService().handleWalletError(e, sourceConnection, i + 1);
if (isTimedOut()) throw new RuntimeException("Trade protocol has timed out while creating reserve tx, tradeId=" + trade.getShortId());
if (i == TradeProtocol.MAX_ATTEMPTS - 1) throw e;
HavenoUtils.waitFor(TradeProtocol.REPROCESS_DELAY_MS); // wait before retrying

View file

@ -37,6 +37,7 @@ import haveno.core.trade.HavenoUtils;
import haveno.core.trade.MakerTrade;
import haveno.core.trade.Trade;
import haveno.core.trade.TradeManager;
import haveno.core.trade.protocol.TradeProtocol;
import haveno.core.user.Preferences;
import haveno.core.user.User;
import haveno.core.xmr.listeners.XmrBalanceListener;
@ -1944,9 +1945,9 @@ public class XmrWalletService extends XmrWalletBase {
doMaybeInitMainWallet(true, MAX_SYNC_ATTEMPTS);
}
public void handleWalletError(Exception e, MoneroRpcConnection sourceConnection) {
public void handleWalletError(Exception e, MoneroRpcConnection sourceConnection, int numAttempts) {
if (HavenoUtils.isUnresponsive(e)) forceCloseMainWallet(); // wallet can be stuck a while
requestSwitchToNextBestConnection(sourceConnection);
if (numAttempts % TradeProtocol.REQUEST_CONNECTION_SWITCH_EVERY_NUM_ATTEMPTS == 0) requestSwitchToNextBestConnection(sourceConnection); // request connection switch every n attempts
if (wallet == null) doMaybeInitMainWallet(true, MAX_SYNC_ATTEMPTS);
}