diff --git a/core/src/main/java/haveno/core/trade/Trade.java b/core/src/main/java/haveno/core/trade/Trade.java index c5698a61c3..3ab3e33a27 100644 --- a/core/src/main/java/haveno/core/trade/Trade.java +++ b/core/src/main/java/haveno/core/trade/Trade.java @@ -2675,7 +2675,7 @@ else if (hasFailedTx && isPayoutPublished()) { pollInProgress = false; } } - requestSaveWallet(); + saveWalletWithDelay(); } } diff --git a/core/src/main/java/haveno/core/xmr/wallet/XmrWalletBase.java b/core/src/main/java/haveno/core/xmr/wallet/XmrWalletBase.java index 06f2e17112..dd0102aa99 100644 --- a/core/src/main/java/haveno/core/xmr/wallet/XmrWalletBase.java +++ b/core/src/main/java/haveno/core/xmr/wallet/XmrWalletBase.java @@ -30,11 +30,13 @@ public abstract class XmrWalletBase { // constants public static final int SYNC_PROGRESS_TIMEOUT_SECONDS = 120; public static final int DIRECT_SYNC_WITHIN_BLOCKS = 100; + public static final int SAVE_WALLET_DELAY_SECONDS = 300; // inherited protected MoneroWallet wallet; @Getter protected final Object walletLock = new Object(); + protected Timer saveWalletDelayTimer; @Getter protected XmrConnectionService xmrConnectionService; protected boolean wasWalletSynced; @@ -146,8 +148,21 @@ public boolean requestSwitchToNextBestConnection(MoneroRpcConnection sourceConne return false; } + public void saveWalletWithDelay() { + // delay writing to disk to avoid frequent write operations + if (saveWalletDelayTimer == null) { + saveWalletDelayTimer = UserThread.runAfter(() -> { + saveWallet(); + UserThread.execute(() -> saveWalletDelayTimer = null); + }, SAVE_WALLET_DELAY_SECONDS, TimeUnit.MILLISECONDS); + } + } + + // --------------------------------- ABSTRACT ----------------------------- + + public abstract void saveWallet(); + protected abstract void onConnectionChanged(MoneroRpcConnection connection); - // ------------------------------ PRIVATE HELPERS ------------------------- diff --git a/core/src/main/java/haveno/core/xmr/wallet/XmrWalletService.java b/core/src/main/java/haveno/core/xmr/wallet/XmrWalletService.java index 7f7b24ed86..399a623426 100644 --- a/core/src/main/java/haveno/core/xmr/wallet/XmrWalletService.java +++ b/core/src/main/java/haveno/core/xmr/wallet/XmrWalletService.java @@ -245,16 +245,16 @@ public long getWalletCreationDate() { return user.getWalletCreationDate(); } - public void saveMainWallet() { - saveMainWallet(!(Utilities.isWindows() && wallet != null)); + public void saveWallet() { + saveWallet(!(Utilities.isWindows() && wallet != null)); } - public void saveMainWallet(boolean backup) { + public void saveWallet(boolean backup) { saveWallet(getWallet(), backup); } - public void requestSaveMainWallet() { - ThreadUtils.submitToPool(() -> saveMainWallet()); // save wallet off main thread + public void requestSaveWallet() { + ThreadUtils.submitToPool(() -> saveWallet()); // save wallet off main thread } public boolean isWalletAvailable() { @@ -443,7 +443,7 @@ public MoneroTxWallet createTx(MoneroTxConfig txConfig) { if (Boolean.TRUE.equals(txConfig.getRelay())) { cachedTxs.addFirst(tx); cacheWalletInfo(); - requestSaveMainWallet(); + requestSaveWallet(); } return tx; } @@ -453,7 +453,7 @@ public MoneroTxWallet createTx(MoneroTxConfig txConfig) { public String relayTx(String metadata) { synchronized (walletLock) { String txId = wallet.relayTx(metadata); - requestSaveMainWallet(); + requestSaveWallet(); return txId; } } @@ -552,7 +552,7 @@ public void freezeOutputs(Collection keyImages) { // freeze outputs for (String keyImage : unfrozenKeyImages) wallet.freezeOutput(keyImage); cacheWalletInfo(); - requestSaveMainWallet(); + requestSaveWallet(); } } @@ -574,7 +574,7 @@ public void thawOutputs(Collection keyImages) { // thaw outputs for (String keyImage : frozenKeyImages) wallet.thawOutput(keyImage); cacheWalletInfo(); - requestSaveMainWallet(); + requestSaveWallet(); } } @@ -1411,14 +1411,14 @@ private void doMaybeInitMainWallet(boolean sync, int numSyncAttempts) { HavenoUtils.havenoSetup.getWalletInitialized().set(true); // save but skip backup on initialization - saveMainWallet(false); + saveWallet(false); } catch (Exception e) { if (isClosingWallet || isShutDownStarted || HavenoUtils.havenoSetup.getWalletInitialized().get()) return; // ignore if wallet closing, shut down started, or app already initialized log.warn("Error initially syncing main wallet: {}", e.getMessage()); if (numSyncAttempts <= 1) { log.warn("Failed to sync main wallet. Opening app without syncing", numSyncAttempts); HavenoUtils.havenoSetup.getWalletInitialized().set(true); - saveMainWallet(false); + saveWallet(false); // reschedule to init main wallet UserThread.runAfter(() -> { @@ -1796,7 +1796,7 @@ private void changeWalletPasswords(String oldPassword, String newPassword) { tasks.add(() -> { try { wallet.changePassword(oldPassword, newPassword); - saveMainWallet(); + saveWallet(); } catch (Exception e) { log.warn("Error changing main wallet password: " + e.getMessage() + "\n", e); throw e; @@ -1989,7 +1989,7 @@ else if (isWalletConnectedToDaemon()) { if (wallet != null && !isShutDownStarted) { try { cacheWalletInfo(); - requestSaveMainWallet(); + saveWalletWithDelay(); } catch (Exception e) { log.warn("Error caching wallet info: " + e.getMessage() + "\n", e); }