avoid redundant wallet backups, max 10 backups (#505)

Co-authored-by: woodser <woodser@protonmail.com>
This commit is contained in:
napoly 2022-12-18 16:15:55 +01:00 committed by GitHub
parent 217e7e03a2
commit 1adf7bd73f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 22 additions and 18 deletions

View file

@ -85,6 +85,7 @@ public class XmrWalletService {
private static final String MONERO_MULTISIG_WALLET_PREFIX = "xmr_multisig_trade_"; private static final String MONERO_MULTISIG_WALLET_PREFIX = "xmr_multisig_trade_";
public static final double MINER_FEE_TOLERANCE = 0.25; // miner fee must be within percent of estimated fee public static final double MINER_FEE_TOLERANCE = 0.25; // miner fee must be within percent of estimated fee
private static final double SECURITY_DEPOSIT_TOLERANCE = Config.baseCurrencyNetwork() == BaseCurrencyNetwork.XMR_LOCAL ? 0.25 : 0.05; // security deposit absorbs miner fee up to percent private static final double SECURITY_DEPOSIT_TOLERANCE = Config.baseCurrencyNetwork() == BaseCurrencyNetwork.XMR_LOCAL ? 0.25 : 0.05; // security deposit absorbs miner fee up to percent
private static final int NUM_MAX_BACKUP_WALLETS = 10;
private final CoreAccountService accountService; private final CoreAccountService accountService;
private final CoreMoneroConnectionsService connectionsService; private final CoreMoneroConnectionsService connectionsService;
@ -166,8 +167,12 @@ public class XmrWalletService {
return wallet; return wallet;
} }
public void saveWallet() { public void saveMainWallet() {
saveWallet(getWallet()); saveMainWallet(true);
}
public void saveMainWallet(boolean backup) {
saveWallet(getWallet(), backup);
} }
public boolean isWalletReady() { public boolean isWalletReady() {
@ -241,13 +246,13 @@ public class XmrWalletService {
return; return;
} }
if (!multisigWallets.containsKey(tradeId)) throw new RuntimeException("Multisig wallet to save was not previously opened for trade " + tradeId); if (!multisigWallets.containsKey(tradeId)) throw new RuntimeException("Multisig wallet to save was not previously opened for trade " + tradeId);
saveWallet(multisigWallets.get(tradeId)); saveWallet(multisigWallets.get(tradeId), true);
} }
} }
private void saveWallet(MoneroWallet wallet) { private void saveWallet(MoneroWallet wallet, boolean backup) {
wallet.save(); wallet.save();
backupWallet(wallet.getPath()); if (backup) backupWallet(wallet.getPath());
} }
public void closeMultisigWallet(String tradeId) { public void closeMultisigWallet(String tradeId) {
@ -340,7 +345,7 @@ public class XmrWalletService {
// freeze inputs // freeze inputs
for (MoneroOutput input : tradeTx.getInputs()) wallet.freezeOutput(input.getKeyImage().getHex()); for (MoneroOutput input : tradeTx.getInputs()) wallet.freezeOutput(input.getKeyImage().getHex());
wallet.save(); saveMainWallet();
return tradeTx; return tradeTx;
} }
} }
@ -516,7 +521,7 @@ public class XmrWalletService {
wallet.sync(); // blocking wallet.sync(); // blocking
wallet.startSyncing(connectionsService.getDefaultRefreshPeriodMs()); // start syncing wallet in background wallet.startSyncing(connectionsService.getDefaultRefreshPeriodMs()); // start syncing wallet in background
connectionsService.doneDownload(); // TODO: using this to signify both daemon and wallet synced, refactor sync handling of both connectionsService.doneDownload(); // TODO: using this to signify both daemon and wallet synced, refactor sync handling of both
saveWallet(wallet); saveMainWallet(false); // skip backup on open
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
@ -653,7 +658,7 @@ public class XmrWalletService {
tasks.add(() -> { tasks.add(() -> {
try { try {
wallet.changePassword(oldPassword, newPassword); wallet.changePassword(oldPassword, newPassword);
saveWallet(wallet); saveMainWallet();
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
throw e; throw e;
@ -667,7 +672,7 @@ public class XmrWalletService {
MoneroWallet multisigWallet = getMultisigWallet(tradeId); // TODO (woodser): this unnecessarily connects and syncs unopen wallets and leaves open MoneroWallet multisigWallet = getMultisigWallet(tradeId); // TODO (woodser): this unnecessarily connects and syncs unopen wallets and leaves open
if (multisigWallet == null) return; if (multisigWallet == null) return;
multisigWallet.changePassword(oldPassword, newPassword); multisigWallet.changePassword(oldPassword, newPassword);
saveWallet(multisigWallet); saveMultisigWallet(tradeId);
}); });
} }
@ -726,9 +731,9 @@ public class XmrWalletService {
} }
private void backupWallet(String walletName) { private void backupWallet(String walletName) {
FileUtil.rollingBackup(walletDir, walletName, 20); FileUtil.rollingBackup(walletDir, walletName, NUM_MAX_BACKUP_WALLETS);
FileUtil.rollingBackup(walletDir, walletName + ".keys", 20); FileUtil.rollingBackup(walletDir, walletName + ".keys", NUM_MAX_BACKUP_WALLETS);
FileUtil.rollingBackup(walletDir, walletName + ".address.txt", 20); FileUtil.rollingBackup(walletDir, walletName + ".address.txt", NUM_MAX_BACKUP_WALLETS);
} }
private void deleteBackupWallets(String walletName) { private void deleteBackupWallets(String walletName) {

View file

@ -568,7 +568,7 @@ public class OpenOfferManager implements PeerManager.Listener, DecryptedDirectMe
Offer offer = openOffer.getOffer(); Offer offer = openOffer.getOffer();
if (offer.getOfferPayload().getReserveTxKeyImages() != null) { if (offer.getOfferPayload().getReserveTxKeyImages() != null) {
for (String frozenKeyImage : offer.getOfferPayload().getReserveTxKeyImages()) xmrWalletService.getWallet().thawOutput(frozenKeyImage); for (String frozenKeyImage : offer.getOfferPayload().getReserveTxKeyImages()) xmrWalletService.getWallet().thawOutput(frozenKeyImage);
xmrWalletService.getWallet().save(); xmrWalletService.saveMainWallet();
} }
offer.setState(Offer.State.REMOVED); offer.setState(Offer.State.REMOVED);
openOffer.setState(OpenOffer.State.CANCELED); openOffer.setState(OpenOffer.State.CANCELED);

View file

@ -317,7 +317,7 @@ public class TradeManager implements PersistedDataHost, DecryptedDirectMessageLi
log.info("Thawing output which is not reserved for offer or trade: " + unreservedFrozenKeyImage); log.info("Thawing output which is not reserved for offer or trade: " + unreservedFrozenKeyImage);
xmrWalletService.getWallet().thawOutput(unreservedFrozenKeyImage); xmrWalletService.getWallet().thawOutput(unreservedFrozenKeyImage);
} }
xmrWalletService.getWallet().save(); if (!frozenKeyImages.isEmpty()) xmrWalletService.saveMainWallet();
} }
public TradeProtocol getTradeProtocol(Trade trade) { public TradeProtocol getTradeProtocol(Trade trade) {
@ -1071,7 +1071,7 @@ public class TradeManager implements PersistedDataHost, DecryptedDirectMessageLi
// unreserve key images // unreserve key images
if (trade instanceof TakerTrade && trade.getSelf().getReserveTxKeyImages() != null) { if (trade instanceof TakerTrade && trade.getSelf().getReserveTxKeyImages() != null) {
for (String keyImage : trade.getSelf().getReserveTxKeyImages()) xmrWalletService.getWallet().thawOutput(keyImage); for (String keyImage : trade.getSelf().getReserveTxKeyImages()) xmrWalletService.getWallet().thawOutput(keyImage);
xmrWalletService.getWallet().save(); xmrWalletService.saveMainWallet();
} }
// remove trade // remove trade

View file

@ -135,7 +135,6 @@ public class MaybeSendSignContractRequest extends TradeTask {
private void completeAux() { private void completeAux() {
trade.setState(State.CONTRACT_SIGNATURE_REQUESTED); trade.setState(State.CONTRACT_SIGNATURE_REQUESTED);
processModel.getTradeManager().requestPersistence(); processModel.getTradeManager().requestPersistence();
processModel.getXmrWalletService().saveWallet();
complete(); complete();
} }
} }

View file

@ -122,7 +122,7 @@ public class ProcessInitMultisigRequest extends TradeTask {
log.info("Importing exchanged multisig hex for trade {}", trade.getId()); log.info("Importing exchanged multisig hex for trade {}", trade.getId());
MoneroMultisigInitResult result = multisigWallet.exchangeMultisigKeys(Arrays.asList(peers[0].getExchangedMultisigHex(), peers[1].getExchangedMultisigHex()), xmrWalletService.getWalletPassword()); MoneroMultisigInitResult result = multisigWallet.exchangeMultisigKeys(Arrays.asList(peers[0].getExchangedMultisigHex(), peers[1].getExchangedMultisigHex()), xmrWalletService.getWalletPassword());
processModel.setMultisigAddress(result.getAddress()); processModel.setMultisigAddress(result.getAddress());
processModel.getProvider().getXmrWalletService().saveMultisigWallet(trade.getId()); // save multisig wallet once it's created trade.saveWallet(); // save multisig wallet on completion
trade.setStateIfValidTransitionTo(Trade.State.MULTISIG_COMPLETED); trade.setStateIfValidTransitionTo(Trade.State.MULTISIG_COMPLETED);
} }