From 8cdd65e7dd9475ea7d54b2277a483f9b9b9274ee Mon Sep 17 00:00:00 2001 From: woodser Date: Sat, 22 Jun 2024 08:35:08 -0400 Subject: [PATCH] install monero bins to local app directories and exclude from backup --- build.gradle | 6 ++++-- .../main/java/haveno/common/util/ZipUtils.java | 17 ++++++++++------- .../haveno/core/api/CoreAccountService.java | 12 +++++++++++- .../haveno/core/api/XmrConnectionService.java | 2 +- .../core/xmr/wallet/XmrWalletService.java | 2 +- 5 files changed, 27 insertions(+), 12 deletions(-) diff --git a/build.gradle b/build.gradle index 92acff7086..6105c30c43 100644 --- a/build.gradle +++ b/build.gradle @@ -532,6 +532,7 @@ configure(project(':core')) { ext.downloadAndVerifyDependencies = { String archiveURL, String archiveSHA256, File destinationArchiveFile -> ext.dependencyDownloadedAndVerified = false + // if archive exists, check to see if its already up to date if (destinationArchiveFile.exists()) { println "Verifying existing archive ${destinationArchiveFile}" @@ -545,14 +546,15 @@ configure(project(':core')) { } } + // download archives println "Downloading ${archiveURL}" ant.get(src: archiveURL, dest: destinationArchiveFile) println 'Download saved to ' + destinationArchiveFile + // verify checksum println 'Verifying checksum for downloaded binary ...' ant.archiveHash = archiveSHA256 - // use a different verifyProperty name from existing verification or it will always fail - ant.checksum(file: destinationArchiveFile, algorithm: 'SHA-256', property: '${archiveHash}', verifyProperty: 'downloadedHashMatches') + ant.checksum(file: destinationArchiveFile, algorithm: 'SHA-256', property: '${archiveHash}', verifyProperty: 'downloadedHashMatches') // use a different verifyProperty name from existing verification or it will always fail if (ant.properties['downloadedHashMatches'] != 'true') { ant.fail('Checksum mismatch: Downloaded archive has a different checksum than expected') } diff --git a/common/src/main/java/haveno/common/util/ZipUtils.java b/common/src/main/java/haveno/common/util/ZipUtils.java index 243ca5ffac..f5a32b69d9 100644 --- a/common/src/main/java/haveno/common/util/ZipUtils.java +++ b/common/src/main/java/haveno/common/util/ZipUtils.java @@ -24,6 +24,7 @@ import java.io.FileOutputStream; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; +import java.util.Collection; import java.util.List; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; @@ -38,13 +39,14 @@ public class ZipUtils { * @param dir The directory to create the zip from. * @param out The stream to write to. */ - public static void zipDirToStream(File dir, OutputStream out, int bufferSize) throws Exception { + public static void zipDirToStream(File dir, OutputStream out, int bufferSize, Collection excludedFiles) throws Exception { // Get all files in directory and subdirectories. - ArrayList fileList = new ArrayList<>(); - getFilesRecursive(dir, fileList); + List fileList = new ArrayList<>(); + getFilesRecursive(dir, fileList, excludedFiles); try (ZipOutputStream zos = new ZipOutputStream(out)) { - for (String filePath : fileList) { + for (File file : fileList) { + String filePath = file.getAbsolutePath(); log.info("Compressing: " + filePath); // Creates a zip entry. @@ -73,14 +75,15 @@ public class ZipUtils { /** * Get files list from the directory recursive to the subdirectory. */ - public static void getFilesRecursive(File directory, List fileList) { + public static void getFilesRecursive(File directory, List fileList, Collection excludedFiles) { File[] files = directory.listFiles(); if (files != null && files.length > 0) { for (File file : files) { + if (excludedFiles != null && excludedFiles.contains(file)) continue; if (file.isFile()) { - fileList.add(file.getAbsolutePath()); + fileList.add(file); } else { - getFilesRecursive(file, fileList); + getFilesRecursive(file, fileList, excludedFiles); } } } diff --git a/core/src/main/java/haveno/core/api/CoreAccountService.java b/core/src/main/java/haveno/core/api/CoreAccountService.java index 0b919bd5ec..2190e0c4f1 100644 --- a/core/src/main/java/haveno/core/api/CoreAccountService.java +++ b/core/src/main/java/haveno/core/api/CoreAccountService.java @@ -27,11 +27,13 @@ import haveno.common.crypto.KeyStorage; import haveno.common.file.FileUtil; import haveno.common.persistence.PersistenceManager; import haveno.common.util.ZipUtils; +import haveno.core.xmr.wallet.XmrWalletService; import java.io.File; import java.io.InputStream; import java.io.PipedInputStream; import java.io.PipedOutputStream; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.function.Consumer; import lombok.Getter; @@ -139,6 +141,7 @@ public class CoreAccountService { } } + // TODO: share common code with BackupView to backup public void backupAccount(int bufferSize, Consumer consume, Consumer error) { if (!accountExists()) throw new IllegalStateException("Cannot backup non existing account"); @@ -149,9 +152,16 @@ public class CoreAccountService { PipedInputStream in = new PipedInputStream(bufferSize); // pipe the serialized account object to stream which will be read by the consumer PipedOutputStream out = new PipedOutputStream(in); log.info("Zipping directory " + dataDir); + + // exclude monero binaries from backup so they're reinstalled with permissions + List excludedFiles = Arrays.asList( + new File(XmrWalletService.MONERO_WALLET_RPC_PATH), + new File(XmrLocalNode.MONEROD_PATH) + ); + new Thread(() -> { try { - ZipUtils.zipDirToStream(dataDir, out, bufferSize); + ZipUtils.zipDirToStream(dataDir, out, bufferSize, excludedFiles); } catch (Exception ex) { error.accept(ex); } diff --git a/core/src/main/java/haveno/core/api/XmrConnectionService.java b/core/src/main/java/haveno/core/api/XmrConnectionService.java index 4830bb9d14..50307f9ced 100644 --- a/core/src/main/java/haveno/core/api/XmrConnectionService.java +++ b/core/src/main/java/haveno/core/api/XmrConnectionService.java @@ -530,7 +530,7 @@ public final class XmrConnectionService { } private void onConnectionChanged(MoneroRpcConnection currentConnection) { - if (isShutDownStarted) return; + if (isShutDownStarted || !accountService.isAccountOpen()) return; if (currentConnection == null) { log.warn("Setting daemon connection to null"); Thread.dumpStack(); 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 21c1d6aa62..21b5d14d04 100644 --- a/core/src/main/java/haveno/core/xmr/wallet/XmrWalletService.java +++ b/core/src/main/java/haveno/core/xmr/wallet/XmrWalletService.java @@ -113,7 +113,7 @@ public class XmrWalletService { // monero configuration public static final int NUM_BLOCKS_UNLOCK = 10; - public static final String MONERO_BINS_DIR = Config.baseCurrencyNetwork().isTestnet() ? System.getProperty("user.dir") + File.separator + ".localnet" : Config.appDataDir().getAbsolutePath(); // .localnet contains monero binaries and wallet files + public static final String MONERO_BINS_DIR = Config.appDataDir().getAbsolutePath(); public static final String MONERO_WALLET_RPC_NAME = Utilities.isWindows() ? "monero-wallet-rpc.exe" : "monero-wallet-rpc"; public static final String MONERO_WALLET_RPC_PATH = MONERO_BINS_DIR + File.separator + MONERO_WALLET_RPC_NAME; public static final double MINER_FEE_TOLERANCE = 0.25; // miner fee must be within percent of estimated fee