mirror of
https://github.com/haveno-dex/haveno.git
synced 2024-11-17 08:17:57 +00:00
don't delete wallet backup if possibly funded
support new trade state: PUBLISH_DEPOSIT_TX_REQUEST_FAILED
This commit is contained in:
parent
a8114e147d
commit
266d129462
6 changed files with 64 additions and 26 deletions
|
@ -278,6 +278,15 @@ public class XmrWalletService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void deleteMultisigWalletBackups(String tradeId) {
|
||||||
|
log.info("{}.deleteMultisigWalletBackups({})", getClass().getSimpleName(), tradeId);
|
||||||
|
initWalletLock(tradeId);
|
||||||
|
synchronized (walletLocks.get(tradeId)) {
|
||||||
|
String walletName = MONERO_MULTISIG_WALLET_PREFIX + tradeId;
|
||||||
|
deleteWalletBackups(walletName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public MoneroTxWallet createTx(List<MoneroDestination> destinations) {
|
public MoneroTxWallet createTx(List<MoneroDestination> destinations) {
|
||||||
try {
|
try {
|
||||||
synchronized (wallet) {
|
synchronized (wallet) {
|
||||||
|
@ -726,7 +735,6 @@ public class XmrWalletService {
|
||||||
if (!new File(path).delete()) throw new RuntimeException("Failed to delete wallet file: " + path);
|
if (!new File(path).delete()) throw new RuntimeException("Failed to delete wallet file: " + path);
|
||||||
if (!new File(path + ".keys").delete()) throw new RuntimeException("Failed to delete wallet file: " + path);
|
if (!new File(path + ".keys").delete()) throw new RuntimeException("Failed to delete wallet file: " + path);
|
||||||
if (!new File(path + ".address.txt").delete()) throw new RuntimeException("Failed to delete wallet file: " + path);
|
if (!new File(path + ".address.txt").delete()) throw new RuntimeException("Failed to delete wallet file: " + path);
|
||||||
deleteBackupWallets(walletName); // TODO: retain backup for some time?
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void closeAllWallets() {
|
private void closeAllWallets() {
|
||||||
|
@ -761,7 +769,7 @@ public class XmrWalletService {
|
||||||
FileUtil.rollingBackup(walletDir, walletName + ".address.txt", NUM_MAX_BACKUP_WALLETS);
|
FileUtil.rollingBackup(walletDir, walletName + ".address.txt", NUM_MAX_BACKUP_WALLETS);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void deleteBackupWallets(String walletName) {
|
private void deleteWalletBackups(String walletName) {
|
||||||
FileUtil.deleteRollingBackup(walletDir, walletName);
|
FileUtil.deleteRollingBackup(walletDir, walletName);
|
||||||
FileUtil.deleteRollingBackup(walletDir, walletName + ".keys");
|
FileUtil.deleteRollingBackup(walletDir, walletName + ".keys");
|
||||||
FileUtil.deleteRollingBackup(walletDir, walletName + ".address.txt");
|
FileUtil.deleteRollingBackup(walletDir, walletName + ".address.txt");
|
||||||
|
|
|
@ -133,6 +133,7 @@ public abstract class Trade implements Tradable, Model {
|
||||||
SENT_PUBLISH_DEPOSIT_TX_REQUEST(Phase.DEPOSIT_REQUESTED),
|
SENT_PUBLISH_DEPOSIT_TX_REQUEST(Phase.DEPOSIT_REQUESTED),
|
||||||
SEND_FAILED_PUBLISH_DEPOSIT_TX_REQUEST(Phase.DEPOSIT_REQUESTED),
|
SEND_FAILED_PUBLISH_DEPOSIT_TX_REQUEST(Phase.DEPOSIT_REQUESTED),
|
||||||
SAW_ARRIVED_PUBLISH_DEPOSIT_TX_REQUEST(Phase.DEPOSIT_REQUESTED),
|
SAW_ARRIVED_PUBLISH_DEPOSIT_TX_REQUEST(Phase.DEPOSIT_REQUESTED),
|
||||||
|
PUBLISH_DEPOSIT_TX_REQUEST_FAILED(Phase.DEPOSIT_REQUESTED),
|
||||||
|
|
||||||
// deposit published
|
// deposit published
|
||||||
ARBITRATOR_PUBLISHED_DEPOSIT_TXS(Phase.DEPOSITS_PUBLISHED),
|
ARBITRATOR_PUBLISHED_DEPOSIT_TXS(Phase.DEPOSITS_PUBLISHED),
|
||||||
|
@ -935,8 +936,24 @@ public abstract class Trade implements Tradable, Model {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void deleteWallet() {
|
public void deleteWallet() {
|
||||||
if (xmrWalletService.multisigWalletExists(getId())) xmrWalletService.deleteMultisigWallet(getId());
|
if (xmrWalletService.multisigWalletExists(getId())) {
|
||||||
else log.warn("Multisig wallet to delete for trade {} does not exist", getId());
|
|
||||||
|
// delete trade wallet unless funded
|
||||||
|
if (isDepositPublished() && !isPayoutUnlocked()) {
|
||||||
|
log.warn("Refusing to delete wallet for {} {} because it could be funded", getClass().getSimpleName(), getId());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
xmrWalletService.deleteMultisigWallet(getId());
|
||||||
|
|
||||||
|
// delete trade wallet backups unless possibly funded
|
||||||
|
boolean possiblyFunded = isDepositRequested() && !isPayoutUnlocked();
|
||||||
|
if (possiblyFunded) {
|
||||||
|
log.warn("Refusing to delete backup wallet for {} {} in the small chance it becomes funded", getClass().getSimpleName(), getId());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.warn("Multisig wallet to delete for trade {} does not exist", getId());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void shutDown() {
|
public void shutDown() {
|
||||||
|
@ -1266,6 +1283,10 @@ public abstract class Trade implements Tradable, Model {
|
||||||
return getState().getPhase().ordinal() >= Phase.DEPOSIT_REQUESTED.ordinal();
|
return getState().getPhase().ordinal() >= Phase.DEPOSIT_REQUESTED.ordinal();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isDepositFailed() {
|
||||||
|
return getState() == Trade.State.PUBLISH_DEPOSIT_TX_REQUEST_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isDepositPublished() {
|
public boolean isDepositPublished() {
|
||||||
return getState().getPhase().ordinal() >= Phase.DEPOSITS_PUBLISHED.ordinal();
|
return getState().getPhase().ordinal() >= Phase.DEPOSITS_PUBLISHED.ordinal();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1078,9 +1078,8 @@ public class TradeManager implements PersistedDataHost, DecryptedDirectMessageLi
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove trade and wallet unless timeout after deposit requested
|
// remove trade and wallet unless deposit requested without nack
|
||||||
boolean isTimeoutError = TradeProtocol.isTimeoutError(trade.getErrorMessage());
|
if (!trade.isDepositRequested() || trade.isDepositFailed()) {
|
||||||
if (!trade.isDepositRequested() || !isTimeoutError) {
|
|
||||||
removeTrade(trade);
|
removeTrade(trade);
|
||||||
if (xmrWalletService.multisigWalletExists(trade.getId())) trade.deleteWallet();
|
if (xmrWalletService.multisigWalletExists(trade.getId())) trade.deleteWallet();
|
||||||
} else {
|
} else {
|
||||||
|
@ -1100,13 +1099,13 @@ public class TradeManager implements PersistedDataHost, DecryptedDirectMessageLi
|
||||||
MoneroTx takerDepositTx = xmrWalletService.getDaemon().getTx(trade.getTaker().getDepositTxHash());
|
MoneroTx takerDepositTx = xmrWalletService.getDaemon().getTx(trade.getTaker().getDepositTxHash());
|
||||||
|
|
||||||
// delete multisig trade wallet if neither deposit tx published
|
// delete multisig trade wallet if neither deposit tx published
|
||||||
if ((makerDepositTx != null && makerDepositTx.isRelayed()) || (takerDepositTx != null && takerDepositTx.isRelayed())) {
|
if (makerDepositTx == null && takerDepositTx == null) {
|
||||||
log.warn("Refusing to delete {} {} after protocol timeout because its wallet might be funded", trade.getClass().getSimpleName(), trade.getId());
|
|
||||||
} else {
|
|
||||||
log.warn("Deleting {} {} after protocol timeout", trade.getClass().getSimpleName(), trade.getId());
|
log.warn("Deleting {} {} after protocol timeout", trade.getClass().getSimpleName(), trade.getId());
|
||||||
removeTrade(trade);
|
removeTrade(trade);
|
||||||
failedTradesManager.removeTrade(trade);
|
failedTradesManager.removeTrade(trade);
|
||||||
if (xmrWalletService.multisigWalletExists(trade.getId())) trade.deleteWallet();
|
if (xmrWalletService.multisigWalletExists(trade.getId())) trade.deleteWallet();
|
||||||
|
} else {
|
||||||
|
log.warn("Refusing to delete {} {} after protocol timeout because its wallet might be funded", trade.getClass().getSimpleName(), trade.getId());
|
||||||
}
|
}
|
||||||
}, 60);
|
}, 60);
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,7 @@ import bisq.core.trade.HavenoUtils;
|
||||||
import bisq.core.trade.SellerTrade;
|
import bisq.core.trade.SellerTrade;
|
||||||
import bisq.core.trade.handlers.TradeResultHandler;
|
import bisq.core.trade.handlers.TradeResultHandler;
|
||||||
import bisq.core.trade.messages.PaymentSentMessage;
|
import bisq.core.trade.messages.PaymentSentMessage;
|
||||||
|
import bisq.core.trade.messages.DepositRequest;
|
||||||
import bisq.core.trade.messages.DepositResponse;
|
import bisq.core.trade.messages.DepositResponse;
|
||||||
import bisq.core.trade.messages.DepositsConfirmedMessage;
|
import bisq.core.trade.messages.DepositsConfirmedMessage;
|
||||||
import bisq.core.trade.messages.InitMultisigRequest;
|
import bisq.core.trade.messages.InitMultisigRequest;
|
||||||
|
@ -549,6 +550,13 @@ public abstract class TradeProtocol implements DecryptedDirectMessageListener, D
|
||||||
String err = "Received AckMessage with error state for " + ackMessage.getSourceMsgClassName() +
|
String err = "Received AckMessage with error state for " + ackMessage.getSourceMsgClassName() +
|
||||||
" from "+ peer + " with tradeId " + trade.getId() + " and errorMessage=" + ackMessage.getErrorMessage();
|
" from "+ peer + " with tradeId " + trade.getId() + " and errorMessage=" + ackMessage.getErrorMessage();
|
||||||
log.warn(err);
|
log.warn(err);
|
||||||
|
|
||||||
|
// set trade state on deposit request nack
|
||||||
|
if (ackMessage.getSourceMsgClassName().equals(DepositRequest.class.getSimpleName())) {
|
||||||
|
trade.setStateIfValidTransitionTo(Trade.State.PUBLISH_DEPOSIT_TX_REQUEST_FAILED);
|
||||||
|
processModel.getTradeManager().requestPersistence();
|
||||||
|
}
|
||||||
|
|
||||||
handleError(err);
|
handleError(err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,6 +47,7 @@ public class ProcessDepositResponse extends TradeTask {
|
||||||
processModel.getTradeManager().requestPersistence();
|
processModel.getTradeManager().requestPersistence();
|
||||||
complete();
|
complete();
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
|
trade.setStateIfValidTransitionTo(Trade.State.PUBLISH_DEPOSIT_TX_REQUEST_FAILED);
|
||||||
failed(t);
|
failed(t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1573,22 +1573,23 @@ message Trade {
|
||||||
SENT_PUBLISH_DEPOSIT_TX_REQUEST = 8;
|
SENT_PUBLISH_DEPOSIT_TX_REQUEST = 8;
|
||||||
SEND_FAILED_PUBLISH_DEPOSIT_TX_REQUEST = 9;
|
SEND_FAILED_PUBLISH_DEPOSIT_TX_REQUEST = 9;
|
||||||
SAW_ARRIVED_PUBLISH_DEPOSIT_TX_REQUEST = 10;
|
SAW_ARRIVED_PUBLISH_DEPOSIT_TX_REQUEST = 10;
|
||||||
ARBITRATOR_PUBLISHED_DEPOSIT_TXS = 11;
|
PUBLISH_DEPOSIT_TX_REQUEST_FAILED = 11;
|
||||||
DEPOSIT_TXS_SEEN_IN_NETWORK = 12;
|
ARBITRATOR_PUBLISHED_DEPOSIT_TXS = 12;
|
||||||
DEPOSIT_TXS_CONFIRMED_IN_BLOCKCHAIN = 13;
|
DEPOSIT_TXS_SEEN_IN_NETWORK = 13;
|
||||||
DEPOSIT_TXS_UNLOCKED_IN_BLOCKCHAIN = 14;
|
DEPOSIT_TXS_CONFIRMED_IN_BLOCKCHAIN = 14;
|
||||||
BUYER_CONFIRMED_IN_UI_PAYMENT_SENT = 15;
|
DEPOSIT_TXS_UNLOCKED_IN_BLOCKCHAIN = 15;
|
||||||
BUYER_SENT_PAYMENT_SENT_MSG = 16;
|
BUYER_CONFIRMED_IN_UI_PAYMENT_SENT = 16;
|
||||||
BUYER_SEND_FAILED_PAYMENT_SENT_MSG = 17;
|
BUYER_SENT_PAYMENT_SENT_MSG = 17;
|
||||||
BUYER_STORED_IN_MAILBOX_PAYMENT_SENT_MSG = 18;
|
BUYER_SEND_FAILED_PAYMENT_SENT_MSG = 18;
|
||||||
BUYER_SAW_ARRIVED_PAYMENT_SENT_MSG = 19;
|
BUYER_STORED_IN_MAILBOX_PAYMENT_SENT_MSG = 19;
|
||||||
SELLER_RECEIVED_PAYMENT_SENT_MSG = 20;
|
BUYER_SAW_ARRIVED_PAYMENT_SENT_MSG = 20;
|
||||||
SELLER_CONFIRMED_IN_UI_PAYMENT_RECEIPT = 21;
|
SELLER_RECEIVED_PAYMENT_SENT_MSG = 21;
|
||||||
SELLER_SENT_PAYMENT_RECEIVED_MSG = 22;
|
SELLER_CONFIRMED_IN_UI_PAYMENT_RECEIPT = 22;
|
||||||
SELLER_SEND_FAILED_PAYMENT_RECEIVED_MSG = 23;
|
SELLER_SENT_PAYMENT_RECEIVED_MSG = 23;
|
||||||
SELLER_STORED_IN_MAILBOX_PAYMENT_RECEIVED_MSG = 24;
|
SELLER_SEND_FAILED_PAYMENT_RECEIVED_MSG = 24;
|
||||||
SELLER_SAW_ARRIVED_PAYMENT_RECEIVED_MSG = 25;
|
SELLER_STORED_IN_MAILBOX_PAYMENT_RECEIVED_MSG = 25;
|
||||||
TRADE_COMPLETED = 26;
|
SELLER_SAW_ARRIVED_PAYMENT_RECEIVED_MSG = 26;
|
||||||
|
TRADE_COMPLETED = 27;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum Phase {
|
enum Phase {
|
||||||
|
|
Loading…
Reference in a new issue