mirror of
https://github.com/haveno-dex/haveno.git
synced 2024-10-01 01:35:48 -04:00
support using monero native libraries (experimental)
This commit is contained in:
parent
53001823af
commit
01dd6a8af9
97
Makefile
97
Makefile
@ -49,7 +49,7 @@ bitcoind:
|
||||
-peerbloomfilters=1 \
|
||||
-datadir=.localnet/ \
|
||||
-rpcuser=haveno \
|
||||
-rpcpassword=1234
|
||||
-rpcpassword=1234 \
|
||||
|
||||
btc-blocks:
|
||||
./.localnet/bitcoin-cli \
|
||||
@ -75,7 +75,7 @@ monerod1-local:
|
||||
--add-exclusive-node 127.0.0.1:58080 \
|
||||
--rpc-access-control-origins http://localhost:8080 \
|
||||
--fixed-difficulty 500 \
|
||||
--disable-rpc-ban
|
||||
--disable-rpc-ban \
|
||||
|
||||
monerod2-local:
|
||||
./.localnet/monerod \
|
||||
@ -93,7 +93,7 @@ monerod2-local:
|
||||
--add-exclusive-node 127.0.0.1:58080 \
|
||||
--rpc-access-control-origins http://localhost:8080 \
|
||||
--fixed-difficulty 500 \
|
||||
--disable-rpc-ban
|
||||
--disable-rpc-ban \
|
||||
|
||||
monerod3-local:
|
||||
./.localnet/monerod \
|
||||
@ -111,7 +111,7 @@ monerod3-local:
|
||||
--add-exclusive-node 127.0.0.1:48080 \
|
||||
--rpc-access-control-origins http://localhost:8080 \
|
||||
--fixed-difficulty 500 \
|
||||
--disable-rpc-ban
|
||||
--disable-rpc-ban \
|
||||
|
||||
funding-wallet-stagenet:
|
||||
./.localnet/monero-wallet-rpc \
|
||||
@ -121,7 +121,7 @@ funding-wallet-stagenet:
|
||||
--rpc-access-control-origins http://localhost:8080 \
|
||||
--wallet-dir ./.localnet \
|
||||
--daemon-ssl-allow-any-cert \
|
||||
--daemon-address http://127.0.0.1:38081
|
||||
--daemon-address http://127.0.0.1:38081 \
|
||||
|
||||
#--proxy 127.0.0.1:49775 \
|
||||
|
||||
@ -132,7 +132,7 @@ funding-wallet-local:
|
||||
--rpc-bind-port 28084 \
|
||||
--rpc-login rpc_user:abc123 \
|
||||
--rpc-access-control-origins http://localhost:8080 \
|
||||
--wallet-dir ./.localnet
|
||||
--wallet-dir ./.localnet \
|
||||
|
||||
# use .bat extension for windows binaries
|
||||
APP_EXT :=
|
||||
@ -168,7 +168,8 @@ arbitrator-daemon-local:
|
||||
--appName=haveno-XMR_LOCAL_arbitrator \
|
||||
--apiPassword=apitest \
|
||||
--apiPort=9998 \
|
||||
--passwordRequired=false
|
||||
--passwordRequired=false \
|
||||
--useNativeXmrWallet=false \
|
||||
|
||||
arbitrator-desktop-local:
|
||||
# Arbitrator needs to be registered before making trades
|
||||
@ -179,7 +180,8 @@ arbitrator-desktop-local:
|
||||
--nodePort=4444 \
|
||||
--appName=haveno-XMR_LOCAL_arbitrator \
|
||||
--apiPassword=apitest \
|
||||
--apiPort=9998
|
||||
--apiPort=9998 \
|
||||
--useNativeXmrWallet=false \
|
||||
|
||||
arbitrator2-daemon-local:
|
||||
# Arbitrator needs to be registered before making trades
|
||||
@ -190,7 +192,8 @@ arbitrator2-daemon-local:
|
||||
--nodePort=7777 \
|
||||
--appName=haveno-XMR_LOCAL_arbitrator2 \
|
||||
--apiPassword=apitest \
|
||||
--apiPort=10001
|
||||
--apiPort=10001 \
|
||||
--useNativeXmrWallet=false \
|
||||
|
||||
arbitrator2-desktop-local:
|
||||
# Arbitrator needs to be registered before making trades
|
||||
@ -201,7 +204,8 @@ arbitrator2-desktop-local:
|
||||
--nodePort=7777 \
|
||||
--appName=haveno-XMR_LOCAL_arbitrator2 \
|
||||
--apiPassword=apitest \
|
||||
--apiPort=10001
|
||||
--apiPort=10001 \
|
||||
--useNativeXmrWallet=false \
|
||||
|
||||
user1-daemon-local:
|
||||
./haveno-daemon$(APP_EXT) \
|
||||
@ -213,7 +217,8 @@ user1-daemon-local:
|
||||
--apiPassword=apitest \
|
||||
--apiPort=9999 \
|
||||
--walletRpcBindPort=38091 \
|
||||
--passwordRequired=false
|
||||
--passwordRequired=false \
|
||||
--useNativeXmrWallet=false \
|
||||
|
||||
user1-desktop-local:
|
||||
./haveno-desktop$(APP_EXT) \
|
||||
@ -225,7 +230,8 @@ user1-desktop-local:
|
||||
--apiPassword=apitest \
|
||||
--apiPort=9999 \
|
||||
--walletRpcBindPort=38091 \
|
||||
--logLevel=info
|
||||
--logLevel=info \
|
||||
--useNativeXmrWallet=false \
|
||||
|
||||
user2-desktop-local:
|
||||
./haveno-desktop$(APP_EXT) \
|
||||
@ -236,7 +242,8 @@ user2-desktop-local:
|
||||
--appName=haveno-XMR_LOCAL_user2 \
|
||||
--apiPassword=apitest \
|
||||
--apiPort=10000 \
|
||||
--walletRpcBindPort=38092
|
||||
--walletRpcBindPort=38092 \
|
||||
--useNativeXmrWallet=false \
|
||||
|
||||
user2-daemon-local:
|
||||
./haveno-daemon$(APP_EXT) \
|
||||
@ -248,7 +255,8 @@ user2-daemon-local:
|
||||
--apiPassword=apitest \
|
||||
--apiPort=10000 \
|
||||
--walletRpcBindPort=38092 \
|
||||
--passwordRequired=false
|
||||
--passwordRequired=false \
|
||||
--useNativeXmrWallet=false \
|
||||
|
||||
user3-desktop-local:
|
||||
./haveno-desktop$(APP_EXT) \
|
||||
@ -259,7 +267,8 @@ user3-desktop-local:
|
||||
--appName=haveno-XMR_LOCAL_user3 \
|
||||
--apiPassword=apitest \
|
||||
--apiPort=10002 \
|
||||
--walletRpcBindPort=38093
|
||||
--walletRpcBindPort=38093 \
|
||||
--useNativeXmrWallet=false \
|
||||
|
||||
user3-daemon-local:
|
||||
./haveno-daemon$(APP_EXT) \
|
||||
@ -271,7 +280,8 @@ user3-daemon-local:
|
||||
--apiPassword=apitest \
|
||||
--apiPort=10002 \
|
||||
--walletRpcBindPort=38093 \
|
||||
--passwordRequired=false
|
||||
--passwordRequired=false \
|
||||
--useNativeXmrWallet=false \
|
||||
|
||||
# Stagenet network
|
||||
|
||||
@ -288,7 +298,7 @@ monerod-stagenet-custom:
|
||||
--p2p-bind-port 39080 \
|
||||
--rpc-bind-port 39081 \
|
||||
--bootstrap-daemon-address auto \
|
||||
--rpc-access-control-origins http://localhost:8080
|
||||
--rpc-access-control-origins http://localhost:8080 \
|
||||
|
||||
seednode-stagenet:
|
||||
./haveno-seednode$(APP_EXT) \
|
||||
@ -297,7 +307,7 @@ seednode-stagenet:
|
||||
--useDevPrivilegeKeys=false \
|
||||
--nodePort=9999 \
|
||||
--appName=haveno-XMR_STAGENET_Seed_3002 \
|
||||
--xmrNode=http://127.0.0.1:38081
|
||||
--xmrNode=http://127.0.0.1:38081 \
|
||||
|
||||
seednode2-stagenet:
|
||||
./haveno-seednode$(APP_EXT) \
|
||||
@ -306,7 +316,7 @@ seednode2-stagenet:
|
||||
--useDevPrivilegeKeys=false \
|
||||
--nodePort=9999 \
|
||||
--appName=haveno-XMR_STAGENET_Seed_3003 \
|
||||
--xmrNode=http://127.0.0.1:38081
|
||||
--xmrNode=http://127.0.0.1:38081 \
|
||||
|
||||
arbitrator-daemon-stagenet:
|
||||
# Arbitrator needs to be registered before making trades
|
||||
@ -319,7 +329,8 @@ arbitrator-daemon-stagenet:
|
||||
--apiPassword=apitest \
|
||||
--apiPort=3200 \
|
||||
--passwordRequired=false \
|
||||
--xmrNode=http://127.0.0.1:38081
|
||||
--xmrNode=http://127.0.0.1:38081 \
|
||||
--useNativeXmrWallet=false \
|
||||
|
||||
# Arbitrator needs to be registered before making trades
|
||||
arbitrator-desktop-stagenet:
|
||||
@ -331,7 +342,8 @@ arbitrator-desktop-stagenet:
|
||||
--appName=haveno-XMR_STAGENET_arbitrator \
|
||||
--apiPassword=apitest \
|
||||
--apiPort=3200 \
|
||||
--xmrNode=http://127.0.0.1:38081
|
||||
--xmrNode=http://127.0.0.1:38081 \
|
||||
--useNativeXmrWallet=false \
|
||||
|
||||
user1-daemon-stagenet:
|
||||
./haveno-daemon$(APP_EXT) \
|
||||
@ -342,7 +354,8 @@ user1-daemon-stagenet:
|
||||
--appName=haveno-XMR_STAGENET_user1 \
|
||||
--apiPassword=apitest \
|
||||
--apiPort=3201 \
|
||||
--passwordRequired=false
|
||||
--passwordRequired=false \
|
||||
--useNativeXmrWallet=false \
|
||||
|
||||
user1-desktop-stagenet:
|
||||
./haveno-desktop$(APP_EXT) \
|
||||
@ -352,7 +365,8 @@ user1-desktop-stagenet:
|
||||
--nodePort=9999 \
|
||||
--appName=haveno-XMR_STAGENET_user1 \
|
||||
--apiPassword=apitest \
|
||||
--apiPort=3201
|
||||
--apiPort=3201 \
|
||||
--useNativeXmrWallet=false \
|
||||
|
||||
user2-daemon-stagenet:
|
||||
./haveno-daemon$(APP_EXT) \
|
||||
@ -363,7 +377,8 @@ user2-daemon-stagenet:
|
||||
--appName=haveno-XMR_STAGENET_user2 \
|
||||
--apiPassword=apitest \
|
||||
--apiPort=3202 \
|
||||
--passwordRequired=false
|
||||
--passwordRequired=false \
|
||||
--useNativeXmrWallet=false \
|
||||
|
||||
user2-desktop-stagenet:
|
||||
./haveno-desktop$(APP_EXT) \
|
||||
@ -373,7 +388,8 @@ user2-desktop-stagenet:
|
||||
--nodePort=9999 \
|
||||
--appName=haveno-XMR_STAGENET_user2 \
|
||||
--apiPassword=apitest \
|
||||
--apiPort=3202
|
||||
--apiPort=3202 \
|
||||
--useNativeXmrWallet=false \
|
||||
|
||||
user3-desktop-stagenet:
|
||||
./haveno-desktop$(APP_EXT) \
|
||||
@ -383,7 +399,8 @@ user3-desktop-stagenet:
|
||||
--nodePort=9999 \
|
||||
--appName=haveno-XMR_STAGENET_user3 \
|
||||
--apiPassword=apitest \
|
||||
--apiPort=3203
|
||||
--apiPort=3203 \
|
||||
--useNativeXmrWallet=false \
|
||||
|
||||
haveno-desktop-stagenet:
|
||||
./haveno-desktop$(APP_EXT) \
|
||||
@ -393,7 +410,8 @@ haveno-desktop-stagenet:
|
||||
--nodePort=9999 \
|
||||
--appName=Haveno \
|
||||
--apiPassword=apitest \
|
||||
--apiPort=3204
|
||||
--apiPort=3204 \
|
||||
--useNativeXmrWallet=false \
|
||||
|
||||
# Mainnet network
|
||||
|
||||
@ -409,7 +427,7 @@ seednode:
|
||||
--useDevPrivilegeKeys=false \
|
||||
--nodePort=9999 \
|
||||
--appName=haveno-XMR_MAINNET_Seed_1002 \
|
||||
--xmrNode=http://127.0.0.1:18081
|
||||
--xmrNode=http://127.0.0.1:18081 \
|
||||
|
||||
seednode2:
|
||||
./haveno-seednode$(APP_EXT) \
|
||||
@ -418,7 +436,7 @@ seednode2:
|
||||
--useDevPrivilegeKeys=false \
|
||||
--nodePort=9999 \
|
||||
--appName=haveno-XMR_MAINNET_Seed_1003 \
|
||||
--xmrNode=http://127.0.0.1:18081
|
||||
--xmrNode=http://127.0.0.1:18081 \
|
||||
|
||||
arbitrator-daemon:
|
||||
# Arbitrator needs to be registered before making trades
|
||||
@ -431,7 +449,8 @@ arbitrator-daemon:
|
||||
--apiPassword=apitest \
|
||||
--apiPort=1200 \
|
||||
--passwordRequired=false \
|
||||
--xmrNode=http://127.0.0.1:18081
|
||||
--xmrNode=http://127.0.0.1:18081 \
|
||||
--useNativeXmrWallet=false \
|
||||
|
||||
# Arbitrator needs to be registered before making trades
|
||||
arbitrator-desktop:
|
||||
@ -443,7 +462,8 @@ arbitrator-desktop:
|
||||
--appName=haveno-XMR_MAINNET_arbitrator \
|
||||
--apiPassword=apitest \
|
||||
--apiPort=1200 \
|
||||
--xmrNode=http://127.0.0.1:18081
|
||||
--xmrNode=http://127.0.0.1:18081 \
|
||||
--useNativeXmrWallet=false \
|
||||
|
||||
user1-daemon:
|
||||
./haveno-daemon$(APP_EXT) \
|
||||
@ -454,7 +474,8 @@ user1-daemon:
|
||||
--appName=haveno-XMR_MAINNET_user1 \
|
||||
--apiPassword=apitest \
|
||||
--apiPort=1201 \
|
||||
--passwordRequired=false
|
||||
--passwordRequired=false \
|
||||
--useNativeXmrWallet=false \
|
||||
|
||||
user1-desktop:
|
||||
./haveno-desktop$(APP_EXT) \
|
||||
@ -464,7 +485,8 @@ user1-desktop:
|
||||
--nodePort=9999 \
|
||||
--appName=haveno-XMR_MAINNET_user1 \
|
||||
--apiPassword=apitest \
|
||||
--apiPort=1201
|
||||
--apiPort=1201 \
|
||||
--useNativeXmrWallet=false \
|
||||
|
||||
user2-daemon:
|
||||
./haveno-daemon$(APP_EXT) \
|
||||
@ -475,7 +497,8 @@ user2-daemon:
|
||||
--appName=haveno-XMR_MAINNET_user2 \
|
||||
--apiPassword=apitest \
|
||||
--apiPort=1202 \
|
||||
--passwordRequired=false
|
||||
--passwordRequired=false \
|
||||
--useNativeXmrWallet=false \
|
||||
|
||||
user2-desktop:
|
||||
./haveno-desktop$(APP_EXT) \
|
||||
@ -485,7 +508,8 @@ user2-desktop:
|
||||
--nodePort=9999 \
|
||||
--appName=haveno-XMR_MAINNET_user2 \
|
||||
--apiPassword=apitest \
|
||||
--apiPort=1202
|
||||
--apiPort=1202 \
|
||||
--useNativeXmrWallet=false \
|
||||
|
||||
user3-desktop:
|
||||
./haveno-desktop$(APP_EXT) \
|
||||
@ -495,4 +519,5 @@ user3-desktop:
|
||||
--nodePort=9999 \
|
||||
--appName=haveno-XMR_MAINNET_user3 \
|
||||
--apiPassword=apitest \
|
||||
--apiPort=1203
|
||||
--apiPort=1203 \
|
||||
--useNativeXmrWallet=false \
|
||||
|
@ -49,7 +49,7 @@ configure(subprojects) {
|
||||
gsonVersion = '2.8.5'
|
||||
guavaVersion = '32.1.1-jre'
|
||||
guiceVersion = '7.0.0'
|
||||
moneroJavaVersion = '0.8.11'
|
||||
moneroJavaVersion = '0.8.21'
|
||||
httpclient5Version = '5.0'
|
||||
hamcrestVersion = '2.2'
|
||||
httpclientVersion = '4.5.12'
|
||||
|
@ -100,6 +100,7 @@ public class Config {
|
||||
public static final String XMR_NODE_USERNAME = "xmrNodeUsername";
|
||||
public static final String XMR_NODE_PASSWORD = "xmrNodePassword";
|
||||
public static final String XMR_NODES = "xmrNodes";
|
||||
public static final String USE_NATIVE_XMR_WALLET = "useNativeXmrWallet";
|
||||
public static final String SOCKS5_DISCOVER_MODE = "socks5DiscoverMode";
|
||||
public static final String USE_ALL_PROVIDED_NODES = "useAllProvidedNodes";
|
||||
public static final String USER_AGENT = "userAgent";
|
||||
@ -188,6 +189,7 @@ public class Config {
|
||||
public final String xmrNodeUsername;
|
||||
public final String xmrNodePassword;
|
||||
public final String xmrNodes;
|
||||
public final boolean useNativeXmrWallet;
|
||||
public final UseTorForXmr useTorForXmr;
|
||||
public final boolean useTorForXmrOptionSetExplicitly;
|
||||
public final String socks5DiscoverMode;
|
||||
@ -532,6 +534,12 @@ public class Config {
|
||||
.describedAs("ip[,...]")
|
||||
.defaultsTo("");
|
||||
|
||||
ArgumentAcceptingOptionSpec<Boolean> useNativeXmrWalletOpt =
|
||||
parser.accepts(USE_NATIVE_XMR_WALLET, "Use native wallet libraries instead of monero-wallet-rpc server")
|
||||
.withRequiredArg()
|
||||
.ofType(boolean.class)
|
||||
.defaultsTo(false);
|
||||
|
||||
//noinspection rawtypes
|
||||
ArgumentAcceptingOptionSpec<Enum> useTorForXmrOpt =
|
||||
parser.accepts(USE_TOR_FOR_XMR, "Configure TOR for Monero connections, one of: after_sync, off, or on.")
|
||||
@ -702,6 +710,7 @@ public class Config {
|
||||
this.xmrNodeUsername = options.valueOf(xmrNodeUsernameOpt);
|
||||
this.xmrNodePassword = options.valueOf(xmrNodePasswordOpt);
|
||||
this.xmrNodes = options.valueOf(xmrNodesOpt);
|
||||
this.useNativeXmrWallet = options.valueOf(useNativeXmrWalletOpt);
|
||||
this.useTorForXmr = (UseTorForXmr) options.valueOf(useTorForXmrOpt);
|
||||
this.useTorForXmrOptionSetExplicitly = options.has(useTorForXmrOpt);
|
||||
this.socks5DiscoverMode = options.valueOf(socks5DiscoverModeOpt);
|
||||
|
@ -25,6 +25,8 @@ import haveno.core.trade.HavenoUtils;
|
||||
import haveno.core.user.Preferences;
|
||||
import haveno.core.xmr.XmrNodeSettings;
|
||||
import haveno.core.xmr.nodes.XmrNodes;
|
||||
import haveno.core.xmr.wallet.XmrWalletService;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
@ -44,10 +46,9 @@ public class XmrLocalNode {
|
||||
|
||||
// constants
|
||||
public static final long REFRESH_PERIOD_LOCAL_MS = 5000; // refresh period for local node
|
||||
public static final String MONEROD_DIR = Config.baseCurrencyNetwork() == BaseCurrencyNetwork.XMR_LOCAL ? System.getProperty("user.dir") + File.separator + ".localnet" : Config.appDataDir().getAbsolutePath();
|
||||
public static final String MONEROD_NAME = Utilities.isWindows() ? "monerod.exe" : "monerod";
|
||||
public static final String MONEROD_PATH = MONEROD_DIR + File.separator + MONEROD_NAME;
|
||||
private static final String MONEROD_DATADIR = Config.baseCurrencyNetwork() == BaseCurrencyNetwork.XMR_LOCAL ? MONEROD_DIR + File.separator + Config.baseCurrencyNetwork().toString().toLowerCase() + File.separator + "node1" : null; // use default directory unless local
|
||||
public static final String MONEROD_PATH = XmrWalletService.MONERO_BINS_DIR + File.separator + MONEROD_NAME;
|
||||
private static final String MONEROD_DATADIR = Config.baseCurrencyNetwork() == BaseCurrencyNetwork.XMR_LOCAL ? XmrWalletService.MONERO_BINS_DIR + File.separator + Config.baseCurrencyNetwork().toString().toLowerCase() + File.separator + "node1" : null; // use default directory unless local
|
||||
|
||||
// instance fields
|
||||
private MoneroDaemonRpc daemon;
|
||||
|
@ -357,6 +357,8 @@ public class HavenoSetup {
|
||||
|
||||
private void maybeInstallDependencies() {
|
||||
try {
|
||||
|
||||
// install monerod
|
||||
File monerodFile = new File(XmrLocalNode.MONEROD_PATH);
|
||||
String monerodResourcePath = "bin/" + XmrLocalNode.MONEROD_NAME;
|
||||
if (!monerodFile.exists() || !FileUtil.resourceEqualToFile(monerodResourcePath, monerodFile)) {
|
||||
@ -366,13 +368,14 @@ public class HavenoSetup {
|
||||
monerodFile.setExecutable(true);
|
||||
}
|
||||
|
||||
File moneroWalletFile = new File(XmrWalletService.MONERO_WALLET_RPC_PATH);
|
||||
String moneroWalletResourcePath = "bin/" + XmrWalletService.MONERO_WALLET_RPC_NAME;
|
||||
if (!moneroWalletFile.exists() || !FileUtil.resourceEqualToFile(moneroWalletResourcePath, moneroWalletFile)) {
|
||||
// install monero-wallet-rpc
|
||||
File moneroWalletRpcFile = new File(XmrWalletService.MONERO_WALLET_RPC_PATH);
|
||||
String moneroWalletRpcResourcePath = "bin/" + XmrWalletService.MONERO_WALLET_RPC_NAME;
|
||||
if (!moneroWalletRpcFile.exists() || !FileUtil.resourceEqualToFile(moneroWalletRpcResourcePath, moneroWalletRpcFile)) {
|
||||
log.info("Installing monero-wallet-rpc");
|
||||
moneroWalletFile.getParentFile().mkdirs();
|
||||
FileUtil.resourceToFile(moneroWalletResourcePath, moneroWalletFile);
|
||||
moneroWalletFile.setExecutable(true);
|
||||
moneroWalletRpcFile.getParentFile().mkdirs();
|
||||
FileUtil.resourceToFile(moneroWalletRpcResourcePath, moneroWalletRpcFile);
|
||||
moneroWalletRpcFile.setExecutable(true);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
|
@ -92,6 +92,7 @@ public class XmrModule extends AppModule {
|
||||
bindConstant().annotatedWith(named(Config.XMR_NODE_USERNAME)).to(config.xmrNodeUsername);
|
||||
bindConstant().annotatedWith(named(Config.XMR_NODE_PASSWORD)).to(config.xmrNodePassword);
|
||||
bindConstant().annotatedWith(named(Config.XMR_NODES)).to(config.xmrNodes);
|
||||
bindConstant().annotatedWith(named(Config.USE_NATIVE_XMR_WALLET)).to(config.useNativeXmrWallet);
|
||||
bindConstant().annotatedWith(named(Config.USER_AGENT)).to(config.userAgent);
|
||||
bindConstant().annotatedWith(named(Config.NUM_CONNECTIONS_FOR_BTC)).to(config.numConnectionsForBtc);
|
||||
bindConstant().annotatedWith(named(Config.USE_ALL_PROVIDED_NODES)).to(config.useAllProvidedNodes);
|
||||
|
@ -85,6 +85,7 @@ import monero.daemon.model.MoneroOutput;
|
||||
import monero.daemon.model.MoneroSubmitTxResult;
|
||||
import monero.daemon.model.MoneroTx;
|
||||
import monero.wallet.MoneroWallet;
|
||||
import monero.wallet.MoneroWalletFull;
|
||||
import monero.wallet.MoneroWalletRpc;
|
||||
import monero.wallet.model.MoneroCheckTx;
|
||||
import monero.wallet.model.MoneroDestination;
|
||||
@ -108,11 +109,11 @@ import org.slf4j.LoggerFactory;
|
||||
public class XmrWalletService {
|
||||
private static final Logger log = LoggerFactory.getLogger(XmrWalletService.class);
|
||||
|
||||
// Monero configuration
|
||||
// monero configuration
|
||||
public static final int NUM_BLOCKS_UNLOCK = 10;
|
||||
public static final String MONERO_WALLET_RPC_DIR = Config.baseCurrencyNetwork().isTestnet() ? System.getProperty("user.dir") + File.separator + ".localnet" : Config.appDataDir().getAbsolutePath(); // .localnet contains monero-wallet-rpc and wallet files
|
||||
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_WALLET_RPC_NAME = Utilities.isWindows() ? "monero-wallet-rpc.exe" : "monero-wallet-rpc";
|
||||
public static final String MONERO_WALLET_RPC_PATH = MONERO_WALLET_RPC_DIR + File.separator + MONERO_WALLET_RPC_NAME;
|
||||
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
|
||||
public static final MoneroTxPriority PROTOCOL_FEE_PRIORITY = MoneroTxPriority.ELEVATED;
|
||||
private static final MoneroNetworkType MONERO_NETWORK_TYPE = getMoneroNetworkType();
|
||||
@ -123,7 +124,7 @@ public class XmrWalletService {
|
||||
private static final String KEYS_FILE_POSTFIX = ".keys";
|
||||
private static final String ADDRESS_FILE_POSTFIX = ".address.txt";
|
||||
private static final int NUM_MAX_WALLET_BACKUPS = 1;
|
||||
private static final int MONERO_LOG_LEVEL = 0;
|
||||
private static final int MONERO_LOG_LEVEL = -1; // monero library log level, -1 to disable
|
||||
private static final int MAX_SYNC_ATTEMPTS = 3;
|
||||
private static final boolean PRINT_STACK_TRACE = false;
|
||||
private static final String THREAD_ID = XmrWalletService.class.getSimpleName();
|
||||
@ -140,12 +141,13 @@ public class XmrWalletService {
|
||||
private final File walletDir;
|
||||
private final File xmrWalletFile;
|
||||
private final int rpcBindPort;
|
||||
private final boolean useNativeXmrWallet;
|
||||
protected final CopyOnWriteArraySet<XmrBalanceListener> balanceListeners = new CopyOnWriteArraySet<>();
|
||||
protected final CopyOnWriteArraySet<MoneroWalletListenerI> walletListeners = new CopyOnWriteArraySet<>();
|
||||
|
||||
private ChangeListener<? super Number> walletInitListener;
|
||||
private TradeManager tradeManager;
|
||||
private MoneroWalletRpc wallet;
|
||||
private MoneroWallet wallet;
|
||||
private Object walletLock = new Object();
|
||||
private boolean wasWalletSynced = false;
|
||||
private final Map<String, Optional<MoneroTx>> txCache = new HashMap<String, Optional<MoneroTx>>();
|
||||
@ -158,6 +160,7 @@ public class XmrWalletService {
|
||||
private List<MoneroSubaddress> cachedSubaddresses;
|
||||
private List<MoneroTxWallet> cachedTxs;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Inject
|
||||
XmrWalletService(User user,
|
||||
Preferences preferences,
|
||||
@ -166,7 +169,8 @@ public class XmrWalletService {
|
||||
WalletsSetup walletsSetup,
|
||||
XmrAddressEntryList xmrAddressEntryList,
|
||||
@Named(Config.WALLET_DIR) File walletDir,
|
||||
@Named(Config.WALLET_RPC_BIND_PORT) int rpcBindPort) {
|
||||
@Named(Config.WALLET_RPC_BIND_PORT) int rpcBindPort,
|
||||
@Named(Config.USE_NATIVE_XMR_WALLET) boolean useNativeXmrWallet) {
|
||||
this.user = user;
|
||||
this.preferences = preferences;
|
||||
this.accountService = accountService;
|
||||
@ -175,10 +179,11 @@ public class XmrWalletService {
|
||||
this.xmrAddressEntryList = xmrAddressEntryList;
|
||||
this.walletDir = walletDir;
|
||||
this.rpcBindPort = rpcBindPort;
|
||||
this.useNativeXmrWallet = useNativeXmrWallet;
|
||||
this.xmrWalletFile = new File(walletDir, MONERO_WALLET_NAME);
|
||||
|
||||
// set monero logging
|
||||
MoneroUtils.setLogLevel(MONERO_LOG_LEVEL);
|
||||
if (MONERO_LOG_LEVEL >= 0) MoneroUtils.setLogLevel(MONERO_LOG_LEVEL);
|
||||
|
||||
// initialize after account open and basic setup
|
||||
walletsSetup.addSetupTaskHandler(() -> { // TODO: use something better than legacy WalletSetup for notification to initialize
|
||||
@ -311,23 +316,37 @@ public class XmrWalletService {
|
||||
return new File(path + KEYS_FILE_POSTFIX).exists();
|
||||
}
|
||||
|
||||
public MoneroWalletRpc createWallet(String walletName) {
|
||||
log.info("{}.createWallet({})", getClass().getSimpleName(), walletName);
|
||||
if (isShutDownStarted) throw new IllegalStateException("Cannot create wallet because shutting down");
|
||||
return createWalletRpc(new MoneroWalletConfig()
|
||||
.setPath(walletName)
|
||||
.setPassword(getWalletPassword()),
|
||||
null);
|
||||
public MoneroWallet createWallet(String walletName) {
|
||||
return createWallet(walletName, null);
|
||||
}
|
||||
|
||||
public MoneroWalletRpc openWallet(String walletName, boolean applyProxyUri) {
|
||||
public MoneroWallet createWallet(String walletName, Integer walletRpcPort) {
|
||||
log.info("{}.createWallet({})", getClass().getSimpleName(), walletName);
|
||||
if (isShutDownStarted) throw new IllegalStateException("Cannot create wallet because shutting down");
|
||||
MoneroWalletConfig config = getWalletConfig(walletName);
|
||||
return isNativeLibraryApplied() ? createWalletFull(config) : createWalletRpc(config, walletRpcPort);
|
||||
}
|
||||
|
||||
public MoneroWallet openWallet(String walletName, boolean applyProxyUri) {
|
||||
return openWallet(walletName, null, applyProxyUri);
|
||||
}
|
||||
|
||||
public MoneroWallet openWallet(String walletName, Integer walletRpcPort, boolean applyProxyUri) {
|
||||
log.info("{}.openWallet({})", getClass().getSimpleName(), walletName);
|
||||
if (isShutDownStarted) throw new IllegalStateException("Cannot open wallet because shutting down");
|
||||
return openWalletRpc(new MoneroWalletConfig()
|
||||
.setPath(walletName)
|
||||
.setPassword(getWalletPassword()),
|
||||
null,
|
||||
applyProxyUri);
|
||||
MoneroWalletConfig config = getWalletConfig(walletName);
|
||||
return isNativeLibraryApplied() ? openWalletFull(config, applyProxyUri) : openWalletRpc(config, walletRpcPort, applyProxyUri);
|
||||
}
|
||||
|
||||
private MoneroWalletConfig getWalletConfig(String walletName) {
|
||||
String walletConfigPath = (isNativeLibraryApplied() ? walletDir.getPath() + File.separator : "") + walletName;
|
||||
MoneroWalletConfig config = new MoneroWalletConfig().setPath(walletConfigPath).setPassword(getWalletPassword());
|
||||
if (isNativeLibraryApplied()) config.setNetworkType(getMoneroNetworkType());
|
||||
return config;
|
||||
}
|
||||
|
||||
private boolean isNativeLibraryApplied() {
|
||||
return useNativeXmrWallet && MoneroUtils.isNativeLibraryLoaded();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -377,8 +396,12 @@ public class XmrWalletService {
|
||||
}
|
||||
|
||||
public void stopWallet(MoneroWallet wallet, String path, boolean force) {
|
||||
|
||||
// only wallet rpc process needs stopped
|
||||
if (wallet instanceof MoneroWalletRpc) {
|
||||
MONERO_WALLET_RPC_MANAGER.stopInstance((MoneroWalletRpc) wallet, path, force);
|
||||
}
|
||||
}
|
||||
|
||||
public void deleteWallet(String walletName) {
|
||||
log.info("{}.deleteWallet({})", getClass().getSimpleName(), walletName);
|
||||
@ -805,6 +828,18 @@ public class XmrWalletService {
|
||||
walletInitListener = (obs, oldVal, newVal) -> initMainWalletIfConnected();
|
||||
xmrConnectionService.downloadPercentageProperty().addListener(walletInitListener);
|
||||
initMainWalletIfConnected();
|
||||
|
||||
// try to load native monero library
|
||||
if (useNativeXmrWallet && !MoneroUtils.isNativeLibraryLoaded()) {
|
||||
try {
|
||||
MoneroUtils.loadNativeLibrary();
|
||||
} catch (Exception | UnsatisfiedLinkError e) {
|
||||
log.warn("Failed to load Monero native libraries: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
String appliedMsg = "Monero native libraries applied: " + isNativeLibraryApplied();
|
||||
if (useNativeXmrWallet && !isNativeLibraryApplied()) log.warn(appliedMsg);
|
||||
else log.info(appliedMsg);
|
||||
}
|
||||
|
||||
private void initMainWalletIfConnected() {
|
||||
@ -823,6 +858,7 @@ public class XmrWalletService {
|
||||
}
|
||||
|
||||
private void maybeInitMainWallet(boolean sync, int numAttempts) {
|
||||
|
||||
synchronized (walletLock) {
|
||||
if (isShutDownStarted) return;
|
||||
|
||||
@ -830,11 +866,10 @@ public class XmrWalletService {
|
||||
if (wallet == null) {
|
||||
MoneroDaemonRpc daemon = xmrConnectionService.getDaemon();
|
||||
log.info("Initializing main wallet with monerod=" + (daemon == null ? "null" : daemon.getRpcConnection().getUri()));
|
||||
MoneroWalletConfig walletConfig = new MoneroWalletConfig().setPath(MONERO_WALLET_NAME).setPassword(getWalletPassword());
|
||||
if (MoneroUtils.walletExists(xmrWalletFile.getPath())) {
|
||||
wallet = openWalletRpc(walletConfig, rpcBindPort, isProxyApplied(wasWalletSynced));
|
||||
wallet = openWallet(MONERO_WALLET_NAME, rpcBindPort, isProxyApplied(wasWalletSynced));
|
||||
} else if (xmrConnectionService.getConnection() != null && Boolean.TRUE.equals(xmrConnectionService.getConnection().isConnected())) {
|
||||
wallet = createWalletRpc(walletConfig, rpcBindPort);
|
||||
wallet = createWallet(MONERO_WALLET_NAME, rpcBindPort);
|
||||
|
||||
// set wallet creation date to yesterday to guarantee complete restore
|
||||
LocalDateTime localDateTime = LocalDate.now().atStartOfDay().minusDays(1);
|
||||
@ -845,7 +880,7 @@ public class XmrWalletService {
|
||||
|
||||
// sync wallet and register listener
|
||||
if (wallet != null && !isShutDownStarted) {
|
||||
log.info("Monero wallet uri={}, path={}", wallet.getRpcConnection().getUri(), wallet.getPath());
|
||||
log.info("Monero wallet path={}", wallet.getPath());
|
||||
|
||||
// sync main wallet if applicable
|
||||
if (sync && numAttempts > 0) {
|
||||
@ -946,6 +981,53 @@ public class XmrWalletService {
|
||||
});
|
||||
}
|
||||
|
||||
private MoneroWalletFull createWalletFull(MoneroWalletConfig config) {
|
||||
|
||||
// must be connected to daemon
|
||||
MoneroRpcConnection connection = xmrConnectionService.getConnection();
|
||||
if (connection == null || !Boolean.TRUE.equals(connection.isConnected())) throw new RuntimeException("Must be connected to daemon before creating wallet");
|
||||
|
||||
// create wallet
|
||||
MoneroWalletFull walletFull = null;
|
||||
try {
|
||||
|
||||
// create wallet
|
||||
log.info("Creating full wallet " + config.getPath() + " connected to daemon " + connection.getUri());
|
||||
long time = System.currentTimeMillis();
|
||||
config.setServer(connection);
|
||||
walletFull = MoneroWalletFull.createWallet(config);
|
||||
walletFull.getDaemonConnection().setPrintStackTrace(PRINT_STACK_TRACE);
|
||||
log.info("Done creating full wallet " + config.getPath() + " in " + (System.currentTimeMillis() - time) + " ms");
|
||||
return walletFull;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
if (walletFull != null) stopWallet(walletFull, config.getPath());
|
||||
throw new IllegalStateException("Could not create wallet '" + config.getPath() + "'");
|
||||
}
|
||||
}
|
||||
|
||||
private MoneroWalletFull openWalletFull(MoneroWalletConfig config, boolean applyProxyUri) {
|
||||
MoneroWalletFull walletFull = null;
|
||||
try {
|
||||
|
||||
// configure connection
|
||||
MoneroRpcConnection connection = new MoneroRpcConnection(xmrConnectionService.getConnection());
|
||||
if (!applyProxyUri) connection.setProxyUri(null);
|
||||
|
||||
// open wallet
|
||||
config.setNetworkType(getMoneroNetworkType());
|
||||
config.setServer(connection);
|
||||
walletFull = MoneroWalletFull.openWallet(config);
|
||||
if (walletFull.getDaemonConnection() != null) walletFull.getDaemonConnection().setPrintStackTrace(PRINT_STACK_TRACE);
|
||||
log.info("Done opening full wallet " + config.getPath());
|
||||
return walletFull;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
if (walletFull != null) stopWallet(walletFull, config.getPath());
|
||||
throw new IllegalStateException("Could not open full wallet '" + config.getPath() + "'");
|
||||
}
|
||||
}
|
||||
|
||||
private MoneroWalletRpc createWalletRpc(MoneroWalletConfig config, Integer port) {
|
||||
|
||||
// must be connected to daemon
|
||||
@ -964,11 +1046,12 @@ public class XmrWalletService {
|
||||
walletRpc.stopSyncing();
|
||||
|
||||
// create wallet
|
||||
log.info("Creating wallet " + config.getPath() + " connected to daemon " + connection.getUri());
|
||||
log.info("Creating RPC wallet " + config.getPath() + " connected to daemon " + connection.getUri());
|
||||
long time = System.currentTimeMillis();
|
||||
walletRpc.createWallet(config.setServer(connection));
|
||||
config.setServer(connection);
|
||||
walletRpc.createWallet(config);
|
||||
walletRpc.getDaemonConnection().setPrintStackTrace(PRINT_STACK_TRACE);
|
||||
log.info("Done creating wallet " + config.getPath() + " in " + (System.currentTimeMillis() - time) + " ms");
|
||||
log.info("Done creating RPC wallet " + config.getPath() + " in " + (System.currentTimeMillis() - time) + " ms");
|
||||
return walletRpc;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
@ -993,9 +1076,11 @@ public class XmrWalletService {
|
||||
if (!applyProxyUri) connection.setProxyUri(null);
|
||||
|
||||
// open wallet
|
||||
walletRpc.openWallet(config.setServer(connection));
|
||||
log.info("Opening RPC wallet " + config.getPath() + " connected to daemon " + connection.getUri());
|
||||
config.setServer(connection);
|
||||
walletRpc.openWallet(config);
|
||||
if (walletRpc.getDaemonConnection() != null) walletRpc.getDaemonConnection().setPrintStackTrace(PRINT_STACK_TRACE);
|
||||
log.info("Done opening wallet " + config.getPath());
|
||||
log.info("Done opening RPC wallet " + config.getPath());
|
||||
return walletRpc;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
@ -1060,6 +1145,7 @@ public class XmrWalletService {
|
||||
maybeInitMainWallet(false);
|
||||
} else {
|
||||
wallet.setDaemonConnection(connection);
|
||||
wallet.setProxyUri(connection.getProxyUri());
|
||||
}
|
||||
|
||||
// sync wallet on new thread
|
||||
|
@ -886,9 +886,9 @@
|
||||
<sha256 value="c92e2ca40a3f2474d61e56831aeb379cf8ae3dddeea61b4a828cee2d99f71f38" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="io.github.woodser" name="monero-java" version="0.8.11">
|
||||
<artifact name="monero-java-0.8.11.jar">
|
||||
<sha256 value="37c125a31463c44e43452bc3e18e74a05b65d1fbebb11adc5131521b29b48a6b" origin="Generated by Gradle"/>
|
||||
<component group="io.github.woodser" name="monero-java" version="0.8.21">
|
||||
<artifact name="monero-java-0.8.21.jar">
|
||||
<sha256 value="6389baa853abcbeaa4949ef798f0705d074b1af1a72466cafcb1fb8efbd4e398" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="io.grpc" name="grpc-api" version="1.42.1">
|
||||
|
Loading…
Reference in New Issue
Block a user