tests: Add swap to wallet restore test.

This commit is contained in:
tecnovert 2022-07-17 22:34:39 +02:00
parent ede01d3fc8
commit 3ad87df844
No known key found for this signature in database
GPG key ID: 8ED6D8750C4E3F93
7 changed files with 236 additions and 55 deletions

View file

@ -78,6 +78,16 @@ logger.level = logging.DEBUG
if not len(logger.handlers): if not len(logger.handlers):
logger.addHandler(logging.StreamHandler(sys.stdout)) logger.addHandler(logging.StreamHandler(sys.stdout))
UI_HTML_PORT = int(os.getenv('UI_HTML_PORT', 12700))
COINS_RPCBIND_IP = os.getenv('COINS_RPCBIND_IP', '127.0.0.1')
PART_ZMQ_PORT = int(os.getenv('PART_ZMQ_PORT', 20792))
PART_RPC_HOST = os.getenv('PART_RPC_HOST', '127.0.0.1')
PART_RPC_PORT = int(os.getenv('PART_RPC_PORT', 19792))
PART_ONION_PORT = int(os.getenv('PART_ONION_PORT', 51734))
PART_RPC_USER = os.getenv('PART_RPC_USER', '')
PART_RPC_PWD = os.getenv('PART_RPC_PWD', '')
XMR_RPC_HOST = os.getenv('XMR_RPC_HOST', '127.0.0.1') XMR_RPC_HOST = os.getenv('XMR_RPC_HOST', '127.0.0.1')
BASE_XMR_RPC_PORT = int(os.getenv('BASE_XMR_RPC_PORT', 29798)) BASE_XMR_RPC_PORT = int(os.getenv('BASE_XMR_RPC_PORT', 29798))
BASE_XMR_ZMQ_PORT = int(os.getenv('BASE_XMR_ZMQ_PORT', 30898)) BASE_XMR_ZMQ_PORT = int(os.getenv('BASE_XMR_ZMQ_PORT', 30898))
@ -86,34 +96,22 @@ XMR_WALLET_RPC_HOST = os.getenv('XMR_WALLET_RPC_HOST', '127.0.0.1')
XMR_WALLET_RPC_USER = os.getenv('XMR_WALLET_RPC_USER', 'xmr_wallet_user') 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 = int(os.getenv('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))
PART_ZMQ_PORT = int(os.getenv('PART_ZMQ_PORT', 20792))
PART_RPC_HOST = os.getenv('PART_RPC_HOST', '127.0.0.1')
LTC_RPC_HOST = os.getenv('LTC_RPC_HOST', '127.0.0.1') LTC_RPC_HOST = os.getenv('LTC_RPC_HOST', '127.0.0.1')
BTC_RPC_HOST = os.getenv('BTC_RPC_HOST', '127.0.0.1')
NMC_RPC_HOST = os.getenv('NMC_RPC_HOST', '127.0.0.1')
PART_RPC_PORT = int(os.getenv('PART_RPC_PORT', 19792))
LTC_RPC_PORT = int(os.getenv('LTC_RPC_PORT', 19895)) LTC_RPC_PORT = int(os.getenv('LTC_RPC_PORT', 19895))
BTC_RPC_PORT = int(os.getenv('BTC_RPC_PORT', 19996))
NMC_RPC_PORT = int(os.getenv('NMC_RPC_PORT', 19698))
PART_ONION_PORT = int(os.getenv('PART_ONION_PORT', 51734))
LTC_ONION_PORT = int(os.getenv('LTC_ONION_PORT', 9333)) LTC_ONION_PORT = int(os.getenv('LTC_ONION_PORT', 9333))
BTC_ONION_PORT = int(os.getenv('BTC_ONION_PORT', 8334))
PART_RPC_USER = os.getenv('PART_RPC_USER', '')
PART_RPC_PWD = os.getenv('PART_RPC_PWD', '')
BTC_RPC_USER = os.getenv('BTC_RPC_USER', '')
BTC_RPC_PWD = os.getenv('BTC_RPC_PWD', '')
LTC_RPC_USER = os.getenv('LTC_RPC_USER', '') LTC_RPC_USER = os.getenv('LTC_RPC_USER', '')
LTC_RPC_PWD = os.getenv('LTC_RPC_PWD', '') LTC_RPC_PWD = os.getenv('LTC_RPC_PWD', '')
COINS_RPCBIND_IP = os.getenv('COINS_RPCBIND_IP', '127.0.0.1') BTC_RPC_HOST = os.getenv('BTC_RPC_HOST', '127.0.0.1')
BTC_RPC_PORT = int(os.getenv('BTC_RPC_PORT', 19996))
BTC_ONION_PORT = int(os.getenv('BTC_ONION_PORT', 8334))
BTC_RPC_USER = os.getenv('BTC_RPC_USER', '')
BTC_RPC_PWD = os.getenv('BTC_RPC_PWD', '')
NMC_RPC_HOST = os.getenv('NMC_RPC_HOST', '127.0.0.1')
NMC_RPC_PORT = int(os.getenv('NMC_RPC_PORT', 19698))
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))
@ -125,7 +123,6 @@ 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
@ -207,9 +204,15 @@ def testOnionLink():
logger.info('Onion links work.') logger.info('Onion links work.')
def ensureValidSignatureBy(result, signing_key_name): def isValidSignature(result):
if result.valid is False \ if result.valid is False \
and not (result.status == 'signature valid' and result.key_status == 'signing key has expired'): and (result.status == 'signature valid' and result.key_status == 'signing key has expired'):
return True
return result.valid
def ensureValidSignatureBy(result, signing_key_name):
if not isValidSignature(result):
raise ValueError('Signature verification failed.') raise ValueError('Signature verification failed.')
if result.key_id not in expected_key_ids[signing_key_name]: if result.key_id not in expected_key_ids[signing_key_name]:
@ -378,17 +381,26 @@ def prepareCore(coin, version_data, settings, data_dir, extra_opts={}):
""" """
gpg = gnupg.GPG() gpg = gnupg.GPG()
keysdirpath = extra_opts.get('keysdirpath', None)
if keysdirpath is not None:
logger.info(f'Loading PGP keys from: {keysdirpath}.')
for path in os.scandir(keysdirpath):
if path.is_file():
with open(path, 'rb') as fp:
rv = gpg.import_keys(fp.read())
for key in rv.fingerprints:
gpg.trust_keys(rv.fingerprints[0], 'TRUST_FULLY')
if coin == 'monero': if coin == 'monero':
with open(assert_path, 'rb') as fp: with open(assert_path, 'rb') as fp:
verified = gpg.verify_file(fp) verified = gpg.verify_file(fp)
if verified.username is None: if not isValidSignature(verified) and verified.username is None:
logger.warning('Signature made by unknown key.') logger.warning('Signature made by unknown key.')
pubkeyurl = 'https://raw.githubusercontent.com/monero-project/monero/master/utils/gpg_keys/binaryfate.asc' pubkeyurl = 'https://raw.githubusercontent.com/monero-project/monero/master/utils/gpg_keys/binaryfate.asc'
logger.info('Importing public key from url: ' + pubkeyurl) logger.info('Importing public key from url: ' + pubkeyurl)
rv = gpg.import_keys(downloadBytes(pubkeyurl)) rv = gpg.import_keys(downloadBytes(pubkeyurl))
assert('F0AF4D462A0BDF92' in rv.fingerprints[0])
gpg.trust_keys(rv.fingerprints[0], 'TRUST_FULLY') gpg.trust_keys(rv.fingerprints[0], 'TRUST_FULLY')
with open(assert_path, 'rb') as fp: with open(assert_path, 'rb') as fp:
verified = gpg.verify_file(fp) verified = gpg.verify_file(fp)
@ -396,7 +408,7 @@ def prepareCore(coin, version_data, settings, data_dir, extra_opts={}):
with open(assert_sig_path, 'rb') as fp: with open(assert_sig_path, 'rb') as fp:
verified = gpg.verify_file(fp, assert_path) verified = gpg.verify_file(fp, assert_path)
if verified.username is None: if not isValidSignature(verified) and verified.username is None:
logger.warning('Signature made by unknown key.') logger.warning('Signature made by unknown key.')
filename = '{}_{}.pgp'.format(coin, signing_key_name) filename = '{}_{}.pgp'.format(coin, signing_key_name)
@ -745,6 +757,7 @@ def printHelp():
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('--initwalletsonly Setup coin wallets only.')
logger.info('--keysdirpath Speed up tests by preloading all PGP keys in directory.')
logger.info('\n' + 'Known coins: %s', ', '.join(known_coins.keys())) logger.info('\n' + 'Known coins: %s', ', '.join(known_coins.keys()))
@ -843,13 +856,11 @@ def main():
xmr_restore_height = DEFAULT_XMR_RESTORE_HEIGHT xmr_restore_height = DEFAULT_XMR_RESTORE_HEIGHT
prepare_bin_only = False prepare_bin_only = False
no_cores = False no_cores = False
use_containers = False
enable_tor = False enable_tor = False
disable_tor = False disable_tor = False
tor_control_password = None
use_btc_fastsync = False
extract_core_overwrite = True
initwalletsonly = False initwalletsonly = False
tor_control_password = None
extra_opts = {}
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] != '-':
@ -883,10 +894,10 @@ def main():
no_cores = True no_cores = True
continue continue
if name == 'usecontainers': if name == 'usecontainers':
use_containers = True extra_opts['use_containers'] = True
continue continue
if name == 'noextractover': if name == 'noextractover':
extract_core_overwrite = False extra_opts['extract_core_overwrite'] = False
continue continue
if name == 'usetorproxy': if name == 'usetorproxy':
use_tor_proxy = True use_tor_proxy = True
@ -898,7 +909,7 @@ def main():
disable_tor = True disable_tor = True
continue continue
if name == 'usebtcfastsync': if name == 'usebtcfastsync':
use_btc_fastsync = True extra_opts['use_btc_fastsync'] = True
continue continue
if name == 'initwalletsonly': if name == 'initwalletsonly':
initwalletsonly = True initwalletsonly = True
@ -947,6 +958,9 @@ def main():
if name == 'xmrrestoreheight': if name == 'xmrrestoreheight':
xmr_restore_height = int(s[1]) xmr_restore_height = int(s[1])
continue continue
if name == 'keysdirpath':
extra_opts['keysdirpath'] = os.path.expanduser(s[1].strip('"'))
continue
exitWithError('Unknown argument {}'.format(v)) exitWithError('Unknown argument {}'.format(v))
@ -1122,13 +1136,8 @@ def main():
logger.info('Done.') logger.info('Done.')
return 0 return 0
extra_opts = { extra_opts['data_dir'] = data_dir
'use_btc_fastsync': use_btc_fastsync, extra_opts['tor_control_password'] = tor_control_password
'extract_core_overwrite': extract_core_overwrite,
'data_dir': data_dir,
'use_containers': use_containers,
'tor_control_password': tor_control_password,
}
if add_coin != '': if add_coin != '':
logger.info('Adding coin: %s', add_coin) logger.info('Adding coin: %s', add_coin)

