docker: Fix and document isolated coins config.

2024-05-20_merge
tecnovert 2 years ago
parent 48e0cac5ab
commit e03f32ea5f
No known key found for this signature in database
GPG Key ID: 8ED6D8750C4E3F93
  1. 2
      Dockerfile
  2. 6
      basicswap/base.py
  3. 4
      basicswap/config.py
  4. 2
      basicswap/interface_xmr.py
  5. 98
      bin/basicswap_prepare.py
  6. 4
      bin/basicswap_run.py
  7. 22
      docker/production/.env
  8. 6
      docker/production/compose-fragments/0_start.yml
  9. 4
      docker/production/compose-fragments/1_bitcoin.yml
  10. 2
      docker/production/compose-fragments/1_litecoin.yml
  11. 2
      docker/production/compose-fragments/1_monero-wallet.yml
  12. 16
      docker/production/compose-fragments/2_tor.yml
  13. 4
      docker/production/compose-fragments/8_monero-daemon.yml
  14. 37
      docker/production/compose-fragments/9_swapprepare.yml
  15. 33
      docker/production/example.env
  16. 3
      docker/production/monero_daemon/Dockerfile
  17. 3
      docker/production/monero_wallet/Dockerfile
  18. 73
      docker/production/notes.md
  19. 2
      docker/production/swapclient/Dockerfile
  20. 8
      docker/production/tor/Dockerfile

@ -12,7 +12,7 @@ RUN wget -O protobuf_src.tar.gz https://github.com/protocolbuffers/protobuf/rele
tar xvf protobuf_src.tar.gz && \ tar xvf protobuf_src.tar.gz && \
cd protobuf-3.21.1 && \ cd protobuf-3.21.1 && \
./configure --prefix=/usr && \ ./configure --prefix=/usr && \
make install && \ make -j$(nproc) install && \
ldconfig ldconfig
ARG COINCURVE_VERSION=v0.1 ARG COINCURVE_VERSION=v0.1

@ -118,10 +118,12 @@ class BaseApp:
return bytes(segwit_addr.decode(chainparams[coin_type][self.chain]['hrp'], addr)[1]) return bytes(segwit_addr.decode(chainparams[coin_type][self.chain]['hrp'], addr)[1])
def callrpc(self, method, params=[], wallet=None): def callrpc(self, method, params=[], wallet=None):
return callrpc(self.coin_clients[Coins.PART]['rpcport'], self.coin_clients[Coins.PART]['rpcauth'], method, params, wallet) cc = self.coin_clients[Coins.PART]
return callrpc(cc['rpcport'], cc['rpcauth'], method, params, wallet, cc['rpchost'])
def callcoinrpc(self, coin, method, params=[], wallet=None): def callcoinrpc(self, coin, method, params=[], wallet=None):
return callrpc(self.coin_clients[coin]['rpcport'], self.coin_clients[coin]['rpcauth'], method, params, wallet) cc = self.coin_clients[coin]
return callrpc(cc['rpcport'], cc['rpcauth'], method, params, wallet, cc['rpchost'])
def calltx(self, cmd): def calltx(self, cmd):
bindir = self.coin_clients[Coins.PART]['bindir'] bindir = self.coin_clients[Coins.PART]['bindir']

@ -1,13 +1,13 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (c) 2019 tecnovert # Copyright (c) 2019-2022 tecnovert
# Distributed under the MIT software license, see the accompanying # Distributed under the MIT software license, see the accompanying
# file LICENSE or http://www.opensource.org/licenses/mit-license.php. # file LICENSE or http://www.opensource.org/licenses/mit-license.php.
import os import os
CONFIG_FILENAME = 'basicswap.json' CONFIG_FILENAME = 'basicswap.json'
DEFAULT_DATADIR = '~/.basicswap' BASICSWAP_DATADIR = os.getenv('BASICSWAP_DATADIR', '~/.basicswap')
DEFAULT_ALLOW_CORS = False DEFAULT_ALLOW_CORS = False
TEST_DATADIRS = os.path.expanduser(os.getenv('DATADIRS', '/tmp/basicswap')) TEST_DATADIRS = os.path.expanduser(os.getenv('DATADIRS', '/tmp/basicswap'))
DEFAULT_TEST_BINDIR = os.path.expanduser(os.getenv('DEFAULT_TEST_BINDIR', '~/tmp/bin')) DEFAULT_TEST_BINDIR = os.path.expanduser(os.getenv('DEFAULT_TEST_BINDIR', '~/tmp/bin'))

