mirror of
https://github.com/haveno-dex/haveno.git
synced 2025-04-19 23:36:00 -04:00
improve error handling when clones taken at the same time
This commit is contained in:
parent
c7a3a9740f
commit
cf9a37f295
@ -145,6 +145,7 @@ public abstract class Trade extends XmrWalletBase implements Tradable, Model {
|
||||
private static final long DELETE_AFTER_MS = TradeProtocol.TRADE_STEP_TIMEOUT_SECONDS;
|
||||
private static final int NUM_CONFIRMATIONS_FOR_SCHEDULED_IMPORT = 5;
|
||||
protected final Object pollLock = new Object();
|
||||
private final Object removeTradeOnErrorLock = new Object();
|
||||
protected static final Object importMultisigLock = new Object();
|
||||
private boolean pollInProgress;
|
||||
private boolean restartInProgress;
|
||||
@ -1608,11 +1609,12 @@ public abstract class Trade extends XmrWalletBase implements Tradable, Model {
|
||||
}
|
||||
|
||||
// shut down trade threads
|
||||
isInitialized = false;
|
||||
isShutDown = true;
|
||||
List<Runnable> shutDownThreads = new ArrayList<>();
|
||||
shutDownThreads.add(() -> ThreadUtils.shutDown(getId()));
|
||||
ThreadUtils.awaitTasks(shutDownThreads);
|
||||
stopProtocolTimeout();
|
||||
isInitialized = false;
|
||||
|
||||
// save and close
|
||||
if (wallet != null) {
|
||||
@ -1765,24 +1767,30 @@ public abstract class Trade extends XmrWalletBase implements Tradable, Model {
|
||||
}
|
||||
|
||||
private void removeTradeOnError() {
|
||||
log.warn("removeTradeOnError() trade={}, tradeId={}, state={}", getClass().getSimpleName(), getShortId(), getState());
|
||||
synchronized (removeTradeOnErrorLock) {
|
||||
|
||||
// force close and re-open wallet in case stuck
|
||||
forceCloseWallet();
|
||||
if (isDepositRequested()) getWallet();
|
||||
// skip if already shut down or removed
|
||||
if (isShutDown || !processModel.getTradeManager().hasTrade(getId())) return;
|
||||
log.warn("removeTradeOnError() trade={}, tradeId={}, state={}", getClass().getSimpleName(), getShortId(), getState());
|
||||
|
||||
// shut down trade thread
|
||||
try {
|
||||
ThreadUtils.shutDown(getId(), 1000l);
|
||||
} catch (Exception e) {
|
||||
log.warn("Error shutting down trade thread for {} {}: {}", getClass().getSimpleName(), getId(), e.getMessage());
|
||||
// force close and re-open wallet in case stuck
|
||||
forceCloseWallet();
|
||||
if (isDepositRequested()) getWallet();
|
||||
|
||||
// clear and shut down trade
|
||||
onShutDownStarted();
|
||||
clearAndShutDown();
|
||||
|
||||
// shut down trade thread
|
||||
try {
|
||||
ThreadUtils.shutDown(getId(), 5000l);
|
||||
} catch (Exception e) {
|
||||
log.warn("Error shutting down trade thread for {} {}: {}", getClass().getSimpleName(), getId(), e.getMessage());
|
||||
}
|
||||
|
||||
// unregister trade
|
||||
processModel.getTradeManager().unregisterTrade(this);
|
||||
}
|
||||
|
||||
// clear and shut down trade
|
||||
clearAndShutDown();
|
||||
|
||||
// unregister trade
|
||||
processModel.getTradeManager().unregisterTrade(this);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -1824,6 +1832,13 @@ public abstract class Trade extends XmrWalletBase implements Tradable, Model {
|
||||
getProtocol().startTimeout(TradeProtocol.TRADE_STEP_TIMEOUT_SECONDS);
|
||||
}
|
||||
|
||||
public void stopProtocolTimeout() {
|
||||
if (!isInitialized) return;
|
||||
TradeProtocol protocol = getProtocol();
|
||||
if (protocol == null) return;
|
||||
protocol.stopTimeout();
|
||||
}
|
||||
|
||||
public void setState(State state) {
|
||||
if (isInitialized) {
|
||||
// We don't want to log at startup the setState calls from all persisted trades
|
||||
|
@ -563,9 +563,14 @@ public class TradeManager implements PersistedDataHost, DecryptedDirectMessageLi
|
||||
Optional<OpenOffer> openOfferOptional = openOfferManager.getOpenOffer(request.getOfferId());
|
||||
if (!openOfferOptional.isPresent()) return;
|
||||
OpenOffer openOffer = openOfferOptional.get();
|
||||
if (openOffer.getState() != OpenOffer.State.AVAILABLE) return;
|
||||
Offer offer = openOffer.getOffer();
|
||||
|
||||
// check availability
|
||||
if (openOffer.getState() != OpenOffer.State.AVAILABLE) {
|
||||
log.warn("Ignoring InitTradeRequest to maker because offer is not available, offerId={}, sender={}", request.getOfferId(), sender);
|
||||
return;
|
||||
}
|
||||
|
||||
// validate challenge
|
||||
if (openOffer.getChallenge() != null && !HavenoUtils.getChallengeHash(openOffer.getChallenge()).equals(HavenoUtils.getChallengeHash(request.getChallenge()))) {
|
||||
log.warn("Ignoring InitTradeRequest to maker because challenge is incorrect, tradeId={}, sender={}", request.getOfferId(), sender);
|
||||
@ -980,9 +985,7 @@ public class TradeManager implements PersistedDataHost, DecryptedDirectMessageLi
|
||||
closedTradableManager.add(trade);
|
||||
trade.setCompleted(true);
|
||||
removeTrade(trade, true);
|
||||
|
||||
// TODO The address entry should have been removed already. Check and if its the case remove that.
|
||||
xmrWalletService.swapPayoutAddressEntryToAvailable(trade.getId());
|
||||
xmrWalletService.swapPayoutAddressEntryToAvailable(trade.getId()); // TODO The address entry should have been removed already. Check and if its the case remove that.
|
||||
requestPersistence();
|
||||
}
|
||||
|
||||
@ -990,6 +993,7 @@ public class TradeManager implements PersistedDataHost, DecryptedDirectMessageLi
|
||||
log.warn("Unregistering {} {}", trade.getClass().getSimpleName(), trade.getId());
|
||||
removeTrade(trade, true);
|
||||
removeFailedTrade(trade);
|
||||
xmrWalletService.swapPayoutAddressEntryToAvailable(trade.getId()); // TODO The address entry should have been removed already. Check and if its the case remove that.
|
||||
requestPersistence();
|
||||
}
|
||||
|
||||
@ -1274,11 +1278,15 @@ public class TradeManager implements PersistedDataHost, DecryptedDirectMessageLi
|
||||
return offer.getDirection() == OfferDirection.SELL;
|
||||
}
|
||||
|
||||
// TODO (woodser): make Optional<Trade> versus Trade return types consistent
|
||||
// TODO: make Optional<Trade> versus Trade return types consistent
|
||||
public Trade getTrade(String tradeId) {
|
||||
return getOpenTrade(tradeId).orElseGet(() -> getClosedTrade(tradeId).orElseGet(() -> getFailedTrade(tradeId).orElseGet(() -> null)));
|
||||
}
|
||||
|
||||
public boolean hasTrade(String tradeId) {
|
||||
return getTrade(tradeId) != null;
|
||||
}
|
||||
|
||||
public Optional<Trade> getOpenTrade(String tradeId) {
|
||||
synchronized (tradableList.getList()) {
|
||||
return tradableList.stream().filter(e -> e.getId().equals(tradeId)).findFirst();
|
||||
|
@ -842,7 +842,7 @@ public abstract class TradeProtocol implements DecryptedDirectMessageListener, D
|
||||
}
|
||||
}
|
||||
|
||||
protected synchronized void stopTimeout() {
|
||||
public synchronized void stopTimeout() {
|
||||
synchronized (timeoutTimerLock) {
|
||||
if (timeoutTimer != null) {
|
||||
timeoutTimer.stop();
|
||||
|
@ -346,8 +346,7 @@ public class DepositView extends ActivatableView<VBox, Void> {
|
||||
List<XmrAddressEntry> addressEntries = xmrWalletService.getAddressEntries();
|
||||
List<DepositListItem> items = new ArrayList<>();
|
||||
for (XmrAddressEntry addressEntry : addressEntries) {
|
||||
DepositListItem item = new DepositListItem(addressEntry, xmrWalletService, formatter);
|
||||
if (addressEntry.isTradePayout() && BigInteger.ZERO.equals(item.getBalanceAsBI())) continue; // do not show empty trade payout addresses
|
||||
if (addressEntry.isTradePayout()) continue; // do not show trade payout addresses
|
||||
items.add(new DepositListItem(addressEntry, xmrWalletService, formatter));
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user