View file

@ -0,0 +1,87 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
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
lmE0kDaYQqoBKXNXcybElBID8Q==
=tkJZ
-----END PGP PUBLIC KEY BLOCK-----

View file

@ -92,6 +92,10 @@ def run_prepare(node_id, datadir_path, bins_path, with_coins, mnemonic_in=None,
'-xmrrestoreheight=0'] '-xmrrestoreheight=0']
if mnemonic_in: if mnemonic_in:
testargs.append(f'-particl_mnemonic="{mnemonic_in}"') testargs.append(f'-particl_mnemonic="{mnemonic_in}"')
keysdirpath = os.getenv('PGP_KEYS_DIR_PATH', None)
if keysdirpath is not None:
testargs.append('-keysdirpath="' + os.path.expanduser(keysdirpath) + '"')
with patch.object(sys, 'argv', testargs), patch('sys.stdout', new=StringIO()) as mocked_stdout: with patch.object(sys, 'argv', testargs), patch('sys.stdout', new=StringIO()) as mocked_stdout:
prepareSystem.main() prepareSystem.main()
lines = mocked_stdout.getvalue().split('\n') lines = mocked_stdout.getvalue().split('\n')

View file

@ -12,8 +12,8 @@ import shutil
import signal import signal
import logging import logging
import unittest import unittest
import traceback
import threading import threading
import traceback
import basicswap.config as cfg import basicswap.config as cfg
from basicswap.basicswap import ( from basicswap.basicswap import (

View file

@ -9,6 +9,7 @@
export TEST_PATH=/tmp/test_basicswap_wallet_restore export TEST_PATH=/tmp/test_basicswap_wallet_restore
mkdir -p ${TEST_PATH}/bin mkdir -p ${TEST_PATH}/bin
cp -r ~/tmp/basicswap_bin/* ${TEST_PATH}/bin cp -r ~/tmp/basicswap_bin/* ${TEST_PATH}/bin
export PGP_KEYS_DIR_PATH=$(pwd)/pgp/keys
export PYTHONPATH=$(pwd) export PYTHONPATH=$(pwd)
python tests/basicswap/extended/test_wallet_restore.py python tests/basicswap/extended/test_wallet_restore.py
@ -20,19 +21,29 @@ import sys
import shutil import shutil
import logging import logging
import unittest import unittest
import threading
import traceback import traceback
import multiprocessing import multiprocessing
from unittest.mock import patch from unittest.mock import patch
from tests.basicswap.common import ( from tests.basicswap.common import (
read_json_api, read_json_api,
post_json_api,
waitForServer, waitForServer,
waitForNumOffers,
waitForNumBids,
) )
from tests.basicswap.common_xmr import ( from tests.basicswap.common_xmr import (
TestBase, TestBase,
run_prepare, run_prepare,
waitForBidState,
) )
from basicswap.rpc import (
callrpc,
)
from tests.basicswap.mnemonics import mnemonics
import bin.basicswap_run as runSystem import bin.basicswap_run as runSystem
from bin.basicswap_prepare import LTC_RPC_PORT, BTC_RPC_PORT
TEST_PATH = os.path.expanduser(os.getenv('TEST_PATH', '~/test_basicswap1')) TEST_PATH = os.path.expanduser(os.getenv('TEST_PATH', '~/test_basicswap1'))
@ -42,6 +53,23 @@ if not len(logger.handlers):
logger.addHandler(logging.StreamHandler(sys.stdout)) logger.addHandler(logging.StreamHandler(sys.stdout))
def callbtcnoderpc(node_id, method, params=[], wallet=None, base_rpc_port=BTC_RPC_PORT):
auth = 'test_btc_{0}:test_btc_pwd_{0}'.format(node_id)
return callrpc(base_rpc_port + node_id, auth, method, params, wallet)
def callltcnoderpc(node_id, method, params=[], wallet=None, base_rpc_port=LTC_RPC_PORT):
auth = 'test_ltc_{0}:test_ltc_pwd_{0}'.format(node_id)
return callrpc(base_rpc_port + node_id, auth, method, params, wallet)
def updateThread(self):
while not self.delay_event.is_set():
callbtcnoderpc(2, 'generatetoaddress', [1, self.btc_addr])
callltcnoderpc(1, 'generatetoaddress', [1, self.ltc_addr])
self.delay_event.wait(2)
def prepare_node(node_id, mnemonic): def prepare_node(node_id, mnemonic):
logging.info('Preparing node: %d.', node_id) logging.info('Preparing node: %d.', node_id)
bins_path = os.path.join(TEST_PATH, 'bin') bins_path = os.path.join(TEST_PATH, 'bin')
@ -50,18 +78,18 @@ def prepare_node(node_id, mnemonic):
shutil.rmtree(client_path) shutil.rmtree(client_path)
except Exception as ex: except Exception as ex:
logging.warning('setUpClass %s', str(ex)) logging.warning('setUpClass %s', str(ex))
return run_prepare(node_id, client_path, bins_path, 'monero,bitcoin,litecoin', mnemonic) return run_prepare(node_id, client_path, bins_path, 'monero,bitcoin,litecoin', mnemonic, 3, use_rpcauth=True)
class Test(TestBase): class Test(TestBase):
@classmethod @classmethod
def setUpClass(cls): def setUpClass(cls):
super(Test, cls).setUpClass(cls) super(Test, cls).setUpClass(cls)
cls.update_thread = None
cls.used_mnemonics = [] cls.used_mnemonics = []
# Load wallets from random mnemonics # Load wallets from random mnemonics, except node0 which needs to import PART from the genesis block
for i in range(3): for i in range(3):
cls.used_mnemonics.append(prepare_node(i, None)) cls.used_mnemonics.append(prepare_node(i, mnemonics[0] if i == 0 else None))
def run_thread(self, client_id): def run_thread(self, client_id):
client_path = os.path.join(TEST_PATH, 'client{}'.format(client_id)) client_path = os.path.join(TEST_PATH, 'client{}'.format(client_id))
@ -70,7 +98,6 @@ class Test(TestBase):
runSystem.main() runSystem.main()
def test_wallet(self): def test_wallet(self):
update_thread = None
processes = [] processes = []
self.wait_seconds(5) self.wait_seconds(5)
@ -81,24 +108,77 @@ class Test(TestBase):
try: try:
waitForServer(self.delay_event, 12700) waitForServer(self.delay_event, 12700)
waitForServer(self.delay_event, 12701) waitForServer(self.delay_event, 12701)
# TODO: Add swaps waitForServer(self.delay_event, 12702)
ltc_before = read_json_api(12700, 'wallets/ltc') num_blocks = 500 # Mine enough to activate segwit
self.btc_addr = callbtcnoderpc(2, 'getnewaddress', ['mining_addr', 'bech32'])
logging.info('Mining %d Bitcoin blocks to %s', num_blocks, self.btc_addr)
callbtcnoderpc(2, 'generatetoaddress', [num_blocks, self.btc_addr])
num_blocks = 431
self.ltc_addr = callltcnoderpc(1, 'getnewaddress', ['mining_addr', 'bech32'])
logging.info('Mining %d Litecoin blocks to %s', num_blocks, self.ltc_addr)
callltcnoderpc(1, 'generatetoaddress', [num_blocks, self.ltc_addr])
mweb_addr = callltcnoderpc(1, 'getnewaddress', ['mweb_addr', 'mweb'])
callltcnoderpc(1, 'sendtoaddress', [mweb_addr, 1])
num_blocks = 69
callltcnoderpc(1, 'generatetoaddress', [num_blocks, self.ltc_addr])
self.update_thread = threading.Thread(target=updateThread, args=(self,))
self.update_thread.start()
data = {
'addr_from': '-1',
'coin_from': 'part',
'coin_to': 'ltc',
'amt_from': '1',
'amt_to': '1',
'lockhrs': '24',
'automation_strat_id': 1}
offer_id = post_json_api(12700, 'offers/new', data)['offer_id']
summary = read_json_api(12700)
assert(summary['num_sent_offers'] == 1)
logger.info('Waiting for offer')
waitForNumOffers(self.delay_event, 12701, 1)
offers = read_json_api(12701, 'offers')
offer = offers[0]
data = {
'offer_id': offer['offer_id'],
'amount_from': offer['amount_from']}
bid_id = post_json_api(12701, 'bids/new', data)['bid_id']
waitForNumBids(self.delay_event, 12700, 1)
waitForBidState(self.delay_event, 12700, bid_id, 'Completed')
waitForBidState(self.delay_event, 12701, bid_id, 'Completed')
logging.info('Starting a new node on the same mnemonic as the first') logging.info('Starting a new node on the same mnemonic as the first')
prepare_node(3, self.used_mnemonics[0]) prepare_node(3, self.used_mnemonics[0])
processes.append(multiprocessing.Process(target=self.run_thread, args=(3,))) processes.append(multiprocessing.Process(target=self.run_thread, args=(3,)))
processes[-1].start() processes[-1].start()
waitForServer(self.delay_event, 12703) waitForServer(self.delay_event, 12703)
ltc_after = read_json_api(12703, 'wallets/ltc')
assert(ltc_before['deposit_address'] == ltc_after['deposit_address']) # TODO: Try detect past swaps
ltc_orig = read_json_api(12700, 'wallets/ltc')
ltc_restored = read_json_api(12703, 'wallets/ltc')
assert(float(ltc_orig['balance']) + float(ltc_orig['unconfirmed']) > 0.0)
assert(float(ltc_orig['balance']) + float(ltc_orig['unconfirmed']) == float(ltc_restored['balance']) + float(ltc_restored['unconfirmed']))
logging.info('Test passed.')
except Exception: except Exception:
traceback.print_exc() traceback.print_exc()
if update_thread: self.delay_event.set()
update_thread.join() if self.update_thread:
self.update_thread.join()
for p in processes: for p in processes:
p.terminate() p.terminate()
for p in processes: for p in processes:

View file

@ -120,8 +120,8 @@ class Test(unittest.TestCase):
random.seed(time.time()) random.seed(time.time())
os.environ['PARTICL_PORT_BASE'] = str(BASE_PART_RPC_PORT) os.environ['PARTICL_RPC_PORT_BASE'] = str(BASE_PART_RPC_PORT)
os.environ['BITCOIN_PORT_BASE'] = str(BASE_BTC_RPC_PORT) os.environ['BITCOIN_RPC_PORT_BASE'] = str(BASE_BTC_RPC_PORT)
logging.info('Preparing %d nodes.', NUM_NODES) logging.info('Preparing %d nodes.', NUM_NODES)
prepare_nodes(NUM_NODES, 'bitcoin,monero', True, {'min_sequence_lock_seconds': 60}, PORT_OFS) prepare_nodes(NUM_NODES, 'bitcoin,monero', True, {'min_sequence_lock_seconds': 60}, PORT_OFS)

View file

@ -441,7 +441,7 @@ class BaseTest(unittest.TestCase):
cls.http_threads.append(t) cls.http_threads.append(t)
t.start() t.start()
# Set future block rewards to nowhere (a random address) # Set future block rewards to nowhere (a random address), so wallet amounts stay constant
eckey = ECKey() eckey = ECKey()
eckey.generate() eckey.generate()
void_block_rewards_pubkey = eckey.get_pubkey().get_bytes() void_block_rewards_pubkey = eckey.get_pubkey().get_bytes()
@ -451,6 +451,7 @@ class BaseTest(unittest.TestCase):
logging.info('Mining %d Bitcoin blocks to %s', num_blocks, cls.btc_addr) logging.info('Mining %d Bitcoin blocks to %s', num_blocks, cls.btc_addr)
callnoderpc(0, 'generatetoaddress', [num_blocks, cls.btc_addr], base_rpc_port=BTC_BASE_RPC_PORT) callnoderpc(0, 'generatetoaddress', [num_blocks, cls.btc_addr], base_rpc_port=BTC_BASE_RPC_PORT)
# Switch addresses so wallet amounts stay constant
num_blocks = 100 num_blocks = 100
cls.btc_addr = cls.swap_clients[0].ci(Coins.BTC).pubkey_to_segwit_address(void_block_rewards_pubkey) cls.btc_addr = cls.swap_clients[0].ci(Coins.BTC).pubkey_to_segwit_address(void_block_rewards_pubkey)
logging.info('Mining %d Bitcoin blocks to %s', num_blocks, cls.btc_addr) logging.info('Mining %d Bitcoin blocks to %s', num_blocks, cls.btc_addr)