Decred: Add to test_xmr_persistent

This commit is contained in:
tecnovert
2024-05-20 16:29:14 +02:00
parent 614fc9ccbd
commit 26eaa2f0b0
19 changed files with 394 additions and 188 deletions

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright (c) 2020-2023 tecnovert
# Copyright (c) 2020-2024 tecnovert
# Distributed under the MIT software license, see the accompanying
# file LICENSE.txt or http://www.opensource.org/licenses/mit-license.php.
@@ -35,6 +35,10 @@ LTC_BASE_PORT = 34792
LTC_BASE_RPC_PORT = 35792
LTC_BASE_ZMQ_PORT = 36792
DCR_BASE_PORT = 18555
DCR_BASE_RPC_PORT = 9110
PIVX_BASE_PORT = 34892
PIVX_BASE_RPC_PORT = 35892
PIVX_BASE_ZMQ_PORT = 36892

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright (c) 2020-2022 tecnovert
# Copyright (c) 2020-2024 tecnovert
# Distributed under the MIT software license, see the accompanying
# file LICENSE or http://www.opensource.org/licenses/mit-license.php.
@@ -29,6 +29,7 @@ from tests.basicswap.common import (
BASE_PORT, BASE_RPC_PORT,
BTC_BASE_PORT, BTC_BASE_RPC_PORT, BTC_BASE_TOR_PORT,
LTC_BASE_PORT, LTC_BASE_RPC_PORT,
DCR_BASE_PORT, DCR_BASE_RPC_PORT,
PIVX_BASE_PORT,
)
from basicswap.contrib.rpcauth import generate_salt, password_to_hmac
@@ -46,6 +47,7 @@ BITCOIN_RPC_PORT_BASE = int(os.getenv('BITCOIN_RPC_PORT_BASE', BTC_BASE_RPC_PORT
BITCOIN_TOR_PORT_BASE = int(os.getenv('BITCOIN_TOR_PORT_BASE', BTC_BASE_TOR_PORT))
LITECOIN_RPC_PORT_BASE = int(os.getenv('LITECOIN_RPC_PORT_BASE', LTC_BASE_RPC_PORT))
DECRED_RPC_PORT_BASE = int(os.getenv('DECRED_RPC_PORT_BASE', DCR_BASE_RPC_PORT))
FIRO_BASE_PORT = 34832
FIRO_BASE_RPC_PORT = 35832
@@ -93,11 +95,14 @@ def run_prepare(node_id, datadir_path, bins_path, with_coins, mnemonic_in=None,
os.environ['PART_RPC_PORT'] = str(PARTICL_RPC_PORT_BASE)
os.environ['BTC_RPC_PORT'] = str(BITCOIN_RPC_PORT_BASE)
os.environ['LTC_RPC_PORT'] = str(LITECOIN_RPC_PORT_BASE)
os.environ['DCR_RPC_PORT'] = str(DECRED_RPC_PORT_BASE)
os.environ['FIRO_RPC_PORT'] = str(FIRO_RPC_PORT_BASE)
os.environ['XMR_RPC_USER'] = 'xmr_user'
os.environ['XMR_RPC_PWD'] = 'xmr_pwd'
os.environ['DCR_RPC_PWD'] = 'dcr_pwd'
import bin.basicswap_prepare as prepareSystem
# Hack: Reload module to set env vars as the basicswap_prepare module is initialised if imported from elsewhere earlier
from importlib import reload
@@ -126,9 +131,10 @@ def run_prepare(node_id, datadir_path, bins_path, with_coins, mnemonic_in=None,
with open(config_path) as fs:
settings = json.load(fs)
with open(os.path.join(datadir_path, 'particl', 'particl.conf'), 'r') as fp:
config_filename = os.path.join(datadir_path, 'particl', 'particl.conf')
with open(config_filename, 'r') as fp:
lines = fp.readlines()
with open(os.path.join(datadir_path, 'particl', 'particl.conf'), 'w') as fp:
with open(config_filename, 'w') as fp:
for line in lines:
if not line.startswith('staking'):
fp.write(line)
@@ -158,9 +164,10 @@ def run_prepare(node_id, datadir_path, bins_path, with_coins, mnemonic_in=None,
if 'bitcoin' in coins_array:
# Pruned nodes don't provide blocks
with open(os.path.join(datadir_path, 'bitcoin', 'bitcoin.conf'), 'r') as fp:
config_filename = os.path.join(datadir_path, 'bitcoin', 'bitcoin.conf')
with open(config_filename, 'r') as fp:
lines = fp.readlines()
with open(os.path.join(datadir_path, 'bitcoin', 'bitcoin.conf'), 'w') as fp:
with open(config_filename, 'w') as fp:
for line in lines:
if not line.startswith('prune'):
fp.write(line)
@@ -188,9 +195,10 @@ def run_prepare(node_id, datadir_path, bins_path, with_coins, mnemonic_in=None,
if 'litecoin' in coins_array:
# Pruned nodes don't provide blocks
with open(os.path.join(datadir_path, 'litecoin', 'litecoin.conf'), 'r') as fp:
config_filename = os.path.join(datadir_path, 'litecoin', 'litecoin.conf')
with open(config_filename, 'r') as fp:
lines = fp.readlines()
with open(os.path.join(datadir_path, 'litecoin', 'litecoin.conf'), 'w') as fp:
with open(config_filename, 'w') as fp:
for line in lines:
if not line.startswith('prune'):
fp.write(line)
@@ -213,11 +221,34 @@ def run_prepare(node_id, datadir_path, bins_path, with_coins, mnemonic_in=None,
for opt in EXTRA_CONFIG_JSON.get('ltc{}'.format(node_id), []):
fp.write(opt + '\n')
if 'decred' in coins_array:
# Pruned nodes don't provide blocks
config_filename = os.path.join(datadir_path, 'decred', 'dcrd.conf')
with open(config_filename, 'r') as fp:
lines = fp.readlines()
with open(config_filename, 'w') as fp:
for line in lines:
if not line.startswith('prune'):
fp.write(line)
fp.write('listen=127.0.0.1:{}\n'.format(DCR_BASE_PORT + node_id + port_ofs))
fp.write('noseeders=1\n')
fp.write('nodnsseed=1\n')
fp.write('nodiscoverip=1\n')
if node_id == 0:
fp.write('miningaddr=SsYbXyjkKAEXXcGdFgr4u4bo4L8RkCxwQpH\n')
for ip in range(num_nodes):
if ip != node_id:
fp.write('addpeer=127.0.0.1:{}\n'.format(DCR_BASE_PORT + ip + port_ofs))
config_filename = os.path.join(datadir_path, 'decred', 'dcrwallet.conf')
with open(config_filename, 'a') as fp:
fp.write('enablevoting=1\n')
if 'pivx' in coins_array:
# Pruned nodes don't provide blocks
with open(os.path.join(datadir_path, 'pivx', 'pivx.conf'), 'r') as fp:
config_filename = os.path.join(datadir_path, 'pivx', 'pivx.conf')
with open(config_filename, 'r') as fp:
lines = fp.readlines()
with open(os.path.join(datadir_path, 'pivx', 'pivx.conf'), 'w') as fp:
with open(config_filename, 'w') as fp:
for line in lines:
if not line.startswith('prune'):
fp.write(line)
@@ -242,9 +273,10 @@ def run_prepare(node_id, datadir_path, bins_path, with_coins, mnemonic_in=None,
if 'firo' in coins_array:
# Pruned nodes don't provide blocks
with open(os.path.join(datadir_path, 'firo', 'firo.conf'), 'r') as fp:
config_filename = os.path.join(datadir_path, 'firo', 'firo.conf')
with open(config_filename, 'r') as fp:
lines = fp.readlines()
with open(os.path.join(datadir_path, 'firo', 'firo.conf'), 'w') as fp:
with open(config_filename, 'w') as fp:
for line in lines:
if not line.startswith('prune'):
fp.write(line)

View File

@@ -9,8 +9,7 @@ import copy
import logging
import os
import random
import select
import subprocess
import unittest
import basicswap.config as cfg
@@ -36,6 +35,9 @@ from basicswap.interface.dcr.messages import (
SigHashType,
TxSerializeType,
)
from basicswap.interface.dcr.util import (
createDCRWallet,
)
from tests.basicswap.common import (
compare_bid_states,
compare_bid_states_unordered,
@@ -466,6 +468,9 @@ def prepareDCDDataDir(datadir, node_id, conf_file, dir_prefix, num_nodes=3):
f'rpcuser=test{node_id}\n',
f'rpcpass=test_pass{node_id}\n',
'notls=1\n',
'noseeders=1\n',
'nodnsseed=1\n',
'nodiscoverip=1\n',
'miningaddr=SsYbXyjkKAEXXcGdFgr4u4bo4L8RkCxwQpH\n',]
for i in range(0, num_nodes):
@@ -511,8 +516,8 @@ class Test(BaseTest):
@classmethod
def prepareExtraCoins(cls):
ci0 = cls.swap_clients[0].ci(cls.test_coin)
if not cls.restore_instance:
ci0 = cls.swap_clients[0].ci(cls.test_coin)
assert (ci0.rpc_wallet('getnewaddress') == cls.dcr_mining_addr)
cls.dcr_ticket_account = ci0.rpc_wallet('getaccount', [cls.dcr_mining_addr, ])
ci0.rpc('generate', [110,])
@@ -567,42 +572,9 @@ class Test(BaseTest):
waitForRPC(make_rpc_func(i, base_rpc_port=DCR_BASE_RPC_PORT), test_delay_event, rpc_command='getnetworkinfo', max_tries=12)
logging.info('Creating wallet')
extra_opts.append('--pass=test_pass')
args = [os.path.join(DCR_BINDIR, DCR_WALLET), '--create'] + extra_opts
(pipe_r, pipe_w) = os.pipe() # subprocess.PIPE is buffered, blocks when read
p = subprocess.Popen(args, stdin=subprocess.PIPE, stdout=pipe_w, stderr=pipe_w)
try:
while p.poll() is None:
while len(select.select([pipe_r], [], [], 0)[0]) == 1:
buf = os.read(pipe_r, 1024).decode('utf-8')
logging.debug(f'dcrwallet {buf}')
response = None
if 'Use the existing configured private passphrase' in buf:
response = b'y\n'
elif 'Do you want to add an additional layer of encryption' in buf:
response = b'n\n'
elif 'Do you have an existing wallet seed' in buf:
response = b'y\n'
elif 'Enter existing wallet seed' in buf:
response = (cls.hex_seeds[i] + '\n').encode('utf-8')
elif 'Seed input successful' in buf:
pass
else:
raise ValueError(f'Unexpected output: {buf}')
if response is not None:
p.stdin.write(response)
p.stdin.flush()
test_delay_event.wait(0.1)
except Exception as e:
logging.error(f'{DCR_WALLET} --create failed: {e}')
finally:
if p.poll() is None:
p.terminate()
os.close(pipe_r)
os.close(pipe_w)
p.stdin.close()
createDCRWallet(args, cls.hex_seeds[i], logging, test_delay_event)
test_delay_event.wait(1.0)
@@ -769,7 +741,7 @@ class Test(BaseTest):
script = bytearray()
push_script_data(script, bytes((3,)))
script += OP_CHECKSEQUENCEVERIFY.to_bytes(1)
script += bytes((OP_CHECKSEQUENCEVERIFY,))
script_dest = ci0.getScriptDest(script)
script_info = ci0.rpc_wallet('decodescript', [script_dest.hex(),])

View File

@@ -49,6 +49,7 @@ from tests.basicswap.common_xmr import (
prepare_nodes,
XMR_BASE_RPC_PORT,
)
from basicswap.interface.dcr.rpc import callrpc as callrpc_dcr
import bin.basicswap_run as runSystem
@@ -61,6 +62,7 @@ UI_PORT = 12700 + PORT_OFS
PARTICL_RPC_PORT_BASE = int(os.getenv('PARTICL_RPC_PORT_BASE', BASE_RPC_PORT))
BITCOIN_RPC_PORT_BASE = int(os.getenv('BITCOIN_RPC_PORT_BASE', BTC_BASE_RPC_PORT))
LITECOIN_RPC_PORT_BASE = int(os.getenv('LITECOIN_RPC_PORT_BASE', LTC_BASE_RPC_PORT))
DECRED_WALLET_RPC_PORT_BASE = int(os.getenv('DECRED_WALLET_RPC_PORT_BASE', 9210))
XMR_BASE_RPC_PORT = int(os.getenv('XMR_BASE_RPC_PORT', XMR_BASE_RPC_PORT))
TEST_COINS_LIST = os.getenv('TEST_COINS_LIST', 'bitcoin,monero')
@@ -88,6 +90,11 @@ def callltcrpc(node_id, method, params=[], wallet=None, base_rpc_port=LITECOIN_R
return callrpc(base_rpc_port + node_id, auth, method, params, wallet)
def calldcrrpc(node_id, method, params=[], wallet=None, base_rpc_port=DECRED_WALLET_RPC_PORT_BASE):
auth = 'user:dcr_pwd'
return callrpc_dcr(base_rpc_port + node_id, auth, method, params)
def updateThread(cls):
while not cls.delay_event.is_set():
try:
@@ -98,7 +105,7 @@ def updateThread(cls):
cls.delay_event.wait(random.randrange(cls.update_min, cls.update_max))
def updateThreadXmr(cls):
def updateThreadXMR(cls):
xmr_auth = None
if os.getenv('XMR_RPC_USER', '') != '':
xmr_auth = (os.getenv('XMR_RPC_USER', ''), os.getenv('XMR_RPC_PWD', ''))
@@ -108,10 +115,38 @@ def updateThreadXmr(cls):
if cls.xmr_addr is not None:
callrpc_xmr(XMR_BASE_RPC_PORT + 1, 'generateblocks', {'wallet_address': cls.xmr_addr, 'amount_of_blocks': 1}, auth=xmr_auth)
except Exception as e:
print('updateThreadXmr error', str(e))
print('updateThreadXMR error', str(e))
cls.delay_event.wait(random.randrange(cls.xmr_update_min, cls.xmr_update_max))
def updateThreadDCR(cls):
while not cls.delay_event.is_set():
try:
pass
num_passed: int = 0
for i in range(30):
try:
calldcrrpc(0, 'purchaseticket', [cls.dcr_acc, 0.1, 0])
num_passed += 1
if num_passed >= 5:
break
cls.delay_event.wait(0.1)
except Exception as e:
if 'double spend' in str(e):
pass
else:
logging.warning('updateThreadDCR purchaseticket {}'.format(e))
cls.delay_event.wait(0.5)
try:
if num_passed >= 5:
calldcrrpc(0, 'generate', [1,])
except Exception as e:
logging.warning('updateThreadDCR generate {}'.format(e))
except Exception as e:
print('updateThreadDCR error', str(e))
cls.delay_event.wait(random.randrange(cls.dcr_update_min, cls.dcr_update_max))
class Test(unittest.TestCase):
@classmethod
def setUpClass(cls):
@@ -123,12 +158,18 @@ class Test(unittest.TestCase):
cls.xmr_update_min = int(os.getenv('XMR_UPDATE_THREAD_MIN_WAIT', '1'))
cls.xmr_update_max = cls.xmr_update_min * 4
cls.dcr_update_min = int(os.getenv('DCR_UPDATE_THREAD_MIN_WAIT', '1'))
cls.dcr_update_max = cls.dcr_update_min * 4
cls.delay_event = threading.Event()
cls.update_thread = None
cls.update_thread_xmr = None
cls.update_thread_dcr = None
cls.processes = []
cls.btc_addr = None
cls.xmr_addr = None
cls.dcr_addr = 'SsYbXyjkKAEXXcGdFgr4u4bo4L8RkCxwQpH'
cls.dcr_acc = None
random.seed(time.time())
@@ -197,13 +238,25 @@ class Test(unittest.TestCase):
have_blocks: int = callltcrpc(0, 'getblockcount')
callltcrpc(0, 'generatetoaddress', [500 - have_blocks, self.ltc_addr], wallet='wallet.dat')
if 'decred' in TEST_COINS_LIST:
if RESET_TEST:
addr = calldcrrpc(0, 'getnewaddress')
# assert (addr == self.dcr_addr)
self.dcr_acc = calldcrrpc(0, 'getaccount', [self.dcr_addr, ])
addr = calldcrrpc(0, 'generate', [110,])
else:
self.dcr_acc = calldcrrpc(0, 'getaccount', [self.dcr_addr, ])
self.update_thread_dcr = threading.Thread(target=updateThreadDCR, args=(self,))
self.update_thread_dcr.start()
# Lower output split threshold for more stakeable outputs
for i in range(NUM_NODES):
callpartrpc(i, 'walletsettings', ['stakingoptions', {'stakecombinethreshold': 100, 'stakesplitthreshold': 200}])
self.update_thread = threading.Thread(target=updateThread, args=(self,))
self.update_thread.start()
self.update_thread_xmr = threading.Thread(target=updateThreadXmr, args=(self,))
self.update_thread_xmr = threading.Thread(target=updateThreadXMR, args=(self,))
self.update_thread_xmr.start()
# Wait for height, or sequencelock is thrown off by genesis blocktime
@@ -228,12 +281,15 @@ class Test(unittest.TestCase):
cls.update_thread.join()
if cls.update_thread_xmr:
cls.update_thread_xmr.join()
if cls.update_thread_dcr:
cls.update_thread_dcr.join()
for p in cls.processes:
p.terminate()
for p in cls.processes:
p.join()
cls.update_thread = None
cls.update_thread_xmr = None
cls.update_thread_dcr = None
cls.processes = []
def test_persistent(self):