From eda47745ca7b104354e4cc197dd262d45127f6b8 Mon Sep 17 00:00:00 2001 From: Alva Swanson Date: Wed, 26 Oct 2022 11:56:42 +0200 Subject: [PATCH] Electrum: Migrate from CLI to JSON-RPC We generated the config file using the electrum binary in the past which lead to several issues. Now, we manually generate the config file and no longer need to rely on the CLI. --- .../wallets/electrum/ElectrumProcess.java | 20 ++--- .../electrum/ElectrumRegtestProcess.java | 24 +++--- .../wallets/electrum/rpc/cli/ElectrumCli.java | 75 ------------------- .../electrum/rpc/cli/ElectrumCliFacade.java | 59 --------------- .../electrum/ElectrumBundledBinaryTest.java | 52 ------------- .../regtest/electrum/ElectrumRegtest.java | 2 +- 6 files changed, 21 insertions(+), 211 deletions(-) delete mode 100644 wallets/electrum/src/main/java/bisq/wallets/electrum/rpc/cli/ElectrumCli.java delete mode 100644 wallets/electrum/src/main/java/bisq/wallets/electrum/rpc/cli/ElectrumCliFacade.java delete mode 100644 wallets/electrum/src/test/java/bisq/wallets/electrum/ElectrumBundledBinaryTest.java diff --git a/wallets/electrum/src/main/java/bisq/wallets/electrum/ElectrumProcess.java b/wallets/electrum/src/main/java/bisq/wallets/electrum/ElectrumProcess.java index 146140b34d..81c86421d6 100644 --- a/wallets/electrum/src/main/java/bisq/wallets/electrum/ElectrumProcess.java +++ b/wallets/electrum/src/main/java/bisq/wallets/electrum/ElectrumProcess.java @@ -17,13 +17,9 @@ package bisq.wallets.electrum; -import bisq.wallets.core.RpcConfig; -import bisq.wallets.core.rpc.DaemonRpcClient; -import bisq.wallets.core.rpc.RpcClientFactory; import bisq.wallets.electrum.rpc.ElectrumDaemon; import bisq.wallets.electrum.rpc.ElectrumProcessConfig; import bisq.wallets.process.BisqProcess; -import bisq.wallets.process.DaemonProcess; import lombok.Getter; import java.nio.file.Path; @@ -37,8 +33,6 @@ public class ElectrumProcess implements BisqProcess { @Getter private Optional binaryPath = Optional.empty(); private Optional electrumRegtestProcess = Optional.empty(); - @Getter - private Optional electrumDaemon = Optional.empty(); private Optional electrumVersion = Optional.empty(); @@ -54,13 +48,11 @@ public void start() { makeBinaryExecutable(); } createAndStartProcess(); - - electrumDaemon = Optional.of(createElectrumDaemon()); } @Override public void shutdown() { - electrumRegtestProcess.ifPresent(DaemonProcess::shutdown); + electrumRegtestProcess.ifPresent(ElectrumRegtestProcess::invokeStopRpcCall); } private void unpackArchive() { @@ -94,12 +86,6 @@ private void createAndStartProcess() { electrumRegtestProcess = Optional.of(process); } - private ElectrumDaemon createElectrumDaemon() { - RpcConfig rpcConfig = electrumRegtestProcess.orElseThrow().getRpcConfig(); - DaemonRpcClient daemonRpcClient = RpcClientFactory.createDaemonRpcClient(rpcConfig); - return new ElectrumDaemon(daemonRpcClient); - } - public Optional getElectrumVersion() { if (electrumVersion.isPresent()) { return electrumVersion; @@ -131,4 +117,8 @@ private String getBinarySuffix() { public Path getDataDir() { return electrumRegtestProcess.orElseThrow().getDataDir(); } + + public ElectrumDaemon getElectrumDaemon() { + return electrumRegtestProcess.orElseThrow().getElectrumDaemon(); + } } diff --git a/wallets/electrum/src/main/java/bisq/wallets/electrum/ElectrumRegtestProcess.java b/wallets/electrum/src/main/java/bisq/wallets/electrum/ElectrumRegtestProcess.java index b0fa8bab88..46598b0c53 100644 --- a/wallets/electrum/src/main/java/bisq/wallets/electrum/ElectrumRegtestProcess.java +++ b/wallets/electrum/src/main/java/bisq/wallets/electrum/ElectrumRegtestProcess.java @@ -19,9 +19,10 @@ import bisq.common.util.FileUtils; import bisq.wallets.core.RpcConfig; +import bisq.wallets.core.rpc.DaemonRpcClient; +import bisq.wallets.core.rpc.RpcClientFactory; +import bisq.wallets.electrum.rpc.ElectrumDaemon; import bisq.wallets.electrum.rpc.ElectrumProcessConfig; -import bisq.wallets.electrum.rpc.cli.ElectrumCli; -import bisq.wallets.electrum.rpc.cli.ElectrumCliFacade; import bisq.wallets.process.DaemonProcess; import bisq.wallets.process.ProcessConfig; import bisq.wallets.process.scanner.FileScanner; @@ -46,7 +47,8 @@ public class ElectrumRegtestProcess extends DaemonProcess { private final Path binaryPath; private final ElectrumProcessConfig electrumProcessConfig; - private final ElectrumCliFacade electrumCliFacade; + @Getter + private final ElectrumDaemon electrumDaemon; @Getter private RpcConfig rpcConfig; @@ -56,9 +58,7 @@ public ElectrumRegtestProcess(Path binaryPath, ElectrumProcessConfig electrumPro super(electrumProcessConfig.getDataDir()); this.binaryPath = binaryPath; this.electrumProcessConfig = electrumProcessConfig; - - var electrumCli = new ElectrumCli(binaryPath, dataDir); - electrumCliFacade = new ElectrumCliFacade(electrumCli); + this.electrumDaemon = createElectrumDaemon(); } @Override @@ -75,14 +75,14 @@ public ProcessConfig createProcessConfig() { return ProcessConfig.builder() .name(binaryPath.toAbsolutePath().toString()) .args(List.of( - ElectrumCli.ELECTRUM_REGTEST_ARG, + "--regtest", "daemon", "-s", electrumProcessConfig.getElectrumXServerHost() + ":" + electrumProcessConfig.getElectrumXServerPort() + ":t", - ElectrumCli.ELECTRUM_DATA_DIR_ARG, + "--dir", dataDir.toAbsolutePath().toString(), "-v" // Enable logging (only works on Mac and Linux) @@ -93,7 +93,7 @@ public ProcessConfig createProcessConfig() { @Override public void invokeStopRpcCall() { - electrumCliFacade.stop(); + electrumDaemon.stop(); } @Override @@ -112,6 +112,12 @@ protected Set getIsSuccessfulStartUpLogLines() { ); } + private ElectrumDaemon createElectrumDaemon() { + RpcConfig rpcConfig = electrumProcessConfig.getElectrumConfig().toRpcConfig(); + DaemonRpcClient daemonRpcClient = RpcClientFactory.createDaemonRpcClient(rpcConfig); + return new ElectrumDaemon(daemonRpcClient); + } + private Future findNewLogFile() { try { Path logsDirPath = dataDir.resolve("regtest").resolve("logs"); diff --git a/wallets/electrum/src/main/java/bisq/wallets/electrum/rpc/cli/ElectrumCli.java b/wallets/electrum/src/main/java/bisq/wallets/electrum/rpc/cli/ElectrumCli.java deleted file mode 100644 index f578a15efe..0000000000 --- a/wallets/electrum/src/main/java/bisq/wallets/electrum/rpc/cli/ElectrumCli.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * This file is part of Bisq. - * - * Bisq is free software: you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or (at - * your option) any later version. - * - * Bisq is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public - * License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with Bisq. If not, see . - */ - -package bisq.wallets.electrum.rpc.cli; - -import bisq.wallets.core.exceptions.RpcCallFailureException; -import bisq.wallets.process.cli.AbstractRpcCliProcess; -import bisq.wallets.process.cli.CliProcessConfig; - -import java.nio.file.Path; -import java.util.List; - -public class ElectrumCli extends AbstractRpcCliProcess { - public static final String ELECTRUM_REGTEST_ARG = "--regtest"; - public static final String ELECTRUM_DATA_DIR_ARG = "--dir"; - public static final String ELECTRUM_HELP_ARG = "--help"; - - private static final String ELECTRUM_SETCONFIG_ARG = "setconfig"; - private static final String ELECTRUM_GETCONFIG_ARG = "getconfig"; - private static final String ELECTRUM_STOP_ARG = "stop"; - - public ElectrumCli(Path binaryPath, Path dataDir) { - super(CliProcessConfig.builder() - .binaryName( - String.valueOf(binaryPath.toAbsolutePath()) - ) - .defaultArgs(List.of( - ELECTRUM_REGTEST_ARG, - ELECTRUM_DATA_DIR_ARG, dataDir.toAbsolutePath().toString() - )) - .build() - ); - } - - public String getConfig(String configName) { - String output = runAndGetOutput(ELECTRUM_GETCONFIG_ARG, configName); - if (output.isEmpty()) { - throw new RpcCallFailureException("Failed to get electrum config: " + configName); - } - return output; - } - - public void setConfig(String configName, String configValue) { - String output = runAndGetOutput(ELECTRUM_SETCONFIG_ARG, configName, configValue); - if (!output.equals("true")) { - throw new RpcCallFailureException("Failed to set electrum config: " + configName + " = " + configValue); - } - } - - public String help() { - return runAndGetOutput(ELECTRUM_HELP_ARG); - } - - public void stop() { - String output = runAndGetOutput(ELECTRUM_STOP_ARG); - boolean isStopped = output.equals("Daemon stopped"); - if (!isStopped) { - throw new RpcCallFailureException("Cannot stop electrum daemon: " + output); - } - } -} diff --git a/wallets/electrum/src/main/java/bisq/wallets/electrum/rpc/cli/ElectrumCliFacade.java b/wallets/electrum/src/main/java/bisq/wallets/electrum/rpc/cli/ElectrumCliFacade.java deleted file mode 100644 index 6bd1c04f75..0000000000 --- a/wallets/electrum/src/main/java/bisq/wallets/electrum/rpc/cli/ElectrumCliFacade.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * This file is part of Bisq. - * - * Bisq is free software: you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or (at - * your option) any later version. - * - * Bisq is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public - * License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with Bisq. If not, see . - */ - -package bisq.wallets.electrum.rpc.cli; - -import lombok.extern.slf4j.Slf4j; - -@Slf4j -public class ElectrumCliFacade { - - private final ElectrumCli electrumCli; - - public ElectrumCliFacade(ElectrumCli electrumCli) { - this.electrumCli = electrumCli; - } - - public void enableLoggingToFile() { - electrumCli.setConfig("log_to_file", "true"); - } - - public void setRpcHost(String host) { - electrumCli.setConfig("rpchost", host); - } - - public void setRpcPort(int port) { - electrumCli.setConfig("rpcport", String.valueOf(port)); - } - - public int getRpcPort() { - String rpcPort = electrumCli.getConfig("rpcport"); - return Integer.parseInt(rpcPort); - } - - public String getRpcUser() { - return electrumCli.getConfig("rpcuser"); - } - - public String getRpcPassword() { - return electrumCli.getConfig("rpcpassword"); - } - - public void stop() { - electrumCli.stop(); - } -} diff --git a/wallets/electrum/src/test/java/bisq/wallets/electrum/ElectrumBundledBinaryTest.java b/wallets/electrum/src/test/java/bisq/wallets/electrum/ElectrumBundledBinaryTest.java deleted file mode 100644 index 5aadf9e4df..0000000000 --- a/wallets/electrum/src/test/java/bisq/wallets/electrum/ElectrumBundledBinaryTest.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * This file is part of Bisq. - * - * Bisq is free software: you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or (at - * your option) any later version. - * - * Bisq is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public - * License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with Bisq. If not, see . - */ - -package bisq.wallets.electrum; - -import bisq.common.util.FileUtils; -import bisq.wallets.electrum.rpc.cli.ElectrumCli; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.condition.EnabledOnOs; -import org.junit.jupiter.api.condition.OS; - -import java.io.IOException; -import java.nio.file.Path; - -import static org.assertj.core.api.Assertions.assertThat; - -public class ElectrumBundledBinaryTest { - private final ElectrumBinaryExtractor binaryExtractor; - - public ElectrumBundledBinaryTest() throws IOException { - Path destDirPath = FileUtils.createTempDir(); - binaryExtractor = new ElectrumBinaryExtractor(destDirPath); - } - - @Test - @EnabledOnOs({OS.LINUX}) - void runHelpTest() throws IOException { - Path electrumBinaryPath = binaryExtractor.extractFileWithSuffix("AppImage"); - boolean isExecutableNow = electrumBinaryPath.toFile().setExecutable(true); - assertThat(isExecutableNow).isTrue(); - - Path dataDir = FileUtils.createTempDir(); - ElectrumCli electrumCli = new ElectrumCli(electrumBinaryPath, dataDir); - - String helpOutput = electrumCli.help(); - assertThat(helpOutput).isNotEmpty(); - } -} diff --git a/wallets/electrum/src/test/java/bisq/wallets/electrum/regtest/electrum/ElectrumRegtest.java b/wallets/electrum/src/test/java/bisq/wallets/electrum/regtest/electrum/ElectrumRegtest.java index 053cfec5a6..9ed96ccebe 100644 --- a/wallets/electrum/src/test/java/bisq/wallets/electrum/regtest/electrum/ElectrumRegtest.java +++ b/wallets/electrum/src/test/java/bisq/wallets/electrum/regtest/electrum/ElectrumRegtest.java @@ -54,7 +54,7 @@ public ElectrumRegtest(RemoteBitcoind remoteBitcoind, String electrumXHost, int public void start() { electrumProcess.start(); - electrumDaemon = electrumProcess.getElectrumDaemon().orElseThrow(); + electrumDaemon = electrumProcess.getElectrumDaemon(); if (doCreateWallet) { walletInfo = electrumDaemon.create(AbstractRegtestSetup.WALLET_PASSPHRASE); electrumDaemon.loadWallet(AbstractRegtestSetup.WALLET_PASSPHRASE);