mirror of
https://github.com/haveno-dex/haveno.git
synced 2025-12-16 16:24:29 -05:00
bug fixes to revert deposit and payout tx state when invalidated
This commit is contained in:
parent
8867e9eb3b
commit
420e3f3887
1 changed files with 25 additions and 18 deletions
|
|
@ -159,7 +159,7 @@ public abstract class Trade extends XmrWalletBase implements Tradable, Model {
|
||||||
public static final long POLL_WALLET_NORMALLY_DEFAULT_PERIOD_MS = 120000; // 2 minutes
|
public static final long POLL_WALLET_NORMALLY_DEFAULT_PERIOD_MS = 120000; // 2 minutes
|
||||||
private static final long IDLE_SYNC_PERIOD_MS = Config.baseCurrencyNetwork().isTestnet() ? 60000 : 28 * 60 * 1000; // 28 minutes (monero's default connection timeout is 30 minutes on a local connection, so beyond this the wallets will disconnect)
|
private static final long IDLE_SYNC_PERIOD_MS = Config.baseCurrencyNetwork().isTestnet() ? 60000 : 28 * 60 * 1000; // 28 minutes (monero's default connection timeout is 30 minutes on a local connection, so beyond this the wallets will disconnect)
|
||||||
private static final long MAX_REPROCESS_DELAY_SECONDS = 7200; // max delay to reprocess messages (once per 2 hours)
|
private static final long MAX_REPROCESS_DELAY_SECONDS = 7200; // max delay to reprocess messages (once per 2 hours)
|
||||||
private static final long REVERT_AFTER_NUM_CONFIRMATIONS = 3;
|
private static final long REVERT_AFTER_NUM_CONFIRMATIONS = 2;
|
||||||
protected final Object pollLock = new Object();
|
protected final Object pollLock = new Object();
|
||||||
private final Object removeTradeOnErrorLock = new Object();
|
private final Object removeTradeOnErrorLock = new Object();
|
||||||
protected static final Object importMultisigLock = new Object();
|
protected static final Object importMultisigLock = new Object();
|
||||||
|
|
@ -171,8 +171,8 @@ public abstract class Trade extends XmrWalletBase implements Tradable, Model {
|
||||||
public BooleanProperty wasWalletPolledProperty = new SimpleBooleanProperty(false);
|
public BooleanProperty wasWalletPolledProperty = new SimpleBooleanProperty(false);
|
||||||
public BooleanProperty wasWalletSyncedAndPolledProperty = new SimpleBooleanProperty(false);
|
public BooleanProperty wasWalletSyncedAndPolledProperty = new SimpleBooleanProperty(false);
|
||||||
private static final long MISSING_TXS_DELAY_MS = Config.baseCurrencyNetwork().isTestnet() ? 5000 : 30000;
|
private static final long MISSING_TXS_DELAY_MS = Config.baseCurrencyNetwork().isTestnet() ? 5000 : 30000;
|
||||||
private Long lastDepositTxMissingHeight; // height when we last saw missing deposit txs (to wait for a confirmation before reverting state)
|
private Long firstDepositTxMissingHeight; // height when we first saw missing deposit txs (to wait for a confirmation before reverting state)
|
||||||
private Long lastPayoutTxMissingHeight; // height when we last saw missing payout tx (to wait for a confirmation before reverting state)
|
private Long firstPayoutTxMissingHeight; // height when we first saw missing payout tx (to wait for a confirmation before reverting state)
|
||||||
private boolean skipNextPollLoop = false;
|
private boolean skipNextPollLoop = false;
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
@ -3433,21 +3433,21 @@ public abstract class Trade extends XmrWalletBase implements Tradable, Model {
|
||||||
// revert deposit state if necessary
|
// revert deposit state if necessary
|
||||||
State depositsState = getDepositsState(makerDepositTx, takerDepositTx);
|
State depositsState = getDepositsState(makerDepositTx, takerDepositTx);
|
||||||
State minDepositsState = isPaymentSent() ? State.DEPOSIT_TXS_UNLOCKED_IN_BLOCKCHAIN : getState();
|
State minDepositsState = isPaymentSent() ? State.DEPOSIT_TXS_UNLOCKED_IN_BLOCKCHAIN : getState();
|
||||||
if (poolChecked && depositsState.ordinal() < minDepositsState.ordinal()) {
|
if (depositsState.ordinal() >= minDepositsState.ordinal()) {
|
||||||
|
firstDepositTxMissingHeight = null;
|
||||||
|
} else if (poolChecked) {
|
||||||
|
|
||||||
// skip reverting state until next confirmation // TODO: sometimes txs are missing from the wallet and reappear without reorg
|
// skip reverting state until next confirmation // TODO: sometimes txs are missing from the wallet and reappear without reorg
|
||||||
if (lastDepositTxMissingHeight != null && walletHeight.get() > lastDepositTxMissingHeight + REVERT_AFTER_NUM_CONFIRMATIONS - 1) {
|
if (firstDepositTxMissingHeight != null && walletHeight.get() > firstDepositTxMissingHeight + REVERT_AFTER_NUM_CONFIRMATIONS - 1) {
|
||||||
log.warn("Reverting deposits state from {} to {} for {} {}. Possible reorg?", minDepositsState, depositsState, getClass().getSimpleName(), getShortId());
|
log.warn("Reverting deposits state from {} to {} for {} {}. Possible reorg?", minDepositsState, depositsState, getClass().getSimpleName(), getShortId());
|
||||||
getMaker().setDepositTx(makerDepositTx);
|
getMaker().setDepositTx(makerDepositTx);
|
||||||
getTaker().setDepositTx(takerDepositTx);
|
getTaker().setDepositTx(takerDepositTx);
|
||||||
if (depositsState == State.ARBITRATOR_PUBLISHED_DEPOSIT_TXS) setErrorMessage("Deposit transactions are missing for trade " + getShortId() + ". This can happen after a blockchain reorganization.\n\nIf the issue continues, you can contact support or mark the trade as failed.");
|
if (depositsState == State.ARBITRATOR_PUBLISHED_DEPOSIT_TXS) setErrorMessage("Deposit transactions are missing for trade " + getShortId() + ". This can happen after a blockchain reorganization.\n\nIf the issue continues, you can contact support or mark the trade as failed.");
|
||||||
if (!isPaymentSent()) setState(depositsState); // only revert state if payment not sent
|
if (!isPaymentSent()) setState(depositsState); // only revert state if payment not sent
|
||||||
} else {
|
} else if (firstDepositTxMissingHeight == null) {
|
||||||
if (lastDepositTxMissingHeight == null) log.warn("Missing deposit txs for {} {} at height {}. Waiting {} confirmation before reverting state", getClass().getSimpleName(), getShortId(), lastDepositTxMissingHeight, REVERT_AFTER_NUM_CONFIRMATIONS);
|
log.warn("Missing deposit txs for {} {} at height {}. Waiting {} confirmation before reverting state", getClass().getSimpleName(), getShortId(), walletHeight.get(), REVERT_AFTER_NUM_CONFIRMATIONS);
|
||||||
lastDepositTxMissingHeight = walletHeight.get();
|
firstDepositTxMissingHeight = walletHeight.get();
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
lastDepositTxMissingHeight = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// announce deposits update
|
// announce deposits update
|
||||||
|
|
@ -3472,12 +3472,16 @@ public abstract class Trade extends XmrWalletBase implements Tradable, Model {
|
||||||
}
|
}
|
||||||
|
|
||||||
// set payout state
|
// set payout state
|
||||||
if (payoutTx != null) setPayoutTx(payoutTx);
|
if (payoutTx != null) {
|
||||||
else if (hasPayoutTx) setPayoutState(PayoutState.PAYOUT_PUBLISHED);
|
firstPayoutTxMissingHeight = null;
|
||||||
else if (poolChecked && isPayoutPublished()) { // payout tx seen then lost (e.g. reorg)
|
setPayoutTx(payoutTx);
|
||||||
|
} else if (hasPayoutTx) {
|
||||||
|
firstPayoutTxMissingHeight = null;
|
||||||
|
setPayoutState(PayoutState.PAYOUT_PUBLISHED);
|
||||||
|
} else if (poolChecked && isPayoutPublished()) { // payout tx seen then lost (e.g. reorg)
|
||||||
|
|
||||||
// skip reverting state until confirmations
|
// skip reverting state until confirmations
|
||||||
if (lastPayoutTxMissingHeight != null && walletHeight.get() > lastPayoutTxMissingHeight + REVERT_AFTER_NUM_CONFIRMATIONS - 1) {
|
if (firstPayoutTxMissingHeight != null && walletHeight.get() > firstPayoutTxMissingHeight + REVERT_AFTER_NUM_CONFIRMATIONS - 1) {
|
||||||
|
|
||||||
// reset payment received and dispute closed messages
|
// reset payment received and dispute closed messages
|
||||||
for (TradePeer peer : getAllPeers()) {
|
for (TradePeer peer : getAllPeers()) {
|
||||||
|
|
@ -3502,9 +3506,9 @@ public abstract class Trade extends XmrWalletBase implements Tradable, Model {
|
||||||
|
|
||||||
// move trade back to pending if marked completed
|
// move trade back to pending if marked completed
|
||||||
if (isCompleted()) processModel.getTradeManager().onMoveClosedTradeToPendingTrades(this);
|
if (isCompleted()) processModel.getTradeManager().onMoveClosedTradeToPendingTrades(this);
|
||||||
} else {
|
} else if (firstPayoutTxMissingHeight == null){
|
||||||
if (lastPayoutTxMissingHeight == null) log.warn("Missing payout tx for {} {} at height {}. Waiting {} confirmations before reverting state", getClass().getSimpleName(), getShortId(), lastPayoutTxMissingHeight, REVERT_AFTER_NUM_CONFIRMATIONS);
|
log.warn("Missing payout tx for {} {} at height {}. Waiting {} confirmations before reverting state", getClass().getSimpleName(), getShortId(), walletHeight.get(), REVERT_AFTER_NUM_CONFIRMATIONS);
|
||||||
lastPayoutTxMissingHeight = walletHeight.get();
|
firstPayoutTxMissingHeight = walletHeight.get();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -3907,7 +3911,10 @@ public abstract class Trade extends XmrWalletBase implements Tradable, Model {
|
||||||
// close open offer or reset address entries
|
// close open offer or reset address entries
|
||||||
if (this instanceof MakerTrade) {
|
if (this instanceof MakerTrade) {
|
||||||
processModel.getOpenOfferManager().closeSpentOffer(getOffer());
|
processModel.getOpenOfferManager().closeSpentOffer(getOffer());
|
||||||
HavenoUtils.notificationService.sendTradeNotification(this, Phase.DEPOSITS_PUBLISHED, "Offer Taken", "Your offer " + offer.getId() + " has been accepted"); // TODO (woodser): use language translation
|
|
||||||
|
// TODO: use language translation
|
||||||
|
// TODO: this will send notification if deposits are revertedt to published
|
||||||
|
HavenoUtils.notificationService.sendTradeNotification(this, Phase.DEPOSITS_PUBLISHED, "Offer Taken", "Your offer " + offer.getId() + " has been accepted");
|
||||||
} else {
|
} else {
|
||||||
getXmrWalletService().resetAddressEntriesForOpenOffer(getId());
|
getXmrWalletService().resetAddressEntriesForOpenOffer(getId());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue