recover from deleted wallet cache

This commit is contained in:
woodser 2024-05-03 17:46:46 -04:00
parent b50238a805
commit ceff34672d
3 changed files with 52 additions and 12 deletions

View File

@ -895,6 +895,9 @@ public class OpenOfferManager implements PeerManager.Listener, DecryptedDirectMe
// if not found, create tx to split exact output
if (splitOutputTx == null) {
if (openOffer.getSplitOutputTxHash() != null) {
log.warn("Split output tx not found for offer {}", openOffer.getId());
}
splitOrSchedule(openOffers, openOffer, amountNeeded);
} else if (!splitOutputTx.isLocked()) {
@ -1026,7 +1029,7 @@ public class OpenOfferManager implements PeerManager.Listener, DecryptedDirectMe
// handle sufficient available balance to split output
boolean sufficientAvailableBalance = xmrWalletService.getAvailableBalance().compareTo(offerReserveAmount) >= 0;
if (sufficientAvailableBalance) {
if (sufficientAvailableBalance && openOffer.getSplitOutputTxHash() == null) {
log.info("Splitting and scheduling outputs for offer {}", openOffer.getShortId());
splitAndSchedule(openOffer);
} else if (openOffer.getScheduledTxHashes() == null) {
@ -1053,7 +1056,7 @@ public class OpenOfferManager implements PeerManager.Listener, DecryptedDirectMe
break;
} catch (Exception e) {
log.warn("Error creating split output tx to fund offer {} at subaddress {}, attempt={}/{}, error={}", openOffer.getShortId(), entry.getSubaddressIndex(), i + 1, TradeProtocol.MAX_ATTEMPTS, e.getMessage());
if (i == TradeProtocol.MAX_ATTEMPTS - 1) throw e;
if (stopped || i == TradeProtocol.MAX_ATTEMPTS - 1) throw e;
HavenoUtils.waitFor(TradeProtocol.REPROCESS_DELAY_MS); // wait before retrying
}
}

View File

@ -482,8 +482,8 @@ public class TradeManager implements PersistedDataHost, DecryptedDirectMessageLi
maybeRemoveTradeOnError(trade);
}
// thaw unreserved outputs
xmrWalletService.thawUnreservedOutputs();
// freeze or thaw outputs
xmrWalletService.fixReservedOutputs();
// reset any available funded address entries
if (isShutDownStarted) return;

View File

@ -459,35 +459,72 @@ public class XmrWalletService {
public MoneroTxWallet createTx(MoneroTxConfig txConfig) {
synchronized (WALLET_LOCK) {
synchronized (HavenoUtils.getWalletFunctionLock()) {
return wallet.createTx(txConfig);
MoneroTxWallet tx = wallet.createTx(txConfig);
if (Boolean.TRUE.equals(txConfig.getRelay())) {
cachedTxs.addFirst(tx);
cacheWalletInfo();
requestSaveMainWallet();
}
return tx;
}
}
}
public MoneroTxWallet createTx(List<MoneroDestination> destinations) {
MoneroTxWallet tx = createTx(new MoneroTxConfig().setAccountIndex(0).setDestinations(destinations).setRelay(false).setCanSplit(false));;
MoneroTxWallet tx = createTx(new MoneroTxConfig().setAccountIndex(0).setDestinations(destinations).setRelay(false).setCanSplit(false));
//printTxs("XmrWalletService.createTx", tx);
requestSaveMainWallet();
return tx;
}
/**
* Thaw all outputs not reserved for a trade.
* Freeze reserved outputs and thaw unreserved outputs.
*/
public void thawUnreservedOutputs() {
public void fixReservedOutputs() {
synchronized (WALLET_LOCK) {
// collect reserved outputs
Set<String> reservedKeyImages = new HashSet<String>();
for (Trade trade : tradeManager.getObservableList()) {
for (Trade trade : tradeManager.getOpenTrades()) {
if (trade.getSelf().getReserveTxKeyImages() == null) continue;
reservedKeyImages.addAll(trade.getSelf().getReserveTxKeyImages());
}
for (OpenOffer openOffer : tradeManager.getOpenOfferManager().getObservableList()) {
for (OpenOffer openOffer : tradeManager.getOpenOfferManager().getOpenOffers()) {
if (openOffer.getOffer().getOfferPayload().getReserveTxKeyImages() == null) continue;
reservedKeyImages.addAll(openOffer.getOffer().getOfferPayload().getReserveTxKeyImages());
}
freezeReservedOutputs(reservedKeyImages);
thawUnreservedOutputs(reservedKeyImages);
}
}
private void freezeReservedOutputs(Set<String> reservedKeyImages) {
synchronized (WALLET_LOCK) {
// ensure wallet is open
if (wallet == null) {
log.warn("Cannot freeze reserved outputs because wallet not open");
return;
}
// freeze reserved outputs
Set<String> reservedUnfrozenKeyImages = getOutputs(new MoneroOutputQuery()
.setIsFrozen(false)
.setIsSpent(false))
.stream()
.map(output -> output.getKeyImage().getHex())
.collect(Collectors.toSet());
reservedUnfrozenKeyImages.retainAll(reservedKeyImages);
if (!reservedUnfrozenKeyImages.isEmpty()) {
log.warn("Freezing unfrozen outputs which are reserved for offer or trade: " + reservedUnfrozenKeyImages);
freezeOutputs(reservedUnfrozenKeyImages);
}
}
}
private void thawUnreservedOutputs(Set<String> reservedKeyImages) {
synchronized (WALLET_LOCK) {
// ensure wallet is open
if (wallet == null) {
log.warn("Cannot thaw unreserved outputs because wallet not open");
@ -503,7 +540,7 @@ public class XmrWalletService {
.collect(Collectors.toSet());
unreservedFrozenKeyImages.removeAll(reservedKeyImages);
if (!unreservedFrozenKeyImages.isEmpty()) {
log.warn("Thawing outputs which are not reserved for offer or trade: " + unreservedFrozenKeyImages);
log.warn("Thawing frozen outputs which are not reserved for offer or trade: " + unreservedFrozenKeyImages);
thawOutputs(unreservedFrozenKeyImages);
}
}