@ -67,7 +67,7 @@ class XMRInterface(CoinInterface):
super().__init__(network) super().__init__(network)
self.rpc_cb = make_xmr_rpc_func(coin_settings['rpcport'], host=coin_settings.get('rpchost', '127.0.0.1')) self.rpc_cb = make_xmr_rpc_func(coin_settings['rpcport'], host=coin_settings.get('rpchost', '127.0.0.1'))
self.rpc_cb2 = make_xmr_rpc2_func(coin_settings['rpcport'], host=coin_settings.get('rpchost', '127.0.0.1')) # non-json endpoint self.rpc_cb2 = make_xmr_rpc2_func(coin_settings['rpcport'], host=coin_settings.get('rpchost', '127.0.0.1')) # non-json endpoint
self.rpc_wallet_cb = make_xmr_wallet_rpc_func(coin_settings['walletrpcport'], coin_settings['walletrpcauth']) self.rpc_wallet_cb = make_xmr_wallet_rpc_func(coin_settings['walletrpcport'], coin_settings['walletrpcauth'], host=coin_settings.get('walletrpchost', '127.0.0.1'))
self.blocks_confirmed = coin_settings['blocks_confirmed'] self.blocks_confirmed = coin_settings['blocks_confirmed']
self._restore_height = coin_settings.get('restore_height', 0) self._restore_height = coin_settings.get('restore_height', 0)

