mirror of
https://github.com/basicswap/basicswap.git
synced 2024-11-16 15:58:17 +00:00
Reformat tests with black.
This commit is contained in:
parent
b484827c15
commit
7b03ce4769
38 changed files with 10345 additions and 5226 deletions
|
@ -6,7 +6,7 @@ lint_task:
|
|||
- pip install flake8 codespell
|
||||
script:
|
||||
- flake8 --version
|
||||
- PYTHONWARNINGS="ignore" flake8 --ignore=E501,F841,W503,E702,E131 --exclude=basicswap/contrib,basicswap/interface/contrib,messages_pb2.py,.eggs,.tox,bin/install_certifi.py
|
||||
- PYTHONWARNINGS="ignore" flake8 --ignore=E203,E501,F841,W503,E702,E131 --exclude=basicswap/contrib,basicswap/interface/contrib,messages_pb2.py,.eggs,.tox,bin/install_certifi.py
|
||||
- codespell --check-filenames --disable-colors --quiet-level=7 --ignore-words=tests/lint/spelling.ignore-words.txt -S .git,.eggs,.tox,pgp,*.pyc,*basicswap/contrib,*basicswap/interface/contrib,*mnemonics.py,bin/install_certifi.py,*basicswap/static
|
||||
|
||||
test_task:
|
||||
|
|
2
.github/workflows/lint.yml
vendored
2
.github/workflows/lint.yml
vendored
|
@ -20,7 +20,7 @@ jobs:
|
|||
pip install flake8 codespell
|
||||
- name: Running flake8
|
||||
run: |
|
||||
flake8 --ignore=E501,F841,W503 --per-file-ignores="basicswap/interface/bch.py:E131,E702" --exclude=basicswap/contrib,basicswap/interface/contrib,messages_pb2.py,.eggs,.tox,bin/install_certifi.py
|
||||
flake8 --ignore=E203,E501,F841,W503 --per-file-ignores="basicswap/interface/bch.py:E131,E702" --exclude=basicswap/contrib,basicswap/interface/contrib,messages_pb2.py,.eggs,.tox,bin/install_certifi.py
|
||||
- name: Running codespell
|
||||
run: |
|
||||
codespell --check-filenames --disable-colors --quiet-level=7 --ignore-words=tests/lint/spelling.ignore-words.txt -S .git,.eggs,.tox,pgp,*.pyc,*basicswap/contrib,*basicswap/interface/contrib,*mnemonics.py,bin/install_certifi.py,*basicswap/static
|
||||
|
|
|
@ -34,6 +34,8 @@ dev = [
|
|||
"flake8",
|
||||
"pip-tools",
|
||||
"pytest",
|
||||
"ruff",
|
||||
"black",
|
||||
"selenium",
|
||||
]
|
||||
|
||||
|
@ -42,3 +44,6 @@ path = "basicswap/__init__.py"
|
|||
|
||||
[tool.hatch.metadata]
|
||||
allow-direct-references = true
|
||||
|
||||
[tool.ruff]
|
||||
exclude = ["basicswap/contrib","basicswap/interface/contrib"]
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright (c) 2020-2024 tecnovert
|
||||
# Copyright (c) 2024 The Basicswap developers
|
||||
# Distributed under the MIT software license, see the accompanying
|
||||
# file LICENSE.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
|
@ -17,7 +18,9 @@ from basicswap.contrib.rpcauth import generate_salt, password_to_hmac
|
|||
from basicswap.bin.prepare import downloadPIVXParams
|
||||
|
||||
|
||||
TEST_HTTP_HOST = os.getenv('TEST_HTTP_HOST', '127.0.0.1') # Set to 0.0.0.0 when used in docker
|
||||
TEST_HTTP_HOST = os.getenv(
|
||||
"TEST_HTTP_HOST", "127.0.0.1"
|
||||
) # Set to 0.0.0.0 when used in docker
|
||||
TEST_HTTP_PORT = 1800
|
||||
|
||||
BASE_P2P_PORT = 12792
|
||||
|
@ -39,84 +42,99 @@ PIVX_BASE_PORT = 34892
|
|||
PIVX_BASE_RPC_PORT = 35892
|
||||
PIVX_BASE_ZMQ_PORT = 36892
|
||||
|
||||
PREFIX_SECRET_KEY_REGTEST = 0x2e
|
||||
PREFIX_SECRET_KEY_REGTEST = 0x2E
|
||||
|
||||
|
||||
def prepareDataDir(datadir, node_id, conf_file, dir_prefix, base_p2p_port=BASE_PORT, base_rpc_port=BASE_RPC_PORT, num_nodes=3, extra_opts=[]):
|
||||
def prepareDataDir(
|
||||
datadir,
|
||||
node_id,
|
||||
conf_file,
|
||||
dir_prefix,
|
||||
base_p2p_port=BASE_PORT,
|
||||
base_rpc_port=BASE_RPC_PORT,
|
||||
num_nodes=3,
|
||||
extra_opts=[],
|
||||
):
|
||||
node_dir = os.path.join(datadir, dir_prefix + str(node_id))
|
||||
if not os.path.exists(node_dir):
|
||||
os.makedirs(node_dir)
|
||||
cfg_file_path = os.path.join(node_dir, conf_file)
|
||||
if os.path.exists(cfg_file_path):
|
||||
return
|
||||
with open(cfg_file_path, 'w+') as fp:
|
||||
fp.write('regtest=1\n')
|
||||
fp.write('[regtest]\n')
|
||||
fp.write('port=' + str(base_p2p_port + node_id) + '\n')
|
||||
fp.write('rpcport=' + str(base_rpc_port + node_id) + '\n')
|
||||
with open(cfg_file_path, "w+") as fp:
|
||||
fp.write("regtest=1\n")
|
||||
fp.write("[regtest]\n")
|
||||
fp.write("port=" + str(base_p2p_port + node_id) + "\n")
|
||||
fp.write("rpcport=" + str(base_rpc_port + node_id) + "\n")
|
||||
|
||||
salt = generate_salt(16)
|
||||
fp.write('rpcauth={}:{}${}\n'.format('test' + str(node_id), salt, password_to_hmac(salt, 'test_pass' + str(node_id))))
|
||||
fp.write(
|
||||
"rpcauth={}:{}${}\n".format(
|
||||
"test" + str(node_id),
|
||||
salt,
|
||||
password_to_hmac(salt, "test_pass" + str(node_id)),
|
||||
)
|
||||
)
|
||||
|
||||
fp.write('daemon=0\n')
|
||||
fp.write('printtoconsole=0\n')
|
||||
fp.write('server=1\n')
|
||||
fp.write('discover=0\n')
|
||||
fp.write('listenonion=0\n')
|
||||
fp.write('bind=127.0.0.1\n')
|
||||
fp.write('debug=1\n')
|
||||
fp.write('debugexclude=libevent\n')
|
||||
fp.write("daemon=0\n")
|
||||
fp.write("printtoconsole=0\n")
|
||||
fp.write("server=1\n")
|
||||
fp.write("discover=0\n")
|
||||
fp.write("listenonion=0\n")
|
||||
fp.write("bind=127.0.0.1\n")
|
||||
fp.write("debug=1\n")
|
||||
fp.write("debugexclude=libevent\n")
|
||||
|
||||
fp.write('fallbackfee=0.01\n')
|
||||
fp.write('acceptnonstdtxn=0\n')
|
||||
fp.write('txindex=1\n')
|
||||
fp.write('wallet=wallet.dat\n')
|
||||
fp.write("fallbackfee=0.01\n")
|
||||
fp.write("acceptnonstdtxn=0\n")
|
||||
fp.write("txindex=1\n")
|
||||
fp.write("wallet=wallet.dat\n")
|
||||
|
||||
fp.write('findpeers=0\n')
|
||||
fp.write("findpeers=0\n")
|
||||
|
||||
for opt in extra_opts:
|
||||
fp.write(opt + '\n')
|
||||
fp.write(opt + "\n")
|
||||
|
||||
if base_p2p_port == BTC_BASE_PORT:
|
||||
fp.write('deprecatedrpc=create_bdb\n')
|
||||
fp.write("deprecatedrpc=create_bdb\n")
|
||||
elif base_p2p_port == BASE_PORT: # Particl
|
||||
fp.write('zmqpubsmsg=tcp://127.0.0.1:{}\n'.format(BASE_ZMQ_PORT + node_id))
|
||||
fp.write("zmqpubsmsg=tcp://127.0.0.1:{}\n".format(BASE_ZMQ_PORT + node_id))
|
||||
# minstakeinterval=5 # Using walletsettings stakelimit instead
|
||||
fp.write('stakethreadconddelayms=1000\n')
|
||||
fp.write('smsgsregtestadjust=0\n')
|
||||
fp.write("stakethreadconddelayms=1000\n")
|
||||
fp.write("smsgsregtestadjust=0\n")
|
||||
|
||||
if conf_file == 'pivx.conf':
|
||||
params_dir = os.path.join(datadir, 'pivx-params')
|
||||
if conf_file == "pivx.conf":
|
||||
params_dir = os.path.join(datadir, "pivx-params")
|
||||
downloadPIVXParams(params_dir)
|
||||
fp.write(f'paramsdir={params_dir}\n')
|
||||
fp.write(f"paramsdir={params_dir}\n")
|
||||
|
||||
for i in range(0, num_nodes):
|
||||
if node_id == i:
|
||||
continue
|
||||
fp.write('addnode=127.0.0.1:{}\n'.format(base_p2p_port + i))
|
||||
fp.write("addnode=127.0.0.1:{}\n".format(base_p2p_port + i))
|
||||
|
||||
return node_dir
|
||||
|
||||
|
||||
def checkForks(ro):
|
||||
try:
|
||||
if 'bip9_softforks' in ro:
|
||||
assert (ro['bip9_softforks']['csv']['status'] == 'active')
|
||||
assert (ro['bip9_softforks']['segwit']['status'] == 'active')
|
||||
if "bip9_softforks" in ro:
|
||||
assert ro["bip9_softforks"]["csv"]["status"] == "active"
|
||||
assert ro["bip9_softforks"]["segwit"]["status"] == "active"
|
||||
else:
|
||||
assert (ro['softforks']['csv']['active'])
|
||||
assert (ro['softforks']['segwit']['active'])
|
||||
assert ro["softforks"]["csv"]["active"]
|
||||
assert ro["softforks"]["segwit"]["active"]
|
||||
except Exception as e:
|
||||
logging.warning('Could not parse deployment info')
|
||||
logging.warning("Could not parse deployment info")
|
||||
|
||||
|
||||
def stopDaemons(daemons):
|
||||
for d in daemons:
|
||||
logging.info('Interrupting %d', d.handle.pid)
|
||||
logging.info("Interrupting %d", d.handle.pid)
|
||||
try:
|
||||
d.handle.send_signal(signal.SIGINT)
|
||||
except Exception as e:
|
||||
logging.info('Interrupting %d, error %s', d.handle.pid, str(e))
|
||||
logging.info("Interrupting %d, error %s", d.handle.pid, str(e))
|
||||
for d in daemons:
|
||||
try:
|
||||
d.handle.wait(timeout=20)
|
||||
|
@ -124,21 +142,23 @@ def stopDaemons(daemons):
|
|||
if fp:
|
||||
fp.close()
|
||||
except Exception as e:
|
||||
logging.info('Closing %d, error %s', d.handle.pid, str(e))
|
||||
logging.info("Closing %d, error %s", d.handle.pid, str(e))
|
||||
|
||||
|
||||
def wait_for_bid(delay_event, swap_client, bid_id, state=None, sent: bool = False, wait_for: int = 20) -> None:
|
||||
logging.info('wait_for_bid %s', bid_id.hex())
|
||||
def wait_for_bid(
|
||||
delay_event, swap_client, bid_id, state=None, sent: bool = False, wait_for: int = 20
|
||||
) -> None:
|
||||
logging.info("wait_for_bid %s", bid_id.hex())
|
||||
for i in range(wait_for):
|
||||
if delay_event.is_set():
|
||||
raise ValueError('Test stopped.')
|
||||
raise ValueError("Test stopped.")
|
||||
delay_event.wait(1)
|
||||
|
||||
filters = {
|
||||
'bid_id': bid_id,
|
||||
"bid_id": bid_id,
|
||||
}
|
||||
bids = swap_client.listBids(sent=sent, filters=filters)
|
||||
assert (len(bids) < 2)
|
||||
assert len(bids) < 2
|
||||
for bid in bids:
|
||||
if bid[2] == bid_id:
|
||||
if isinstance(state, (list, tuple)):
|
||||
|
@ -149,55 +169,65 @@ def wait_for_bid(delay_event, swap_client, bid_id, state=None, sent: bool = Fals
|
|||
elif state is not None and state != bid[5]:
|
||||
continue
|
||||
return
|
||||
raise ValueError('wait_for_bid timed out.')
|
||||
raise ValueError("wait_for_bid timed out.")
|
||||
|
||||
|
||||
def wait_for_bid_tx_state(delay_event, swap_client, bid_id, initiate_state, participate_state, wait_for=30):
|
||||
logging.info('wait_for_bid_tx_state %s %s %s', bid_id.hex(), str(initiate_state), str(participate_state))
|
||||
def wait_for_bid_tx_state(
|
||||
delay_event, swap_client, bid_id, initiate_state, participate_state, wait_for=30
|
||||
):
|
||||
logging.info(
|
||||
"wait_for_bid_tx_state %s %s %s",
|
||||
bid_id.hex(),
|
||||
str(initiate_state),
|
||||
str(participate_state),
|
||||
)
|
||||
for i in range(wait_for):
|
||||
if delay_event.is_set():
|
||||
raise ValueError('Test stopped.')
|
||||
raise ValueError("Test stopped.")
|
||||
delay_event.wait(1)
|
||||
bid = swap_client.getBid(bid_id)
|
||||
if (initiate_state is None or bid.getITxState() == initiate_state) \
|
||||
and (participate_state is None or bid.getPTxState() == participate_state):
|
||||
if (initiate_state is None or bid.getITxState() == initiate_state) and (
|
||||
participate_state is None or bid.getPTxState() == participate_state
|
||||
):
|
||||
return
|
||||
raise ValueError('wait_for_bid_tx_state timed out.')
|
||||
raise ValueError("wait_for_bid_tx_state timed out.")
|
||||
|
||||
|
||||
def wait_for_event(delay_event, swap_client, linked_type, linked_id, event_type=None, wait_for=20):
|
||||
logging.info('wait_for_event')
|
||||
def wait_for_event(
|
||||
delay_event, swap_client, linked_type, linked_id, event_type=None, wait_for=20
|
||||
):
|
||||
logging.info("wait_for_event")
|
||||
|
||||
for i in range(wait_for):
|
||||
if delay_event.is_set():
|
||||
raise ValueError('Test stopped.')
|
||||
raise ValueError("Test stopped.")
|
||||
delay_event.wait(1)
|
||||
rv = swap_client.getEvents(linked_type, linked_id)
|
||||
|
||||
for event in rv:
|
||||
if event_type is None or event.event_type == event_type:
|
||||
return event
|
||||
raise ValueError('wait_for_event timed out.')
|
||||
raise ValueError("wait_for_event timed out.")
|
||||
|
||||
|
||||
def wait_for_offer(delay_event, swap_client, offer_id, wait_for=20):
|
||||
logging.info('wait_for_offer %s', offer_id.hex())
|
||||
logging.info("wait_for_offer %s", offer_id.hex())
|
||||
for i in range(wait_for):
|
||||
if delay_event.is_set():
|
||||
raise ValueError('Test stopped.')
|
||||
raise ValueError("Test stopped.")
|
||||
delay_event.wait(1)
|
||||
offers = swap_client.listOffers()
|
||||
for offer in offers:
|
||||
if offer.offer_id == offer_id:
|
||||
return
|
||||
raise ValueError('wait_for_offer timed out.')
|
||||
raise ValueError("wait_for_offer timed out.")
|
||||
|
||||
|
||||
def wait_for_no_offer(delay_event, swap_client, offer_id, wait_for=20):
|
||||
logging.info('wait_for_no_offer %s', offer_id.hex())
|
||||
logging.info("wait_for_no_offer %s", offer_id.hex())
|
||||
for i in range(wait_for):
|
||||
if delay_event.is_set():
|
||||
raise ValueError('Test stopped.')
|
||||
raise ValueError("Test stopped.")
|
||||
delay_event.wait(1)
|
||||
offers = swap_client.listOffers()
|
||||
found_offer = False
|
||||
|
@ -207,35 +237,35 @@ def wait_for_no_offer(delay_event, swap_client, offer_id, wait_for=20):
|
|||
break
|
||||
if not found_offer:
|
||||
return True
|
||||
raise ValueError('wait_for_offer timed out.')
|
||||
raise ValueError("wait_for_offer timed out.")
|
||||
|
||||
|
||||
def wait_for_in_progress(delay_event, swap_client, bid_id, sent=False):
|
||||
logging.info('wait_for_in_progress %s', bid_id.hex())
|
||||
logging.info("wait_for_in_progress %s", bid_id.hex())
|
||||
for i in range(20):
|
||||
if delay_event.is_set():
|
||||
raise ValueError('Test stopped.')
|
||||
raise ValueError("Test stopped.")
|
||||
delay_event.wait(1)
|
||||
swaps = swap_client.listSwapsInProgress()
|
||||
for b in swaps:
|
||||
if b[0] == bid_id:
|
||||
return
|
||||
raise ValueError('wait_for_in_progress timed out.')
|
||||
raise ValueError("wait_for_in_progress timed out.")
|
||||
|
||||
|
||||
def wait_for_none_active(delay_event, port, wait_for=30):
|
||||
for i in range(wait_for):
|
||||
if delay_event.is_set():
|
||||
raise ValueError('Test stopped.')
|
||||
raise ValueError("Test stopped.")
|
||||
delay_event.wait(1)
|
||||
js = read_json_api(port)
|
||||
if js['num_swapping'] == 0 and js['num_watched_outputs'] == 0:
|
||||
if js["num_swapping"] == 0 and js["num_watched_outputs"] == 0:
|
||||
return
|
||||
raise ValueError('wait_for_none_active timed out.')
|
||||
raise ValueError("wait_for_none_active timed out.")
|
||||
|
||||
|
||||
def abandon_all_swaps(delay_event, swap_client) -> None:
|
||||
logging.info('abandon_all_swaps')
|
||||
logging.info("abandon_all_swaps")
|
||||
for bid in swap_client.listBids(sent=True):
|
||||
swap_client.abandonBid(bid[2])
|
||||
for bid in swap_client.listBids(sent=False):
|
||||
|
@ -245,37 +275,39 @@ def abandon_all_swaps(delay_event, swap_client) -> None:
|
|||
def waitForNumOffers(delay_event, port, offers, wait_for=20):
|
||||
for i in range(wait_for):
|
||||
if delay_event.is_set():
|
||||
raise ValueError('Test stopped.')
|
||||
raise ValueError("Test stopped.")
|
||||
summary = read_json_api(port)
|
||||
if summary['num_network_offers'] >= offers:
|
||||
if summary["num_network_offers"] >= offers:
|
||||
return
|
||||
delay_event.wait(1)
|
||||
raise ValueError('waitForNumOffers failed')
|
||||
raise ValueError("waitForNumOffers failed")
|
||||
|
||||
|
||||
def waitForNumBids(delay_event, port, bids, wait_for=20):
|
||||
for i in range(wait_for):
|
||||
if delay_event.is_set():
|
||||
raise ValueError('Test stopped.')
|
||||
raise ValueError("Test stopped.")
|
||||
summary = read_json_api(port)
|
||||
if summary['num_recv_bids'] >= bids:
|
||||
if summary["num_recv_bids"] >= bids:
|
||||
return
|
||||
delay_event.wait(1)
|
||||
raise ValueError('waitForNumBids failed')
|
||||
raise ValueError("waitForNumBids failed")
|
||||
|
||||
|
||||
def waitForNumSwapping(delay_event, port, bids, wait_for=60):
|
||||
for i in range(wait_for):
|
||||
if delay_event.is_set():
|
||||
raise ValueError('Test stopped.')
|
||||
raise ValueError("Test stopped.")
|
||||
summary = read_json_api(port)
|
||||
if summary['num_swapping'] >= bids:
|
||||
if summary["num_swapping"] >= bids:
|
||||
return
|
||||
delay_event.wait(1)
|
||||
raise ValueError('waitForNumSwapping failed')
|
||||
raise ValueError("waitForNumSwapping failed")
|
||||
|
||||
|
||||
def wait_for_balance(delay_event, url, balance_key, expect_amount, iterations=20, delay_time=3) -> None:
|
||||
def wait_for_balance(
|
||||
delay_event, url, balance_key, expect_amount, iterations=20, delay_time=3
|
||||
) -> None:
|
||||
i = 0
|
||||
while not delay_event.is_set():
|
||||
rv_js = json.loads(urlopen(url).read())
|
||||
|
@ -284,11 +316,13 @@ def wait_for_balance(delay_event, url, balance_key, expect_amount, iterations=20
|
|||
delay_event.wait(delay_time)
|
||||
i += 1
|
||||
if i > iterations:
|
||||
raise ValueError('Expect {} {}'.format(balance_key, expect_amount))
|
||||
raise ValueError("Expect {} {}".format(balance_key, expect_amount))
|
||||
|
||||
|
||||
def wait_for_unspent(delay_event, ci, expect_amount, iterations=20, delay_time=1) -> None:
|
||||
logging.info(f'Waiting for unspent balance: {expect_amount}')
|
||||
def wait_for_unspent(
|
||||
delay_event, ci, expect_amount, iterations=20, delay_time=1
|
||||
) -> None:
|
||||
logging.info(f"Waiting for unspent balance: {expect_amount}")
|
||||
i = 0
|
||||
while not delay_event.is_set():
|
||||
unspent_addr = ci.getUnspentsByAddr()
|
||||
|
@ -298,36 +332,41 @@ def wait_for_unspent(delay_event, ci, expect_amount, iterations=20, delay_time=1
|
|||
delay_event.wait(delay_time)
|
||||
i += 1
|
||||
if i > iterations:
|
||||
raise ValueError('wait_for_unspent {}'.format(expect_amount))
|
||||
raise ValueError("wait_for_unspent {}".format(expect_amount))
|
||||
|
||||
|
||||
def delay_for(delay_event, delay_for=60):
|
||||
logging.info('Delaying for {} seconds.'.format(delay_for))
|
||||
logging.info("Delaying for {} seconds.".format(delay_for))
|
||||
delay_event.wait(delay_for)
|
||||
|
||||
|
||||
def make_rpc_func(node_id, base_rpc_port=BASE_RPC_PORT):
|
||||
node_id = node_id
|
||||
auth = 'test{0}:test_pass{0}'.format(node_id)
|
||||
auth = "test{0}:test_pass{0}".format(node_id)
|
||||
|
||||
def rpc_func(method, params=None, wallet=None):
|
||||
nonlocal node_id, auth
|
||||
return callrpc(base_rpc_port + node_id, auth, method, params, wallet)
|
||||
|
||||
return rpc_func
|
||||
|
||||
|
||||
def waitForRPC(rpc_func, delay_event, rpc_command='getwalletinfo', max_tries=7):
|
||||
def waitForRPC(rpc_func, delay_event, rpc_command="getwalletinfo", max_tries=7):
|
||||
for i in range(max_tries + 1):
|
||||
if delay_event.is_set():
|
||||
raise ValueError('Test stopped.')
|
||||
raise ValueError("Test stopped.")
|
||||
try:
|
||||
rpc_func(rpc_command)
|
||||
return
|
||||
except Exception as ex:
|
||||
if i < max_tries:
|
||||
logging.warning('Can\'t connect to RPC: %s. Retrying in %d second/s.', str(ex), (i + 1))
|
||||
logging.warning(
|
||||
"Can't connect to RPC: %s. Retrying in %d second/s.",
|
||||
str(ex),
|
||||
(i + 1),
|
||||
)
|
||||
delay_event.wait(i + 1)
|
||||
raise ValueError('waitForRPC failed')
|
||||
raise ValueError("waitForRPC failed")
|
||||
|
||||
|
||||
def extract_states_from_xu_file(file_path, prefix):
|
||||
|
@ -336,39 +375,41 @@ def extract_states_from_xu_file(file_path, prefix):
|
|||
alt_counter = 0
|
||||
active_path = 0
|
||||
states[active_path] = []
|
||||
path_stack = [active_path, ]
|
||||
path_stack = [
|
||||
active_path,
|
||||
]
|
||||
with open(file_path) as fp:
|
||||
for line in fp:
|
||||
line = line.strip()
|
||||
if line.startswith('#'):
|
||||
if line.startswith("#"):
|
||||
continue
|
||||
|
||||
if line == '};':
|
||||
if line == "};":
|
||||
if len(path_stack) > 1:
|
||||
path_stack.pop()
|
||||
active_path = path_stack[-1]
|
||||
continue
|
||||
|
||||
split_line = line.split('[')
|
||||
split_line = line.split("[")
|
||||
if len(split_line) < 2:
|
||||
continue
|
||||
|
||||
definitions = split_line[0].split(' ')
|
||||
definitions = split_line[0].split(" ")
|
||||
if len(definitions) < 2:
|
||||
continue
|
||||
|
||||
if definitions[1] == 'alt':
|
||||
if definitions[1] == "alt":
|
||||
alt_counter += 1
|
||||
path_stack.append(alt_counter)
|
||||
|
||||
states[alt_counter] = [s for s in states[active_path]]
|
||||
continue
|
||||
|
||||
if definitions[0] == '---':
|
||||
if definitions[0] == "---":
|
||||
active_path = path_stack[-1]
|
||||
continue
|
||||
|
||||
if definitions[1] != 'abox':
|
||||
if definitions[1] != "abox":
|
||||
continue
|
||||
if definitions[0] != prefix:
|
||||
continue
|
||||
|
@ -384,7 +425,7 @@ def extract_states_from_xu_file(file_path, prefix):
|
|||
continue
|
||||
label = split_line[1][pos_start:pos_end]
|
||||
|
||||
if line.find('textbgcolor') > 0:
|
||||
if line.find("textbgcolor") > 0:
|
||||
# transaction status
|
||||
pass
|
||||
|
||||
|
@ -396,35 +437,39 @@ def extract_states_from_xu_file(file_path, prefix):
|
|||
def compare_bid_states(states, expect_states, exact_match: bool = True) -> bool:
|
||||
|
||||
for i in range(len(states) - 1, -1, -1):
|
||||
if states[i][1] == 'Bid Delaying':
|
||||
if states[i][1] == "Bid Delaying":
|
||||
del states[i]
|
||||
|
||||
try:
|
||||
if exact_match:
|
||||
assert (len(states) == len(expect_states))
|
||||
assert len(states) == len(expect_states)
|
||||
else:
|
||||
assert (len(states) >= len(expect_states))
|
||||
assert len(states) >= len(expect_states)
|
||||
|
||||
for i in range(len(expect_states)):
|
||||
s = states[i]
|
||||
if s[1] != expect_states[i]:
|
||||
if 'Bid ' + expect_states[i] == s[1]:
|
||||
logging.warning(f'Expected state {expect_states[i]} not an exact match to {s[1]}.')
|
||||
if "Bid " + expect_states[i] == s[1]:
|
||||
logging.warning(
|
||||
f"Expected state {expect_states[i]} not an exact match to {s[1]}."
|
||||
)
|
||||
continue
|
||||
if [s[0], expect_states[i]] in states:
|
||||
logging.warning(f'Expected state {expect_states[i]} found out of order at the same time as {s[1]}.')
|
||||
logging.warning(
|
||||
f"Expected state {expect_states[i]} found out of order at the same time as {s[1]}."
|
||||
)
|
||||
continue
|
||||
raise ValueError(f'Expected state {expect_states[i]}, found {s[1]}')
|
||||
assert (s[1] == expect_states[i])
|
||||
raise ValueError(f"Expected state {expect_states[i]}, found {s[1]}")
|
||||
assert s[1] == expect_states[i]
|
||||
except Exception as e:
|
||||
logging.info('Expecting states: {}'.format(json.dumps(expect_states, indent=4)))
|
||||
logging.info('Have states: {}'.format(json.dumps(states, indent=4)))
|
||||
logging.info("Expecting states: {}".format(json.dumps(expect_states, indent=4)))
|
||||
logging.info("Have states: {}".format(json.dumps(states, indent=4)))
|
||||
raise e
|
||||
return True
|
||||
|
||||
|
||||
def compare_bid_states_unordered(states, expect_states, ignore_states=[]) -> bool:
|
||||
ignore_states.append('Bid Delaying')
|
||||
ignore_states.append("Bid Delaying")
|
||||
for i in range(len(states) - 1, -1, -1):
|
||||
if states[i][1] in ignore_states:
|
||||
del states[i]
|
||||
|
@ -432,9 +477,9 @@ def compare_bid_states_unordered(states, expect_states, ignore_states=[]) -> boo
|
|||
try:
|
||||
assert len(states) == len(expect_states)
|
||||
for state in expect_states:
|
||||
assert (any(state in s[1] for s in states))
|
||||
assert any(state in s[1] for s in states)
|
||||
except Exception as e:
|
||||
logging.info('Expecting states: {}'.format(json.dumps(expect_states, indent=4)))
|
||||
logging.info('Have states: {}'.format(json.dumps(states, indent=4)))
|
||||
logging.info("Expecting states: {}".format(json.dumps(expect_states, indent=4)))
|
||||
logging.info("Have states: {}".format(json.dumps(states, indent=4)))
|
||||
raise e
|
||||
return True
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright (c) 2020-2024 tecnovert
|
||||
# Copyright (c) 2024 The Basicswap developers
|
||||
# Distributed under the MIT software license, see the accompanying
|
||||
# file LICENSE or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
|
@ -26,16 +27,22 @@ from tests.basicswap.util import (
|
|||
waitForServer,
|
||||
)
|
||||
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,
|
||||
BASE_PORT,
|
||||
BASE_RPC_PORT,
|
||||
BTC_BASE_PORT,
|
||||
BTC_BASE_RPC_PORT,
|
||||
BTC_BASE_TOR_PORT,
|
||||
LTC_BASE_PORT,
|
||||
LTC_BASE_RPC_PORT,
|
||||
PIVX_BASE_PORT,
|
||||
)
|
||||
from tests.basicswap.extended.test_dcr import (
|
||||
DCR_BASE_PORT, DCR_BASE_RPC_PORT,
|
||||
DCR_BASE_PORT,
|
||||
DCR_BASE_RPC_PORT,
|
||||
)
|
||||
from tests.basicswap.test_bch_xmr import (
|
||||
BCH_BASE_PORT, BCH_BASE_RPC_PORT,
|
||||
BCH_BASE_PORT,
|
||||
BCH_BASE_RPC_PORT,
|
||||
)
|
||||
|
||||
from basicswap.contrib.rpcauth import generate_salt, password_to_hmac
|
||||
|
@ -43,49 +50,58 @@ from basicswap.contrib.rpcauth import generate_salt, password_to_hmac
|
|||
import basicswap.config as cfg
|
||||
import basicswap.bin.run as runSystem
|
||||
|
||||
TEST_PATH = os.path.expanduser(os.getenv('TEST_PATH', '~/test_basicswap1'))
|
||||
TEST_PATH = os.path.expanduser(os.getenv("TEST_PATH", "~/test_basicswap1"))
|
||||
|
||||
PARTICL_PORT_BASE = int(os.getenv('PARTICL_PORT_BASE', BASE_PORT))
|
||||
PARTICL_RPC_PORT_BASE = int(os.getenv('PARTICL_RPC_PORT_BASE', BASE_RPC_PORT))
|
||||
PARTICL_PORT_BASE = int(os.getenv("PARTICL_PORT_BASE", BASE_PORT))
|
||||
PARTICL_RPC_PORT_BASE = int(os.getenv("PARTICL_RPC_PORT_BASE", BASE_RPC_PORT))
|
||||
|
||||
BITCOIN_PORT_BASE = int(os.getenv('BITCOIN_PORT_BASE', BTC_BASE_PORT))
|
||||
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))
|
||||
BITCOIN_PORT_BASE = int(os.getenv("BITCOIN_PORT_BASE", BTC_BASE_PORT))
|
||||
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))
|
||||
BITCOINCASH_RPC_PORT_BASE = int(os.getenv('BITCOINCASH_RPC_PORT_BASE', BCH_BASE_RPC_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))
|
||||
BITCOINCASH_RPC_PORT_BASE = int(
|
||||
os.getenv("BITCOINCASH_RPC_PORT_BASE", BCH_BASE_RPC_PORT)
|
||||
)
|
||||
|
||||
|
||||
FIRO_BASE_PORT = 34832
|
||||
FIRO_BASE_RPC_PORT = 35832
|
||||
FIRO_RPC_PORT_BASE = int(os.getenv('FIRO_RPC_PORT_BASE', FIRO_BASE_RPC_PORT))
|
||||
FIRO_RPC_PORT_BASE = int(os.getenv("FIRO_RPC_PORT_BASE", FIRO_BASE_RPC_PORT))
|
||||
|
||||
|
||||
XMR_BASE_P2P_PORT = 17792
|
||||
XMR_BASE_RPC_PORT = 29798
|
||||
XMR_BASE_WALLET_RPC_PORT = 29998
|
||||
|
||||
EXTRA_CONFIG_JSON = json.loads(os.getenv('EXTRA_CONFIG_JSON', '{}'))
|
||||
EXTRA_CONFIG_JSON = json.loads(os.getenv("EXTRA_CONFIG_JSON", "{}"))
|
||||
|
||||
|
||||
def waitForBidState(delay_event, port, bid_id, state_str, wait_for=60):
|
||||
for i in range(wait_for):
|
||||
if delay_event.is_set():
|
||||
raise ValueError('Test stopped.')
|
||||
bid = json.loads(urlopen('http://127.0.0.1:12700/json/bids/{}'.format(bid_id)).read())
|
||||
if bid['bid_state'] == state_str:
|
||||
raise ValueError("Test stopped.")
|
||||
bid = json.loads(
|
||||
urlopen("http://127.0.0.1:12700/json/bids/{}".format(bid_id)).read()
|
||||
)
|
||||
if bid["bid_state"] == state_str:
|
||||
return
|
||||
delay_event.wait(1)
|
||||
raise ValueError('waitForBidState failed')
|
||||
raise ValueError("waitForBidState failed")
|
||||
|
||||
|
||||
def updateThread(xmr_addr, delay_event, xmr_auth):
|
||||
while not delay_event.is_set():
|
||||
try:
|
||||
callrpc_xmr(XMR_BASE_RPC_PORT + 1, 'generateblocks', {'wallet_address': xmr_addr, 'amount_of_blocks': 1}, auth=xmr_auth)
|
||||
callrpc_xmr(
|
||||
XMR_BASE_RPC_PORT + 1,
|
||||
"generateblocks",
|
||||
{"wallet_address": xmr_addr, "amount_of_blocks": 1},
|
||||
auth=xmr_auth,
|
||||
)
|
||||
except Exception as e:
|
||||
print('updateThread error', str(e))
|
||||
print("updateThread error", str(e))
|
||||
delay_event.wait(2)
|
||||
|
||||
|
||||
|
@ -97,47 +113,63 @@ def recursive_update_dict(base, new_vals):
|
|||
base[key] = value
|
||||
|
||||
|
||||
def run_prepare(node_id, datadir_path, bins_path, with_coins, mnemonic_in=None, num_nodes=3, use_rpcauth=False, extra_settings={}, port_ofs=0):
|
||||
def run_prepare(
|
||||
node_id,
|
||||
datadir_path,
|
||||
bins_path,
|
||||
with_coins,
|
||||
mnemonic_in=None,
|
||||
num_nodes=3,
|
||||
use_rpcauth=False,
|
||||
extra_settings={},
|
||||
port_ofs=0,
|
||||
):
|
||||
config_path = os.path.join(datadir_path, cfg.CONFIG_FILENAME)
|
||||
|
||||
os.environ['BSX_TEST_MODE'] = 'true'
|
||||
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['BCH_PORT'] = str(BCH_BASE_PORT)
|
||||
os.environ['BCH_RPC_PORT'] = str(BITCOINCASH_RPC_PORT_BASE)
|
||||
os.environ['FIRO_RPC_PORT'] = str(FIRO_RPC_PORT_BASE)
|
||||
os.environ["BSX_TEST_MODE"] = "true"
|
||||
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["BCH_PORT"] = str(BCH_BASE_PORT)
|
||||
os.environ["BCH_RPC_PORT"] = str(BITCOINCASH_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["XMR_RPC_USER"] = "xmr_user"
|
||||
os.environ["XMR_RPC_PWD"] = "xmr_pwd"
|
||||
|
||||
os.environ['DCR_RPC_PWD'] = 'dcr_pwd'
|
||||
os.environ["DCR_RPC_PWD"] = "dcr_pwd"
|
||||
|
||||
import basicswap.bin.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
|
||||
|
||||
prepareSystem = reload(prepareSystem)
|
||||
|
||||
testargs = [
|
||||
'basicswap-prepare',
|
||||
"basicswap-prepare",
|
||||
f'-datadir="{datadir_path}"',
|
||||
f'-bindir="{bins_path}"',
|
||||
f'-portoffset={(node_id + port_ofs)}',
|
||||
'-regtest',
|
||||
f'-withcoins={with_coins}',
|
||||
'-noextractover',
|
||||
'-noreleasesizecheck',
|
||||
'-xmrrestoreheight=0']
|
||||
f"-portoffset={(node_id + port_ofs)}",
|
||||
"-regtest",
|
||||
f"-withcoins={with_coins}",
|
||||
"-noextractover",
|
||||
"-noreleasesizecheck",
|
||||
"-xmrrestoreheight=0",
|
||||
]
|
||||
if mnemonic_in:
|
||||
testargs.append(f'-particl_mnemonic="{mnemonic_in}"')
|
||||
|
||||
keysdirpath = os.getenv('PGP_KEYS_DIR_PATH', None)
|
||||
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()
|
||||
lines = mocked_stdout.getvalue().split('\n')
|
||||
lines = mocked_stdout.getvalue().split("\n")
|
||||
if mnemonic_in is None:
|
||||
mnemonic_out = lines[-4]
|
||||
else:
|
||||
|
@ -146,248 +178,311 @@ def run_prepare(node_id, datadir_path, bins_path, with_coins, mnemonic_in=None,
|
|||
with open(config_path) as fs:
|
||||
settings = json.load(fs)
|
||||
|
||||
config_filename = os.path.join(datadir_path, 'particl', 'particl.conf')
|
||||
with open(config_filename, '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(config_filename, 'w') as fp:
|
||||
with open(config_filename, "w") as fp:
|
||||
for line in lines:
|
||||
if not line.startswith('staking'):
|
||||
if not line.startswith("staking"):
|
||||
fp.write(line)
|
||||
fp.write('port={}\n'.format(PARTICL_PORT_BASE + node_id + port_ofs))
|
||||
fp.write('bind=127.0.0.1\n')
|
||||
fp.write('dnsseed=0\n')
|
||||
fp.write('discover=0\n')
|
||||
fp.write('listenonion=0\n')
|
||||
fp.write('upnp=0\n')
|
||||
fp.write('minstakeinterval=5\n')
|
||||
fp.write('stakethreadconddelayms=2000\n')
|
||||
fp.write('smsgsregtestadjust=0\n')
|
||||
fp.write("port={}\n".format(PARTICL_PORT_BASE + node_id + port_ofs))
|
||||
fp.write("bind=127.0.0.1\n")
|
||||
fp.write("dnsseed=0\n")
|
||||
fp.write("discover=0\n")
|
||||
fp.write("listenonion=0\n")
|
||||
fp.write("upnp=0\n")
|
||||
fp.write("minstakeinterval=5\n")
|
||||
fp.write("stakethreadconddelayms=2000\n")
|
||||
fp.write("smsgsregtestadjust=0\n")
|
||||
if use_rpcauth:
|
||||
salt = generate_salt(16)
|
||||
rpc_user = 'test_part_' + str(node_id)
|
||||
rpc_pass = 'test_part_pwd_' + str(node_id)
|
||||
fp.write('rpcauth={}:{}${}\n'.format(rpc_user, salt, password_to_hmac(salt, rpc_pass)))
|
||||
settings['chainclients']['particl']['rpcuser'] = rpc_user
|
||||
settings['chainclients']['particl']['rpcpassword'] = rpc_pass
|
||||
rpc_user = "test_part_" + str(node_id)
|
||||
rpc_pass = "test_part_pwd_" + str(node_id)
|
||||
fp.write(
|
||||
"rpcauth={}:{}${}\n".format(
|
||||
rpc_user, salt, password_to_hmac(salt, rpc_pass)
|
||||
)
|
||||
)
|
||||
settings["chainclients"]["particl"]["rpcuser"] = rpc_user
|
||||
settings["chainclients"]["particl"]["rpcpassword"] = rpc_pass
|
||||
for ip in range(num_nodes):
|
||||
if ip != node_id:
|
||||
fp.write('connect=127.0.0.1:{}\n'.format(PARTICL_PORT_BASE + ip + port_ofs))
|
||||
for opt in EXTRA_CONFIG_JSON.get('part{}'.format(node_id), []):
|
||||
fp.write(opt + '\n')
|
||||
fp.write(
|
||||
"connect=127.0.0.1:{}\n".format(PARTICL_PORT_BASE + ip + port_ofs)
|
||||
)
|
||||
for opt in EXTRA_CONFIG_JSON.get("part{}".format(node_id), []):
|
||||
fp.write(opt + "\n")
|
||||
|
||||
coins_array = with_coins.split(',')
|
||||
coins_array = with_coins.split(",")
|
||||
|
||||
if 'bitcoin' in coins_array:
|
||||
if "bitcoin" in coins_array:
|
||||
# Pruned nodes don't provide blocks
|
||||
config_filename = os.path.join(datadir_path, 'bitcoin', 'bitcoin.conf')
|
||||
with open(config_filename, '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(config_filename, 'w') as fp:
|
||||
with open(config_filename, "w") as fp:
|
||||
for line in lines:
|
||||
if not line.startswith('prune'):
|
||||
if not line.startswith("prune"):
|
||||
fp.write(line)
|
||||
fp.write('port={}\n'.format(BITCOIN_PORT_BASE + node_id + port_ofs))
|
||||
fp.write('bind=127.0.0.1\n')
|
||||
fp.write("port={}\n".format(BITCOIN_PORT_BASE + node_id + port_ofs))
|
||||
fp.write("bind=127.0.0.1\n")
|
||||
# listenonion=0 does not stop the node from trying to bind to the tor port
|
||||
# https://github.com/bitcoin/bitcoin/issues/22726
|
||||
fp.write('bind=127.0.0.1:{}=onion\n'.format(BITCOIN_TOR_PORT_BASE + node_id + port_ofs))
|
||||
fp.write('dnsseed=0\n')
|
||||
fp.write('discover=0\n')
|
||||
fp.write('listenonion=0\n')
|
||||
fp.write('upnp=0\n')
|
||||
fp.write(
|
||||
"bind=127.0.0.1:{}=onion\n".format(
|
||||
BITCOIN_TOR_PORT_BASE + node_id + port_ofs
|
||||
)
|
||||
)
|
||||
fp.write("dnsseed=0\n")
|
||||
fp.write("discover=0\n")
|
||||
fp.write("listenonion=0\n")
|
||||
fp.write("upnp=0\n")
|
||||
if use_rpcauth:
|
||||
salt = generate_salt(16)
|
||||
rpc_user = 'test_btc_' + str(node_id)
|
||||
rpc_pass = 'test_btc_pwd_' + str(node_id)
|
||||
fp.write('rpcauth={}:{}${}\n'.format(rpc_user, salt, password_to_hmac(salt, rpc_pass)))
|
||||
settings['chainclients']['bitcoin']['rpcuser'] = rpc_user
|
||||
settings['chainclients']['bitcoin']['rpcpassword'] = rpc_pass
|
||||
rpc_user = "test_btc_" + str(node_id)
|
||||
rpc_pass = "test_btc_pwd_" + str(node_id)
|
||||
fp.write(
|
||||
"rpcauth={}:{}${}\n".format(
|
||||
rpc_user, salt, password_to_hmac(salt, rpc_pass)
|
||||
)
|
||||
)
|
||||
settings["chainclients"]["bitcoin"]["rpcuser"] = rpc_user
|
||||
settings["chainclients"]["bitcoin"]["rpcpassword"] = rpc_pass
|
||||
for ip in range(num_nodes):
|
||||
if ip != node_id:
|
||||
fp.write('connect=127.0.0.1:{}\n'.format(BITCOIN_PORT_BASE + ip + port_ofs))
|
||||
for opt in EXTRA_CONFIG_JSON.get('btc{}'.format(node_id), []):
|
||||
fp.write(opt + '\n')
|
||||
fp.write(
|
||||
"connect=127.0.0.1:{}\n".format(
|
||||
BITCOIN_PORT_BASE + ip + port_ofs
|
||||
)
|
||||
)
|
||||
for opt in EXTRA_CONFIG_JSON.get("btc{}".format(node_id), []):
|
||||
fp.write(opt + "\n")
|
||||
|
||||
if 'litecoin' in coins_array:
|
||||
if "litecoin" in coins_array:
|
||||
# Pruned nodes don't provide blocks
|
||||
config_filename = os.path.join(datadir_path, 'litecoin', 'litecoin.conf')
|
||||
with open(config_filename, '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(config_filename, 'w') as fp:
|
||||
with open(config_filename, "w") as fp:
|
||||
for line in lines:
|
||||
if not line.startswith('prune'):
|
||||
if not line.startswith("prune"):
|
||||
fp.write(line)
|
||||
fp.write('port={}\n'.format(LTC_BASE_PORT + node_id + port_ofs))
|
||||
fp.write('bind=127.0.0.1\n')
|
||||
fp.write('dnsseed=0\n')
|
||||
fp.write('discover=0\n')
|
||||
fp.write('listenonion=0\n')
|
||||
fp.write('upnp=0\n')
|
||||
fp.write("port={}\n".format(LTC_BASE_PORT + node_id + port_ofs))
|
||||
fp.write("bind=127.0.0.1\n")
|
||||
fp.write("dnsseed=0\n")
|
||||
fp.write("discover=0\n")
|
||||
fp.write("listenonion=0\n")
|
||||
fp.write("upnp=0\n")
|
||||
if use_rpcauth:
|
||||
salt = generate_salt(16)
|
||||
rpc_user = 'test_ltc_' + str(node_id)
|
||||
rpc_pass = 'test_ltc_pwd_' + str(node_id)
|
||||
fp.write('rpcauth={}:{}${}\n'.format(rpc_user, salt, password_to_hmac(salt, rpc_pass)))
|
||||
settings['chainclients']['litecoin']['rpcuser'] = rpc_user
|
||||
settings['chainclients']['litecoin']['rpcpassword'] = rpc_pass
|
||||
rpc_user = "test_ltc_" + str(node_id)
|
||||
rpc_pass = "test_ltc_pwd_" + str(node_id)
|
||||
fp.write(
|
||||
"rpcauth={}:{}${}\n".format(
|
||||
rpc_user, salt, password_to_hmac(salt, rpc_pass)
|
||||
)
|
||||
)
|
||||
settings["chainclients"]["litecoin"]["rpcuser"] = rpc_user
|
||||
settings["chainclients"]["litecoin"]["rpcpassword"] = rpc_pass
|
||||
for ip in range(num_nodes):
|
||||
if ip != node_id:
|
||||
fp.write('connect=127.0.0.1:{}\n'.format(LTC_BASE_PORT + ip + port_ofs))
|
||||
for opt in EXTRA_CONFIG_JSON.get('ltc{}'.format(node_id), []):
|
||||
fp.write(opt + '\n')
|
||||
fp.write(
|
||||
"connect=127.0.0.1:{}\n".format(LTC_BASE_PORT + ip + port_ofs)
|
||||
)
|
||||
for opt in EXTRA_CONFIG_JSON.get("ltc{}".format(node_id), []):
|
||||
fp.write(opt + "\n")
|
||||
|
||||
if 'decred' in coins_array:
|
||||
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:
|
||||
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:
|
||||
with open(config_filename, "w") as fp:
|
||||
for line in lines:
|
||||
if not line.startswith('prune'):
|
||||
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')
|
||||
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')
|
||||
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')
|
||||
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:
|
||||
if "pivx" in coins_array:
|
||||
# Pruned nodes don't provide blocks
|
||||
config_filename = os.path.join(datadir_path, 'pivx', 'pivx.conf')
|
||||
with open(config_filename, '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(config_filename, 'w') as fp:
|
||||
with open(config_filename, "w") as fp:
|
||||
for line in lines:
|
||||
if not line.startswith('prune'):
|
||||
if not line.startswith("prune"):
|
||||
fp.write(line)
|
||||
fp.write('port={}\n'.format(PIVX_BASE_PORT + node_id + port_ofs))
|
||||
fp.write('bind=127.0.0.1\n')
|
||||
fp.write('dnsseed=0\n')
|
||||
fp.write('discover=0\n')
|
||||
fp.write('listenonion=0\n')
|
||||
fp.write('upnp=0\n')
|
||||
fp.write("port={}\n".format(PIVX_BASE_PORT + node_id + port_ofs))
|
||||
fp.write("bind=127.0.0.1\n")
|
||||
fp.write("dnsseed=0\n")
|
||||
fp.write("discover=0\n")
|
||||
fp.write("listenonion=0\n")
|
||||
fp.write("upnp=0\n")
|
||||
if use_rpcauth:
|
||||
salt = generate_salt(16)
|
||||
rpc_user = 'test_pivx_' + str(node_id)
|
||||
rpc_pass = 'test_pivx_pwd_' + str(node_id)
|
||||
fp.write('rpcauth={}:{}${}\n'.format(rpc_user, salt, password_to_hmac(salt, rpc_pass)))
|
||||
settings['chainclients']['pivx']['rpcuser'] = rpc_user
|
||||
settings['chainclients']['pivx']['rpcpassword'] = rpc_pass
|
||||
rpc_user = "test_pivx_" + str(node_id)
|
||||
rpc_pass = "test_pivx_pwd_" + str(node_id)
|
||||
fp.write(
|
||||
"rpcauth={}:{}${}\n".format(
|
||||
rpc_user, salt, password_to_hmac(salt, rpc_pass)
|
||||
)
|
||||
)
|
||||
settings["chainclients"]["pivx"]["rpcuser"] = rpc_user
|
||||
settings["chainclients"]["pivx"]["rpcpassword"] = rpc_pass
|
||||
for ip in range(num_nodes):
|
||||
if ip != node_id:
|
||||
fp.write('connect=127.0.0.1:{}\n'.format(PIVX_BASE_PORT + ip + port_ofs))
|
||||
for opt in EXTRA_CONFIG_JSON.get('pivx{}'.format(node_id), []):
|
||||
fp.write(opt + '\n')
|
||||
fp.write(
|
||||
"connect=127.0.0.1:{}\n".format(PIVX_BASE_PORT + ip + port_ofs)
|
||||
)
|
||||
for opt in EXTRA_CONFIG_JSON.get("pivx{}".format(node_id), []):
|
||||
fp.write(opt + "\n")
|
||||
|
||||
if 'firo' in coins_array:
|
||||
if "firo" in coins_array:
|
||||
# Pruned nodes don't provide blocks
|
||||
config_filename = os.path.join(datadir_path, 'firo', 'firo.conf')
|
||||
with open(config_filename, '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(config_filename, 'w') as fp:
|
||||
with open(config_filename, "w") as fp:
|
||||
for line in lines:
|
||||
if not line.startswith('prune'):
|
||||
if not line.startswith("prune"):
|
||||
fp.write(line)
|
||||
fp.write('port={}\n'.format(FIRO_BASE_PORT + node_id + port_ofs))
|
||||
fp.write('bind=127.0.0.1\n')
|
||||
fp.write('dnsseed=0\n')
|
||||
fp.write('discover=0\n')
|
||||
fp.write('listenonion=0\n')
|
||||
fp.write('upnp=0\n')
|
||||
fp.write("port={}\n".format(FIRO_BASE_PORT + node_id + port_ofs))
|
||||
fp.write("bind=127.0.0.1\n")
|
||||
fp.write("dnsseed=0\n")
|
||||
fp.write("discover=0\n")
|
||||
fp.write("listenonion=0\n")
|
||||
fp.write("upnp=0\n")
|
||||
if use_rpcauth:
|
||||
salt = generate_salt(16)
|
||||
rpc_user = 'test_firo_' + str(node_id)
|
||||
rpc_pass = 'test_firo_pwd_' + str(node_id)
|
||||
fp.write('rpcauth={}:{}${}\n'.format(rpc_user, salt, password_to_hmac(salt, rpc_pass)))
|
||||
settings['chainclients']['firo']['rpcuser'] = rpc_user
|
||||
settings['chainclients']['firo']['rpcpassword'] = rpc_pass
|
||||
rpc_user = "test_firo_" + str(node_id)
|
||||
rpc_pass = "test_firo_pwd_" + str(node_id)
|
||||
fp.write(
|
||||
"rpcauth={}:{}${}\n".format(
|
||||
rpc_user, salt, password_to_hmac(salt, rpc_pass)
|
||||
)
|
||||
)
|
||||
settings["chainclients"]["firo"]["rpcuser"] = rpc_user
|
||||
settings["chainclients"]["firo"]["rpcpassword"] = rpc_pass
|
||||
for ip in range(num_nodes):
|
||||
if ip != node_id:
|
||||
fp.write('connect=127.0.0.1:{}\n'.format(FIRO_BASE_PORT + ip + port_ofs))
|
||||
for opt in EXTRA_CONFIG_JSON.get('firo{}'.format(node_id), []):
|
||||
fp.write(opt + '\n')
|
||||
fp.write(
|
||||
"connect=127.0.0.1:{}\n".format(FIRO_BASE_PORT + ip + port_ofs)
|
||||
)
|
||||
for opt in EXTRA_CONFIG_JSON.get("firo{}".format(node_id), []):
|
||||
fp.write(opt + "\n")
|
||||
|
||||
if 'monero' in coins_array:
|
||||
with open(os.path.join(datadir_path, 'monero', 'monerod.conf'), 'a') as fp:
|
||||
fp.write('p2p-bind-ip=127.0.0.1\n')
|
||||
fp.write('p2p-bind-port={}\n'.format(XMR_BASE_P2P_PORT + node_id + port_ofs))
|
||||
if "monero" in coins_array:
|
||||
with open(os.path.join(datadir_path, "monero", "monerod.conf"), "a") as fp:
|
||||
fp.write("p2p-bind-ip=127.0.0.1\n")
|
||||
fp.write(
|
||||
"p2p-bind-port={}\n".format(XMR_BASE_P2P_PORT + node_id + port_ofs)
|
||||
)
|
||||
for ip in range(num_nodes):
|
||||
if ip != node_id:
|
||||
fp.write('add-exclusive-node=127.0.0.1:{}\n'.format(XMR_BASE_P2P_PORT + ip + port_ofs))
|
||||
fp.write(
|
||||
"add-exclusive-node=127.0.0.1:{}\n".format(
|
||||
XMR_BASE_P2P_PORT + ip + port_ofs
|
||||
)
|
||||
)
|
||||
|
||||
if 'bitcoincash' in coins_array:
|
||||
config_filename = os.path.join(datadir_path, 'bitcoincash', 'bitcoin.conf')
|
||||
with open(config_filename, 'r') as fp:
|
||||
if "bitcoincash" in coins_array:
|
||||
config_filename = os.path.join(datadir_path, "bitcoincash", "bitcoin.conf")
|
||||
with open(config_filename, "r") as fp:
|
||||
lines = fp.readlines()
|
||||
with open(config_filename, 'w') as fp:
|
||||
with open(config_filename, "w") as fp:
|
||||
for line in lines:
|
||||
if not line.startswith('prune'):
|
||||
if not line.startswith("prune"):
|
||||
fp.write(line)
|
||||
# NOTE: port is set (when starting daemon) from basicswap.json
|
||||
fp.write('bind=127.0.0.1\n')
|
||||
fp.write('dnsseed=0\n')
|
||||
fp.write('discover=0\n')
|
||||
fp.write('listenonion=0\n')
|
||||
fp.write('upnp=0\n')
|
||||
fp.write("bind=127.0.0.1\n")
|
||||
fp.write("dnsseed=0\n")
|
||||
fp.write("discover=0\n")
|
||||
fp.write("listenonion=0\n")
|
||||
fp.write("upnp=0\n")
|
||||
if use_rpcauth:
|
||||
salt = generate_salt(16)
|
||||
rpc_user = 'test_bch_' + str(node_id)
|
||||
rpc_pass = 'test_bch_pwd_' + str(node_id)
|
||||
fp.write('rpcauth={}:{}${}\n'.format(rpc_user, salt, password_to_hmac(salt, rpc_pass)))
|
||||
settings['chainclients']['bitcoincash']['rpcuser'] = rpc_user
|
||||
settings['chainclients']['bitcoincash']['rpcpassword'] = rpc_pass
|
||||
rpc_user = "test_bch_" + str(node_id)
|
||||
rpc_pass = "test_bch_pwd_" + str(node_id)
|
||||
fp.write(
|
||||
"rpcauth={}:{}${}\n".format(
|
||||
rpc_user, salt, password_to_hmac(salt, rpc_pass)
|
||||
)
|
||||
)
|
||||
settings["chainclients"]["bitcoincash"]["rpcuser"] = rpc_user
|
||||
settings["chainclients"]["bitcoincash"]["rpcpassword"] = rpc_pass
|
||||
for ip in range(num_nodes):
|
||||
if ip != node_id:
|
||||
fp.write('connect=127.0.0.1:{}\n'.format(BCH_BASE_PORT + ip + port_ofs))
|
||||
for opt in EXTRA_CONFIG_JSON.get('bch{}'.format(node_id), []):
|
||||
fp.write(opt + '\n')
|
||||
fp.write(
|
||||
"connect=127.0.0.1:{}\n".format(BCH_BASE_PORT + ip + port_ofs)
|
||||
)
|
||||
for opt in EXTRA_CONFIG_JSON.get("bch{}".format(node_id), []):
|
||||
fp.write(opt + "\n")
|
||||
|
||||
with open(config_path) as fs:
|
||||
settings = json.load(fs)
|
||||
|
||||
settings['min_delay_event'] = 1
|
||||
settings['max_delay_event'] = 4
|
||||
settings['min_delay_event_short'] = 1
|
||||
settings['max_delay_event_short'] = 4
|
||||
settings['min_delay_retry'] = 10
|
||||
settings['max_delay_retry'] = 20
|
||||
settings["min_delay_event"] = 1
|
||||
settings["max_delay_event"] = 4
|
||||
settings["min_delay_event_short"] = 1
|
||||
settings["max_delay_event_short"] = 4
|
||||
settings["min_delay_retry"] = 10
|
||||
settings["max_delay_retry"] = 20
|
||||
|
||||
settings['check_progress_seconds'] = 5
|
||||
settings['check_watched_seconds'] = 5
|
||||
settings['check_expired_seconds'] = 60
|
||||
settings['check_events_seconds'] = 5
|
||||
settings['check_xmr_swaps_seconds'] = 5
|
||||
settings["check_progress_seconds"] = 5
|
||||
settings["check_watched_seconds"] = 5
|
||||
settings["check_expired_seconds"] = 60
|
||||
settings["check_events_seconds"] = 5
|
||||
settings["check_xmr_swaps_seconds"] = 5
|
||||
|
||||
recursive_update_dict(settings, extra_settings)
|
||||
|
||||
extra_config = EXTRA_CONFIG_JSON.get('sc{}'.format(node_id), {})
|
||||
extra_config = EXTRA_CONFIG_JSON.get("sc{}".format(node_id), {})
|
||||
recursive_update_dict(settings, extra_config)
|
||||
|
||||
with open(config_path, 'w') as fp:
|
||||
with open(config_path, "w") as fp:
|
||||
json.dump(settings, fp, indent=4)
|
||||
|
||||
return mnemonic_out
|
||||
|
||||
|
||||
def prepare_nodes(num_nodes, extra_coins, use_rpcauth=False, extra_settings={}, port_ofs=0):
|
||||
bins_path = os.path.join(TEST_PATH, 'bin')
|
||||
def prepare_nodes(
|
||||
num_nodes, extra_coins, use_rpcauth=False, extra_settings={}, port_ofs=0
|
||||
):
|
||||
bins_path = os.path.join(TEST_PATH, "bin")
|
||||
for i in range(num_nodes):
|
||||
logging.info('Preparing node: %d.', i)
|
||||
client_path = os.path.join(TEST_PATH, 'client{}'.format(i))
|
||||
logging.info("Preparing node: %d.", i)
|
||||
client_path = os.path.join(TEST_PATH, "client{}".format(i))
|
||||
try:
|
||||
shutil.rmtree(client_path)
|
||||
except Exception as ex:
|
||||
logging.warning('setUpClass %s', str(ex))
|
||||
logging.warning("setUpClass %s", str(ex))
|
||||
|
||||
run_prepare(i, client_path, bins_path, extra_coins, mnemonics[i] if i < len(mnemonics) else None,
|
||||
num_nodes=num_nodes, use_rpcauth=use_rpcauth, extra_settings=extra_settings, port_ofs=port_ofs)
|
||||
run_prepare(
|
||||
i,
|
||||
client_path,
|
||||
bins_path,
|
||||
extra_coins,
|
||||
mnemonics[i] if i < len(mnemonics) else None,
|
||||
num_nodes=num_nodes,
|
||||
use_rpcauth=use_rpcauth,
|
||||
extra_settings=extra_settings,
|
||||
port_ofs=port_ofs,
|
||||
)
|
||||
|
||||
|
||||
class TestBase(unittest.TestCase):
|
||||
|
@ -395,34 +490,38 @@ class TestBase(unittest.TestCase):
|
|||
super(TestBase, cls).setUpClass()
|
||||
|
||||
cls.delay_event = threading.Event()
|
||||
signal.signal(signal.SIGINT, lambda signal, frame: cls.signal_handler(cls, signal, frame))
|
||||
signal.signal(
|
||||
signal.SIGINT, lambda signal, frame: cls.signal_handler(cls, signal, frame)
|
||||
)
|
||||
|
||||
def signal_handler(self, sig, frame):
|
||||
logging.info('signal {} detected.'.format(sig))
|
||||
logging.info("signal {} detected.".format(sig))
|
||||
self.delay_event.set()
|
||||
|
||||
def wait_seconds(self, seconds):
|
||||
self.delay_event.wait(seconds)
|
||||
if self.delay_event.is_set():
|
||||
raise ValueError('Test stopped.')
|
||||
raise ValueError("Test stopped.")
|
||||
|
||||
def wait_for_particl_height(self, http_port, num_blocks=3):
|
||||
# Wait for height, or sequencelock is thrown off by genesis blocktime
|
||||
logging.info('Waiting for Particl chain height %d', num_blocks)
|
||||
logging.info("Waiting for Particl chain height %d", num_blocks)
|
||||
for i in range(60):
|
||||
if self.delay_event.is_set():
|
||||
raise ValueError('Test stopped.')
|
||||
raise ValueError("Test stopped.")
|
||||
try:
|
||||
wallets = json.loads(urlopen(f'http://127.0.0.1:{http_port}/json/wallets').read())
|
||||
particl_blocks = wallets['PART']['blocks']
|
||||
print('particl_blocks', particl_blocks)
|
||||
wallets = json.loads(
|
||||
urlopen(f"http://127.0.0.1:{http_port}/json/wallets").read()
|
||||
)
|
||||
particl_blocks = wallets["PART"]["blocks"]
|
||||
print("particl_blocks", particl_blocks)
|
||||
if particl_blocks >= num_blocks:
|
||||
return
|
||||
except Exception as e:
|
||||
print('Error reading wallets', str(e))
|
||||
print("Error reading wallets", str(e))
|
||||
|
||||
self.delay_event.wait(1)
|
||||
raise ValueError(f'wait_for_particl_height failed http_port: {http_port}')
|
||||
raise ValueError(f"wait_for_particl_height failed http_port: {http_port}")
|
||||
|
||||
|
||||
class XmrTestBase(TestBase):
|
||||
|
@ -433,19 +532,21 @@ class XmrTestBase(TestBase):
|
|||
cls.update_thread = None
|
||||
cls.processes = []
|
||||
|
||||
prepare_nodes(3, 'monero')
|
||||
prepare_nodes(3, "monero")
|
||||
|
||||
def run_thread(self, client_id):
|
||||
client_path = os.path.join(TEST_PATH, 'client{}'.format(client_id))
|
||||
testargs = ['basicswap-run', '-datadir=' + client_path, '-regtest']
|
||||
with patch.object(sys, 'argv', testargs):
|
||||
client_path = os.path.join(TEST_PATH, "client{}".format(client_id))
|
||||
testargs = ["basicswap-run", "-datadir=" + client_path, "-regtest"]
|
||||
with patch.object(sys, "argv", testargs):
|
||||
runSystem.main()
|
||||
|
||||
def start_processes(self):
|
||||
self.delay_event.clear()
|
||||
|
||||
for i in range(3):
|
||||
self.processes.append(multiprocessing.Process(target=self.run_thread, args=(i,)))
|
||||
self.processes.append(
|
||||
multiprocessing.Process(target=self.run_thread, args=(i,))
|
||||
)
|
||||
self.processes[-1].start()
|
||||
|
||||
waitForServer(self.delay_event, 12701)
|
||||
|
@ -453,35 +554,55 @@ class XmrTestBase(TestBase):
|
|||
def waitForMainAddress():
|
||||
for i in range(20):
|
||||
if self.delay_event.is_set():
|
||||
raise ValueError('Test stopped.')
|
||||
raise ValueError("Test stopped.")
|
||||
try:
|
||||
wallets = json.loads(urlopen('http://127.0.0.1:12701/json/wallets').read())
|
||||
return wallets['XMR']['main_address']
|
||||
wallets = json.loads(
|
||||
urlopen("http://127.0.0.1:12701/json/wallets").read()
|
||||
)
|
||||
return wallets["XMR"]["main_address"]
|
||||
except Exception as e:
|
||||
print('Waiting for main address {}'.format(str(e)))
|
||||
print("Waiting for main address {}".format(str(e)))
|
||||
self.delay_event.wait(1)
|
||||
raise ValueError('waitForMainAddress timedout')
|
||||
raise ValueError("waitForMainAddress timedout")
|
||||
|
||||
xmr_addr1 = waitForMainAddress()
|
||||
|
||||
num_blocks = 100
|
||||
|
||||
xmr_auth = None
|
||||
if os.getenv('XMR_RPC_USER', '') != '':
|
||||
xmr_auth = (os.getenv('XMR_RPC_USER', ''), os.getenv('XMR_RPC_PWD', ''))
|
||||
if os.getenv("XMR_RPC_USER", "") != "":
|
||||
xmr_auth = (os.getenv("XMR_RPC_USER", ""), os.getenv("XMR_RPC_PWD", ""))
|
||||
|
||||
if callrpc_xmr(XMR_BASE_RPC_PORT + 1, 'get_block_count', auth=xmr_auth)['count'] < num_blocks:
|
||||
logging.info('Mining {} Monero blocks to {}.'.format(num_blocks, xmr_addr1))
|
||||
callrpc_xmr(XMR_BASE_RPC_PORT + 1, 'generateblocks', {'wallet_address': xmr_addr1, 'amount_of_blocks': num_blocks}, auth=xmr_auth)
|
||||
logging.info('XMR blocks: %d', callrpc_xmr(XMR_BASE_RPC_PORT + 1, 'get_block_count', auth=xmr_auth)['count'])
|
||||
if (
|
||||
callrpc_xmr(XMR_BASE_RPC_PORT + 1, "get_block_count", auth=xmr_auth)[
|
||||
"count"
|
||||
]
|
||||
< num_blocks
|
||||
):
|
||||
logging.info("Mining {} Monero blocks to {}.".format(num_blocks, xmr_addr1))
|
||||
callrpc_xmr(
|
||||
XMR_BASE_RPC_PORT + 1,
|
||||
"generateblocks",
|
||||
{"wallet_address": xmr_addr1, "amount_of_blocks": num_blocks},
|
||||
auth=xmr_auth,
|
||||
)
|
||||
logging.info(
|
||||
"XMR blocks: %d",
|
||||
callrpc_xmr(XMR_BASE_RPC_PORT + 1, "get_block_count", auth=xmr_auth)[
|
||||
"count"
|
||||
],
|
||||
)
|
||||
|
||||
self.update_thread = threading.Thread(target=updateThread, args=(xmr_addr1, self.delay_event, xmr_auth))
|
||||
self.update_thread = threading.Thread(
|
||||
target=updateThread, args=(xmr_addr1, self.delay_event, xmr_auth)
|
||||
)
|
||||
self.update_thread.start()
|
||||
|
||||
self.wait_for_particl_height(12701, num_blocks=3)
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
logging.info('Stopping test')
|
||||
logging.info("Stopping test")
|
||||
cls.delay_event.set()
|
||||
if cls.update_thread:
|
||||
cls.update_thread.join()
|
||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -2,6 +2,7 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright (c) 2020-2023 tecnovert
|
||||
# Copyright (c) 2024 The Basicswap developers
|
||||
# Distributed under the MIT software license, see the accompanying
|
||||
# file LICENSE or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
|
@ -47,77 +48,76 @@ class Test(XmrTestBase):
|
|||
|
||||
waitForServer(self.delay_event, 12700)
|
||||
waitForServer(self.delay_event, 12701)
|
||||
wallets1 = read_json_api(12701, 'wallets')
|
||||
assert (float(wallets1['XMR']['balance']) > 0.0)
|
||||
wallets1 = read_json_api(12701, "wallets")
|
||||
assert float(wallets1["XMR"]["balance"]) > 0.0
|
||||
|
||||
node1_password: str = 'notapassword123'
|
||||
logger.info('Encrypting node 1 wallets')
|
||||
rv = read_json_api(12701, 'setpassword', {'oldpassword': '', 'newpassword': node1_password})
|
||||
assert ('success' in rv)
|
||||
rv = read_json_api(12701, 'unlock', {'password': node1_password})
|
||||
assert ('success' in rv)
|
||||
node1_password: str = "notapassword123"
|
||||
logger.info("Encrypting node 1 wallets")
|
||||
rv = read_json_api(
|
||||
12701, "setpassword", {"oldpassword": "", "newpassword": node1_password}
|
||||
)
|
||||
assert "success" in rv
|
||||
rv = read_json_api(12701, "unlock", {"password": node1_password})
|
||||
assert "success" in rv
|
||||
|
||||
data = {
|
||||
'addr_from': '-1',
|
||||
'coin_from': 'part',
|
||||
'coin_to': 'xmr',
|
||||
'amt_from': '1',
|
||||
'amt_to': '1',
|
||||
'lockhrs': '24'}
|
||||
"addr_from": "-1",
|
||||
"coin_from": "part",
|
||||
"coin_to": "xmr",
|
||||
"amt_from": "1",
|
||||
"amt_to": "1",
|
||||
"lockhrs": "24",
|
||||
}
|
||||
|
||||
offer_id = post_json_api(12700, 'offers/new', data)['offer_id']
|
||||
offer_id = post_json_api(12700, "offers/new", data)["offer_id"]
|
||||
summary = read_json_api(12700)
|
||||
assert (summary['num_sent_offers'] == 1)
|
||||
assert summary["num_sent_offers"] == 1
|
||||
|
||||
logger.info('Waiting for offer')
|
||||
logger.info("Waiting for offer")
|
||||
waitForNumOffers(self.delay_event, 12701, 1)
|
||||
|
||||
offers = read_json_api(12701, 'offers')
|
||||
offers = read_json_api(12701, "offers")
|
||||
offer = offers[0]
|
||||
|
||||
data = {
|
||||
'offer_id': offer['offer_id'],
|
||||
'amount_from': offer['amount_from']}
|
||||
data = {"offer_id": offer["offer_id"], "amount_from": offer["amount_from"]}
|
||||
|
||||
data['valid_for_seconds'] = 24 * 60 * 60 + 1
|
||||
bid = post_json_api(12701, 'bids/new', data)
|
||||
assert (bid['error'] == 'Bid TTL too high')
|
||||
del data['valid_for_seconds']
|
||||
data['validmins'] = 24 * 60 + 1
|
||||
bid = post_json_api(12701, 'bids/new', data)
|
||||
assert (bid['error'] == 'Bid TTL too high')
|
||||
data["valid_for_seconds"] = 24 * 60 * 60 + 1
|
||||
bid = post_json_api(12701, "bids/new", data)
|
||||
assert bid["error"] == "Bid TTL too high"
|
||||
del data["valid_for_seconds"]
|
||||
data["validmins"] = 24 * 60 + 1
|
||||
bid = post_json_api(12701, "bids/new", data)
|
||||
assert bid["error"] == "Bid TTL too high"
|
||||
|
||||
del data['validmins']
|
||||
data['valid_for_seconds'] = 10
|
||||
bid = post_json_api(12701, 'bids/new', data)
|
||||
assert (bid['error'] == 'Bid TTL too low')
|
||||
del data['valid_for_seconds']
|
||||
data['validmins'] = 1
|
||||
bid = post_json_api(12701, 'bids/new', data)
|
||||
assert (bid['error'] == 'Bid TTL too low')
|
||||
del data["validmins"]
|
||||
data["valid_for_seconds"] = 10
|
||||
bid = post_json_api(12701, "bids/new", data)
|
||||
assert bid["error"] == "Bid TTL too low"
|
||||
del data["valid_for_seconds"]
|
||||
data["validmins"] = 1
|
||||
bid = post_json_api(12701, "bids/new", data)
|
||||
assert bid["error"] == "Bid TTL too low"
|
||||
|
||||
data['validmins'] = 60
|
||||
bid_id = post_json_api(12701, 'bids/new', data)
|
||||
data["validmins"] = 60
|
||||
post_json_api(12701, "bids/new", data)
|
||||
|
||||
waitForNumBids(self.delay_event, 12700, 1)
|
||||
|
||||
for i in range(10):
|
||||
bids = read_json_api(12700, 'bids')
|
||||
bids = read_json_api(12700, "bids")
|
||||
bid = bids[0]
|
||||
if bid['bid_state'] == 'Received':
|
||||
if bid["bid_state"] == "Received":
|
||||
break
|
||||
self.delay_event.wait(1)
|
||||
assert (bid['expire_at'] == bid['created_at'] + data['validmins'] * 60)
|
||||
assert bid["expire_at"] == bid["created_at"] + data["validmins"] * 60
|
||||
|
||||
data = {
|
||||
'accept': True
|
||||
}
|
||||
rv = post_json_api(12700, 'bids/{}'.format(bid['bid_id']), data)
|
||||
assert (rv['bid_state'] == 'Accepted')
|
||||
data = {"accept": True}
|
||||
rv = post_json_api(12700, "bids/{}".format(bid["bid_id"]), data)
|
||||
assert rv["bid_state"] == "Accepted"
|
||||
|
||||
waitForNumSwapping(self.delay_event, 12701, 1)
|
||||
|
||||
logger.info('Restarting node 1')
|
||||
logger.info("Restarting node 1")
|
||||
c1 = self.processes[1]
|
||||
c1.terminate()
|
||||
c1.join()
|
||||
|
@ -126,35 +126,35 @@ class Test(XmrTestBase):
|
|||
|
||||
waitForServer(self.delay_event, 12701)
|
||||
rv = read_json_api(12701)
|
||||
assert ('error' in rv)
|
||||
assert "error" in rv
|
||||
|
||||
logger.info('Unlocking node 1')
|
||||
rv = read_json_api(12701, 'unlock', {'password': node1_password})
|
||||
assert ('success' in rv)
|
||||
logger.info("Unlocking node 1")
|
||||
rv = read_json_api(12701, "unlock", {"password": node1_password})
|
||||
assert "success" in rv
|
||||
rv = read_json_api(12701)
|
||||
assert (rv['num_swapping'] == 1)
|
||||
assert rv["num_swapping"] == 1
|
||||
|
||||
rv = read_json_api(12700, 'revokeoffer/{}'.format(offer_id))
|
||||
assert (rv['revoked_offer'] == offer_id)
|
||||
rv = read_json_api(12700, "revokeoffer/{}".format(offer_id))
|
||||
assert rv["revoked_offer"] == offer_id
|
||||
|
||||
logger.info('Completing swap')
|
||||
logger.info("Completing swap")
|
||||
for i in range(240):
|
||||
if self.delay_event.is_set():
|
||||
raise ValueError('Test stopped.')
|
||||
raise ValueError("Test stopped.")
|
||||
self.delay_event.wait(4)
|
||||
|
||||
rv = read_json_api(12700, 'bids/{}'.format(bid['bid_id']))
|
||||
if rv['bid_state'] == 'Completed':
|
||||
rv = read_json_api(12700, "bids/{}".format(bid["bid_id"]))
|
||||
if rv["bid_state"] == "Completed":
|
||||
break
|
||||
assert (rv['bid_state'] == 'Completed')
|
||||
assert rv["bid_state"] == "Completed"
|
||||
|
||||
# Ensure offer was revoked
|
||||
summary = read_json_api(12700)
|
||||
assert (summary['num_network_offers'] == 0)
|
||||
assert summary["num_network_offers"] == 0
|
||||
|
||||
# Wait for bid to be removed from in-progress
|
||||
waitForNumBids(self.delay_event, 12700, 0)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright (c) 2022-2023 tecnovert
|
||||
# Copyright (c) 2024 The Basicswap developers
|
||||
# Distributed under the MIT software license, see the accompanying
|
||||
# file LICENSE or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
|
@ -49,10 +50,12 @@ from tests.basicswap.test_xmr import BaseTest, test_delay_event, callnoderpc
|
|||
|
||||
logger = logging.getLogger()
|
||||
|
||||
FIRO_BINDIR = os.path.expanduser(os.getenv('FIRO_BINDIR', os.path.join(cfg.DEFAULT_TEST_BINDIR, 'firo')))
|
||||
FIROD = os.getenv('FIROD', 'firod' + cfg.bin_suffix)
|
||||
FIRO_CLI = os.getenv('FIRO_CLI', 'firo-cli' + cfg.bin_suffix)
|
||||
FIRO_TX = os.getenv('FIRO_TX', 'firo-tx' + cfg.bin_suffix)
|
||||
FIRO_BINDIR = os.path.expanduser(
|
||||
os.getenv("FIRO_BINDIR", os.path.join(cfg.DEFAULT_TEST_BINDIR, "firo"))
|
||||
)
|
||||
FIROD = os.getenv("FIROD", "firod" + cfg.bin_suffix)
|
||||
FIRO_CLI = os.getenv("FIRO_CLI", "firo-cli" + cfg.bin_suffix)
|
||||
FIRO_TX = os.getenv("FIRO_TX", "firo-tx" + cfg.bin_suffix)
|
||||
|
||||
FIRO_BASE_PORT = 34832
|
||||
FIRO_BASE_RPC_PORT = 35832
|
||||
|
@ -60,50 +63,64 @@ FIRO_BASE_ZMQ_PORT = 36832
|
|||
|
||||
|
||||
def firoCli(cmd, node_id=0):
|
||||
return callrpc_cli(FIRO_BINDIR, os.path.join(cfg.TEST_DATADIRS, 'firo_' + str(node_id)), 'regtest', cmd, FIRO_CLI)
|
||||
return callrpc_cli(
|
||||
FIRO_BINDIR,
|
||||
os.path.join(cfg.TEST_DATADIRS, "firo_" + str(node_id)),
|
||||
"regtest",
|
||||
cmd,
|
||||
FIRO_CLI,
|
||||
)
|
||||
|
||||
|
||||
def prepareDataDir(datadir, node_id, conf_file, dir_prefix, base_p2p_port, base_rpc_port, num_nodes=3):
|
||||
def prepareDataDir(
|
||||
datadir, node_id, conf_file, dir_prefix, base_p2p_port, base_rpc_port, num_nodes=3
|
||||
):
|
||||
node_dir = os.path.join(datadir, dir_prefix + str(node_id))
|
||||
if not os.path.exists(node_dir):
|
||||
os.makedirs(node_dir)
|
||||
cfg_file_path = os.path.join(node_dir, conf_file)
|
||||
if os.path.exists(cfg_file_path):
|
||||
return
|
||||
with open(cfg_file_path, 'w+') as fp:
|
||||
fp.write('regtest=1\n')
|
||||
fp.write('port=' + str(base_p2p_port + node_id) + '\n')
|
||||
fp.write('rpcport=' + str(base_rpc_port + node_id) + '\n')
|
||||
with open(cfg_file_path, "w+") as fp:
|
||||
fp.write("regtest=1\n")
|
||||
fp.write("port=" + str(base_p2p_port + node_id) + "\n")
|
||||
fp.write("rpcport=" + str(base_rpc_port + node_id) + "\n")
|
||||
|
||||
salt = generate_salt(16)
|
||||
fp.write('rpcauth={}:{}${}\n'.format('test' + str(node_id), salt, password_to_hmac(salt, 'test_pass' + str(node_id))))
|
||||
fp.write(
|
||||
"rpcauth={}:{}${}\n".format(
|
||||
"test" + str(node_id),
|
||||
salt,
|
||||
password_to_hmac(salt, "test_pass" + str(node_id)),
|
||||
)
|
||||
)
|
||||
|
||||
fp.write('daemon=0\n')
|
||||
fp.write('dandelion=0\n')
|
||||
fp.write('printtoconsole=0\n')
|
||||
fp.write('server=1\n')
|
||||
fp.write('discover=0\n')
|
||||
fp.write('listenonion=0\n')
|
||||
fp.write('bind=127.0.0.1\n')
|
||||
fp.write('findpeers=0\n')
|
||||
fp.write('debug=1\n')
|
||||
fp.write('debugexclude=libevent\n')
|
||||
fp.write("daemon=0\n")
|
||||
fp.write("dandelion=0\n")
|
||||
fp.write("printtoconsole=0\n")
|
||||
fp.write("server=1\n")
|
||||
fp.write("discover=0\n")
|
||||
fp.write("listenonion=0\n")
|
||||
fp.write("bind=127.0.0.1\n")
|
||||
fp.write("findpeers=0\n")
|
||||
fp.write("debug=1\n")
|
||||
fp.write("debugexclude=libevent\n")
|
||||
|
||||
fp.write('fallbackfee=0.01\n')
|
||||
fp.write('acceptnonstdtxn=0\n')
|
||||
fp.write("fallbackfee=0.01\n")
|
||||
fp.write("acceptnonstdtxn=0\n")
|
||||
|
||||
'''
|
||||
"""
|
||||
# qa/rpc-tests/segwit.py
|
||||
fp.write('prematurewitness=1\n')
|
||||
fp.write('walletprematurewitness=1\n')
|
||||
fp.write('blockversion=4\n')
|
||||
fp.write('promiscuousmempoolflags=517\n')
|
||||
'''
|
||||
"""
|
||||
|
||||
for i in range(0, num_nodes):
|
||||
if node_id == i:
|
||||
continue
|
||||
fp.write('addnode=127.0.0.1:{}\n'.format(base_p2p_port + i))
|
||||
fp.write("addnode=127.0.0.1:{}\n".format(base_p2p_port + i))
|
||||
|
||||
return node_dir
|
||||
|
||||
|
@ -121,9 +138,9 @@ class Test(BaseTest):
|
|||
|
||||
# Particl node mnemonics are test_xmr.py, node 2 is set randomly
|
||||
firo_seeds = [
|
||||
'd90b7ed1be614e1c172653aee1f3b6230f43b7fa99cf07fa984a17966ad81de7',
|
||||
'6c81d6d74ba33a0db9e41518c2b6789fbe938e98018a4597dac661cfc5f2dfc1',
|
||||
'c5de2be44834e7e47ad7dc8e35c6b77c79f17c6bb40d5509a00fc3dff384a865',
|
||||
"d90b7ed1be614e1c172653aee1f3b6230f43b7fa99cf07fa984a17966ad81de7",
|
||||
"6c81d6d74ba33a0db9e41518c2b6789fbe938e98018a4597dac661cfc5f2dfc1",
|
||||
"c5de2be44834e7e47ad7dc8e35c6b77c79f17c6bb40d5509a00fc3dff384a865",
|
||||
]
|
||||
|
||||
@classmethod
|
||||
|
@ -131,13 +148,33 @@ class Test(BaseTest):
|
|||
extra_opts = []
|
||||
if not cls.restore_instance:
|
||||
seed_hex = cls.firo_seeds[i]
|
||||
extra_opts.append(f'-hdseed={seed_hex}')
|
||||
data_dir = prepareDataDir(cfg.TEST_DATADIRS, i, 'firo.conf', 'firo_', base_p2p_port=FIRO_BASE_PORT, base_rpc_port=FIRO_BASE_RPC_PORT)
|
||||
if os.path.exists(os.path.join(FIRO_BINDIR, 'firo-wallet')):
|
||||
callrpc_cli(FIRO_BINDIR, data_dir, 'regtest', '-wallet=wallet.dat create', 'firo-wallet')
|
||||
extra_opts.append(f"-hdseed={seed_hex}")
|
||||
data_dir = prepareDataDir(
|
||||
cfg.TEST_DATADIRS,
|
||||
i,
|
||||
"firo.conf",
|
||||
"firo_",
|
||||
base_p2p_port=FIRO_BASE_PORT,
|
||||
base_rpc_port=FIRO_BASE_RPC_PORT,
|
||||
)
|
||||
if os.path.exists(os.path.join(FIRO_BINDIR, "firo-wallet")):
|
||||
callrpc_cli(
|
||||
FIRO_BINDIR,
|
||||
data_dir,
|
||||
"regtest",
|
||||
"-wallet=wallet.dat create",
|
||||
"firo-wallet",
|
||||
)
|
||||
|
||||
cls.firo_daemons.append(startDaemon(os.path.join(cfg.TEST_DATADIRS, 'firo_' + str(i)), FIRO_BINDIR, FIROD, opts=extra_opts))
|
||||
logging.info('Started %s %d', FIROD, cls.firo_daemons[-1].handle.pid)
|
||||
cls.firo_daemons.append(
|
||||
startDaemon(
|
||||
os.path.join(cfg.TEST_DATADIRS, "firo_" + str(i)),
|
||||
FIRO_BINDIR,
|
||||
FIROD,
|
||||
opts=extra_opts,
|
||||
)
|
||||
)
|
||||
logging.info("Started %s %d", FIROD, cls.firo_daemons[-1].handle.pid)
|
||||
|
||||
waitForRPC(make_rpc_func(i, base_rpc_port=FIRO_BASE_RPC_PORT), test_delay_event)
|
||||
|
||||
|
@ -153,30 +190,59 @@ class Test(BaseTest):
|
|||
|
||||
if cls.restore_instance:
|
||||
void_block_rewards_pubkey = cls.getRandomPubkey()
|
||||
cls.firo_addr = cls.swap_clients[0].ci(Coins.FIRO).pubkey_to_address(void_block_rewards_pubkey)
|
||||
cls.firo_addr = (
|
||||
cls.swap_clients[0]
|
||||
.ci(Coins.FIRO)
|
||||
.pubkey_to_address(void_block_rewards_pubkey)
|
||||
)
|
||||
else:
|
||||
num_blocks = 400
|
||||
cls.firo_addr = callnoderpc(0, 'getnewaddress', ['mining_addr'], base_rpc_port=FIRO_BASE_RPC_PORT)
|
||||
cls.firo_addr = callnoderpc(
|
||||
0, "getnewaddress", ["mining_addr"], base_rpc_port=FIRO_BASE_RPC_PORT
|
||||
)
|
||||
# cls.firo_addr = callnoderpc(0, 'addwitnessaddress', [cls.firo_addr], base_rpc_port=FIRO_BASE_RPC_PORT)
|
||||
logging.info('Mining %d Firo blocks to %s', num_blocks, cls.firo_addr)
|
||||
callnoderpc(0, 'generatetoaddress', [num_blocks, cls.firo_addr], base_rpc_port=FIRO_BASE_RPC_PORT)
|
||||
logging.info("Mining %d Firo blocks to %s", num_blocks, cls.firo_addr)
|
||||
callnoderpc(
|
||||
0,
|
||||
"generatetoaddress",
|
||||
[num_blocks, cls.firo_addr],
|
||||
base_rpc_port=FIRO_BASE_RPC_PORT,
|
||||
)
|
||||
|
||||
firo_addr1 = callnoderpc(1, 'getnewaddress', ['initial addr'], base_rpc_port=FIRO_BASE_RPC_PORT)
|
||||
firo_addr1 = callnoderpc(
|
||||
1, "getnewaddress", ["initial addr"], base_rpc_port=FIRO_BASE_RPC_PORT
|
||||
)
|
||||
# firo_addr1 = callnoderpc(1, 'addwitnessaddress', [firo_addr1], base_rpc_port=FIRO_BASE_RPC_PORT)
|
||||
for i in range(5):
|
||||
callnoderpc(0, 'sendtoaddress', [firo_addr1, 1000], base_rpc_port=FIRO_BASE_RPC_PORT)
|
||||
callnoderpc(
|
||||
0,
|
||||
"sendtoaddress",
|
||||
[firo_addr1, 1000],
|
||||
base_rpc_port=FIRO_BASE_RPC_PORT,
|
||||
)
|
||||
|
||||
# Set future block rewards to nowhere (a random address), so wallet amounts stay constant
|
||||
void_block_rewards_pubkey = cls.getRandomPubkey()
|
||||
cls.firo_addr = cls.swap_clients[0].ci(Coins.FIRO).pubkey_to_address(void_block_rewards_pubkey)
|
||||
chain_height = callnoderpc(0, 'getblockcount', base_rpc_port=FIRO_BASE_RPC_PORT)
|
||||
cls.firo_addr = (
|
||||
cls.swap_clients[0]
|
||||
.ci(Coins.FIRO)
|
||||
.pubkey_to_address(void_block_rewards_pubkey)
|
||||
)
|
||||
chain_height = callnoderpc(
|
||||
0, "getblockcount", base_rpc_port=FIRO_BASE_RPC_PORT
|
||||
)
|
||||
num_blocks = 1352 - chain_height # Activate CTLV (bip65)
|
||||
logging.info('Mining %d Firo blocks to %s', num_blocks, cls.firo_addr)
|
||||
callnoderpc(0, 'generatetoaddress', [num_blocks, cls.firo_addr], base_rpc_port=FIRO_BASE_RPC_PORT)
|
||||
logging.info("Mining %d Firo blocks to %s", num_blocks, cls.firo_addr)
|
||||
callnoderpc(
|
||||
0,
|
||||
"generatetoaddress",
|
||||
[num_blocks, cls.firo_addr],
|
||||
base_rpc_port=FIRO_BASE_RPC_PORT,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
logging.info('Finalising FIRO Test')
|
||||
logging.info("Finalising FIRO Test")
|
||||
super(Test, cls).tearDownClass()
|
||||
|
||||
stopDaemons(cls.firo_daemons)
|
||||
|
@ -184,163 +250,223 @@ class Test(BaseTest):
|
|||
|
||||
@classmethod
|
||||
def addCoinSettings(cls, settings, datadir, node_id):
|
||||
settings['chainclients']['firo'] = {
|
||||
'connection_type': 'rpc',
|
||||
'manage_daemon': False,
|
||||
'rpcport': FIRO_BASE_RPC_PORT + node_id,
|
||||
'rpcuser': 'test' + str(node_id),
|
||||
'rpcpassword': 'test_pass' + str(node_id),
|
||||
'datadir': os.path.join(datadir, 'firo_' + str(node_id)),
|
||||
'bindir': FIRO_BINDIR,
|
||||
'use_csv': False,
|
||||
'use_segwit': False,
|
||||
settings["chainclients"]["firo"] = {
|
||||
"connection_type": "rpc",
|
||||
"manage_daemon": False,
|
||||
"rpcport": FIRO_BASE_RPC_PORT + node_id,
|
||||
"rpcuser": "test" + str(node_id),
|
||||
"rpcpassword": "test_pass" + str(node_id),
|
||||
"datadir": os.path.join(datadir, "firo_" + str(node_id)),
|
||||
"bindir": FIRO_BINDIR,
|
||||
"use_csv": False,
|
||||
"use_segwit": False,
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def coins_loop(cls):
|
||||
super(Test, cls).coins_loop()
|
||||
callnoderpc(0, 'generatetoaddress', [1, cls.firo_addr], base_rpc_port=FIRO_BASE_RPC_PORT)
|
||||
callnoderpc(
|
||||
0, "generatetoaddress", [1, cls.firo_addr], base_rpc_port=FIRO_BASE_RPC_PORT
|
||||
)
|
||||
|
||||
def getBalance(self, js_wallets):
|
||||
return float(js_wallets[self.test_coin_from.name]['balance']) + float(js_wallets[self.test_coin_from.name]['unconfirmed'])
|
||||
return float(js_wallets[self.test_coin_from.name]["balance"]) + float(
|
||||
js_wallets[self.test_coin_from.name]["unconfirmed"]
|
||||
)
|
||||
|
||||
def getXmrBalance(self, js_wallets):
|
||||
return float(js_wallets[Coins.XMR.name]['unconfirmed']) + float(js_wallets[Coins.XMR.name]['balance'])
|
||||
return float(js_wallets[Coins.XMR.name]["unconfirmed"]) + float(
|
||||
js_wallets[Coins.XMR.name]["balance"]
|
||||
)
|
||||
|
||||
def callnoderpc(self, method, params=[], wallet=None, node_id=0):
|
||||
return callnoderpc(node_id, method, params, wallet, base_rpc_port=FIRO_BASE_RPC_PORT)
|
||||
return callnoderpc(
|
||||
node_id, method, params, wallet, base_rpc_port=FIRO_BASE_RPC_PORT
|
||||
)
|
||||
|
||||
def mineBlock(self, num_blocks: int = 1):
|
||||
self.callnoderpc('generatetoaddress', [num_blocks, self.firo_addr])
|
||||
self.callnoderpc("generatetoaddress", [num_blocks, self.firo_addr])
|
||||
|
||||
def test_001_firo(self):
|
||||
logging.info('---------- Test {} segwit'.format(self.test_coin_from.name))
|
||||
logging.info("---------- Test {} segwit".format(self.test_coin_from.name))
|
||||
|
||||
'''
|
||||
"""
|
||||
Segwit is not currently enabled:
|
||||
https://github.com/firoorg/firo/blob/master/src/validation.cpp#L4425
|
||||
|
||||
Txns spending segwit utxos don't get mined.
|
||||
'''
|
||||
"""
|
||||
return
|
||||
|
||||
swap_clients = self.swap_clients
|
||||
|
||||
addr_plain = firoCli('getnewaddress \"segwit test\"')
|
||||
addr_witness = firoCli(f'addwitnessaddress {addr_plain}')
|
||||
addr_witness_info = firoCli(f'validateaddress {addr_witness}')
|
||||
txid = firoCli(f'sendtoaddress {addr_witness} 1.0')
|
||||
addr_plain = firoCli('getnewaddress "segwit test"')
|
||||
addr_witness = firoCli(f"addwitnessaddress {addr_plain}")
|
||||
addr_witness_info = firoCli(f"validateaddress {addr_witness}")
|
||||
txid = firoCli(f"sendtoaddress {addr_witness} 1.0")
|
||||
assert len(txid) == 64
|
||||
|
||||
self.callnoderpc('generatetoaddress', [1, self.firo_addr])
|
||||
'''
|
||||
self.callnoderpc("generatetoaddress", [1, self.firo_addr])
|
||||
"""
|
||||
TODO: Add back when segwit is active
|
||||
ro = self.callnoderpc('scantxoutset', ['start', ['addr({})'.format(addr_witness)]])
|
||||
assert (len(ro['unspents']) == 1)
|
||||
assert (ro['unspents'][0]['txid'] == txid)
|
||||
'''
|
||||
"""
|
||||
|
||||
tx_wallet = firoCli(f'gettransaction {txid}')
|
||||
tx_hex = tx_wallet['hex']
|
||||
tx = firoCli(f'decoderawtransaction {tx_hex}')
|
||||
tx_wallet = firoCli(f"gettransaction {txid}")
|
||||
tx_hex = tx_wallet["hex"]
|
||||
tx = firoCli(f"decoderawtransaction {tx_hex}")
|
||||
|
||||
prevout_n = -1
|
||||
for txo in tx['vout']:
|
||||
if addr_witness in txo['scriptPubKey']['addresses']:
|
||||
prevout_n = txo['n']
|
||||
for txo in tx["vout"]:
|
||||
if addr_witness in txo["scriptPubKey"]["addresses"]:
|
||||
prevout_n = txo["n"]
|
||||
break
|
||||
assert prevout_n > -1
|
||||
|
||||
tx_funded = firoCli(f'createrawtransaction [{{\\"txid\\":\\"{txid}\\",\\"vout\\":{prevout_n}}}] {{\\"{addr_plain}\\":0.99}}')
|
||||
tx_signed = firoCli(f'signrawtransaction {tx_funded}')['hex']
|
||||
tx_funded = firoCli(
|
||||
f'createrawtransaction [{{\\"txid\\":\\"{txid}\\",\\"vout\\":{prevout_n}}}] {{\\"{addr_plain}\\":0.99}}'
|
||||
)
|
||||
tx_signed = firoCli(f"signrawtransaction {tx_funded}")["hex"]
|
||||
|
||||
# Add scriptsig for txids to match
|
||||
decoded_tx = CTransaction()
|
||||
decoded_tx = FromHex(decoded_tx, tx_funded)
|
||||
decoded_tx.vin[0].scriptSig = bytes.fromhex('16' + addr_witness_info['hex'])
|
||||
decoded_tx.vin[0].scriptSig = bytes.fromhex("16" + addr_witness_info["hex"])
|
||||
decoded_tx.rehash()
|
||||
txid_with_scriptsig = decoded_tx.hash
|
||||
|
||||
tx_funded_decoded = firoCli(f'decoderawtransaction {tx_funded}')
|
||||
tx_signed_decoded = firoCli(f'decoderawtransaction {tx_signed}')
|
||||
assert tx_funded_decoded['txid'] != tx_signed_decoded['txid']
|
||||
assert txid_with_scriptsig == tx_signed_decoded['txid']
|
||||
tx_funded_decoded = firoCli(f"decoderawtransaction {tx_funded}")
|
||||
tx_signed_decoded = firoCli(f"decoderawtransaction {tx_signed}")
|
||||
assert tx_funded_decoded["txid"] != tx_signed_decoded["txid"]
|
||||
assert txid_with_scriptsig == tx_signed_decoded["txid"]
|
||||
|
||||
def test_007_hdwallet(self):
|
||||
logging.info('---------- Test {} hdwallet'.format(self.test_coin_from.name))
|
||||
logging.info("---------- Test {} hdwallet".format(self.test_coin_from.name))
|
||||
|
||||
swap_client = self.swap_clients[0]
|
||||
# Run initialiseWallet to set 'main_wallet_seedid_'
|
||||
swap_client.initialiseWallet(self.test_coin_from)
|
||||
ci = swap_client.ci(self.test_coin_from)
|
||||
assert ('490ba1e2c3894d5534c467141ee3cdf77292c362' == ci.getWalletSeedID())
|
||||
assert "490ba1e2c3894d5534c467141ee3cdf77292c362" == ci.getWalletSeedID()
|
||||
assert swap_client.checkWalletSeed(self.test_coin_from) is True
|
||||
|
||||
def test_008_gettxout(self):
|
||||
logging.info('---------- Test {} gettxout'.format(self.test_coin_from.name))
|
||||
logging.info("---------- Test {} gettxout".format(self.test_coin_from.name))
|
||||
|
||||
swap_client = self.swap_clients[0]
|
||||
|
||||
# First address sometimes has a balance already
|
||||
addr_plain = self.callnoderpc('getnewaddress', ['gettxout test',])
|
||||
_ = self.callnoderpc(
|
||||
"getnewaddress",
|
||||
[
|
||||
"gettxout test",
|
||||
],
|
||||
)
|
||||
|
||||
addr_plain1 = self.callnoderpc('getnewaddress', ['gettxout test 1',])
|
||||
addr_plain = self.callnoderpc(
|
||||
"getnewaddress",
|
||||
[
|
||||
"gettxout test 1",
|
||||
],
|
||||
)
|
||||
|
||||
txid = self.callnoderpc('sendtoaddress', [addr_plain1, 1.0])
|
||||
txid = self.callnoderpc("sendtoaddress", [addr_plain, 1.0])
|
||||
assert len(txid) == 64
|
||||
|
||||
self.mineBlock()
|
||||
|
||||
unspents = self.callnoderpc('listunspent', [0, 999999999, [addr_plain1,]])
|
||||
assert (len(unspents) == 1)
|
||||
unspents = self.callnoderpc(
|
||||
"listunspent",
|
||||
[
|
||||
0,
|
||||
999999999,
|
||||
[
|
||||
addr_plain,
|
||||
],
|
||||
],
|
||||
)
|
||||
assert len(unspents) == 1
|
||||
|
||||
utxo = unspents[0]
|
||||
txout = self.callnoderpc('gettxout', [utxo['txid'], utxo['vout']])
|
||||
assert (addr_plain1 in txout['scriptPubKey']['addresses'])
|
||||
txout = self.callnoderpc("gettxout", [utxo["txid"], utxo["vout"]])
|
||||
assert addr_plain in txout["scriptPubKey"]["addresses"]
|
||||
# Spend
|
||||
addr_plain2 = self.callnoderpc('getnewaddress', ['gettxout test 2',])
|
||||
tx_funded = self.callnoderpc('createrawtransaction', [[{'txid': utxo['txid'], 'vout': utxo['vout']}], {addr_plain2: 0.99}])
|
||||
tx_signed = self.callnoderpc('signrawtransaction', [tx_funded,])['hex']
|
||||
self.callnoderpc('sendrawtransaction', [tx_signed,])
|
||||
addr_plain2 = self.callnoderpc(
|
||||
"getnewaddress",
|
||||
[
|
||||
"gettxout test 2",
|
||||
],
|
||||
)
|
||||
tx_funded = self.callnoderpc(
|
||||
"createrawtransaction",
|
||||
[[{"txid": utxo["txid"], "vout": utxo["vout"]}], {addr_plain2: 0.99}],
|
||||
)
|
||||
tx_signed = self.callnoderpc(
|
||||
"signrawtransaction",
|
||||
[
|
||||
tx_funded,
|
||||
],
|
||||
)["hex"]
|
||||
self.callnoderpc(
|
||||
"sendrawtransaction",
|
||||
[
|
||||
tx_signed,
|
||||
],
|
||||
)
|
||||
|
||||
# utxo should be unavailable when spent in the mempool
|
||||
txout = self.callnoderpc('gettxout', [utxo['txid'], utxo['vout']])
|
||||
assert (txout is None)
|
||||
txout = self.callnoderpc("gettxout", [utxo["txid"], utxo["vout"]])
|
||||
assert txout is None
|
||||
|
||||
self.mineBlock()
|
||||
|
||||
ci = swap_client.ci(Coins.FIRO)
|
||||
require_amount: int = ci.make_int(1)
|
||||
funds_proof = ci.getProofOfFunds(require_amount, 'test'.encode('utf-8'))
|
||||
funds_proof = ci.getProofOfFunds(require_amount, "test".encode("utf-8"))
|
||||
|
||||
amount_proved = ci.verifyProofOfFunds(funds_proof[0], funds_proof[1], funds_proof[2], 'test'.encode('utf-8'))
|
||||
assert (amount_proved >= require_amount)
|
||||
amount_proved = ci.verifyProofOfFunds(
|
||||
funds_proof[0], funds_proof[1], funds_proof[2], "test".encode("utf-8")
|
||||
)
|
||||
assert amount_proved >= require_amount
|
||||
|
||||
def test_08_wallet(self):
|
||||
logging.info('---------- Test {} wallet'.format(self.test_coin_from.name))
|
||||
logging.info("---------- Test {} wallet".format(self.test_coin_from.name))
|
||||
|
||||
logging.info('Test withdrawal')
|
||||
addr = self.callnoderpc('getnewaddress', ['Withdrawal test', ])
|
||||
wallets = read_json_api(TEST_HTTP_PORT + 0, 'wallets')
|
||||
assert (float(wallets[self.test_coin_from.name]['balance']) > 100)
|
||||
logging.info("Test withdrawal")
|
||||
addr = self.callnoderpc(
|
||||
"getnewaddress",
|
||||
[
|
||||
"Withdrawal test",
|
||||
],
|
||||
)
|
||||
wallets = read_json_api(TEST_HTTP_PORT + 0, "wallets")
|
||||
assert float(wallets[self.test_coin_from.name]["balance"]) > 100
|
||||
|
||||
post_json = {
|
||||
'value': 100,
|
||||
'address': addr,
|
||||
'subfee': False,
|
||||
"value": 100,
|
||||
"address": addr,
|
||||
"subfee": False,
|
||||
}
|
||||
json_rv = read_json_api(TEST_HTTP_PORT + 0, 'wallets/{}/withdraw'.format(self.test_coin_from.name.lower()), post_json)
|
||||
assert (len(json_rv['txid']) == 64)
|
||||
json_rv = read_json_api(
|
||||
TEST_HTTP_PORT + 0,
|
||||
"wallets/{}/withdraw".format(self.test_coin_from.name.lower()),
|
||||
post_json,
|
||||
)
|
||||
assert len(json_rv["txid"]) == 64
|
||||
|
||||
logging.info('Test createutxo')
|
||||
logging.info("Test createutxo")
|
||||
post_json = {
|
||||
'value': 10,
|
||||
"value": 10,
|
||||
}
|
||||
json_rv = read_json_api(TEST_HTTP_PORT + 0, 'wallets/{}/createutxo'.format(self.test_coin_from.name.lower()), post_json)
|
||||
assert (len(json_rv['txid']) == 64)
|
||||
json_rv = read_json_api(
|
||||
TEST_HTTP_PORT + 0,
|
||||
"wallets/{}/createutxo".format(self.test_coin_from.name.lower()),
|
||||
post_json,
|
||||
)
|
||||
assert len(json_rv["txid"]) == 64
|
||||
|
||||
def test_11_xmrswap_to(self):
|
||||
logging.info('---------- Test xmr swap protocol to')
|
||||
logging.info("---------- Test xmr swap protocol to")
|
||||
|
||||
swap_clients = self.swap_clients
|
||||
coin_from = Coins.BTC
|
||||
|
@ -351,7 +477,9 @@ class Test(BaseTest):
|
|||
|
||||
swap_value = ci_from.make_int(random.uniform(0.2, 20.0), r=1)
|
||||
rate_swap = ci_to.make_int(random.uniform(0.2, 20.0), r=1)
|
||||
offer_id = swap_clients[0].postOffer(coin_from, coin_to, swap_value, rate_swap, swap_value, swap_type)
|
||||
offer_id = swap_clients[0].postOffer(
|
||||
coin_from, coin_to, swap_value, rate_swap, swap_value, swap_type
|
||||
)
|
||||
|
||||
wait_for_offer(test_delay_event, swap_clients[1], offer_id)
|
||||
offer = swap_clients[1].getOffer(offer_id)
|
||||
|
@ -360,13 +488,30 @@ class Test(BaseTest):
|
|||
wait_for_bid(test_delay_event, swap_clients[0], bid_id, BidStates.BID_RECEIVED)
|
||||
swap_clients[0].acceptBid(bid_id)
|
||||
|
||||
wait_for_bid(test_delay_event, swap_clients[0], bid_id, BidStates.SWAP_COMPLETED, wait_for=120)
|
||||
wait_for_bid(test_delay_event, swap_clients[1], bid_id, BidStates.SWAP_COMPLETED, sent=True, wait_for=120)
|
||||
wait_for_bid(
|
||||
test_delay_event,
|
||||
swap_clients[0],
|
||||
bid_id,
|
||||
BidStates.SWAP_COMPLETED,
|
||||
wait_for=120,
|
||||
)
|
||||
wait_for_bid(
|
||||
test_delay_event,
|
||||
swap_clients[1],
|
||||
bid_id,
|
||||
BidStates.SWAP_COMPLETED,
|
||||
sent=True,
|
||||
wait_for=120,
|
||||
)
|
||||
|
||||
def test_12_xmrswap_to_recover_b_lock_tx(self):
|
||||
coin_from = Coins.BTC
|
||||
coin_to = Coins.FIRO
|
||||
logging.info('---------- Test {} to {} follower recovers coin b lock tx'.format(coin_from.name, coin_to.name))
|
||||
logging.info(
|
||||
"---------- Test {} to {} follower recovers coin b lock tx".format(
|
||||
coin_from.name, coin_to.name
|
||||
)
|
||||
)
|
||||
|
||||
swap_clients = self.swap_clients
|
||||
ci_from = swap_clients[0].ci(coin_from)
|
||||
|
@ -375,8 +520,15 @@ class Test(BaseTest):
|
|||
amt_swap = ci_from.make_int(random.uniform(0.1, 2.0), r=1)
|
||||
rate_swap = ci_to.make_int(random.uniform(0.2, 20.0), r=1)
|
||||
offer_id = swap_clients[0].postOffer(
|
||||
coin_from, coin_to, amt_swap, rate_swap, amt_swap, SwapTypes.XMR_SWAP,
|
||||
lock_type=TxLockTypes.SEQUENCE_LOCK_BLOCKS, lock_value=32)
|
||||
coin_from,
|
||||
coin_to,
|
||||
amt_swap,
|
||||
rate_swap,
|
||||
amt_swap,
|
||||
SwapTypes.XMR_SWAP,
|
||||
lock_type=TxLockTypes.SEQUENCE_LOCK_BLOCKS,
|
||||
lock_value=32,
|
||||
)
|
||||
wait_for_offer(test_delay_event, swap_clients[1], offer_id)
|
||||
offer = swap_clients[1].getOffer(offer_id)
|
||||
|
||||
|
@ -387,11 +539,23 @@ class Test(BaseTest):
|
|||
swap_clients[1].setBidDebugInd(bid_id, DebugTypes.CREATE_INVALID_COIN_B_LOCK)
|
||||
swap_clients[0].acceptXmrBid(bid_id)
|
||||
|
||||
wait_for_bid(test_delay_event, swap_clients[0], bid_id, BidStates.XMR_SWAP_FAILED_REFUNDED, wait_for=180)
|
||||
wait_for_bid(test_delay_event, swap_clients[1], bid_id, BidStates.XMR_SWAP_FAILED_REFUNDED, sent=True)
|
||||
wait_for_bid(
|
||||
test_delay_event,
|
||||
swap_clients[0],
|
||||
bid_id,
|
||||
BidStates.XMR_SWAP_FAILED_REFUNDED,
|
||||
wait_for=180,
|
||||
)
|
||||
wait_for_bid(
|
||||
test_delay_event,
|
||||
swap_clients[1],
|
||||
bid_id,
|
||||
BidStates.XMR_SWAP_FAILED_REFUNDED,
|
||||
sent=True,
|
||||
)
|
||||
|
||||
def test_13_adsswap_reverse(self):
|
||||
logging.info('---------- Test ads swap protocol reverse')
|
||||
logging.info("---------- Test ads swap protocol reverse")
|
||||
|
||||
swap_clients = self.swap_clients
|
||||
coin_from = Coins.FIRO
|
||||
|
@ -402,7 +566,9 @@ class Test(BaseTest):
|
|||
|
||||
swap_value = ci_from.make_int(random.uniform(0.2, 20.0), r=1)
|
||||
rate_swap = ci_to.make_int(random.uniform(0.2, 10.0), r=1)
|
||||
offer_id = swap_clients[0].postOffer(coin_from, coin_to, swap_value, rate_swap, swap_value, swap_type)
|
||||
offer_id = swap_clients[0].postOffer(
|
||||
coin_from, coin_to, swap_value, rate_swap, swap_value, swap_type
|
||||
)
|
||||
|
||||
wait_for_offer(test_delay_event, swap_clients[1], offer_id)
|
||||
offer = swap_clients[1].getOffer(offer_id)
|
||||
|
@ -411,28 +577,44 @@ class Test(BaseTest):
|
|||
wait_for_bid(test_delay_event, swap_clients[0], bid_id, BidStates.BID_RECEIVED)
|
||||
swap_clients[0].acceptBid(bid_id)
|
||||
|
||||
wait_for_bid(test_delay_event, swap_clients[0], bid_id, BidStates.SWAP_COMPLETED, wait_for=120)
|
||||
wait_for_bid(test_delay_event, swap_clients[1], bid_id, BidStates.SWAP_COMPLETED, sent=True, wait_for=120)
|
||||
wait_for_bid(
|
||||
test_delay_event,
|
||||
swap_clients[0],
|
||||
bid_id,
|
||||
BidStates.SWAP_COMPLETED,
|
||||
wait_for=120,
|
||||
)
|
||||
wait_for_bid(
|
||||
test_delay_event,
|
||||
swap_clients[1],
|
||||
bid_id,
|
||||
BidStates.SWAP_COMPLETED,
|
||||
sent=True,
|
||||
wait_for=120,
|
||||
)
|
||||
|
||||
def test_101_full_swap(self):
|
||||
logging.info('---------- Test {} to XMR'.format(self.test_coin_from.name))
|
||||
logging.info("---------- Test {} to XMR".format(self.test_coin_from.name))
|
||||
if not self.test_xmr:
|
||||
logging.warning('Skipping test')
|
||||
logging.warning("Skipping test")
|
||||
return
|
||||
swap_clients = self.swap_clients
|
||||
|
||||
js_0 = read_json_api(1800, 'wallets')
|
||||
node0_from_before = self.getBalance(js_0)
|
||||
|
||||
js_1 = read_json_api(1801, 'wallets')
|
||||
js_1 = read_json_api(1801, "wallets")
|
||||
node1_from_before = self.getBalance(js_1)
|
||||
|
||||
js_0_xmr = read_json_api(1800, 'wallets/xmr')
|
||||
js_1_xmr = read_json_api(1801, 'wallets/xmr')
|
||||
js_1_xmr = read_json_api(1801, "wallets/xmr")
|
||||
|
||||
amt_swap = make_int(random.uniform(0.1, 2.0), scale=8, r=1)
|
||||
rate_swap = make_int(random.uniform(0.2, 20.0), scale=12, r=1)
|
||||
offer_id = swap_clients[0].postOffer(self.test_coin_from, Coins.XMR, amt_swap, rate_swap, amt_swap, SwapTypes.XMR_SWAP)
|
||||
offer_id = swap_clients[0].postOffer(
|
||||
self.test_coin_from,
|
||||
Coins.XMR,
|
||||
amt_swap,
|
||||
rate_swap,
|
||||
amt_swap,
|
||||
SwapTypes.XMR_SWAP,
|
||||
)
|
||||
wait_for_offer(test_delay_event, swap_clients[1], offer_id)
|
||||
offer = swap_clients[0].getOffer(offer_id)
|
||||
|
||||
|
@ -440,29 +622,42 @@ class Test(BaseTest):
|
|||
wait_for_bid(test_delay_event, swap_clients[0], bid_id, BidStates.BID_RECEIVED)
|
||||
swap_clients[0].acceptXmrBid(bid_id)
|
||||
|
||||
wait_for_bid(test_delay_event, swap_clients[0], bid_id, BidStates.SWAP_COMPLETED, wait_for=180)
|
||||
wait_for_bid(test_delay_event, swap_clients[1], bid_id, BidStates.SWAP_COMPLETED, sent=True)
|
||||
wait_for_bid(
|
||||
test_delay_event,
|
||||
swap_clients[0],
|
||||
bid_id,
|
||||
BidStates.SWAP_COMPLETED,
|
||||
wait_for=180,
|
||||
)
|
||||
wait_for_bid(
|
||||
test_delay_event,
|
||||
swap_clients[1],
|
||||
bid_id,
|
||||
BidStates.SWAP_COMPLETED,
|
||||
sent=True,
|
||||
)
|
||||
|
||||
amount_from = float(format_amount(amt_swap, 8))
|
||||
js_1 = read_json_api(1801, 'wallets')
|
||||
js_1 = read_json_api(1801, "wallets")
|
||||
node1_from_after = self.getBalance(js_1)
|
||||
assert (node1_from_after > node1_from_before + (amount_from - 0.05))
|
||||
assert node1_from_after > node1_from_before + (amount_from - 0.05)
|
||||
|
||||
js_0 = read_json_api(1800, 'wallets')
|
||||
node0_from_after = self.getBalance(js_0)
|
||||
# TODO: Discard block rewards
|
||||
# js_0 = read_json_api(1800, 'wallets')
|
||||
# node0_from_after = self.getBalance(js_0)
|
||||
# assert (node0_from_after < node0_from_before - amount_from)
|
||||
|
||||
js_0_xmr_after = read_json_api(1800, 'wallets/xmr')
|
||||
js_1_xmr_after = read_json_api(1801, 'wallets/xmr')
|
||||
js_1_xmr_after = read_json_api(1801, "wallets/xmr")
|
||||
|
||||
scale_from = 8
|
||||
amount_to = int((amt_swap * rate_swap) // (10 ** scale_from))
|
||||
amount_to = int((amt_swap * rate_swap) // (10**scale_from))
|
||||
amount_to_float = float(format_amount(amount_to, 12))
|
||||
node1_xmr_after = float(js_1_xmr_after['unconfirmed']) + float(js_1_xmr_after['balance'])
|
||||
node1_xmr_before = float(js_1_xmr['unconfirmed']) + float(js_1_xmr['balance'])
|
||||
assert (node1_xmr_after > node1_xmr_before + (amount_to_float - 0.02))
|
||||
node1_xmr_after = float(js_1_xmr_after["unconfirmed"]) + float(
|
||||
js_1_xmr_after["balance"]
|
||||
)
|
||||
node1_xmr_before = float(js_1_xmr["unconfirmed"]) + float(js_1_xmr["balance"])
|
||||
assert node1_xmr_after > node1_xmr_before + (amount_to_float - 0.02)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
|
|
@ -1,68 +0,0 @@
|
|||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# https://chromedriver.chromium.org/downloads
|
||||
# 7z x chromedriver_linux64.zip
|
||||
# sudo mv chromedriver /opt/chromedriver88
|
||||
|
||||
# Run test_xmr_persistent.py
|
||||
# python tests/basicswap/extended/test_http_ui.py
|
||||
|
||||
import time
|
||||
import logging
|
||||
from urllib.parse import urljoin
|
||||
|
||||
from selenium import webdriver
|
||||
from selenium.webdriver.support.ui import Select, WebDriverWait
|
||||
|
||||
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
|
||||
|
||||
|
||||
def run_test():
|
||||
base_url = 'http://localhost:12701'
|
||||
driver = webdriver.Chrome('/opt/chromedriver88')
|
||||
|
||||
driver.get(base_url)
|
||||
link = driver.find_element_by_xpath('//a[@href="/offers"]')
|
||||
num_offers_start = int(link.text.split(':')[1].strip())
|
||||
logging.info('Offers: %d', num_offers_start)
|
||||
|
||||
logging.info('Creating offer')
|
||||
driver.get(urljoin(base_url, 'newoffer'))
|
||||
select_coin_from = Select(driver.find_element_by_name('coin_from'))
|
||||
select_coin_from.select_by_visible_text('Particl')
|
||||
|
||||
select_coin_to = Select(driver.find_element_by_name('coin_to'))
|
||||
select_coin_to.select_by_visible_text('Monero')
|
||||
|
||||
from_value = driver.find_element_by_name('amt_from')
|
||||
from_value.send_keys('1')
|
||||
to_value = driver.find_element_by_name('amt_to')
|
||||
to_value.send_keys('2')
|
||||
|
||||
submit_button = driver.find_element_by_name('continue')
|
||||
submit_button.click()
|
||||
time.sleep(0.1)
|
||||
|
||||
submit_button = driver.find_element_by_name('check_offer')
|
||||
submit_button.click()
|
||||
time.sleep(0.1)
|
||||
|
||||
submit_button = driver.find_element_by_name('submit_offer')
|
||||
submit_button.click()
|
||||
time.sleep(0.1)
|
||||
|
||||
link = WebDriverWait(driver, 5).until(lambda d: d.find_element_by_xpath("//a[contains(@href, '/offer')]"))
|
||||
offer_id = link.text.rsplit(' ', 1)[1]
|
||||
logging.info('Offer ID: %s', offer_id)
|
||||
|
||||
driver.get(base_url)
|
||||
link = driver.find_element_by_xpath('//a[@href="/offers"]')
|
||||
num_offers_end = int(link.text.split(':')[1].strip())
|
||||
assert num_offers_end == num_offers_start + 1
|
||||
|
||||
driver.quit()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
run_test()
|
File diff suppressed because it is too large
Load diff
|
@ -2,6 +2,7 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright (c) 2020-2021 tecnovert
|
||||
# Copyright (c) 2024 The Basicswap developers
|
||||
# Distributed under the MIT software license, see the accompanying
|
||||
# file LICENSE or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
|
@ -72,79 +73,90 @@ stop_test = False
|
|||
|
||||
|
||||
def prepare_swapclient_dir(datadir, node_id, network_key, network_pubkey):
|
||||
basicswap_dir = os.path.join(datadir, 'basicswap_' + str(node_id))
|
||||
basicswap_dir = os.path.join(datadir, "basicswap_" + str(node_id))
|
||||
if not os.path.exists(basicswap_dir):
|
||||
os.makedirs(basicswap_dir)
|
||||
|
||||
settings_path = os.path.join(basicswap_dir, cfg.CONFIG_FILENAME)
|
||||
settings = {
|
||||
'debug': True,
|
||||
'p2p_host': '127.0.0.1',
|
||||
'p2p_port': BASE_P2P_PORT + node_id,
|
||||
'zmqhost': 'tcp://127.0.0.1',
|
||||
'zmqport': BASE_ZMQ_PORT + node_id,
|
||||
'htmlhost': '127.0.0.1',
|
||||
'htmlport': TEST_HTTP_PORT + node_id,
|
||||
'network_key': network_key,
|
||||
'network_pubkey': network_pubkey,
|
||||
'chainclients': {
|
||||
'particl': {
|
||||
'connection_type': 'rpc',
|
||||
'manage_daemon': False,
|
||||
'rpcport': BASE_RPC_PORT + node_id,
|
||||
'rpcuser': 'test' + str(node_id),
|
||||
'rpcpassword': 'test_pass' + str(node_id),
|
||||
'datadir': os.path.join(datadir, 'part_' + str(node_id)),
|
||||
'bindir': cfg.PARTICL_BINDIR,
|
||||
'blocks_confirmed': 2, # Faster testing
|
||||
"debug": True,
|
||||
"p2p_host": "127.0.0.1",
|
||||
"p2p_port": BASE_P2P_PORT + node_id,
|
||||
"zmqhost": "tcp://127.0.0.1",
|
||||
"zmqport": BASE_ZMQ_PORT + node_id,
|
||||
"htmlhost": "127.0.0.1",
|
||||
"htmlport": TEST_HTTP_PORT + node_id,
|
||||
"network_key": network_key,
|
||||
"network_pubkey": network_pubkey,
|
||||
"chainclients": {
|
||||
"particl": {
|
||||
"connection_type": "rpc",
|
||||
"manage_daemon": False,
|
||||
"rpcport": BASE_RPC_PORT + node_id,
|
||||
"rpcuser": "test" + str(node_id),
|
||||
"rpcpassword": "test_pass" + str(node_id),
|
||||
"datadir": os.path.join(datadir, "part_" + str(node_id)),
|
||||
"bindir": cfg.PARTICL_BINDIR,
|
||||
"blocks_confirmed": 2, # Faster testing
|
||||
},
|
||||
"bitcoin": {
|
||||
"connection_type": "rpc",
|
||||
"manage_daemon": False,
|
||||
"rpcport": BTC_BASE_RPC_PORT + node_id,
|
||||
"rpcuser": "test" + str(node_id),
|
||||
"rpcpassword": "test_pass" + str(node_id),
|
||||
"datadir": os.path.join(datadir, "btc_" + str(node_id)),
|
||||
"bindir": cfg.BITCOIN_BINDIR,
|
||||
"use_segwit": True,
|
||||
},
|
||||
'bitcoin': {
|
||||
'connection_type': 'rpc',
|
||||
'manage_daemon': False,
|
||||
'rpcport': BTC_BASE_RPC_PORT + node_id,
|
||||
'rpcuser': 'test' + str(node_id),
|
||||
'rpcpassword': 'test_pass' + str(node_id),
|
||||
'datadir': os.path.join(datadir, 'btc_' + str(node_id)),
|
||||
'bindir': cfg.BITCOIN_BINDIR,
|
||||
'use_segwit': True,
|
||||
}
|
||||
|
||||
},
|
||||
'check_progress_seconds': 2,
|
||||
'check_watched_seconds': 4,
|
||||
'check_expired_seconds': 60,
|
||||
'check_events_seconds': 1,
|
||||
'check_xmr_swaps_seconds': 1,
|
||||
'min_delay_event': 1,
|
||||
'max_delay_event': 5,
|
||||
'min_delay_event_short': 1,
|
||||
'max_delay_event_short': 5,
|
||||
'min_delay_retry': 2,
|
||||
'max_delay_retry': 10,
|
||||
'restrict_unknown_seed_wallets': False
|
||||
"check_progress_seconds": 2,
|
||||
"check_watched_seconds": 4,
|
||||
"check_expired_seconds": 60,
|
||||
"check_events_seconds": 1,
|
||||
"check_xmr_swaps_seconds": 1,
|
||||
"min_delay_event": 1,
|
||||
"max_delay_event": 5,
|
||||
"min_delay_event_short": 1,
|
||||
"max_delay_event_short": 5,
|
||||
"min_delay_retry": 2,
|
||||
"max_delay_retry": 10,
|
||||
"restrict_unknown_seed_wallets": False,
|
||||
}
|
||||
|
||||
with open(settings_path, 'w') as fp:
|
||||
with open(settings_path, "w") as fp:
|
||||
json.dump(settings, fp, indent=4)
|
||||
|
||||
|
||||
def partRpc(cmd, node_id=0):
|
||||
return callrpc_cli(cfg.PARTICL_BINDIR, os.path.join(TEST_DIR, 'part_' + str(node_id)), 'regtest', cmd, cfg.PARTICL_CLI)
|
||||
return callrpc_cli(
|
||||
cfg.PARTICL_BINDIR,
|
||||
os.path.join(TEST_DIR, "part_" + str(node_id)),
|
||||
"regtest",
|
||||
cmd,
|
||||
cfg.PARTICL_CLI,
|
||||
)
|
||||
|
||||
|
||||
def btcRpc(cmd, node_id=0):
|
||||
return callrpc_cli(cfg.BITCOIN_BINDIR, os.path.join(TEST_DIR, 'btc_' + str(node_id)), 'regtest', cmd, cfg.BITCOIN_CLI)
|
||||
return callrpc_cli(
|
||||
cfg.BITCOIN_BINDIR,
|
||||
os.path.join(TEST_DIR, "btc_" + str(node_id)),
|
||||
"regtest",
|
||||
cmd,
|
||||
cfg.BITCOIN_CLI,
|
||||
)
|
||||
|
||||
|
||||
def signal_handler(sig, frame):
|
||||
global stop_test
|
||||
logging.info('signal {} detected.'.format(sig))
|
||||
logging.info("signal {} detected.".format(sig))
|
||||
stop_test = True
|
||||
delay_event.set()
|
||||
|
||||
|
||||
def callnoderpc(node_id, method, params=[], wallet=None, base_rpc_port=BASE_RPC_PORT):
|
||||
auth = 'test{0}:test_pass{0}'.format(node_id)
|
||||
auth = "test{0}:test_pass{0}".format(node_id)
|
||||
return callrpc(base_rpc_port + node_id, auth, method, params, wallet)
|
||||
|
||||
|
||||
|
@ -152,9 +164,9 @@ def run_coins_loop(cls):
|
|||
while not stop_test:
|
||||
try:
|
||||
if cls.btc_addr is not None:
|
||||
btcRpc('generatetoaddress 1 {}'.format(cls.btc_addr))
|
||||
btcRpc("generatetoaddress 1 {}".format(cls.btc_addr))
|
||||
except Exception as e:
|
||||
logging.warning('run_coins_loop ' + str(e))
|
||||
logging.warning("run_coins_loop " + str(e))
|
||||
time.sleep(1.0)
|
||||
|
||||
|
||||
|
@ -183,58 +195,122 @@ class Test(unittest.TestCase):
|
|||
logger.propagate = False
|
||||
logger.handlers = []
|
||||
logger.setLevel(logging.INFO) # DEBUG shows many messages from requests.post
|
||||
formatter = logging.Formatter('%(asctime)s %(levelname)s : %(message)s')
|
||||
formatter = logging.Formatter("%(asctime)s %(levelname)s : %(message)s")
|
||||
stream_stdout = logging.StreamHandler()
|
||||
stream_stdout.setFormatter(formatter)
|
||||
logger.addHandler(stream_stdout)
|
||||
|
||||
if os.path.isdir(TEST_DIR):
|
||||
logging.info('Removing ' + TEST_DIR)
|
||||
logging.info("Removing " + TEST_DIR)
|
||||
shutil.rmtree(TEST_DIR)
|
||||
if not os.path.exists(TEST_DIR):
|
||||
os.makedirs(TEST_DIR)
|
||||
|
||||
cls.stream_fp = logging.FileHandler(os.path.join(TEST_DIR, 'test.log'))
|
||||
cls.stream_fp = logging.FileHandler(os.path.join(TEST_DIR, "test.log"))
|
||||
cls.stream_fp.setFormatter(formatter)
|
||||
logger.addHandler(cls.stream_fp)
|
||||
|
||||
try:
|
||||
logging.info('Preparing coin nodes.')
|
||||
logging.info("Preparing coin nodes.")
|
||||
for i in range(NUM_NODES):
|
||||
data_dir = prepareDataDir(TEST_DIR, i, 'particl.conf', 'part_')
|
||||
if os.path.exists(os.path.join(cfg.PARTICL_BINDIR, 'particl-wallet')):
|
||||
callrpc_cli(cfg.PARTICL_BINDIR, data_dir, 'regtest', '-wallet=wallet.dat -legacy create', 'particl-wallet')
|
||||
data_dir = prepareDataDir(TEST_DIR, i, "particl.conf", "part_")
|
||||
if os.path.exists(os.path.join(cfg.PARTICL_BINDIR, "particl-wallet")):
|
||||
callrpc_cli(
|
||||
cfg.PARTICL_BINDIR,
|
||||
data_dir,
|
||||
"regtest",
|
||||
"-wallet=wallet.dat -legacy create",
|
||||
"particl-wallet",
|
||||
)
|
||||
|
||||
cls.part_daemons.append(startDaemon(os.path.join(TEST_DIR, 'part_' + str(i)), cfg.PARTICL_BINDIR, cfg.PARTICLD))
|
||||
logging.info('Started %s %d', cfg.PARTICLD, cls.handle.part_daemons[-1].handle.pid)
|
||||
cls.part_daemons.append(
|
||||
startDaemon(
|
||||
os.path.join(TEST_DIR, "part_" + str(i)),
|
||||
cfg.PARTICL_BINDIR,
|
||||
cfg.PARTICLD,
|
||||
)
|
||||
)
|
||||
logging.info(
|
||||
"Started %s %d",
|
||||
cfg.PARTICLD,
|
||||
cls.handle.part_daemons[-1].handle.pid,
|
||||
)
|
||||
|
||||
for i in range(NUM_NODES):
|
||||
# Load mnemonics after all nodes have started to avoid staking getting stuck in TryToSync
|
||||
rpc = make_rpc_func(i)
|
||||
waitForRPC(rpc, delay_event)
|
||||
if i == 0:
|
||||
rpc('extkeyimportmaster', ['abandon baby cabbage dad eager fabric gadget habit ice kangaroo lab absorb'])
|
||||
rpc(
|
||||
"extkeyimportmaster",
|
||||
[
|
||||
"abandon baby cabbage dad eager fabric gadget habit ice kangaroo lab absorb"
|
||||
],
|
||||
)
|
||||
elif i == 1:
|
||||
rpc('extkeyimportmaster', ['pact mammal barrel matrix local final lecture chunk wasp survey bid various book strong spread fall ozone daring like topple door fatigue limb olympic', '', 'true'])
|
||||
rpc('getnewextaddress', ['lblExtTest'])
|
||||
rpc('rescanblockchain')
|
||||
rpc(
|
||||
"extkeyimportmaster",
|
||||
[
|
||||
"pact mammal barrel matrix local final lecture chunk wasp survey bid various book strong spread fall ozone daring like topple door fatigue limb olympic",
|
||||
"",
|
||||
"true",
|
||||
],
|
||||
)
|
||||
rpc("getnewextaddress", ["lblExtTest"])
|
||||
rpc("rescanblockchain")
|
||||
else:
|
||||
rpc('extkeyimportmaster', [rpc('mnemonic', ['new'])['master']])
|
||||
rpc("extkeyimportmaster", [rpc("mnemonic", ["new"])["master"]])
|
||||
# Lower output split threshold for more stakeable outputs
|
||||
rpc('walletsettings', ['stakingoptions', {'stakecombinethreshold': 100, 'stakesplitthreshold': 200}])
|
||||
rpc('reservebalance', [False,])
|
||||
rpc(
|
||||
"walletsettings",
|
||||
[
|
||||
"stakingoptions",
|
||||
{"stakecombinethreshold": 100, "stakesplitthreshold": 200},
|
||||
],
|
||||
)
|
||||
rpc(
|
||||
"reservebalance",
|
||||
[
|
||||
False,
|
||||
],
|
||||
)
|
||||
|
||||
for i in range(NUM_BTC_NODES):
|
||||
data_dir = prepareDataDir(TEST_DIR, i, 'bitcoin.conf', 'btc_', base_p2p_port=BTC_BASE_PORT, base_rpc_port=BTC_BASE_RPC_PORT)
|
||||
if os.path.exists(os.path.join(cfg.BITCOIN_BINDIR, 'bitcoin-wallet')):
|
||||
callrpc_cli(cfg.BITCOIN_BINDIR, data_dir, 'regtest', '-wallet=wallet.dat -legacy create', 'bitcoin-wallet')
|
||||
data_dir = prepareDataDir(
|
||||
TEST_DIR,
|
||||
i,
|
||||
"bitcoin.conf",
|
||||
"btc_",
|
||||
base_p2p_port=BTC_BASE_PORT,
|
||||
base_rpc_port=BTC_BASE_RPC_PORT,
|
||||
)
|
||||
if os.path.exists(os.path.join(cfg.BITCOIN_BINDIR, "bitcoin-wallet")):
|
||||
callrpc_cli(
|
||||
cfg.BITCOIN_BINDIR,
|
||||
data_dir,
|
||||
"regtest",
|
||||
"-wallet=wallet.dat -legacy create",
|
||||
"bitcoin-wallet",
|
||||
)
|
||||
|
||||
cls.btc_daemons.append(startDaemon(os.path.join(TEST_DIR, 'btc_' + str(i)), cfg.BITCOIN_BINDIR, cfg.BITCOIND))
|
||||
logging.info('Started %s %d', cfg.BITCOIND, cls.handle.part_daemons[-1].handle.pid)
|
||||
cls.btc_daemons.append(
|
||||
startDaemon(
|
||||
os.path.join(TEST_DIR, "btc_" + str(i)),
|
||||
cfg.BITCOIN_BINDIR,
|
||||
cfg.BITCOIND,
|
||||
)
|
||||
)
|
||||
logging.info(
|
||||
"Started %s %d",
|
||||
cfg.BITCOIND,
|
||||
cls.handle.part_daemons[-1].handle.pid,
|
||||
)
|
||||
|
||||
waitForRPC(make_rpc_func(i, base_rpc_port=BTC_BASE_RPC_PORT), delay_event)
|
||||
waitForRPC(
|
||||
make_rpc_func(i, base_rpc_port=BTC_BASE_RPC_PORT), delay_event
|
||||
)
|
||||
|
||||
logging.info('Preparing swap clients.')
|
||||
logging.info("Preparing swap clients.")
|
||||
eckey = ECKey()
|
||||
eckey.generate()
|
||||
cls.network_key = toWIF(PREFIX_SECRET_KEY_REGTEST, eckey.get_bytes())
|
||||
|
@ -242,12 +318,20 @@ class Test(unittest.TestCase):
|
|||
|
||||
for i in range(NUM_NODES):
|
||||
prepare_swapclient_dir(TEST_DIR, i, cls.network_key, cls.network_pubkey)
|
||||
basicswap_dir = os.path.join(os.path.join(TEST_DIR, 'basicswap_' + str(i)))
|
||||
basicswap_dir = os.path.join(
|
||||
os.path.join(TEST_DIR, "basicswap_" + str(i))
|
||||
)
|
||||
settings_path = os.path.join(basicswap_dir, cfg.CONFIG_FILENAME)
|
||||
with open(settings_path) as fs:
|
||||
settings = json.load(fs)
|
||||
fp = open(os.path.join(basicswap_dir, 'basicswap.log'), 'w')
|
||||
sc = BasicSwap(fp, basicswap_dir, settings, 'regtest', log_name='BasicSwap{}'.format(i))
|
||||
fp = open(os.path.join(basicswap_dir, "basicswap.log"), "w")
|
||||
sc = BasicSwap(
|
||||
fp,
|
||||
basicswap_dir,
|
||||
settings,
|
||||
"regtest",
|
||||
log_name="BasicSwap{}".format(i),
|
||||
)
|
||||
cls.swap_clients.append(sc)
|
||||
sc.setDaemonPID(Coins.BTC, cls.btc_daemons[i].handle.pid)
|
||||
sc.setDaemonPID(Coins.PART, cls.part_daemons[i].handle.pid)
|
||||
|
@ -257,41 +341,55 @@ class Test(unittest.TestCase):
|
|||
cls.http_threads.append(t)
|
||||
t.start()
|
||||
|
||||
cls.btc_addr = callnoderpc(0, 'getnewaddress', ['mining_addr', 'bech32'], base_rpc_port=BTC_BASE_RPC_PORT)
|
||||
cls.btc_addr = callnoderpc(
|
||||
0,
|
||||
"getnewaddress",
|
||||
["mining_addr", "bech32"],
|
||||
base_rpc_port=BTC_BASE_RPC_PORT,
|
||||
)
|
||||
|
||||
num_blocks = 500
|
||||
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)
|
||||
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,
|
||||
)
|
||||
|
||||
checkForks(callnoderpc(0, 'getblockchaininfo', base_rpc_port=BTC_BASE_RPC_PORT))
|
||||
checkForks(
|
||||
callnoderpc(0, "getblockchaininfo", base_rpc_port=BTC_BASE_RPC_PORT)
|
||||
)
|
||||
|
||||
logging.info('Starting update thread.')
|
||||
logging.info("Starting update thread.")
|
||||
signal.signal(signal.SIGINT, signal_handler)
|
||||
cls.update_thread = threading.Thread(target=run_loop, args=(cls,))
|
||||
cls.update_thread.start()
|
||||
|
||||
cls.coins_update_thread = threading.Thread(target=run_coins_loop, args=(cls,))
|
||||
cls.coins_update_thread = threading.Thread(
|
||||
target=run_coins_loop, args=(cls,)
|
||||
)
|
||||
cls.coins_update_thread.start()
|
||||
except Exception:
|
||||
traceback.print_exc()
|
||||
cls.tearDownClass()
|
||||
raise ValueError('setUpClass() failed.')
|
||||
raise ValueError("setUpClass() failed.")
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
global stop_test
|
||||
logging.info('Finalising')
|
||||
logging.info("Finalising")
|
||||
stop_test = True
|
||||
if cls.update_thread is not None:
|
||||
try:
|
||||
cls.update_thread.join()
|
||||
except Exception:
|
||||
logging.info('Failed to join update_thread')
|
||||
logging.info("Failed to join update_thread")
|
||||
if cls.coins_update_thread is not None:
|
||||
try:
|
||||
cls.coins_update_thread.join()
|
||||
except Exception:
|
||||
logging.info('Failed to join coins_update_thread')
|
||||
logging.info("Failed to join coins_update_thread")
|
||||
|
||||
for t in cls.http_threads:
|
||||
t.stop()
|
||||
|
@ -313,39 +411,51 @@ class Test(unittest.TestCase):
|
|||
def wait_for_num_nodes(self, port, expect_nodes, wait_for=20):
|
||||
for i in range(wait_for):
|
||||
if delay_event.is_set():
|
||||
raise ValueError('Test stopped.')
|
||||
js = read_json_api(port, 'network')
|
||||
raise ValueError("Test stopped.")
|
||||
js = read_json_api(port, "network")
|
||||
num_nodes = 0
|
||||
for p in js['peers']:
|
||||
if p['ready'] is True:
|
||||
for p in js["peers"]:
|
||||
if p["ready"] is True:
|
||||
num_nodes += 1
|
||||
if num_nodes >= expect_nodes:
|
||||
return True
|
||||
delay_event.wait(1)
|
||||
raise ValueError('wait_for_num_nodes timed out.')
|
||||
raise ValueError("wait_for_num_nodes timed out.")
|
||||
|
||||
def test_01_network(self):
|
||||
|
||||
logging.info('---------- Test Network')
|
||||
logging.info("---------- Test Network")
|
||||
swap_clients = self.swap_clients
|
||||
|
||||
js_1 = read_json_api(1801, 'wallets')
|
||||
swap_clients[0].postOffer(
|
||||
Coins.PART,
|
||||
Coins.BTC,
|
||||
100 * COIN,
|
||||
0.1 * COIN,
|
||||
100 * COIN,
|
||||
SwapTypes.SELLER_FIRST,
|
||||
)
|
||||
|
||||
offer_id = swap_clients[0].postOffer(Coins.PART, Coins.BTC, 100 * COIN, 0.1 * COIN, 100 * COIN, SwapTypes.SELLER_FIRST)
|
||||
|
||||
swap_clients[1].add_connection('127.0.0.1', BASE_P2P_PORT + 0, swap_clients[0]._network._network_pubkey)
|
||||
swap_clients[2].add_connection('127.0.0.1', BASE_P2P_PORT + 0, swap_clients[0]._network._network_pubkey)
|
||||
swap_clients[1].add_connection(
|
||||
"127.0.0.1", BASE_P2P_PORT + 0, swap_clients[0]._network._network_pubkey
|
||||
)
|
||||
swap_clients[2].add_connection(
|
||||
"127.0.0.1", BASE_P2P_PORT + 0, swap_clients[0]._network._network_pubkey
|
||||
)
|
||||
|
||||
self.wait_for_num_nodes(1800, 2)
|
||||
|
||||
js_n0 = read_json_api(1800, 'network')
|
||||
js_n0 = read_json_api(1800, "network")
|
||||
print(dumpj(js_n0))
|
||||
|
||||
path = [swap_clients[0]._network._network_pubkey, swap_clients[2]._network._network_pubkey]
|
||||
path = [
|
||||
swap_clients[0]._network._network_pubkey,
|
||||
swap_clients[2]._network._network_pubkey,
|
||||
]
|
||||
swap_clients[1]._network.test_onion(path)
|
||||
|
||||
delay_for(delay_event, 1000)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright (c) 2019-2021 tecnovert
|
||||
# Copyright (c) 2024 The Basicswap developers
|
||||
# Distributed under the MIT software license, see the accompanying
|
||||
# file LICENSE or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
|
@ -80,74 +81,74 @@ delay_event = threading.Event()
|
|||
stop_test = False
|
||||
|
||||
|
||||
def prepareOtherDir(datadir, nodeId, conf_file='namecoin.conf'):
|
||||
def prepareOtherDir(datadir, nodeId, conf_file="namecoin.conf"):
|
||||
node_dir = os.path.join(datadir, str(nodeId))
|
||||
if not os.path.exists(node_dir):
|
||||
os.makedirs(node_dir)
|
||||
filePath = os.path.join(node_dir, conf_file)
|
||||
|
||||
with open(filePath, 'w+') as fp:
|
||||
fp.write('regtest=1\n')
|
||||
fp.write('[regtest]\n')
|
||||
fp.write('port=' + str(BASE_PORT + nodeId) + '\n')
|
||||
fp.write('rpcport=' + str(BASE_RPC_PORT + nodeId) + '\n')
|
||||
with open(filePath, "w+") as fp:
|
||||
fp.write("regtest=1\n")
|
||||
fp.write("[regtest]\n")
|
||||
fp.write("port=" + str(BASE_PORT + nodeId) + "\n")
|
||||
fp.write("rpcport=" + str(BASE_RPC_PORT + nodeId) + "\n")
|
||||
|
||||
fp.write('daemon=0\n')
|
||||
fp.write('printtoconsole=0\n')
|
||||
fp.write('server=1\n')
|
||||
fp.write('discover=0\n')
|
||||
fp.write('listenonion=0\n')
|
||||
fp.write('bind=127.0.0.1\n')
|
||||
fp.write('findpeers=0\n')
|
||||
fp.write('debug=1\n')
|
||||
fp.write('debugexclude=libevent\n')
|
||||
fp.write("daemon=0\n")
|
||||
fp.write("printtoconsole=0\n")
|
||||
fp.write("server=1\n")
|
||||
fp.write("discover=0\n")
|
||||
fp.write("listenonion=0\n")
|
||||
fp.write("bind=127.0.0.1\n")
|
||||
fp.write("findpeers=0\n")
|
||||
fp.write("debug=1\n")
|
||||
fp.write("debugexclude=libevent\n")
|
||||
|
||||
fp.write('fallbackfee=0.01\n')
|
||||
fp.write('acceptnonstdtxn=0\n')
|
||||
fp.write("fallbackfee=0.01\n")
|
||||
fp.write("acceptnonstdtxn=0\n")
|
||||
|
||||
if conf_file == 'bitcoin.conf':
|
||||
fp.write('wallet=wallet.dat\n')
|
||||
if conf_file == "bitcoin.conf":
|
||||
fp.write("wallet=wallet.dat\n")
|
||||
|
||||
|
||||
def prepareDir(datadir, nodeId, network_key, network_pubkey):
|
||||
node_dir = os.path.join(datadir, str(nodeId))
|
||||
if not os.path.exists(node_dir):
|
||||
os.makedirs(node_dir)
|
||||
filePath = os.path.join(node_dir, 'particl.conf')
|
||||
filePath = os.path.join(node_dir, "particl.conf")
|
||||
|
||||
with open(filePath, 'w+') as fp:
|
||||
fp.write('regtest=1\n')
|
||||
fp.write('[regtest]\n')
|
||||
fp.write('port=' + str(BASE_PORT + nodeId) + '\n')
|
||||
fp.write('rpcport=' + str(BASE_RPC_PORT + nodeId) + '\n')
|
||||
with open(filePath, "w+") as fp:
|
||||
fp.write("regtest=1\n")
|
||||
fp.write("[regtest]\n")
|
||||
fp.write("port=" + str(BASE_PORT + nodeId) + "\n")
|
||||
fp.write("rpcport=" + str(BASE_RPC_PORT + nodeId) + "\n")
|
||||
|
||||
fp.write('daemon=0\n')
|
||||
fp.write('printtoconsole=0\n')
|
||||
fp.write('server=1\n')
|
||||
fp.write('discover=0\n')
|
||||
fp.write('listenonion=0\n')
|
||||
fp.write('bind=127.0.0.1\n')
|
||||
fp.write('findpeers=0\n')
|
||||
fp.write('debug=1\n')
|
||||
fp.write('debugexclude=libevent\n')
|
||||
fp.write('zmqpubsmsg=tcp://127.0.0.1:' + str(BASE_ZMQ_PORT + nodeId) + '\n')
|
||||
fp.write('wallet=wallet.dat\n')
|
||||
fp.write('fallbackfee=0.01\n')
|
||||
fp.write("daemon=0\n")
|
||||
fp.write("printtoconsole=0\n")
|
||||
fp.write("server=1\n")
|
||||
fp.write("discover=0\n")
|
||||
fp.write("listenonion=0\n")
|
||||
fp.write("bind=127.0.0.1\n")
|
||||
fp.write("findpeers=0\n")
|
||||
fp.write("debug=1\n")
|
||||
fp.write("debugexclude=libevent\n")
|
||||
fp.write("zmqpubsmsg=tcp://127.0.0.1:" + str(BASE_ZMQ_PORT + nodeId) + "\n")
|
||||
fp.write("wallet=wallet.dat\n")
|
||||
fp.write("fallbackfee=0.01\n")
|
||||
|
||||
fp.write('acceptnonstdtxn=0\n')
|
||||
fp.write('minstakeinterval=5\n')
|
||||
fp.write('smsgsregtestadjust=0\n')
|
||||
fp.write("acceptnonstdtxn=0\n")
|
||||
fp.write("minstakeinterval=5\n")
|
||||
fp.write("smsgsregtestadjust=0\n")
|
||||
|
||||
for i in range(0, NUM_NODES):
|
||||
if nodeId == i:
|
||||
continue
|
||||
fp.write('addnode=127.0.0.1:%d\n' % (BASE_PORT + i))
|
||||
fp.write("addnode=127.0.0.1:%d\n" % (BASE_PORT + i))
|
||||
|
||||
if nodeId < 2:
|
||||
fp.write('spentindex=1\n')
|
||||
fp.write('txindex=1\n')
|
||||
fp.write("spentindex=1\n")
|
||||
fp.write("txindex=1\n")
|
||||
|
||||
basicswap_dir = os.path.join(datadir, str(nodeId), 'basicswap')
|
||||
basicswap_dir = os.path.join(datadir, str(nodeId), "basicswap")
|
||||
if not os.path.exists(basicswap_dir):
|
||||
os.makedirs(basicswap_dir)
|
||||
|
||||
|
@ -155,64 +156,82 @@ def prepareDir(datadir, nodeId, network_key, network_pubkey):
|
|||
btcdatadir = os.path.join(datadir, str(BTC_NODE))
|
||||
settings_path = os.path.join(basicswap_dir, cfg.CONFIG_FILENAME)
|
||||
settings = {
|
||||
'debug': True,
|
||||
'zmqhost': 'tcp://127.0.0.1',
|
||||
'zmqport': BASE_ZMQ_PORT + nodeId,
|
||||
'htmlhost': '127.0.0.1',
|
||||
'htmlport': 12700 + nodeId,
|
||||
'network_key': network_key,
|
||||
'network_pubkey': network_pubkey,
|
||||
'chainclients': {
|
||||
'particl': {
|
||||
'connection_type': 'rpc',
|
||||
'manage_daemon': False,
|
||||
'rpcport': BASE_RPC_PORT + nodeId,
|
||||
'datadir': node_dir,
|
||||
'bindir': cfg.PARTICL_BINDIR,
|
||||
'blocks_confirmed': 2, # Faster testing
|
||||
"debug": True,
|
||||
"zmqhost": "tcp://127.0.0.1",
|
||||
"zmqport": BASE_ZMQ_PORT + nodeId,
|
||||
"htmlhost": "127.0.0.1",
|
||||
"htmlport": 12700 + nodeId,
|
||||
"network_key": network_key,
|
||||
"network_pubkey": network_pubkey,
|
||||
"chainclients": {
|
||||
"particl": {
|
||||
"connection_type": "rpc",
|
||||
"manage_daemon": False,
|
||||
"rpcport": BASE_RPC_PORT + nodeId,
|
||||
"datadir": node_dir,
|
||||
"bindir": cfg.PARTICL_BINDIR,
|
||||
"blocks_confirmed": 2, # Faster testing
|
||||
},
|
||||
'namecoin': {
|
||||
'connection_type': 'rpc',
|
||||
'manage_daemon': False,
|
||||
'rpcport': BASE_RPC_PORT + NMC_NODE,
|
||||
'datadir': nmcdatadir,
|
||||
'bindir': cfg.NAMECOIN_BINDIR,
|
||||
'use_csv': False,
|
||||
"namecoin": {
|
||||
"connection_type": "rpc",
|
||||
"manage_daemon": False,
|
||||
"rpcport": BASE_RPC_PORT + NMC_NODE,
|
||||
"datadir": nmcdatadir,
|
||||
"bindir": cfg.NAMECOIN_BINDIR,
|
||||
"use_csv": False,
|
||||
# 'use_segwit': True,
|
||||
},
|
||||
'bitcoin': {
|
||||
'connection_type': 'rpc',
|
||||
'manage_daemon': False,
|
||||
'rpcport': BASE_RPC_PORT + BTC_NODE,
|
||||
'datadir': btcdatadir,
|
||||
'bindir': cfg.BITCOIN_BINDIR,
|
||||
'use_segwit': True,
|
||||
}
|
||||
"bitcoin": {
|
||||
"connection_type": "rpc",
|
||||
"manage_daemon": False,
|
||||
"rpcport": BASE_RPC_PORT + BTC_NODE,
|
||||
"datadir": btcdatadir,
|
||||
"bindir": cfg.BITCOIN_BINDIR,
|
||||
"use_segwit": True,
|
||||
},
|
||||
},
|
||||
'check_progress_seconds': 2,
|
||||
'check_watched_seconds': 4,
|
||||
'check_expired_seconds': 60,
|
||||
'restrict_unknown_seed_wallets': False,
|
||||
"check_progress_seconds": 2,
|
||||
"check_watched_seconds": 4,
|
||||
"check_expired_seconds": 60,
|
||||
"restrict_unknown_seed_wallets": False,
|
||||
}
|
||||
with open(settings_path, 'w') as fp:
|
||||
with open(settings_path, "w") as fp:
|
||||
json.dump(settings, fp, indent=4)
|
||||
|
||||
|
||||
def partRpc(cmd, node_id=0):
|
||||
return callrpc_cli(cfg.PARTICL_BINDIR, os.path.join(cfg.TEST_DATADIRS, str(node_id)), 'regtest', cmd, cfg.PARTICL_CLI)
|
||||
return callrpc_cli(
|
||||
cfg.PARTICL_BINDIR,
|
||||
os.path.join(cfg.TEST_DATADIRS, str(node_id)),
|
||||
"regtest",
|
||||
cmd,
|
||||
cfg.PARTICL_CLI,
|
||||
)
|
||||
|
||||
|
||||
def btcRpc(cmd):
|
||||
return callrpc_cli(cfg.BITCOIN_BINDIR, os.path.join(cfg.TEST_DATADIRS, str(BTC_NODE)), 'regtest', cmd, cfg.BITCOIN_CLI)
|
||||
return callrpc_cli(
|
||||
cfg.BITCOIN_BINDIR,
|
||||
os.path.join(cfg.TEST_DATADIRS, str(BTC_NODE)),
|
||||
"regtest",
|
||||
cmd,
|
||||
cfg.BITCOIN_CLI,
|
||||
)
|
||||
|
||||
|
||||
def nmcRpc(cmd):
|
||||
return callrpc_cli(cfg.NAMECOIN_BINDIR, os.path.join(cfg.TEST_DATADIRS, str(NMC_NODE)), 'regtest', cmd, cfg.NAMECOIN_CLI)
|
||||
return callrpc_cli(
|
||||
cfg.NAMECOIN_BINDIR,
|
||||
os.path.join(cfg.TEST_DATADIRS, str(NMC_NODE)),
|
||||
"regtest",
|
||||
cmd,
|
||||
cfg.NAMECOIN_CLI,
|
||||
)
|
||||
|
||||
|
||||
def signal_handler(sig, frame):
|
||||
global stop_test
|
||||
print('signal {} detected.'.format(sig))
|
||||
print("signal {} detected.".format(sig))
|
||||
stop_test = True
|
||||
delay_event.set()
|
||||
|
||||
|
@ -220,10 +239,10 @@ def signal_handler(sig, frame):
|
|||
def run_coins_loop(cls):
|
||||
while not stop_test:
|
||||
try:
|
||||
nmcRpc('generatetoaddress 1 {}'.format(cls.nmc_addr))
|
||||
btcRpc('generatetoaddress 1 {}'.format(cls.btc_addr))
|
||||
nmcRpc("generatetoaddress 1 {}".format(cls.nmc_addr))
|
||||
btcRpc("generatetoaddress 1 {}".format(cls.btc_addr))
|
||||
except Exception as e:
|
||||
logging.warning('run_coins_loop ' + str(e))
|
||||
logging.warning("run_coins_loop " + str(e))
|
||||
time.sleep(1.0)
|
||||
|
||||
|
||||
|
@ -244,6 +263,7 @@ def make_part_cli_rpc_func(node_id):
|
|||
for p in params:
|
||||
cmd += ' "' + p + '"'
|
||||
return partRpc(cmd, node_id)
|
||||
|
||||
return rpc_func
|
||||
|
||||
|
||||
|
@ -259,54 +279,96 @@ class Test(unittest.TestCase):
|
|||
cls.network_pubkey = eckey.get_pubkey().get_bytes().hex()
|
||||
|
||||
if os.path.isdir(cfg.TEST_DATADIRS):
|
||||
logging.info('Removing ' + cfg.TEST_DATADIRS)
|
||||
logging.info("Removing " + cfg.TEST_DATADIRS)
|
||||
shutil.rmtree(cfg.TEST_DATADIRS)
|
||||
|
||||
for i in range(NUM_NODES):
|
||||
prepareDir(cfg.TEST_DATADIRS, i, cls.network_key, cls.network_pubkey)
|
||||
|
||||
prepareOtherDir(cfg.TEST_DATADIRS, NMC_NODE)
|
||||
prepareOtherDir(cfg.TEST_DATADIRS, BTC_NODE, 'bitcoin.conf')
|
||||
prepareOtherDir(cfg.TEST_DATADIRS, BTC_NODE, "bitcoin.conf")
|
||||
|
||||
cls.daemons = []
|
||||
cls.swap_clients = []
|
||||
cls.http_threads = []
|
||||
|
||||
btc_data_dir = os.path.join(cfg.TEST_DATADIRS, str(BTC_NODE))
|
||||
if os.path.exists(os.path.join(cfg.BITCOIN_BINDIR, 'bitcoin-wallet')):
|
||||
callrpc_cli(cfg.BITCOIN_BINDIR, btc_data_dir, 'regtest', '-wallet=wallet.dat -legacy create', 'bitcoin-wallet')
|
||||
if os.path.exists(os.path.join(cfg.BITCOIN_BINDIR, "bitcoin-wallet")):
|
||||
callrpc_cli(
|
||||
cfg.BITCOIN_BINDIR,
|
||||
btc_data_dir,
|
||||
"regtest",
|
||||
"-wallet=wallet.dat -legacy create",
|
||||
"bitcoin-wallet",
|
||||
)
|
||||
cls.daemons.append(startDaemon(btc_data_dir, cfg.BITCOIN_BINDIR, cfg.BITCOIND))
|
||||
logging.info('Started %s %d', cfg.BITCOIND, cls.daemons[-1].handle.pid)
|
||||
cls.daemons.append(startDaemon(os.path.join(cfg.TEST_DATADIRS, str(NMC_NODE)), cfg.NAMECOIN_BINDIR, cfg.NAMECOIND))
|
||||
logging.info('Started %s %d', cfg.NAMECOIND, cls.daemons[-1].handle.pid)
|
||||
logging.info("Started %s %d", cfg.BITCOIND, cls.daemons[-1].handle.pid)
|
||||
cls.daemons.append(
|
||||
startDaemon(
|
||||
os.path.join(cfg.TEST_DATADIRS, str(NMC_NODE)),
|
||||
cfg.NAMECOIN_BINDIR,
|
||||
cfg.NAMECOIND,
|
||||
)
|
||||
)
|
||||
logging.info("Started %s %d", cfg.NAMECOIND, cls.daemons[-1].handle.pid)
|
||||
|
||||
for i in range(NUM_NODES):
|
||||
data_dir = os.path.join(cfg.TEST_DATADIRS, str(i))
|
||||
if os.path.exists(os.path.join(cfg.PARTICL_BINDIR, 'particl-wallet')):
|
||||
callrpc_cli(cfg.PARTICL_BINDIR, data_dir, 'regtest', '-wallet=wallet.dat -legacy create', 'particl-wallet')
|
||||
if os.path.exists(os.path.join(cfg.PARTICL_BINDIR, "particl-wallet")):
|
||||
callrpc_cli(
|
||||
cfg.PARTICL_BINDIR,
|
||||
data_dir,
|
||||
"regtest",
|
||||
"-wallet=wallet.dat -legacy create",
|
||||
"particl-wallet",
|
||||
)
|
||||
cls.daemons.append(startDaemon(data_dir, cfg.PARTICL_BINDIR, cfg.PARTICLD))
|
||||
logging.info('Started %s %d', cfg.PARTICLD, cls.daemons[-1].handle.pid)
|
||||
logging.info("Started %s %d", cfg.PARTICLD, cls.daemons[-1].handle.pid)
|
||||
|
||||
for i in range(NUM_NODES):
|
||||
rpc = make_part_cli_rpc_func(i)
|
||||
waitForRPC(rpc, delay_event)
|
||||
if i == 0:
|
||||
rpc('extkeyimportmaster', ['abandon baby cabbage dad eager fabric gadget habit ice kangaroo lab absorb'])
|
||||
rpc(
|
||||
"extkeyimportmaster",
|
||||
[
|
||||
"abandon baby cabbage dad eager fabric gadget habit ice kangaroo lab absorb"
|
||||
],
|
||||
)
|
||||
elif i == 1:
|
||||
rpc('extkeyimportmaster', ['pact mammal barrel matrix local final lecture chunk wasp survey bid various book strong spread fall ozone daring like topple door fatigue limb olympic', '', 'true'])
|
||||
rpc('getnewextaddress', ['lblExtTest'])
|
||||
rpc('rescanblockchain')
|
||||
rpc(
|
||||
"extkeyimportmaster",
|
||||
[
|
||||
"pact mammal barrel matrix local final lecture chunk wasp survey bid various book strong spread fall ozone daring like topple door fatigue limb olympic",
|
||||
"",
|
||||
"true",
|
||||
],
|
||||
)
|
||||
rpc("getnewextaddress", ["lblExtTest"])
|
||||
rpc("rescanblockchain")
|
||||
else:
|
||||
rpc('extkeyimportmaster', [rpc('mnemonic', ['new'])['master']])
|
||||
rpc('walletsettings', ['stakingoptions', json.dumps({'stakecombinethreshold': 100, 'stakesplitthreshold': 200}).replace('"', '\\"')])
|
||||
rpc('reservebalance', ['false'])
|
||||
rpc("extkeyimportmaster", [rpc("mnemonic", ["new"])["master"]])
|
||||
rpc(
|
||||
"walletsettings",
|
||||
[
|
||||
"stakingoptions",
|
||||
json.dumps(
|
||||
{"stakecombinethreshold": 100, "stakesplitthreshold": 200}
|
||||
).replace('"', '\\"'),
|
||||
],
|
||||
)
|
||||
rpc("reservebalance", ["false"])
|
||||
|
||||
basicswap_dir = os.path.join(os.path.join(cfg.TEST_DATADIRS, str(i)), 'basicswap')
|
||||
basicswap_dir = os.path.join(
|
||||
os.path.join(cfg.TEST_DATADIRS, str(i)), "basicswap"
|
||||
)
|
||||
settings_path = os.path.join(basicswap_dir, cfg.CONFIG_FILENAME)
|
||||
with open(settings_path) as fs:
|
||||
settings = json.load(fs)
|
||||
fp = open(os.path.join(basicswap_dir, 'basicswap.log'), 'w')
|
||||
sc = BasicSwap(fp, basicswap_dir, settings, 'regtest', log_name='BasicSwap{}'.format(i))
|
||||
fp = open(os.path.join(basicswap_dir, "basicswap.log"), "w")
|
||||
sc = BasicSwap(
|
||||
fp, basicswap_dir, settings, "regtest", log_name="BasicSwap{}".format(i)
|
||||
)
|
||||
cls.swap_clients.append(sc)
|
||||
|
||||
sc.setDaemonPID(Coins.BTC, cls.daemons[0].handle.pid)
|
||||
|
@ -320,30 +382,30 @@ class Test(unittest.TestCase):
|
|||
|
||||
waitForRPC(nmcRpc, delay_event)
|
||||
num_blocks = 500
|
||||
logging.info('Mining %d namecoin blocks', num_blocks)
|
||||
cls.nmc_addr = nmcRpc('getnewaddress mining_addr legacy')
|
||||
nmcRpc('generatetoaddress {} {}'.format(num_blocks, cls.nmc_addr))
|
||||
logging.info("Mining %d namecoin blocks", num_blocks)
|
||||
cls.nmc_addr = nmcRpc("getnewaddress mining_addr legacy")
|
||||
nmcRpc("generatetoaddress {} {}".format(num_blocks, cls.nmc_addr))
|
||||
|
||||
ro = nmcRpc('getblockchaininfo')
|
||||
ro = nmcRpc("getblockchaininfo")
|
||||
try:
|
||||
assert (ro['bip9_softforks']['csv']['status'] == 'active')
|
||||
assert ro["bip9_softforks"]["csv"]["status"] == "active"
|
||||
except Exception:
|
||||
logging.info('nmc: csv is not active')
|
||||
logging.info("nmc: csv is not active")
|
||||
try:
|
||||
assert (ro['bip9_softforks']['segwit']['status'] == 'active')
|
||||
assert ro["bip9_softforks"]["segwit"]["status"] == "active"
|
||||
except Exception:
|
||||
logging.info('nmc: segwit is not active')
|
||||
logging.info("nmc: segwit is not active")
|
||||
|
||||
waitForRPC(btcRpc, delay_event)
|
||||
cls.btc_addr = btcRpc('getnewaddress mining_addr bech32')
|
||||
logging.info('Mining %d Bitcoin blocks to %s', num_blocks, cls.btc_addr)
|
||||
btcRpc('generatetoaddress {} {}'.format(num_blocks, cls.btc_addr))
|
||||
cls.btc_addr = btcRpc("getnewaddress mining_addr bech32")
|
||||
logging.info("Mining %d Bitcoin blocks to %s", num_blocks, cls.btc_addr)
|
||||
btcRpc("generatetoaddress {} {}".format(num_blocks, cls.btc_addr))
|
||||
|
||||
ro = btcRpc('getblockchaininfo')
|
||||
ro = btcRpc("getblockchaininfo")
|
||||
checkForks(ro)
|
||||
|
||||
ro = nmcRpc('getwalletinfo')
|
||||
print('nmcRpc', ro)
|
||||
ro = nmcRpc("getwalletinfo")
|
||||
print("nmcRpc", ro)
|
||||
|
||||
signal.signal(signal.SIGINT, signal_handler)
|
||||
cls.update_thread = threading.Thread(target=run_loop, args=(cls,))
|
||||
|
@ -354,19 +416,19 @@ class Test(unittest.TestCase):
|
|||
|
||||
# Wait for height, or sequencelock is thrown off by genesis blocktime
|
||||
num_blocks = 3
|
||||
logging.info('Waiting for Particl chain height %d', num_blocks)
|
||||
logging.info("Waiting for Particl chain height %d", num_blocks)
|
||||
for i in range(60):
|
||||
particl_blocks = cls.swap_clients[0].callrpc('getblockcount')
|
||||
print('particl_blocks', particl_blocks)
|
||||
particl_blocks = cls.swap_clients[0].callrpc("getblockcount")
|
||||
print("particl_blocks", particl_blocks)
|
||||
if particl_blocks >= num_blocks:
|
||||
break
|
||||
delay_event.wait(1)
|
||||
assert (particl_blocks >= num_blocks)
|
||||
assert particl_blocks >= num_blocks
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
global stop_test
|
||||
logging.info('Finalising')
|
||||
logging.info("Finalising")
|
||||
stop_test = True
|
||||
cls.update_thread.join()
|
||||
cls.coins_update_thread.join()
|
||||
|
@ -385,10 +447,18 @@ class Test(unittest.TestCase):
|
|||
super(Test, cls).tearDownClass()
|
||||
|
||||
def test_02_part_nmc(self):
|
||||
logging.info('---------- Test PART to NMC')
|
||||
logging.info("---------- Test PART to NMC")
|
||||
swap_clients = self.swap_clients
|
||||
|
||||
offer_id = swap_clients[0].postOffer(Coins.PART, Coins.NMC, 100 * COIN, 0.1 * COIN, 100 * COIN, SwapTypes.SELLER_FIRST, TxLockTypes.ABS_LOCK_TIME)
|
||||
offer_id = swap_clients[0].postOffer(
|
||||
Coins.PART,
|
||||
Coins.NMC,
|
||||
100 * COIN,
|
||||
0.1 * COIN,
|
||||
100 * COIN,
|
||||
SwapTypes.SELLER_FIRST,
|
||||
TxLockTypes.ABS_LOCK_TIME,
|
||||
)
|
||||
|
||||
wait_for_offer(delay_event, swap_clients[1], offer_id)
|
||||
offer = swap_clients[1].getOffer(offer_id)
|
||||
|
@ -400,19 +470,36 @@ class Test(unittest.TestCase):
|
|||
|
||||
wait_for_in_progress(delay_event, swap_clients[1], bid_id, sent=True)
|
||||
|
||||
wait_for_bid(delay_event, swap_clients[0], bid_id, BidStates.SWAP_COMPLETED, wait_for=60)
|
||||
wait_for_bid(delay_event, swap_clients[1], bid_id, BidStates.SWAP_COMPLETED, sent=True, wait_for=60)
|
||||
wait_for_bid(
|
||||
delay_event, swap_clients[0], bid_id, BidStates.SWAP_COMPLETED, wait_for=60
|
||||
)
|
||||
wait_for_bid(
|
||||
delay_event,
|
||||
swap_clients[1],
|
||||
bid_id,
|
||||
BidStates.SWAP_COMPLETED,
|
||||
sent=True,
|
||||
wait_for=60,
|
||||
)
|
||||
|
||||
js_0 = read_json_api(1800)
|
||||
js_1 = read_json_api(1801)
|
||||
assert (js_0['num_swapping'] == 0 and js_0['num_watched_outputs'] == 0)
|
||||
assert (js_1['num_swapping'] == 0 and js_1['num_watched_outputs'] == 0)
|
||||
assert js_0["num_swapping"] == 0 and js_0["num_watched_outputs"] == 0
|
||||
assert js_1["num_swapping"] == 0 and js_1["num_watched_outputs"] == 0
|
||||
|
||||
def test_03_nmc_part(self):
|
||||
logging.info('---------- Test NMC to PART')
|
||||
logging.info("---------- Test NMC to PART")
|
||||
swap_clients = self.swap_clients
|
||||
|
||||
offer_id = swap_clients[1].postOffer(Coins.NMC, Coins.PART, 10 * COIN, 9.0 * COIN, 10 * COIN, SwapTypes.SELLER_FIRST, TxLockTypes.ABS_LOCK_TIME)
|
||||
offer_id = swap_clients[1].postOffer(
|
||||
Coins.NMC,
|
||||
Coins.PART,
|
||||
10 * COIN,
|
||||
9.0 * COIN,
|
||||
10 * COIN,
|
||||
SwapTypes.SELLER_FIRST,
|
||||
TxLockTypes.ABS_LOCK_TIME,
|
||||
)
|
||||
|
||||
wait_for_offer(delay_event, swap_clients[0], offer_id)
|
||||
offer = swap_clients[0].getOffer(offer_id)
|
||||
|
@ -423,19 +510,36 @@ class Test(unittest.TestCase):
|
|||
|
||||
wait_for_in_progress(delay_event, swap_clients[0], bid_id, sent=True)
|
||||
|
||||
wait_for_bid(delay_event, swap_clients[0], bid_id, BidStates.SWAP_COMPLETED, sent=True, wait_for=60)
|
||||
wait_for_bid(delay_event, swap_clients[1], bid_id, BidStates.SWAP_COMPLETED, wait_for=60)
|
||||
wait_for_bid(
|
||||
delay_event,
|
||||
swap_clients[0],
|
||||
bid_id,
|
||||
BidStates.SWAP_COMPLETED,
|
||||
sent=True,
|
||||
wait_for=60,
|
||||
)
|
||||
wait_for_bid(
|
||||
delay_event, swap_clients[1], bid_id, BidStates.SWAP_COMPLETED, wait_for=60
|
||||
)
|
||||
|
||||
js_0 = read_json_api(1800)
|
||||
js_1 = read_json_api(1801)
|
||||
assert (js_0['num_swapping'] == 0 and js_0['num_watched_outputs'] == 0)
|
||||
assert (js_1['num_swapping'] == 0 and js_1['num_watched_outputs'] == 0)
|
||||
assert js_0["num_swapping"] == 0 and js_0["num_watched_outputs"] == 0
|
||||
assert js_1["num_swapping"] == 0 and js_1["num_watched_outputs"] == 0
|
||||
|
||||
def test_04_nmc_btc(self):
|
||||
logging.info('---------- Test NMC to BTC')
|
||||
logging.info("---------- Test NMC to BTC")
|
||||
swap_clients = self.swap_clients
|
||||
|
||||
offer_id = swap_clients[0].postOffer(Coins.NMC, Coins.BTC, 10 * COIN, 0.1 * COIN, 10 * COIN, SwapTypes.SELLER_FIRST, TxLockTypes.ABS_LOCK_TIME)
|
||||
offer_id = swap_clients[0].postOffer(
|
||||
Coins.NMC,
|
||||
Coins.BTC,
|
||||
10 * COIN,
|
||||
0.1 * COIN,
|
||||
10 * COIN,
|
||||
SwapTypes.SELLER_FIRST,
|
||||
TxLockTypes.ABS_LOCK_TIME,
|
||||
)
|
||||
|
||||
wait_for_offer(delay_event, swap_clients[1], offer_id)
|
||||
offer = swap_clients[1].getOffer(offer_id)
|
||||
|
@ -446,24 +550,39 @@ class Test(unittest.TestCase):
|
|||
|
||||
wait_for_in_progress(delay_event, swap_clients[1], bid_id, sent=True)
|
||||
|
||||
wait_for_bid(delay_event, swap_clients[0], bid_id, BidStates.SWAP_COMPLETED, wait_for=60)
|
||||
wait_for_bid(delay_event, swap_clients[1], bid_id, BidStates.SWAP_COMPLETED, sent=True, wait_for=60)
|
||||
|
||||
js_0bid = read_json_api(1800, 'bids/{}'.format(bid_id.hex()))
|
||||
wait_for_bid(
|
||||
delay_event, swap_clients[0], bid_id, BidStates.SWAP_COMPLETED, wait_for=60
|
||||
)
|
||||
wait_for_bid(
|
||||
delay_event,
|
||||
swap_clients[1],
|
||||
bid_id,
|
||||
BidStates.SWAP_COMPLETED,
|
||||
sent=True,
|
||||
wait_for=60,
|
||||
)
|
||||
|
||||
js_0 = read_json_api(1800)
|
||||
js_1 = read_json_api(1801)
|
||||
|
||||
assert (js_0['num_swapping'] == 0 and js_0['num_watched_outputs'] == 0)
|
||||
assert (js_1['num_swapping'] == 0 and js_1['num_watched_outputs'] == 0)
|
||||
assert js_0["num_swapping"] == 0 and js_0["num_watched_outputs"] == 0
|
||||
assert js_1["num_swapping"] == 0 and js_1["num_watched_outputs"] == 0
|
||||
|
||||
def test_05_refund(self):
|
||||
# Seller submits initiate txn, buyer doesn't respond
|
||||
logging.info('---------- Test refund, NMC to BTC')
|
||||
logging.info("---------- Test refund, NMC to BTC")
|
||||
swap_clients = self.swap_clients
|
||||
|
||||
offer_id = swap_clients[0].postOffer(Coins.NMC, Coins.BTC, 10 * COIN, 0.1 * COIN, 10 * COIN, SwapTypes.SELLER_FIRST,
|
||||
TxLockTypes.ABS_LOCK_BLOCKS, 10)
|
||||
offer_id = swap_clients[0].postOffer(
|
||||
Coins.NMC,
|
||||
Coins.BTC,
|
||||
10 * COIN,
|
||||
0.1 * COIN,
|
||||
10 * COIN,
|
||||
SwapTypes.SELLER_FIRST,
|
||||
TxLockTypes.ABS_LOCK_BLOCKS,
|
||||
10,
|
||||
)
|
||||
|
||||
wait_for_offer(delay_event, swap_clients[1], offer_id)
|
||||
offer = swap_clients[1].getOffer(offer_id)
|
||||
|
@ -473,21 +592,38 @@ class Test(unittest.TestCase):
|
|||
swap_clients[1].abandonBid(bid_id)
|
||||
swap_clients[0].acceptBid(bid_id)
|
||||
|
||||
wait_for_bid(delay_event, swap_clients[0], bid_id, BidStates.SWAP_COMPLETED, wait_for=60)
|
||||
wait_for_bid(delay_event, swap_clients[1], bid_id, BidStates.BID_ABANDONED, sent=True, wait_for=60)
|
||||
wait_for_bid(
|
||||
delay_event, swap_clients[0], bid_id, BidStates.SWAP_COMPLETED, wait_for=60
|
||||
)
|
||||
wait_for_bid(
|
||||
delay_event,
|
||||
swap_clients[1],
|
||||
bid_id,
|
||||
BidStates.BID_ABANDONED,
|
||||
sent=True,
|
||||
wait_for=60,
|
||||
)
|
||||
|
||||
js_0 = read_json_api(1800)
|
||||
js_1 = read_json_api(1801)
|
||||
assert (js_0['num_swapping'] == 0 and js_0['num_watched_outputs'] == 0)
|
||||
assert (js_1['num_swapping'] == 0 and js_1['num_watched_outputs'] == 0)
|
||||
assert js_0["num_swapping"] == 0 and js_0["num_watched_outputs"] == 0
|
||||
assert js_1["num_swapping"] == 0 and js_1["num_watched_outputs"] == 0
|
||||
|
||||
def test_06_self_bid(self):
|
||||
logging.info('---------- Test same client, BTC to NMC')
|
||||
logging.info("---------- Test same client, BTC to NMC")
|
||||
swap_clients = self.swap_clients
|
||||
|
||||
js_0_before = read_json_api(1800)
|
||||
|
||||
offer_id = swap_clients[0].postOffer(Coins.NMC, Coins.BTC, 10 * COIN, 10 * COIN, 10 * COIN, SwapTypes.SELLER_FIRST, TxLockTypes.ABS_LOCK_TIME)
|
||||
offer_id = swap_clients[0].postOffer(
|
||||
Coins.NMC,
|
||||
Coins.BTC,
|
||||
10 * COIN,
|
||||
10 * COIN,
|
||||
10 * COIN,
|
||||
SwapTypes.SELLER_FIRST,
|
||||
TxLockTypes.ABS_LOCK_TIME,
|
||||
)
|
||||
|
||||
wait_for_offer(delay_event, swap_clients[0], offer_id)
|
||||
offer = swap_clients[0].getOffer(offer_id)
|
||||
|
@ -496,20 +632,38 @@ class Test(unittest.TestCase):
|
|||
wait_for_bid(delay_event, swap_clients[0], bid_id)
|
||||
swap_clients[0].acceptBid(bid_id)
|
||||
|
||||
wait_for_bid_tx_state(delay_event, swap_clients[0], bid_id, TxStates.TX_REDEEMED, TxStates.TX_REDEEMED, wait_for=60)
|
||||
wait_for_bid(delay_event, swap_clients[0], bid_id, BidStates.SWAP_COMPLETED, wait_for=60)
|
||||
wait_for_bid_tx_state(
|
||||
delay_event,
|
||||
swap_clients[0],
|
||||
bid_id,
|
||||
TxStates.TX_REDEEMED,
|
||||
TxStates.TX_REDEEMED,
|
||||
wait_for=60,
|
||||
)
|
||||
wait_for_bid(
|
||||
delay_event, swap_clients[0], bid_id, BidStates.SWAP_COMPLETED, wait_for=60
|
||||
)
|
||||
|
||||
js_0 = read_json_api(1800)
|
||||
assert (js_0['num_swapping'] == 0 and js_0['num_watched_outputs'] == 0)
|
||||
assert (js_0['num_recv_bids'] == js_0_before['num_recv_bids'] + 1 and js_0['num_sent_bids'] == js_0_before['num_sent_bids'] + 1)
|
||||
assert js_0["num_swapping"] == 0 and js_0["num_watched_outputs"] == 0
|
||||
assert (
|
||||
js_0["num_recv_bids"] == js_0_before["num_recv_bids"] + 1
|
||||
and js_0["num_sent_bids"] == js_0_before["num_sent_bids"] + 1
|
||||
)
|
||||
|
||||
def test_07_error(self):
|
||||
logging.info('---------- Test error, BTC to NMC, set fee above bid value')
|
||||
logging.info("---------- Test error, BTC to NMC, set fee above bid value")
|
||||
swap_clients = self.swap_clients
|
||||
|
||||
js_0_before = read_json_api(1800)
|
||||
|
||||
offer_id = swap_clients[0].postOffer(Coins.NMC, Coins.BTC, 0.001 * COIN, 1.0 * COIN, 0.001 * COIN, SwapTypes.SELLER_FIRST, TxLockTypes.ABS_LOCK_TIME)
|
||||
offer_id = swap_clients[0].postOffer(
|
||||
Coins.NMC,
|
||||
Coins.BTC,
|
||||
0.001 * COIN,
|
||||
1.0 * COIN,
|
||||
0.001 * COIN,
|
||||
SwapTypes.SELLER_FIRST,
|
||||
TxLockTypes.ABS_LOCK_TIME,
|
||||
)
|
||||
|
||||
wait_for_offer(delay_event, swap_clients[0], offer_id)
|
||||
offer = swap_clients[0].getOffer(offer_id)
|
||||
|
@ -518,24 +672,26 @@ class Test(unittest.TestCase):
|
|||
wait_for_bid(delay_event, swap_clients[0], bid_id)
|
||||
swap_clients[0].acceptBid(bid_id)
|
||||
try:
|
||||
swap_clients[0].getChainClientSettings(Coins.BTC)['override_feerate'] = 10.0
|
||||
swap_clients[0].getChainClientSettings(Coins.NMC)['override_feerate'] = 10.0
|
||||
wait_for_bid(delay_event, swap_clients[0], bid_id, BidStates.BID_ERROR, wait_for=60)
|
||||
swap_clients[0].getChainClientSettings(Coins.BTC)["override_feerate"] = 10.0
|
||||
swap_clients[0].getChainClientSettings(Coins.NMC)["override_feerate"] = 10.0
|
||||
wait_for_bid(
|
||||
delay_event, swap_clients[0], bid_id, BidStates.BID_ERROR, wait_for=60
|
||||
)
|
||||
swap_clients[0].abandonBid(bid_id)
|
||||
finally:
|
||||
del swap_clients[0].getChainClientSettings(Coins.BTC)['override_feerate']
|
||||
del swap_clients[0].getChainClientSettings(Coins.NMC)['override_feerate']
|
||||
del swap_clients[0].getChainClientSettings(Coins.BTC)["override_feerate"]
|
||||
del swap_clients[0].getChainClientSettings(Coins.NMC)["override_feerate"]
|
||||
|
||||
def pass_99_delay(self):
|
||||
global stop_test
|
||||
logging.info('Delay')
|
||||
logging.info("Delay")
|
||||
for i in range(60 * 5):
|
||||
if stop_test:
|
||||
break
|
||||
time.sleep(1)
|
||||
print('delay', i)
|
||||
print("delay", i)
|
||||
stop_test = True
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -2,6 +2,7 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright (c) 2019-2024 tecnovert
|
||||
# Copyright (c) 2024 The Basicswap developers
|
||||
# Distributed under the MIT software license, see the accompanying
|
||||
# file LICENSE or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
|
@ -23,11 +24,11 @@ from tests.basicswap.util import (
|
|||
waitForServer,
|
||||
)
|
||||
|
||||
bin_path = os.path.expanduser(os.getenv('TEST_BIN_PATH', ''))
|
||||
test_base_path = os.path.expanduser(os.getenv('TEST_PREPARE_PATH', '~/test_basicswap'))
|
||||
test_path_plain = os.path.join(test_base_path, 'plain')
|
||||
test_path_encrypted = os.path.join(test_base_path, 'encrypted')
|
||||
test_path_encrypt = os.path.join(test_base_path, 'encrypt')
|
||||
bin_path = os.path.expanduser(os.getenv("TEST_BIN_PATH", ""))
|
||||
test_base_path = os.path.expanduser(os.getenv("TEST_PREPARE_PATH", "~/test_basicswap"))
|
||||
test_path_plain = os.path.join(test_base_path, "plain")
|
||||
test_path_encrypted = os.path.join(test_base_path, "encrypted")
|
||||
test_path_encrypt = os.path.join(test_base_path, "encrypt")
|
||||
|
||||
delay_event = threading.Event()
|
||||
logger = logging.getLogger()
|
||||
|
@ -40,7 +41,8 @@ def start_prepare(args, env_pairs=[]):
|
|||
os.environ[pair[0]] = pair[1]
|
||||
print(pair[0], os.environ[pair[0]])
|
||||
import basicswap.bin.prepare as prepareSystemThread
|
||||
with patch.object(sys, 'argv', args):
|
||||
|
||||
with patch.object(sys, "argv", args):
|
||||
prepareSystemThread.main()
|
||||
del prepareSystemThread
|
||||
|
||||
|
@ -50,7 +52,8 @@ def start_run(args, env_pairs=[]):
|
|||
os.environ[pair[0]] = pair[1]
|
||||
print(pair[0], os.environ[pair[0]])
|
||||
import basicswap.bin.run as runSystemThread
|
||||
with patch.object(sys, 'argv', args):
|
||||
|
||||
with patch.object(sys, "argv", args):
|
||||
runSystemThread.main()
|
||||
del runSystemThread
|
||||
|
||||
|
@ -63,17 +66,21 @@ class Test(unittest.TestCase):
|
|||
if os.path.exists(test_dir):
|
||||
shutil.rmtree(test_dir)
|
||||
except Exception as ex:
|
||||
logger.warning('tearDownClass %s', str(ex))
|
||||
logger.warning("tearDownClass %s", str(ex))
|
||||
super(Test, self).tearDownClass()
|
||||
|
||||
def test_plain(self):
|
||||
if os.path.exists(test_path_plain):
|
||||
shutil.rmtree(test_path_plain)
|
||||
if bin_path != '':
|
||||
if bin_path != "":
|
||||
os.makedirs(test_path_plain)
|
||||
os.symlink(bin_path, os.path.join(test_path_plain, 'bin'))
|
||||
os.symlink(bin_path, os.path.join(test_path_plain, "bin"))
|
||||
|
||||
testargs = ('basicswap-prepare', '-datadir=' + test_path_plain, '-withcoin=litecoin')
|
||||
testargs = (
|
||||
"basicswap-prepare",
|
||||
"-datadir=" + test_path_plain,
|
||||
"-withcoin=litecoin",
|
||||
)
|
||||
process = multiprocessing.Process(target=start_prepare, args=(testargs,))
|
||||
process.start()
|
||||
process.join()
|
||||
|
@ -82,50 +89,81 @@ class Test(unittest.TestCase):
|
|||
self.assertTrue(os.path.exists(config_path))
|
||||
|
||||
import basicswap.bin.prepare as prepareSystem
|
||||
|
||||
try:
|
||||
logging.info('Test no overwrite')
|
||||
testargs = ['basicswap-prepare', '-datadir=' + test_path_plain, '-withcoin=litecoin']
|
||||
with patch('sys.stderr', new=StringIO()) as fake_stderr:
|
||||
with patch.object(sys, 'argv', testargs):
|
||||
logging.info("Test no overwrite")
|
||||
testargs = [
|
||||
"basicswap-prepare",
|
||||
"-datadir=" + test_path_plain,
|
||||
"-withcoin=litecoin",
|
||||
]
|
||||
with patch("sys.stderr", new=StringIO()) as fake_stderr:
|
||||
with patch.object(sys, "argv", testargs):
|
||||
with self.assertRaises(SystemExit) as cm:
|
||||
prepareSystem.main()
|
||||
|
||||
self.assertEqual(cm.exception.code, 1)
|
||||
self.assertTrue('exists, exiting' in fake_stderr.getvalue())
|
||||
self.assertTrue("exists, exiting" in fake_stderr.getvalue())
|
||||
|
||||
logger.info('Test addcoin new')
|
||||
testargs = ['basicswap-prepare', '-datadir=' + test_path_plain, '-addcoin=namecoin']
|
||||
with patch.object(sys, 'argv', testargs):
|
||||
logger.info("Test addcoin new")
|
||||
testargs = [
|
||||
"basicswap-prepare",
|
||||
"-datadir=" + test_path_plain,
|
||||
"-addcoin=namecoin",
|
||||
]
|
||||
with patch.object(sys, "argv", testargs):
|
||||
prepareSystem.main()
|
||||
with open(config_path) as fs:
|
||||
settings = json.load(fs)
|
||||
self.assertTrue(settings['chainclients']['namecoin']['connection_type'] == 'rpc')
|
||||
self.assertTrue(
|
||||
settings["chainclients"]["namecoin"]["connection_type"] == "rpc"
|
||||
)
|
||||
|
||||
logger.info('Test disablecoin')
|
||||
testargs = ['basicswap-prepare', '-datadir=' + test_path_plain, '-disablecoin=namecoin']
|
||||
with patch.object(sys, 'argv', testargs):
|
||||
logger.info("Test disablecoin")
|
||||
testargs = [
|
||||
"basicswap-prepare",
|
||||
"-datadir=" + test_path_plain,
|
||||
"-disablecoin=namecoin",
|
||||
]
|
||||
with patch.object(sys, "argv", testargs):
|
||||
prepareSystem.main()
|
||||
with open(config_path) as fs:
|
||||
settings = json.load(fs)
|
||||
self.assertTrue(settings['chainclients']['namecoin']['connection_type'] == 'none')
|
||||
self.assertTrue(
|
||||
settings["chainclients"]["namecoin"]["connection_type"] == "none"
|
||||
)
|
||||
|
||||
logger.info('Test addcoin existing')
|
||||
testargs = ['basicswap-prepare', '-datadir=' + test_path_plain, '-addcoin=namecoin']
|
||||
with patch.object(sys, 'argv', testargs):
|
||||
logger.info("Test addcoin existing")
|
||||
testargs = [
|
||||
"basicswap-prepare",
|
||||
"-datadir=" + test_path_plain,
|
||||
"-addcoin=namecoin",
|
||||
]
|
||||
with patch.object(sys, "argv", testargs):
|
||||
prepareSystem.main()
|
||||
with open(config_path) as fs:
|
||||
settings = json.load(fs)
|
||||
self.assertTrue(settings['chainclients']['namecoin']['connection_type'] == 'rpc')
|
||||
self.assertTrue(
|
||||
settings["chainclients"]["namecoin"]["connection_type"] == "rpc"
|
||||
)
|
||||
|
||||
logging.info('notorproxy')
|
||||
testargs = ['basicswap-prepare', '-datadir=' + test_path_plain, '-addcoin=firo', '--usetorproxy', '--notorproxy']
|
||||
with patch('sys.stderr', new=StringIO()) as fake_stderr:
|
||||
with patch.object(sys, 'argv', testargs):
|
||||
logging.info("notorproxy")
|
||||
testargs = [
|
||||
"basicswap-prepare",
|
||||
"-datadir=" + test_path_plain,
|
||||
"-addcoin=firo",
|
||||
"--usetorproxy",
|
||||
"--notorproxy",
|
||||
]
|
||||
with patch("sys.stderr", new=StringIO()) as fake_stderr:
|
||||
with patch.object(sys, "argv", testargs):
|
||||
with self.assertRaises(SystemExit) as cm:
|
||||
prepareSystem.main()
|
||||
|
||||
self.assertEqual(cm.exception.code, 1)
|
||||
self.assertTrue('--usetorproxy and --notorproxy together' in fake_stderr.getvalue())
|
||||
self.assertTrue(
|
||||
"--usetorproxy and --notorproxy together" in fake_stderr.getvalue()
|
||||
)
|
||||
|
||||
finally:
|
||||
del prepareSystem
|
||||
|
@ -133,81 +171,114 @@ class Test(unittest.TestCase):
|
|||
def test_encrypted(self):
|
||||
if os.path.exists(test_path_encrypted):
|
||||
shutil.rmtree(test_path_encrypted)
|
||||
if bin_path != '':
|
||||
if bin_path != "":
|
||||
os.makedirs(test_path_encrypted)
|
||||
os.symlink(bin_path, os.path.join(test_path_encrypted, 'bin'))
|
||||
os.symlink(bin_path, os.path.join(test_path_encrypted, "bin"))
|
||||
|
||||
env_vars = [('WALLET_ENCRYPTION_PWD', 'test123'), ]
|
||||
testargs = ('basicswap-prepare', '-datadir=' + test_path_encrypted, '-withcoin=litecoin,monero')
|
||||
process = multiprocessing.Process(target=start_prepare, args=(testargs, env_vars))
|
||||
env_vars = [
|
||||
("WALLET_ENCRYPTION_PWD", "test123"),
|
||||
]
|
||||
testargs = (
|
||||
"basicswap-prepare",
|
||||
"-datadir=" + test_path_encrypted,
|
||||
"-withcoin=litecoin,monero",
|
||||
)
|
||||
process = multiprocessing.Process(
|
||||
target=start_prepare, args=(testargs, env_vars)
|
||||
)
|
||||
process.start()
|
||||
process.join()
|
||||
assert (process.exitcode == 0)
|
||||
assert process.exitcode == 0
|
||||
|
||||
logger.info('Should not be able to add a coin without setting WALLET_ENCRYPTION_PWD')
|
||||
testargs = ('basicswap-prepare', '-datadir=' + test_path_encrypted, '-addcoin=bitcoin')
|
||||
logger.info(
|
||||
"Should not be able to add a coin without setting WALLET_ENCRYPTION_PWD"
|
||||
)
|
||||
testargs = (
|
||||
"basicswap-prepare",
|
||||
"-datadir=" + test_path_encrypted,
|
||||
"-addcoin=bitcoin",
|
||||
)
|
||||
process = multiprocessing.Process(target=start_prepare, args=(testargs, []))
|
||||
process.start()
|
||||
process.join()
|
||||
assert (process.exitcode == 1)
|
||||
assert process.exitcode == 1
|
||||
|
||||
testargs = ('basicswap-prepare', '-datadir=' + test_path_encrypted, '-addcoin=bitcoin')
|
||||
process = multiprocessing.Process(target=start_prepare, args=(testargs, env_vars))
|
||||
testargs = (
|
||||
"basicswap-prepare",
|
||||
"-datadir=" + test_path_encrypted,
|
||||
"-addcoin=bitcoin",
|
||||
)
|
||||
process = multiprocessing.Process(
|
||||
target=start_prepare, args=(testargs, env_vars)
|
||||
)
|
||||
process.start()
|
||||
process.join()
|
||||
assert (process.exitcode == 0)
|
||||
assert process.exitcode == 0
|
||||
|
||||
def test_encrypt(self):
|
||||
if os.path.exists(test_path_encrypt):
|
||||
shutil.rmtree(test_path_encrypt)
|
||||
if bin_path != '':
|
||||
if bin_path != "":
|
||||
os.makedirs(test_path_encrypt)
|
||||
os.symlink(bin_path, os.path.join(test_path_encrypt, 'bin'))
|
||||
os.symlink(bin_path, os.path.join(test_path_encrypt, "bin"))
|
||||
|
||||
testargs = ('basicswap-prepare', '-regtest=1', '-datadir=' + test_path_encrypt, '-withcoin=litecoin,monero')
|
||||
process = multiprocessing.Process(target=start_prepare, args=(testargs, ))
|
||||
testargs = (
|
||||
"basicswap-prepare",
|
||||
"-regtest=1",
|
||||
"-datadir=" + test_path_encrypt,
|
||||
"-withcoin=litecoin,monero",
|
||||
)
|
||||
process = multiprocessing.Process(target=start_prepare, args=(testargs,))
|
||||
process.start()
|
||||
process.join()
|
||||
assert (process.exitcode == 0)
|
||||
assert process.exitcode == 0
|
||||
|
||||
logger.info('basicswap-run should fail if WALLET_ENCRYPTION_PWD is set')
|
||||
env_vars = [('WALLET_ENCRYPTION_PWD', 'test123'), ]
|
||||
testargs = ('basicswap-run', '-regtest=1', '-datadir=' + test_path_encrypt)
|
||||
logger.info("basicswap-run should fail if WALLET_ENCRYPTION_PWD is set")
|
||||
env_vars = [
|
||||
("WALLET_ENCRYPTION_PWD", "test123"),
|
||||
]
|
||||
testargs = ("basicswap-run", "-regtest=1", "-datadir=" + test_path_encrypt)
|
||||
process = multiprocessing.Process(target=start_run, args=(testargs, env_vars))
|
||||
process.start()
|
||||
process.join()
|
||||
assert (process.exitcode == 1)
|
||||
assert process.exitcode == 1
|
||||
|
||||
testargs = ('basicswap-run', '-regtest=1', '-datadir=' + test_path_encrypt)
|
||||
process = multiprocessing.Process(target=start_run, args=(testargs, ))
|
||||
testargs = ("basicswap-run", "-regtest=1", "-datadir=" + test_path_encrypt)
|
||||
process = multiprocessing.Process(target=start_run, args=(testargs,))
|
||||
process.start()
|
||||
|
||||
waitForServer(delay_event, 12700)
|
||||
rv = read_json_api(12700, 'setpassword', {'oldpassword': 'wrongpass', 'newpassword': 'test123'})
|
||||
assert ('error' in rv)
|
||||
rv = read_json_api(
|
||||
12700, "setpassword", {"oldpassword": "wrongpass", "newpassword": "test123"}
|
||||
)
|
||||
assert "error" in rv
|
||||
|
||||
rv = read_json_api(12700, 'setpassword', {'oldpassword': '', 'newpassword': 'test123'})
|
||||
assert ('success' in rv)
|
||||
rv = read_json_api(
|
||||
12700, "setpassword", {"oldpassword": "", "newpassword": "test123"}
|
||||
)
|
||||
assert "success" in rv
|
||||
|
||||
rv = read_json_api(12700, 'setpassword', {'oldpassword': 'test123', 'newpassword': 'next123'})
|
||||
assert ('success' in rv)
|
||||
rv = read_json_api(
|
||||
12700, "setpassword", {"oldpassword": "test123", "newpassword": "next123"}
|
||||
)
|
||||
assert "success" in rv
|
||||
|
||||
rv = read_json_api(12700, 'lock')
|
||||
assert ('success' in rv)
|
||||
rv = read_json_api(12700, "lock")
|
||||
assert "success" in rv
|
||||
|
||||
rv = read_json_api(12700, 'wallets')
|
||||
assert ('error' in rv)
|
||||
rv = read_json_api(12700, "wallets")
|
||||
assert "error" in rv
|
||||
|
||||
rv = read_json_api(12700, 'unlock', {'password': 'next123'})
|
||||
assert ('success' in rv)
|
||||
rv = read_json_api(12700, "unlock", {"password": "next123"})
|
||||
assert "success" in rv
|
||||
|
||||
rv = read_json_api(12700, 'wallets')
|
||||
assert ('PART' in rv)
|
||||
rv = read_json_api(12700, "wallets")
|
||||
assert "PART" in rv
|
||||
|
||||
process.terminate()
|
||||
process.join()
|
||||
assert (process.exitcode == 0)
|
||||
assert process.exitcode == 0
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -2,6 +2,7 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright (c) 2020-2022 tecnovert
|
||||
# Copyright (c) 2024 The Basicswap developers
|
||||
# Distributed under the MIT software license, see the accompanying
|
||||
# file LICENSE or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
|
@ -36,7 +37,7 @@ from tests.basicswap.common_xmr import (
|
|||
)
|
||||
import basicswap.bin.run as runSystem
|
||||
|
||||
TEST_PATH = os.path.expanduser(os.getenv('TEST_PATH', '~/test_basicswap1'))
|
||||
TEST_PATH = os.path.expanduser(os.getenv("TEST_PATH", "~/test_basicswap1"))
|
||||
|
||||
logger = logging.getLogger()
|
||||
logger.level = logging.DEBUG
|
||||
|
@ -52,21 +53,21 @@ class Test(unittest.TestCase):
|
|||
cls.delay_event = threading.Event()
|
||||
|
||||
# Load both wallets from the same mnemonic
|
||||
bins_path = os.path.join(TEST_PATH, 'bin')
|
||||
bins_path = os.path.join(TEST_PATH, "bin")
|
||||
for i in range(2):
|
||||
logging.info('Preparing node: %d.', i)
|
||||
client_path = os.path.join(TEST_PATH, 'client{}'.format(i))
|
||||
logging.info("Preparing node: %d.", i)
|
||||
client_path = os.path.join(TEST_PATH, "client{}".format(i))
|
||||
try:
|
||||
shutil.rmtree(client_path)
|
||||
except Exception as ex:
|
||||
logging.warning('setUpClass %s', str(ex))
|
||||
logging.warning("setUpClass %s", str(ex))
|
||||
|
||||
run_prepare(i, client_path, bins_path, 'monero,bitcoin', mnemonics[0])
|
||||
run_prepare(i, client_path, bins_path, "monero,bitcoin", mnemonics[0])
|
||||
|
||||
def run_thread(self, client_id):
|
||||
client_path = os.path.join(TEST_PATH, 'client{}'.format(client_id))
|
||||
testargs = ['basicswap-run', '-datadir=' + client_path, '-regtest']
|
||||
with patch.object(sys, 'argv', testargs):
|
||||
client_path = os.path.join(TEST_PATH, "client{}".format(client_id))
|
||||
testargs = ["basicswap-run", "-datadir=" + client_path, "-regtest"]
|
||||
with patch.object(sys, "argv", testargs):
|
||||
runSystem.main()
|
||||
|
||||
def test_wallet(self):
|
||||
|
@ -81,20 +82,25 @@ class Test(unittest.TestCase):
|
|||
try:
|
||||
waitForServer(self.delay_event, 12700)
|
||||
|
||||
wallets_0 = read_json_api(12700, 'wallets')
|
||||
assert (wallets_0['PART']['expected_seed'] is True)
|
||||
assert (wallets_0['XMR']['expected_seed'] is True)
|
||||
wallets_0 = read_json_api(12700, "wallets")
|
||||
assert wallets_0["PART"]["expected_seed"] is True
|
||||
assert wallets_0["XMR"]["expected_seed"] is True
|
||||
|
||||
waitForServer(self.delay_event, 12701)
|
||||
wallets_1 = read_json_api(12701, 'wallets')
|
||||
wallets_1 = read_json_api(12701, "wallets")
|
||||
|
||||
assert (wallets_0['PART']['expected_seed'] is True)
|
||||
assert (wallets_1['XMR']['expected_seed'] is True)
|
||||
assert wallets_0["PART"]["expected_seed"] is True
|
||||
assert wallets_1["XMR"]["expected_seed"] is True
|
||||
|
||||
# TODO: Check other coins
|
||||
|
||||
assert (wallets_0['PART']['deposit_address'] == wallets_1['1']['deposit_address'])
|
||||
assert (wallets_0['XMR']['deposit_address'] == wallets_1['6']['deposit_address'])
|
||||
assert (
|
||||
wallets_0["PART"]["deposit_address"]
|
||||
== wallets_1["1"]["deposit_address"]
|
||||
)
|
||||
assert (
|
||||
wallets_0["XMR"]["deposit_address"] == wallets_1["6"]["deposit_address"]
|
||||
)
|
||||
except Exception:
|
||||
traceback.print_exc()
|
||||
|
||||
|
@ -106,5 +112,5 @@ class Test(unittest.TestCase):
|
|||
p.join()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright (c) 2022 tecnovert
|
||||
# Copyright (c) 2024 The Basicswap developers
|
||||
# Distributed under the MIT software license, see the accompanying
|
||||
# file LICENSE or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
|
@ -50,10 +51,10 @@ from tests.basicswap.common import (
|
|||
LTC_BASE_RPC_PORT,
|
||||
)
|
||||
|
||||
PORT_OFS = int(os.getenv('PORT_OFS', 1))
|
||||
TEST_PATH = os.path.expanduser(os.getenv('TEST_PATH', '~/test_basicswap1'))
|
||||
LITECOIN_RPC_PORT_BASE = int(os.getenv('LITECOIN_RPC_PORT_BASE', LTC_BASE_RPC_PORT))
|
||||
BITCOIN_RPC_PORT_BASE = int(os.getenv('BITCOIN_RPC_PORT_BASE', BTC_BASE_RPC_PORT))
|
||||
PORT_OFS = int(os.getenv("PORT_OFS", 1))
|
||||
TEST_PATH = os.path.expanduser(os.getenv("TEST_PATH", "~/test_basicswap1"))
|
||||
LITECOIN_RPC_PORT_BASE = int(os.getenv("LITECOIN_RPC_PORT_BASE", LTC_BASE_RPC_PORT))
|
||||
BITCOIN_RPC_PORT_BASE = int(os.getenv("BITCOIN_RPC_PORT_BASE", BTC_BASE_RPC_PORT))
|
||||
|
||||
logger = logging.getLogger()
|
||||
logger.level = logging.DEBUG
|
||||
|
@ -61,32 +62,44 @@ if not len(logger.handlers):
|
|||
logger.addHandler(logging.StreamHandler(sys.stdout))
|
||||
|
||||
|
||||
def callbtcnoderpc(node_id, method, params=[], wallet=None, base_rpc_port=BITCOIN_RPC_PORT_BASE):
|
||||
auth = 'test_btc_{0}:test_btc_pwd_{0}'.format(node_id)
|
||||
def callbtcnoderpc(
|
||||
node_id, method, params=[], wallet=None, base_rpc_port=BITCOIN_RPC_PORT_BASE
|
||||
):
|
||||
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=LITECOIN_RPC_PORT_BASE):
|
||||
auth = 'test_ltc_{0}:test_ltc_pwd_{0}'.format(node_id)
|
||||
def callltcnoderpc(
|
||||
node_id, method, params=[], wallet=None, base_rpc_port=LITECOIN_RPC_PORT_BASE
|
||||
):
|
||||
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])
|
||||
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):
|
||||
logging.info('Preparing node: %d.', node_id)
|
||||
bins_path = os.path.join(TEST_PATH, 'bin')
|
||||
client_path = os.path.join(TEST_PATH, 'client{}'.format(node_id))
|
||||
logging.info("Preparing node: %d.", node_id)
|
||||
bins_path = os.path.join(TEST_PATH, "bin")
|
||||
client_path = os.path.join(TEST_PATH, "client{}".format(node_id))
|
||||
try:
|
||||
shutil.rmtree(client_path)
|
||||
except Exception as ex:
|
||||
logging.warning('setUpClass %s', str(ex))
|
||||
return run_prepare(node_id, client_path, bins_path, 'monero,bitcoin,litecoin', mnemonic, 3, use_rpcauth=True)
|
||||
logging.warning("setUpClass %s", str(ex))
|
||||
return run_prepare(
|
||||
node_id,
|
||||
client_path,
|
||||
bins_path,
|
||||
"monero,bitcoin,litecoin",
|
||||
mnemonic,
|
||||
3,
|
||||
use_rpcauth=True,
|
||||
)
|
||||
|
||||
|
||||
class Test(TestBase):
|
||||
|
@ -100,9 +113,9 @@ class Test(TestBase):
|
|||
cls.used_mnemonics.append(prepare_node(i, mnemonics[0] if i == 0 else None))
|
||||
|
||||
def run_thread(self, client_id):
|
||||
client_path = os.path.join(TEST_PATH, 'client{}'.format(client_id))
|
||||
testargs = ['basicswap-run', '-datadir=' + client_path, '-regtest']
|
||||
with patch.object(sys, 'argv', testargs):
|
||||
client_path = os.path.join(TEST_PATH, "client{}".format(client_id))
|
||||
testargs = ["basicswap-run", "-datadir=" + client_path, "-regtest"]
|
||||
with patch.object(sys, "argv", testargs):
|
||||
runSystem.main()
|
||||
|
||||
def finalise(self, processes):
|
||||
|
@ -127,19 +140,25 @@ class Test(TestBase):
|
|||
waitForServer(self.delay_event, 12702)
|
||||
|
||||
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])
|
||||
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'], wallet='wallet.dat')
|
||||
logging.info('Mining %d Litecoin blocks to %s', num_blocks, self.ltc_addr)
|
||||
callltcnoderpc(1, 'generatetoaddress', [num_blocks, self.ltc_addr])
|
||||
self.ltc_addr = callltcnoderpc(
|
||||
1, "getnewaddress", ["mining_addr", "bech32"], wallet="wallet.dat"
|
||||
)
|
||||
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'], wallet='mweb')
|
||||
callltcnoderpc(1, 'sendtoaddress', [mweb_addr, 1], wallet='wallet.dat')
|
||||
mweb_addr = callltcnoderpc(
|
||||
1, "getnewaddress", ["mweb_addr", "mweb"], wallet="mweb"
|
||||
)
|
||||
callltcnoderpc(1, "sendtoaddress", [mweb_addr, 1], wallet="wallet.dat")
|
||||
num_blocks = 69
|
||||
callltcnoderpc(1, 'generatetoaddress', [num_blocks, self.ltc_addr])
|
||||
callltcnoderpc(1, "generatetoaddress", [num_blocks, self.ltc_addr])
|
||||
|
||||
self.update_thread = threading.Thread(target=updateThread, args=(self,))
|
||||
self.update_thread.start()
|
||||
|
@ -147,36 +166,35 @@ class Test(TestBase):
|
|||
self.wait_for_particl_height(12701, num_blocks=3)
|
||||
|
||||
data = {
|
||||
'addr_from': '-1',
|
||||
'coin_from': 'part',
|
||||
'coin_to': 'ltc',
|
||||
'amt_from': '1',
|
||||
'amt_to': '1',
|
||||
'lockhrs': '24',
|
||||
'automation_strat_id': 1}
|
||||
"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']
|
||||
post_json_api(12700, "offers/new", data)["offer_id"]
|
||||
summary = read_json_api(12700)
|
||||
assert (summary['num_sent_offers'] == 1)
|
||||
assert summary["num_sent_offers"] == 1
|
||||
|
||||
logger.info('Waiting for offer')
|
||||
logger.info("Waiting for offer")
|
||||
waitForNumOffers(self.delay_event, 12701, 1)
|
||||
|
||||
offers = read_json_api(12701, 'offers')
|
||||
offers = read_json_api(12701, "offers")
|
||||
offer = offers[0]
|
||||
|
||||
data = {
|
||||
'offer_id': offer['offer_id'],
|
||||
'amount_from': offer['amount_from']}
|
||||
data = {"offer_id": offer["offer_id"], "amount_from": offer["amount_from"]}
|
||||
|
||||
bid_id = post_json_api(12701, 'bids/new', data)['bid_id']
|
||||
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', wait_for=120)
|
||||
waitForBidState(self.delay_event, 12701, bid_id, 'Completed', wait_for=120)
|
||||
waitForBidState(self.delay_event, 12700, bid_id, "Completed", wait_for=120)
|
||||
waitForBidState(self.delay_event, 12701, bid_id, "Completed", wait_for=120)
|
||||
|
||||
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])
|
||||
processes.append(multiprocessing.Process(target=self.run_thread, args=(3,)))
|
||||
processes[-1].start()
|
||||
|
@ -186,30 +204,32 @@ class Test(TestBase):
|
|||
|
||||
# TODO: Attempt to detect past swaps
|
||||
|
||||
for coin in ('part', 'btc', 'ltc'):
|
||||
logging.info(f'Checking {coin} balance')
|
||||
original = read_json_api(12700, f'wallets/{coin}')
|
||||
restored = read_json_api(12703, f'wallets/{coin}')
|
||||
assert (float(original['balance']) + float(original['unconfirmed']) == float(restored['balance']) + float(restored['unconfirmed']))
|
||||
for coin in ("part", "btc", "ltc"):
|
||||
logging.info(f"Checking {coin} balance")
|
||||
original = read_json_api(12700, f"wallets/{coin}")
|
||||
restored = read_json_api(12703, f"wallets/{coin}")
|
||||
assert float(original["balance"]) + float(
|
||||
original["unconfirmed"]
|
||||
) == float(restored["balance"]) + float(restored["unconfirmed"])
|
||||
|
||||
wallets_original = read_json_api(12700, 'wallets')
|
||||
wallets_original = read_json_api(12700, "wallets")
|
||||
# TODO: After restoring a new deposit address should be generated, should be automated
|
||||
# Swaps should use a new key path, not the external path
|
||||
next_addr = read_json_api(12700, 'wallets/part/nextdepositaddr')
|
||||
next_addr = read_json_api(12703, 'wallets/part/nextdepositaddr')
|
||||
wallets_restored = read_json_api(12703, 'wallets')
|
||||
_ = read_json_api(12700, "wallets/part/nextdepositaddr")
|
||||
_ = read_json_api(12703, "wallets/part/nextdepositaddr")
|
||||
wallets_restored = read_json_api(12703, "wallets")
|
||||
for k, w in wallets_original.items():
|
||||
assert (w['deposit_address'] == wallets_restored[k]['deposit_address'])
|
||||
assert w["deposit_address"] == wallets_restored[k]["deposit_address"]
|
||||
|
||||
except Exception as e:
|
||||
traceback.print_exc()
|
||||
self.finalise(processes)
|
||||
logging.info('Test failed.')
|
||||
logging.info("Test failed.")
|
||||
raise e
|
||||
|
||||
self.finalise(processes)
|
||||
logging.info('Test passed.')
|
||||
logging.info("Test passed.")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright (c) 2024 tecnovert
|
||||
# Copyright (c) 2024 The Basicswap developers
|
||||
# Distributed under the MIT software license, see the accompanying
|
||||
# file LICENSE or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
|
@ -30,9 +30,11 @@ from tests.basicswap.extended.test_dcr import (
|
|||
|
||||
NUM_NODES = 3
|
||||
|
||||
WOW_BINDIR = os.path.expanduser(os.getenv('WOW_BINDIR', os.path.join(cfg.DEFAULT_TEST_BINDIR, 'wownero')))
|
||||
WOWD = os.getenv('WOWD', 'wownerod' + cfg.bin_suffix)
|
||||
WOW_WALLET_RPC = os.getenv('WOW_WALLET', 'wownero-wallet-rpc' + cfg.bin_suffix)
|
||||
WOW_BINDIR = os.path.expanduser(
|
||||
os.getenv("WOW_BINDIR", os.path.join(cfg.DEFAULT_TEST_BINDIR, "wownero"))
|
||||
)
|
||||
WOWD = os.getenv("WOWD", "wownerod" + cfg.bin_suffix)
|
||||
WOW_WALLET_RPC = os.getenv("WOW_WALLET", "wownero-wallet-rpc" + cfg.bin_suffix)
|
||||
|
||||
WOW_BASE_PORT = 54932
|
||||
WOW_BASE_RPC_PORT = 55932
|
||||
|
@ -41,45 +43,52 @@ WOW_BASE_ZMQ_PORT = 55972
|
|||
|
||||
|
||||
def prepareWOWDataDir(datadir, node_id, conf_file):
|
||||
node_dir = os.path.join(datadir, 'wow_' + str(node_id))
|
||||
node_dir = os.path.join(datadir, "wow_" + str(node_id))
|
||||
if not os.path.exists(node_dir):
|
||||
os.makedirs(node_dir)
|
||||
cfg_file_path = os.path.join(node_dir, conf_file)
|
||||
if os.path.exists(cfg_file_path):
|
||||
return
|
||||
with open(cfg_file_path, 'w+') as fp:
|
||||
fp.write('regtest=1\n')
|
||||
fp.write('log-level=4\n')
|
||||
fp.write('keep-fakechain=1\n')
|
||||
fp.write('data-dir={}\n'.format(node_dir))
|
||||
fp.write('fixed-difficulty=1\n')
|
||||
fp.write('p2p-bind-port={}\n'.format(WOW_BASE_PORT + node_id))
|
||||
fp.write('rpc-bind-port={}\n'.format(WOW_BASE_RPC_PORT + node_id))
|
||||
fp.write('p2p-bind-ip=127.0.0.1\n')
|
||||
fp.write('rpc-bind-ip=127.0.0.1\n')
|
||||
fp.write('prune-blockchain=1\n')
|
||||
fp.write('zmq-rpc-bind-port={}\n'.format(WOW_BASE_ZMQ_PORT + node_id))
|
||||
fp.write('zmq-rpc-bind-ip=127.0.0.1\n')
|
||||
with open(cfg_file_path, "w+") as fp:
|
||||
fp.write("regtest=1\n")
|
||||
fp.write("log-level=4\n")
|
||||
fp.write("keep-fakechain=1\n")
|
||||
fp.write("data-dir={}\n".format(node_dir))
|
||||
fp.write("fixed-difficulty=1\n")
|
||||
fp.write("p2p-bind-port={}\n".format(WOW_BASE_PORT + node_id))
|
||||
fp.write("rpc-bind-port={}\n".format(WOW_BASE_RPC_PORT + node_id))
|
||||
fp.write("p2p-bind-ip=127.0.0.1\n")
|
||||
fp.write("rpc-bind-ip=127.0.0.1\n")
|
||||
fp.write("prune-blockchain=1\n")
|
||||
fp.write("zmq-rpc-bind-port={}\n".format(WOW_BASE_ZMQ_PORT + node_id))
|
||||
fp.write("zmq-rpc-bind-ip=127.0.0.1\n")
|
||||
|
||||
for i in range(0, NUM_NODES):
|
||||
if node_id == i:
|
||||
continue
|
||||
fp.write('add-exclusive-node=127.0.0.1:{}\n'.format(WOW_BASE_PORT + i))
|
||||
fp.write("add-exclusive-node=127.0.0.1:{}\n".format(WOW_BASE_PORT + i))
|
||||
|
||||
|
||||
def waitForWOWNode(rpc_offset, max_tries=7, auth=None):
|
||||
for i in range(max_tries + 1):
|
||||
try:
|
||||
if auth is None:
|
||||
callrpc_xmr(WOW_BASE_RPC_PORT + rpc_offset, 'get_block_count')
|
||||
callrpc_xmr(WOW_BASE_RPC_PORT + rpc_offset, "get_block_count")
|
||||
else:
|
||||
callrpc_xmr(WOW_BASE_WALLET_RPC_PORT + rpc_offset, 'get_languages', auth=auth)
|
||||
callrpc_xmr(
|
||||
WOW_BASE_WALLET_RPC_PORT + rpc_offset, "get_languages", auth=auth
|
||||
)
|
||||
return
|
||||
except Exception as ex:
|
||||
if i < max_tries:
|
||||
logging.warning('Can\'t connect to WOW%s RPC: %s. Retrying in %d second/s.', '' if auth is None else ' wallet', str(ex), (i + 1))
|
||||
logging.warning(
|
||||
"Can't connect to WOW%s RPC: %s. Retrying in %d second/s.",
|
||||
"" if auth is None else " wallet",
|
||||
str(ex),
|
||||
(i + 1),
|
||||
)
|
||||
time.sleep(i + 1)
|
||||
raise ValueError('waitForWOWNode failed')
|
||||
raise ValueError("waitForWOWNode failed")
|
||||
|
||||
|
||||
class Test(BaseTest):
|
||||
|
@ -96,15 +105,22 @@ class Test(BaseTest):
|
|||
def prepareExtraCoins(cls):
|
||||
pass
|
||||
num_blocks = 300
|
||||
cls.wow_addr = cls.callwownodewallet(cls, 1, 'get_address')['address']
|
||||
if callrpc_xmr(WOW_BASE_RPC_PORT + 1, 'get_block_count')['count'] < num_blocks:
|
||||
logging.info('Mining %d Wownero blocks to %s.', num_blocks, cls.wow_addr)
|
||||
callrpc_xmr(WOW_BASE_RPC_PORT + 1, 'generateblocks', {'wallet_address': cls.wow_addr, 'amount_of_blocks': num_blocks})
|
||||
logging.info('WOW blocks: %d', callrpc_xmr(WOW_BASE_RPC_PORT + 1, 'get_block_count')['count'])
|
||||
cls.wow_addr = cls.callwownodewallet(cls, 1, "get_address")["address"]
|
||||
if callrpc_xmr(WOW_BASE_RPC_PORT + 1, "get_block_count")["count"] < num_blocks:
|
||||
logging.info("Mining %d Wownero blocks to %s.", num_blocks, cls.wow_addr)
|
||||
callrpc_xmr(
|
||||
WOW_BASE_RPC_PORT + 1,
|
||||
"generateblocks",
|
||||
{"wallet_address": cls.wow_addr, "amount_of_blocks": num_blocks},
|
||||
)
|
||||
logging.info(
|
||||
"WOW blocks: %d",
|
||||
callrpc_xmr(WOW_BASE_RPC_PORT + 1, "get_block_count")["count"],
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
logging.info('Finalising Wownero Test')
|
||||
logging.info("Finalising Wownero Test")
|
||||
super(Test, cls).tearDownClass()
|
||||
|
||||
stopDaemons(cls.wow_daemons)
|
||||
|
@ -115,38 +131,51 @@ class Test(BaseTest):
|
|||
super(Test, cls).coins_loop()
|
||||
|
||||
if cls.wow_addr is not None:
|
||||
callrpc_xmr(WOW_BASE_RPC_PORT + 0, 'generateblocks', {'wallet_address': cls.wow_addr, 'amount_of_blocks': 1})
|
||||
callrpc_xmr(
|
||||
WOW_BASE_RPC_PORT + 0,
|
||||
"generateblocks",
|
||||
{"wallet_address": cls.wow_addr, "amount_of_blocks": 1},
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def prepareExtraDataDir(cls, i):
|
||||
if not cls.restore_instance:
|
||||
prepareWOWDataDir(cfg.TEST_DATADIRS, i, 'wownerod.conf')
|
||||
prepareWOWDataDir(cfg.TEST_DATADIRS, i, "wownerod.conf")
|
||||
|
||||
node_dir = os.path.join(cfg.TEST_DATADIRS, 'wow_' + str(i))
|
||||
node_dir = os.path.join(cfg.TEST_DATADIRS, "wow_" + str(i))
|
||||
cls.wow_daemons.append(startXmrDaemon(node_dir, WOW_BINDIR, WOWD))
|
||||
logging.info('Started %s %d', WOWD, cls.wow_daemons[-1].handle.pid)
|
||||
logging.info("Started %s %d", WOWD, cls.wow_daemons[-1].handle.pid)
|
||||
waitForWOWNode(i)
|
||||
|
||||
opts = [
|
||||
'--daemon-address=127.0.0.1:{}'.format(WOW_BASE_RPC_PORT + i),
|
||||
'--no-dns',
|
||||
'--rpc-bind-port={}'.format(WOW_BASE_WALLET_RPC_PORT + i),
|
||||
'--wallet-dir={}'.format(os.path.join(node_dir, 'wallets')),
|
||||
'--log-file={}'.format(os.path.join(node_dir, 'wallet.log')),
|
||||
'--rpc-login=test{0}:test_pass{0}'.format(i),
|
||||
'--wow-shared-ringdb-dir={}'.format(os.path.join(node_dir, 'shared-ringdb')),
|
||||
'--allow-mismatched-daemon-version',
|
||||
"--daemon-address=127.0.0.1:{}".format(WOW_BASE_RPC_PORT + i),
|
||||
"--no-dns",
|
||||
"--rpc-bind-port={}".format(WOW_BASE_WALLET_RPC_PORT + i),
|
||||
"--wallet-dir={}".format(os.path.join(node_dir, "wallets")),
|
||||
"--log-file={}".format(os.path.join(node_dir, "wallet.log")),
|
||||
"--rpc-login=test{0}:test_pass{0}".format(i),
|
||||
"--wow-shared-ringdb-dir={}".format(
|
||||
os.path.join(node_dir, "shared-ringdb")
|
||||
),
|
||||
"--allow-mismatched-daemon-version",
|
||||
]
|
||||
cls.wow_daemons.append(startXmrWalletDaemon(node_dir, WOW_BINDIR, WOW_WALLET_RPC, opts=opts))
|
||||
cls.wow_daemons.append(
|
||||
startXmrWalletDaemon(node_dir, WOW_BINDIR, WOW_WALLET_RPC, opts=opts)
|
||||
)
|
||||
|
||||
cls.wow_wallet_auth.append(('test{0}'.format(i), 'test_pass{0}'.format(i)))
|
||||
cls.wow_wallet_auth.append(("test{0}".format(i), "test_pass{0}".format(i)))
|
||||
|
||||
waitForWOWNode(i, auth=cls.wow_wallet_auth[i])
|
||||
|
||||
if not cls.restore_instance:
|
||||
logging.info('Creating WOW wallet %i', i)
|
||||
cls.callwownodewallet(cls, i, 'create_wallet', {'filename': 'testwallet', 'language': 'English'})
|
||||
cls.callwownodewallet(cls, i, 'open_wallet', {'filename': 'testwallet'})
|
||||
logging.info("Creating WOW wallet %i", i)
|
||||
cls.callwownodewallet(
|
||||
cls,
|
||||
i,
|
||||
"create_wallet",
|
||||
{"filename": "testwallet", "language": "English"},
|
||||
)
|
||||
cls.callwownodewallet(cls, i, "open_wallet", {"filename": "testwallet"})
|
||||
|
||||
@classmethod
|
||||
def addPIDInfo(cls, sc, i):
|
||||
|
@ -154,20 +183,25 @@ class Test(BaseTest):
|
|||
|
||||
@classmethod
|
||||
def addCoinSettings(cls, settings, datadir, node_id):
|
||||
settings['chainclients']['wownero'] = {
|
||||
'connection_type': 'rpc',
|
||||
'manage_daemon': False,
|
||||
'rpcport': WOW_BASE_RPC_PORT + node_id,
|
||||
'walletrpcport': WOW_BASE_WALLET_RPC_PORT + node_id,
|
||||
'walletrpcuser': 'test' + str(node_id),
|
||||
'walletrpcpassword': 'test_pass' + str(node_id),
|
||||
'walletfile': 'testwallet',
|
||||
'datadir': os.path.join(datadir, 'xmr_' + str(node_id)),
|
||||
'bindir': WOW_BINDIR,
|
||||
settings["chainclients"]["wownero"] = {
|
||||
"connection_type": "rpc",
|
||||
"manage_daemon": False,
|
||||
"rpcport": WOW_BASE_RPC_PORT + node_id,
|
||||
"walletrpcport": WOW_BASE_WALLET_RPC_PORT + node_id,
|
||||
"walletrpcuser": "test" + str(node_id),
|
||||
"walletrpcpassword": "test_pass" + str(node_id),
|
||||
"walletfile": "testwallet",
|
||||
"datadir": os.path.join(datadir, "xmr_" + str(node_id)),
|
||||
"bindir": WOW_BINDIR,
|
||||
}
|
||||
|
||||
def callwownodewallet(self, node_id, method, params=None):
|
||||
return callrpc_xmr(WOW_BASE_WALLET_RPC_PORT + node_id, method, params, auth=self.wow_wallet_auth[node_id])
|
||||
return callrpc_xmr(
|
||||
WOW_BASE_WALLET_RPC_PORT + node_id,
|
||||
method,
|
||||
params,
|
||||
auth=self.wow_wallet_auth[node_id],
|
||||
)
|
||||
|
||||
def test_01_ads_part_coin(self):
|
||||
run_test_ads_success_path(self, Coins.PART, self.test_coin)
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright (c) 2021-2024 tecnovert
|
||||
# Copyright (c) 2024 The Basicswap developers
|
||||
# Distributed under the MIT software license, see the accompanying
|
||||
# file LICENSE or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
|
@ -60,22 +61,24 @@ from basicswap.interface.dcr.rpc import callrpc as callrpc_dcr
|
|||
import basicswap.bin.run as runSystem
|
||||
|
||||
|
||||
test_path = os.path.expanduser(os.getenv('TEST_PATH', '/tmp/test_persistent'))
|
||||
RESET_TEST = make_boolean(os.getenv('RESET_TEST', 'false'))
|
||||
test_path = os.path.expanduser(os.getenv("TEST_PATH", "/tmp/test_persistent"))
|
||||
RESET_TEST = make_boolean(os.getenv("RESET_TEST", "false"))
|
||||
|
||||
PORT_OFS = int(os.getenv('PORT_OFS', 1))
|
||||
PORT_OFS = int(os.getenv("PORT_OFS", 1))
|
||||
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))
|
||||
BITCOINCASH_RPC_PORT_BASE = int(os.getenv('BITCOINCASH_RPC_PORT_BASE', BCH_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')
|
||||
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))
|
||||
BITCOINCASH_RPC_PORT_BASE = int(
|
||||
os.getenv("BITCOINCASH_RPC_PORT_BASE", BCH_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")
|
||||
|
||||
NUM_NODES = int(os.getenv('NUM_NODES', 3))
|
||||
EXTRA_CONFIG_JSON = json.loads(os.getenv('EXTRA_CONFIG_JSON', '{}'))
|
||||
NUM_NODES = int(os.getenv("NUM_NODES", 3))
|
||||
EXTRA_CONFIG_JSON = json.loads(os.getenv("EXTRA_CONFIG_JSON", "{}"))
|
||||
|
||||
logger = logging.getLogger()
|
||||
logger.level = logging.DEBUG
|
||||
|
@ -83,28 +86,54 @@ if not len(logger.handlers):
|
|||
logger.addHandler(logging.StreamHandler(sys.stdout))
|
||||
|
||||
|
||||
def callpartrpc(node_id, method, params=[], wallet=None, base_rpc_port=PARTICL_RPC_PORT_BASE + PORT_OFS):
|
||||
auth = 'test_part_{0}:test_part_pwd_{0}'.format(node_id)
|
||||
def callpartrpc(
|
||||
node_id,
|
||||
method,
|
||||
params=[],
|
||||
wallet=None,
|
||||
base_rpc_port=PARTICL_RPC_PORT_BASE + PORT_OFS,
|
||||
):
|
||||
auth = "test_part_{0}:test_part_pwd_{0}".format(node_id)
|
||||
return callrpc(base_rpc_port + node_id, auth, method, params, wallet)
|
||||
|
||||
|
||||
def callbtcrpc(node_id, method, params=[], wallet=None, base_rpc_port=BITCOIN_RPC_PORT_BASE + PORT_OFS):
|
||||
auth = 'test_btc_{0}:test_btc_pwd_{0}'.format(node_id)
|
||||
def callbtcrpc(
|
||||
node_id,
|
||||
method,
|
||||
params=[],
|
||||
wallet=None,
|
||||
base_rpc_port=BITCOIN_RPC_PORT_BASE + PORT_OFS,
|
||||
):
|
||||
auth = "test_btc_{0}:test_btc_pwd_{0}".format(node_id)
|
||||
return callrpc(base_rpc_port + node_id, auth, method, params, wallet)
|
||||
|
||||
|
||||
def callltcrpc(node_id, method, params=[], wallet=None, base_rpc_port=LITECOIN_RPC_PORT_BASE + PORT_OFS):
|
||||
auth = 'test_ltc_{0}:test_ltc_pwd_{0}'.format(node_id)
|
||||
def callltcrpc(
|
||||
node_id,
|
||||
method,
|
||||
params=[],
|
||||
wallet=None,
|
||||
base_rpc_port=LITECOIN_RPC_PORT_BASE + PORT_OFS,
|
||||
):
|
||||
auth = "test_ltc_{0}:test_ltc_pwd_{0}".format(node_id)
|
||||
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'
|
||||
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 callbchrpc(node_id, method, params=[], wallet=None, base_rpc_port=BITCOINCASH_RPC_PORT_BASE + PORT_OFS):
|
||||
auth = 'test_bch_{0}:test_bch_pwd_{0}'.format(node_id)
|
||||
def callbchrpc(
|
||||
node_id,
|
||||
method,
|
||||
params=[],
|
||||
wallet=None,
|
||||
base_rpc_port=BITCOINCASH_RPC_PORT_BASE + PORT_OFS,
|
||||
):
|
||||
auth = "test_bch_{0}:test_bch_pwd_{0}".format(node_id)
|
||||
return callrpc(base_rpc_port + node_id, auth, method, params, wallet)
|
||||
|
||||
|
||||
|
@ -112,27 +141,32 @@ def updateThread(cls):
|
|||
while not cls.delay_event.is_set():
|
||||
try:
|
||||
if cls.btc_addr is not None:
|
||||
callbtcrpc(0, 'generatetoaddress', [1, cls.btc_addr])
|
||||
callbtcrpc(0, "generatetoaddress", [1, cls.btc_addr])
|
||||
if cls.ltc_addr is not None:
|
||||
callltcrpc(0, 'generatetoaddress', [1, cls.ltc_addr])
|
||||
callltcrpc(0, "generatetoaddress", [1, cls.ltc_addr])
|
||||
if cls.bch_addr is not None:
|
||||
callbchrpc(0, 'generatetoaddress', [1, cls.bch_addr])
|
||||
callbchrpc(0, "generatetoaddress", [1, cls.bch_addr])
|
||||
except Exception as e:
|
||||
print('updateThread error', str(e))
|
||||
print("updateThread error", str(e))
|
||||
cls.delay_event.wait(random.randrange(cls.update_min, cls.update_max))
|
||||
|
||||
|
||||
def updateThreadXMR(cls):
|
||||
xmr_auth = None
|
||||
if os.getenv('XMR_RPC_USER', '') != '':
|
||||
xmr_auth = (os.getenv('XMR_RPC_USER', ''), os.getenv('XMR_RPC_PWD', ''))
|
||||
if os.getenv("XMR_RPC_USER", "") != "":
|
||||
xmr_auth = (os.getenv("XMR_RPC_USER", ""), os.getenv("XMR_RPC_PWD", ""))
|
||||
|
||||
while not cls.delay_event.is_set():
|
||||
try:
|
||||
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)
|
||||
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))
|
||||
|
||||
|
||||
|
@ -143,24 +177,30 @@ def updateThreadDCR(cls):
|
|||
num_passed: int = 0
|
||||
for i in range(30):
|
||||
try:
|
||||
calldcrrpc(0, 'purchaseticket', [cls.dcr_acc, 0.1, 0])
|
||||
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):
|
||||
if "double spend" in str(e):
|
||||
pass
|
||||
else:
|
||||
logging.warning('updateThreadDCR purchaseticket {}'.format(e))
|
||||
logging.warning("updateThreadDCR purchaseticket {}".format(e))
|
||||
cls.delay_event.wait(0.5)
|
||||
try:
|
||||
if num_passed >= 5:
|
||||
calldcrrpc(0, 'generate', [1,])
|
||||
calldcrrpc(
|
||||
0,
|
||||
"generate",
|
||||
[
|
||||
1,
|
||||
],
|
||||
)
|
||||
except Exception as e:
|
||||
logging.warning('updateThreadDCR generate {}'.format(e))
|
||||
logging.warning("updateThreadDCR generate {}".format(e))
|
||||
except Exception as e:
|
||||
print('updateThreadDCR error', str(e))
|
||||
print("updateThreadDCR error", str(e))
|
||||
cls.delay_event.wait(random.randrange(cls.dcr_update_min, cls.dcr_update_max))
|
||||
|
||||
|
||||
|
@ -169,13 +209,13 @@ class Test(unittest.TestCase):
|
|||
def setUpClass(cls):
|
||||
super(Test, cls).setUpClass()
|
||||
|
||||
cls.update_min = int(os.getenv('UPDATE_THREAD_MIN_WAIT', '1'))
|
||||
cls.update_min = int(os.getenv("UPDATE_THREAD_MIN_WAIT", "1"))
|
||||
cls.update_max = cls.update_min * 4
|
||||
|
||||
cls.xmr_update_min = int(os.getenv('XMR_UPDATE_THREAD_MIN_WAIT', '1'))
|
||||
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_min = int(os.getenv("DCR_UPDATE_THREAD_MIN_WAIT", "1"))
|
||||
cls.dcr_update_max = cls.dcr_update_min * 4
|
||||
|
||||
cls.delay_event = threading.Event()
|
||||
|
@ -187,100 +227,181 @@ class Test(unittest.TestCase):
|
|||
cls.ltc_addr = None
|
||||
cls.bch_addr = None
|
||||
cls.xmr_addr = None
|
||||
cls.dcr_addr = 'SsYbXyjkKAEXXcGdFgr4u4bo4L8RkCxwQpH'
|
||||
cls.dcr_addr = "SsYbXyjkKAEXXcGdFgr4u4bo4L8RkCxwQpH"
|
||||
cls.dcr_acc = None
|
||||
|
||||
random.seed(time.time())
|
||||
|
||||
if os.path.exists(test_path) and not RESET_TEST:
|
||||
logging.info(f'Continuing with existing directory: {test_path}')
|
||||
logging.info(f"Continuing with existing directory: {test_path}")
|
||||
else:
|
||||
logging.info('Preparing %d nodes.', NUM_NODES)
|
||||
prepare_nodes(NUM_NODES, TEST_COINS_LIST, True, {'min_sequence_lock_seconds': 60}, PORT_OFS)
|
||||
logging.info("Preparing %d nodes.", NUM_NODES)
|
||||
prepare_nodes(
|
||||
NUM_NODES,
|
||||
TEST_COINS_LIST,
|
||||
True,
|
||||
{"min_sequence_lock_seconds": 60},
|
||||
PORT_OFS,
|
||||
)
|
||||
|
||||
signal.signal(signal.SIGINT, lambda signal, frame: cls.signal_handler(cls, signal, frame))
|
||||
signal.signal(
|
||||
signal.SIGINT, lambda signal, frame: cls.signal_handler(cls, signal, frame)
|
||||
)
|
||||
|
||||
def signal_handler(self, sig, frame):
|
||||
logging.info('signal {} detected.'.format(sig))
|
||||
logging.info("signal {} detected.".format(sig))
|
||||
self.delay_event.set()
|
||||
|
||||
def run_thread(self, client_id):
|
||||
client_path = os.path.join(test_path, 'client{}'.format(client_id))
|
||||
testargs = ['basicswap-run', '-datadir=' + client_path, '-regtest']
|
||||
with patch.object(sys, 'argv', testargs):
|
||||
client_path = os.path.join(test_path, "client{}".format(client_id))
|
||||
testargs = ["basicswap-run", "-datadir=" + client_path, "-regtest"]
|
||||
with patch.object(sys, "argv", testargs):
|
||||
runSystem.main()
|
||||
|
||||
def start_processes(self):
|
||||
self.delay_event.clear()
|
||||
|
||||
for i in range(NUM_NODES):
|
||||
self.processes.append(multiprocessing.Process(target=self.run_thread, args=(i,)))
|
||||
self.processes.append(
|
||||
multiprocessing.Process(target=self.run_thread, args=(i,))
|
||||
)
|
||||
self.processes[-1].start()
|
||||
|
||||
for i in range(NUM_NODES):
|
||||
waitForServer(self.delay_event, UI_PORT + i)
|
||||
|
||||
wallets = read_json_api(UI_PORT + 1, 'wallets')
|
||||
wallets = read_json_api(UI_PORT + 1, "wallets")
|
||||
|
||||
xmr_auth = None
|
||||
if os.getenv('XMR_RPC_USER', '') != '':
|
||||
xmr_auth = (os.getenv('XMR_RPC_USER', ''), os.getenv('XMR_RPC_PWD', ''))
|
||||
if os.getenv("XMR_RPC_USER", "") != "":
|
||||
xmr_auth = (os.getenv("XMR_RPC_USER", ""), os.getenv("XMR_RPC_PWD", ""))
|
||||
|
||||
self.xmr_addr = wallets['XMR']['main_address']
|
||||
self.xmr_addr = wallets["XMR"]["main_address"]
|
||||
num_blocks = 100
|
||||
if callrpc_xmr(XMR_BASE_RPC_PORT + 1, 'get_block_count', auth=xmr_auth)['count'] < num_blocks:
|
||||
logging.info('Mining {} Monero blocks to {}.'.format(num_blocks, self.xmr_addr))
|
||||
callrpc_xmr(XMR_BASE_RPC_PORT + 1, 'generateblocks', {'wallet_address': self.xmr_addr, 'amount_of_blocks': num_blocks}, auth=xmr_auth)
|
||||
logging.info('XMR blocks: %d', callrpc_xmr(XMR_BASE_RPC_PORT + 1, 'get_block_count', auth=xmr_auth)['count'])
|
||||
if (
|
||||
callrpc_xmr(XMR_BASE_RPC_PORT + 1, "get_block_count", auth=xmr_auth)[
|
||||
"count"
|
||||
]
|
||||
< num_blocks
|
||||
):
|
||||
logging.info(
|
||||
"Mining {} Monero blocks to {}.".format(num_blocks, self.xmr_addr)
|
||||
)
|
||||
callrpc_xmr(
|
||||
XMR_BASE_RPC_PORT + 1,
|
||||
"generateblocks",
|
||||
{"wallet_address": self.xmr_addr, "amount_of_blocks": num_blocks},
|
||||
auth=xmr_auth,
|
||||
)
|
||||
logging.info(
|
||||
"XMR blocks: %d",
|
||||
callrpc_xmr(XMR_BASE_RPC_PORT + 1, "get_block_count", auth=xmr_auth)[
|
||||
"count"
|
||||
],
|
||||
)
|
||||
|
||||
self.btc_addr = callbtcrpc(0, 'getnewaddress', ['mining_addr', 'bech32'])
|
||||
self.btc_addr = callbtcrpc(0, "getnewaddress", ["mining_addr", "bech32"])
|
||||
num_blocks: int = 500 # Mine enough to activate segwit
|
||||
if callbtcrpc(0, 'getblockcount') < num_blocks:
|
||||
logging.info('Mining %d Bitcoin blocks to %s', num_blocks, self.btc_addr)
|
||||
callbtcrpc(0, 'generatetoaddress', [num_blocks, self.btc_addr])
|
||||
logging.info('BTC blocks: %d', callbtcrpc(0, 'getblockcount'))
|
||||
if callbtcrpc(0, "getblockcount") < num_blocks:
|
||||
logging.info("Mining %d Bitcoin blocks to %s", num_blocks, self.btc_addr)
|
||||
callbtcrpc(0, "generatetoaddress", [num_blocks, self.btc_addr])
|
||||
logging.info("BTC blocks: %d", callbtcrpc(0, "getblockcount"))
|
||||
|
||||
if 'litecoin' in TEST_COINS_LIST:
|
||||
self.ltc_addr = callltcrpc(0, 'getnewaddress', ['mining_addr'], wallet='wallet.dat')
|
||||
if "litecoin" in TEST_COINS_LIST:
|
||||
self.ltc_addr = callltcrpc(
|
||||
0, "getnewaddress", ["mining_addr"], wallet="wallet.dat"
|
||||
)
|
||||
num_blocks: int = 431
|
||||
have_blocks: int = callltcrpc(0, 'getblockcount')
|
||||
have_blocks: int = callltcrpc(0, "getblockcount")
|
||||
if have_blocks < 500:
|
||||
logging.info('Mining %d Litecoin blocks to %s', num_blocks, self.ltc_addr)
|
||||
callltcrpc(0, 'generatetoaddress', [num_blocks - have_blocks, self.ltc_addr], wallet='wallet.dat')
|
||||
logging.info(
|
||||
"Mining %d Litecoin blocks to %s", num_blocks, self.ltc_addr
|
||||
)
|
||||
callltcrpc(
|
||||
0,
|
||||
"generatetoaddress",
|
||||
[num_blocks - have_blocks, self.ltc_addr],
|
||||
wallet="wallet.dat",
|
||||
)
|
||||
|
||||
# https://github.com/litecoin-project/litecoin/issues/807
|
||||
# Block 432 is when MWEB activates. It requires a peg-in. You'll need to generate an mweb address and send some coins to it. Then it will allow you to mine the next block.
|
||||
mweb_addr = callltcrpc(0, 'getnewaddress', ['mweb_addr', 'mweb'], wallet='mweb')
|
||||
callltcrpc(0, 'sendtoaddress', [mweb_addr, 1.0], wallet='wallet.dat')
|
||||
mweb_addr = callltcrpc(
|
||||
0, "getnewaddress", ["mweb_addr", "mweb"], wallet="mweb"
|
||||
)
|
||||
callltcrpc(0, "sendtoaddress", [mweb_addr, 1.0], wallet="wallet.dat")
|
||||
num_blocks = 69
|
||||
|
||||
have_blocks: int = callltcrpc(0, 'getblockcount')
|
||||
callltcrpc(0, 'generatetoaddress', [500 - have_blocks, self.ltc_addr], wallet='wallet.dat')
|
||||
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 "decred" in TEST_COINS_LIST:
|
||||
if RESET_TEST:
|
||||
addr = calldcrrpc(0, 'getnewaddress')
|
||||
_ = calldcrrpc(0, "getnewaddress")
|
||||
# assert (addr == self.dcr_addr)
|
||||
self.dcr_acc = calldcrrpc(0, 'getaccount', [self.dcr_addr, ])
|
||||
addr = calldcrrpc(0, 'generate', [110,])
|
||||
self.dcr_acc = calldcrrpc(
|
||||
0,
|
||||
"getaccount",
|
||||
[
|
||||
self.dcr_addr,
|
||||
],
|
||||
)
|
||||
calldcrrpc(
|
||||
0,
|
||||
"generate",
|
||||
[
|
||||
110,
|
||||
],
|
||||
)
|
||||
else:
|
||||
self.dcr_acc = calldcrrpc(0, 'getaccount', [self.dcr_addr, ])
|
||||
self.dcr_acc = calldcrrpc(
|
||||
0,
|
||||
"getaccount",
|
||||
[
|
||||
self.dcr_addr,
|
||||
],
|
||||
)
|
||||
|
||||
self.update_thread_dcr = threading.Thread(target=updateThreadDCR, args=(self,))
|
||||
self.update_thread_dcr = threading.Thread(
|
||||
target=updateThreadDCR, args=(self,)
|
||||
)
|
||||
self.update_thread_dcr.start()
|
||||
|
||||
if 'bitcoincash' in TEST_COINS_LIST:
|
||||
self.bch_addr = callbchrpc(0, 'getnewaddress', ['mining_addr'], wallet='wallet.dat')
|
||||
if "bitcoincash" in TEST_COINS_LIST:
|
||||
self.bch_addr = callbchrpc(
|
||||
0, "getnewaddress", ["mining_addr"], wallet="wallet.dat"
|
||||
)
|
||||
num_blocks: int = 200
|
||||
have_blocks: int = callbchrpc(0, 'getblockcount')
|
||||
have_blocks: int = callbchrpc(0, "getblockcount")
|
||||
if have_blocks < num_blocks:
|
||||
logging.info('Mining %d Bitcoincash blocks to %s', num_blocks - have_blocks, self.bch_addr)
|
||||
callbchrpc(0, 'generatetoaddress', [num_blocks - have_blocks, self.bch_addr], wallet='wallet.dat')
|
||||
logging.info(
|
||||
"Mining %d Bitcoincash blocks to %s",
|
||||
num_blocks - have_blocks,
|
||||
self.bch_addr,
|
||||
)
|
||||
callbchrpc(
|
||||
0,
|
||||
"generatetoaddress",
|
||||
[num_blocks - have_blocks, self.bch_addr],
|
||||
wallet="wallet.dat",
|
||||
)
|
||||
|
||||
if RESET_TEST:
|
||||
# Lower output split threshold for more stakeable outputs
|
||||
for i in range(NUM_NODES):
|
||||
callpartrpc(i, 'walletsettings', ['stakingoptions', {'stakecombinethreshold': 100, 'stakesplitthreshold': 200}])
|
||||
callpartrpc(
|
||||
i,
|
||||
"walletsettings",
|
||||
[
|
||||
"stakingoptions",
|
||||
{"stakecombinethreshold": 100, "stakesplitthreshold": 200},
|
||||
],
|
||||
)
|
||||
self.update_thread = threading.Thread(target=updateThread, args=(self,))
|
||||
self.update_thread.start()
|
||||
|
||||
|
@ -289,21 +410,21 @@ class Test(unittest.TestCase):
|
|||
|
||||
# Wait for height, or sequencelock is thrown off by genesis blocktime
|
||||
num_blocks = 3
|
||||
logging.info('Waiting for Particl chain height %d', num_blocks)
|
||||
logging.info("Waiting for Particl chain height %d", num_blocks)
|
||||
for i in range(60):
|
||||
if self.delay_event.is_set():
|
||||
raise ValueError('Test stopped.')
|
||||
particl_blocks = callpartrpc(0, 'getblockcount')
|
||||
print('particl_blocks', particl_blocks)
|
||||
raise ValueError("Test stopped.")
|
||||
particl_blocks = callpartrpc(0, "getblockcount")
|
||||
print("particl_blocks", particl_blocks)
|
||||
if particl_blocks >= num_blocks:
|
||||
break
|
||||
self.delay_event.wait(1)
|
||||
logging.info('PART blocks: %d', callpartrpc(0, 'getblockcount'))
|
||||
logging.info("PART blocks: %d", callpartrpc(0, "getblockcount"))
|
||||
assert particl_blocks >= num_blocks
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
logging.info('Stopping test')
|
||||
logging.info("Stopping test")
|
||||
cls.delay_event.set()
|
||||
if cls.update_thread:
|
||||
cls.update_thread.join()
|
||||
|
@ -328,9 +449,9 @@ class Test(unittest.TestCase):
|
|||
waitForServer(self.delay_event, UI_PORT + 1)
|
||||
|
||||
while not self.delay_event.is_set():
|
||||
logging.info('Looping indefinitely, ctrl+c to exit.')
|
||||
logging.info("Looping indefinitely, ctrl+c to exit.")
|
||||
self.delay_event.wait(10)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
|
|
@ -2,11 +2,12 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright (c) 2020 tecnovert
|
||||
# Copyright (c) 2024 The Basicswap developers
|
||||
# Distributed under the MIT software license, see the accompanying
|
||||
# file LICENSE or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
mnemonics = [
|
||||
'abandon baby cabbage dad eager fabric gadget habit ice kangaroo lab absorb',
|
||||
'actuel comédie poésie noble facile éprouver brave cellule rotule académie hilarant chambre',
|
||||
'ちしき いてざ きおち あしあと ぽちぶくろ こえる さつえい むえき あける ほんき むさぼる ねいろ',
|
||||
"abandon baby cabbage dad eager fabric gadget habit ice kangaroo lab absorb",
|
||||
"actuel comédie poésie noble facile éprouver brave cellule rotule académie hilarant chambre",
|
||||
"ちしき いてざ きおち あしあと ぽちぶくろ こえる さつえい むえき あける ほんき むさぼる ねいろ",
|
||||
]
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright (c) 2023-2024 tecnovert
|
||||
# Copyright (c) 2024 The Basicswap developers
|
||||
# Distributed under the MIT software license, see the accompanying
|
||||
# file LICENSE or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
|
@ -18,106 +19,125 @@ from util import get_driver
|
|||
|
||||
|
||||
def test_offer(driver):
|
||||
node1_url = 'http://localhost:12701'
|
||||
node2_url = 'http://localhost:12702'
|
||||
node1_url = "http://localhost:12701"
|
||||
|
||||
driver.get(node1_url + '/newoffer')
|
||||
driver.get(node1_url + "/newoffer")
|
||||
time.sleep(1)
|
||||
|
||||
select = Select(driver.find_element(By.ID, 'coin_from'))
|
||||
select.select_by_visible_text('Bitcoin')
|
||||
select = Select(driver.find_element(By.ID, 'coin_to'))
|
||||
select.select_by_visible_text('Monero')
|
||||
select = Select(driver.find_element(By.ID, "coin_from"))
|
||||
select.select_by_visible_text("Bitcoin")
|
||||
select = Select(driver.find_element(By.ID, "coin_to"))
|
||||
select.select_by_visible_text("Monero")
|
||||
|
||||
amt_from = driver.find_element(By.NAME, 'amt_from')
|
||||
amt_to = driver.find_element(By.NAME, 'amt_to')
|
||||
rate = driver.find_element(By.ID, 'rate')
|
||||
amt_from.send_keys('1')
|
||||
amt_to.send_keys('2')
|
||||
amt_from = driver.find_element(By.NAME, "amt_from")
|
||||
amt_to = driver.find_element(By.NAME, "amt_to")
|
||||
rate = driver.find_element(By.ID, "rate")
|
||||
amt_from.send_keys("1")
|
||||
amt_to.send_keys("2")
|
||||
amt_from.click()
|
||||
time.sleep(0.5)
|
||||
rate_value = rate.get_attribute('value')
|
||||
assert (float(rate_value) == 2.0)
|
||||
rate_value = rate.get_attribute("value")
|
||||
assert float(rate_value) == 2.0
|
||||
|
||||
rate.clear()
|
||||
rate.send_keys('3')
|
||||
rate.send_keys("3")
|
||||
amt_from.click()
|
||||
time.sleep(0.5)
|
||||
amt_to_value = amt_to.get_attribute('value')
|
||||
assert (float(amt_to_value) == 3.0)
|
||||
amt_to_value = amt_to.get_attribute("value")
|
||||
assert float(amt_to_value) == 3.0
|
||||
|
||||
amt_from.clear()
|
||||
amt_from.send_keys('2')
|
||||
amt_from.send_keys("2")
|
||||
amt_to.click()
|
||||
time.sleep(0.5)
|
||||
amt_to_value = amt_to.get_attribute('value')
|
||||
assert (float(amt_to_value) == 6.0)
|
||||
amt_to_value = amt_to.get_attribute("value")
|
||||
assert float(amt_to_value) == 6.0
|
||||
|
||||
amt_from.clear()
|
||||
amt_to.clear()
|
||||
rate.clear()
|
||||
amt_to.send_keys('2')
|
||||
rate.send_keys('2')
|
||||
amt_to.send_keys("2")
|
||||
rate.send_keys("2")
|
||||
amt_to.click()
|
||||
time.sleep(0.2)
|
||||
amt_from_value = amt_from.get_attribute('value')
|
||||
assert (float(amt_from_value) == 1.0)
|
||||
amt_from_value = amt_from.get_attribute("value")
|
||||
assert float(amt_from_value) == 1.0
|
||||
|
||||
driver.find_element(By.NAME, 'continue').click()
|
||||
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.NAME, 'check_offer'))).click()
|
||||
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.NAME, 'submit_offer'))).click()
|
||||
driver.find_element(By.NAME, "continue").click()
|
||||
WebDriverWait(driver, 20).until(
|
||||
EC.element_to_be_clickable((By.NAME, "check_offer"))
|
||||
).click()
|
||||
WebDriverWait(driver, 20).until(
|
||||
EC.element_to_be_clickable((By.NAME, "submit_offer"))
|
||||
).click()
|
||||
time.sleep(1)
|
||||
|
||||
offer_link = driver.find_element(By.XPATH, "//a[contains(text(),'Sent Offer')]")
|
||||
offer1_id = offer_link.text.split(' ')[2]
|
||||
offer1_id = offer_link.text.split(" ")[2]
|
||||
|
||||
driver.get(node1_url + '/newoffer')
|
||||
driver.get(node1_url + "/newoffer")
|
||||
time.sleep(1)
|
||||
|
||||
select = Select(driver.find_element(By.ID, 'coin_from'))
|
||||
select.select_by_visible_text('Particl')
|
||||
select = Select(driver.find_element(By.ID, 'coin_to'))
|
||||
select.select_by_visible_text('Monero')
|
||||
select = Select(driver.find_element(By.ID, "coin_from"))
|
||||
select.select_by_visible_text("Particl")
|
||||
select = Select(driver.find_element(By.ID, "coin_to"))
|
||||
select.select_by_visible_text("Monero")
|
||||
|
||||
driver.find_element(By.NAME, 'amt_from').send_keys('3')
|
||||
driver.find_element(By.NAME, 'amt_to').send_keys('4')
|
||||
driver.find_element(By.NAME, "amt_from").send_keys("3")
|
||||
driver.find_element(By.NAME, "amt_to").send_keys("4")
|
||||
|
||||
driver.find_element(By.NAME, 'continue').click()
|
||||
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.NAME, 'check_offer'))).click()
|
||||
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.NAME, 'submit_offer'))).click()
|
||||
driver.find_element(By.NAME, "continue").click()
|
||||
WebDriverWait(driver, 20).until(
|
||||
EC.element_to_be_clickable((By.NAME, "check_offer"))
|
||||
).click()
|
||||
WebDriverWait(driver, 20).until(
|
||||
EC.element_to_be_clickable((By.NAME, "submit_offer"))
|
||||
).click()
|
||||
time.sleep(1)
|
||||
|
||||
offer_link = driver.find_element(By.XPATH, "//a[contains(text(),'Sent Offer')]")
|
||||
offer2_id = offer_link.text.split(' ')[2]
|
||||
offer2_id = offer_link.text.split(" ")[2]
|
||||
|
||||
driver.get(node1_url + '/offer/' + offer1_id)
|
||||
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.NAME, 'repeat_offer'))).click()
|
||||
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.NAME, 'check_offer'))).click()
|
||||
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.NAME, 'submit_offer'))).click()
|
||||
driver.get(node1_url + "/offer/" + offer1_id)
|
||||
WebDriverWait(driver, 20).until(
|
||||
EC.element_to_be_clickable((By.NAME, "repeat_offer"))
|
||||
).click()
|
||||
WebDriverWait(driver, 20).until(
|
||||
EC.element_to_be_clickable((By.NAME, "check_offer"))
|
||||
).click()
|
||||
WebDriverWait(driver, 20).until(
|
||||
EC.element_to_be_clickable((By.NAME, "submit_offer"))
|
||||
).click()
|
||||
time.sleep(1)
|
||||
|
||||
offer_link = driver.find_element(By.XPATH, "//a[contains(text(),'Sent Offer')]")
|
||||
offer3_id = offer_link.text.split(' ')[2]
|
||||
offer3_id = offer_link.text.split(" ")[2]
|
||||
|
||||
offer3_json = json.loads(urlopen(node1_url + '/json/offers/' + offer3_id).read())[0]
|
||||
assert (offer3_json['coin_from'] == 'Bitcoin')
|
||||
assert (offer3_json['coin_to'] == 'Monero')
|
||||
offer3_json = json.loads(urlopen(node1_url + "/json/offers/" + offer3_id).read())[0]
|
||||
assert offer3_json["coin_from"] == "Bitcoin"
|
||||
assert offer3_json["coin_to"] == "Monero"
|
||||
|
||||
driver.get(node1_url + '/offer/' + offer2_id)
|
||||
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.NAME, 'repeat_offer'))).click()
|
||||
driver.get(node1_url + "/offer/" + offer2_id)
|
||||
WebDriverWait(driver, 20).until(
|
||||
EC.element_to_be_clickable((By.NAME, "repeat_offer"))
|
||||
).click()
|
||||
time.sleep(1) # Add time for setupCustomSelect to fire
|
||||
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.NAME, 'check_offer'))).click()
|
||||
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.NAME, 'submit_offer'))).click()
|
||||
WebDriverWait(driver, 20).until(
|
||||
EC.element_to_be_clickable((By.NAME, "check_offer"))
|
||||
).click()
|
||||
WebDriverWait(driver, 20).until(
|
||||
EC.element_to_be_clickable((By.NAME, "submit_offer"))
|
||||
).click()
|
||||
time.sleep(1)
|
||||
|
||||
offer_link = driver.find_element(By.XPATH, "//a[contains(text(),'Sent Offer')]")
|
||||
offer4_id = offer_link.text.split(' ')[2]
|
||||
offer4_id = offer_link.text.split(" ")[2]
|
||||
|
||||
offer4_json = json.loads(urlopen(node1_url + '/json/offers/' + offer4_id).read())[0]
|
||||
assert (offer4_json['coin_from'] == 'Particl')
|
||||
assert (offer4_json['coin_to'] == 'Monero')
|
||||
offer4_json = json.loads(urlopen(node1_url + "/json/offers/" + offer4_id).read())[0]
|
||||
assert offer4_json["coin_from"] == "Particl"
|
||||
assert offer4_json["coin_to"] == "Monero"
|
||||
|
||||
print('Test Passed!')
|
||||
print("Test Passed!")
|
||||
|
||||
|
||||
def run_tests():
|
||||
|
@ -128,5 +148,5 @@ def run_tests():
|
|||
driver.close()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if __name__ == "__main__":
|
||||
run_tests()
|
||||
|
|
|
@ -13,196 +13,229 @@ from selenium.webdriver.support.select import Select
|
|||
from selenium.webdriver.support import expected_conditions as EC
|
||||
|
||||
from util import (
|
||||
BSX_0_PORT, BSX_1_PORT,
|
||||
BSX_0_PORT,
|
||||
BSX_1_PORT,
|
||||
click_option,
|
||||
get_driver,
|
||||
)
|
||||
from tests.basicswap.util import read_json_api
|
||||
|
||||
|
||||
base_url = 'http://localhost'
|
||||
base_url = "http://localhost"
|
||||
|
||||
|
||||
def recover_chain_b_lock_tx(driver, offer_data, offerer_port, bidder_port):
|
||||
print('Test case: {} -> {}'.format(offer_data['coin_from'], offer_data['coin_to']))
|
||||
offerer_url = f'{base_url}:{offerer_port}'
|
||||
bidder_url = f'{base_url}:{bidder_port}'
|
||||
print("Test case: {} -> {}".format(offer_data["coin_from"], offer_data["coin_to"]))
|
||||
offerer_url = f"{base_url}:{offerer_port}"
|
||||
bidder_url = f"{base_url}:{bidder_port}"
|
||||
|
||||
rv = read_json_api(offerer_port, 'offers/new', offer_data)
|
||||
offer0_id = rv['offer_id']
|
||||
rv = read_json_api(offerer_port, "offers/new", offer_data)
|
||||
offer0_id = rv["offer_id"]
|
||||
|
||||
for i in range(10):
|
||||
rv = read_json_api(bidder_port, f'offers/{offer0_id}')
|
||||
rv = read_json_api(bidder_port, f"offers/{offer0_id}")
|
||||
if len(rv) > 0:
|
||||
break
|
||||
print('Bidder: Waiting for offer')
|
||||
print("Bidder: Waiting for offer")
|
||||
time.sleep(1)
|
||||
|
||||
bid_data = {
|
||||
'offer_id': offer0_id,
|
||||
'amount_from': 1.0}
|
||||
rv = read_json_api(bidder_port, 'bids/new', bid_data)
|
||||
bid0_id = rv['bid_id']
|
||||
bid_data = {"offer_id": offer0_id, "amount_from": 1.0}
|
||||
rv = read_json_api(bidder_port, "bids/new", bid_data)
|
||||
bid0_id = rv["bid_id"]
|
||||
|
||||
bid_state = None
|
||||
for i in range(10):
|
||||
rv = read_json_api(offerer_port, f'bids/{bid0_id}')
|
||||
if 'error' not in rv:
|
||||
bid_state = rv['bid_state']
|
||||
if bid_state == 'Received':
|
||||
rv = read_json_api(offerer_port, f"bids/{bid0_id}")
|
||||
if "error" not in rv:
|
||||
bid_state = rv["bid_state"]
|
||||
if bid_state == "Received":
|
||||
break
|
||||
print('Offerer: Waiting for bid')
|
||||
print("Offerer: Waiting for bid")
|
||||
time.sleep(2)
|
||||
assert (bid_state == 'Received')
|
||||
assert bid_state == "Received"
|
||||
|
||||
# Set BID_STOP_AFTER_COIN_B_LOCK (13) debugind
|
||||
rv = read_json_api(offerer_port, f'bids/{bid0_id}', {'debugind': 13})
|
||||
assert ('error' not in rv)
|
||||
rv = read_json_api(offerer_port, f"bids/{bid0_id}", {"debugind": 13})
|
||||
assert "error" not in rv
|
||||
|
||||
# Accept bid
|
||||
rv = read_json_api(offerer_port, f'bids/{bid0_id}', {'accept': 1})
|
||||
assert ('error' not in rv)
|
||||
rv = read_json_api(offerer_port, f"bids/{bid0_id}", {"accept": 1})
|
||||
assert "error" not in rv
|
||||
|
||||
for i in range(100):
|
||||
rv = read_json_api(bidder_port, f'bids/{bid0_id}')
|
||||
bid_state = rv['bid_state']
|
||||
if bid_state == 'Scriptless coin locked':
|
||||
rv = read_json_api(bidder_port, f"bids/{bid0_id}")
|
||||
bid_state = rv["bid_state"]
|
||||
if bid_state == "Scriptless coin locked":
|
||||
break
|
||||
print('Bidder: Waiting for state')
|
||||
print("Bidder: Waiting for state")
|
||||
time.sleep(5)
|
||||
assert (bid_state == 'Scriptless coin locked')
|
||||
assert bid_state == "Scriptless coin locked"
|
||||
|
||||
for i in range(100):
|
||||
rv = read_json_api(offerer_port, f'bids/{bid0_id}')
|
||||
bid_state = rv['bid_state']
|
||||
if bid_state == 'Stalled (debug)':
|
||||
rv = read_json_api(offerer_port, f"bids/{bid0_id}")
|
||||
bid_state = rv["bid_state"]
|
||||
if bid_state == "Stalled (debug)":
|
||||
break
|
||||
print('Offerer: Waiting for state')
|
||||
print("Offerer: Waiting for state")
|
||||
time.sleep(5)
|
||||
assert (bid_state == 'Stalled (debug)')
|
||||
assert bid_state == "Stalled (debug)"
|
||||
|
||||
# Show bid state history
|
||||
rv = read_json_api(offerer_port, f'bids/{bid0_id}/states')
|
||||
assert (len(rv) > 1)
|
||||
rv = read_json_api(offerer_port, f"bids/{bid0_id}/states")
|
||||
assert len(rv) > 1
|
||||
|
||||
url = f'{bidder_url}/bid/{bid0_id}'
|
||||
url = f"{bidder_url}/bid/{bid0_id}"
|
||||
driver.get(url)
|
||||
btn_more_info = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.NAME, 'show_txns')))
|
||||
btn_more_info = WebDriverWait(driver, 10).until(
|
||||
EC.element_to_be_clickable((By.NAME, "show_txns"))
|
||||
)
|
||||
btn_more_info.click()
|
||||
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.NAME, 'hide_txns')))
|
||||
bidder_localkeyhalf = driver.find_element(By.ID, 'localkeyhalf').text
|
||||
print('Bidder keyhalf', bidder_localkeyhalf)
|
||||
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.NAME, "hide_txns")))
|
||||
bidder_localkeyhalf = driver.find_element(By.ID, "localkeyhalf").text
|
||||
print("Bidder keyhalf", bidder_localkeyhalf)
|
||||
try:
|
||||
driver.find_element(By.ID, 'remotekeyhalf')
|
||||
driver.find_element(By.ID, "remotekeyhalf")
|
||||
except Exception:
|
||||
pass
|
||||
else:
|
||||
raise ValueError('Nodes should not have remotekeyhalves yet.')
|
||||
raise ValueError("Nodes should not have remotekeyhalves yet.")
|
||||
|
||||
url = f'{offerer_url}/bid/{bid0_id}'
|
||||
url = f"{offerer_url}/bid/{bid0_id}"
|
||||
driver.get(url)
|
||||
btn_more_info = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.NAME, 'show_txns')))
|
||||
btn_more_info = WebDriverWait(driver, 10).until(
|
||||
EC.element_to_be_clickable((By.NAME, "show_txns"))
|
||||
)
|
||||
btn_more_info.click()
|
||||
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.NAME, 'hide_txns')))
|
||||
offerer_localkeyhalf = driver.find_element(By.ID, 'localkeyhalf').text
|
||||
print('Offerer keyhalf', offerer_localkeyhalf)
|
||||
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.NAME, "hide_txns")))
|
||||
offerer_localkeyhalf = driver.find_element(By.ID, "localkeyhalf").text
|
||||
print("Offerer keyhalf", offerer_localkeyhalf)
|
||||
|
||||
print('Trying with the local key in place of remote')
|
||||
btn_edit = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.NAME, 'edit_bid')))
|
||||
print("Trying with the local key in place of remote")
|
||||
btn_edit = WebDriverWait(driver, 10).until(
|
||||
EC.element_to_be_clickable((By.NAME, "edit_bid"))
|
||||
)
|
||||
btn_edit.click()
|
||||
btn_submit = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.NAME, 'edit_bid_submit')))
|
||||
kbs_other = driver.find_element(By.ID, 'kbs_other')
|
||||
btn_submit = WebDriverWait(driver, 20).until(
|
||||
EC.element_to_be_clickable((By.NAME, "edit_bid_submit"))
|
||||
)
|
||||
kbs_other = driver.find_element(By.ID, "kbs_other")
|
||||
kbs_other.send_keys(offerer_localkeyhalf)
|
||||
btn_submit.click()
|
||||
|
||||
btn_edit = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.NAME, 'edit_bid')))
|
||||
elements = driver.find_elements(By.CLASS_NAME, 'error_msg')
|
||||
expect_err_msg: str = 'Provided key matches local key'
|
||||
assert (any(expect_err_msg in el.text for el in elements))
|
||||
print('Found expected error: ' + expect_err_msg)
|
||||
btn_edit = WebDriverWait(driver, 10).until(
|
||||
EC.element_to_be_clickable((By.NAME, "edit_bid"))
|
||||
)
|
||||
elements = driver.find_elements(By.CLASS_NAME, "error_msg")
|
||||
expect_err_msg: str = "Provided key matches local key"
|
||||
assert any(expect_err_msg in el.text for el in elements)
|
||||
print("Found expected error: " + expect_err_msg)
|
||||
|
||||
print('Trying with incorrect key')
|
||||
btn_edit = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.NAME, 'edit_bid')))
|
||||
print("Trying with incorrect key")
|
||||
btn_edit = WebDriverWait(driver, 10).until(
|
||||
EC.element_to_be_clickable((By.NAME, "edit_bid"))
|
||||
)
|
||||
btn_edit.click()
|
||||
btn_submit = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.NAME, 'edit_bid_submit')))
|
||||
kbs_other = driver.find_element(By.ID, 'kbs_other')
|
||||
btn_submit = WebDriverWait(driver, 20).until(
|
||||
EC.element_to_be_clickable((By.NAME, "edit_bid_submit"))
|
||||
)
|
||||
kbs_other = driver.find_element(By.ID, "kbs_other")
|
||||
last_byte = bidder_localkeyhalf[-2:]
|
||||
invalid_byte = '01' if last_byte == '00' else '00'
|
||||
invalid_byte = "01" if last_byte == "00" else "00"
|
||||
kbs_other.send_keys(bidder_localkeyhalf[:-2] + invalid_byte)
|
||||
btn_submit.click()
|
||||
|
||||
btn_edit = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.NAME, 'edit_bid')))
|
||||
elements = driver.find_elements(By.CLASS_NAME, 'error_msg')
|
||||
expect_err_msg: str = 'Summed key does not match expected wallet'
|
||||
assert (any(expect_err_msg in el.text for el in elements))
|
||||
print('Found expected error: ' + expect_err_msg)
|
||||
btn_edit = WebDriverWait(driver, 10).until(
|
||||
EC.element_to_be_clickable((By.NAME, "edit_bid"))
|
||||
)
|
||||
elements = driver.find_elements(By.CLASS_NAME, "error_msg")
|
||||
expect_err_msg: str = "Summed key does not match expected wallet"
|
||||
assert any(expect_err_msg in el.text for el in elements)
|
||||
print("Found expected error: " + expect_err_msg)
|
||||
|
||||
print('Trying with correct key')
|
||||
print("Trying with correct key")
|
||||
btn_edit.click()
|
||||
btn_submit = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.NAME, 'edit_bid_submit')))
|
||||
btn_submit = WebDriverWait(driver, 20).until(
|
||||
EC.element_to_be_clickable((By.NAME, "edit_bid_submit"))
|
||||
)
|
||||
|
||||
lock_tx_b_depth = -1
|
||||
for i in range(100):
|
||||
# Check the non-stalled node
|
||||
rv = read_json_api(bidder_port, f'bids/{bid0_id}', {'show_extra': True})
|
||||
for tx in rv['txns']:
|
||||
if tx['type'] == 'Chain B Lock' and tx['confirms'] is not None:
|
||||
lock_tx_b_depth = tx['confirms']
|
||||
rv = read_json_api(bidder_port, f"bids/{bid0_id}", {"show_extra": True})
|
||||
for tx in rv["txns"]:
|
||||
if tx["type"] == "Chain B Lock" and tx["confirms"] is not None:
|
||||
lock_tx_b_depth = tx["confirms"]
|
||||
break
|
||||
if lock_tx_b_depth >= 10:
|
||||
break
|
||||
print(f'Waiting for lock tx B depth, have {lock_tx_b_depth}')
|
||||
print(f"Waiting for lock tx B depth, have {lock_tx_b_depth}")
|
||||
time.sleep(2)
|
||||
|
||||
kbs_other = driver.find_element(By.ID, 'kbs_other')
|
||||
kbs_other = driver.find_element(By.ID, "kbs_other")
|
||||
kbs_other.send_keys(bidder_localkeyhalf)
|
||||
btn_submit.click()
|
||||
btn_edit = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.NAME, 'edit_bid')))
|
||||
elements = driver.find_elements(By.CLASS_NAME, 'infomsg')
|
||||
expect_msg: str = 'Bid edited'
|
||||
assert (any(expect_msg in el.text for el in elements))
|
||||
print('Found expected message: ' + expect_msg)
|
||||
btn_edit = WebDriverWait(driver, 10).until(
|
||||
EC.element_to_be_clickable((By.NAME, "edit_bid"))
|
||||
)
|
||||
elements = driver.find_elements(By.CLASS_NAME, "infomsg")
|
||||
expect_msg: str = "Bid edited"
|
||||
assert any(expect_msg in el.text for el in elements)
|
||||
print("Found expected message: " + expect_msg)
|
||||
|
||||
print('Trying with nodes reversed (should fail as already spent)') # But should sum to the expected wallet key
|
||||
url = f'{bidder_url}/bid/{bid0_id}'
|
||||
print(
|
||||
"Trying with nodes reversed (should fail as already spent)"
|
||||
) # But should sum to the expected wallet key
|
||||
url = f"{bidder_url}/bid/{bid0_id}"
|
||||
driver.get(url)
|
||||
btn_edit = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.NAME, 'edit_bid')))
|
||||
btn_edit = WebDriverWait(driver, 10).until(
|
||||
EC.element_to_be_clickable((By.NAME, "edit_bid"))
|
||||
)
|
||||
btn_edit.click()
|
||||
btn_submit = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.NAME, 'edit_bid_submit')))
|
||||
btn_submit = WebDriverWait(driver, 20).until(
|
||||
EC.element_to_be_clickable((By.NAME, "edit_bid_submit"))
|
||||
)
|
||||
|
||||
driver.get(url)
|
||||
btn_edit = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.NAME, 'edit_bid')))
|
||||
btn_edit = WebDriverWait(driver, 10).until(
|
||||
EC.element_to_be_clickable((By.NAME, "edit_bid"))
|
||||
)
|
||||
btn_edit.click()
|
||||
btn_submit = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.NAME, 'edit_bid_submit')))
|
||||
btn_submit = WebDriverWait(driver, 20).until(
|
||||
EC.element_to_be_clickable((By.NAME, "edit_bid_submit"))
|
||||
)
|
||||
|
||||
kbs_other = driver.find_element(By.ID, 'kbs_other')
|
||||
kbs_other = driver.find_element(By.ID, "kbs_other")
|
||||
kbs_other.send_keys(offerer_localkeyhalf)
|
||||
btn_submit.click()
|
||||
btn_edit = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.NAME, 'edit_bid')))
|
||||
btn_edit = WebDriverWait(driver, 10).until(
|
||||
EC.element_to_be_clickable((By.NAME, "edit_bid"))
|
||||
)
|
||||
# In log: "Balance is too low, checking for existing spend"
|
||||
# Should error here, but the code can't tell where the tx was sent, and treats any existing send as correct.
|
||||
elements = driver.find_elements(By.CLASS_NAME, 'infomsg')
|
||||
expect_msg: str = 'Bid edited'
|
||||
assert (any(expect_msg in el.text for el in elements))
|
||||
elements = driver.find_elements(By.CLASS_NAME, "infomsg")
|
||||
expect_msg: str = "Bid edited"
|
||||
assert any(expect_msg in el.text for el in elements)
|
||||
|
||||
|
||||
def enable_debug_ui(driver):
|
||||
for port in (BSX_0_PORT, BSX_1_PORT):
|
||||
url = f'{base_url}:{port}/settings'
|
||||
url = f"{base_url}:{port}/settings"
|
||||
driver.get(url)
|
||||
driver.find_element(By.ID, 'general-tab').click()
|
||||
driver.find_element(By.ID, "general-tab").click()
|
||||
|
||||
btn_apply_general = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.NAME, 'apply_general')))
|
||||
btn_apply_general = WebDriverWait(driver, 10).until(
|
||||
EC.element_to_be_clickable((By.NAME, "apply_general"))
|
||||
)
|
||||
|
||||
el = driver.find_element(By.NAME, 'debugmode')
|
||||
el = driver.find_element(By.NAME, "debugmode")
|
||||
selected_option = Select(el).first_selected_option
|
||||
if selected_option.text != 'True':
|
||||
click_option(el, 'True')
|
||||
if selected_option.text != "True":
|
||||
click_option(el, "True")
|
||||
|
||||
el = driver.find_element(By.NAME, 'debugui')
|
||||
el = driver.find_element(By.NAME, "debugui")
|
||||
selected_option = Select(el).first_selected_option
|
||||
if selected_option.text != 'True':
|
||||
click_option(el, 'True')
|
||||
if selected_option.text != "True":
|
||||
click_option(el, "True")
|
||||
|
||||
btn_apply_general.click()
|
||||
|
||||
|
@ -213,25 +246,27 @@ def run_tests():
|
|||
enable_debug_ui(driver)
|
||||
|
||||
offer_data = {
|
||||
'coin_from': 'BTC',
|
||||
'coin_to': 'XMR',
|
||||
'amt_from': 1.0,
|
||||
'amt_to': 2.0,
|
||||
'lockhrs': 24}
|
||||
"coin_from": "BTC",
|
||||
"coin_to": "XMR",
|
||||
"amt_from": 1.0,
|
||||
"amt_to": 2.0,
|
||||
"lockhrs": 24,
|
||||
}
|
||||
recover_chain_b_lock_tx(driver, offer_data, BSX_0_PORT, BSX_1_PORT)
|
||||
|
||||
offer_data = {
|
||||
'coin_from': 'XMR',
|
||||
'coin_to': 'BTC',
|
||||
'amt_from': 1.0,
|
||||
'amt_to': 2.0,
|
||||
'lockhrs': 24}
|
||||
"coin_from": "XMR",
|
||||
"coin_to": "BTC",
|
||||
"amt_from": 1.0,
|
||||
"amt_to": 2.0,
|
||||
"lockhrs": 24,
|
||||
}
|
||||
recover_chain_b_lock_tx(driver, offer_data, BSX_1_PORT, BSX_0_PORT)
|
||||
|
||||
print('Test Passed!')
|
||||
print("Test Passed!")
|
||||
finally:
|
||||
driver.close()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if __name__ == "__main__":
|
||||
run_tests()
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright (c) 2022-2024 tecnovert
|
||||
# Copyright (c) 2024 The Basicswap developers
|
||||
# Distributed under the MIT software license, see the accompanying
|
||||
# file LICENSE or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
|
@ -14,7 +15,7 @@ from selenium.webdriver.support.select import Select
|
|||
from selenium.webdriver.support import expected_conditions as EC
|
||||
|
||||
from util import (
|
||||
BSX_0_PORT, BSX_1_PORT,
|
||||
BSX_0_PORT,
|
||||
click_option,
|
||||
get_driver,
|
||||
)
|
||||
|
@ -22,118 +23,121 @@ from basicswap.ui.page_offers import default_chart_api_key
|
|||
|
||||
|
||||
def test_settings(driver):
|
||||
base_url = f'http://localhost:{BSX_0_PORT}'
|
||||
node2_url = f'http://localhost:{BSX_1_PORT}'
|
||||
base_url = f"http://localhost:{BSX_0_PORT}"
|
||||
|
||||
url = base_url + '/settings'
|
||||
url = base_url + "/settings"
|
||||
driver.get(url)
|
||||
driver.find_element(By.ID, 'general-tab').click()
|
||||
driver.find_element(By.ID, "general-tab").click()
|
||||
|
||||
wait = WebDriverWait(driver, 10)
|
||||
btn_apply_general = wait.until(EC.element_to_be_clickable((By.NAME, 'apply_general')))
|
||||
btn_apply_general = wait.until(
|
||||
EC.element_to_be_clickable((By.NAME, "apply_general"))
|
||||
)
|
||||
|
||||
el = driver.find_element(By.NAME, 'debugmode')
|
||||
el = driver.find_element(By.NAME, "debugmode")
|
||||
selected_option = Select(el).first_selected_option
|
||||
assert (selected_option.text == 'True')
|
||||
click_option(el, 'False')
|
||||
assert selected_option.text == "True"
|
||||
click_option(el, "False")
|
||||
|
||||
el = driver.find_element(By.NAME, 'debugui')
|
||||
el = driver.find_element(By.NAME, "debugui")
|
||||
selected_option = Select(el).first_selected_option
|
||||
assert (selected_option.text == 'False')
|
||||
click_option(el, 'True')
|
||||
assert selected_option.text == "False"
|
||||
click_option(el, "True")
|
||||
|
||||
btn_apply_general.click()
|
||||
time.sleep(1)
|
||||
|
||||
settings_path_0 = '/tmp/test_persistent/client0/basicswap.json'
|
||||
settings_path_0 = "/tmp/test_persistent/client0/basicswap.json"
|
||||
with open(settings_path_0) as fs:
|
||||
settings = json.load(fs)
|
||||
|
||||
assert (settings['debug'] is False)
|
||||
assert (settings['debug_ui'] is True)
|
||||
assert settings["debug"] is False
|
||||
assert settings["debug_ui"] is True
|
||||
|
||||
el = driver.find_element(By.NAME, 'showchart')
|
||||
el = driver.find_element(By.NAME, "showchart")
|
||||
selected_option = Select(el).first_selected_option
|
||||
assert (selected_option.text == 'True')
|
||||
click_option(el, 'False')
|
||||
assert selected_option.text == "True"
|
||||
click_option(el, "False")
|
||||
|
||||
difficult_text = '`~!@#$%^&*()-_=+[{}]\\|;:\'",<>./? '
|
||||
el = driver.find_element(By.NAME, 'chartapikey')
|
||||
difficult_text = "`~!@#$%^&*()-_=+[{}]\\|;:'\",<>./? "
|
||||
el = driver.find_element(By.NAME, "chartapikey")
|
||||
el.clear()
|
||||
el.send_keys(difficult_text)
|
||||
|
||||
btn_apply_chart = wait.until(EC.element_to_be_clickable((By.NAME, 'apply_chart')))
|
||||
btn_apply_chart = wait.until(EC.element_to_be_clickable((By.NAME, "apply_chart")))
|
||||
btn_apply_chart.click()
|
||||
time.sleep(1)
|
||||
|
||||
with open(settings_path_0) as fs:
|
||||
settings = json.load(fs)
|
||||
|
||||
assert (settings['show_chart'] is False)
|
||||
chart_api_key = bytes.fromhex(settings.get('chart_api_key_enc', '')).decode('utf-8')
|
||||
assert (chart_api_key == difficult_text)
|
||||
assert settings["show_chart"] is False
|
||||
chart_api_key = bytes.fromhex(settings.get("chart_api_key_enc", "")).decode("utf-8")
|
||||
assert chart_api_key == difficult_text
|
||||
|
||||
hex_text = default_chart_api_key
|
||||
el = driver.find_element(By.NAME, 'chartapikey')
|
||||
el = driver.find_element(By.NAME, "chartapikey")
|
||||
el.clear()
|
||||
el.send_keys(hex_text)
|
||||
btn_apply_chart = wait.until(EC.element_to_be_clickable((By.NAME, 'apply_chart')))
|
||||
btn_apply_chart = wait.until(EC.element_to_be_clickable((By.NAME, "apply_chart")))
|
||||
btn_apply_chart.click()
|
||||
time.sleep(1)
|
||||
|
||||
el = driver.find_element(By.NAME, 'chartapikey')
|
||||
assert el.get_property('value') == hex_text
|
||||
el = driver.find_element(By.NAME, "chartapikey")
|
||||
assert el.get_property("value") == hex_text
|
||||
|
||||
with open(settings_path_0) as fs:
|
||||
settings = json.load(fs)
|
||||
|
||||
assert (settings.get('chart_api_key') == hex_text)
|
||||
assert settings.get("chart_api_key") == hex_text
|
||||
|
||||
# Reset
|
||||
btn_apply_general = wait.until(EC.element_to_be_clickable((By.NAME, 'apply_general')))
|
||||
click_option(driver.find_element(By.NAME, 'debugmode'), 'True')
|
||||
click_option(driver.find_element(By.NAME, 'debugui'), 'False')
|
||||
btn_apply_general = wait.until(
|
||||
EC.element_to_be_clickable((By.NAME, "apply_general"))
|
||||
)
|
||||
click_option(driver.find_element(By.NAME, "debugmode"), "True")
|
||||
click_option(driver.find_element(By.NAME, "debugui"), "False")
|
||||
btn_apply_general.click()
|
||||
btn_apply_chart = wait.until(EC.element_to_be_clickable((By.NAME, 'apply_chart')))
|
||||
click_option(driver.find_element(By.NAME, 'showchart'), 'True')
|
||||
btn_apply_chart = wait.until(EC.element_to_be_clickable((By.NAME, "apply_chart")))
|
||||
click_option(driver.find_element(By.NAME, "showchart"), "True")
|
||||
btn_apply_chart.click()
|
||||
time.sleep(1)
|
||||
|
||||
# Apply XMR settings with blank nodes list
|
||||
driver.find_element(By.ID, 'coins-tab').click()
|
||||
btn_apply_monero = wait.until(EC.element_to_be_clickable((By.NAME, 'apply_monero')))
|
||||
el = driver.find_element(By.NAME, 'remotedaemonurls_monero')
|
||||
driver.find_element(By.ID, "coins-tab").click()
|
||||
btn_apply_monero = wait.until(EC.element_to_be_clickable((By.NAME, "apply_monero")))
|
||||
el = driver.find_element(By.NAME, "remotedaemonurls_monero")
|
||||
el.clear()
|
||||
btn_apply_monero.click()
|
||||
time.sleep(1)
|
||||
|
||||
with open(settings_path_0) as fs:
|
||||
settings = json.load(fs)
|
||||
assert (len(settings['chainclients']['monero']['remote_daemon_urls']) == 0)
|
||||
assert len(settings["chainclients"]["monero"]["remote_daemon_urls"]) == 0
|
||||
|
||||
btn_apply_monero = wait.until(EC.element_to_be_clickable((By.NAME, 'apply_monero')))
|
||||
el = driver.find_element(By.NAME, 'remotedaemonurls_monero')
|
||||
btn_apply_monero = wait.until(EC.element_to_be_clickable((By.NAME, "apply_monero")))
|
||||
el = driver.find_element(By.NAME, "remotedaemonurls_monero")
|
||||
el.clear()
|
||||
el.send_keys('node.xmr.to:18081\nnode1.xmr.to:18082')
|
||||
el.send_keys("node.xmr.to:18081\nnode1.xmr.to:18082")
|
||||
btn_apply_monero.click()
|
||||
time.sleep(1)
|
||||
|
||||
with open(settings_path_0) as fs:
|
||||
settings = json.load(fs)
|
||||
remotedaemonurls = settings['chainclients']['monero']['remote_daemon_urls']
|
||||
assert (len(remotedaemonurls) == 2)
|
||||
remotedaemonurls = settings["chainclients"]["monero"]["remote_daemon_urls"]
|
||||
assert len(remotedaemonurls) == 2
|
||||
|
||||
btn_apply_monero = wait.until(EC.element_to_be_clickable((By.NAME, 'apply_monero')))
|
||||
el = driver.find_element(By.NAME, 'remotedaemonurls_monero')
|
||||
btn_apply_monero = wait.until(EC.element_to_be_clickable((By.NAME, "apply_monero")))
|
||||
el = driver.find_element(By.NAME, "remotedaemonurls_monero")
|
||||
el.clear()
|
||||
btn_apply_monero.click()
|
||||
time.sleep(1)
|
||||
|
||||
with open(settings_path_0) as fs:
|
||||
settings = json.load(fs)
|
||||
assert (len(settings['chainclients']['monero']['remote_daemon_urls']) == 0)
|
||||
assert len(settings["chainclients"]["monero"]["remote_daemon_urls"]) == 0
|
||||
|
||||
print('Test Passed!')
|
||||
print("Test Passed!")
|
||||
|
||||
|
||||
def run_tests():
|
||||
|
@ -144,5 +148,5 @@ def run_tests():
|
|||
driver.close()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if __name__ == "__main__":
|
||||
run_tests()
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright (c) 2022-2023 tecnovert
|
||||
# Copyright (c) 2024 The Basicswap developers
|
||||
# Distributed under the MIT software license, see the accompanying
|
||||
# file LICENSE or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
|
@ -17,47 +18,48 @@ from util import get_driver
|
|||
def test_swap_dir(driver):
|
||||
node_1_port = 12701
|
||||
node_2_port = 12702
|
||||
node1_url = f'http://localhost:{node_1_port}'
|
||||
node2_url = f'http://localhost:{node_2_port}'
|
||||
node1_url = f"http://localhost:{node_1_port}"
|
||||
node2_url = f"http://localhost:{node_2_port}"
|
||||
|
||||
offer_data = {
|
||||
'addr_from': -1,
|
||||
'coin_from': 'PART',
|
||||
'coin_to': 'XMR',
|
||||
'amt_from': 1,
|
||||
'amt_to': 2,
|
||||
'lockhrs': 24}
|
||||
rv = read_json_api(node_1_port, 'offers/new', offer_data)
|
||||
offer0_id = rv['offer_id']
|
||||
"addr_from": -1,
|
||||
"coin_from": "PART",
|
||||
"coin_to": "XMR",
|
||||
"amt_from": 1,
|
||||
"amt_to": 2,
|
||||
"lockhrs": 24,
|
||||
}
|
||||
read_json_api(node_1_port, "offers/new", offer_data)
|
||||
|
||||
offer_data = {
|
||||
'addr_from': -1,
|
||||
'coin_from': 'PART',
|
||||
'coin_to': 'BTC',
|
||||
'amt_from': 3,
|
||||
'amt_to': 4,
|
||||
'lockhrs': 24}
|
||||
rv = read_json_api(node_1_port, 'offers/new', offer_data)
|
||||
offer0_id = rv['offer_id']
|
||||
"addr_from": -1,
|
||||
"coin_from": "PART",
|
||||
"coin_to": "BTC",
|
||||
"amt_from": 3,
|
||||
"amt_to": 4,
|
||||
"lockhrs": 24,
|
||||
}
|
||||
read_json_api(node_1_port, "offers/new", offer_data)
|
||||
|
||||
# Wait for offer to propagate
|
||||
offers_api_1 = read_json_api(node_1_port, 'offers')
|
||||
print('offers_api_1', offers_api_1)
|
||||
offers_api_1 = read_json_api(node_1_port, "offers")
|
||||
print("offers_api_1", offers_api_1)
|
||||
|
||||
offers_api_2 = read_json_api(node_2_port, 'offers')
|
||||
offers_api_2 = read_json_api(node_2_port, "offers")
|
||||
while len(offers_api_2) < 1:
|
||||
rv = read_json_api(node_2_port, 'offers')
|
||||
print('offers_api_2', offers_api_2)
|
||||
offers_api_2 = read_json_api(node_2_port, "offers")
|
||||
time.sleep(0.1)
|
||||
print("offers_api_2", offers_api_2)
|
||||
|
||||
driver.get(f'{node1_url}/offers')
|
||||
driver.get(f"{node1_url}/offers")
|
||||
time.sleep(1)
|
||||
|
||||
driver.get(f'{node2_url}/offers')
|
||||
driver.get(f"{node2_url}/offers")
|
||||
time.sleep(300)
|
||||
|
||||
raise ValueError('TODO')
|
||||
raise ValueError("TODO")
|
||||
|
||||
print('Test Passed!')
|
||||
print("Test Passed!")
|
||||
|
||||
|
||||
def run_tests():
|
||||
|
@ -68,5 +70,5 @@ def run_tests():
|
|||
driver.close()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if __name__ == "__main__":
|
||||
run_tests()
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright (c) 2022-2024 tecnovert
|
||||
# Copyright (c) 2024 The Basicswap developers
|
||||
# Distributed under the MIT software license, see the accompanying
|
||||
# file LICENSE or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
|
@ -16,109 +17,113 @@ from util import get_driver
|
|||
|
||||
|
||||
def test_wallets(driver):
|
||||
base_url = 'http://localhost:12701'
|
||||
node2_url = 'http://localhost:12702'
|
||||
base_url = "http://localhost:12701"
|
||||
node2_url = "http://localhost:12702"
|
||||
|
||||
# Check json coins data
|
||||
coins = json.loads(urlopen(base_url + '/json/coins').read())
|
||||
part_coin = [f for f in coins if f['ticker'] == 'PART'][0]
|
||||
part_id = part_coin['id']
|
||||
assert (part_id == 1)
|
||||
coins = json.loads(urlopen(base_url + "/json/coins").read())
|
||||
part_coin = [f for f in coins if f["ticker"] == "PART"][0]
|
||||
part_id = part_coin["id"]
|
||||
assert part_id == 1
|
||||
|
||||
# Check 404 pages
|
||||
url = base_url + '/unknown'
|
||||
url = base_url + "/unknown"
|
||||
driver.get(url)
|
||||
p1 = driver.find_element(By.TAG_NAME, 'body')
|
||||
assert ('Error 404' in p1.text)
|
||||
p1 = driver.find_element(By.TAG_NAME, "body")
|
||||
assert "Error 404" in p1.text
|
||||
|
||||
url = base_url + '/static/nothing.png'
|
||||
url = base_url + "/static/nothing.png"
|
||||
driver.get(url)
|
||||
p1 = driver.find_element(By.TAG_NAME, 'body')
|
||||
assert ('Error 404' in p1.text)
|
||||
p1 = driver.find_element(By.TAG_NAME, "body")
|
||||
assert "Error 404" in p1.text
|
||||
|
||||
url = base_url + '/wallet'
|
||||
url = base_url + "/wallet"
|
||||
driver.get(url)
|
||||
h2 = driver.find_element(By.TAG_NAME, 'h2')
|
||||
assert ('Error' in h2.text)
|
||||
p1 = driver.find_element(By.TAG_NAME, 'p')
|
||||
assert ('Wallet not specified' in p1.text)
|
||||
h2 = driver.find_element(By.TAG_NAME, "h2")
|
||||
assert "Error" in h2.text
|
||||
p1 = driver.find_element(By.TAG_NAME, "p")
|
||||
assert "Wallet not specified" in p1.text
|
||||
|
||||
url = base_url + '/wallet/NOCOIN'
|
||||
url = base_url + "/wallet/NOCOIN"
|
||||
driver.get(url)
|
||||
h2 = driver.find_element(By.TAG_NAME, 'h2')
|
||||
assert ('Error' in h2.text)
|
||||
p1 = driver.find_element(By.TAG_NAME, 'p')
|
||||
assert ('Unknown coin' in p1.text)
|
||||
h2 = driver.find_element(By.TAG_NAME, "h2")
|
||||
assert "Error" in h2.text
|
||||
p1 = driver.find_element(By.TAG_NAME, "p")
|
||||
assert "Unknown coin" in p1.text
|
||||
|
||||
driver.get(base_url + '/wallets')
|
||||
driver.get(base_url + "/wallets")
|
||||
time.sleep(1)
|
||||
driver.refresh()
|
||||
driver.find_element(By.ID, 'refresh').click()
|
||||
driver.find_element(By.ID, "refresh").click()
|
||||
time.sleep(1)
|
||||
driver.refresh()
|
||||
|
||||
print('Finding deposit address of node 2')
|
||||
driver.get(node2_url + '/wallet/PART')
|
||||
e = driver.find_element(By.ID, 'deposit_address')
|
||||
print("Finding deposit address of node 2")
|
||||
driver.get(node2_url + "/wallet/PART")
|
||||
e = driver.find_element(By.ID, "deposit_address")
|
||||
node2_deposit_address = e.text
|
||||
|
||||
print('Withdrawing from node 1')
|
||||
driver.get(base_url + '/wallet/PART')
|
||||
driver.find_element(By.NAME, f'to_{part_id}').send_keys(node2_deposit_address)
|
||||
driver.find_element(By.NAME, f'amt_{part_id}').send_keys('10')
|
||||
driver.find_element(By.NAME, f'withdraw_{part_id}').click()
|
||||
print("Withdrawing from node 1")
|
||||
driver.get(base_url + "/wallet/PART")
|
||||
driver.find_element(By.NAME, f"to_{part_id}").send_keys(node2_deposit_address)
|
||||
driver.find_element(By.NAME, f"amt_{part_id}").send_keys("10")
|
||||
driver.find_element(By.NAME, f"withdraw_{part_id}").click()
|
||||
driver.switch_to.alert.accept()
|
||||
time.sleep(1)
|
||||
elements = driver.find_elements(By.CLASS_NAME, 'infomsg')
|
||||
assert (len(elements) == 1)
|
||||
elements = driver.find_elements(By.CLASS_NAME, "infomsg")
|
||||
assert len(elements) == 1
|
||||
e = elements[0]
|
||||
assert ('Withdrew 10 rtPART (plain to plain) to address' in e.text)
|
||||
assert "Withdrew 10 rtPART (plain to plain) to address" in e.text
|
||||
|
||||
print('Locking UTXO')
|
||||
driver.get(base_url + '/rpc')
|
||||
el = driver.find_element(By.NAME, 'coin_type')
|
||||
for option in el.find_elements(By.TAG_NAME, 'option'):
|
||||
if option.text == 'Particl':
|
||||
print("Locking UTXO")
|
||||
driver.get(base_url + "/rpc")
|
||||
el = driver.find_element(By.NAME, "coin_type")
|
||||
for option in el.find_elements(By.TAG_NAME, "option"):
|
||||
if option.text == "Particl":
|
||||
option.click()
|
||||
break
|
||||
driver.find_element(By.NAME, 'cmd').send_keys('listunspent')
|
||||
driver.find_element(By.NAME, 'apply').click()
|
||||
driver.find_element(By.NAME, "cmd").send_keys("listunspent")
|
||||
driver.find_element(By.NAME, "apply").click()
|
||||
time.sleep(1)
|
||||
|
||||
text_value = driver.find_element(By.NAME, 'result').text
|
||||
utxos = json.loads(text_value.split('\n', 1)[1])
|
||||
text_value = driver.find_element(By.NAME, "result").text
|
||||
utxos = json.loads(text_value.split("\n", 1)[1])
|
||||
|
||||
lock_utxos = [{'txid': utxos[0]['txid'], 'vout': utxos[0]['vout']}]
|
||||
driver.find_element(By.NAME, 'cmd').send_keys('lockunspent false "{}"'.format(dumpje(lock_utxos)))
|
||||
driver.find_element(By.NAME, 'apply').click()
|
||||
lock_utxos = [{"txid": utxos[0]["txid"], "vout": utxos[0]["vout"]}]
|
||||
driver.find_element(By.NAME, "cmd").send_keys(
|
||||
'lockunspent false "{}"'.format(dumpje(lock_utxos))
|
||||
)
|
||||
driver.find_element(By.NAME, "apply").click()
|
||||
|
||||
print('Check for locked UTXO count')
|
||||
driver.get(base_url + '/wallet/PART')
|
||||
print("Check for locked UTXO count")
|
||||
driver.get(base_url + "/wallet/PART")
|
||||
found = False
|
||||
for i in range(5):
|
||||
try:
|
||||
el = driver.find_element(By.ID, 'locked_utxos')
|
||||
el = driver.find_element(By.ID, "locked_utxos")
|
||||
found = True
|
||||
break
|
||||
except Exception:
|
||||
continue
|
||||
driver.find_element(By.ID, 'refresh').click()
|
||||
driver.find_element(By.ID, "refresh").click()
|
||||
time.sleep(2)
|
||||
found = True
|
||||
assert (found)
|
||||
assert found
|
||||
driver.refresh()
|
||||
|
||||
print('Unlocking UTXO')
|
||||
driver.get(base_url + '/rpc')
|
||||
el = driver.find_element(By.NAME, 'coin_type')
|
||||
for option in el.find_elements(By.TAG_NAME, 'option'):
|
||||
if option.text == 'Particl':
|
||||
print("Unlocking UTXO")
|
||||
driver.get(base_url + "/rpc")
|
||||
el = driver.find_element(By.NAME, "coin_type")
|
||||
for option in el.find_elements(By.TAG_NAME, "option"):
|
||||
if option.text == "Particl":
|
||||
option.click()
|
||||
break
|
||||
driver.find_element(By.NAME, 'cmd').send_keys('lockunspent true "{}"'.format(dumpje(lock_utxos)))
|
||||
driver.find_element(By.NAME, 'apply').click()
|
||||
driver.find_element(By.NAME, "cmd").send_keys(
|
||||
'lockunspent true "{}"'.format(dumpje(lock_utxos))
|
||||
)
|
||||
driver.find_element(By.NAME, "apply").click()
|
||||
|
||||
print('Test Passed!')
|
||||
print("Test Passed!")
|
||||
|
||||
|
||||
def run_tests():
|
||||
|
@ -129,5 +134,5 @@ def run_tests():
|
|||
driver.close()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if __name__ == "__main__":
|
||||
run_tests()
|
||||
|
|
|
@ -10,31 +10,34 @@ import os
|
|||
from selenium.webdriver.common.by import By
|
||||
|
||||
|
||||
BSX_0_PORT = int(os.getenv('BSX_0_PORT', 12701))
|
||||
BSX_1_PORT = int(os.getenv('BSX_1_PORT', BSX_0_PORT + 1))
|
||||
BSX_2_PORT = int(os.getenv('BSX_1_PORT', BSX_0_PORT + 2))
|
||||
BSX_0_PORT = int(os.getenv("BSX_0_PORT", 12701))
|
||||
BSX_1_PORT = int(os.getenv("BSX_1_PORT", BSX_0_PORT + 1))
|
||||
BSX_2_PORT = int(os.getenv("BSX_1_PORT", BSX_0_PORT + 2))
|
||||
|
||||
BSX_SELENIUM_DRIVER = os.getenv('BSX_SELENIUM_DRIVER', 'firefox')
|
||||
BSX_SELENIUM_DRIVER = os.getenv("BSX_SELENIUM_DRIVER", "firefox")
|
||||
|
||||
|
||||
def get_driver():
|
||||
if BSX_SELENIUM_DRIVER == 'firefox':
|
||||
if BSX_SELENIUM_DRIVER == "firefox":
|
||||
from selenium.webdriver import Firefox, FirefoxOptions
|
||||
|
||||
driver = Firefox(options=FirefoxOptions())
|
||||
elif BSX_SELENIUM_DRIVER == 'chrome':
|
||||
elif BSX_SELENIUM_DRIVER == "chrome":
|
||||
from selenium.webdriver import Chrome, ChromeOptions
|
||||
|
||||
driver = Chrome(options=ChromeOptions())
|
||||
elif BSX_SELENIUM_DRIVER == 'safari':
|
||||
elif BSX_SELENIUM_DRIVER == "safari":
|
||||
from selenium.webdriver import Safari, SafariOptions
|
||||
|
||||
driver = Safari(options=SafariOptions())
|
||||
else:
|
||||
raise ValueError('Unknown driver ' + BSX_SELENIUM_DRIVER)
|
||||
raise ValueError("Unknown driver " + BSX_SELENIUM_DRIVER)
|
||||
|
||||
return driver
|
||||
|
||||
|
||||
def click_option(el, option_text):
|
||||
for option in el.find_elements(By.TAG_NAME, 'option'):
|
||||
for option in el.find_elements(By.TAG_NAME, "option"):
|
||||
if option.text == option_text:
|
||||
option.click()
|
||||
break
|
||||
|
|
|
@ -47,13 +47,17 @@ from .test_xmr import test_delay_event, callnoderpc
|
|||
from coincurve.ecdsaotves import (
|
||||
ecdsaotves_enc_sign,
|
||||
ecdsaotves_enc_verify,
|
||||
ecdsaotves_dec_sig
|
||||
ecdsaotves_dec_sig,
|
||||
)
|
||||
|
||||
BITCOINCASH_BINDIR = os.path.expanduser(os.getenv('BITCOINCASH_BINDIR', os.path.join(cfg.DEFAULT_TEST_BINDIR, 'bitcoincash')))
|
||||
BITCOINCASHD = os.getenv('BITCOINCASHD', 'bitcoind' + cfg.bin_suffix)
|
||||
BITCOINCASH_CLI = os.getenv('BITCOINCASH_CLI', 'bitcoin-cli' + cfg.bin_suffix)
|
||||
BITCOINCASH_TX = os.getenv('BITCOINCASH_TX', 'bitcoin-tx' + cfg.bin_suffix)
|
||||
BITCOINCASH_BINDIR = os.path.expanduser(
|
||||
os.getenv(
|
||||
"BITCOINCASH_BINDIR", os.path.join(cfg.DEFAULT_TEST_BINDIR, "bitcoincash")
|
||||
)
|
||||
)
|
||||
BITCOINCASHD = os.getenv("BITCOINCASHD", "bitcoind" + cfg.bin_suffix)
|
||||
BITCOINCASH_CLI = os.getenv("BITCOINCASH_CLI", "bitcoin-cli" + cfg.bin_suffix)
|
||||
BITCOINCASH_TX = os.getenv("BITCOINCASH_TX", "bitcoin-tx" + cfg.bin_suffix)
|
||||
|
||||
BCH_BASE_PORT = 41792
|
||||
BCH_BASE_RPC_PORT = 42792
|
||||
|
@ -63,12 +67,19 @@ BCH_BASE_TOR_PORT = 43732
|
|||
logger = logging.getLogger()
|
||||
|
||||
|
||||
bch_lock_spend_tx = '0200000001bfc6bbb47851441c7827059ae337a06aa9064da7f9537eb9243e45766c3dd34c00000000d8473045022100a0161ea14d3b41ed41250c8474fc8ec6ce1cab8df7f401e69ecf77c2ab63d82102207a2a57ddf2ea400e09ea059f3b261da96f5098858b17239931f3cc2fb929bb2a4c8ec3519dc4519d02e80300c600cc949d00ce00d18800cf00d28800d000d39d00cb641976a91481ec21969399d15c26af089d5db437ead066c5ba88ac00cd788821024ffcc0481629866671d89f05f3da813a2aacec1b52e69b8c0c586b665f5d4574ba6752b27523aa20df65a90e9becc316ff5aca44d4e06dfaade56622f32bafa197aba706c5e589758700cd87680000000001251cde06000000001976a91481ec21969399d15c26af089d5db437ead066c5ba88ac00000000'
|
||||
bch_lock_script = 'c3519dc4519d02e80300c600cc949d00ce00d18800cf00d28800d000d39d00cb641976a91481ec21969399d15c26af089d5db437ead066c5ba88ac00cd788821024ffcc0481629866671d89f05f3da813a2aacec1b52e69b8c0c586b665f5d4574ba6752b27523aa20df65a90e9becc316ff5aca44d4e06dfaade56622f32bafa197aba706c5e589758700cd8768'
|
||||
bch_lock_spend_script = '473045022100a0161ea14d3b41ed41250c8474fc8ec6ce1cab8df7f401e69ecf77c2ab63d82102207a2a57ddf2ea400e09ea059f3b261da96f5098858b17239931f3cc2fb929bb2a4c8ec3519dc4519d02e80300c600cc949d00ce00d18800cf00d28800d000d39d00cb641976a91481ec21969399d15c26af089d5db437ead066c5ba88ac00cd788821024ffcc0481629866671d89f05f3da813a2aacec1b52e69b8c0c586b665f5d4574ba6752b27523aa20df65a90e9becc316ff5aca44d4e06dfaade56622f32bafa197aba706c5e589758700cd8768'
|
||||
bch_lock_swipe_script = '4c8fc3519dc4519d02e80300c600cc949d00ce00d18800cf00d28800d000d39d00cb641976a9141ab50aedd2e48297073f0f6eef46f97b37c9354e88ac00cd7888210234fe304a5b129b8265c177c92aa40b7840e8303f8b0fcca2359023163c7c2768ba670120b27523aa20191b09e40d1277fa14fea1e9b41e4fcc4528c9cb77e39e1b7b1a0b3332180cb78700cd8768'
|
||||
bch_lock_spend_tx = "0200000001bfc6bbb47851441c7827059ae337a06aa9064da7f9537eb9243e45766c3dd34c00000000d8473045022100a0161ea14d3b41ed41250c8474fc8ec6ce1cab8df7f401e69ecf77c2ab63d82102207a2a57ddf2ea400e09ea059f3b261da96f5098858b17239931f3cc2fb929bb2a4c8ec3519dc4519d02e80300c600cc949d00ce00d18800cf00d28800d000d39d00cb641976a91481ec21969399d15c26af089d5db437ead066c5ba88ac00cd788821024ffcc0481629866671d89f05f3da813a2aacec1b52e69b8c0c586b665f5d4574ba6752b27523aa20df65a90e9becc316ff5aca44d4e06dfaade56622f32bafa197aba706c5e589758700cd87680000000001251cde06000000001976a91481ec21969399d15c26af089d5db437ead066c5ba88ac00000000"
|
||||
bch_lock_script = "c3519dc4519d02e80300c600cc949d00ce00d18800cf00d28800d000d39d00cb641976a91481ec21969399d15c26af089d5db437ead066c5ba88ac00cd788821024ffcc0481629866671d89f05f3da813a2aacec1b52e69b8c0c586b665f5d4574ba6752b27523aa20df65a90e9becc316ff5aca44d4e06dfaade56622f32bafa197aba706c5e589758700cd8768"
|
||||
bch_lock_spend_script = "473045022100a0161ea14d3b41ed41250c8474fc8ec6ce1cab8df7f401e69ecf77c2ab63d82102207a2a57ddf2ea400e09ea059f3b261da96f5098858b17239931f3cc2fb929bb2a4c8ec3519dc4519d02e80300c600cc949d00ce00d18800cf00d28800d000d39d00cb641976a91481ec21969399d15c26af089d5db437ead066c5ba88ac00cd788821024ffcc0481629866671d89f05f3da813a2aacec1b52e69b8c0c586b665f5d4574ba6752b27523aa20df65a90e9becc316ff5aca44d4e06dfaade56622f32bafa197aba706c5e589758700cd8768"
|
||||
bch_lock_swipe_script = "4c8fc3519dc4519d02e80300c600cc949d00ce00d18800cf00d28800d000d39d00cb641976a9141ab50aedd2e48297073f0f6eef46f97b37c9354e88ac00cd7888210234fe304a5b129b8265c177c92aa40b7840e8303f8b0fcca2359023163c7c2768ba670120b27523aa20191b09e40d1277fa14fea1e9b41e4fcc4528c9cb77e39e1b7b1a0b3332180cb78700cd8768"
|
||||
|
||||
coin_settings = {'rpcport': 0, 'rpcauth': 'none', 'blocks_confirmed': 1, 'conf_target': 1, 'use_segwit': False, 'connection_type': 'rpc'}
|
||||
coin_settings = {
|
||||
"rpcport": 0,
|
||||
"rpcauth": "none",
|
||||
"blocks_confirmed": 1,
|
||||
"conf_target": 1,
|
||||
"use_segwit": False,
|
||||
"connection_type": "rpc",
|
||||
}
|
||||
|
||||
|
||||
class TestXmrBchSwapInterface(unittest.TestCase):
|
||||
|
@ -79,12 +90,16 @@ class TestXmrBchSwapInterface(unittest.TestCase):
|
|||
ci.extractScriptLockScriptValues(script_bytes)
|
||||
|
||||
script_bytes = CScript(bytes.fromhex(bch_lock_spend_script))
|
||||
signature, mining_fee, out_1, out_2, public_key, timelock = ci.extractScriptLockScriptValuesFromScriptSig(script_bytes)
|
||||
ensure(signature is not None, 'signature not present')
|
||||
signature, mining_fee, out_1, out_2, public_key, timelock = (
|
||||
ci.extractScriptLockScriptValuesFromScriptSig(script_bytes)
|
||||
)
|
||||
ensure(signature is not None, "signature not present")
|
||||
|
||||
script_bytes = CScript(bytes.fromhex(bch_lock_swipe_script))
|
||||
signature, mining_fee, out_1, out_2, public_key, timelock = ci.extractScriptLockScriptValuesFromScriptSig(script_bytes)
|
||||
ensure(signature is None, 'signature present')
|
||||
signature, mining_fee, out_1, out_2, public_key, timelock = (
|
||||
ci.extractScriptLockScriptValuesFromScriptSig(script_bytes)
|
||||
)
|
||||
ensure(signature is None, "signature present")
|
||||
|
||||
|
||||
class TestBCH(BasicSwapTest):
|
||||
|
@ -100,26 +115,47 @@ class TestBCH(BasicSwapTest):
|
|||
@classmethod
|
||||
def prepareExtraDataDir(cls, i):
|
||||
if not cls.restore_instance:
|
||||
data_dir = prepareDataDir(cfg.TEST_DATADIRS, i, 'bitcoin.conf', 'bch_', base_p2p_port=BCH_BASE_PORT, base_rpc_port=BCH_BASE_RPC_PORT)
|
||||
data_dir = prepareDataDir(
|
||||
cfg.TEST_DATADIRS,
|
||||
i,
|
||||
"bitcoin.conf",
|
||||
"bch_",
|
||||
base_p2p_port=BCH_BASE_PORT,
|
||||
base_rpc_port=BCH_BASE_RPC_PORT,
|
||||
)
|
||||
|
||||
# Rewrite conf file
|
||||
config_filename: str = os.path.join(cfg.TEST_DATADIRS, 'bch_' + str(i), 'bitcoin.conf')
|
||||
with open(config_filename, 'r') as fp:
|
||||
config_filename: str = os.path.join(
|
||||
cfg.TEST_DATADIRS, "bch_" + str(i), "bitcoin.conf"
|
||||
)
|
||||
with open(config_filename, "r") as fp:
|
||||
lines = fp.readlines()
|
||||
with open(config_filename, 'w') as fp:
|
||||
with open(config_filename, "w") as fp:
|
||||
for line in lines:
|
||||
if not line.startswith('findpeers'):
|
||||
if not line.startswith("findpeers"):
|
||||
fp.write(line)
|
||||
|
||||
if os.path.exists(os.path.join(BITCOINCASH_BINDIR, 'bitcoin-wallet')):
|
||||
if os.path.exists(os.path.join(BITCOINCASH_BINDIR, "bitcoin-wallet")):
|
||||
try:
|
||||
callrpc_cli(BITCOINCASH_BINDIR, data_dir, 'regtest', '-wallet=wallet.dat create', 'bitcoin-wallet')
|
||||
callrpc_cli(
|
||||
BITCOINCASH_BINDIR,
|
||||
data_dir,
|
||||
"regtest",
|
||||
"-wallet=wallet.dat create",
|
||||
"bitcoin-wallet",
|
||||
)
|
||||
except Exception as e:
|
||||
logging.warning('bch: bitcoin-wallet create failed')
|
||||
logging.warning("bch: bitcoin-wallet create failed")
|
||||
raise e
|
||||
|
||||
cls.bch_daemons.append(startDaemon(os.path.join(cfg.TEST_DATADIRS, 'bch_' + str(i)), BITCOINCASH_BINDIR, BITCOINCASHD))
|
||||
logging.info('BCH: Started %s %d', BITCOINCASHD, cls.bch_daemons[-1].handle.pid)
|
||||
cls.bch_daemons.append(
|
||||
startDaemon(
|
||||
os.path.join(cfg.TEST_DATADIRS, "bch_" + str(i)),
|
||||
BITCOINCASH_BINDIR,
|
||||
BITCOINCASHD,
|
||||
)
|
||||
)
|
||||
logging.info("BCH: Started %s %d", BITCOINCASHD, cls.bch_daemons[-1].handle.pid)
|
||||
waitForRPC(make_rpc_func(i, base_rpc_port=BCH_BASE_RPC_PORT), test_delay_event)
|
||||
|
||||
@classmethod
|
||||
|
@ -128,24 +164,36 @@ class TestBCH(BasicSwapTest):
|
|||
|
||||
@classmethod
|
||||
def prepareExtraCoins(cls):
|
||||
cls.bch_addr = callnoderpc(0, 'getnewaddress', ['mining_addr'], base_rpc_port=BCH_BASE_RPC_PORT, wallet='wallet.dat')
|
||||
cls.bch_addr = callnoderpc(
|
||||
0,
|
||||
"getnewaddress",
|
||||
["mining_addr"],
|
||||
base_rpc_port=BCH_BASE_RPC_PORT,
|
||||
wallet="wallet.dat",
|
||||
)
|
||||
if not cls.restore_instance:
|
||||
num_blocks: int = 200
|
||||
logging.info('Mining %d BitcoinCash blocks to %s', num_blocks, cls.bch_addr)
|
||||
callnoderpc(0, 'generatetoaddress', [num_blocks, cls.bch_addr], base_rpc_port=BCH_BASE_RPC_PORT, wallet='wallet.dat')
|
||||
logging.info("Mining %d BitcoinCash blocks to %s", num_blocks, cls.bch_addr)
|
||||
callnoderpc(
|
||||
0,
|
||||
"generatetoaddress",
|
||||
[num_blocks, cls.bch_addr],
|
||||
base_rpc_port=BCH_BASE_RPC_PORT,
|
||||
wallet="wallet.dat",
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def addCoinSettings(cls, settings, datadir, node_id):
|
||||
|
||||
settings['chainclients']['bitcoincash'] = {
|
||||
'connection_type': 'rpc',
|
||||
'manage_daemon': False,
|
||||
'rpcport': BCH_BASE_RPC_PORT + node_id,
|
||||
'rpcuser': 'test' + str(node_id),
|
||||
'rpcpassword': 'test_pass' + str(node_id),
|
||||
'datadir': os.path.join(datadir, 'bch_' + str(node_id)),
|
||||
'bindir': BITCOINCASH_BINDIR,
|
||||
'use_segwit': False,
|
||||
settings["chainclients"]["bitcoincash"] = {
|
||||
"connection_type": "rpc",
|
||||
"manage_daemon": False,
|
||||
"rpcport": BCH_BASE_RPC_PORT + node_id,
|
||||
"rpcuser": "test" + str(node_id),
|
||||
"rpcpassword": "test_pass" + str(node_id),
|
||||
"datadir": os.path.join(datadir, "bch_" + str(node_id)),
|
||||
"bindir": BITCOINCASH_BINDIR,
|
||||
"use_segwit": False,
|
||||
}
|
||||
|
||||
@classmethod
|
||||
|
@ -154,60 +202,88 @@ class TestBCH(BasicSwapTest):
|
|||
ci0 = cls.swap_clients[0].ci(cls.test_coin)
|
||||
try:
|
||||
if cls.bch_addr is not None:
|
||||
ci0.rpc_wallet('generatetoaddress', [1, cls.bch_addr])
|
||||
ci0.rpc_wallet("generatetoaddress", [1, cls.bch_addr])
|
||||
except Exception as e:
|
||||
logging.warning('coins_loop generate {}'.format(e))
|
||||
logging.warning("coins_loop generate {}".format(e))
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
logging.info('Finalising Bitcoincash Test')
|
||||
logging.info("Finalising Bitcoincash Test")
|
||||
super(TestBCH, cls).tearDownClass()
|
||||
|
||||
stopDaemons(cls.bch_daemons)
|
||||
cls.bch_daemons.clear()
|
||||
|
||||
def mineBlock(self, num_blocks=1):
|
||||
self.callnoderpc('generatetoaddress', [num_blocks, self.bch_addr])
|
||||
self.callnoderpc("generatetoaddress", [num_blocks, self.bch_addr])
|
||||
|
||||
def check_softfork_active(self, feature_name):
|
||||
return True
|
||||
|
||||
def test_001_nested_segwit(self):
|
||||
logging.info('---------- Test {} p2sh nested segwit'.format(self.test_coin.name))
|
||||
logging.info('Skipped')
|
||||
logging.info(
|
||||
"---------- Test {} p2sh nested segwit".format(self.test_coin.name)
|
||||
)
|
||||
logging.info("Skipped")
|
||||
|
||||
def test_002_native_segwit(self):
|
||||
logging.info('---------- Test {} p2sh native segwit'.format(self.test_coin.name))
|
||||
logging.info('Skipped')
|
||||
logging.info(
|
||||
"---------- Test {} p2sh native segwit".format(self.test_coin.name)
|
||||
)
|
||||
logging.info("Skipped")
|
||||
|
||||
def test_003_cltv(self):
|
||||
logging.info('---------- Test {} cltv'.format(self.test_coin.name))
|
||||
logging.info("---------- Test {} cltv".format(self.test_coin.name))
|
||||
|
||||
ci = self.swap_clients[0].ci(self.test_coin)
|
||||
|
||||
self.check_softfork_active('bip65')
|
||||
self.check_softfork_active("bip65")
|
||||
|
||||
chain_height = self.callnoderpc('getblockcount')
|
||||
script = CScript([chain_height + 3, OP_CHECKLOCKTIMEVERIFY, ])
|
||||
chain_height = self.callnoderpc("getblockcount")
|
||||
script = CScript(
|
||||
[
|
||||
chain_height + 3,
|
||||
OP_CHECKLOCKTIMEVERIFY,
|
||||
]
|
||||
)
|
||||
|
||||
script_dest = ci.getScriptDest(script)
|
||||
tx = CTransaction()
|
||||
tx.nVersion = ci.txVersion()
|
||||
tx.vout.append(ci.txoType()(ci.make_int(1.1), script_dest))
|
||||
tx_hex = ToHex(tx)
|
||||
tx_funded = ci.rpc_wallet('fundrawtransaction', [tx_hex])
|
||||
utxo_pos = 0 if tx_funded['changepos'] == 1 else 1
|
||||
tx_signed = ci.rpc_wallet('signrawtransactionwithwallet', [tx_funded['hex'], ])['hex']
|
||||
txid = ci.rpc('sendrawtransaction', [tx_signed, ])
|
||||
tx_funded = ci.rpc_wallet("fundrawtransaction", [tx_hex])
|
||||
utxo_pos = 0 if tx_funded["changepos"] == 1 else 1
|
||||
tx_signed = ci.rpc_wallet(
|
||||
"signrawtransactionwithwallet",
|
||||
[
|
||||
tx_funded["hex"],
|
||||
],
|
||||
)["hex"]
|
||||
txid = ci.rpc(
|
||||
"sendrawtransaction",
|
||||
[
|
||||
tx_signed,
|
||||
],
|
||||
)
|
||||
|
||||
addr_out = ci.rpc_wallet('getnewaddress', ['cltv test'])
|
||||
addr_out = ci.rpc_wallet("getnewaddress", ["cltv test"])
|
||||
pkh = ci.decodeAddress(addr_out)
|
||||
script_out = ci.getScriptForPubkeyHash(pkh)
|
||||
|
||||
tx_spend = CTransaction()
|
||||
tx_spend.nVersion = ci.txVersion()
|
||||
tx_spend.nLockTime = chain_height + 3
|
||||
tx_spend.vin.append(CTxIn(COutPoint(int(txid, 16), utxo_pos), scriptSig=CScript([script,])))
|
||||
tx_spend.vin.append(
|
||||
CTxIn(
|
||||
COutPoint(int(txid, 16), utxo_pos),
|
||||
scriptSig=CScript(
|
||||
[
|
||||
script,
|
||||
]
|
||||
),
|
||||
)
|
||||
)
|
||||
tx_spend.vout.append(ci.txoType()(ci.make_int(1.0999), script_out))
|
||||
tx_spend_hex = ToHex(tx_spend)
|
||||
|
||||
|
@ -216,116 +292,205 @@ class TestBCH(BasicSwapTest):
|
|||
|
||||
for tx_hex in [tx_spend_invalid_hex, tx_spend_hex]:
|
||||
try:
|
||||
txid = self.callnoderpc('sendrawtransaction', [tx_hex, ])
|
||||
txid = self.callnoderpc(
|
||||
"sendrawtransaction",
|
||||
[
|
||||
tx_hex,
|
||||
],
|
||||
)
|
||||
except Exception as e:
|
||||
assert ('non-final' in str(e))
|
||||
assert "non-final" in str(e)
|
||||
else:
|
||||
assert False, 'Should fail'
|
||||
assert False, "Should fail"
|
||||
|
||||
self.mineBlock(5)
|
||||
try:
|
||||
txid = ci.rpc('sendrawtransaction', [tx_spend_invalid_hex, ])
|
||||
txid = ci.rpc(
|
||||
"sendrawtransaction",
|
||||
[
|
||||
tx_spend_invalid_hex,
|
||||
],
|
||||
)
|
||||
except Exception as e:
|
||||
assert ('Locktime requirement not satisfied' in str(e))
|
||||
assert "Locktime requirement not satisfied" in str(e)
|
||||
else:
|
||||
assert False, 'Should fail'
|
||||
assert False, "Should fail"
|
||||
|
||||
txid = ci.rpc('sendrawtransaction', [tx_spend_hex, ])
|
||||
txid = ci.rpc(
|
||||
"sendrawtransaction",
|
||||
[
|
||||
tx_spend_hex,
|
||||
],
|
||||
)
|
||||
self.mineBlock()
|
||||
ro = ci.rpc_wallet('listreceivedbyaddress', [0, ])
|
||||
ro = ci.rpc_wallet(
|
||||
"listreceivedbyaddress",
|
||||
[
|
||||
0,
|
||||
],
|
||||
)
|
||||
sum_addr = 0
|
||||
for entry in ro:
|
||||
if entry['address'] == addr_out:
|
||||
sum_addr += entry['amount']
|
||||
assert (sum_addr == 1.0999)
|
||||
if entry["address"] == addr_out:
|
||||
sum_addr += entry["amount"]
|
||||
assert sum_addr == 1.0999
|
||||
|
||||
# Ensure tx was mined
|
||||
tx_wallet = ci.rpc_wallet('gettransaction', [txid, ])
|
||||
assert (len(tx_wallet['blockhash']) == 64)
|
||||
tx_wallet = ci.rpc_wallet(
|
||||
"gettransaction",
|
||||
[
|
||||
txid,
|
||||
],
|
||||
)
|
||||
assert len(tx_wallet["blockhash"]) == 64
|
||||
|
||||
def test_004_csv(self):
|
||||
logging.info('---------- Test {} csv'.format(self.test_coin.name))
|
||||
logging.info("---------- Test {} csv".format(self.test_coin.name))
|
||||
|
||||
swap_clients = self.swap_clients
|
||||
ci = self.swap_clients[0].ci(self.test_coin)
|
||||
|
||||
self.check_softfork_active('csv')
|
||||
self.check_softfork_active("csv")
|
||||
|
||||
script = CScript([3, OP_CHECKSEQUENCEVERIFY, ])
|
||||
script = CScript(
|
||||
[
|
||||
3,
|
||||
OP_CHECKSEQUENCEVERIFY,
|
||||
]
|
||||
)
|
||||
|
||||
script_dest = ci.getScriptDest(script)
|
||||
tx = CTransaction()
|
||||
tx.nVersion = ci.txVersion()
|
||||
tx.vout.append(ci.txoType()(ci.make_int(1.1), script_dest))
|
||||
tx_hex = ToHex(tx)
|
||||
tx_funded = ci.rpc_wallet('fundrawtransaction', [tx_hex])
|
||||
utxo_pos = 0 if tx_funded['changepos'] == 1 else 1
|
||||
tx_signed = ci.rpc_wallet('signrawtransactionwithwallet', [tx_funded['hex'], ])['hex']
|
||||
txid = ci.rpc('sendrawtransaction', [tx_signed, ])
|
||||
tx_funded = ci.rpc_wallet("fundrawtransaction", [tx_hex])
|
||||
utxo_pos = 0 if tx_funded["changepos"] == 1 else 1
|
||||
tx_signed = ci.rpc_wallet(
|
||||
"signrawtransactionwithwallet",
|
||||
[
|
||||
tx_funded["hex"],
|
||||
],
|
||||
)["hex"]
|
||||
txid = ci.rpc(
|
||||
"sendrawtransaction",
|
||||
[
|
||||
tx_signed,
|
||||
],
|
||||
)
|
||||
|
||||
addr_out = ci.rpc_wallet('getnewaddress', ['csv test'])
|
||||
addr_out = ci.rpc_wallet("getnewaddress", ["csv test"])
|
||||
pkh = ci.decodeAddress(addr_out)
|
||||
script_out = ci.getScriptForPubkeyHash(pkh)
|
||||
|
||||
# Double check output type
|
||||
prev_tx = ci.rpc('decoderawtransaction', [tx_signed, ])
|
||||
assert (prev_tx['vout'][utxo_pos]['scriptPubKey']['type'] == 'scripthash')
|
||||
prev_tx = ci.rpc(
|
||||
"decoderawtransaction",
|
||||
[
|
||||
tx_signed,
|
||||
],
|
||||
)
|
||||
assert prev_tx["vout"][utxo_pos]["scriptPubKey"]["type"] == "scripthash"
|
||||
|
||||
tx_spend = CTransaction()
|
||||
tx_spend.nVersion = ci.txVersion()
|
||||
tx_spend.vin.append(CTxIn(COutPoint(int(txid, 16), utxo_pos),
|
||||
nSequence=3,
|
||||
scriptSig=CScript([script,])))
|
||||
tx_spend.vin.append(
|
||||
CTxIn(
|
||||
COutPoint(int(txid, 16), utxo_pos),
|
||||
nSequence=3,
|
||||
scriptSig=CScript(
|
||||
[
|
||||
script,
|
||||
]
|
||||
),
|
||||
)
|
||||
)
|
||||
tx_spend.vout.append(ci.txoType()(ci.make_int(1.0999), script_out))
|
||||
tx_spend_hex = ToHex(tx_spend)
|
||||
try:
|
||||
txid = ci.rpc('sendrawtransaction', [tx_spend_hex, ])
|
||||
txid = ci.rpc(
|
||||
"sendrawtransaction",
|
||||
[
|
||||
tx_spend_hex,
|
||||
],
|
||||
)
|
||||
except Exception as e:
|
||||
assert ('non-BIP68-final' in str(e))
|
||||
assert "non-BIP68-final" in str(e)
|
||||
else:
|
||||
assert False, 'Should fail'
|
||||
assert False, "Should fail"
|
||||
|
||||
self.mineBlock(3)
|
||||
txid = ci.rpc('sendrawtransaction', [tx_spend_hex, ])
|
||||
txid = ci.rpc(
|
||||
"sendrawtransaction",
|
||||
[
|
||||
tx_spend_hex,
|
||||
],
|
||||
)
|
||||
self.mineBlock(1)
|
||||
ro = ci.rpc_wallet('listreceivedbyaddress', [0, ])
|
||||
ro = ci.rpc_wallet(
|
||||
"listreceivedbyaddress",
|
||||
[
|
||||
0,
|
||||
],
|
||||
)
|
||||
sum_addr = 0
|
||||
for entry in ro:
|
||||
if entry['address'] == addr_out:
|
||||
sum_addr += entry['amount']
|
||||
assert (sum_addr == 1.0999)
|
||||
if entry["address"] == addr_out:
|
||||
sum_addr += entry["amount"]
|
||||
assert sum_addr == 1.0999
|
||||
|
||||
# Ensure tx was mined
|
||||
tx_wallet = ci.rpc_wallet('gettransaction', [txid, ])
|
||||
assert (len(tx_wallet['blockhash']) == 64)
|
||||
tx_wallet = ci.rpc_wallet(
|
||||
"gettransaction",
|
||||
[
|
||||
txid,
|
||||
],
|
||||
)
|
||||
assert len(tx_wallet["blockhash"]) == 64
|
||||
|
||||
def test_005_watchonly(self):
|
||||
logging.info('---------- Test {} watchonly'.format(self.test_coin.name))
|
||||
logging.info("---------- Test {} watchonly".format(self.test_coin.name))
|
||||
ci = self.swap_clients[0].ci(self.test_coin)
|
||||
ci1 = self.swap_clients[1].ci(self.test_coin)
|
||||
|
||||
addr = ci.rpc_wallet('getnewaddress', ['watchonly test'])
|
||||
ro = ci1.rpc_wallet('importaddress', [addr, '', False])
|
||||
txid = ci.rpc_wallet('sendtoaddress', [addr, 1.0])
|
||||
tx_hex = ci.rpc('getrawtransaction', [txid, ])
|
||||
ci1.rpc_wallet('sendrawtransaction', [tx_hex, ])
|
||||
ro = ci1.rpc_wallet('gettransaction', [txid, ])
|
||||
assert (ro['txid'] == txid)
|
||||
addr = ci.rpc_wallet("getnewaddress", ["watchonly test"])
|
||||
ro = ci1.rpc_wallet("importaddress", [addr, "", False])
|
||||
txid = ci.rpc_wallet("sendtoaddress", [addr, 1.0])
|
||||
tx_hex = ci.rpc(
|
||||
"getrawtransaction",
|
||||
[
|
||||
txid,
|
||||
],
|
||||
)
|
||||
ci1.rpc_wallet(
|
||||
"sendrawtransaction",
|
||||
[
|
||||
tx_hex,
|
||||
],
|
||||
)
|
||||
ro = ci1.rpc_wallet(
|
||||
"gettransaction",
|
||||
[
|
||||
txid,
|
||||
],
|
||||
)
|
||||
assert ro["txid"] == txid
|
||||
|
||||
def test_006_getblock_verbosity(self):
|
||||
super().test_006_getblock_verbosity()
|
||||
|
||||
def test_007_hdwallet(self):
|
||||
logging.info('---------- Test {} hdwallet'.format(self.test_coin.name))
|
||||
logging.info("---------- Test {} hdwallet".format(self.test_coin.name))
|
||||
|
||||
test_seed = '8e54a313e6df8918df6d758fafdbf127a115175fdd2238d0e908dd8093c9ac3b'
|
||||
test_wif = self.swap_clients[0].ci(self.test_coin).encodeKey(bytes.fromhex(test_seed))
|
||||
test_seed = "8e54a313e6df8918df6d758fafdbf127a115175fdd2238d0e908dd8093c9ac3b"
|
||||
test_wif = (
|
||||
self.swap_clients[0].ci(self.test_coin).encodeKey(bytes.fromhex(test_seed))
|
||||
)
|
||||
new_wallet_name = random.randbytes(10).hex()
|
||||
self.callnoderpc('createwallet', [new_wallet_name])
|
||||
self.callnoderpc('sethdseed', [True, test_wif], wallet=new_wallet_name)
|
||||
addr = self.callnoderpc('getnewaddress', wallet=new_wallet_name)
|
||||
self.callnoderpc('unloadwallet', [new_wallet_name])
|
||||
assert (addr == 'bchreg:qqxr67wf5ltty5jvm44zryywmpt7ntdaa50carjt59')
|
||||
self.callnoderpc("createwallet", [new_wallet_name])
|
||||
self.callnoderpc("sethdseed", [True, test_wif], wallet=new_wallet_name)
|
||||
addr = self.callnoderpc("getnewaddress", wallet=new_wallet_name)
|
||||
self.callnoderpc("unloadwallet", [new_wallet_name])
|
||||
assert addr == "bchreg:qqxr67wf5ltty5jvm44zryywmpt7ntdaa50carjt59"
|
||||
|
||||
def test_008_gettxout(self):
|
||||
super().test_008_gettxout()
|
||||
|
@ -334,7 +499,7 @@ class TestBCH(BasicSwapTest):
|
|||
super().test_009_scantxoutset()
|
||||
|
||||
def test_010_txn_size(self):
|
||||
logging.info('---------- Test {} txn_size'.format(Coins.BCH))
|
||||
logging.info("---------- Test {} txn_size".format(Coins.BCH))
|
||||
|
||||
swap_clients = self.swap_clients
|
||||
ci = swap_clients[0].ci(Coins.BCH)
|
||||
|
@ -343,7 +508,7 @@ class TestBCH(BasicSwapTest):
|
|||
amount: int = ci.make_int(random.uniform(0.1, 2.0), r=1)
|
||||
|
||||
# Record unspents before createSCLockTx as the used ones will be locked
|
||||
unspents = ci.rpc('listunspent')
|
||||
unspents = ci.rpc("listunspent")
|
||||
|
||||
# fee_rate is in sats/B
|
||||
fee_rate: int = 1
|
||||
|
@ -355,29 +520,28 @@ class TestBCH(BasicSwapTest):
|
|||
B = ci.getPubkey(b)
|
||||
|
||||
mining_fee = 1000
|
||||
timelock = 2
|
||||
b_receive = ci.getNewAddress()
|
||||
a_refund = ci.getNewAddress()
|
||||
|
||||
refundExtraArgs = dict()
|
||||
lockExtraArgs = dict()
|
||||
|
||||
refundExtraArgs['mining_fee'] = 1000
|
||||
refundExtraArgs['out_1'] = ci.addressToLockingBytecode(a_refund)
|
||||
refundExtraArgs['out_2'] = ci.addressToLockingBytecode(b_receive)
|
||||
refundExtraArgs['public_key'] = B
|
||||
refundExtraArgs['timelock'] = 5
|
||||
refundExtraArgs["mining_fee"] = 1000
|
||||
refundExtraArgs["out_1"] = ci.addressToLockingBytecode(a_refund)
|
||||
refundExtraArgs["out_2"] = ci.addressToLockingBytecode(b_receive)
|
||||
refundExtraArgs["public_key"] = B
|
||||
refundExtraArgs["timelock"] = 5
|
||||
|
||||
refund_lock_tx_script = pi.genScriptLockTxScript(ci, A, B, **refundExtraArgs)
|
||||
# will make use of this in `createSCLockRefundTx`
|
||||
refundExtraArgs['refund_lock_tx_script'] = refund_lock_tx_script
|
||||
refundExtraArgs["refund_lock_tx_script"] = refund_lock_tx_script
|
||||
|
||||
# lock script
|
||||
lockExtraArgs['mining_fee'] = 1000
|
||||
lockExtraArgs['out_1'] = ci.addressToLockingBytecode(b_receive)
|
||||
lockExtraArgs['out_2'] = ci.scriptToP2SH32LockingBytecode(refund_lock_tx_script)
|
||||
lockExtraArgs['public_key'] = A
|
||||
lockExtraArgs['timelock'] = 2
|
||||
lockExtraArgs["mining_fee"] = 1000
|
||||
lockExtraArgs["out_1"] = ci.addressToLockingBytecode(b_receive)
|
||||
lockExtraArgs["out_2"] = ci.scriptToP2SH32LockingBytecode(refund_lock_tx_script)
|
||||
lockExtraArgs["public_key"] = A
|
||||
lockExtraArgs["timelock"] = 2
|
||||
|
||||
lock_tx_script = pi.genScriptLockTxScript(ci, A, B, **lockExtraArgs)
|
||||
|
||||
|
@ -386,36 +550,35 @@ class TestBCH(BasicSwapTest):
|
|||
lock_tx = ci.signTxWithWallet(lock_tx)
|
||||
print(lock_tx.hex())
|
||||
|
||||
unspents_after = ci.rpc('listunspent')
|
||||
assert (len(unspents) > len(unspents_after))
|
||||
unspents_after = ci.rpc("listunspent")
|
||||
assert len(unspents) > len(unspents_after)
|
||||
|
||||
tx_decoded = ci.rpc('decoderawtransaction', [lock_tx.hex()])
|
||||
txid = tx_decoded['txid']
|
||||
tx_decoded = ci.rpc("decoderawtransaction", [lock_tx.hex()])
|
||||
txid = tx_decoded["txid"]
|
||||
|
||||
vsize = tx_decoded['size']
|
||||
vsize = tx_decoded["size"]
|
||||
expect_fee_int = round(fee_rate * vsize)
|
||||
expect_fee = ci.format_amount(expect_fee_int)
|
||||
|
||||
out_value: int = 0
|
||||
for txo in tx_decoded['vout']:
|
||||
if 'value' in txo:
|
||||
out_value += ci.make_int(txo['value'])
|
||||
for txo in tx_decoded["vout"]:
|
||||
if "value" in txo:
|
||||
out_value += ci.make_int(txo["value"])
|
||||
in_value: int = 0
|
||||
for txi in tx_decoded['vin']:
|
||||
for txi in tx_decoded["vin"]:
|
||||
for utxo in unspents:
|
||||
if 'vout' not in utxo:
|
||||
if "vout" not in utxo:
|
||||
continue
|
||||
if utxo['txid'] == txi['txid'] and utxo['vout'] == txi['vout']:
|
||||
in_value += ci.make_int(utxo['amount'])
|
||||
if utxo["txid"] == txi["txid"] and utxo["vout"] == txi["vout"]:
|
||||
in_value += ci.make_int(utxo["amount"])
|
||||
break
|
||||
fee_value = in_value - out_value
|
||||
|
||||
ci.rpc('sendrawtransaction', [lock_tx.hex()])
|
||||
rv = ci.rpc('gettransaction', [txid])
|
||||
wallet_tx_fee = -ci.make_int(rv['fee'])
|
||||
ci.rpc("sendrawtransaction", [lock_tx.hex()])
|
||||
rv = ci.rpc("gettransaction", [txid])
|
||||
wallet_tx_fee = -ci.make_int(rv["fee"])
|
||||
|
||||
assert (wallet_tx_fee == fee_value)
|
||||
assert (wallet_tx_fee == expect_fee_int)
|
||||
assert wallet_tx_fee == fee_value
|
||||
assert wallet_tx_fee == expect_fee_int
|
||||
|
||||
pkh_out = ci.decodeAddress(b_receive)
|
||||
|
||||
|
@ -425,126 +588,219 @@ class TestBCH(BasicSwapTest):
|
|||
aAdaptorSig = ecdsaotves_enc_sign(a, B, msg)
|
||||
|
||||
# alice verifies the adaptor signature
|
||||
assert (ecdsaotves_enc_verify(A, B, msg, aAdaptorSig))
|
||||
assert ecdsaotves_enc_verify(A, B, msg, aAdaptorSig)
|
||||
|
||||
# alice decrypts the adaptor signature
|
||||
aAdaptorSig_dec = ecdsaotves_dec_sig(b, aAdaptorSig)
|
||||
|
||||
fee_info = {}
|
||||
lock_spend_tx = ci.createSCLockSpendTx(lock_tx, lock_tx_script, pkh_out, mining_fee, fee_info=fee_info, ves=aAdaptorSig_dec)
|
||||
vsize_estimated: int = fee_info['vsize']
|
||||
lock_spend_tx = ci.createSCLockSpendTx(
|
||||
lock_tx,
|
||||
lock_tx_script,
|
||||
pkh_out,
|
||||
mining_fee,
|
||||
fee_info=fee_info,
|
||||
ves=aAdaptorSig_dec,
|
||||
)
|
||||
vsize_estimated: int = fee_info["vsize"]
|
||||
|
||||
tx_decoded = ci.rpc('decoderawtransaction', [lock_spend_tx.hex()])
|
||||
print('lock_spend_tx', lock_spend_tx.hex(), '\n', 'tx_decoded', tx_decoded)
|
||||
txid = tx_decoded['txid']
|
||||
tx_decoded = ci.rpc("decoderawtransaction", [lock_spend_tx.hex()])
|
||||
print("lock_spend_tx", lock_spend_tx.hex(), "\n", "tx_decoded", tx_decoded)
|
||||
txid = tx_decoded["txid"]
|
||||
|
||||
tx_decoded = ci.rpc('decoderawtransaction', [lock_spend_tx.hex()])
|
||||
vsize_actual: int = tx_decoded['size']
|
||||
tx_decoded = ci.rpc("decoderawtransaction", [lock_spend_tx.hex()])
|
||||
vsize_actual: int = tx_decoded["size"]
|
||||
|
||||
assert (vsize_actual <= vsize_estimated and vsize_estimated - vsize_actual < 4)
|
||||
assert (ci.rpc('sendrawtransaction', [lock_spend_tx.hex()]) == txid)
|
||||
assert vsize_actual <= vsize_estimated and vsize_estimated - vsize_actual < 4
|
||||
assert ci.rpc("sendrawtransaction", [lock_spend_tx.hex()]) == txid
|
||||
|
||||
expect_size: int = ci.xmr_swap_a_lock_spend_tx_vsize()
|
||||
assert (expect_size >= vsize_actual)
|
||||
assert (expect_size - vsize_actual < 10)
|
||||
assert expect_size >= vsize_actual
|
||||
assert expect_size - vsize_actual < 10
|
||||
|
||||
def test_011_p2sh(self):
|
||||
# Not used in bsx for native-segwit coins
|
||||
logging.info('---------- Test {} p2sh'.format(self.test_coin.name))
|
||||
logging.info("---------- Test {} p2sh".format(self.test_coin.name))
|
||||
|
||||
swap_clients = self.swap_clients
|
||||
ci = self.swap_clients[0].ci(self.test_coin)
|
||||
|
||||
script = CScript([2, 2, OP_EQUAL, ])
|
||||
script = CScript(
|
||||
[
|
||||
2,
|
||||
2,
|
||||
OP_EQUAL,
|
||||
]
|
||||
)
|
||||
|
||||
script_dest = ci.get_p2sh_script_pubkey(script)
|
||||
tx = CTransaction()
|
||||
tx.nVersion = ci.txVersion()
|
||||
tx.vout.append(ci.txoType()(ci.make_int(1.1), script_dest))
|
||||
tx_hex = ToHex(tx)
|
||||
tx_funded = ci.rpc_wallet('fundrawtransaction', [tx_hex])
|
||||
utxo_pos = 0 if tx_funded['changepos'] == 1 else 1
|
||||
tx_signed = ci.rpc_wallet('signrawtransactionwithwallet', [tx_funded['hex'], ])['hex']
|
||||
txid = ci.rpc('sendrawtransaction', [tx_signed, ])
|
||||
tx_funded = ci.rpc_wallet("fundrawtransaction", [tx_hex])
|
||||
utxo_pos = 0 if tx_funded["changepos"] == 1 else 1
|
||||
tx_signed = ci.rpc_wallet(
|
||||
"signrawtransactionwithwallet",
|
||||
[
|
||||
tx_funded["hex"],
|
||||
],
|
||||
)["hex"]
|
||||
txid = ci.rpc(
|
||||
"sendrawtransaction",
|
||||
[
|
||||
tx_signed,
|
||||
],
|
||||
)
|
||||
|
||||
addr_out = ci.rpc_wallet('getnewaddress', ['csv test'])
|
||||
addr_out = ci.rpc_wallet("getnewaddress", ["csv test"])
|
||||
pkh = ci.decodeAddress(addr_out)
|
||||
script_out = ci.getScriptForPubkeyHash(pkh)
|
||||
|
||||
# Double check output type
|
||||
prev_tx = ci.rpc('decoderawtransaction', [tx_signed, ])
|
||||
assert (prev_tx['vout'][utxo_pos]['scriptPubKey']['type'] == 'scripthash')
|
||||
prev_tx = ci.rpc(
|
||||
"decoderawtransaction",
|
||||
[
|
||||
tx_signed,
|
||||
],
|
||||
)
|
||||
assert prev_tx["vout"][utxo_pos]["scriptPubKey"]["type"] == "scripthash"
|
||||
|
||||
tx_spend = CTransaction()
|
||||
tx_spend.nVersion = ci.txVersion()
|
||||
tx_spend.vin.append(CTxIn(COutPoint(int(txid, 16), utxo_pos),
|
||||
scriptSig=CScript([script,])))
|
||||
tx_spend.vin.append(
|
||||
CTxIn(
|
||||
COutPoint(int(txid, 16), utxo_pos),
|
||||
scriptSig=CScript(
|
||||
[
|
||||
script,
|
||||
]
|
||||
),
|
||||
)
|
||||
)
|
||||
tx_spend.vout.append(ci.txoType()(ci.make_int(1.0999), script_out))
|
||||
tx_spend_hex = ToHex(tx_spend)
|
||||
|
||||
txid = ci.rpc('sendrawtransaction', [tx_spend_hex, ])
|
||||
txid = ci.rpc(
|
||||
"sendrawtransaction",
|
||||
[
|
||||
tx_spend_hex,
|
||||
],
|
||||
)
|
||||
self.mineBlock(1)
|
||||
ro = ci.rpc_wallet('listreceivedbyaddress', [0, ])
|
||||
ro = ci.rpc_wallet(
|
||||
"listreceivedbyaddress",
|
||||
[
|
||||
0,
|
||||
],
|
||||
)
|
||||
sum_addr = 0
|
||||
for entry in ro:
|
||||
if entry['address'] == addr_out:
|
||||
sum_addr += entry['amount']
|
||||
assert (sum_addr == 1.0999)
|
||||
if entry["address"] == addr_out:
|
||||
sum_addr += entry["amount"]
|
||||
assert sum_addr == 1.0999
|
||||
|
||||
# Ensure tx was mined
|
||||
tx_wallet = ci.rpc_wallet('gettransaction', [txid, ])
|
||||
assert (len(tx_wallet['blockhash']) == 64)
|
||||
tx_wallet = ci.rpc_wallet(
|
||||
"gettransaction",
|
||||
[
|
||||
txid,
|
||||
],
|
||||
)
|
||||
assert len(tx_wallet["blockhash"]) == 64
|
||||
|
||||
def test_011_p2sh32(self):
|
||||
# Not used in bsx for native-segwit coins
|
||||
logging.info('---------- Test {} p2sh32'.format(self.test_coin.name))
|
||||
logging.info("---------- Test {} p2sh32".format(self.test_coin.name))
|
||||
|
||||
swap_clients = self.swap_clients
|
||||
ci = self.swap_clients[0].ci(self.test_coin)
|
||||
|
||||
script = CScript([2, 2, OP_EQUAL, ])
|
||||
script = CScript(
|
||||
[
|
||||
2,
|
||||
2,
|
||||
OP_EQUAL,
|
||||
]
|
||||
)
|
||||
|
||||
script_dest = ci.scriptToP2SH32LockingBytecode(script)
|
||||
tx = CTransaction()
|
||||
tx.nVersion = ci.txVersion()
|
||||
tx.vout.append(ci.txoType()(ci.make_int(1.1), script_dest))
|
||||
tx_hex = ToHex(tx)
|
||||
tx_funded = ci.rpc_wallet('fundrawtransaction', [tx_hex])
|
||||
utxo_pos = 0 if tx_funded['changepos'] == 1 else 1
|
||||
tx_signed = ci.rpc_wallet('signrawtransactionwithwallet', [tx_funded['hex'], ])['hex']
|
||||
txid = ci.rpc('sendrawtransaction', [tx_signed, ])
|
||||
tx_funded = ci.rpc_wallet("fundrawtransaction", [tx_hex])
|
||||
utxo_pos = 0 if tx_funded["changepos"] == 1 else 1
|
||||
tx_signed = ci.rpc_wallet(
|
||||
"signrawtransactionwithwallet",
|
||||
[
|
||||
tx_funded["hex"],
|
||||
],
|
||||
)["hex"]
|
||||
txid = ci.rpc(
|
||||
"sendrawtransaction",
|
||||
[
|
||||
tx_signed,
|
||||
],
|
||||
)
|
||||
|
||||
addr_out = ci.rpc_wallet('getnewaddress', ['csv test'])
|
||||
addr_out = ci.rpc_wallet("getnewaddress", ["csv test"])
|
||||
pkh = ci.decodeAddress(addr_out)
|
||||
script_out = ci.getScriptForPubkeyHash(pkh)
|
||||
|
||||
# Double check output type
|
||||
prev_tx = ci.rpc('decoderawtransaction', [tx_signed, ])
|
||||
assert (prev_tx['vout'][utxo_pos]['scriptPubKey']['type'] == 'scripthash')
|
||||
prev_tx = ci.rpc(
|
||||
"decoderawtransaction",
|
||||
[
|
||||
tx_signed,
|
||||
],
|
||||
)
|
||||
assert prev_tx["vout"][utxo_pos]["scriptPubKey"]["type"] == "scripthash"
|
||||
|
||||
tx_spend = CTransaction()
|
||||
tx_spend.nVersion = ci.txVersion()
|
||||
tx_spend.vin.append(CTxIn(COutPoint(int(txid, 16), utxo_pos),
|
||||
scriptSig=CScript([script,])))
|
||||
tx_spend.vin.append(
|
||||
CTxIn(
|
||||
COutPoint(int(txid, 16), utxo_pos),
|
||||
scriptSig=CScript(
|
||||
[
|
||||
script,
|
||||
]
|
||||
),
|
||||
)
|
||||
)
|
||||
tx_spend.vout.append(ci.txoType()(ci.make_int(1.0999), script_out))
|
||||
tx_spend_hex = ToHex(tx_spend)
|
||||
|
||||
txid = ci.rpc('sendrawtransaction', [tx_spend_hex, ])
|
||||
txid = ci.rpc(
|
||||
"sendrawtransaction",
|
||||
[
|
||||
tx_spend_hex,
|
||||
],
|
||||
)
|
||||
self.mineBlock(1)
|
||||
ro = ci.rpc_wallet('listreceivedbyaddress', [0, ])
|
||||
ro = ci.rpc_wallet(
|
||||
"listreceivedbyaddress",
|
||||
[
|
||||
0,
|
||||
],
|
||||
)
|
||||
sum_addr = 0
|
||||
for entry in ro:
|
||||
if entry['address'] == addr_out:
|
||||
sum_addr += entry['amount']
|
||||
assert (sum_addr == 1.0999)
|
||||
if entry["address"] == addr_out:
|
||||
sum_addr += entry["amount"]
|
||||
assert sum_addr == 1.0999
|
||||
|
||||
# Ensure tx was mined
|
||||
tx_wallet = ci.rpc_wallet('gettransaction', [txid, ])
|
||||
assert (len(tx_wallet['blockhash']) == 64)
|
||||
tx_wallet = ci.rpc_wallet(
|
||||
"gettransaction",
|
||||
[
|
||||
txid,
|
||||
],
|
||||
)
|
||||
assert len(tx_wallet["blockhash"]) == 64
|
||||
|
||||
def test_012_p2sh_p2wsh(self):
|
||||
logging.info('---------- Test {} p2sh-p2wsh'.format(self.test_coin.name))
|
||||
logging.info('Skipped')
|
||||
logging.info("---------- Test {} p2sh-p2wsh".format(self.test_coin.name))
|
||||
logging.info("Skipped")
|
||||
|
||||
def test_01_a_full_swap(self):
|
||||
super().test_01_a_full_swap()
|
||||
|
@ -564,12 +820,16 @@ class TestBCH(BasicSwapTest):
|
|||
super().test_02_a_leader_recover_a_lock_tx()
|
||||
|
||||
def test_03_a_follower_recover_a_lock_tx(self):
|
||||
self.do_test_03_follower_recover_a_lock_tx(self.test_coin_from, Coins.XMR, with_mercy=True)
|
||||
self.do_test_03_follower_recover_a_lock_tx(
|
||||
self.test_coin_from, Coins.XMR, with_mercy=True
|
||||
)
|
||||
|
||||
def test_03_b_follower_recover_a_lock_tx_reverse(self):
|
||||
self.prepare_balance(Coins.BCH, 100.0, 1801, 1800)
|
||||
self.prepare_balance(Coins.XMR, 100.0, 1800, 1801)
|
||||
self.do_test_03_follower_recover_a_lock_tx(Coins.XMR, self.test_coin_from, lock_value=12, with_mercy=True)
|
||||
self.do_test_03_follower_recover_a_lock_tx(
|
||||
Coins.XMR, self.test_coin_from, lock_value=12, with_mercy=True
|
||||
)
|
||||
|
||||
def test_03_c_follower_recover_a_lock_tx_to_part(self):
|
||||
super().test_03_c_follower_recover_a_lock_tx_to_part()
|
||||
|
@ -610,8 +870,8 @@ class TestBCH(BasicSwapTest):
|
|||
|
||||
def test_06_preselect_inputs(self):
|
||||
tla_from = self.test_coin.name
|
||||
logging.info('---------- Test {} Preselected inputs'.format(tla_from))
|
||||
logging.info('Skipped')
|
||||
logging.info("---------- Test {} Preselected inputs".format(tla_from))
|
||||
logging.info("Skipped")
|
||||
|
||||
def test_07_expire_stuck_accepted(self):
|
||||
super().test_07_expire_stuck_accepted()
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -2,6 +2,7 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright (c) 2021-2024 tecnovert
|
||||
# Copyright (c) 2024 The Basicswap developers
|
||||
# Distributed under the MIT software license, see the accompanying
|
||||
# file LICENSE or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
|
@ -40,64 +41,112 @@ class TestLTC(BasicSwapTest):
|
|||
base_rpc_port = LTC_BASE_RPC_PORT
|
||||
|
||||
def mineBlock(self, num_blocks=1):
|
||||
self.callnoderpc('generatetoaddress', [num_blocks, self.ltc_addr])
|
||||
self.callnoderpc("generatetoaddress", [num_blocks, self.ltc_addr])
|
||||
|
||||
def check_softfork_active(self, feature_name):
|
||||
deploymentinfo = self.callnoderpc('getblockchaininfo')
|
||||
assert (deploymentinfo['softforks'][feature_name]['active'] is True)
|
||||
deploymentinfo = self.callnoderpc("getblockchaininfo")
|
||||
assert deploymentinfo["softforks"][feature_name]["active"] is True
|
||||
|
||||
def test_001_nested_segwit(self):
|
||||
logging.info('---------- Test {} p2sh nested segwit'.format(self.test_coin_from.name))
|
||||
logging.info('Skipped')
|
||||
logging.info(
|
||||
"---------- Test {} p2sh nested segwit".format(self.test_coin_from.name)
|
||||
)
|
||||
logging.info("Skipped")
|
||||
|
||||
def test_002_native_segwit(self):
|
||||
logging.info('---------- Test {} p2sh native segwit'.format(self.test_coin_from.name))
|
||||
logging.info(
|
||||
"---------- Test {} p2sh native segwit".format(self.test_coin_from.name)
|
||||
)
|
||||
|
||||
ci = self.swap_clients[0].ci(self.test_coin_from)
|
||||
addr_segwit = ci.rpc_wallet('getnewaddress', ['segwit test', 'bech32'])
|
||||
addr_info = ci.rpc_wallet('getaddressinfo', [addr_segwit, ])
|
||||
assert addr_info['iswitness'] is True
|
||||
addr_segwit = ci.rpc_wallet("getnewaddress", ["segwit test", "bech32"])
|
||||
addr_info = ci.rpc_wallet(
|
||||
"getaddressinfo",
|
||||
[
|
||||
addr_segwit,
|
||||
],
|
||||
)
|
||||
assert addr_info["iswitness"] is True
|
||||
|
||||
txid = ci.rpc_wallet('sendtoaddress', [addr_segwit, 1.0])
|
||||
txid = ci.rpc_wallet("sendtoaddress", [addr_segwit, 1.0])
|
||||
assert len(txid) == 64
|
||||
tx_wallet = ci.rpc_wallet('gettransaction', [txid, ])['hex']
|
||||
tx = ci.rpc('decoderawtransaction', [tx_wallet, ])
|
||||
tx_wallet = ci.rpc_wallet(
|
||||
"gettransaction",
|
||||
[
|
||||
txid,
|
||||
],
|
||||
)["hex"]
|
||||
tx = ci.rpc(
|
||||
"decoderawtransaction",
|
||||
[
|
||||
tx_wallet,
|
||||
],
|
||||
)
|
||||
|
||||
self.mineBlock()
|
||||
ro = ci.rpc('scantxoutset', ['start', ['addr({})'.format(addr_segwit)]])
|
||||
assert (len(ro['unspents']) == 1)
|
||||
assert (ro['unspents'][0]['txid'] == txid)
|
||||
ro = ci.rpc("scantxoutset", ["start", ["addr({})".format(addr_segwit)]])
|
||||
assert len(ro["unspents"]) == 1
|
||||
assert ro["unspents"][0]["txid"] == txid
|
||||
|
||||
prevout_n = -1
|
||||
for txo in tx['vout']:
|
||||
if addr_segwit in txo['scriptPubKey']['addresses']:
|
||||
prevout_n = txo['n']
|
||||
for txo in tx["vout"]:
|
||||
if addr_segwit in txo["scriptPubKey"]["addresses"]:
|
||||
prevout_n = txo["n"]
|
||||
break
|
||||
assert prevout_n > -1
|
||||
|
||||
tx_funded = ci.rpc('createrawtransaction', [[{'txid': txid, 'vout': prevout_n}], {addr_segwit: 0.99}])
|
||||
tx_signed = ci.rpc_wallet('signrawtransactionwithwallet', [tx_funded, ])['hex']
|
||||
tx_funded_decoded = ci.rpc('decoderawtransaction', [tx_funded, ])
|
||||
tx_signed_decoded = ci.rpc('decoderawtransaction', [tx_signed, ])
|
||||
assert tx_funded_decoded['txid'] == tx_signed_decoded['txid']
|
||||
tx_funded = ci.rpc(
|
||||
"createrawtransaction",
|
||||
[[{"txid": txid, "vout": prevout_n}], {addr_segwit: 0.99}],
|
||||
)
|
||||
tx_signed = ci.rpc_wallet(
|
||||
"signrawtransactionwithwallet",
|
||||
[
|
||||
tx_funded,
|
||||
],
|
||||
)["hex"]
|
||||
tx_funded_decoded = ci.rpc(
|
||||
"decoderawtransaction",
|
||||
[
|
||||
tx_funded,
|
||||
],
|
||||
)
|
||||
tx_signed_decoded = ci.rpc(
|
||||
"decoderawtransaction",
|
||||
[
|
||||
tx_signed,
|
||||
],
|
||||
)
|
||||
assert tx_funded_decoded["txid"] == tx_signed_decoded["txid"]
|
||||
|
||||
def test_007_hdwallet(self):
|
||||
logging.info('---------- Test {} hdwallet'.format(self.test_coin_from.name))
|
||||
logging.info("---------- Test {} hdwallet".format(self.test_coin_from.name))
|
||||
|
||||
test_seed = '8e54a313e6df8918df6d758fafdbf127a115175fdd2238d0e908dd8093c9ac3b'
|
||||
test_wif = self.swap_clients[0].ci(self.test_coin_from).encodeKey(bytes.fromhex(test_seed))
|
||||
test_seed = "8e54a313e6df8918df6d758fafdbf127a115175fdd2238d0e908dd8093c9ac3b"
|
||||
test_wif = (
|
||||
self.swap_clients[0]
|
||||
.ci(self.test_coin_from)
|
||||
.encodeKey(bytes.fromhex(test_seed))
|
||||
)
|
||||
new_wallet_name = random.randbytes(10).hex()
|
||||
self.callnoderpc('createwallet', [new_wallet_name])
|
||||
self.callnoderpc('sethdseed', [True, test_wif], wallet=new_wallet_name)
|
||||
addr = self.callnoderpc('getnewaddress', wallet=new_wallet_name)
|
||||
self.callnoderpc('unloadwallet', [new_wallet_name])
|
||||
assert (addr == 'rltc1qps7hnjd866e9ynxadgseprkc2l56m00djr82la')
|
||||
self.callnoderpc("createwallet", [new_wallet_name])
|
||||
self.callnoderpc("sethdseed", [True, test_wif], wallet=new_wallet_name)
|
||||
addr = self.callnoderpc("getnewaddress", wallet=new_wallet_name)
|
||||
self.callnoderpc("unloadwallet", [new_wallet_name])
|
||||
assert addr == "rltc1qps7hnjd866e9ynxadgseprkc2l56m00djr82la"
|
||||
|
||||
def test_20_btc_coin(self):
|
||||
logging.info('---------- Test BTC to {}'.format(self.test_coin_from.name))
|
||||
logging.info("---------- Test BTC to {}".format(self.test_coin_from.name))
|
||||
swap_clients = self.swap_clients
|
||||
|
||||
offer_id = swap_clients[0].postOffer(Coins.BTC, self.test_coin_from, 100 * COIN, 0.1 * COIN, 100 * COIN, SwapTypes.SELLER_FIRST)
|
||||
offer_id = swap_clients[0].postOffer(
|
||||
Coins.BTC,
|
||||
self.test_coin_from,
|
||||
100 * COIN,
|
||||
0.1 * COIN,
|
||||
100 * COIN,
|
||||
SwapTypes.SELLER_FIRST,
|
||||
)
|
||||
|
||||
wait_for_offer(test_delay_event, swap_clients[1], offer_id)
|
||||
offer = swap_clients[1].getOffer(offer_id)
|
||||
|
@ -107,147 +156,187 @@ class TestLTC(BasicSwapTest):
|
|||
swap_clients[0].acceptBid(bid_id)
|
||||
|
||||
wait_for_in_progress(test_delay_event, swap_clients[1], bid_id, sent=True)
|
||||
wait_for_bid(test_delay_event, swap_clients[0], bid_id, BidStates.SWAP_COMPLETED, wait_for=60)
|
||||
wait_for_bid(test_delay_event, swap_clients[1], bid_id, BidStates.SWAP_COMPLETED, sent=True, wait_for=60)
|
||||
wait_for_bid(
|
||||
test_delay_event,
|
||||
swap_clients[0],
|
||||
bid_id,
|
||||
BidStates.SWAP_COMPLETED,
|
||||
wait_for=60,
|
||||
)
|
||||
wait_for_bid(
|
||||
test_delay_event,
|
||||
swap_clients[1],
|
||||
bid_id,
|
||||
BidStates.SWAP_COMPLETED,
|
||||
sent=True,
|
||||
wait_for=60,
|
||||
)
|
||||
|
||||
js_0 = read_json_api(1800)
|
||||
js_1 = read_json_api(1801)
|
||||
assert (js_0['num_swapping'] == 0 and js_0['num_watched_outputs'] == 0)
|
||||
assert (js_1['num_swapping'] == 0 and js_1['num_watched_outputs'] == 0)
|
||||
assert js_0["num_swapping"] == 0 and js_0["num_watched_outputs"] == 0
|
||||
assert js_1["num_swapping"] == 0 and js_1["num_watched_outputs"] == 0
|
||||
|
||||
def test_21_mweb(self):
|
||||
logging.info('---------- Test MWEB {}'.format(self.test_coin_from.name))
|
||||
logging.info("---------- Test MWEB {}".format(self.test_coin_from.name))
|
||||
swap_clients = self.swap_clients
|
||||
|
||||
ci0 = swap_clients[0].ci(self.test_coin_from)
|
||||
ci1 = swap_clients[1].ci(self.test_coin_from)
|
||||
|
||||
mweb_addr_0 = ci0.rpc_wallet('getnewaddress', ['mweb addr test 0', 'mweb'])
|
||||
mweb_addr_1 = ci1.rpc_wallet('getnewaddress', ['mweb addr test 1', 'mweb'])
|
||||
mweb_addr_0 = ci0.rpc_wallet("getnewaddress", ["mweb addr test 0", "mweb"])
|
||||
mweb_addr_1 = ci1.rpc_wallet("getnewaddress", ["mweb addr test 1", "mweb"])
|
||||
|
||||
addr_info0 = ci0.rpc_wallet('getaddressinfo', [mweb_addr_0,])
|
||||
assert (addr_info0['ismweb'] is True)
|
||||
addr_info0 = ci0.rpc_wallet(
|
||||
"getaddressinfo",
|
||||
[
|
||||
mweb_addr_0,
|
||||
],
|
||||
)
|
||||
assert addr_info0["ismweb"] is True
|
||||
|
||||
addr_info1 = ci1.rpc_wallet('getaddressinfo', [mweb_addr_1,])
|
||||
assert (addr_info1['ismweb'] is True)
|
||||
addr_info1 = ci1.rpc_wallet(
|
||||
"getaddressinfo",
|
||||
[
|
||||
mweb_addr_1,
|
||||
],
|
||||
)
|
||||
assert addr_info1["ismweb"] is True
|
||||
|
||||
trusted_before = ci0.rpc_wallet('getbalances')['mine']['trusted']
|
||||
ci0.rpc_wallet('sendtoaddress', [mweb_addr_0, 10.0])
|
||||
assert (trusted_before - float(ci0.rpc_wallet('getbalances')['mine']['trusted']) < 0.1)
|
||||
trusted_before = ci0.rpc_wallet("getbalances")["mine"]["trusted"]
|
||||
ci0.rpc_wallet("sendtoaddress", [mweb_addr_0, 10.0])
|
||||
assert (
|
||||
trusted_before - float(ci0.rpc_wallet("getbalances")["mine"]["trusted"])
|
||||
< 0.1
|
||||
)
|
||||
|
||||
try:
|
||||
pause_event.clear() # Stop mining
|
||||
ci0.rpc_wallet('sendtoaddress', [mweb_addr_1, 10.0])
|
||||
ci0.rpc_wallet("sendtoaddress", [mweb_addr_1, 10.0])
|
||||
|
||||
found_unconfirmed: bool = False
|
||||
for i in range(20):
|
||||
test_delay_event.wait(1)
|
||||
ltc_wallet = read_json_api(TEST_HTTP_PORT + 1, 'wallets/ltc')
|
||||
if float(ltc_wallet['unconfirmed']) == 10.0:
|
||||
ltc_wallet = read_json_api(TEST_HTTP_PORT + 1, "wallets/ltc")
|
||||
if float(ltc_wallet["unconfirmed"]) == 10.0:
|
||||
found_unconfirmed = True
|
||||
break
|
||||
finally:
|
||||
pause_event.set()
|
||||
assert (found_unconfirmed)
|
||||
assert found_unconfirmed
|
||||
|
||||
self.mineBlock()
|
||||
|
||||
txns = ci0.rpc_wallet('listtransactions')
|
||||
|
||||
utxos = ci0.rpc_wallet('listunspent')
|
||||
balances = ci0.rpc_wallet('getbalances')
|
||||
wi = ci0.rpc_wallet('getwalletinfo')
|
||||
|
||||
txid = ci0.rpc_wallet('sendtoaddress', [mweb_addr_1, 10.0])
|
||||
ci0.rpc_wallet("sendtoaddress", [mweb_addr_1, 10.0])
|
||||
|
||||
self.mineBlock()
|
||||
|
||||
txns = ci1.rpc_wallet('listtransactions')
|
||||
|
||||
utxos = ci1.rpc_wallet('listunspent')
|
||||
balances = ci1.rpc_wallet('getbalances')
|
||||
wi = ci1.rpc_wallet('getwalletinfo')
|
||||
utxos = ci1.rpc_wallet("listunspent")
|
||||
|
||||
mweb_tx = None
|
||||
for utxo in utxos:
|
||||
if utxo.get('address', '') == mweb_addr_1:
|
||||
if utxo.get("address", "") == mweb_addr_1:
|
||||
mweb_tx = utxo
|
||||
assert (mweb_tx is not None)
|
||||
assert mweb_tx is not None
|
||||
|
||||
tx = ci1.rpc_wallet('gettransaction', [mweb_tx['txid'],])
|
||||
|
||||
blockhash = tx['blockhash']
|
||||
block3 = ci1.rpc('getblock', [blockhash, 3])
|
||||
block0 = ci1.rpc('getblock', [blockhash, 0])
|
||||
|
||||
require_amount: int = ci1.make_int(1)
|
||||
unspent_addr = ci1.getUnspentsByAddr()
|
||||
assert (len(unspent_addr) > 0)
|
||||
assert len(unspent_addr) > 0
|
||||
for addr, _ in unspent_addr.items():
|
||||
if 'mweb1' in addr:
|
||||
raise ValueError('getUnspentsByAddr should exclude mweb UTXOs.')
|
||||
if "mweb1" in addr:
|
||||
raise ValueError("getUnspentsByAddr should exclude mweb UTXOs.")
|
||||
|
||||
# TODO
|
||||
|
||||
def test_22_mweb_balance(self):
|
||||
logging.info('---------- Test MWEB balance {}'.format(self.test_coin_from.name))
|
||||
logging.info("---------- Test MWEB balance {}".format(self.test_coin_from.name))
|
||||
swap_clients = self.swap_clients
|
||||
|
||||
ci_mweb = swap_clients[0].ci(Coins.LTC_MWEB)
|
||||
mweb_addr_0 = ci_mweb.getNewAddress()
|
||||
addr_info0 = ci_mweb.rpc_wallet('getaddressinfo', [mweb_addr_0,])
|
||||
assert (addr_info0['ismweb'] is True)
|
||||
addr_info0 = ci_mweb.rpc_wallet(
|
||||
"getaddressinfo",
|
||||
[
|
||||
mweb_addr_0,
|
||||
],
|
||||
)
|
||||
assert addr_info0["ismweb"] is True
|
||||
|
||||
ltc_addr = read_json_api(TEST_HTTP_PORT + 0, 'wallets/ltc/nextdepositaddr')
|
||||
ltc_mweb_addr = read_json_api(TEST_HTTP_PORT + 0, 'wallets/ltc_mweb/nextdepositaddr')
|
||||
ltc_mweb_addr2 = read_json_api(TEST_HTTP_PORT + 0, 'wallets/ltc/newmwebaddress')
|
||||
ltc_addr = read_json_api(TEST_HTTP_PORT + 0, "wallets/ltc/nextdepositaddr")
|
||||
ltc_mweb_addr = read_json_api(
|
||||
TEST_HTTP_PORT + 0, "wallets/ltc_mweb/nextdepositaddr"
|
||||
)
|
||||
ltc_mweb_addr2 = read_json_api(TEST_HTTP_PORT + 0, "wallets/ltc/newmwebaddress")
|
||||
|
||||
assert (ci_mweb.rpc_wallet('getaddressinfo', [ltc_addr,])['ismweb'] is False)
|
||||
assert (ci_mweb.rpc_wallet('getaddressinfo', [ltc_mweb_addr,])['ismweb'] is True)
|
||||
assert (ci_mweb.rpc_wallet('getaddressinfo', [ltc_mweb_addr2,])['ismweb'] is True)
|
||||
assert (
|
||||
ci_mweb.rpc_wallet(
|
||||
"getaddressinfo",
|
||||
[
|
||||
ltc_addr,
|
||||
],
|
||||
)["ismweb"]
|
||||
is False
|
||||
)
|
||||
assert (
|
||||
ci_mweb.rpc_wallet(
|
||||
"getaddressinfo",
|
||||
[
|
||||
ltc_mweb_addr,
|
||||
],
|
||||
)["ismweb"]
|
||||
is True
|
||||
)
|
||||
assert (
|
||||
ci_mweb.rpc_wallet(
|
||||
"getaddressinfo",
|
||||
[
|
||||
ltc_mweb_addr2,
|
||||
],
|
||||
)["ismweb"]
|
||||
is True
|
||||
)
|
||||
|
||||
post_json = {
|
||||
'value': 10,
|
||||
'address': ltc_mweb_addr,
|
||||
'subfee': False,
|
||||
"value": 10,
|
||||
"address": ltc_mweb_addr,
|
||||
"subfee": False,
|
||||
}
|
||||
json_rv = read_json_api(TEST_HTTP_PORT + 0, 'wallets/ltc/withdraw', post_json)
|
||||
assert (len(json_rv['txid']) == 64)
|
||||
json_rv = read_json_api(TEST_HTTP_PORT + 0, "wallets/ltc/withdraw", post_json)
|
||||
assert len(json_rv["txid"]) == 64
|
||||
|
||||
self.mineBlock()
|
||||
|
||||
json_rv = read_json_api(TEST_HTTP_PORT + 0, 'wallets/ltc', post_json)
|
||||
assert (json_rv['mweb_balance'] == 10.0)
|
||||
mweb_address = json_rv['mweb_address']
|
||||
json_rv = read_json_api(TEST_HTTP_PORT + 0, "wallets/ltc", post_json)
|
||||
assert json_rv["mweb_balance"] == 10.0
|
||||
mweb_address = json_rv["mweb_address"]
|
||||
|
||||
post_json = {
|
||||
'value': 11,
|
||||
'address': mweb_address,
|
||||
'subfee': False,
|
||||
"value": 11,
|
||||
"address": mweb_address,
|
||||
"subfee": False,
|
||||
}
|
||||
json_rv = read_json_api(TEST_HTTP_PORT + 0, 'wallets/ltc/withdraw', post_json)
|
||||
assert (len(json_rv['txid']) == 64)
|
||||
json_rv = read_json_api(TEST_HTTP_PORT + 0, "wallets/ltc/withdraw", post_json)
|
||||
assert len(json_rv["txid"]) == 64
|
||||
|
||||
self.mineBlock()
|
||||
|
||||
json_rv = read_json_api(TEST_HTTP_PORT + 0, 'wallets/ltc_mweb', post_json)
|
||||
assert (json_rv['mweb_balance'] == 21.0)
|
||||
assert (json_rv['mweb_address'] == mweb_address)
|
||||
ltc_address = json_rv['deposit_address']
|
||||
json_rv = read_json_api(TEST_HTTP_PORT + 0, "wallets/ltc_mweb", post_json)
|
||||
assert json_rv["mweb_balance"] == 21.0
|
||||
assert json_rv["mweb_address"] == mweb_address
|
||||
ltc_address = json_rv["deposit_address"]
|
||||
|
||||
# Check that spending the mweb balance takes from the correct wallet
|
||||
post_json = {
|
||||
'value': 1,
|
||||
'address': ltc_address,
|
||||
'subfee': False,
|
||||
'type_from': 'mweb',
|
||||
"value": 1,
|
||||
"address": ltc_address,
|
||||
"subfee": False,
|
||||
"type_from": "mweb",
|
||||
}
|
||||
json_rv = read_json_api(TEST_HTTP_PORT + 0, 'wallets/ltc/withdraw', post_json)
|
||||
assert (len(json_rv['txid']) == 64)
|
||||
json_rv = read_json_api(TEST_HTTP_PORT + 0, "wallets/ltc/withdraw", post_json)
|
||||
assert len(json_rv["txid"]) == 64
|
||||
|
||||
json_rv = read_json_api(TEST_HTTP_PORT + 0, 'wallets/ltc', post_json)
|
||||
assert (json_rv['mweb_balance'] <= 20.0)
|
||||
json_rv = read_json_api(TEST_HTTP_PORT + 0, "wallets/ltc", post_json)
|
||||
assert json_rv["mweb_balance"] <= 20.0
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright (c) 2019-2024 tecnovert
|
||||
# Copyright (c) 2024 The Basicswap developers
|
||||
# Distributed under the MIT software license, see the accompanying
|
||||
# file LICENSE or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
|
@ -18,9 +19,9 @@ from coincurve.ecdsaotves import (
|
|||
ecdsaotves_enc_sign,
|
||||
ecdsaotves_enc_verify,
|
||||
ecdsaotves_dec_sig,
|
||||
ecdsaotves_rec_enc_key)
|
||||
from coincurve.keys import (
|
||||
PrivateKey)
|
||||
ecdsaotves_rec_enc_key,
|
||||
)
|
||||
from coincurve.keys import PrivateKey
|
||||
|
||||
from basicswap.contrib.mnemonic import Mnemonic
|
||||
from basicswap.util import i2b, h2b
|
||||
|
@ -36,14 +37,14 @@ from basicswap.interface.xmr import XMRInterface
|
|||
from tests.basicswap.mnemonics import mnemonics
|
||||
from tests.basicswap.util import REQUIRED_SETTINGS
|
||||
|
||||
from basicswap.basicswap_util import (
|
||||
TxLockTypes)
|
||||
from basicswap.basicswap_util import TxLockTypes
|
||||
from basicswap.util import (
|
||||
make_int,
|
||||
SerialiseNum,
|
||||
format_amount,
|
||||
DeserialiseNum,
|
||||
validate_amount)
|
||||
validate_amount,
|
||||
)
|
||||
from basicswap.messages_npb import (
|
||||
BidMessage,
|
||||
)
|
||||
|
@ -56,8 +57,9 @@ class Test(unittest.TestCase):
|
|||
def test_case(v, nb=None):
|
||||
b = SerialiseNum(v)
|
||||
if nb is not None:
|
||||
assert (len(b) == nb)
|
||||
assert (v == DeserialiseNum(b))
|
||||
assert len(b) == nb
|
||||
assert v == DeserialiseNum(b)
|
||||
|
||||
test_case(0, 1)
|
||||
test_case(1, 1)
|
||||
test_case(16, 1)
|
||||
|
@ -70,104 +72,106 @@ class Test(unittest.TestCase):
|
|||
test_case(4194642)
|
||||
|
||||
def test_sequence(self):
|
||||
coin_settings = {'rpcport': 0, 'rpcauth': 'none'}
|
||||
coin_settings = {"rpcport": 0, "rpcauth": "none"}
|
||||
coin_settings.update(REQUIRED_SETTINGS)
|
||||
|
||||
ci = BTCInterface(coin_settings, 'regtest')
|
||||
ci = BTCInterface(coin_settings, "regtest")
|
||||
|
||||
time_val = 48 * 60 * 60
|
||||
encoded = ci.getExpectedSequence(TxLockTypes.SEQUENCE_LOCK_TIME, time_val)
|
||||
decoded = ci.decodeSequence(encoded)
|
||||
assert (decoded >= time_val)
|
||||
assert (decoded <= time_val + 512)
|
||||
assert decoded >= time_val
|
||||
assert decoded <= time_val + 512
|
||||
|
||||
time_val = 24 * 60
|
||||
encoded = ci.getExpectedSequence(TxLockTypes.SEQUENCE_LOCK_TIME, time_val)
|
||||
decoded = ci.decodeSequence(encoded)
|
||||
assert (decoded >= time_val)
|
||||
assert (decoded <= time_val + 512)
|
||||
assert decoded >= time_val
|
||||
assert decoded <= time_val + 512
|
||||
|
||||
blocks_val = 123
|
||||
encoded = ci.getExpectedSequence(TxLockTypes.SEQUENCE_LOCK_BLOCKS, blocks_val)
|
||||
decoded = ci.decodeSequence(encoded)
|
||||
assert (decoded == blocks_val)
|
||||
assert decoded == blocks_val
|
||||
|
||||
def test_make_int(self):
|
||||
def test_case(vs, vf, expect_int):
|
||||
i = make_int(vs)
|
||||
assert (i == expect_int and isinstance(i, int))
|
||||
assert i == expect_int and isinstance(i, int)
|
||||
i = make_int(vf)
|
||||
assert (i == expect_int and isinstance(i, int))
|
||||
assert i == expect_int and isinstance(i, int)
|
||||
vs_out = format_amount(i, 8)
|
||||
# Strip
|
||||
for i in range(7):
|
||||
if vs_out[-1] == '0':
|
||||
if vs_out[-1] == "0":
|
||||
vs_out = vs_out[:-1]
|
||||
if '.' in vs:
|
||||
assert (vs_out == vs)
|
||||
if "." in vs:
|
||||
assert vs_out == vs
|
||||
else:
|
||||
assert (vs_out[:-2] == vs)
|
||||
test_case('0', 0, 0)
|
||||
test_case('1', 1, 100000000)
|
||||
test_case('10', 10, 1000000000)
|
||||
test_case('0.00899999', 0.00899999, 899999)
|
||||
test_case('899999.0', 899999.0, 89999900000000)
|
||||
test_case('899999.00899999', 899999.00899999, 89999900899999)
|
||||
test_case('0.0', 0.0, 0)
|
||||
test_case('1.0', 1.0, 100000000)
|
||||
test_case('1.1', 1.1, 110000000)
|
||||
test_case('1.2', 1.2, 120000000)
|
||||
test_case('0.00899991', 0.00899991, 899991)
|
||||
test_case('0.0089999', 0.0089999, 899990)
|
||||
test_case('0.0089991', 0.0089991, 899910)
|
||||
test_case('0.123', 0.123, 12300000)
|
||||
test_case('123000.000123', 123000.000123, 12300000012300)
|
||||
assert vs_out[:-2] == vs
|
||||
|
||||
test_case("0", 0, 0)
|
||||
test_case("1", 1, 100000000)
|
||||
test_case("10", 10, 1000000000)
|
||||
test_case("0.00899999", 0.00899999, 899999)
|
||||
test_case("899999.0", 899999.0, 89999900000000)
|
||||
test_case("899999.00899999", 899999.00899999, 89999900899999)
|
||||
test_case("0.0", 0.0, 0)
|
||||
test_case("1.0", 1.0, 100000000)
|
||||
test_case("1.1", 1.1, 110000000)
|
||||
test_case("1.2", 1.2, 120000000)
|
||||
test_case("0.00899991", 0.00899991, 899991)
|
||||
test_case("0.0089999", 0.0089999, 899990)
|
||||
test_case("0.0089991", 0.0089991, 899910)
|
||||
test_case("0.123", 0.123, 12300000)
|
||||
test_case("123000.000123", 123000.000123, 12300000012300)
|
||||
|
||||
try:
|
||||
make_int('0.123456789')
|
||||
assert (False)
|
||||
make_int("0.123456789")
|
||||
assert False
|
||||
except Exception as e:
|
||||
assert (str(e) == 'Mantissa too long')
|
||||
validate_amount('0.12345678')
|
||||
assert str(e) == "Mantissa too long"
|
||||
validate_amount("0.12345678")
|
||||
|
||||
# floor
|
||||
assert (make_int('0.123456789', r=-1) == 12345678)
|
||||
assert make_int("0.123456789", r=-1) == 12345678
|
||||
# Round up
|
||||
assert (make_int('0.123456789', r=1) == 12345679)
|
||||
assert make_int("0.123456789", r=1) == 12345679
|
||||
|
||||
def test_make_int12(self):
|
||||
def test_case(vs, vf, expect_int):
|
||||
i = make_int(vs, 12)
|
||||
assert (i == expect_int and isinstance(i, int))
|
||||
assert i == expect_int and isinstance(i, int)
|
||||
i = make_int(vf, 12)
|
||||
assert (i == expect_int and isinstance(i, int))
|
||||
assert i == expect_int and isinstance(i, int)
|
||||
vs_out = format_amount(i, 12)
|
||||
# Strip
|
||||
for i in range(7):
|
||||
if vs_out[-1] == '0':
|
||||
if vs_out[-1] == "0":
|
||||
vs_out = vs_out[:-1]
|
||||
if '.' in vs:
|
||||
assert (vs_out == vs)
|
||||
if "." in vs:
|
||||
assert vs_out == vs
|
||||
else:
|
||||
assert (vs_out[:-2] == vs)
|
||||
test_case('0.123456789', 0.123456789, 123456789000)
|
||||
test_case('0.123456789123', 0.123456789123, 123456789123)
|
||||
assert vs_out[:-2] == vs
|
||||
|
||||
test_case("0.123456789", 0.123456789, 123456789000)
|
||||
test_case("0.123456789123", 0.123456789123, 123456789123)
|
||||
try:
|
||||
make_int('0.1234567891234', 12)
|
||||
assert (False)
|
||||
make_int("0.1234567891234", 12)
|
||||
assert False
|
||||
except Exception as e:
|
||||
assert (str(e) == 'Mantissa too long')
|
||||
validate_amount('0.123456789123', 12)
|
||||
assert str(e) == "Mantissa too long"
|
||||
validate_amount("0.123456789123", 12)
|
||||
try:
|
||||
validate_amount('0.1234567891234', 12)
|
||||
assert (False)
|
||||
validate_amount("0.1234567891234", 12)
|
||||
assert False
|
||||
except Exception as e:
|
||||
assert ('Too many decimal places' in str(e))
|
||||
assert "Too many decimal places" in str(e)
|
||||
try:
|
||||
validate_amount(0.1234567891234, 12)
|
||||
assert (False)
|
||||
assert False
|
||||
except Exception as e:
|
||||
assert ('Too many decimal places' in str(e))
|
||||
assert "Too many decimal places" in str(e)
|
||||
|
||||
def test_ed25519(self):
|
||||
privkey = edu.get_secret()
|
||||
|
@ -175,12 +179,12 @@ class Test(unittest.TestCase):
|
|||
|
||||
privkey_bytes = i2b(privkey)
|
||||
pubkey_test = ed25519_get_pubkey(privkey_bytes)
|
||||
assert (pubkey == pubkey_test)
|
||||
assert pubkey == pubkey_test
|
||||
|
||||
def test_ecdsa_otves(self):
|
||||
coin_settings = {'rpcport': 0, 'rpcauth': 'none'}
|
||||
coin_settings = {"rpcport": 0, "rpcauth": "none"}
|
||||
coin_settings.update(REQUIRED_SETTINGS)
|
||||
ci = BTCInterface(coin_settings, 'regtest')
|
||||
ci = BTCInterface(coin_settings, "regtest")
|
||||
vk_sign = ci.getNewSecretKey()
|
||||
vk_encrypt = ci.getNewSecretKey()
|
||||
|
||||
|
@ -190,79 +194,79 @@ class Test(unittest.TestCase):
|
|||
|
||||
cipher_text = ecdsaotves_enc_sign(vk_sign, pk_encrypt, sign_hash)
|
||||
|
||||
assert (ecdsaotves_enc_verify(pk_sign, pk_encrypt, sign_hash, cipher_text))
|
||||
assert ecdsaotves_enc_verify(pk_sign, pk_encrypt, sign_hash, cipher_text)
|
||||
|
||||
sig = ecdsaotves_dec_sig(vk_encrypt, cipher_text)
|
||||
|
||||
assert (ci.verifySig(pk_sign, sign_hash, sig))
|
||||
assert ci.verifySig(pk_sign, sign_hash, sig)
|
||||
|
||||
recovered_key = ecdsaotves_rec_enc_key(pk_encrypt, cipher_text, sig)
|
||||
|
||||
assert (vk_encrypt == recovered_key)
|
||||
assert vk_encrypt == recovered_key
|
||||
|
||||
def test_sign(self):
|
||||
coin_settings = {'rpcport': 0, 'rpcauth': 'none'}
|
||||
coin_settings = {"rpcport": 0, "rpcauth": "none"}
|
||||
coin_settings.update(REQUIRED_SETTINGS)
|
||||
ci = BTCInterface(coin_settings, 'regtest')
|
||||
ci = BTCInterface(coin_settings, "regtest")
|
||||
|
||||
vk = ci.getNewSecretKey()
|
||||
pk = ci.getPubkey(vk)
|
||||
|
||||
message = 'test signing message'
|
||||
message_hash = hashlib.sha256(bytes(message, 'utf-8')).digest()
|
||||
message = "test signing message"
|
||||
message_hash = hashlib.sha256(bytes(message, "utf-8")).digest()
|
||||
eck = PrivateKey(vk)
|
||||
sig = eck.sign(message.encode('utf-8'))
|
||||
sig = eck.sign(message.encode("utf-8"))
|
||||
|
||||
ci.verifySig(pk, message_hash, sig)
|
||||
|
||||
def test_sign_compact(self):
|
||||
coin_settings = {'rpcport': 0, 'rpcauth': 'none'}
|
||||
coin_settings = {"rpcport": 0, "rpcauth": "none"}
|
||||
coin_settings.update(REQUIRED_SETTINGS)
|
||||
ci = BTCInterface(coin_settings, 'regtest')
|
||||
ci = BTCInterface(coin_settings, "regtest")
|
||||
|
||||
vk = ci.getNewSecretKey()
|
||||
pk = ci.getPubkey(vk)
|
||||
sig = ci.signCompact(vk, 'test signing message')
|
||||
assert (len(sig) == 64)
|
||||
ci.verifyCompactSig(pk, 'test signing message', sig)
|
||||
sig = ci.signCompact(vk, "test signing message")
|
||||
assert len(sig) == 64
|
||||
ci.verifyCompactSig(pk, "test signing message", sig)
|
||||
|
||||
# Nonce is set deterministically (using default libsecp256k1 method rfc6979)
|
||||
sig2 = ci.signCompact(vk, 'test signing message')
|
||||
assert (sig == sig2)
|
||||
sig2 = ci.signCompact(vk, "test signing message")
|
||||
assert sig == sig2
|
||||
|
||||
def test_sign_recoverable(self):
|
||||
coin_settings = {'rpcport': 0, 'rpcauth': 'none'}
|
||||
coin_settings = {"rpcport": 0, "rpcauth": "none"}
|
||||
coin_settings.update(REQUIRED_SETTINGS)
|
||||
ci = BTCInterface(coin_settings, 'regtest')
|
||||
ci = BTCInterface(coin_settings, "regtest")
|
||||
|
||||
vk = ci.getNewSecretKey()
|
||||
pk = ci.getPubkey(vk)
|
||||
sig = ci.signRecoverable(vk, 'test signing message')
|
||||
assert (len(sig) == 65)
|
||||
pk_rec = ci.verifySigAndRecover(sig, 'test signing message')
|
||||
assert (pk == pk_rec)
|
||||
sig = ci.signRecoverable(vk, "test signing message")
|
||||
assert len(sig) == 65
|
||||
pk_rec = ci.verifySigAndRecover(sig, "test signing message")
|
||||
assert pk == pk_rec
|
||||
|
||||
# Nonce is set deterministically (using default libsecp256k1 method rfc6979)
|
||||
sig2 = ci.signRecoverable(vk, 'test signing message')
|
||||
assert (sig == sig2)
|
||||
sig2 = ci.signRecoverable(vk, "test signing message")
|
||||
assert sig == sig2
|
||||
|
||||
def test_pubkey_to_address(self):
|
||||
coin_settings = {'rpcport': 0, 'rpcauth': 'none'}
|
||||
coin_settings = {"rpcport": 0, "rpcauth": "none"}
|
||||
coin_settings.update(REQUIRED_SETTINGS)
|
||||
ci = BTCInterface(coin_settings, 'regtest')
|
||||
pk = h2b('02c26a344e7d21bcc6f291532679559f2fd234c881271ff98714855edc753763a6')
|
||||
ci = BTCInterface(coin_settings, "regtest")
|
||||
pk = h2b("02c26a344e7d21bcc6f291532679559f2fd234c881271ff98714855edc753763a6")
|
||||
addr = ci.pubkey_to_address(pk)
|
||||
assert (addr == 'mj6SdSxmWRmdDqR5R3FfZmRiLmQfQAsLE8')
|
||||
assert addr == "mj6SdSxmWRmdDqR5R3FfZmRiLmQfQAsLE8"
|
||||
|
||||
def test_dleag(self):
|
||||
coin_settings = {'rpcport': 0, 'walletrpcport': 0, 'walletrpcauth': 'none'}
|
||||
coin_settings = {"rpcport": 0, "walletrpcport": 0, "walletrpcauth": "none"}
|
||||
coin_settings.update(REQUIRED_SETTINGS)
|
||||
|
||||
ci = XMRInterface(coin_settings, 'regtest')
|
||||
ci = XMRInterface(coin_settings, "regtest")
|
||||
|
||||
key = ci.getNewSecretKey()
|
||||
proof = ci.proveDLEAG(key)
|
||||
assert (ci.verifyDLEAG(proof))
|
||||
assert ci.verifyDLEAG(proof)
|
||||
|
||||
def test_rate(self):
|
||||
scale_from = 8
|
||||
|
@ -270,53 +274,58 @@ class Test(unittest.TestCase):
|
|||
amount_from = make_int(100, scale_from)
|
||||
rate = make_int(0.1, scale_to)
|
||||
|
||||
amount_to = int((amount_from * rate) // (10 ** scale_from))
|
||||
assert ('100.00000000' == format_amount(amount_from, scale_from))
|
||||
assert ('10.000000000000' == format_amount(amount_to, scale_to))
|
||||
amount_to = int((amount_from * rate) // (10**scale_from))
|
||||
assert "100.00000000" == format_amount(amount_from, scale_from)
|
||||
assert "10.000000000000" == format_amount(amount_to, scale_to)
|
||||
|
||||
rate_check = make_int((amount_to / amount_from), scale_from)
|
||||
assert (rate == rate_check)
|
||||
assert rate == rate_check
|
||||
|
||||
scale_from = 12
|
||||
scale_to = 8
|
||||
amount_from = make_int(1, scale_from)
|
||||
rate = make_int(12, scale_to)
|
||||
|
||||
amount_to = int((amount_from * rate) // (10 ** scale_from))
|
||||
assert ('1.000000000000' == format_amount(amount_from, scale_from))
|
||||
assert ('12.00000000' == format_amount(amount_to, scale_to))
|
||||
amount_to = int((amount_from * rate) // (10**scale_from))
|
||||
assert "1.000000000000" == format_amount(amount_from, scale_from)
|
||||
assert "12.00000000" == format_amount(amount_to, scale_to)
|
||||
|
||||
rate_check = make_int((amount_to / amount_from), scale_from)
|
||||
assert (rate == rate_check)
|
||||
assert rate == rate_check
|
||||
|
||||
scale_from = 8
|
||||
scale_to = 8
|
||||
amount_from = make_int(0.073, scale_from)
|
||||
amount_to = make_int(10, scale_to)
|
||||
rate = make_int(amount_to / amount_from, scale_to, r=1)
|
||||
amount_to_recreate = int((amount_from * rate) // (10 ** scale_from))
|
||||
assert ('10.00000000' == format_amount(amount_to_recreate, scale_to))
|
||||
amount_to_recreate = int((amount_from * rate) // (10**scale_from))
|
||||
assert "10.00000000" == format_amount(amount_to_recreate, scale_to)
|
||||
|
||||
scale_from = 8
|
||||
scale_to = 12
|
||||
amount_from = make_int(10.0, scale_from)
|
||||
amount_to = make_int(0.06935, scale_to)
|
||||
rate = make_int(amount_to / amount_from, scale_from, r=1)
|
||||
amount_to_recreate = int((amount_from * rate) // (10 ** scale_from))
|
||||
assert ('0.069350000000' == format_amount(amount_to_recreate, scale_to))
|
||||
amount_to_recreate = int((amount_from * rate) // (10**scale_from))
|
||||
assert "0.069350000000" == format_amount(amount_to_recreate, scale_to)
|
||||
|
||||
scale_from = 12
|
||||
scale_to = 8
|
||||
amount_from = make_int(0.06935, scale_from)
|
||||
amount_to = make_int(10.0, scale_to)
|
||||
rate = make_int(amount_to / amount_from, scale_from, r=1)
|
||||
amount_to_recreate = int((amount_from * rate) // (10 ** scale_from))
|
||||
assert ('10.00000000' == format_amount(amount_to_recreate, scale_to))
|
||||
amount_to_recreate = int((amount_from * rate) // (10**scale_from))
|
||||
assert "10.00000000" == format_amount(amount_to_recreate, scale_to)
|
||||
|
||||
coin_settings = {'rpcport': 0, 'rpcauth': 'none', 'walletrpcport': 0, 'walletrpcauth': 'none'}
|
||||
coin_settings = {
|
||||
"rpcport": 0,
|
||||
"rpcauth": "none",
|
||||
"walletrpcport": 0,
|
||||
"walletrpcauth": "none",
|
||||
}
|
||||
coin_settings.update(REQUIRED_SETTINGS)
|
||||
ci_xmr = XMRInterface(coin_settings, 'regtest')
|
||||
ci_btc = BTCInterface(coin_settings, 'regtest')
|
||||
ci_xmr = XMRInterface(coin_settings, "regtest")
|
||||
ci_btc = BTCInterface(coin_settings, "regtest")
|
||||
|
||||
for i in range(10000):
|
||||
test_pairs = random.randint(0, 3)
|
||||
|
@ -362,55 +371,73 @@ class Test(unittest.TestCase):
|
|||
amount_to = random.randint(10000, 2100000000 * ci_to.COIN())
|
||||
|
||||
offer_rate = ci_from.make_int(amount_to / amount_from, r=1)
|
||||
amount_to_from_rate: int = int((int(amount_from) * offer_rate) // (10 ** scale_from))
|
||||
amount_to_from_rate: int = int(
|
||||
(int(amount_from) * offer_rate) // (10**scale_from)
|
||||
)
|
||||
|
||||
scale_from = 24
|
||||
offer_rate = make_int(amount_to, scale_from) // amount_from
|
||||
amount_to_from_rate: int = int((int(amount_from) * offer_rate) // (10 ** scale_from))
|
||||
amount_to_from_rate: int = int(
|
||||
(int(amount_from) * offer_rate) // (10**scale_from)
|
||||
)
|
||||
|
||||
if abs(amount_to - amount_to_from_rate) == 1:
|
||||
offer_rate += 1
|
||||
|
||||
offer_rate_human_read: int = int(offer_rate // (10 ** (scale_from - ci_from.exp())))
|
||||
amount_to_from_rate: int = int((int(amount_from) * offer_rate) // (10 ** scale_from))
|
||||
offer_rate_human_read: int = int(
|
||||
offer_rate // (10 ** (scale_from - ci_from.exp()))
|
||||
)
|
||||
amount_to_from_rate: int = int(
|
||||
(int(amount_from) * offer_rate) // (10**scale_from)
|
||||
)
|
||||
|
||||
if amount_to != amount_to_from_rate:
|
||||
print('from exp, amount', ci_from.exp(), amount_from)
|
||||
print('to exp, amount', ci_to.exp(), amount_to)
|
||||
print('amount_to_from_rate', amount_to_from_rate)
|
||||
raise ValueError('Bad amount_to')
|
||||
print("from exp, amount", ci_from.exp(), amount_from)
|
||||
print("to exp, amount", ci_to.exp(), amount_to)
|
||||
print("offer_rate_human_read", offer_rate_human_read)
|
||||
print("amount_to_from_rate", amount_to_from_rate)
|
||||
raise ValueError("Bad amount_to")
|
||||
|
||||
scale_to = 24
|
||||
reversed_rate = make_int(amount_from, scale_to) // amount_to
|
||||
|
||||
amount_from_from_rate: int = int((int(amount_to) * reversed_rate) // (10 ** scale_to))
|
||||
amount_from_from_rate: int = int(
|
||||
(int(amount_to) * reversed_rate) // (10**scale_to)
|
||||
)
|
||||
if abs(amount_from - amount_from_from_rate) == 1:
|
||||
reversed_rate += 1
|
||||
|
||||
amount_from_from_rate: int = int((int(amount_to) * reversed_rate) // (10 ** scale_to))
|
||||
amount_from_from_rate: int = int(
|
||||
(int(amount_to) * reversed_rate) // (10**scale_to)
|
||||
)
|
||||
|
||||
if amount_from != amount_from_from_rate:
|
||||
print('from exp, amount', ci_from.exp(), amount_from)
|
||||
print('to exp, amount', ci_to.exp(), amount_to)
|
||||
print('amount_from_from_rate', amount_from_from_rate)
|
||||
raise ValueError('Bad amount_from')
|
||||
print("from exp, amount", ci_from.exp(), amount_from)
|
||||
print("to exp, amount", ci_to.exp(), amount_to)
|
||||
print("amount_from_from_rate", amount_from_from_rate)
|
||||
raise ValueError("Bad amount_from")
|
||||
|
||||
def test_rfc2440(self):
|
||||
password = 'test'
|
||||
salt = bytes.fromhex('B7A94A7E4988630E')
|
||||
password = "test"
|
||||
salt = bytes.fromhex("B7A94A7E4988630E")
|
||||
password_hash = rfc2440_hash_password(password, salt=salt)
|
||||
|
||||
assert (password_hash == '16:B7A94A7E4988630E6095334BA67F06FBA509B2A7136A04C9C1B430F539')
|
||||
assert (
|
||||
password_hash
|
||||
== "16:B7A94A7E4988630E6095334BA67F06FBA509B2A7136A04C9C1B430F539"
|
||||
)
|
||||
|
||||
def test_ripemd160(self):
|
||||
input_data = b'hash this'
|
||||
assert (ripemd160(input_data).hex() == 'd5443a154f167e2c1332f6de72cfb4c6ab9c8c17')
|
||||
input_data = b"hash this"
|
||||
assert ripemd160(input_data).hex() == "d5443a154f167e2c1332f6de72cfb4c6ab9c8c17"
|
||||
|
||||
def test_hash160(self):
|
||||
# hash160 is RIPEMD(SHA256(data))
|
||||
input_data = b'hash this'
|
||||
assert (hash160(input_data).hex() == '072985b3583a4a71f548494a5e1d5f6b00d0fe13')
|
||||
assert (hash160_btc(input_data).hex() == '072985b3583a4a71f548494a5e1d5f6b00d0fe13')
|
||||
input_data = b"hash this"
|
||||
assert hash160(input_data).hex() == "072985b3583a4a71f548494a5e1d5f6b00d0fe13"
|
||||
assert (
|
||||
hash160_btc(input_data).hex() == "072985b3583a4a71f548494a5e1d5f6b00d0fe13"
|
||||
)
|
||||
|
||||
def test_protobuf(self):
|
||||
msg_buf = BidMessage()
|
||||
|
@ -420,37 +447,37 @@ class Test(unittest.TestCase):
|
|||
|
||||
msg_buf_2 = BidMessage()
|
||||
msg_buf_2.from_bytes(serialised_msg)
|
||||
assert (msg_buf_2.protocol_version == 2)
|
||||
assert (msg_buf_2.time_valid == 1024)
|
||||
assert (msg_buf_2.amount == 0)
|
||||
assert (msg_buf_2.pkhash_buyer is not None)
|
||||
assert (len(msg_buf_2.pkhash_buyer) == 0)
|
||||
assert msg_buf_2.protocol_version == 2
|
||||
assert msg_buf_2.time_valid == 1024
|
||||
assert msg_buf_2.amount == 0
|
||||
assert msg_buf_2.pkhash_buyer is not None
|
||||
assert len(msg_buf_2.pkhash_buyer) == 0
|
||||
|
||||
# Decode only the first field
|
||||
msg_buf_3 = BidMessage()
|
||||
msg_buf_3.from_bytes(serialised_msg[:2])
|
||||
assert (msg_buf_3.protocol_version == 2)
|
||||
assert (msg_buf_3.time_valid == 0)
|
||||
assert msg_buf_3.protocol_version == 2
|
||||
assert msg_buf_3.time_valid == 0
|
||||
|
||||
try:
|
||||
msg_buf_4 = BidMessage(doesnotexist=1)
|
||||
_ = BidMessage(doesnotexist=1)
|
||||
except Exception as e:
|
||||
assert ('unexpected keyword argument' in str(e))
|
||||
assert "unexpected keyword argument" in str(e)
|
||||
else:
|
||||
raise ValueError('Should have errored.')
|
||||
raise ValueError("Should have errored.")
|
||||
|
||||
def test_is_private_ip_address(self):
|
||||
test_addresses = [
|
||||
('localhost', True),
|
||||
('127.0.0.1', True),
|
||||
('10.0.0.0', True),
|
||||
('172.16.0.0', True),
|
||||
('192.168.0.0', True),
|
||||
('20.87.245.0', False),
|
||||
('particl.io', False),
|
||||
("localhost", True),
|
||||
("127.0.0.1", True),
|
||||
("10.0.0.0", True),
|
||||
("172.16.0.0", True),
|
||||
("192.168.0.0", True),
|
||||
("20.87.245.0", False),
|
||||
("particl.io", False),
|
||||
]
|
||||
for addr, is_private in test_addresses:
|
||||
assert (is_private_ip_address(addr) is is_private)
|
||||
assert is_private_ip_address(addr) is is_private
|
||||
|
||||
def test_varint(self):
|
||||
test_vectors = [
|
||||
|
@ -467,8 +494,8 @@ class Test(unittest.TestCase):
|
|||
]
|
||||
for i, expect_length in test_vectors:
|
||||
b = encode_varint(i)
|
||||
assert (len(b) == expect_length)
|
||||
assert (decode_varint(b) == (i, expect_length))
|
||||
assert len(b) == expect_length
|
||||
assert decode_varint(b) == (i, expect_length)
|
||||
|
||||
def test_base58(self):
|
||||
kv = edu.get_secret()
|
||||
|
@ -477,55 +504,58 @@ class Test(unittest.TestCase):
|
|||
Ks = edu.encodepoint(edf.scalarmult_B(ks))
|
||||
|
||||
addr = xmr_encode_address(Kv, Ks)
|
||||
assert (addr.startswith('4'))
|
||||
assert addr.startswith("4")
|
||||
|
||||
addr = xmr_encode_address(Kv, Ks, 4146)
|
||||
assert (addr.startswith('Wo'))
|
||||
assert addr.startswith("Wo")
|
||||
|
||||
def test_blake256(self):
|
||||
test_vectors = [
|
||||
('716f6e863f744b9ac22c97ec7b76ea5f5908bc5b2f67c61510bfc4751384ea7a', b''),
|
||||
('7576698ee9cad30173080678e5965916adbb11cb5245d386bf1ffda1cb26c9d7', b'The quick brown fox jumps over the lazy dog'),
|
||||
("716f6e863f744b9ac22c97ec7b76ea5f5908bc5b2f67c61510bfc4751384ea7a", b""),
|
||||
(
|
||||
"7576698ee9cad30173080678e5965916adbb11cb5245d386bf1ffda1cb26c9d7",
|
||||
b"The quick brown fox jumps over the lazy dog",
|
||||
),
|
||||
]
|
||||
for expect_hash, data in test_vectors:
|
||||
assert (blake256(data).hex() == expect_hash)
|
||||
assert blake256(data).hex() == expect_hash
|
||||
|
||||
def test_extkey(self):
|
||||
test_key = 'XPARHAr37YxmFP8wyjkaHAQWmp84GiyLikL7EL8j9BCx4LkB8Q1Bw5Kr8sA1GA3Ym53zNLcaxxFHr6u81JVTeCaD61c6fKS1YRAuti8Zu5SzJCjh'
|
||||
test_key_c0 = 'XPARHAt1XMcNYAwP5wEnQXknBAkGSzaetdZt2eoJZehdB4WXfV1xbSjpgHe44AivmumcSejW5KaYx6L5M6MyR1WyXrsWTwaiUEfHq2RrqCfXj3ZW'
|
||||
test_key_c0_p = 'PPARTKPL4rp5WLnrYP6jZfuRjx6jrmvbsz5QdHofPfFqJdm918mQwdPLq6Dd9TkdbQeKUqjbHWkyzWe7Pftd7itzm7ETEoUMq4cbG4fY9FKH1YSU'
|
||||
test_key_c0h = 'XPARHAt1XMcNgWbv48LwoQbjs1bC8kCXKomzvJLRT5xmbQ2GKf9e8Vfr1MMcfiWJC34RyDp5HvAfjeiNyLDfkFm1UrRCrPkVC9GGaAWa3nXMWew8'
|
||||
test_key = "XPARHAr37YxmFP8wyjkaHAQWmp84GiyLikL7EL8j9BCx4LkB8Q1Bw5Kr8sA1GA3Ym53zNLcaxxFHr6u81JVTeCaD61c6fKS1YRAuti8Zu5SzJCjh"
|
||||
test_key_c0 = "XPARHAt1XMcNYAwP5wEnQXknBAkGSzaetdZt2eoJZehdB4WXfV1xbSjpgHe44AivmumcSejW5KaYx6L5M6MyR1WyXrsWTwaiUEfHq2RrqCfXj3ZW"
|
||||
test_key_c0_p = "PPARTKPL4rp5WLnrYP6jZfuRjx6jrmvbsz5QdHofPfFqJdm918mQwdPLq6Dd9TkdbQeKUqjbHWkyzWe7Pftd7itzm7ETEoUMq4cbG4fY9FKH1YSU"
|
||||
test_key_c0h = "XPARHAt1XMcNgWbv48LwoQbjs1bC8kCXKomzvJLRT5xmbQ2GKf9e8Vfr1MMcfiWJC34RyDp5HvAfjeiNyLDfkFm1UrRCrPkVC9GGaAWa3nXMWew8"
|
||||
|
||||
ek_data = decodeAddress(test_key)[4:]
|
||||
|
||||
ek = ExtKeyPair()
|
||||
ek.decode(ek_data)
|
||||
assert (ek.encode_v() == ek_data)
|
||||
assert ek.encode_v() == ek_data
|
||||
|
||||
m_0 = ek.derive(0)
|
||||
|
||||
ek_c0_data = decodeAddress(test_key_c0)[4:]
|
||||
assert (m_0.encode_v() == ek_c0_data)
|
||||
assert m_0.encode_v() == ek_c0_data
|
||||
|
||||
child_no: int = 0 | (1 << 31)
|
||||
m_0h = ek.derive(child_no)
|
||||
|
||||
ek_c0h_data = decodeAddress(test_key_c0h)[4:]
|
||||
assert (m_0h.encode_v() == ek_c0h_data)
|
||||
assert m_0h.encode_v() == ek_c0h_data
|
||||
|
||||
ek.neuter()
|
||||
assert (ek.has_key() is False)
|
||||
assert ek.has_key() is False
|
||||
m_0 = ek.derive(0)
|
||||
|
||||
ek_c0_p_data = decodeAddress(test_key_c0_p)[4:]
|
||||
assert (m_0.encode_p() == ek_c0_p_data)
|
||||
assert m_0.encode_p() == ek_c0_p_data
|
||||
|
||||
def test_mnemonic(self):
|
||||
entropy0: bytes = Mnemonic('english').to_entropy(mnemonics[0])
|
||||
assert (entropy0.hex() == '0002207e9b744ea2d7ab41702f31f000')
|
||||
mnemonic_recovered: str = Mnemonic('english').to_mnemonic(entropy0)
|
||||
assert (mnemonic_recovered == mnemonics[0])
|
||||
entropy0: bytes = Mnemonic("english").to_entropy(mnemonics[0])
|
||||
assert entropy0.hex() == "0002207e9b744ea2d7ab41702f31f000"
|
||||
mnemonic_recovered: str = Mnemonic("english").to_mnemonic(entropy0)
|
||||
assert mnemonic_recovered == mnemonics[0]
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright (c) 2021-2023 tecnovert
|
||||
# Copyright (c) 2024 The Basicswap developers
|
||||
# Distributed under the MIT software license, see the accompanying
|
||||
# file LICENSE or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
|
@ -51,45 +52,65 @@ class Test(BaseTest):
|
|||
def setUpClass(cls):
|
||||
super(Test, cls).setUpClass()
|
||||
|
||||
js_0 = read_json_api(1800, 'wallets/part')
|
||||
node0_blind_before = js_0['blind_balance'] + js_0['blind_unconfirmed']
|
||||
js_0 = read_json_api(1800, "wallets/part")
|
||||
node0_blind_before = js_0["blind_balance"] + js_0["blind_unconfirmed"]
|
||||
|
||||
post_json = {
|
||||
'value': 100,
|
||||
'address': js_0['stealth_address'],
|
||||
'subfee': False,
|
||||
'type_to': 'blind',
|
||||
"value": 100,
|
||||
"address": js_0["stealth_address"],
|
||||
"subfee": False,
|
||||
"type_to": "blind",
|
||||
}
|
||||
json_rv = json.loads(post_json_req('http://127.0.0.1:1800/json/wallets/part/withdraw', post_json))
|
||||
assert (len(json_rv['txid']) == 64)
|
||||
json_rv = json.loads(
|
||||
post_json_req("http://127.0.0.1:1800/json/wallets/part/withdraw", post_json)
|
||||
)
|
||||
assert len(json_rv["txid"]) == 64
|
||||
|
||||
logging.info('Waiting for blind balance')
|
||||
wait_for_balance(test_delay_event, 'http://127.0.0.1:1800/json/wallets/part', 'blind_balance', 100.0 + node0_blind_before)
|
||||
js_0 = read_json_api(1800, 'wallets/part')
|
||||
logging.info("Waiting for blind balance")
|
||||
wait_for_balance(
|
||||
test_delay_event,
|
||||
"http://127.0.0.1:1800/json/wallets/part",
|
||||
"blind_balance",
|
||||
100.0 + node0_blind_before,
|
||||
)
|
||||
js_0 = read_json_api(1800, "wallets/part")
|
||||
|
||||
def ensure_balance(self, coin_type, node_id, amount):
|
||||
tla = 'PART'
|
||||
js_w = read_json_api(1800 + node_id, 'wallets')
|
||||
print('js_w', js_w)
|
||||
if float(js_w[tla]['blind_balance']) < amount:
|
||||
tla = "PART"
|
||||
js_w = read_json_api(1800 + node_id, "wallets")
|
||||
print("js_w", js_w)
|
||||
if float(js_w[tla]["blind_balance"]) < amount:
|
||||
post_json = {
|
||||
'value': amount,
|
||||
'type_to': 'blind',
|
||||
'address': js_w[tla]['stealth_address'],
|
||||
'subfee': False,
|
||||
"value": amount,
|
||||
"type_to": "blind",
|
||||
"address": js_w[tla]["stealth_address"],
|
||||
"subfee": False,
|
||||
}
|
||||
json_rv = read_json_api(1800, 'wallets/{}/withdraw'.format(tla.lower()), post_json)
|
||||
assert (len(json_rv['txid']) == 64)
|
||||
wait_for_balance(test_delay_event, 'http://127.0.0.1:{}/json/wallets/{}'.format(1800 + node_id, tla.lower()), 'blind_balance', amount)
|
||||
json_rv = read_json_api(
|
||||
1800, "wallets/{}/withdraw".format(tla.lower()), post_json
|
||||
)
|
||||
assert len(json_rv["txid"]) == 64
|
||||
wait_for_balance(
|
||||
test_delay_event,
|
||||
"http://127.0.0.1:{}/json/wallets/{}".format(
|
||||
1800 + node_id, tla.lower()
|
||||
),
|
||||
"blind_balance",
|
||||
amount,
|
||||
)
|
||||
|
||||
def getBalance(self, js_wallets):
|
||||
return float(js_wallets[Coins.PART.name]['blind_balance']) + float(js_wallets[Coins.PART.name]['blind_unconfirmed'])
|
||||
return float(js_wallets[Coins.PART.name]["blind_balance"]) + float(
|
||||
js_wallets[Coins.PART.name]["blind_unconfirmed"]
|
||||
)
|
||||
|
||||
def getXmrBalance(self, js_wallets):
|
||||
return float(js_wallets[Coins.XMR.name]['unconfirmed']) + float(js_wallets[Coins.XMR.name]['balance'])
|
||||
return float(js_wallets[Coins.XMR.name]["unconfirmed"]) + float(
|
||||
js_wallets[Coins.XMR.name]["balance"]
|
||||
)
|
||||
|
||||
def test_010_txn_size(self):
|
||||
logging.info('---------- Test {} txn_size'.format(self.test_coin_from.name))
|
||||
logging.info("---------- Test {} txn_size".format(self.test_coin_from.name))
|
||||
|
||||
self.ensure_balance(self.test_coin_from, 0, 100.0)
|
||||
|
||||
|
@ -101,20 +122,21 @@ class Test(BaseTest):
|
|||
nonlocal ci
|
||||
i = 0
|
||||
while not delay_event.is_set():
|
||||
unspents = ci.rpc_wallet('listunspentblind')
|
||||
unspents = ci.rpc_wallet("listunspentblind")
|
||||
if len(unspents) >= 1:
|
||||
return
|
||||
delay_event.wait(delay_time)
|
||||
i += 1
|
||||
if i > iterations:
|
||||
raise ValueError('wait_for_unspents timed out')
|
||||
raise ValueError("wait_for_unspents timed out")
|
||||
|
||||
wait_for_unspents(test_delay_event)
|
||||
|
||||
amount: int = ci.make_int(random.uniform(0.1, 2.0), r=1)
|
||||
|
||||
# Record unspents before createSCLockTx as the used ones will be locked
|
||||
unspents = ci.rpc_wallet('listunspentblind')
|
||||
locked_utxos_before = ci.rpc_wallet('listlockunspent')
|
||||
unspents = ci.rpc_wallet("listunspentblind")
|
||||
locked_utxos_before = ci.rpc_wallet("listlockunspent")
|
||||
|
||||
# fee_rate is in sats/kvB
|
||||
fee_rate: int = 1000
|
||||
|
@ -131,53 +153,61 @@ class Test(BaseTest):
|
|||
lock_tx = ci.fundSCLockTx(lock_tx, fee_rate, vkbv)
|
||||
lock_tx = ci.signTxWithWallet(lock_tx)
|
||||
|
||||
unspents_after = ci.rpc_wallet('listunspentblind')
|
||||
locked_utxos_after = ci.rpc_wallet('listlockunspent')
|
||||
unspents_after = ci.rpc_wallet("listunspentblind")
|
||||
locked_utxos_after = ci.rpc_wallet("listlockunspent")
|
||||
|
||||
assert (len(unspents) > len(unspents_after))
|
||||
assert (len(locked_utxos_after) > len(locked_utxos_before))
|
||||
lock_tx_decoded = ci.rpc_wallet('decoderawtransaction', [lock_tx.hex()])
|
||||
txid = lock_tx_decoded['txid']
|
||||
assert len(unspents) > len(unspents_after)
|
||||
assert len(locked_utxos_after) > len(locked_utxos_before)
|
||||
lock_tx_decoded = ci.rpc_wallet("decoderawtransaction", [lock_tx.hex()])
|
||||
txid = lock_tx_decoded["txid"]
|
||||
|
||||
vsize = lock_tx_decoded['vsize']
|
||||
vsize = lock_tx_decoded["vsize"]
|
||||
expect_fee_int = round(fee_rate * vsize / 1000)
|
||||
expect_fee = ci.format_amount(expect_fee_int)
|
||||
|
||||
ci.rpc_wallet('sendrawtransaction', [lock_tx.hex()])
|
||||
rv = ci.rpc_wallet('gettransaction', [txid])
|
||||
wallet_tx_fee = -ci.make_int(rv['details'][0]['fee'])
|
||||
ci.rpc_wallet("sendrawtransaction", [lock_tx.hex()])
|
||||
rv = ci.rpc_wallet("gettransaction", [txid])
|
||||
wallet_tx_fee = -ci.make_int(rv["details"][0]["fee"])
|
||||
|
||||
assert (wallet_tx_fee >= expect_fee_int)
|
||||
assert (wallet_tx_fee - expect_fee_int < 20)
|
||||
assert wallet_tx_fee >= expect_fee_int
|
||||
assert wallet_tx_fee - expect_fee_int < 20
|
||||
|
||||
addr_out = ci.getNewAddress(True)
|
||||
addrinfo = ci.rpc_wallet('getaddressinfo', [addr_out,])
|
||||
pk_out = bytes.fromhex(addrinfo['pubkey'])
|
||||
addrinfo = ci.rpc_wallet(
|
||||
"getaddressinfo",
|
||||
[
|
||||
addr_out,
|
||||
],
|
||||
)
|
||||
pk_out = bytes.fromhex(addrinfo["pubkey"])
|
||||
fee_info = {}
|
||||
lock_spend_tx = ci.createSCLockSpendTx(lock_tx, lock_tx_script, pk_out, fee_rate, vkbv, fee_info=fee_info)
|
||||
vsize_estimated: int = fee_info['vsize']
|
||||
lock_spend_tx = ci.createSCLockSpendTx(
|
||||
lock_tx, lock_tx_script, pk_out, fee_rate, vkbv, fee_info=fee_info
|
||||
)
|
||||
vsize_estimated: int = fee_info["vsize"]
|
||||
|
||||
spend_tx_decoded = ci.rpc('decoderawtransaction', [lock_spend_tx.hex()])
|
||||
txid = spend_tx_decoded['txid']
|
||||
spend_tx_decoded = ci.rpc("decoderawtransaction", [lock_spend_tx.hex()])
|
||||
txid = spend_tx_decoded["txid"]
|
||||
|
||||
nonce = ci.getScriptLockTxNonce(vkbv)
|
||||
output_n, _ = ci.findOutputByNonce(lock_tx_decoded, nonce)
|
||||
assert (output_n is not None)
|
||||
valueCommitment = bytes.fromhex(lock_tx_decoded['vout'][output_n]['valueCommitment'])
|
||||
assert output_n is not None
|
||||
valueCommitment = bytes.fromhex(
|
||||
lock_tx_decoded["vout"][output_n]["valueCommitment"]
|
||||
)
|
||||
|
||||
witness_stack = [
|
||||
b'',
|
||||
b"",
|
||||
ci.signTx(a, lock_spend_tx, 0, lock_tx_script, valueCommitment),
|
||||
ci.signTx(b, lock_spend_tx, 0, lock_tx_script, valueCommitment),
|
||||
lock_tx_script,
|
||||
]
|
||||
lock_spend_tx = ci.setTxSignature(lock_spend_tx, witness_stack)
|
||||
tx_decoded = ci.rpc('decoderawtransaction', [lock_spend_tx.hex()])
|
||||
vsize_actual: int = tx_decoded['vsize']
|
||||
tx_decoded = ci.rpc("decoderawtransaction", [lock_spend_tx.hex()])
|
||||
vsize_actual: int = tx_decoded["vsize"]
|
||||
|
||||
# Note: The fee is set allowing 9 bytes for the encoded fee amount, causing a small overestimate
|
||||
assert (vsize_actual <= vsize_estimated and vsize_estimated - vsize_actual < 10)
|
||||
assert (ci.rpc('sendrawtransaction', [lock_spend_tx.hex()]) == txid)
|
||||
assert vsize_actual <= vsize_estimated and vsize_estimated - vsize_actual < 10
|
||||
assert ci.rpc("sendrawtransaction", [lock_spend_tx.hex()]) == txid
|
||||
|
||||
# Test chain b (no-script) lock tx size
|
||||
v = ci.getNewSecretKey()
|
||||
|
@ -189,40 +219,50 @@ class Test(BaseTest):
|
|||
lock_tx_b_spend_txid = None
|
||||
for i in range(20):
|
||||
try:
|
||||
lock_tx_b_spend_txid = ci.spendBLockTx(lock_tx_b_txid, addr_out, v, s, amount, fee_rate, 0)
|
||||
lock_tx_b_spend_txid = ci.spendBLockTx(
|
||||
lock_tx_b_txid, addr_out, v, s, amount, fee_rate, 0
|
||||
)
|
||||
break
|
||||
except Exception as e:
|
||||
print('spendBLockTx failed', str(e))
|
||||
print("spendBLockTx failed", str(e))
|
||||
test_delay_event.wait(2)
|
||||
assert (lock_tx_b_spend_txid is not None)
|
||||
assert lock_tx_b_spend_txid is not None
|
||||
lock_tx_b_spend = ci.getTransaction(lock_tx_b_spend_txid)
|
||||
if lock_tx_b_spend is None:
|
||||
lock_tx_b_spend = ci.getWalletTransaction(lock_tx_b_spend_txid)
|
||||
lock_tx_b_spend_decoded = ci.rpc('decoderawtransaction', [lock_tx_b_spend.hex()])
|
||||
lock_tx_b_spend_decoded = ci.rpc(
|
||||
"decoderawtransaction", [lock_tx_b_spend.hex()]
|
||||
)
|
||||
|
||||
expect_vsize: int = ci.xmr_swap_b_lock_spend_tx_vsize()
|
||||
assert (expect_vsize >= lock_tx_b_spend_decoded['vsize'])
|
||||
assert (expect_vsize - lock_tx_b_spend_decoded['vsize'] < 10)
|
||||
assert expect_vsize >= lock_tx_b_spend_decoded["vsize"]
|
||||
assert expect_vsize - lock_tx_b_spend_decoded["vsize"] < 10
|
||||
|
||||
def test_01_part_xmr(self):
|
||||
logging.info('---------- Test PARTct to XMR')
|
||||
logging.info("---------- Test PARTct to XMR")
|
||||
swap_clients = self.swap_clients
|
||||
|
||||
js_0 = read_json_api(1800, 'wallets/part')
|
||||
assert (float(js_0['blind_balance']) > 10.0)
|
||||
node0_blind_before = js_0['blind_balance'] + js_0['blind_unconfirmed']
|
||||
js_0 = read_json_api(1800, "wallets/part")
|
||||
assert float(js_0["blind_balance"]) > 10.0
|
||||
node0_blind_before = js_0["blind_balance"] + js_0["blind_unconfirmed"]
|
||||
|
||||
js_1 = read_json_api(1801, 'wallets/part')
|
||||
node1_blind_before = js_1['blind_balance'] + js_1['blind_unconfirmed']
|
||||
js_1 = read_json_api(1801, "wallets/part")
|
||||
node1_blind_before = js_1["blind_balance"] + js_1["blind_unconfirmed"]
|
||||
|
||||
js_0_xmr = read_json_api(1800, 'wallets/xmr')
|
||||
js_1_xmr = read_json_api(1801, 'wallets/xmr')
|
||||
js_1_xmr = read_json_api(1801, "wallets/xmr")
|
||||
|
||||
amt_swap = make_int(random.uniform(0.1, 2.0), scale=8, r=1)
|
||||
rate_swap = make_int(random.uniform(0.2, 20.0), scale=12, r=1)
|
||||
offer_id = swap_clients[0].postOffer(Coins.PART_BLIND, Coins.XMR, amt_swap, rate_swap, amt_swap, SwapTypes.XMR_SWAP)
|
||||
offer_id = swap_clients[0].postOffer(
|
||||
Coins.PART_BLIND,
|
||||
Coins.XMR,
|
||||
amt_swap,
|
||||
rate_swap,
|
||||
amt_swap,
|
||||
SwapTypes.XMR_SWAP,
|
||||
)
|
||||
wait_for_offer(test_delay_event, swap_clients[1], offer_id)
|
||||
offers = swap_clients[0].listOffers(filters={'offer_id': offer_id})
|
||||
offers = swap_clients[0].listOffers(filters={"offer_id": offer_id})
|
||||
offer = offers[0]
|
||||
|
||||
bid_id = swap_clients[1].postXmrBid(offer_id, offer.amount_from)
|
||||
|
@ -231,40 +271,60 @@ class Test(BaseTest):
|
|||
|
||||
swap_clients[0].acceptXmrBid(bid_id)
|
||||
|
||||
wait_for_bid(test_delay_event, swap_clients[0], bid_id, BidStates.SWAP_COMPLETED, wait_for=180)
|
||||
wait_for_bid(test_delay_event, swap_clients[1], bid_id, BidStates.SWAP_COMPLETED, sent=True)
|
||||
wait_for_bid(
|
||||
test_delay_event,
|
||||
swap_clients[0],
|
||||
bid_id,
|
||||
BidStates.SWAP_COMPLETED,
|
||||
wait_for=180,
|
||||
)
|
||||
wait_for_bid(
|
||||
test_delay_event,
|
||||
swap_clients[1],
|
||||
bid_id,
|
||||
BidStates.SWAP_COMPLETED,
|
||||
sent=True,
|
||||
)
|
||||
|
||||
amount_from = float(format_amount(amt_swap, 8))
|
||||
js_1 = read_json_api(1801, 'wallets/part')
|
||||
node1_blind_after = js_1['blind_balance'] + js_1['blind_unconfirmed']
|
||||
assert (node1_blind_after > node1_blind_before + (amount_from - 0.05))
|
||||
js_1 = read_json_api(1801, "wallets/part")
|
||||
node1_blind_after = js_1["blind_balance"] + js_1["blind_unconfirmed"]
|
||||
assert node1_blind_after > node1_blind_before + (amount_from - 0.05)
|
||||
|
||||
js_0 = read_json_api(1800, 'wallets/part')
|
||||
node0_blind_after = js_0['blind_balance'] + js_0['blind_unconfirmed']
|
||||
assert (node0_blind_after < node0_blind_before - amount_from)
|
||||
js_0 = read_json_api(1800, "wallets/part")
|
||||
node0_blind_after = js_0["blind_balance"] + js_0["blind_unconfirmed"]
|
||||
assert node0_blind_after < node0_blind_before - amount_from
|
||||
|
||||
js_0_xmr_after = read_json_api(1800, 'wallets/xmr')
|
||||
js_1_xmr_after = read_json_api(1801, 'wallets/xmr')
|
||||
js_1_xmr_after = read_json_api(1801, "wallets/xmr")
|
||||
|
||||
scale_from = 8
|
||||
amount_to = int((amt_swap * rate_swap) // (10 ** scale_from))
|
||||
amount_to = int((amt_swap * rate_swap) // (10**scale_from))
|
||||
amount_to_float = float(format_amount(amount_to, 12))
|
||||
node1_xmr_after = float(js_1_xmr_after['unconfirmed']) + float(js_1_xmr_after['balance'])
|
||||
node1_xmr_before = float(js_1_xmr['unconfirmed']) + float(js_1_xmr['balance'])
|
||||
assert (node1_xmr_after > node1_xmr_before + (amount_to_float - 0.02))
|
||||
node1_xmr_after = float(js_1_xmr_after["unconfirmed"]) + float(
|
||||
js_1_xmr_after["balance"]
|
||||
)
|
||||
node1_xmr_before = float(js_1_xmr["unconfirmed"]) + float(js_1_xmr["balance"])
|
||||
assert node1_xmr_after > node1_xmr_before + (amount_to_float - 0.02)
|
||||
|
||||
def test_02_leader_recover_a_lock_tx(self):
|
||||
logging.info('---------- Test PARTct to XMR leader recovers coin a lock tx')
|
||||
logging.info("---------- Test PARTct to XMR leader recovers coin a lock tx")
|
||||
swap_clients = self.swap_clients
|
||||
|
||||
js_w0_before = read_json_api(1800, 'wallets')
|
||||
js_w0_before = read_json_api(1800, "wallets")
|
||||
node0_blind_before = self.getBalance(js_w0_before)
|
||||
|
||||
amt_swap = make_int(random.uniform(0.1, 2.0), scale=8, r=1)
|
||||
rate_swap = make_int(random.uniform(0.2, 20.0), scale=12, r=1)
|
||||
offer_id = swap_clients[0].postOffer(
|
||||
Coins.PART_BLIND, Coins.XMR, amt_swap, rate_swap, amt_swap, SwapTypes.XMR_SWAP,
|
||||
lock_type=TxLockTypes.SEQUENCE_LOCK_BLOCKS, lock_value=12)
|
||||
Coins.PART_BLIND,
|
||||
Coins.XMR,
|
||||
amt_swap,
|
||||
rate_swap,
|
||||
amt_swap,
|
||||
SwapTypes.XMR_SWAP,
|
||||
lock_type=TxLockTypes.SEQUENCE_LOCK_BLOCKS,
|
||||
lock_value=12,
|
||||
)
|
||||
wait_for_offer(test_delay_event, swap_clients[1], offer_id)
|
||||
offer = swap_clients[1].getOffer(offer_id)
|
||||
|
||||
|
@ -273,31 +333,49 @@ class Test(BaseTest):
|
|||
wait_for_bid(test_delay_event, swap_clients[0], bid_id, BidStates.BID_RECEIVED)
|
||||
|
||||
bid, xmr_swap = swap_clients[0].getXmrBid(bid_id)
|
||||
assert (xmr_swap)
|
||||
assert xmr_swap
|
||||
|
||||
swap_clients[1].setBidDebugInd(bid_id, DebugTypes.BID_STOP_AFTER_COIN_A_LOCK)
|
||||
|
||||
swap_clients[0].acceptXmrBid(bid_id)
|
||||
|
||||
wait_for_bid(test_delay_event, swap_clients[0], bid_id, BidStates.XMR_SWAP_FAILED_REFUNDED, wait_for=180)
|
||||
wait_for_bid(test_delay_event, swap_clients[1], bid_id, [BidStates.BID_STALLED_FOR_TEST, BidStates.XMR_SWAP_FAILED], sent=True)
|
||||
wait_for_bid(
|
||||
test_delay_event,
|
||||
swap_clients[0],
|
||||
bid_id,
|
||||
BidStates.XMR_SWAP_FAILED_REFUNDED,
|
||||
wait_for=180,
|
||||
)
|
||||
wait_for_bid(
|
||||
test_delay_event,
|
||||
swap_clients[1],
|
||||
bid_id,
|
||||
[BidStates.BID_STALLED_FOR_TEST, BidStates.XMR_SWAP_FAILED],
|
||||
sent=True,
|
||||
)
|
||||
|
||||
js_w0_after = read_json_api(1800, 'wallets')
|
||||
js_w0_after = read_json_api(1800, "wallets")
|
||||
node0_blind_after = self.getBalance(js_w0_after)
|
||||
assert (node0_blind_before - node0_blind_after < 0.02)
|
||||
assert node0_blind_before - node0_blind_after < 0.02
|
||||
|
||||
def test_03_follower_recover_a_lock_tx(self):
|
||||
logging.info('---------- Test PARTct to XMR follower recovers coin a lock tx')
|
||||
logging.info("---------- Test PARTct to XMR follower recovers coin a lock tx")
|
||||
swap_clients = self.swap_clients
|
||||
|
||||
js_w0_before = read_json_api(1800, 'wallets')
|
||||
js_w1_before = read_json_api(1801, 'wallets')
|
||||
js_w1_before = read_json_api(1801, "wallets")
|
||||
|
||||
amt_swap = make_int(random.uniform(0.1, 2.0), scale=8, r=1)
|
||||
rate_swap = make_int(random.uniform(0.2, 20.0), scale=12, r=1)
|
||||
offer_id = swap_clients[0].postOffer(
|
||||
Coins.PART_BLIND, Coins.XMR, amt_swap, rate_swap, amt_swap, SwapTypes.XMR_SWAP,
|
||||
lock_type=TxLockTypes.SEQUENCE_LOCK_BLOCKS, lock_value=32)
|
||||
Coins.PART_BLIND,
|
||||
Coins.XMR,
|
||||
amt_swap,
|
||||
rate_swap,
|
||||
amt_swap,
|
||||
SwapTypes.XMR_SWAP,
|
||||
lock_type=TxLockTypes.SEQUENCE_LOCK_BLOCKS,
|
||||
lock_value=32,
|
||||
)
|
||||
wait_for_offer(test_delay_event, swap_clients[1], offer_id)
|
||||
offer = swap_clients[1].getOffer(offer_id)
|
||||
|
||||
|
@ -306,22 +384,37 @@ class Test(BaseTest):
|
|||
wait_for_bid(test_delay_event, swap_clients[0], bid_id, BidStates.BID_RECEIVED)
|
||||
|
||||
bid, xmr_swap = swap_clients[0].getXmrBid(bid_id)
|
||||
assert (xmr_swap)
|
||||
assert xmr_swap
|
||||
|
||||
swap_clients[1].setBidDebugInd(bid_id, DebugTypes.CREATE_INVALID_COIN_B_LOCK)
|
||||
swap_clients[0].setBidDebugInd(bid_id, DebugTypes.BID_DONT_SPEND_COIN_A_LOCK_REFUND)
|
||||
swap_clients[0].setBidDebugInd(
|
||||
bid_id, DebugTypes.BID_DONT_SPEND_COIN_A_LOCK_REFUND
|
||||
)
|
||||
|
||||
swap_clients[0].acceptXmrBid(bid_id)
|
||||
|
||||
wait_for_bid(test_delay_event, swap_clients[0], bid_id, BidStates.BID_STALLED_FOR_TEST, wait_for=180)
|
||||
wait_for_bid(test_delay_event, swap_clients[1], bid_id, BidStates.XMR_SWAP_FAILED_SWIPED, wait_for=80, sent=True)
|
||||
wait_for_bid(
|
||||
test_delay_event,
|
||||
swap_clients[0],
|
||||
bid_id,
|
||||
BidStates.BID_STALLED_FOR_TEST,
|
||||
wait_for=180,
|
||||
)
|
||||
wait_for_bid(
|
||||
test_delay_event,
|
||||
swap_clients[1],
|
||||
bid_id,
|
||||
BidStates.XMR_SWAP_FAILED_SWIPED,
|
||||
wait_for=80,
|
||||
sent=True,
|
||||
)
|
||||
|
||||
js_w1_after = read_json_api(1801, 'wallets')
|
||||
js_w1_after = read_json_api(1801, "wallets")
|
||||
|
||||
node1_blind_before = self.getBalance(js_w1_before)
|
||||
node1_blind_after = self.getBalance(js_w1_after)
|
||||
amount_from = float(format_amount(amt_swap, 8))
|
||||
assert (node1_blind_after - node1_blind_before > (amount_from - 0.02))
|
||||
assert node1_blind_after - node1_blind_before > (amount_from - 0.02)
|
||||
|
||||
swap_clients[0].abandonBid(bid_id)
|
||||
swap_clients[1].abandonBid(bid_id)
|
||||
|
@ -329,20 +422,29 @@ class Test(BaseTest):
|
|||
wait_for_none_active(test_delay_event, 1800)
|
||||
wait_for_none_active(test_delay_event, 1801)
|
||||
|
||||
data = parse.urlencode({
|
||||
'chainbkeysplit': True
|
||||
}).encode()
|
||||
offerer_key = json.loads(urlopen('http://127.0.0.1:1800/json/bids/{}'.format(bid_id.hex()), data=data).read())['splitkey']
|
||||
data = parse.urlencode({"chainbkeysplit": True}).encode()
|
||||
offerer_key = json.loads(
|
||||
urlopen(
|
||||
"http://127.0.0.1:1800/json/bids/{}".format(bid_id.hex()), data=data
|
||||
).read()
|
||||
)["splitkey"]
|
||||
|
||||
data = parse.urlencode({
|
||||
'spendchainblocktx': True,
|
||||
'remote_key': offerer_key
|
||||
}).encode()
|
||||
redeemed_txid = json.loads(urlopen('http://127.0.0.1:1801/json/bids/{}'.format(bid_id.hex()), data=data).read())['txid']
|
||||
assert (len(redeemed_txid) == 64)
|
||||
data = parse.urlencode(
|
||||
{"spendchainblocktx": True, "remote_key": offerer_key}
|
||||
).encode()
|
||||
redeemed_txid = json.loads(
|
||||
urlopen(
|
||||
"http://127.0.0.1:1801/json/bids/{}".format(bid_id.hex()), data=data
|
||||
).read()
|
||||
)["txid"]
|
||||
assert len(redeemed_txid) == 64
|
||||
|
||||
def do_test_04_follower_recover_b_lock_tx(self, coin_from, coin_to):
|
||||
logging.info('---------- Test {} to {} follower recovers coin b lock tx'.format(coin_from.name, coin_to.name))
|
||||
logging.info(
|
||||
"---------- Test {} to {} follower recovers coin b lock tx".format(
|
||||
coin_from.name, coin_to.name
|
||||
)
|
||||
)
|
||||
|
||||
swap_clients = self.swap_clients
|
||||
ci_from = swap_clients[0].ci(coin_from)
|
||||
|
@ -351,8 +453,15 @@ class Test(BaseTest):
|
|||
amt_swap = ci_from.make_int(random.uniform(0.1, 2.0), r=1)
|
||||
rate_swap = ci_to.make_int(random.uniform(0.2, 20.0), r=1)
|
||||
offer_id = swap_clients[0].postOffer(
|
||||
coin_from, coin_to, amt_swap, rate_swap, amt_swap, SwapTypes.XMR_SWAP,
|
||||
lock_type=TxLockTypes.SEQUENCE_LOCK_BLOCKS, lock_value=28)
|
||||
coin_from,
|
||||
coin_to,
|
||||
amt_swap,
|
||||
rate_swap,
|
||||
amt_swap,
|
||||
SwapTypes.XMR_SWAP,
|
||||
lock_type=TxLockTypes.SEQUENCE_LOCK_BLOCKS,
|
||||
lock_value=28,
|
||||
)
|
||||
wait_for_offer(test_delay_event, swap_clients[1], offer_id)
|
||||
offer = swap_clients[1].getOffer(offer_id)
|
||||
|
||||
|
@ -361,36 +470,50 @@ class Test(BaseTest):
|
|||
wait_for_bid(test_delay_event, swap_clients[0], bid_id, BidStates.BID_RECEIVED)
|
||||
|
||||
bid, xmr_swap = swap_clients[0].getXmrBid(bid_id)
|
||||
assert (xmr_swap)
|
||||
assert xmr_swap
|
||||
|
||||
swap_clients[1].setBidDebugInd(bid_id, DebugTypes.CREATE_INVALID_COIN_B_LOCK)
|
||||
|
||||
swap_clients[0].acceptXmrBid(bid_id)
|
||||
|
||||
wait_for_bid(test_delay_event, swap_clients[0], bid_id, BidStates.XMR_SWAP_FAILED_REFUNDED, wait_for=180)
|
||||
wait_for_bid(test_delay_event, swap_clients[1], bid_id, BidStates.XMR_SWAP_FAILED_REFUNDED, sent=True)
|
||||
wait_for_bid(
|
||||
test_delay_event,
|
||||
swap_clients[0],
|
||||
bid_id,
|
||||
BidStates.XMR_SWAP_FAILED_REFUNDED,
|
||||
wait_for=180,
|
||||
)
|
||||
wait_for_bid(
|
||||
test_delay_event,
|
||||
swap_clients[1],
|
||||
bid_id,
|
||||
BidStates.XMR_SWAP_FAILED_REFUNDED,
|
||||
sent=True,
|
||||
)
|
||||
|
||||
def test_04_follower_recover_b_lock_tx(self):
|
||||
js_w0_before = read_json_api(1800, 'wallets')
|
||||
js_w1_before = read_json_api(1801, 'wallets')
|
||||
js_w0_before = read_json_api(1800, "wallets")
|
||||
js_w1_before = read_json_api(1801, "wallets")
|
||||
|
||||
self.do_test_04_follower_recover_b_lock_tx(self.test_coin_from, Coins.XMR)
|
||||
js_w0_after = read_json_api(1800, 'wallets')
|
||||
js_w1_after = read_json_api(1801, 'wallets')
|
||||
js_w0_after = read_json_api(1800, "wallets")
|
||||
js_w1_after = read_json_api(1801, "wallets")
|
||||
node0_blind_before = self.getBalance(js_w0_before)
|
||||
node0_blind_after = self.getBalance(js_w0_after)
|
||||
assert (node0_blind_before - node0_blind_after < 0.02)
|
||||
assert node0_blind_before - node0_blind_after < 0.02
|
||||
|
||||
node1_xmr_before = self.getXmrBalance(js_w1_before)
|
||||
node1_xmr_after = self.getXmrBalance(js_w1_after)
|
||||
assert (node1_xmr_before - node1_xmr_after < 0.02)
|
||||
assert node1_xmr_before - node1_xmr_after < 0.02
|
||||
|
||||
def test_04_follower_recover_b_lock_tx_from_part(self):
|
||||
self.ensure_balance(self.test_coin_from, 1, 50.0)
|
||||
self.do_test_04_follower_recover_b_lock_tx(Coins.PART, self.test_coin_from)
|
||||
|
||||
def do_test_05_self_bid(self, coin_from, coin_to):
|
||||
logging.info('---------- Test {} to {} same client'.format(coin_from.name, coin_to.name))
|
||||
logging.info(
|
||||
"---------- Test {} to {} same client".format(coin_from.name, coin_to.name)
|
||||
)
|
||||
|
||||
swap_clients = self.swap_clients
|
||||
ci_to = swap_clients[0].ci(coin_to)
|
||||
|
@ -400,10 +523,24 @@ class Test(BaseTest):
|
|||
amt_swap = make_int(random.uniform(0.1, 2.0), scale=8, r=1)
|
||||
rate_swap = ci_to.make_int(random.uniform(0.2, 20.0), r=1)
|
||||
|
||||
offer_id = swap_clients[1].postOffer(coin_from, coin_to, amt_swap, rate_swap, amt_swap, SwapTypes.XMR_SWAP, auto_accept_bids=True)
|
||||
offer_id = swap_clients[1].postOffer(
|
||||
coin_from,
|
||||
coin_to,
|
||||
amt_swap,
|
||||
rate_swap,
|
||||
amt_swap,
|
||||
SwapTypes.XMR_SWAP,
|
||||
auto_accept_bids=True,
|
||||
)
|
||||
bid_id = swap_clients[1].postXmrBid(offer_id, amt_swap)
|
||||
|
||||
wait_for_bid(test_delay_event, swap_clients[1], bid_id, BidStates.SWAP_COMPLETED, wait_for=180)
|
||||
wait_for_bid(
|
||||
test_delay_event,
|
||||
swap_clients[1],
|
||||
bid_id,
|
||||
BidStates.SWAP_COMPLETED,
|
||||
wait_for=180,
|
||||
)
|
||||
|
||||
def test_05_self_bid(self):
|
||||
if not self.has_segwit:
|
||||
|
@ -419,45 +556,58 @@ class Test(BaseTest):
|
|||
self.do_test_05_self_bid(Coins.PART, self.test_coin_from)
|
||||
|
||||
def test_06_preselect_inputs(self):
|
||||
raise ValueError('TODO')
|
||||
raise ValueError("TODO")
|
||||
tla_from = self.test_coin_from.name
|
||||
logging.info('---------- Test {} Preselected inputs'.format(tla_from))
|
||||
logging.info("---------- Test {} Preselected inputs".format(tla_from))
|
||||
swap_clients = self.swap_clients
|
||||
|
||||
# Prepare balance
|
||||
self.ensure_balance(self.test_coin_from, 2, 100.0)
|
||||
|
||||
js_w2 = read_json_api(1802, 'wallets')
|
||||
js_w2 = read_json_api(1802, "wallets")
|
||||
post_json = {
|
||||
'value': float(js_w2['PART']['blind_balance']),
|
||||
'type_from': 'blind',
|
||||
'type_to': 'blind',
|
||||
'address': js_w2['PART']['stealth_address'],
|
||||
'subfee': True,
|
||||
"value": float(js_w2["PART"]["blind_balance"]),
|
||||
"type_from": "blind",
|
||||
"type_to": "blind",
|
||||
"address": js_w2["PART"]["stealth_address"],
|
||||
"subfee": True,
|
||||
}
|
||||
json_rv = read_json_api(1802, 'wallets/{}/withdraw'.format('part'), post_json)
|
||||
wait_for_balance(test_delay_event, 'http://127.0.0.1:1802/json/wallets/{}'.format('part'), 'blind_balance', 10.0)
|
||||
assert (len(json_rv['txid']) == 64)
|
||||
json_rv = read_json_api(1802, "wallets/{}/withdraw".format("part"), post_json)
|
||||
wait_for_balance(
|
||||
test_delay_event,
|
||||
"http://127.0.0.1:1802/json/wallets/{}".format("part"),
|
||||
"blind_balance",
|
||||
10.0,
|
||||
)
|
||||
assert len(json_rv["txid"]) == 64
|
||||
|
||||
# Create prefunded ITX
|
||||
ci = swap_clients[2].ci(self.test_coin_from)
|
||||
ci_to = swap_clients[2].ci(Coins.XMR)
|
||||
pi = swap_clients[2].pi(SwapTypes.XMR_SWAP)
|
||||
js_w2 = read_json_api(1802, 'wallets')
|
||||
swap_value = ci.make_int(js_w2['PART']['blind_balance'])
|
||||
assert (swap_value > ci.make_int(95))
|
||||
js_w2 = read_json_api(1802, "wallets")
|
||||
swap_value = ci.make_int(js_w2["PART"]["blind_balance"])
|
||||
assert swap_value > ci.make_int(95)
|
||||
|
||||
itx = pi.getFundedInitiateTxTemplate(ci, swap_value, True)
|
||||
itx_decoded = ci.describeTx(itx.hex())
|
||||
n = pi.findMockVout(ci, itx_decoded)
|
||||
value_after_subfee = ci.make_int(itx_decoded['vout'][n]['value'])
|
||||
assert (value_after_subfee < swap_value)
|
||||
value_after_subfee = ci.make_int(itx_decoded["vout"][n]["value"])
|
||||
assert value_after_subfee < swap_value
|
||||
swap_value = value_after_subfee
|
||||
wait_for_unspent(test_delay_event, ci, swap_value)
|
||||
|
||||
extra_options = {'prefunded_itx': itx}
|
||||
extra_options = {"prefunded_itx": itx}
|
||||
rate_swap = ci_to.make_int(random.uniform(0.2, 20.0))
|
||||
offer_id = swap_clients[2].postOffer(self.test_coin_from, Coins.XMR, swap_value, rate_swap, swap_value, SwapTypes.XMR_SWAP, extra_options=extra_options)
|
||||
offer_id = swap_clients[2].postOffer(
|
||||
self.test_coin_from,
|
||||
Coins.XMR,
|
||||
swap_value,
|
||||
rate_swap,
|
||||
swap_value,
|
||||
SwapTypes.XMR_SWAP,
|
||||
extra_options=extra_options,
|
||||
)
|
||||
|
||||
wait_for_offer(test_delay_event, swap_clients[1], offer_id)
|
||||
offer = swap_clients[1].getOffer(offer_id)
|
||||
|
@ -466,20 +616,38 @@ class Test(BaseTest):
|
|||
wait_for_bid(test_delay_event, swap_clients[2], bid_id, BidStates.BID_RECEIVED)
|
||||
swap_clients[2].acceptBid(bid_id)
|
||||
|
||||
wait_for_bid(test_delay_event, swap_clients[2], bid_id, BidStates.SWAP_COMPLETED, wait_for=120)
|
||||
wait_for_bid(test_delay_event, swap_clients[1], bid_id, BidStates.SWAP_COMPLETED, sent=True, wait_for=120)
|
||||
wait_for_bid(
|
||||
test_delay_event,
|
||||
swap_clients[2],
|
||||
bid_id,
|
||||
BidStates.SWAP_COMPLETED,
|
||||
wait_for=120,
|
||||
)
|
||||
wait_for_bid(
|
||||
test_delay_event,
|
||||
swap_clients[1],
|
||||
bid_id,
|
||||
BidStates.SWAP_COMPLETED,
|
||||
sent=True,
|
||||
wait_for=120,
|
||||
)
|
||||
|
||||
# Verify expected inputs were used
|
||||
bid, _, _, _, _ = swap_clients[2].getXmrBidAndOffer(bid_id)
|
||||
assert (bid.xmr_a_lock_tx)
|
||||
wtx = ci.rpc_wallet('gettransaction', [bid.xmr_a_lock_tx.txid.hex(),])
|
||||
itx_after = ci.describeTx(wtx['hex'])
|
||||
assert (len(itx_after['vin']) == len(itx_decoded['vin']))
|
||||
for i, txin in enumerate(itx_decoded['vin']):
|
||||
txin_after = itx_after['vin'][i]
|
||||
assert (txin['txid'] == txin_after['txid'])
|
||||
assert (txin['vout'] == txin_after['vout'])
|
||||
assert bid.xmr_a_lock_tx
|
||||
wtx = ci.rpc_wallet(
|
||||
"gettransaction",
|
||||
[
|
||||
bid.xmr_a_lock_tx.txid.hex(),
|
||||
],
|
||||
)
|
||||
itx_after = ci.describeTx(wtx["hex"])
|
||||
assert len(itx_after["vin"]) == len(itx_decoded["vin"])
|
||||
for i, txin in enumerate(itx_decoded["vin"]):
|
||||
txin_after = itx_after["vin"][i]
|
||||
assert txin["txid"] == txin_after["txid"]
|
||||
assert txin["vout"] == txin_after["vout"]
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright (c) 2019-2023 tecnovert
|
||||
# Copyright (c) 2024 The Basicswap developers
|
||||
# Distributed under the MIT software license, see the accompanying
|
||||
# file LICENSE or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
|
@ -41,7 +42,7 @@ from tests.basicswap.common_xmr import (
|
|||
)
|
||||
import basicswap.bin.run as runSystem
|
||||
|
||||
TEST_PATH = os.path.expanduser(os.getenv('TEST_PATH', '~/test_basicswap1'))
|
||||
TEST_PATH = os.path.expanduser(os.getenv("TEST_PATH", "~/test_basicswap1"))
|
||||
delay_event = threading.Event()
|
||||
|
||||
logger = logging.getLogger()
|
||||
|
@ -51,22 +52,22 @@ if not len(logger.handlers):
|
|||
|
||||
|
||||
def btcRpc(client_no, cmd):
|
||||
bin_path = os.path.join(TEST_PATH, 'bin', 'bitcoin')
|
||||
data_path = os.path.join(TEST_PATH, 'client{}'.format(client_no), 'bitcoin')
|
||||
return callrpc_cli(bin_path, data_path, 'regtest', cmd, 'bitcoin-cli')
|
||||
bin_path = os.path.join(TEST_PATH, "bin", "bitcoin")
|
||||
data_path = os.path.join(TEST_PATH, "client{}".format(client_no), "bitcoin")
|
||||
return callrpc_cli(bin_path, data_path, "regtest", cmd, "bitcoin-cli")
|
||||
|
||||
|
||||
def partRpc(client_no, cmd):
|
||||
bin_path = os.path.join(TEST_PATH, 'bin', 'particl')
|
||||
data_path = os.path.join(TEST_PATH, 'client{}'.format(client_no), 'particl')
|
||||
return callrpc_cli(bin_path, data_path, 'regtest', cmd, 'particl-cli')
|
||||
bin_path = os.path.join(TEST_PATH, "bin", "particl")
|
||||
data_path = os.path.join(TEST_PATH, "client{}".format(client_no), "particl")
|
||||
return callrpc_cli(bin_path, data_path, "regtest", cmd, "particl-cli")
|
||||
|
||||
|
||||
def updateThread():
|
||||
btc_addr = btcRpc(0, 'getnewaddress mining_addr bech32')
|
||||
btc_addr = btcRpc(0, "getnewaddress mining_addr bech32")
|
||||
|
||||
while not delay_event.is_set():
|
||||
btcRpc(0, 'generatetoaddress {} {}'.format(1, btc_addr))
|
||||
btcRpc(0, "generatetoaddress {} {}".format(1, btc_addr))
|
||||
delay_event.wait(5)
|
||||
|
||||
|
||||
|
@ -75,30 +76,34 @@ class Test(unittest.TestCase):
|
|||
def setUpClass(cls):
|
||||
super(Test, cls).setUpClass()
|
||||
|
||||
prepare_nodes(3, 'bitcoin')
|
||||
prepare_nodes(3, "bitcoin")
|
||||
|
||||
def run_thread(self, client_id):
|
||||
client_path = os.path.join(TEST_PATH, 'client{}'.format(client_id))
|
||||
testargs = ['basicswap-run', '-datadir=' + client_path, '-regtest']
|
||||
with patch.object(sys, 'argv', testargs):
|
||||
client_path = os.path.join(TEST_PATH, "client{}".format(client_id))
|
||||
testargs = ["basicswap-run", "-datadir=" + client_path, "-regtest"]
|
||||
with patch.object(sys, "argv", testargs):
|
||||
runSystem.main()
|
||||
|
||||
def wait_for_node_height(self, port=12701, wallet_ticker='part', wait_for_blocks=3):
|
||||
def wait_for_node_height(self, port=12701, wallet_ticker="part", wait_for_blocks=3):
|
||||
# Wait for height, or sequencelock is thrown off by genesis blocktime
|
||||
logging.info(f'Waiting for {wallet_ticker} chain height {wait_for_blocks} at port {port}', )
|
||||
logging.info(
|
||||
f"Waiting for {wallet_ticker} chain height {wait_for_blocks} at port {port}",
|
||||
)
|
||||
for i in range(60):
|
||||
if delay_event.is_set():
|
||||
raise ValueError('Test stopped.')
|
||||
raise ValueError("Test stopped.")
|
||||
try:
|
||||
wallet = read_json_api(port, f'wallets/{wallet_ticker}')
|
||||
node_blocks = wallet['blocks']
|
||||
print(f'{wallet_ticker} node_blocks {node_blocks}')
|
||||
wallet = read_json_api(port, f"wallets/{wallet_ticker}")
|
||||
node_blocks = wallet["blocks"]
|
||||
print(f"{wallet_ticker} node_blocks {node_blocks}")
|
||||
if node_blocks >= wait_for_blocks:
|
||||
return
|
||||
except Exception as e:
|
||||
print('Error reading wallets', str(e))
|
||||
print("Error reading wallets", str(e))
|
||||
delay_event.wait(1)
|
||||
raise ValueError(f'wait_for_node_height timed out, {wallet_ticker}, {wait_for_blocks}, {port}')
|
||||
raise ValueError(
|
||||
f"wait_for_node_height timed out, {wallet_ticker}, {wait_for_blocks}, {port}"
|
||||
)
|
||||
|
||||
def test_reload(self):
|
||||
global stop_test
|
||||
|
@ -110,58 +115,55 @@ class Test(unittest.TestCase):
|
|||
|
||||
try:
|
||||
waitForServer(delay_event, 12700)
|
||||
partRpc(0, 'reservebalance false') # WakeThreadStakeMiner
|
||||
partRpc(0, "reservebalance false") # WakeThreadStakeMiner
|
||||
self.wait_for_node_height()
|
||||
|
||||
num_blocks = 500
|
||||
btc_addr = btcRpc(1, 'getnewaddress mining_addr bech32')
|
||||
logging.info('Mining %d Bitcoin blocks to %s', num_blocks, btc_addr)
|
||||
btcRpc(1, 'generatetoaddress {} {}'.format(num_blocks, btc_addr))
|
||||
self.wait_for_node_height(12700, 'btc', num_blocks)
|
||||
btc_addr = btcRpc(1, "getnewaddress mining_addr bech32")
|
||||
logging.info("Mining %d Bitcoin blocks to %s", num_blocks, btc_addr)
|
||||
btcRpc(1, "generatetoaddress {} {}".format(num_blocks, btc_addr))
|
||||
self.wait_for_node_height(12700, "btc", num_blocks)
|
||||
|
||||
data = {
|
||||
'addr_from': '-1',
|
||||
'coin_from': 'PART',
|
||||
'coin_to': '2',
|
||||
'amt_from': '1',
|
||||
'amt_to': '1',
|
||||
'lockhrs': '24'}
|
||||
"addr_from": "-1",
|
||||
"coin_from": "PART",
|
||||
"coin_to": "2",
|
||||
"amt_from": "1",
|
||||
"amt_to": "1",
|
||||
"lockhrs": "24",
|
||||
}
|
||||
|
||||
offer_id = post_json_api(12700, 'offers/new', data)['offer_id']
|
||||
offer_id = post_json_api(12700, "offers/new", data)["offer_id"]
|
||||
summary = read_json_api(12700)
|
||||
assert (summary['num_sent_offers'] == 1)
|
||||
assert summary["num_sent_offers"] == 1
|
||||
except Exception:
|
||||
traceback.print_exc()
|
||||
|
||||
sentoffers = read_json_api(12700, 'sentoffers', {'active': True})
|
||||
assert sentoffers[0]['offer_id'] == offer_id
|
||||
sentoffers = read_json_api(12700, "sentoffers", {"active": True})
|
||||
assert sentoffers[0]["offer_id"] == offer_id
|
||||
|
||||
logger.info('Waiting for offer:')
|
||||
logger.info("Waiting for offer:")
|
||||
waitForNumOffers(delay_event, 12701, 1)
|
||||
|
||||
offers = read_json_api(12701, 'offers')
|
||||
offers = read_json_api(12701, "offers")
|
||||
offer = offers[0]
|
||||
|
||||
data = {
|
||||
'offer_id': offer['offer_id'],
|
||||
'amount_from': offer['amount_from']}
|
||||
data = {"offer_id": offer["offer_id"], "amount_from": offer["amount_from"]}
|
||||
|
||||
bid_id = post_json_api(12701, 'bids/new', data)
|
||||
post_json_api(12701, "bids/new", data)
|
||||
|
||||
waitForNumBids(delay_event, 12700, 1)
|
||||
|
||||
bids = read_json_api(12700, 'bids')
|
||||
bids = read_json_api(12700, "bids")
|
||||
bid = bids[0]
|
||||
|
||||
data = {
|
||||
'accept': True
|
||||
}
|
||||
rv = post_json_api(12700, 'bids/{}'.format(bid['bid_id']), data)
|
||||
assert (rv['bid_state'] == 'Accepted')
|
||||
data = {"accept": True}
|
||||
rv = post_json_api(12700, "bids/{}".format(bid["bid_id"]), data)
|
||||
assert rv["bid_state"] == "Accepted"
|
||||
|
||||
waitForNumSwapping(delay_event, 12701, 1)
|
||||
|
||||
logger.info('Restarting client:')
|
||||
logger.info("Restarting client:")
|
||||
c1 = processes[1]
|
||||
c1.terminate()
|
||||
c1.join()
|
||||
|
@ -170,19 +172,19 @@ class Test(unittest.TestCase):
|
|||
|
||||
waitForServer(delay_event, 12701)
|
||||
rv = read_json_api(12701)
|
||||
assert (rv['num_swapping'] == 1)
|
||||
assert rv["num_swapping"] == 1
|
||||
|
||||
update_thread = threading.Thread(target=updateThread)
|
||||
update_thread.start()
|
||||
|
||||
logger.info('Completing swap:')
|
||||
logger.info("Completing swap:")
|
||||
for i in range(240):
|
||||
delay_event.wait(5)
|
||||
|
||||
rv = read_json_api(12700, 'bids/{}'.format(bid['bid_id']))
|
||||
if rv['bid_state'] == 'Completed':
|
||||
rv = read_json_api(12700, "bids/{}".format(bid["bid_id"]))
|
||||
if rv["bid_state"] == "Completed":
|
||||
break
|
||||
assert (rv['bid_state'] == 'Completed')
|
||||
assert rv["bid_state"] == "Completed"
|
||||
|
||||
delay_event.set()
|
||||
update_thread.join()
|
||||
|
@ -192,5 +194,5 @@ class Test(unittest.TestCase):
|
|||
p.join()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -2,6 +2,7 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright (c) 2021-2022 tecnovert
|
||||
# Copyright (c) 2024 The Basicswap developers
|
||||
# Distributed under the MIT software license, see the accompanying
|
||||
# file LICENSE or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
|
@ -51,105 +52,140 @@ class Test(XmrTestBase):
|
|||
|
||||
waitForServer(self.delay_event, 12700)
|
||||
waitForServer(self.delay_event, 12701)
|
||||
wallets1 = read_json_api(12701, 'wallets')
|
||||
assert (float(wallets1['XMR']['balance']) > 0.0)
|
||||
wallets1 = read_json_api(12701, "wallets")
|
||||
assert float(wallets1["XMR"]["balance"]) > 0.0
|
||||
|
||||
offer_data = {
|
||||
'addr_from': -1,
|
||||
'coin_from': 'PART',
|
||||
'coin_to': 'XMR',
|
||||
'amt_from': 1,
|
||||
'amt_to': 1,
|
||||
'lockhrs': 24,
|
||||
'automation_strat_id': 1}
|
||||
rv = json.loads(urlopen('http://127.0.0.1:12700/json/offers/new', data=parse.urlencode(offer_data).encode()).read())
|
||||
offer0_id = rv['offer_id']
|
||||
"addr_from": -1,
|
||||
"coin_from": "PART",
|
||||
"coin_to": "XMR",
|
||||
"amt_from": 1,
|
||||
"amt_to": 1,
|
||||
"lockhrs": 24,
|
||||
"automation_strat_id": 1,
|
||||
}
|
||||
rv = json.loads(
|
||||
urlopen(
|
||||
"http://127.0.0.1:12700/json/offers/new",
|
||||
data=parse.urlencode(offer_data).encode(),
|
||||
).read()
|
||||
)
|
||||
offer0_id = rv["offer_id"]
|
||||
|
||||
offer_data['amt_from'] = '2'
|
||||
rv = json.loads(urlopen('http://127.0.0.1:12700/json/offers/new', data=parse.urlencode(offer_data).encode()).read())
|
||||
offer1_id = rv['offer_id']
|
||||
offer_data["amt_from"] = "2"
|
||||
rv = json.loads(
|
||||
urlopen(
|
||||
"http://127.0.0.1:12700/json/offers/new",
|
||||
data=parse.urlencode(offer_data).encode(),
|
||||
).read()
|
||||
)
|
||||
offer1_id = rv["offer_id"]
|
||||
|
||||
summary = read_json_api(12700)
|
||||
assert (summary['num_sent_offers'] > 1)
|
||||
assert summary["num_sent_offers"] > 1
|
||||
|
||||
logger.info('Waiting for offer')
|
||||
logger.info("Waiting for offer")
|
||||
waitForNumOffers(self.delay_event, 12701, 2)
|
||||
|
||||
logger.info('Stopping node 0')
|
||||
logger.info("Stopping node 0")
|
||||
c0 = self.processes[0]
|
||||
c0.terminate()
|
||||
c0.join()
|
||||
|
||||
offers = json.loads(urlopen('http://127.0.0.1:12701/json/offers/{}'.format(offer0_id)).read())
|
||||
assert (len(offers) == 1)
|
||||
offers = json.loads(
|
||||
urlopen("http://127.0.0.1:12701/json/offers/{}".format(offer0_id)).read()
|
||||
)
|
||||
assert len(offers) == 1
|
||||
offer0 = offers[0]
|
||||
|
||||
post_data = {
|
||||
'coin_from': 'PART'
|
||||
}
|
||||
test_post_offers = json.loads(urlopen('http://127.0.0.1:12701/json/offers', data=parse.urlencode(post_data).encode()).read())
|
||||
assert (len(test_post_offers) == 2)
|
||||
post_data['coin_from'] = '2'
|
||||
test_post_offers = json.loads(urlopen('http://127.0.0.1:12701/json/offers', data=parse.urlencode(post_data).encode()).read())
|
||||
assert (len(test_post_offers) == 0)
|
||||
post_data = {"coin_from": "PART"}
|
||||
test_post_offers = json.loads(
|
||||
urlopen(
|
||||
"http://127.0.0.1:12701/json/offers",
|
||||
data=parse.urlencode(post_data).encode(),
|
||||
).read()
|
||||
)
|
||||
assert len(test_post_offers) == 2
|
||||
post_data["coin_from"] = "2"
|
||||
test_post_offers = json.loads(
|
||||
urlopen(
|
||||
"http://127.0.0.1:12701/json/offers",
|
||||
data=parse.urlencode(post_data).encode(),
|
||||
).read()
|
||||
)
|
||||
assert len(test_post_offers) == 0
|
||||
|
||||
bid_data = {
|
||||
'offer_id': offer0_id,
|
||||
'amount_from': offer0['amount_from']}
|
||||
bid_data = {"offer_id": offer0_id, "amount_from": offer0["amount_from"]}
|
||||
|
||||
bid0_id = json.loads(urlopen('http://127.0.0.1:12701/json/bids/new', data=parse.urlencode(bid_data).encode()).read())['bid_id']
|
||||
bid0_id = json.loads(
|
||||
urlopen(
|
||||
"http://127.0.0.1:12701/json/bids/new",
|
||||
data=parse.urlencode(bid_data).encode(),
|
||||
).read()
|
||||
)["bid_id"]
|
||||
|
||||
offers = json.loads(urlopen('http://127.0.0.1:12701/json/offers/{}'.format(offer1_id)).read())
|
||||
assert (len(offers) == 1)
|
||||
offers = json.loads(
|
||||
urlopen("http://127.0.0.1:12701/json/offers/{}".format(offer1_id)).read()
|
||||
)
|
||||
assert len(offers) == 1
|
||||
offer1 = offers[0]
|
||||
|
||||
bid_data = {
|
||||
'offer_id': offer1_id,
|
||||
'amount_from': offer1['amount_from']}
|
||||
bid_data = {"offer_id": offer1_id, "amount_from": offer1["amount_from"]}
|
||||
|
||||
bid1_id = json.loads(urlopen('http://127.0.0.1:12701/json/bids/new', data=parse.urlencode(bid_data).encode()).read())['bid_id']
|
||||
bid1_id = json.loads(
|
||||
urlopen(
|
||||
"http://127.0.0.1:12701/json/bids/new",
|
||||
data=parse.urlencode(bid_data).encode(),
|
||||
).read()
|
||||
)["bid_id"]
|
||||
|
||||
logger.info('Delaying for 5 seconds.')
|
||||
logger.info("Delaying for 5 seconds.")
|
||||
self.delay_event.wait(5)
|
||||
|
||||
logger.info('Starting node 0')
|
||||
logger.info("Starting node 0")
|
||||
self.processes[0] = multiprocessing.Process(target=self.run_thread, args=(0,))
|
||||
self.processes[0].start()
|
||||
|
||||
waitForServer(self.delay_event, 12700)
|
||||
waitForNumBids(self.delay_event, 12700, 2)
|
||||
|
||||
waitForBidState(self.delay_event, 12700, bid0_id, 'Received')
|
||||
waitForBidState(self.delay_event, 12700, bid1_id, 'Received')
|
||||
waitForBidState(self.delay_event, 12700, bid0_id, "Received")
|
||||
waitForBidState(self.delay_event, 12700, bid1_id, "Received")
|
||||
|
||||
# Manually accept on top of auto-accept for extra chaos
|
||||
data = parse.urlencode({
|
||||
'accept': True
|
||||
}).encode()
|
||||
data = parse.urlencode({"accept": True}).encode()
|
||||
try:
|
||||
rv = json.loads(urlopen('http://127.0.0.1:12700/json/bids/{}'.format(bid0_id), data=data).read())
|
||||
assert rv['bid_state'] == 'Accepted'
|
||||
rv = json.loads(
|
||||
urlopen(
|
||||
"http://127.0.0.1:12700/json/bids/{}".format(bid0_id), data=data
|
||||
).read()
|
||||
)
|
||||
assert rv["bid_state"] == "Accepted"
|
||||
except Exception as e:
|
||||
print('Accept bid failed', str(e), rv)
|
||||
print("Accept bid failed", str(e), rv)
|
||||
try:
|
||||
rv = json.loads(urlopen('http://127.0.0.1:12700/json/bids/{}'.format(bid1_id), data=data).read())
|
||||
assert (rv['bid_state'] == 'Accepted')
|
||||
rv = json.loads(
|
||||
urlopen(
|
||||
"http://127.0.0.1:12700/json/bids/{}".format(bid1_id), data=data
|
||||
).read()
|
||||
)
|
||||
assert rv["bid_state"] == "Accepted"
|
||||
except Exception as e:
|
||||
print('Accept bid failed', str(e), rv)
|
||||
print("Accept bid failed", str(e), rv)
|
||||
|
||||
logger.info('Completing swap')
|
||||
logger.info("Completing swap")
|
||||
for i in range(240):
|
||||
if self.delay_event.is_set():
|
||||
raise ValueError('Test stopped.')
|
||||
raise ValueError("Test stopped.")
|
||||
self.delay_event.wait(4)
|
||||
|
||||
rv0 = read_json_api(12700, 'bids/{}'.format(bid0_id))
|
||||
rv1 = read_json_api(12700, 'bids/{}'.format(bid1_id))
|
||||
if rv0['bid_state'] == 'Completed' and rv1['bid_state'] == 'Completed':
|
||||
rv0 = read_json_api(12700, "bids/{}".format(bid0_id))
|
||||
rv1 = read_json_api(12700, "bids/{}".format(bid1_id))
|
||||
if rv0["bid_state"] == "Completed" and rv1["bid_state"] == "Completed":
|
||||
break
|
||||
assert rv0['bid_state'] == 'Completed'
|
||||
assert rv1['bid_state'] == 'Completed'
|
||||
assert rv0["bid_state"] == "Completed"
|
||||
assert rv1["bid_state"] == "Completed"
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright (c) 2020-2022 tecnovert
|
||||
# Copyright (c) 2024 The Basicswap developers
|
||||
# Distributed under the MIT software license, see the accompanying
|
||||
# file LICENSE or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
|
@ -47,70 +48,67 @@ class Test(XmrTestBase):
|
|||
|
||||
waitForServer(self.delay_event, 12700)
|
||||
waitForServer(self.delay_event, 12701)
|
||||
wallets1 = read_json_api(12701, 'wallets')
|
||||
assert (float(wallets1['XMR']['balance']) > 0.0)
|
||||
wallets1 = read_json_api(12701, "wallets")
|
||||
assert float(wallets1["XMR"]["balance"]) > 0.0
|
||||
|
||||
data = {
|
||||
'addr_from': '-1',
|
||||
'coin_from': 'part',
|
||||
'coin_to': 'xmr',
|
||||
'amt_from': '1',
|
||||
'amt_to': '1',
|
||||
'lockhrs': '24'}
|
||||
"addr_from": "-1",
|
||||
"coin_from": "part",
|
||||
"coin_to": "xmr",
|
||||
"amt_from": "1",
|
||||
"amt_to": "1",
|
||||
"lockhrs": "24",
|
||||
}
|
||||
|
||||
offer_id = post_json_api(12700, 'offers/new', data)['offer_id']
|
||||
offer_id = post_json_api(12700, "offers/new", data)["offer_id"]
|
||||
summary = read_json_api(12700)
|
||||
assert (summary['num_sent_offers'] == 1)
|
||||
assert summary["num_sent_offers"] == 1
|
||||
|
||||
logger.info('Waiting for offer')
|
||||
logger.info("Waiting for offer")
|
||||
waitForNumOffers(self.delay_event, 12701, 1)
|
||||
|
||||
offers = read_json_api(12701, 'offers')
|
||||
offers = read_json_api(12701, "offers")
|
||||
offer = offers[0]
|
||||
|
||||
data = {
|
||||
'offer_id': offer['offer_id'],
|
||||
'amount_from': offer['amount_from']}
|
||||
data = {"offer_id": offer["offer_id"], "amount_from": offer["amount_from"]}
|
||||
|
||||
data['valid_for_seconds'] = 24 * 60 * 60 + 1
|
||||
bid = post_json_api(12701, 'bids/new', data)
|
||||
assert (bid['error'] == 'Bid TTL too high')
|
||||
del data['valid_for_seconds']
|
||||
data['validmins'] = 24 * 60 + 1
|
||||
bid = post_json_api(12701, 'bids/new', data)
|
||||
assert (bid['error'] == 'Bid TTL too high')
|
||||
data["valid_for_seconds"] = 24 * 60 * 60 + 1
|
||||
bid = post_json_api(12701, "bids/new", data)
|
||||
assert bid["error"] == "Bid TTL too high"
|
||||
del data["valid_for_seconds"]
|
||||
data["validmins"] = 24 * 60 + 1
|
||||
bid = post_json_api(12701, "bids/new", data)
|
||||
assert bid["error"] == "Bid TTL too high"
|
||||
|
||||
del data['validmins']
|
||||
data['valid_for_seconds'] = 10
|
||||
bid = post_json_api(12701, 'bids/new', data)
|
||||
assert (bid['error'] == 'Bid TTL too low')
|
||||
del data['valid_for_seconds']
|
||||
data['validmins'] = 1
|
||||
bid = post_json_api(12701, 'bids/new', data)
|
||||
assert (bid['error'] == 'Bid TTL too low')
|
||||
del data["validmins"]
|
||||
data["valid_for_seconds"] = 10
|
||||
bid = post_json_api(12701, "bids/new", data)
|
||||
assert bid["error"] == "Bid TTL too low"
|
||||
del data["valid_for_seconds"]
|
||||
data["validmins"] = 1
|
||||
bid = post_json_api(12701, "bids/new", data)
|
||||
assert bid["error"] == "Bid TTL too low"
|
||||
|
||||
data['validmins'] = 60
|
||||
bid_id = post_json_api(12701, 'bids/new', data)
|
||||
data["validmins"] = 60
|
||||
post_json_api(12701, "bids/new", data)
|
||||
|
||||
waitForNumBids(self.delay_event, 12700, 1)
|
||||
|
||||
for i in range(10):
|
||||
bids = read_json_api(12700, 'bids')
|
||||
bids = read_json_api(12700, "bids")
|
||||
bid = bids[0]
|
||||
if bid['bid_state'] == 'Received':
|
||||
if bid["bid_state"] == "Received":
|
||||
break
|
||||
self.delay_event.wait(1)
|
||||
assert (bid['expire_at'] == bid['created_at'] + data['validmins'] * 60)
|
||||
assert bid["expire_at"] == bid["created_at"] + data["validmins"] * 60
|
||||
|
||||
data = {
|
||||
'accept': True
|
||||
}
|
||||
rv = post_json_api(12700, 'bids/{}'.format(bid['bid_id']), data)
|
||||
assert (rv['bid_state'] == 'Accepted')
|
||||
data = {"accept": True}
|
||||
rv = post_json_api(12700, "bids/{}".format(bid["bid_id"]), data)
|
||||
assert rv["bid_state"] == "Accepted"
|
||||
|
||||
waitForNumSwapping(self.delay_event, 12701, 1)
|
||||
|
||||
logger.info('Restarting client')
|
||||
logger.info("Restarting client")
|
||||
c1 = self.processes[1]
|
||||
c1.terminate()
|
||||
c1.join()
|
||||
|
@ -119,29 +117,29 @@ class Test(XmrTestBase):
|
|||
|
||||
waitForServer(self.delay_event, 12701)
|
||||
rv = read_json_api(12701)
|
||||
assert (rv['num_swapping'] == 1)
|
||||
assert rv["num_swapping"] == 1
|
||||
|
||||
rv = read_json_api(12700, 'revokeoffer/{}'.format(offer_id))
|
||||
assert (rv['revoked_offer'] == offer_id)
|
||||
rv = read_json_api(12700, "revokeoffer/{}".format(offer_id))
|
||||
assert rv["revoked_offer"] == offer_id
|
||||
|
||||
logger.info('Completing swap')
|
||||
logger.info("Completing swap")
|
||||
for i in range(240):
|
||||
if self.delay_event.is_set():
|
||||
raise ValueError('Test stopped.')
|
||||
raise ValueError("Test stopped.")
|
||||
self.delay_event.wait(4)
|
||||
|
||||
rv = read_json_api(12700, 'bids/{}'.format(bid['bid_id']))
|
||||
if rv['bid_state'] == 'Completed':
|
||||
rv = read_json_api(12700, "bids/{}".format(bid["bid_id"]))
|
||||
if rv["bid_state"] == "Completed":
|
||||
break
|
||||
assert (rv['bid_state'] == 'Completed')
|
||||
assert rv["bid_state"] == "Completed"
|
||||
|
||||
# Ensure offer was revoked
|
||||
summary = read_json_api(12700)
|
||||
assert (summary['num_network_offers'] == 0)
|
||||
assert summary["num_network_offers"] == 0
|
||||
|
||||
# Wait for bid to be removed from in-progress
|
||||
waitForNumBids(self.delay_event, 12700, 0)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright (c) 2022-2024 tecnovert
|
||||
# Copyright (c) 2024 The Basicswap developers
|
||||
# Distributed under the MIT software license, see the accompanying
|
||||
# file LICENSE.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
|
@ -10,32 +11,37 @@ import urllib
|
|||
from urllib.request import urlopen
|
||||
|
||||
|
||||
REQUIRED_SETTINGS = {'blocks_confirmed': 1, 'conf_target': 1, 'use_segwit': True, 'connection_type': 'rpc'}
|
||||
REQUIRED_SETTINGS = {
|
||||
"blocks_confirmed": 1,
|
||||
"conf_target": 1,
|
||||
"use_segwit": True,
|
||||
"connection_type": "rpc",
|
||||
}
|
||||
|
||||
|
||||
def make_boolean(s):
|
||||
return s.lower() in ['1', 'true']
|
||||
return s.lower() in ["1", "true"]
|
||||
|
||||
|
||||
def post_json_req(url, json_data):
|
||||
req = urllib.request.Request(url)
|
||||
req.add_header('Content-Type', 'application/json; charset=utf-8')
|
||||
post_bytes = json.dumps(json_data).encode('utf-8')
|
||||
req.add_header('Content-Length', len(post_bytes))
|
||||
req.add_header("Content-Type", "application/json; charset=utf-8")
|
||||
post_bytes = json.dumps(json_data).encode("utf-8")
|
||||
req.add_header("Content-Length", len(post_bytes))
|
||||
return urlopen(req, post_bytes, timeout=300).read()
|
||||
|
||||
|
||||
def read_text_api(port, path=None):
|
||||
url = f'http://127.0.0.1:{port}/json'
|
||||
url = f"http://127.0.0.1:{port}/json"
|
||||
if path is not None:
|
||||
url += '/' + path
|
||||
return urlopen(url, timeout=300).read().decode('utf-8')
|
||||
url += "/" + path
|
||||
return urlopen(url, timeout=300).read().decode("utf-8")
|
||||
|
||||
|
||||
def read_json_api(port, path=None, json_data=None):
|
||||
url = f'http://127.0.0.1:{port}/json'
|
||||
url = f"http://127.0.0.1:{port}/json"
|
||||
if path is not None:
|
||||
url += '/' + path
|
||||
url += "/" + path
|
||||
|
||||
if json_data is not None:
|
||||
return json.loads(post_json_req(url, json_data))
|
||||
|
@ -43,20 +49,20 @@ def read_json_api(port, path=None, json_data=None):
|
|||
|
||||
|
||||
def post_json_api(port, path, json_data):
|
||||
url = f'http://127.0.0.1:{port}/json'
|
||||
url = f"http://127.0.0.1:{port}/json"
|
||||
if path is not None:
|
||||
url += '/' + path
|
||||
url += "/" + path
|
||||
return json.loads(post_json_req(url, json_data))
|
||||
|
||||
|
||||
def waitForServer(delay_event, port, wait_for=20):
|
||||
for i in range(wait_for):
|
||||
if delay_event.is_set():
|
||||
raise ValueError('Test stopped.')
|
||||
raise ValueError("Test stopped.")
|
||||
try:
|
||||
delay_event.wait(1)
|
||||
summary = read_json_api(port)
|
||||
_ = read_json_api(port)
|
||||
return
|
||||
except Exception as e:
|
||||
print('waitForServer, error:', str(e))
|
||||
raise ValueError('waitForServer failed')
|
||||
print("waitForServer, error:", str(e))
|
||||
raise ValueError("waitForServer failed")
|
||||
|
|
Loading…
Reference in a new issue