From 48e0cac5ab538afd1d59a91a7f0d4b7026f6a7ac Mon Sep 17 00:00:00 2001 From: tecnovert Date: Sat, 9 Jul 2022 23:58:40 +0200 Subject: [PATCH] refactor: Prepare script uses swap_client to create all wallets. --- bin/basicswap_prepare.py | 170 +++++++----------- docker/production/.gitignore | 2 + .../production/compose-fragments/0_start.yml | 25 +++ .../compose-fragments/1_bitcoin.yml | 18 ++ .../compose-fragments/1_litecoin.yml | 14 ++ .../compose-fragments/1_monero-daemon.yml | 18 ++ .../compose-fragments/1_monero-wallet.yml | 16 ++ .../compose-fragments/8_swapclient.yml | 20 +++ .../compose-fragments/9_swapprepare.yml | 44 +++++ docker/production/docker-compose.yml | 155 ---------------- docker/production/notes.md | 24 +++ 11 files changed, 247 insertions(+), 259 deletions(-) create mode 100644 docker/production/compose-fragments/0_start.yml create mode 100644 docker/production/compose-fragments/1_bitcoin.yml create mode 100644 docker/production/compose-fragments/1_litecoin.yml create mode 100644 docker/production/compose-fragments/1_monero-daemon.yml create mode 100644 docker/production/compose-fragments/1_monero-wallet.yml create mode 100644 docker/production/compose-fragments/8_swapclient.yml create mode 100644 docker/production/compose-fragments/9_swapprepare.yml delete mode 100644 docker/production/docker-compose.yml create mode 100644 docker/production/notes.md diff --git a/bin/basicswap_prepare.py b/bin/basicswap_prepare.py index 1ac9e0f..0ea738d 100755 --- a/bin/basicswap_prepare.py +++ b/bin/basicswap_prepare.py @@ -24,10 +24,6 @@ import urllib.parse from urllib.request import urlretrieve import basicswap.config as cfg -from basicswap.rpc import ( - callrpc_cli, - waitForRPC, -) from basicswap.base import getaddrinfo_tor from basicswap.basicswap import BasicSwap from basicswap.chainparams import Coins @@ -586,12 +582,6 @@ def prepareDataDir(coin, settings, chain, particl_mnemonic, extra_opts={}): with tarfile.open(sync_file_path) as ft: ft.extractall(path=data_dir) - # Create the wallet later, no option to set bestblock through wallet_util - else: - wallet_util = coin + '-wallet' - if os.path.exists(os.path.join(bin_dir, wallet_util)): - logger.info('Creating wallet.dat for {}.'.format(wallet_util.capitalize())) - callrpc_cli(bin_dir, data_dir, chain, '-wallet=wallet.dat create', wallet_util) def write_torrc(data_dir, tor_control_password): @@ -702,20 +692,6 @@ def modify_tor_config(settings, coin, tor_control_password=None, enable=False): writeTorSettings(fp, coin, coin_settings, tor_control_password) -def make_rpc_func(bin_dir, data_dir, chain, cli_binary=cfg.PARTICL_CLI): - bin_dir = bin_dir - data_dir = data_dir - chain = chain - - def rpc_func(cmd): - nonlocal bin_dir - nonlocal data_dir - nonlocal chain - - return callrpc_cli(bin_dir, data_dir, chain, cmd, cli_binary) - return rpc_func - - def exitWithError(error_msg): sys.stderr.write('Error: {}, exiting.\n'.format(error_msg)) sys.exit(1) @@ -770,6 +746,67 @@ def finalise_daemon(d): fp.close() +def initialise_wallets(particl_wallet_mnemonic, with_coins, data_dir, settings, chain, use_tor_proxy): + daemons = [] + daemon_args = ['-noconnect', '-nodnsseed'] + if not use_tor_proxy: + # Cannot set -bind or -whitebind together with -listen=0 + daemon_args.append('-nolisten') + try: + with open(os.path.join(data_dir, 'basicswap.log'), 'a') as fp: + swap_client = BasicSwap(fp, data_dir, settings, chain) + + start_daemons = with_coins + if 'particl' not in with_coins: + # Particl must be running to initialise a wallet in addcoin mode + start_daemons.append('particl') + + for coin_name in start_daemons: + coin_settings = settings['chainclients'][coin_name] + c = swap_client.getCoinIdFromName(coin_name) + swap_client.setCoinConnectParams(c) + + if c == Coins.XMR: + if coin_settings['manage_wallet_daemon']: + daemons.append(startXmrWalletDaemon(coin_settings['datadir'], coin_settings['bindir'], 'monero-wallet-rpc')) + else: + if coin_settings['manage_daemon']: + filename = coin_name + 'd' + ('.exe' if os.name == 'nt' else '') + coin_args = ['-nofindpeers', '-nostaking'] if c == Coins.PART else [] + daemons.append(startDaemon(coin_settings['datadir'], coin_settings['bindir'], filename, daemon_args + coin_args)) + swap_client.setDaemonPID(c, daemons[-1].pid) + swap_client.setCoinRunParams(c) + swap_client.createCoinInterface(c) + + if c in (Coins.PART, Coins.BTC, Coins.LTC): + swap_client.waitForDaemonRPC(c, with_wallet=False) + # Create wallet if it doesn't exist yet + wallets = swap_client.callcoinrpc(c, 'listwallets') + if 'wallet.dat' not in wallets: + logger.info('Creating wallet.dat for {}.'.format(coin_name.capitalize())) + swap_client.callcoinrpc(c, 'createwallet', ['wallet.dat']) + + if 'particl' in with_coins: + logger.info('Loading Particl mnemonic') + if particl_wallet_mnemonic is None: + particl_wallet_mnemonic = swap_client.callcoinrpc(Coins.PART, 'mnemonic', ['new'])['mnemonic'] + swap_client.callcoinrpc(Coins.PART, 'extkeyimportmaster', [particl_wallet_mnemonic]) + + for coin_name in with_coins: + c = swap_client.getCoinIdFromName(coin_name) + if c == Coins.PART: + continue + swap_client.waitForDaemonRPC(c) + swap_client.initialiseWallet(c) + + swap_client.finalise() + del swap_client + finally: + for d in daemons: + finalise_daemon(d) + return particl_wallet_mnemonic + + def main(): global use_tor_proxy data_dir = None @@ -1095,21 +1132,7 @@ def main(): if not prepare_bin_only: prepareDataDir(add_coin, settings, chain, particl_wallet_mnemonic, extra_opts) - - if use_btc_fastsync and add_coin == 'bitcoin': - # Need to create wallet file through daemon - logger.info('Creating wallet.dat for {}.'.format(add_coin.capitalize())) - bitcoin_settings = settings['chainclients']['bitcoin'] - try: - btcRpc = make_rpc_func(bitcoin_settings['bindir'], bitcoin_settings['datadir'], chain, cli_binary=cfg.BITCOIN_CLI) - filename = 'bitcoind' + ('.exe' if os.name == 'nt' else '') - daemon_args = ['-noconnect', '-nodnsseed', '-nolisten'] - btcd = startDaemon(bitcoin_settings['datadir'], bitcoin_settings['bindir'], filename, daemon_args) - waitForRPC(btcRpc, expect_wallet=False, max_tries=12) - btcRpc('createwallet wallet.dat') - logger.info('createwallet succeeded.') - finally: - finalise_daemon(btcd) + initialise_wallets(None, [add_coin, ], data_dir, settings, chain, use_tor_proxy) with open(config_path, 'w') as fp: json.dump(settings, fp, indent=4) @@ -1166,71 +1189,10 @@ def main(): logger.info('Done.') return 0 - logger.info('Loading Particl mnemonic') - - particl_settings = settings['chainclients']['particl'] - partRpc = make_rpc_func(particl_settings['bindir'], particl_settings['datadir'], chain) - - daemons = [] - daemon_args = ['-noconnect', '-nodnsseed'] - if not use_tor_proxy: - # Cannot set -bind or -whitebind together with -listen=0 - daemon_args.append('-nolisten') - daemons.append(startDaemon(particl_settings['datadir'], particl_settings['bindir'], cfg.PARTICLD, daemon_args + ['-nofindpeers', '-nostaking'])) - try: - waitForRPC(partRpc) - - if particl_wallet_mnemonic is None: - particl_wallet_mnemonic = partRpc('mnemonic new')['mnemonic'] - partRpc('extkeyimportmaster "{}"'.format(particl_wallet_mnemonic)) - - # Initialise wallets - with open(os.path.join(data_dir, 'basicswap.log'), 'a') as fp: - swap_client = BasicSwap(fp, data_dir, settings, chain) - - swap_client.setCoinConnectParams(Coins.PART) - swap_client.setDaemonPID(Coins.PART, daemons[-1].pid) - swap_client.setCoinRunParams(Coins.PART) - swap_client.createCoinInterface(Coins.PART) - - for coin_name in with_coins: - coin_settings = settings['chainclients'][coin_name] - c = swap_client.getCoinIdFromName(coin_name) - if c == Coins.PART: - continue - - swap_client.setCoinConnectParams(c) - - if c == Coins.XMR: - if not coin_settings['manage_wallet_daemon']: - continue - daemons.append(startXmrWalletDaemon(coin_settings['datadir'], coin_settings['bindir'], 'monero-wallet-rpc')) - else: - if not coin_settings['manage_daemon']: - continue - filename = coin_name + 'd' + ('.exe' if os.name == 'nt' else '') - daemons.append(startDaemon(coin_settings['datadir'], coin_settings['bindir'], filename, daemon_args)) - swap_client.setDaemonPID(c, daemons[-1].pid) - swap_client.setCoinRunParams(c) - swap_client.createCoinInterface(c) - - # Create wallet if it doesn't exist yet - if c == Coins.BTC: - swap_client.waitForDaemonRPC(c, with_wallet=False) - wallets = swap_client.callcoinrpc(c, 'listwallets') - if 'wallet.dat' not in wallets: - swap_client.callcoinrpc(c, 'createwallet', ['wallet.dat']) - - swap_client.waitForDaemonRPC(c) - swap_client.initialiseWallet(c) - swap_client.finalise() - del swap_client - finally: - for d in daemons: - finalise_daemon(d) - - # Print directly to stdout for tests - print('IMPORTANT - Save your particl wallet recovery phrase:\n{}\n'.format(particl_wallet_mnemonic)) + particl_wallet_mnemonic = initialise_wallets(particl_wallet_mnemonic, with_coins, data_dir, settings, chain, use_tor_proxy) + if particl_wallet_mnemonic: + # Print directly to stdout for tests + print('IMPORTANT - Save your particl wallet recovery phrase:\n{}\n'.format(particl_wallet_mnemonic)) print('Done.') diff --git a/docker/production/.gitignore b/docker/production/.gitignore index 4c49bd7..3d7f25c 100644 --- a/docker/production/.gitignore +++ b/docker/production/.gitignore @@ -1 +1,3 @@ .env +docker-compose-prepare.yml +docker-compose.yml diff --git a/docker/production/compose-fragments/0_start.yml b/docker/production/compose-fragments/0_start.yml new file mode 100644 index 0000000..4d4943a --- /dev/null +++ b/docker/production/compose-fragments/0_start.yml @@ -0,0 +1,25 @@ +version: '3.3' + +networks: + default: + external: + name: coinswap_network +services: + particl_core: + image: i_particl + build: + context: particl + dockerfile: Dockerfile + container_name: particl_core + volumes: + - ${DATA_PATH}/particl:/data + #ports: + # - "51738:51738" + expose: + - 51735 + logging: + driver: "json-file" + options: + max-size: "10m" + max-file: "3" + restart: unless-stopped diff --git a/docker/production/compose-fragments/1_bitcoin.yml b/docker/production/compose-fragments/1_bitcoin.yml new file mode 100644 index 0000000..0a18417 --- /dev/null +++ b/docker/production/compose-fragments/1_bitcoin.yml @@ -0,0 +1,18 @@ + bitcoin_core: + image: i_bitcoin + build: + context: bitcoin + dockerfile: Dockerfile + container_name: bitcoin_core + volumes: + - ${DATA_PATH}/bitcoin:/data + #ports: + # - "8333:8333" + expose: + - 8332 + logging: + driver: "json-file" + options: + max-size: "10m" + max-file: "3" + restart: unless-stopped diff --git a/docker/production/compose-fragments/1_litecoin.yml b/docker/production/compose-fragments/1_litecoin.yml new file mode 100644 index 0000000..99f4d89 --- /dev/null +++ b/docker/production/compose-fragments/1_litecoin.yml @@ -0,0 +1,14 @@ + litecoin_core: + image: i_litecoin + build: + context: litecoin + dockerfile: Dockerfile + container_name: litecoin_core + volumes: + - ${DATA_PATH}/litecoin:/data + logging: + driver: "json-file" + options: + max-size: "10m" + max-file: "3" + restart: unless-stopped diff --git a/docker/production/compose-fragments/1_monero-daemon.yml b/docker/production/compose-fragments/1_monero-daemon.yml new file mode 100644 index 0000000..355f88e --- /dev/null +++ b/docker/production/compose-fragments/1_monero-daemon.yml @@ -0,0 +1,18 @@ + monero_daemon: + image: i_monero_daemon + build: + context: monero_daemon + dockerfile: Dockerfile + container_name: monero_daemon + volumes: + - ${DATA_PATH}/monero_daemon:/data + #ports: + # - "18080:18080" + expose: + - 8332 + logging: + driver: "json-file" + options: + max-size: "10m" + max-file: "3" + restart: unless-stopped diff --git a/docker/production/compose-fragments/1_monero-wallet.yml b/docker/production/compose-fragments/1_monero-wallet.yml new file mode 100644 index 0000000..0b5b091 --- /dev/null +++ b/docker/production/compose-fragments/1_monero-wallet.yml @@ -0,0 +1,16 @@ + monero_wallet: + image: i_monero_wallet + build: + context: monero_wallet + dockerfile: Dockerfile + container_name: monero_wallet + volumes: + - ${DATA_PATH}/monero_wallet:/data + expose: + - 8332 + logging: + driver: "json-file" + options: + max-size: "10m" + max-file: "3" + restart: unless-stopped diff --git a/docker/production/compose-fragments/8_swapclient.yml b/docker/production/compose-fragments/8_swapclient.yml new file mode 100644 index 0000000..f80165e --- /dev/null +++ b/docker/production/compose-fragments/8_swapclient.yml @@ -0,0 +1,20 @@ + swapclient: + image: i_swapclient + build: + context: swapclient + dockerfile: Dockerfile + container_name: swapclient + volumes: + - ${DATA_PATH}/swapclient:/data + ports: + - "${HTML_PORT}" # Expose only to localhost, see .env + environment: + - TZ + logging: + driver: "json-file" + options: + max-size: "10m" + max-file: "5" + depends_on: + - particl_core + restart: unless-stopped diff --git a/docker/production/compose-fragments/9_swapprepare.yml b/docker/production/compose-fragments/9_swapprepare.yml new file mode 100644 index 0000000..02f2f9f --- /dev/null +++ b/docker/production/compose-fragments/9_swapprepare.yml @@ -0,0 +1,44 @@ + swapprepare: + image: i_swapclient + build: + context: swapclient + dockerfile: Dockerfile + container_name: swapprepare + volumes: + - ${DATA_PATH}/swapclient:/data/swapclient + - ${DATA_PATH}/monero_daemon:/data/monero_daemon + - ${DATA_PATH}/monero_wallet:/data/monero_wallet + - ${DATA_PATH}/particl:/data/particl + - ${DATA_PATH}/bitcoin:/data/bitcoin + - ${DATA_PATH}/litecoin:/data/litecoin + environment: + - TZ + - PART_RPC_HOST + - LTC_RPC_HOST + - BTC_RPC_HOST + - PART_RPC_PORT + - LTC_RPC_PORT + - BTC_RPC_PORT + - XMR_RPC_HOST + - BASE_XMR_RPC_PORT + - BASE_XMR_ZMQ_PORT + - BASE_XMR_WALLET_PORT + - XMR_WALLET_RPC_HOST + - XMR_WALLET_RPC_USER + - XMR_WALLET_RPC_PWD + - DEFAULT_XMR_RESTORE_HEIGHT + - UI_HTML_PORT + - PART_ZMQ_PORT + - PART_RPC_USER + - PART_RPC_PWD + - BTC_RPC_USER + - BTC_RPC_PWD + - LTC_RPC_USER + - LTC_RPC_PWD + - PART_DATA_DIR + - LTC_DATA_DIR + - BTC_DATA_DIR + - XMR_DATA_DIR + - XMR_WALLETS_DIR + - COINS_RPCBIND_IP + restart: "no" diff --git a/docker/production/docker-compose.yml b/docker/production/docker-compose.yml deleted file mode 100644 index ba9af16..0000000 --- a/docker/production/docker-compose.yml +++ /dev/null @@ -1,155 +0,0 @@ -version: '3.3' - -services: - particl_core: - image: i_particl - build: - context: particl - dockerfile: Dockerfile - container_name: particl_core - volumes: - - ${DATA_PATH}/particl:/data - #ports: - # - "51738:51738" - expose: - - 51735 - logging: - driver: "json-file" - options: - max-size: "10m" - max-file: "3" - #restart: unless-stopped - #bitcoin_core: - #image: i_bitcoin - #build: - #context: bitcoin - #dockerfile: Dockerfile - #container_name: bitcoin_core - #volumes: - #- ${DATA_PATH}/bitcoin:/data - ##ports: - ## - "8333:8333" - #expose: - #- 8332 - #logging: - #driver: "json-file" - #options: - #max-size: "10m" - #max-file: "3" - #restart: unless-stopped - litecoin_core: - image: i_litecoin - build: - context: litecoin - dockerfile: Dockerfile - container_name: litecoin_core - volumes: - - ${DATA_PATH}/litecoin:/data - logging: - driver: "json-file" - options: - max-size: "10m" - max-file: "3" - #restart: unless-stopped - #monero_daemon: - #image: i_monero_daemon - #build: - #context: monero_daemon - #dockerfile: Dockerfile - #container_name: monero_daemon - #volumes: - #- ${DATA_PATH}/monero_daemon:/data - #ports: - #- "18080:18080" - #expose: - #- 8332 - #logging: - #driver: "json-file" - #options: - #max-size: "10m" - #max-file: "3" - #restart: unless-stopped - #monero_wallet: - #image: i_monero_wallet - #build: - #context: monero_wallet - #dockerfile: Dockerfile - #container_name: monero_wallet - #volumes: - #- ${DATA_PATH}/monero_wallet:/data - #expose: - #- 8332 - #logging: - #driver: "json-file" - #options: - #max-size: "10m" - #max-file: "3" - #restart: unless-stopped - swapclient: - image: i_swapclient - build: - context: swapclient - dockerfile: Dockerfile - container_name: swapclient - volumes: - - ${DATA_PATH}/swapclient:/data - ports: - - "${HTML_PORT}" # Expose only to localhost, see .env - environment: - - TZ - logging: - driver: "json-file" - options: - max-size: "10m" - max-file: "5" - depends_on: - - particl_core - restart: unless-stopped - swapprepare: - image: i_swapclient - build: - context: swapclient - dockerfile: Dockerfile - container_name: swapprepare - volumes: - - ${DATA_PATH}/swapclient:/data/swapclient - - ${DATA_PATH}/monero_daemon:/data/monero_daemon - - ${DATA_PATH}/monero_wallet:/data/monero_wallet - - ${DATA_PATH}/particl:/data/particl - - ${DATA_PATH}/bitcoin:/data/bitcoin - - ${DATA_PATH}/litecoin:/data/litecoin - environment: - - TZ - - PART_RPC_HOST - - LTC_RPC_HOST - - BTC_RPC_HOST - - PART_RPC_PORT - - LTC_RPC_PORT - - BTC_RPC_PORT - - XMR_RPC_HOST - - BASE_XMR_RPC_PORT - - BASE_XMR_ZMQ_PORT - - BASE_XMR_WALLET_PORT - - XMR_WALLET_RPC_HOST - - XMR_WALLET_RPC_USER - - XMR_WALLET_RPC_PWD - - DEFAULT_XMR_RESTORE_HEIGHT - - UI_HTML_PORT - - PART_ZMQ_PORT - - PART_RPC_USER - - PART_RPC_PWD - - BTC_RPC_USER - - BTC_RPC_PWD - - LTC_RPC_USER - - LTC_RPC_PWD - - PART_DATA_DIR - - LTC_DATA_DIR - - BTC_DATA_DIR - - XMR_DATA_DIR - - XMR_WALLETS_DIR - - COINS_RPCBIND_IP - restart: "no" -networks: - default: - external: - name: coinswap_network diff --git a/docker/production/notes.md b/docker/production/notes.md new file mode 100644 index 0000000..e7c478e --- /dev/null +++ b/docker/production/notes.md @@ -0,0 +1,24 @@ + + +Copy and edit .env config: + + $ cp example.env .env + + +Create docker-compose config: + + cat compose-fragments/0_start.yml > docker-compose.yml + + # Add the relevant coin fragments + cat compose-fragments/1_bitcoin.yml >> docker-compose.yml + cat compose-fragments/1_litecoin.yml >> docker-compose.yml + cat compose-fragments/1_monero-daemon.yml >> docker-compose.yml + cat compose-fragments/1_monero-wallet.yml >> docker-compose.yml + + cat compose-fragments/8_swapclient.yml >> docker-compose.yml + + # Copy for prepare script config + cp docker-compose.yml docker-compose-prepare.yml + cat compose-fragments/9_swapprepare.yml >> docker-compose-prepare.yml + +