dash: Add to prepare script.

This commit is contained in:
tecnovert 2022-10-20 22:23:25 +02:00
parent 9fc4fe3b79
commit 7298867e18
No known key found for this signature in database
GPG Key ID: 8ED6D8750C4E3F93
6 changed files with 180 additions and 18 deletions

View File

@ -33,6 +33,7 @@ from .interface.ltc import LTCInterface
from .interface.nmc import NMCInterface from .interface.nmc import NMCInterface
from .interface.xmr import XMRInterface from .interface.xmr import XMRInterface
from .interface.pivx import PIVXInterface from .interface.pivx import PIVXInterface
from .interface.dash import DASHInterface
from .interface.passthrough_btc import PassthroughBTCInterface from .interface.passthrough_btc import PassthroughBTCInterface
from . import __version__ from . import __version__
@ -527,6 +528,8 @@ class BasicSwap(BaseApp):
return xmr_i return xmr_i
elif coin == Coins.PIVX: elif coin == Coins.PIVX:
return PIVXInterface(self.coin_clients[coin], self.chain, self) return PIVXInterface(self.coin_clients[coin], self.chain, self)
elif coin == Coins.DASH:
return DASHInterface(self.coin_clients[coin], self.chain, self)
else: else:
raise ValueError('Unknown coin type') raise ValueError('Unknown coin type')
@ -545,7 +548,7 @@ class BasicSwap(BaseApp):
authcookiepath = os.path.join(self.getChainDatadirPath(coin), '.cookie') authcookiepath = os.path.join(self.getChainDatadirPath(coin), '.cookie')
pidfilename = cc['name'] pidfilename = cc['name']
if cc['name'] in ('bitcoin', 'litecoin', 'namecoin'): if cc['name'] in ('bitcoin', 'litecoin', 'namecoin', 'dash'):
pidfilename += 'd' pidfilename += 'd'
pidfilepath = os.path.join(self.getChainDatadirPath(coin), pidfilename + '.pid') pidfilepath = os.path.join(self.getChainDatadirPath(coin), pidfilename + '.pid')

View File

@ -29,6 +29,7 @@ class Coins(IntEnum):
# ZANO = 9 # ZANO = 9
# NDAU = 10 # NDAU = 10
PIVX = 11 PIVX = 11
DASH = 12
chainparams = { chainparams = {
@ -247,6 +248,45 @@ chainparams = {
'max_amount': 100000 * COIN, 'max_amount': 100000 * COIN,
} }
}, },
Coins.DASH: {
'name': 'dash',
'ticker': 'DASH',
'message_magic': 'DarkCoin Signed Message:\n',
'blocks_target': 60 * 2.5,
'decimal_places': 8,
'has_csv': True,
'has_segwit': False,
'mainnet': {
'rpcport': 9998,
'pubkey_address': 76,
'script_address': 16,
'key_prefix': 204,
'hrp': '',
'bip44': 5,
'min_amount': 1000,
'max_amount': 100000 * COIN,
},
'testnet': {
'rpcport': 19998,
'pubkey_address': 140,
'script_address': 19,
'key_prefix': 239,
'hrp': '',
'bip44': 1,
'min_amount': 1000,
'max_amount': 100000 * COIN,
},
'regtest': {
'rpcport': 18332,
'pubkey_address': 140,
'script_address': 19,
'key_prefix': 239,
'hrp': '',
'bip44': 1,
'min_amount': 1000,
'max_amount': 100000 * COIN,
}
}
} }
ticker_map = {} ticker_map = {}

View File