@ -87,7 +87,7 @@ XMR_WALLET_RPC_USER = os.getenv('XMR_WALLET_RPC_USER', 'xmr_wallet_user')
XMR_WALLET_RPC_PWD = os.getenv('XMR_WALLET_RPC_PWD', 'xmr_wallet_pwd') XMR_WALLET_RPC_PWD = os.getenv('XMR_WALLET_RPC_PWD', 'xmr_wallet_pwd')
XMR_SITE_COMMIT = 'abcf12c4ccac3e48bb4ff178f18bb8a95d94b029' # Lock hashes.txt to monero version XMR_SITE_COMMIT = 'abcf12c4ccac3e48bb4ff178f18bb8a95d94b029' # Lock hashes.txt to monero version
DEFAULT_XMR_RESTORE_HEIGHT = 2245107 DEFAULT_XMR_RESTORE_HEIGHT = int(os.getenv('DEFAULT_XMR_RESTORE_HEIGHT', 2245107))
UI_HTML_PORT = int(os.getenv('UI_HTML_PORT', 12700)) UI_HTML_PORT = int(os.getenv('UI_HTML_PORT', 12700))
PART_ZMQ_PORT = int(os.getenv('PART_ZMQ_PORT', 20792)) PART_ZMQ_PORT = int(os.getenv('PART_ZMQ_PORT', 20792))
@ -125,6 +125,7 @@ TEST_ONION_LINK = toBool(os.getenv('TEST_ONION_LINK', 'false'))
BITCOIN_FASTSYNC_URL = os.getenv('BITCOIN_FASTSYNC_URL', 'http://utxosets.blob.core.windows.net/public/') BITCOIN_FASTSYNC_URL = os.getenv('BITCOIN_FASTSYNC_URL', 'http://utxosets.blob.core.windows.net/public/')
BITCOIN_FASTSYNC_FILE = os.getenv('BITCOIN_FASTSYNC_FILE', 'utxo-snapshot-bitcoin-mainnet-720179.tar') BITCOIN_FASTSYNC_FILE = os.getenv('BITCOIN_FASTSYNC_FILE', 'utxo-snapshot-bitcoin-mainnet-720179.tar')
use_tor_proxy = False use_tor_proxy = False
default_socket = socket.socket default_socket = socket.socket
@ -461,7 +462,11 @@ def prepareDataDir(coin, settings, chain, particl_mnemonic, extra_opts={}):
fp.write('restricted-rpc=1\n') fp.write('restricted-rpc=1\n')
if chain == 'testnet': if chain == 'testnet':
fp.write('testnet=1\n') fp.write('testnet=1\n')
fp.write('data-dir={}\n'.format(data_dir)) config_datadir = data_dir
if core_settings['manage_daemon'] is False:
# Assume conf file is for isolated coin docker setup
config_datadir = '/data'
fp.write(f'data-dir={config_datadir}\n')
fp.write('rpc-bind-port={}\n'.format(core_settings['rpcport'])) fp.write('rpc-bind-port={}\n'.format(core_settings['rpcport']))
fp.write('rpc-bind-ip={}\n'.format(COINS_RPCBIND_IP)) fp.write('rpc-bind-ip={}\n'.format(COINS_RPCBIND_IP))
fp.write('zmq-rpc-bind-port={}\n'.format(core_settings['zmqport'])) fp.write('zmq-rpc-bind-port={}\n'.format(core_settings['zmqport']))
@ -487,9 +492,13 @@ def prepareDataDir(coin, settings, chain, particl_mnemonic, extra_opts={}):
fp.write('no-dns=1\n') fp.write('no-dns=1\n')
fp.write('rpc-bind-port={}\n'.format(core_settings['walletrpcport'])) fp.write('rpc-bind-port={}\n'.format(core_settings['walletrpcport']))
fp.write('rpc-bind-ip={}\n'.format(COINS_RPCBIND_IP)) fp.write('rpc-bind-ip={}\n'.format(COINS_RPCBIND_IP))
fp.write('wallet-dir={}\n'.format(os.path.join(data_dir, 'wallets'))) config_datadir = os.path.join(data_dir, 'wallets')
fp.write('log-file={}\n'.format(os.path.join(data_dir, 'wallet.log'))) if core_settings['manage_wallet_daemon'] is False:
fp.write('shared-ringdb-dir={}\n'.format(os.path.join(data_dir, 'shared-ringdb'))) # Assume conf file is for isolated coin docker setup
config_datadir = '/data'
fp.write(f'wallet-dir={config_datadir}\n')
fp.write('log-file={}\n'.format(os.path.join(config_datadir, 'wallet.log')))
fp.write('shared-ringdb-dir={}\n'.format(os.path.join(config_datadir, 'shared-ringdb')))
fp.write('rpc-login={}:{}\n'.format(core_settings['walletrpcuser'], core_settings['walletrpcpassword'])) fp.write('rpc-login={}:{}\n'.format(core_settings['walletrpcuser'], core_settings['walletrpcpassword']))
if tor_control_password is not None: if tor_control_password is not None:
@ -532,7 +541,7 @@ def prepareDataDir(coin, settings, chain, particl_mnemonic, extra_opts={}):
fp.write('staking=0\n') fp.write('staking=0\n')
if PART_RPC_USER != '': if PART_RPC_USER != '':
fp.write('rpcauth={}:{}${}\n'.format(PART_RPC_USER, salt, password_to_hmac(salt, PART_RPC_PWD))) fp.write('rpcauth={}:{}${}\n'.format(PART_RPC_USER, salt, password_to_hmac(salt, PART_RPC_PWD)))
if particl_mnemonic == 'none': if particl_mnemonic == 'auto':
fp.write('createdefaultmasterkey=1') fp.write('createdefaultmasterkey=1')
elif coin == 'litecoin': elif coin == 'litecoin':
fp.write('prune=4000\n') fp.write('prune=4000\n')
@ -710,13 +719,14 @@ def printHelp():
logger.info('Usage: basicswap-prepare ') logger.info('Usage: basicswap-prepare ')
logger.info('\n--help, -h Print help.') logger.info('\n--help, -h Print help.')
logger.info('--version, -v Print version.') logger.info('--version, -v Print version.')
logger.info('--datadir=PATH Path to basicswap data directory, default:{}.'.format(cfg.DEFAULT_DATADIR)) logger.info('--datadir=PATH Path to basicswap data directory, default:{}.'.format(cfg.BASICSWAP_DATADIR))
logger.info('--bindir=PATH Path to cores directory, default:datadir/bin.') logger.info('--bindir=PATH Path to cores directory, default:datadir/bin.')
logger.info('--mainnet Run in mainnet mode.') logger.info('--mainnet Run in mainnet mode.')
logger.info('--testnet Run in testnet mode.') logger.info('--testnet Run in testnet mode.')
logger.info('--regtest Run in regtest mode.') logger.info('--regtest Run in regtest mode.')
logger.info('--particl_mnemonic= Recovery phrase to use for the Particl wallet, default is randomly generated,\n' logger.info('--particl_mnemonic= Recovery phrase to use for the Particl wallet, default is randomly generated,\n'
+ ' "none" to set autogenerate account mode.') + ' "auto" to create a wallet automatically - No mnemonic.'
+ ' "none" to disable wallet initialisation.')
logger.info('--withcoin= Prepare system to run daemon for coin.') logger.info('--withcoin= Prepare system to run daemon for coin.')
logger.info('--withoutcoin= Do not prepare system to run daemon for coin.') logger.info('--withoutcoin= Do not prepare system to run daemon for coin.')
logger.info('--addcoin= Add coin to existing setup.') logger.info('--addcoin= Add coin to existing setup.')
@ -733,6 +743,7 @@ def printHelp():
logger.info('--disabletor Setup Basicswap instance to not use TOR.') logger.info('--disabletor Setup Basicswap instance to not use TOR.')
logger.info('--usebtcfastsync Initialise the BTC chain with a snapshot from btcpayserver FastSync.\n' logger.info('--usebtcfastsync Initialise the BTC chain with a snapshot from btcpayserver FastSync.\n'
+ ' See https://github.com/btcpayserver/btcpayserver-docker/blob/master/contrib/FastSync/README.md') + ' See https://github.com/btcpayserver/btcpayserver-docker/blob/master/contrib/FastSync/README.md')
logger.info('--initwalletsonly Setup coin wallets only.')
logger.info('\n' + 'Known coins: %s', ', '.join(known_coins.keys())) logger.info('\n' + 'Known coins: %s', ', '.join(known_coins.keys()))
@ -764,7 +775,6 @@ def initialise_wallets(particl_wallet_mnemonic, with_coins, data_dir, settings,
for coin_name in start_daemons: for coin_name in start_daemons:
coin_settings = settings['chainclients'][coin_name] coin_settings = settings['chainclients'][coin_name]
c = swap_client.getCoinIdFromName(coin_name) c = swap_client.getCoinIdFromName(coin_name)
swap_client.setCoinConnectParams(c)
if c == Coins.XMR: if c == Coins.XMR:
if coin_settings['manage_wallet_daemon']: if coin_settings['manage_wallet_daemon']:
@ -804,7 +814,18 @@ def initialise_wallets(particl_wallet_mnemonic, with_coins, data_dir, settings,
finally: finally:
for d in daemons: for d in daemons:
finalise_daemon(d) finalise_daemon(d)
return particl_wallet_mnemonic
if particl_wallet_mnemonic is not None:
if particl_wallet_mnemonic:
# Print directly to stdout for tests
print('IMPORTANT - Save your particl wallet recovery phrase:\n{}\n'.format(particl_wallet_mnemonic))
def load_config(config_path):
if not os.path.exists(config_path):
exitWithError('{} does not exist'.format(config_path))
with open(config_path) as fs:
return json.load(fs)
def main(): def main():
@ -814,19 +835,20 @@ def main():
port_offset = None port_offset = None
chain = 'mainnet' chain = 'mainnet'
particl_wallet_mnemonic = None particl_wallet_mnemonic = None
prepare_bin_only = False
no_cores = False
use_containers = False
with_coins = {'particl', } with_coins = {'particl', }
add_coin = '' add_coin = ''
disable_coin = '' disable_coin = ''
htmlhost = '127.0.0.1' htmlhost = '127.0.0.1'
xmr_restore_height = DEFAULT_XMR_RESTORE_HEIGHT xmr_restore_height = DEFAULT_XMR_RESTORE_HEIGHT
prepare_bin_only = False
no_cores = False
use_containers = False
enable_tor = False enable_tor = False
disable_tor = False disable_tor = False
tor_control_password = None tor_control_password = None
use_btc_fastsync = False use_btc_fastsync = False
extract_core_overwrite = True extract_core_overwrite = True
initwalletsonly = False
for v in sys.argv[1:]: for v in sys.argv[1:]:
if len(v) < 2 or v[0] != '-': if len(v) < 2 or v[0] != '-':
@ -877,6 +899,9 @@ def main():
if name == 'usebtcfastsync': if name == 'usebtcfastsync':
use_btc_fastsync = True use_btc_fastsync = True
continue continue
if name == 'initwalletsonly':
initwalletsonly = True
continue
if len(s) == 2: if len(s) == 2:
if name == 'datadir': if name == 'datadir':
data_dir = os.path.expanduser(s[1].strip('"')) data_dir = os.path.expanduser(s[1].strip('"'))
@ -933,7 +958,7 @@ def main():
testOnionLink() testOnionLink()
if data_dir is None: if data_dir is None:
data_dir = os.path.join(os.path.expanduser(cfg.DEFAULT_DATADIR)) data_dir = os.path.join(os.path.expanduser(cfg.BASICSWAP_DATADIR))
if bin_dir is None: if bin_dir is None:
bin_dir = os.path.join(data_dir, 'bin') bin_dir = os.path.join(data_dir, 'bin')
@ -1037,13 +1062,20 @@ def main():
chainclients['monero']['walletsdir'] = os.getenv('XMR_WALLETS_DIR', chainclients['monero']['datadir']) chainclients['monero']['walletsdir'] = os.getenv('XMR_WALLETS_DIR', chainclients['monero']['datadir'])
if initwalletsonly:
logger.info('Initialising wallets')
settings = load_config(config_path)
init_coins = settings['chainclients'].keys()
logger.info('Active coins: %s', ', '.join(init_coins))
initialise_wallets(particl_wallet_mnemonic, init_coins, data_dir, settings, chain, use_tor_proxy)
print('Done.')
return 0
if enable_tor: if enable_tor:
logger.info('Enabling TOR') logger.info('Enabling TOR')
settings = load_config(config_path)
if not os.path.exists(config_path):
exitWithError('{} does not exist'.format(config_path))
with open(config_path) as fs:
settings = json.load(fs)
tor_control_password = settings.get('tor_control_password', None) tor_control_password = settings.get('tor_control_password', None)
if tor_control_password is None: if tor_control_password is None:
@ -1063,12 +1095,7 @@ def main():
if disable_tor: if disable_tor:
logger.info('Disabling TOR') logger.info('Disabling TOR')
settings = load_config(config_path)
if not os.path.exists(config_path):
exitWithError('{} does not exist'.format(config_path))
with open(config_path) as fs:
settings = json.load(fs)
settings['use_tor'] = False settings['use_tor'] = False
for coin in settings['chainclients']: for coin in settings['chainclients']:
modify_tor_config(settings, coin, tor_control_password=None, enable=False) modify_tor_config(settings, coin, tor_control_password=None, enable=False)
@ -1081,10 +1108,7 @@ def main():
if disable_coin != '': if disable_coin != '':
logger.info('Disabling coin: %s', disable_coin) logger.info('Disabling coin: %s', disable_coin)
if not os.path.exists(config_path): settings = load_config(config_path)
exitWithError('{} does not exist'.format(config_path))
with open(config_path) as fs:
settings = json.load(fs)
if disable_coin not in settings['chainclients']: if disable_coin not in settings['chainclients']:
exitWithError('{} has not been prepared'.format(disable_coin)) exitWithError('{} has not been prepared'.format(disable_coin))
@ -1107,10 +1131,7 @@ def main():
if add_coin != '': if add_coin != '':
logger.info('Adding coin: %s', add_coin) logger.info('Adding coin: %s', add_coin)
if not os.path.exists(config_path): settings = load_config(config_path)
exitWithError('{} does not exist'.format(config_path))
with open(config_path) as fs:
settings = json.load(fs)
if add_coin in settings['chainclients']: if add_coin in settings['chainclients']:
coin_settings = settings['chainclients'][add_coin] coin_settings = settings['chainclients'][add_coin]
@ -1132,6 +1153,8 @@ def main():
if not prepare_bin_only: if not prepare_bin_only:
prepareDataDir(add_coin, settings, chain, particl_wallet_mnemonic, extra_opts) prepareDataDir(add_coin, settings, chain, particl_wallet_mnemonic, extra_opts)
if particl_wallet_mnemonic not in ('none', 'auto'):
initialise_wallets(None, [add_coin, ], data_dir, settings, chain, use_tor_proxy) initialise_wallets(None, [add_coin, ], data_dir, settings, chain, use_tor_proxy)
with open(config_path, 'w') as fp: with open(config_path, 'w') as fp:
@ -1153,7 +1176,7 @@ def main():
settings = { settings = {
'debug': True, 'debug': True,
'zmqhost': 'tcp://127.0.0.1', 'zmqhost': f'tcp://{PART_RPC_HOST}',
'zmqport': PART_ZMQ_PORT + port_offset, 'zmqport': PART_ZMQ_PORT + port_offset,
'htmlhost': htmlhost, 'htmlhost': htmlhost,
'htmlport': UI_HTML_PORT + port_offset, 'htmlport': UI_HTML_PORT + port_offset,
@ -1185,14 +1208,11 @@ def main():
with open(config_path, 'w') as fp: with open(config_path, 'w') as fp:
json.dump(settings, fp, indent=4) json.dump(settings, fp, indent=4)
if particl_wallet_mnemonic == 'none': if particl_wallet_mnemonic in ('none', 'auto'):
logger.info('Done.') logger.info('Done.')
return 0 return 0
particl_wallet_mnemonic = initialise_wallets(particl_wallet_mnemonic, with_coins, data_dir, settings, chain, use_tor_proxy) 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.') print('Done.')

@ -216,7 +216,7 @@ def printHelp():
logger.info('Usage: basicswap-run ') logger.info('Usage: basicswap-run ')
logger.info('\n--help, -h Print help.') logger.info('\n--help, -h Print help.')
logger.info('--version, -v Print version.') logger.info('--version, -v Print version.')
logger.info('--datadir=PATH Path to basicswap data directory, default:{}.'.format(cfg.DEFAULT_DATADIR)) logger.info('--datadir=PATH Path to basicswap data directory, default:{}.'.format(cfg.BASICSWAP_DATADIR))
logger.info('--mainnet Run in mainnet mode.') logger.info('--mainnet Run in mainnet mode.')
logger.info('--testnet Run in testnet mode.') logger.info('--testnet Run in testnet mode.')
logger.info('--regtest Run in regtest mode.') logger.info('--regtest Run in regtest mode.')
@ -260,7 +260,7 @@ def main():
logger.warning('Unknown argument %s', v) logger.warning('Unknown argument %s', v)
if data_dir is None: if data_dir is None:
data_dir = os.path.join(os.path.expanduser(cfg.DEFAULT_DATADIR)) data_dir = os.path.join(os.path.expanduser(cfg.BASICSWAP_DATADIR))
logger.info('Using datadir: %s', data_dir) logger.info('Using datadir: %s', data_dir)
logger.info('Chain: %s', chain) logger.info('Chain: %s', chain)

@ -1,22 +0,0 @@
HTML_PORT=127.0.0.1:12700:12700
TZ=UTC
DATA_PATH=/mnt/hdd50/docker2
PART_RPC_HOST=particl_core
LTC_RPC_HOST=litecoin_core
BTC_RPC_HOST=bitcoin_core
PART_RPC_USER=particl_user
PART_RPC_PWD=particl_pwd
BTC_RPC_USER=bitcoin_user
BTC_RPC_PWD=bitcoin_pwd
LTC_RPC_USER=litecoin_user
LTC_RPC_PWD=litecoin_pwd
PART_DATA_DIR=/data/particl
LTC_DATA_DIR=/data/litecoin
BTC_DATA_DIR=/data/bitcoin
XMR_DATA_DIR=/data/monero_daemon
XMR_WALLETS_DIR=/data/monero_wallet
COINS_RPCBIND_IP=0.0.0.0

@ -2,7 +2,6 @@ version: '3.3'
networks: networks:
default: default:
external:
name: coinswap_network name: coinswap_network
services: services:
particl_core: particl_core:
@ -13,10 +12,9 @@ services:
container_name: particl_core container_name: particl_core
volumes: volumes:
- ${DATA_PATH}/particl:/data - ${DATA_PATH}/particl:/data
#ports:
# - "51738:51738"
expose: expose:
- 51735 - ${PART_RPC_PORT}
- ${PART_ZMQ_PORT}
logging: logging:
driver: "json-file" driver: "json-file"
options: options:

@ -6,10 +6,8 @@
container_name: bitcoin_core container_name: bitcoin_core
volumes: volumes:
- ${DATA_PATH}/bitcoin:/data - ${DATA_PATH}/bitcoin:/data
#ports:
# - "8333:8333"
expose: expose:
- 8332 - ${BTC_RPC_PORT}
logging: logging:
driver: "json-file" driver: "json-file"
options: options:

@ -6,6 +6,8 @@
container_name: litecoin_core container_name: litecoin_core
volumes: volumes:
- ${DATA_PATH}/litecoin:/data - ${DATA_PATH}/litecoin:/data
expose:
- ${LTC_RPC_PORT}
logging: logging:
driver: "json-file" driver: "json-file"
options: options:

@ -7,7 +7,7 @@
volumes: volumes:
- ${DATA_PATH}/monero_wallet:/data - ${DATA_PATH}/monero_wallet:/data
expose: expose:
- 8332 - ${BASE_XMR_WALLET_PORT}
logging: logging:
driver: "json-file" driver: "json-file"
options: options:

@ -0,0 +1,16 @@
tor:
image: i_tor
container_name: tor
build:
context: ./tor
volumes:
- ${DATA_PATH}/tor/data:/var/lib/tor/
- ${DATA_PATH}/tor/torrc:/etc/tor/torrc
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "5"
networks:
tor_net:
coinswap_network: 172.16.238.200

@ -6,10 +6,8 @@
container_name: monero_daemon container_name: monero_daemon
volumes: volumes:
- ${DATA_PATH}/monero_daemon:/data - ${DATA_PATH}/monero_daemon:/data
#ports:
# - "18080:18080"
expose: expose:
- 8332 - ${BASE_XMR_RPC_PORT}
logging: logging:
driver: "json-file" driver: "json-file"
options: options:

@ -13,32 +13,33 @@
- ${DATA_PATH}/litecoin:/data/litecoin - ${DATA_PATH}/litecoin:/data/litecoin
environment: environment:
- TZ - 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 - UI_HTML_PORT
- COINS_RPCBIND_IP
- BASICSWAP_DATADIR
- PART_DATA_DIR
- PART_RPC_HOST
- PART_ZMQ_PORT - PART_ZMQ_PORT
- PART_RPC_USER - PART_RPC_USER
- PART_RPC_PWD - PART_RPC_PWD
- PART_RPC_PORT
- BTC_DATA_DIR
- BTC_RPC_HOST
- BTC_RPC_PORT
- BTC_RPC_USER - BTC_RPC_USER
- BTC_RPC_PWD - BTC_RPC_PWD
- LTC_DATA_DIR
- LTC_RPC_HOST
- LTC_RPC_PORT
- LTC_RPC_USER - LTC_RPC_USER
- LTC_RPC_PWD - LTC_RPC_PWD
- PART_DATA_DIR
- LTC_DATA_DIR
- BTC_DATA_DIR
- XMR_DATA_DIR - XMR_DATA_DIR
- XMR_RPC_HOST
- BASE_XMR_RPC_PORT
- BASE_XMR_ZMQ_PORT
- XMR_WALLETS_DIR - XMR_WALLETS_DIR
- COINS_RPCBIND_IP - XMR_WALLET_RPC_HOST
- BASE_XMR_WALLET_PORT
- XMR_WALLET_RPC_USER
- XMR_WALLET_RPC_PWD
- DEFAULT_XMR_RESTORE_HEIGHT
restart: "no" restart: "no"

@ -1,21 +1,36 @@
HTML_PORT=127.0.0.1:12700:12700 HTML_PORT=127.0.0.1:12700:12700
TZ=UTC TZ=UTC
DATA_PATH=/var/swapdata/ DATA_PATH=/var/swapdata/
PART_RPC_HOST=particl_core
LTC_RPC_HOST=litecoin_core
BTC_RPC_HOST=bitcoin_core
BASICSWAP_DATADIR=/data/swapclient
COINS_RPCBIND_IP=0.0.0.0
PART_DATA_DIR=/data/particl
PART_RPC_HOST=particl_core
PART_RPC_PORT=19792
PART_ZMQ_PORT=20792
PART_RPC_USER=particl_user PART_RPC_USER=particl_user
PART_RPC_PWD=particl_pwd PART_RPC_PWD=particl_pwd
BTC_RPC_USER=bitcoin_user
BTC_RPC_PWD=bitcoin_pwd LTC_DATA_DIR=/data/litecoin
LTC_RPC_HOST=litecoin_core
LTC_RPC_PORT=19795
LTC_RPC_USER=litecoin_user LTC_RPC_USER=litecoin_user
LTC_RPC_PWD=litecoin_pwd LTC_RPC_PWD=litecoin_pwd
PART_DATA_DIR=/data/particl
LTC_DATA_DIR=/data/litecoin
BTC_DATA_DIR=/data/bitcoin BTC_DATA_DIR=/data/bitcoin
BTC_RPC_HOST=bitcoin_core
BTC_RPC_PORT=19796
BTC_RPC_USER=bitcoin_user
BTC_RPC_PWD=bitcoin_pwd
XMR_DATA_DIR=/data/monero_daemon XMR_DATA_DIR=/data/monero_daemon
XMR_WALLETS_DIR=/data/monero_wallet XMR_RPC_HOST=monero_daemon
BASE_XMR_RPC_PORT=29798
COINS_RPCBIND_IP=0.0.0.0 XMR_WALLETS_DIR=/data/monero_wallet
XMR_WALLET_RPC_HOST=monero_wallet
BASE_XMR_WALLET_PORT=29998
XMR_WALLET_RPC_USER=xmr_wallet_user
XMR_WALLET_RPC_PWD=xmr_wallet_pwd

@ -21,5 +21,4 @@ VOLUME $MONERO_DATA
COPY entrypoint.sh /entrypoint.sh COPY entrypoint.sh /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"] ENTRYPOINT ["/entrypoint.sh"]
EXPOSE 18080 CMD ["/monero/monerod", "--non-interactive", "--config-file=/home/monero/.monero/monerod.conf", "--confirm-external-bind"]
CMD ["monerod", "--non-interactive", "--config-file=/home/monero/.monero/monerod.conf"]

@ -13,5 +13,4 @@ VOLUME $MONERO_DATA
COPY entrypoint.sh /entrypoint.sh COPY entrypoint.sh /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"] ENTRYPOINT ["/entrypoint.sh"]
EXPOSE 18080 CMD ["/monero/monero-wallet-rpc", "--non-interactive", "--config-file=/data/monero_wallet.conf", "--confirm-external-bind"]
CMD ["monero-wallet-rpc", "--non-interactive", "--config-file=/data/monero_wallet.conf"]

@ -1,8 +1,16 @@
# Split container setup
This will setup Basicswap so that each coin runs in it's own container.
Copy and edit .env config: Copy and edit .env config:
$ cp example.env .env cp example.env .env
Set the latest Monero chain height, or the height your wallet must restore from:
echo "DEFAULT_XMR_RESTORE_HEIGHT=$(curl https://localmonero.co/blocks/api/get_stats | jq .height)" >> .env
Create docker-compose config: Create docker-compose config:
@ -12,13 +20,70 @@ Create docker-compose config:
# Add the relevant coin fragments # Add the relevant coin fragments
cat compose-fragments/1_bitcoin.yml >> docker-compose.yml cat compose-fragments/1_bitcoin.yml >> docker-compose.yml
cat compose-fragments/1_litecoin.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/1_monero-wallet.yml >> docker-compose.yml
cat compose-fragments/8_swapclient.yml >> docker-compose.yml
# Copy for prepare script config # Copy for prepare script config
cp docker-compose.yml docker-compose-prepare.yml cp docker-compose.yml docker-compose-prepare.yml
cat compose-fragments/9_swapprepare.yml >> docker-compose-prepare.yml cat compose-fragments/9_swapprepare.yml >> docker-compose-prepare.yml
# Add the Monero daemon if required (should not go in docker-compose-prepare.yml)
cat compose-fragments/8_monero-daemon.yml >> docker-compose.yml
# Add the swapclient
cat compose-fragments/8_swapclient.yml >> docker-compose.yml
Create the docker network, with a specific subnet (for optional tor use):
docker network create coinswap_network --subnet="172.16.238.0/24"
Build the swapclient container:
docker-compose build swapclient
Build the monero container, if required:
docker-compose build monero_daemon
Build the remaining coin containers:
docker-compose build
Build the prepare-only containers:
docker-compose -f docker-compose-prepare.yml build
Create config files:
# Select relevant coins:
export WITH_COINS=bitcoin,litecoin,monero
docker-compose -f docker-compose-prepare.yml run --rm swapprepare \
basicswap-prepare --nocores --withcoins=${WITH_COINS} --htmlhost="0.0.0.0" --particl_mnemonic=none
Start coin cores only:
docker-compose -f docker-compose-prepare.yml up -d --scale swapprepare=0
Initialise wallets:
docker-compose -f docker-compose-prepare.yml run --rm swapprepare \
basicswap-prepare --initwalletsonly
Stop cores:
docker-compose -f docker-compose-prepare.yml stop
Start BasicSwap:
docker-compose up

@ -12,7 +12,7 @@ RUN wget -O protobuf_src.tar.gz https://github.com/protocolbuffers/protobuf/rele
tar xvf protobuf_src.tar.gz && \ tar xvf protobuf_src.tar.gz && \
cd protobuf-3.21.1 && \ cd protobuf-3.21.1 && \
./configure --prefix=/usr && \ ./configure --prefix=/usr && \
make install && \ make -j$(nproc) install && \
ldconfig ldconfig
ARG COINCURVE_VERSION=v0.1 ARG COINCURVE_VERSION=v0.1

@ -0,0 +1,8 @@
FROM alpine:latest
# 9050 SOCKS port
# 9051 control port
# 5353 DNS port
EXPOSE 9050 9051 5353
RUN apk add --no-cache tor
CMD tor -f /etc/tor/torrc
Loading…
Cancel
Save