@ -41,3 +41,8 @@ PIVX_BINDIR = os.path.expanduser(os.getenv('PIVX_BINDIR', os.path.join(DEFAULT_T
PIVXD = os.getenv('PIVXD', 'pivxd' + bin_suffix) PIVXD = os.getenv('PIVXD', 'pivxd' + bin_suffix)
PIVX_CLI = os.getenv('PIVX_CLI', 'pivx-cli' + bin_suffix) PIVX_CLI = os.getenv('PIVX_CLI', 'pivx-cli' + bin_suffix)
PIVX_TX = os.getenv('PIVX_TX', 'pivx-tx' + bin_suffix) PIVX_TX = os.getenv('PIVX_TX', 'pivx-tx' + bin_suffix)
DASH_BINDIR = os.path.expanduser(os.getenv('DASH_BINDIR', os.path.join(DEFAULT_TEST_BINDIR, 'dash')))
DASHD = os.getenv('DASHD', 'dashd' + bin_suffix)
DASH_CLI = os.getenv('DASH_CLI', 'dash-cli' + bin_suffix)
DASH_TX = os.getenv('DASH_TX', 'dash-tx' + bin_suffix)

View File

@ -0,0 +1,18 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright (c) 2022 tecnovert
# Distributed under the MIT software license, see the accompanying
# file LICENSE or http://www.opensource.org/licenses/mit-license.php.
from .btc import BTCInterface
from basicswap.chainparams import Coins
class DASHInterface(BTCInterface):
@staticmethod
def coin_type():
return Coins.DASH
def initialiseWallet(self, key):
raise ValueError('Load seed with with -hdseed daemon argument')

View File

@ -49,7 +49,10 @@ XMR_SITE_COMMIT = 'f093c0da2219d94e6bef5f3948ac61b4ecdcb95b' # Lock hashes.txt
PIVX_VERSION = os.getenv('PIVX_VERSION', '5.4.99') PIVX_VERSION = os.getenv('PIVX_VERSION', '5.4.99')
PIVX_VERSION_TAG = os.getenv('PIVX_VERSION_TAG', '_scantxoutset') PIVX_VERSION_TAG = os.getenv('PIVX_VERSION_TAG', '_scantxoutset')
# version, version tag eg. "rc1", signers DASH_VERSION = os.getenv('DASH_VERSION', '18.1.0')
DASH_VERSION_TAG = os.getenv('DASH_VERSION_TAG', '')
known_coins = { known_coins = {
'particl': (PARTICL_VERSION, PARTICL_VERSION_TAG, ('tecnovert',)), 'particl': (PARTICL_VERSION, PARTICL_VERSION_TAG, ('tecnovert',)),
'litecoin': (LITECOIN_VERSION, LITECOIN_VERSION_TAG, ('davidburkett38',)), 'litecoin': (LITECOIN_VERSION, LITECOIN_VERSION_TAG, ('davidburkett38',)),
@ -57,6 +60,7 @@ known_coins = {
'namecoin': ('0.18.0', '', ('JeremyRand',)), 'namecoin': ('0.18.0', '', ('JeremyRand',)),
'monero': (MONERO_VERSION, MONERO_VERSION_TAG, ('binaryfate',)), 'monero': (MONERO_VERSION, MONERO_VERSION_TAG, ('binaryfate',)),
'pivx': (PIVX_VERSION, PIVX_VERSION_TAG, ('tecnovert',)), 'pivx': (PIVX_VERSION, PIVX_VERSION_TAG, ('tecnovert',)),
'dash': (DASH_VERSION, DASH_VERSION_TAG, ('pasta',)),
} }
expected_key_ids = { expected_key_ids = {
@ -67,6 +71,7 @@ expected_key_ids = {
'binaryfate': ('F0AF4D462A0BDF92',), 'binaryfate': ('F0AF4D462A0BDF92',),
'davidburkett38': ('3620E9D387E55666',), 'davidburkett38': ('3620E9D387E55666',),
'fuzzbawls': ('3BDCDA2D87A881D9',), 'fuzzbawls': ('3BDCDA2D87A881D9',),
'pasta': ('52527BEDABE87984',),
} }
if platform.system() == 'Darwin': if platform.system() == 'Darwin':
@ -125,6 +130,12 @@ PIVX_ONION_PORT = int(os.getenv('PIVX_ONION_PORT', 51472)) # nDefaultPort
PIVX_RPC_USER = os.getenv('PIVX_RPC_USER', '') PIVX_RPC_USER = os.getenv('PIVX_RPC_USER', '')
PIVX_RPC_PWD = os.getenv('PIVX_RPC_PWD', '') PIVX_RPC_PWD = os.getenv('PIVX_RPC_PWD', '')
DASH_RPC_HOST = os.getenv('DASH_RPC_HOST', '127.0.0.1')
DASH_RPC_PORT = int(os.getenv('DASH_RPC_PORT', 9998))
DASH_ONION_PORT = int(os.getenv('DASH_ONION_PORT', 9999)) # nDefaultPort
DASH_RPC_USER = os.getenv('DASH_RPC_USER', '')
DASH_RPC_PWD = os.getenv('DASH_RPC_PWD', '')
TOR_PROXY_HOST = os.getenv('TOR_PROXY_HOST', '127.0.0.1') TOR_PROXY_HOST = os.getenv('TOR_PROXY_HOST', '127.0.0.1')
TOR_PROXY_PORT = int(os.getenv('TOR_PROXY_PORT', 9050)) TOR_PROXY_PORT = int(os.getenv('TOR_PROXY_PORT', 9050))
TOR_CONTROL_PORT = int(os.getenv('TOR_CONTROL_PORT', 9051)) TOR_CONTROL_PORT = int(os.getenv('TOR_CONTROL_PORT', 9051))
@ -296,6 +307,7 @@ def extractCore(coin, version_data, settings, bin_dir, release_path, extra_opts=
bins = [coin + 'd', coin + '-cli', coin + '-tx'] bins = [coin + 'd', coin + '-cli', coin + '-tx']
versions = version.split('.') versions = version.split('.')
dir_name = 'dashcore' if coin == 'dash' else coin
if int(versions[0]) >= 22 or int(versions[1]) >= 19: if int(versions[0]) >= 22 or int(versions[1]) >= 19:
bins.append(coin + '-wallet') bins.append(coin + '-wallet')
if 'win32' in BIN_ARCH or 'win64' in BIN_ARCH: if 'win32' in BIN_ARCH or 'win64' in BIN_ARCH:
@ -305,7 +317,7 @@ def extractCore(coin, version_data, settings, bin_dir, release_path, extra_opts=
out_path = os.path.join(bin_dir, b) out_path = os.path.join(bin_dir, b)
if (not os.path.exists(out_path)) or extract_core_overwrite: if (not os.path.exists(out_path)) or extract_core_overwrite:
with open(out_path, 'wb') as fout: with open(out_path, 'wb') as fout:
fout.write(fz.read('{}-{}/bin/{}'.format(coin, version, b))) fout.write(fz.read('{}-{}/bin/{}'.format(dir_name, version, b)))
try: try:
os.chmod(out_path, stat.S_IRWXU | stat.S_IXGRP | stat.S_IXOTH) os.chmod(out_path, stat.S_IRWXU | stat.S_IXGRP | stat.S_IXOTH)
except Exception as e: except Exception as e:
@ -317,9 +329,9 @@ def extractCore(coin, version_data, settings, bin_dir, release_path, extra_opts=
if not os.path.exists(out_path) or extract_core_overwrite: if not os.path.exists(out_path) or extract_core_overwrite:
if coin == 'pivx': if coin == 'pivx':
filename = '{}-{}/bin/{}'.format(coin, version, b) filename = '{}-{}/bin/{}'.format(dir_name, version, b)
else: else:
filename = '{}-{}/bin/{}'.format(coin, version + version_tag, b) filename = '{}-{}/bin/{}'.format(dir_name, version + version_tag, b)
with open(out_path, 'wb') as fout, ft.extractfile(filename) as fi: with open(out_path, 'wb') as fout, ft.extractfile(filename) as fi:
fout.write(fi.read()) fout.write(fi.read())
@ -394,6 +406,11 @@ def prepareCore(coin, version_data, settings, data_dir, extra_opts={}):
release_url = 'https://github.com/tecnovert/particl-core/releases/download/v{}/{}'.format(version + version_tag, release_filename) release_url = 'https://github.com/tecnovert/particl-core/releases/download/v{}/{}'.format(version + version_tag, release_filename)
assert_filename = 'pivx-{}-6.0-build.assert'.format(os_name) assert_filename = 'pivx-{}-6.0-build.assert'.format(os_name)
assert_url = 'https://raw.githubusercontent.com/tecnovert/gitian.sigs/pivx/5.4.99_scantxoutset-{}/tecnovert/{}'.format(os_dir_name, assert_filename) assert_url = 'https://raw.githubusercontent.com/tecnovert/gitian.sigs/pivx/5.4.99_scantxoutset-{}/tecnovert/{}'.format(os_dir_name, assert_filename)
elif coin == 'dash':
release_filename = '{}-{}-{}{}.{}'.format('dashcore', version + version_tag, BIN_ARCH, filename_extra, FILE_EXT)
release_url = 'https://github.com/dashpay/dash/releases/download/v{}/{}'.format(version + version_tag, release_filename)
assert_filename = '{}-{}-{}-build.assert'.format(coin, os_name, major_version)
assert_url = 'https://raw.githubusercontent.com/dashpay/gitian.sigs/master/%s-%s/%s/%s' % (version + version_tag, os_dir_name, signing_key_name, assert_filename)
else: else:
raise ValueError('Unknown coin') raise ValueError('Unknown coin')
@ -468,10 +485,12 @@ def prepareCore(coin, version_data, settings, data_dir, extra_opts={}):
filename = '{}_{}.pgp'.format('particl', signing_key_name) filename = '{}_{}.pgp'.format('particl', signing_key_name)
else: else:
filename = '{}_{}.pgp'.format(coin, signing_key_name) filename = '{}_{}.pgp'.format(coin, signing_key_name)
pubkeyurls = ( pubkeyurls = [
'https://raw.githubusercontent.com/tecnovert/basicswap/master/pgp/keys/' + filename, 'https://raw.githubusercontent.com/tecnovert/basicswap/master/pgp/keys/' + filename,
'https://gitlab.com/particl/basicswap/-/raw/master/pgp/keys/' + filename, 'https://gitlab.com/particl/basicswap/-/raw/master/pgp/keys/' + filename,
) ]
if coin == 'dash':
pubkeyurls.append('https://raw.githubusercontent.com/dashpay/dash/master/contrib/gitian-keys/pasta.pgp')
for url in pubkeyurls: for url in pubkeyurls:
try: try:
logger.info('Importing public key from url: ' + url) logger.info('Importing public key from url: ' + url)
@ -631,6 +650,11 @@ def prepareDataDir(coin, settings, chain, particl_mnemonic, extra_opts={}):
fp.write(f'paramsdir={params_dir}\n') fp.write(f'paramsdir={params_dir}\n')
if PIVX_RPC_USER != '': if PIVX_RPC_USER != '':
fp.write('rpcauth={}:{}${}\n'.format(PIVX_RPC_USER, salt, password_to_hmac(salt, PIVX_RPC_PWD))) fp.write('rpcauth={}:{}${}\n'.format(PIVX_RPC_USER, salt, password_to_hmac(salt, PIVX_RPC_PWD)))
elif coin == 'dash':
fp.write('prune=4000\n')
fp.write('fallbackfee=0.0002\n')
if DASH_RPC_USER != '':
fp.write('rpcauth={}:{}${}\n'.format(DASH_RPC_USER, salt, password_to_hmac(salt, DASH_RPC_PWD)))
else: else:
logger.warning('Unknown coin %s', coin) logger.warning('Unknown coin %s', coin)
@ -846,11 +870,9 @@ def initialise_wallets(particl_wallet_mnemonic, with_coins, data_dir, settings,
with open(os.path.join(data_dir, 'basicswap.log'), 'a') as fp: with open(os.path.join(data_dir, 'basicswap.log'), 'a') as fp:
swap_client = BasicSwap(fp, data_dir, settings, chain) swap_client = BasicSwap(fp, data_dir, settings, chain)
start_daemons = {c for c in with_coins} # Always start Particl, it must be running to initialise a wallet in addcoin mode
if 'particl' not in with_coins: # Particl must be loaded first as subsequent coins are initialised from the Particl mnemonic
# Particl must be running to initialise a wallet in addcoin mode start_daemons = ['particl', ] + [c for c in with_coins if c != 'particl']
start_daemons.add('particl')
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)
@ -862,6 +884,10 @@ def initialise_wallets(particl_wallet_mnemonic, with_coins, data_dir, settings,
if coin_settings['manage_daemon']: if coin_settings['manage_daemon']:
filename = coin_name + 'd' + ('.exe' if os.name == 'nt' else '') filename = coin_name + 'd' + ('.exe' if os.name == 'nt' else '')
coin_args = ['-nofindpeers', '-nostaking'] if c == Coins.PART else [] coin_args = ['-nofindpeers', '-nostaking'] if c == Coins.PART else []
if c == Coins.DASH:
coin_args += ['-hdseed={}'.format(swap_client.getWalletKey(Coins.DASH, 1).hex())]
daemons.append(startDaemon(coin_settings['datadir'], coin_settings['bindir'], filename, daemon_args + coin_args)) daemons.append(startDaemon(coin_settings['datadir'], coin_settings['bindir'], filename, daemon_args + coin_args))
swap_client.setDaemonPID(c, daemons[-1].pid) swap_client.setDaemonPID(c, daemons[-1].pid)
swap_client.setCoinRunParams(c) swap_client.setCoinRunParams(c)
@ -875,15 +901,15 @@ def initialise_wallets(particl_wallet_mnemonic, with_coins, data_dir, settings,
logger.info('Creating wallet.dat for {}.'.format(coin_name.capitalize())) logger.info('Creating wallet.dat for {}.'.format(coin_name.capitalize()))
swap_client.callcoinrpc(c, 'createwallet', ['wallet.dat']) swap_client.callcoinrpc(c, 'createwallet', ['wallet.dat'])
if 'particl' in with_coins: if 'particl' in with_coins and c == Coins.PART:
logger.info('Loading Particl mnemonic') logger.info('Loading Particl mnemonic')
if particl_wallet_mnemonic is None: if particl_wallet_mnemonic is None:
particl_wallet_mnemonic = swap_client.callcoinrpc(Coins.PART, 'mnemonic', ['new'])['mnemonic'] particl_wallet_mnemonic = swap_client.callcoinrpc(Coins.PART, 'mnemonic', ['new'])['mnemonic']
swap_client.callcoinrpc(Coins.PART, 'extkeyimportmaster', [particl_wallet_mnemonic]) swap_client.callcoinrpc(Coins.PART, 'extkeyimportmaster', [particl_wallet_mnemonic])
for coin_name in with_coins: for coin_name in with_coins:
c = swap_client.getCoinIdFromName(coin_name) c = swap_client.getCoinIdFromName(coin_name)
if c == Coins.PART: if c in (Coins.PART, Coins.DASH):
continue continue
swap_client.waitForDaemonRPC(c) swap_client.waitForDaemonRPC(c)
swap_client.initialiseWallet(c) swap_client.initialiseWallet(c)
@ -1146,6 +1172,21 @@ def main():
'conf_target': 2, 'conf_target': 2,
'core_version_group': 20, 'core_version_group': 20,
'chain_lookups': 'local', 'chain_lookups': 'local',
},
'dash': {
'connection_type': 'rpc' if 'dash' in with_coins else 'none',
'manage_daemon': True if ('dash' in with_coins and PIVX_RPC_HOST == '127.0.0.1') else False,
'rpchost': DASH_RPC_HOST,
'rpcport': DASH_RPC_PORT + port_offset,
'onionport': DASH_ONION_PORT + port_offset,
'datadir': os.getenv('DASH_DATA_DIR', os.path.join(data_dir, 'dash')),
'bindir': os.path.join(bin_dir, 'dash'),
'use_segwit': False,
'use_csv': True,
'blocks_confirmed': 1,
'conf_target': 2,
'core_version_group': 18,
'chain_lookups': 'local',
} }
} }
@ -1161,6 +1202,9 @@ def main():
if PIVX_RPC_USER != '': if PIVX_RPC_USER != '':
chainclients['pivx']['rpcuser'] = PIVX_RPC_USER chainclients['pivx']['rpcuser'] = PIVX_RPC_USER
chainclients['pivx']['rpcpassword'] = PIVX_RPC_PWD chainclients['pivx']['rpcpassword'] = PIVX_RPC_PWD
if DASH_RPC_USER != '':
chainclients['dash']['rpcuser'] = DASH_RPC_USER
chainclients['dash']['rpcpassword'] = DASH_RPC_PWD
chainclients['monero']['walletsdir'] = os.getenv('XMR_WALLETS_DIR', chainclients['monero']['datadir']) chainclients['monero']['walletsdir'] = os.getenv('XMR_WALLETS_DIR', chainclients['monero']['datadir'])

52
pgp/keys/dash_pasta.pgp Normal file
View File

@ -0,0 +1,52 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
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
oPei
=42dS
-----END PGP PUBLIC KEY BLOCK-----