mirror of
https://github.com/basicswap/basicswap.git
synced 2025-05-05 04:12:16 +00:00
nmc: Update test.
This commit is contained in:
parent
8967f677c3
commit
f263bb53c3
6 changed files with 309 additions and 741 deletions
basicswap
tests/basicswap
|
@ -52,11 +52,17 @@ PARTICL_VERSION = os.getenv("PARTICL_VERSION", "23.2.7.0")
|
||||||
PARTICL_VERSION_TAG = os.getenv("PARTICL_VERSION_TAG", "")
|
PARTICL_VERSION_TAG = os.getenv("PARTICL_VERSION_TAG", "")
|
||||||
PARTICL_LINUX_EXTRA = os.getenv("PARTICL_LINUX_EXTRA", "nousb")
|
PARTICL_LINUX_EXTRA = os.getenv("PARTICL_LINUX_EXTRA", "nousb")
|
||||||
|
|
||||||
|
BITCOIN_VERSION = os.getenv("BITCOIN_VERSION", "28.0")
|
||||||
|
BITCOIN_VERSION_TAG = os.getenv("BITCOIN_VERSION_TAG", "")
|
||||||
|
|
||||||
LITECOIN_VERSION = os.getenv("LITECOIN_VERSION", "0.21.4")
|
LITECOIN_VERSION = os.getenv("LITECOIN_VERSION", "0.21.4")
|
||||||
LITECOIN_VERSION_TAG = os.getenv("LITECOIN_VERSION_TAG", "")
|
LITECOIN_VERSION_TAG = os.getenv("LITECOIN_VERSION_TAG", "")
|
||||||
|
|
||||||
BITCOIN_VERSION = os.getenv("BITCOIN_VERSION", "28.0")
|
DCR_VERSION = os.getenv("DCR_VERSION", "1.8.1")
|
||||||
BITCOIN_VERSION_TAG = os.getenv("BITCOIN_VERSION_TAG", "")
|
DCR_VERSION_TAG = os.getenv("DCR_VERSION_TAG", "")
|
||||||
|
|
||||||
|
NMC_VERSION = os.getenv("NMC_VERSION", "28.0")
|
||||||
|
NMC_VERSION_TAG = os.getenv("NMC_VERSION_TAG", "")
|
||||||
|
|
||||||
MONERO_VERSION = os.getenv("MONERO_VERSION", "0.18.3.4")
|
MONERO_VERSION = os.getenv("MONERO_VERSION", "0.18.3.4")
|
||||||
MONERO_VERSION_TAG = os.getenv("MONERO_VERSION_TAG", "")
|
MONERO_VERSION_TAG = os.getenv("MONERO_VERSION_TAG", "")
|
||||||
|
@ -82,12 +88,6 @@ FIRO_VERSION_TAG = os.getenv("FIRO_VERSION_TAG", "")
|
||||||
NAV_VERSION = os.getenv("NAV_VERSION", "7.0.3")
|
NAV_VERSION = os.getenv("NAV_VERSION", "7.0.3")
|
||||||
NAV_VERSION_TAG = os.getenv("NAV_VERSION_TAG", "")
|
NAV_VERSION_TAG = os.getenv("NAV_VERSION_TAG", "")
|
||||||
|
|
||||||
NMC_VERSION = os.getenv("NAV_VERSION", "28.0")
|
|
||||||
NMC_VERSION_TAG = os.getenv("NAV_VERSION_TAG", "")
|
|
||||||
|
|
||||||
DCR_VERSION = os.getenv("DCR_VERSION", "1.8.1")
|
|
||||||
DCR_VERSION_TAG = os.getenv("DCR_VERSION_TAG", "")
|
|
||||||
|
|
||||||
BITCOINCASH_VERSION = os.getenv("BITCOINCASH_VERSION", "28.0.1")
|
BITCOINCASH_VERSION = os.getenv("BITCOINCASH_VERSION", "28.0.1")
|
||||||
BITCOINCASH_VERSION_TAG = os.getenv("BITCOINCASH_VERSION_TAG", "")
|
BITCOINCASH_VERSION_TAG = os.getenv("BITCOINCASH_VERSION_TAG", "")
|
||||||
|
|
||||||
|
@ -117,9 +117,7 @@ known_coins = {
|
||||||
"dogecoin": (DOGECOIN_VERSION, DOGECOIN_VERSION_TAG, ("tecnovert",)),
|
"dogecoin": (DOGECOIN_VERSION, DOGECOIN_VERSION_TAG, ("tecnovert",)),
|
||||||
}
|
}
|
||||||
|
|
||||||
disabled_coins = [
|
disabled_coins = ["navcoin"]
|
||||||
"navcoin"
|
|
||||||
]
|
|
||||||
|
|
||||||
expected_key_ids = {
|
expected_key_ids = {
|
||||||
"tecnovert": ("13F13651C9CF0D6B",),
|
"tecnovert": ("13F13651C9CF0D6B",),
|
||||||
|
@ -184,6 +182,35 @@ PART_ONION_PORT = int(os.getenv("PART_ONION_PORT", 51734))
|
||||||
PART_RPC_USER = os.getenv("PART_RPC_USER", "")
|
PART_RPC_USER = os.getenv("PART_RPC_USER", "")
|
||||||
PART_RPC_PWD = os.getenv("PART_RPC_PWD", "")
|
PART_RPC_PWD = os.getenv("PART_RPC_PWD", "")
|
||||||
|
|
||||||
|
BTC_RPC_HOST = os.getenv("BTC_RPC_HOST", "127.0.0.1")
|
||||||
|
BTC_RPC_PORT = int(os.getenv("BTC_RPC_PORT", 19996))
|
||||||
|
BTC_PORT = int(os.getenv("BTC_PORT", 8333))
|
||||||
|
BTC_ONION_PORT = int(os.getenv("BTC_ONION_PORT", 8334))
|
||||||
|
BTC_RPC_USER = os.getenv("BTC_RPC_USER", "")
|
||||||
|
BTC_RPC_PWD = os.getenv("BTC_RPC_PWD", "")
|
||||||
|
|
||||||
|
LTC_RPC_HOST = os.getenv("LTC_RPC_HOST", "127.0.0.1")
|
||||||
|
LTC_RPC_PORT = int(os.getenv("LTC_RPC_PORT", 19895))
|
||||||
|
LTC_ONION_PORT = int(os.getenv("LTC_ONION_PORT", 9333))
|
||||||
|
LTC_RPC_USER = os.getenv("LTC_RPC_USER", "")
|
||||||
|
LTC_RPC_PWD = os.getenv("LTC_RPC_PWD", "")
|
||||||
|
|
||||||
|
DCR_RPC_HOST = os.getenv("DCR_RPC_HOST", "127.0.0.1")
|
||||||
|
DCR_RPC_PORT = int(os.getenv("DCR_RPC_PORT", 9109))
|
||||||
|
DCR_WALLET_RPC_HOST = os.getenv("DCR_WALLET_RPC_HOST", "127.0.0.1")
|
||||||
|
DCR_WALLET_RPC_PORT = int(os.getenv("DCR_WALLET_RPC_PORT", 9209))
|
||||||
|
DCR_WALLET_PWD = os.getenv(
|
||||||
|
"DCR_WALLET_PWD", random.randbytes(random.randint(14, 18)).hex()
|
||||||
|
)
|
||||||
|
DCR_RPC_USER = os.getenv("DCR_RPC_USER", "user")
|
||||||
|
DCR_RPC_PWD = os.getenv("DCR_RPC_PWD", random.randbytes(random.randint(14, 18)).hex())
|
||||||
|
|
||||||
|
NMC_RPC_HOST = os.getenv("NMC_RPC_HOST", "127.0.0.1")
|
||||||
|
NMC_RPC_PORT = int(os.getenv("NMC_RPC_PORT", 19698))
|
||||||
|
NMC_ONION_PORT = int(os.getenv("NMC_ONION_PORT", 9698))
|
||||||
|
NMC_RPC_USER = os.getenv("NMC_RPC_USER", "")
|
||||||
|
NMC_RPC_PWD = os.getenv("NMC_RPC_PWD", "")
|
||||||
|
|
||||||
XMR_RPC_HOST = os.getenv("XMR_RPC_HOST", "127.0.0.1")
|
XMR_RPC_HOST = os.getenv("XMR_RPC_HOST", "127.0.0.1")
|
||||||
XMR_RPC_PORT = int(os.getenv("XMR_RPC_PORT", 29798))
|
XMR_RPC_PORT = int(os.getenv("XMR_RPC_PORT", 29798))
|
||||||
XMR_ZMQ_PORT = int(os.getenv("XMR_ZMQ_PORT", 30898))
|
XMR_ZMQ_PORT = int(os.getenv("XMR_ZMQ_PORT", 30898))
|
||||||
|
@ -206,35 +233,6 @@ WOW_RPC_USER = os.getenv("WOW_RPC_USER", "")
|
||||||
WOW_RPC_PWD = os.getenv("WOW_RPC_PWD", "")
|
WOW_RPC_PWD = os.getenv("WOW_RPC_PWD", "")
|
||||||
DEFAULT_WOW_RESTORE_HEIGHT = int(os.getenv("DEFAULT_WOW_RESTORE_HEIGHT", 450000))
|
DEFAULT_WOW_RESTORE_HEIGHT = int(os.getenv("DEFAULT_WOW_RESTORE_HEIGHT", 450000))
|
||||||
|
|
||||||
LTC_RPC_HOST = os.getenv("LTC_RPC_HOST", "127.0.0.1")
|
|
||||||
LTC_RPC_PORT = int(os.getenv("LTC_RPC_PORT", 19895))
|
|
||||||
LTC_ONION_PORT = int(os.getenv("LTC_ONION_PORT", 9333))
|
|
||||||
LTC_RPC_USER = os.getenv("LTC_RPC_USER", "")
|
|
||||||
LTC_RPC_PWD = os.getenv("LTC_RPC_PWD", "")
|
|
||||||
|
|
||||||
BTC_RPC_HOST = os.getenv("BTC_RPC_HOST", "127.0.0.1")
|
|
||||||
BTC_RPC_PORT = int(os.getenv("BTC_RPC_PORT", 19996))
|
|
||||||
BTC_PORT = int(os.getenv("BTC_PORT", 8333))
|
|
||||||
BTC_ONION_PORT = int(os.getenv("BTC_ONION_PORT", 8334))
|
|
||||||
BTC_RPC_USER = os.getenv("BTC_RPC_USER", "")
|
|
||||||
BTC_RPC_PWD = os.getenv("BTC_RPC_PWD", "")
|
|
||||||
|
|
||||||
DCR_RPC_HOST = os.getenv("DCR_RPC_HOST", "127.0.0.1")
|
|
||||||
DCR_RPC_PORT = int(os.getenv("DCR_RPC_PORT", 9109))
|
|
||||||
DCR_WALLET_RPC_HOST = os.getenv("DCR_WALLET_RPC_HOST", "127.0.0.1")
|
|
||||||
DCR_WALLET_RPC_PORT = int(os.getenv("DCR_WALLET_RPC_PORT", 9209))
|
|
||||||
DCR_WALLET_PWD = os.getenv(
|
|
||||||
"DCR_WALLET_PWD", random.randbytes(random.randint(14, 18)).hex()
|
|
||||||
)
|
|
||||||
DCR_RPC_USER = os.getenv("DCR_RPC_USER", "user")
|
|
||||||
DCR_RPC_PWD = os.getenv("DCR_RPC_PWD", random.randbytes(random.randint(14, 18)).hex())
|
|
||||||
|
|
||||||
NMC_RPC_HOST = os.getenv("NMC_RPC_HOST", "127.0.0.1")
|
|
||||||
NMC_RPC_PORT = int(os.getenv("NMC_RPC_PORT", 19698))
|
|
||||||
NMC_ONION_PORT = int(os.getenv("NMC_ONION_PORT", 9698))
|
|
||||||
NMC_RPC_USER = os.getenv("NMC_RPC_USER", "")
|
|
||||||
NMC_RPC_PWD = os.getenv("NMC_RPC_PWD", "")
|
|
||||||
|
|
||||||
PIVX_RPC_HOST = os.getenv("PIVX_RPC_HOST", "127.0.0.1")
|
PIVX_RPC_HOST = os.getenv("PIVX_RPC_HOST", "127.0.0.1")
|
||||||
PIVX_RPC_PORT = int(os.getenv("PIVX_RPC_PORT", 51473))
|
PIVX_RPC_PORT = int(os.getenv("PIVX_RPC_PORT", 51473))
|
||||||
PIVX_ONION_PORT = int(os.getenv("PIVX_ONION_PORT", 51472)) # nDefaultPort
|
PIVX_ONION_PORT = int(os.getenv("PIVX_ONION_PORT", 51472)) # nDefaultPort
|
||||||
|
@ -1400,8 +1398,10 @@ def prepareDataDir(coin, settings, chain, particl_mnemonic, extra_opts={}):
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
elif coin == "namecoin":
|
elif coin == "namecoin":
|
||||||
fp.write("deprecatedrpc=create_bdb\n")
|
|
||||||
fp.write("prune=2000\n")
|
fp.write("prune=2000\n")
|
||||||
|
fp.write("deprecatedrpc=create_bdb\n")
|
||||||
|
fp.write("addresstype=bech32\n")
|
||||||
|
fp.write("changetype=bech32\n")
|
||||||
elif coin == "pivx":
|
elif coin == "pivx":
|
||||||
params_dir = os.path.join(data_dir, "pivx-params")
|
params_dir = os.path.join(data_dir, "pivx-params")
|
||||||
downloadPIVXParams(params_dir)
|
downloadPIVXParams(params_dir)
|
||||||
|
|
|
@ -256,6 +256,8 @@ chainparams = {
|
||||||
"bip44": 7,
|
"bip44": 7,
|
||||||
"min_amount": 100000,
|
"min_amount": 100000,
|
||||||
"max_amount": 10000000 * COIN,
|
"max_amount": 10000000 * COIN,
|
||||||
|
"ext_public_key_prefix": 0x0488B21E, # base58Prefixes[EXT_PUBLIC_KEY]
|
||||||
|
"ext_secret_key_prefix": 0x0488ADE4,
|
||||||
},
|
},
|
||||||
"testnet": {
|
"testnet": {
|
||||||
"rpcport": 18336,
|
"rpcport": 18336,
|
||||||
|
@ -267,6 +269,8 @@ chainparams = {
|
||||||
"min_amount": 100000,
|
"min_amount": 100000,
|
||||||
"max_amount": 10000000 * COIN,
|
"max_amount": 10000000 * COIN,
|
||||||
"name": "testnet3",
|
"name": "testnet3",
|
||||||
|
"ext_public_key_prefix": 0x043587CF,
|
||||||
|
"ext_secret_key_prefix": 0x04358394,
|
||||||
},
|
},
|
||||||
"regtest": {
|
"regtest": {
|
||||||
"rpcport": 18443,
|
"rpcport": 18443,
|
||||||
|
@ -277,6 +281,8 @@ chainparams = {
|
||||||
"bip44": 1,
|
"bip44": 1,
|
||||||
"min_amount": 100000,
|
"min_amount": 100000,
|
||||||
"max_amount": 10000000 * COIN,
|
"max_amount": 10000000 * COIN,
|
||||||
|
"ext_public_key_prefix": 0x043587CF,
|
||||||
|
"ext_secret_key_prefix": 0x04358394,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Coins.XMR: {
|
Coins.XMR: {
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
# Copyright (c) 2020-2022 tecnovert
|
# Copyright (c) 2020-2022 tecnovert
|
||||||
|
# Copyright (c) 2025 The Basicswap developers
|
||||||
# Distributed under the MIT software license, see the accompanying
|
# Distributed under the MIT software license, see the accompanying
|
||||||
# file LICENSE or http://www.opensource.org/licenses/mit-license.php.
|
# file LICENSE or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
@ -14,38 +15,56 @@ class NMCInterface(BTCInterface):
|
||||||
def coin_type():
|
def coin_type():
|
||||||
return Coins.NMC
|
return Coins.NMC
|
||||||
|
|
||||||
def getLockTxHeight(
|
def lockNonSegwitPrevouts(self) -> None:
|
||||||
self,
|
# For tests
|
||||||
txid,
|
# NMC Seems to ignore utxo locks
|
||||||
dest_address,
|
unspent = self.rpc_wallet("listunspent")
|
||||||
bid_amount,
|
|
||||||
rescan_from,
|
|
||||||
find_index: bool = False,
|
|
||||||
vout: int = -1,
|
|
||||||
):
|
|
||||||
self._log.debug("[rm] scantxoutset start") # scantxoutset is slow
|
|
||||||
ro = self.rpc(
|
|
||||||
"scantxoutset", ["start", ["addr({})".format(dest_address)]]
|
|
||||||
) # TODO: Use combo(address) where possible
|
|
||||||
self._log.debug("[rm] scantxoutset end")
|
|
||||||
return_txid = True if txid is None else False
|
|
||||||
for o in ro["unspents"]:
|
|
||||||
if txid and o["txid"] != txid.hex():
|
|
||||||
continue
|
|
||||||
# Verify amount
|
|
||||||
if self.make_int(o["amount"]) != int(bid_amount):
|
|
||||||
self._log.warning(
|
|
||||||
"Found output to lock tx address of incorrect value: %s, %s",
|
|
||||||
str(o["amount"]),
|
|
||||||
o["txid"],
|
|
||||||
)
|
|
||||||
continue
|
|
||||||
|
|
||||||
rv = {"depth": 0, "height": o["height"]}
|
to_lock = []
|
||||||
if o["height"] > 0:
|
for u in unspent:
|
||||||
rv["depth"] = ro["height"] - o["height"]
|
if u.get("spendable", False) is False:
|
||||||
if find_index:
|
continue
|
||||||
rv["index"] = o["vout"]
|
if "desc" in u:
|
||||||
if return_txid:
|
desc = u["desc"]
|
||||||
rv["txid"] = o["txid"]
|
if self.use_p2shp2wsh():
|
||||||
return rv
|
if not desc.startswith("sh(wpkh"):
|
||||||
|
to_lock.append(
|
||||||
|
{
|
||||||
|
"txid": u["txid"],
|
||||||
|
"vout": u["vout"],
|
||||||
|
"amount": u["amount"],
|
||||||
|
}
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
if not desc.startswith("wpkh"):
|
||||||
|
to_lock.append(
|
||||||
|
{
|
||||||
|
"txid": u["txid"],
|
||||||
|
"vout": u["vout"],
|
||||||
|
"amount": u["amount"],
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
if len(to_lock) > 0:
|
||||||
|
self._log.debug(f"Spending {len(to_lock)} non segwit prevouts")
|
||||||
|
addr_out = self.rpc_wallet(
|
||||||
|
"getnewaddress", ["convert non segwit", "bech32"]
|
||||||
|
)
|
||||||
|
prevouts = []
|
||||||
|
sum_amount: int = 0
|
||||||
|
for utxo in to_lock:
|
||||||
|
prevouts.append(
|
||||||
|
{
|
||||||
|
"txid": utxo["txid"],
|
||||||
|
"vout": utxo["vout"],
|
||||||
|
}
|
||||||
|
)
|
||||||
|
sum_amount += self.make_int(utxo["amount"])
|
||||||
|
|
||||||
|
fee = 100000 * len(prevouts)
|
||||||
|
funded_tx = self.rpc(
|
||||||
|
"createrawtransaction",
|
||||||
|
[prevouts, {addr_out: self.format_amount(sum_amount - fee)}],
|
||||||
|
)
|
||||||
|
signed_tx = self.rpc_wallet("signrawtransactionwithwallet", [funded_tx])
|
||||||
|
self.rpc("sendrawtransaction", [signed_tx["hex"]])
|
||||||
|
|
|
@ -138,7 +138,6 @@ def run_test_success_path(self, coin_from: Coins, coin_to: Coins):
|
||||||
|
|
||||||
# Verify lock tx spends are found in the expected wallets
|
# Verify lock tx spends are found in the expected wallets
|
||||||
bid, offer = swap_clients[node_from].getBidAndOffer(bid_id)
|
bid, offer = swap_clients[node_from].getBidAndOffer(bid_id)
|
||||||
max_fee: int = 10000
|
|
||||||
itx_spend = bid.initiate_tx.spend_txid.hex()
|
itx_spend = bid.initiate_tx.spend_txid.hex()
|
||||||
node_to_ci_from = swap_clients[node_to].ci(coin_from)
|
node_to_ci_from = swap_clients[node_to].ci(coin_from)
|
||||||
wtx = node_to_ci_from.rpc_wallet(
|
wtx = node_to_ci_from.rpc_wallet(
|
||||||
|
@ -147,7 +146,9 @@ def run_test_success_path(self, coin_from: Coins, coin_to: Coins):
|
||||||
itx_spend,
|
itx_spend,
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
assert amt_swap - node_to_ci_from.make_int(wtx["details"][0]["amount"]) < max_fee
|
assert (
|
||||||
|
amt_swap - node_to_ci_from.make_int(wtx["details"][0]["amount"]) < self.max_fee
|
||||||
|
)
|
||||||
|
|
||||||
node_from_ci_to = swap_clients[node_from].ci(coin_to)
|
node_from_ci_to = swap_clients[node_from].ci(coin_to)
|
||||||
ptx_spend = bid.participate_tx.spend_txid.hex()
|
ptx_spend = bid.participate_tx.spend_txid.hex()
|
||||||
|
@ -158,7 +159,8 @@ def run_test_success_path(self, coin_from: Coins, coin_to: Coins):
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
assert (
|
assert (
|
||||||
bid.amount_to - node_from_ci_to.make_int(wtx["details"][0]["amount"]) < max_fee
|
bid.amount_to - node_from_ci_to.make_int(wtx["details"][0]["amount"])
|
||||||
|
< self.max_fee
|
||||||
)
|
)
|
||||||
|
|
||||||
js_0 = read_json_api(1800 + node_from)
|
js_0 = read_json_api(1800 + node_from)
|
||||||
|
@ -235,7 +237,6 @@ def run_test_bad_ptx(self, coin_from: Coins, coin_to: Coins):
|
||||||
|
|
||||||
# Verify lock tx spends are found in the expected wallets
|
# Verify lock tx spends are found in the expected wallets
|
||||||
bid, offer = swap_clients[node_from].getBidAndOffer(bid_id)
|
bid, offer = swap_clients[node_from].getBidAndOffer(bid_id)
|
||||||
max_fee: int = 10000
|
|
||||||
itx_spend = bid.initiate_tx.spend_txid.hex()
|
itx_spend = bid.initiate_tx.spend_txid.hex()
|
||||||
node_from_ci_from = swap_clients[node_from].ci(coin_from)
|
node_from_ci_from = swap_clients[node_from].ci(coin_from)
|
||||||
wtx = node_from_ci_from.rpc_wallet(
|
wtx = node_from_ci_from.rpc_wallet(
|
||||||
|
@ -244,7 +245,10 @@ def run_test_bad_ptx(self, coin_from: Coins, coin_to: Coins):
|
||||||
itx_spend,
|
itx_spend,
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
assert amt_swap - node_from_ci_from.make_int(wtx["details"][0]["amount"]) < max_fee
|
assert (
|
||||||
|
amt_swap - node_from_ci_from.make_int(wtx["details"][0]["amount"])
|
||||||
|
< self.max_fee
|
||||||
|
)
|
||||||
|
|
||||||
node_to_ci_to = swap_clients[node_to].ci(coin_to)
|
node_to_ci_to = swap_clients[node_to].ci(coin_to)
|
||||||
bid, offer = swap_clients[node_to].getBidAndOffer(bid_id)
|
bid, offer = swap_clients[node_to].getBidAndOffer(bid_id)
|
||||||
|
@ -255,7 +259,10 @@ def run_test_bad_ptx(self, coin_from: Coins, coin_to: Coins):
|
||||||
ptx_spend,
|
ptx_spend,
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
assert bid.amount_to - node_to_ci_to.make_int(wtx["details"][0]["amount"]) < max_fee
|
assert (
|
||||||
|
bid.amount_to - node_to_ci_to.make_int(wtx["details"][0]["amount"])
|
||||||
|
< self.max_fee
|
||||||
|
)
|
||||||
|
|
||||||
bid_id_hex = bid_id.hex()
|
bid_id_hex = bid_id.hex()
|
||||||
path = f"bids/{bid_id_hex}/states"
|
path = f"bids/{bid_id_hex}/states"
|
||||||
|
@ -338,7 +345,6 @@ def run_test_itx_refund(self, coin_from: Coins, coin_to: Coins):
|
||||||
|
|
||||||
# Verify lock tx spends are found in the expected wallets
|
# Verify lock tx spends are found in the expected wallets
|
||||||
bid, offer = swap_clients[node_from].getBidAndOffer(bid_id)
|
bid, offer = swap_clients[node_from].getBidAndOffer(bid_id)
|
||||||
max_fee: int = 10000
|
|
||||||
itx_spend = bid.initiate_tx.spend_txid.hex()
|
itx_spend = bid.initiate_tx.spend_txid.hex()
|
||||||
node_from_ci_from = swap_clients[node_from].ci(coin_from)
|
node_from_ci_from = swap_clients[node_from].ci(coin_from)
|
||||||
wtx = node_from_ci_from.rpc_wallet(
|
wtx = node_from_ci_from.rpc_wallet(
|
||||||
|
@ -348,7 +354,8 @@ def run_test_itx_refund(self, coin_from: Coins, coin_to: Coins):
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
assert (
|
assert (
|
||||||
swap_value - node_from_ci_from.make_int(wtx["details"][0]["amount"]) < max_fee
|
swap_value - node_from_ci_from.make_int(wtx["details"][0]["amount"])
|
||||||
|
< self.max_fee
|
||||||
)
|
)
|
||||||
|
|
||||||
node_from_ci_to = swap_clients[node_from].ci(coin_to)
|
node_from_ci_to = swap_clients[node_from].ci(coin_to)
|
||||||
|
@ -360,7 +367,8 @@ def run_test_itx_refund(self, coin_from: Coins, coin_to: Coins):
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
assert (
|
assert (
|
||||||
bid.amount_to - node_from_ci_to.make_int(wtx["details"][0]["amount"]) < max_fee
|
bid.amount_to - node_from_ci_to.make_int(wtx["details"][0]["amount"])
|
||||||
|
< self.max_fee
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -425,7 +433,6 @@ def run_test_ads_success_path(self, coin_from: Coins, coin_to: Coins):
|
||||||
bid, xmr_swap = swap_clients[id_offerer].getXmrBid(bid_id)
|
bid, xmr_swap = swap_clients[id_offerer].getXmrBid(bid_id)
|
||||||
|
|
||||||
node_from_ci_to = swap_clients[0].ci(coin_to)
|
node_from_ci_to = swap_clients[0].ci(coin_to)
|
||||||
max_fee: int = 10000
|
|
||||||
if node_from_ci_to.coin_type() in (Coins.XMR, Coins.WOW):
|
if node_from_ci_to.coin_type() in (Coins.XMR, Coins.WOW):
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
|
@ -437,7 +444,7 @@ def run_test_ads_success_path(self, coin_from: Coins, coin_to: Coins):
|
||||||
)
|
)
|
||||||
assert (
|
assert (
|
||||||
bid.amount_to - node_from_ci_to.make_int(wtx["details"][0]["amount"])
|
bid.amount_to - node_from_ci_to.make_int(wtx["details"][0]["amount"])
|
||||||
< max_fee
|
< self.max_fee
|
||||||
)
|
)
|
||||||
|
|
||||||
node_to_ci_from = swap_clients[1].ci(coin_from)
|
node_to_ci_from = swap_clients[1].ci(coin_from)
|
||||||
|
@ -451,7 +458,8 @@ def run_test_ads_success_path(self, coin_from: Coins, coin_to: Coins):
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
assert (
|
assert (
|
||||||
bid.amount - node_to_ci_from.make_int(wtx["details"][0]["amount"]) < max_fee
|
bid.amount - node_to_ci_from.make_int(wtx["details"][0]["amount"])
|
||||||
|
< self.max_fee
|
||||||
)
|
)
|
||||||
|
|
||||||
bid_id_hex = bid_id.hex()
|
bid_id_hex = bid_id.hex()
|
||||||
|
@ -550,7 +558,6 @@ def run_test_ads_both_refund(
|
||||||
bid, xmr_swap = swap_clients[id_bidder].getXmrBid(bid_id)
|
bid, xmr_swap = swap_clients[id_bidder].getXmrBid(bid_id)
|
||||||
|
|
||||||
node_from_ci_from = swap_clients[0].ci(coin_from)
|
node_from_ci_from = swap_clients[0].ci(coin_from)
|
||||||
max_fee: int = 10000
|
|
||||||
if node_from_ci_from.coin_type() in (Coins.XMR, Coins.WOW):
|
if node_from_ci_from.coin_type() in (Coins.XMR, Coins.WOW):
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
|
@ -562,7 +569,7 @@ def run_test_ads_both_refund(
|
||||||
)
|
)
|
||||||
assert (
|
assert (
|
||||||
bid.amount - node_from_ci_from.make_int(wtx["details"][0]["amount"])
|
bid.amount - node_from_ci_from.make_int(wtx["details"][0]["amount"])
|
||||||
< max_fee
|
< self.max_fee
|
||||||
)
|
)
|
||||||
|
|
||||||
node_to_ci_to = swap_clients[1].ci(coin_to)
|
node_to_ci_to = swap_clients[1].ci(coin_to)
|
||||||
|
@ -577,7 +584,7 @@ def run_test_ads_both_refund(
|
||||||
)
|
)
|
||||||
assert (
|
assert (
|
||||||
bid.amount_to - node_to_ci_to.make_int(wtx["details"][0]["amount"])
|
bid.amount_to - node_to_ci_to.make_int(wtx["details"][0]["amount"])
|
||||||
< max_fee
|
< self.max_fee
|
||||||
)
|
)
|
||||||
|
|
||||||
bid_id_hex = bid_id.hex()
|
bid_id_hex = bid_id.hex()
|
||||||
|
@ -720,6 +727,7 @@ class Test(BaseTest):
|
||||||
start_xmr_nodes = True
|
start_xmr_nodes = True
|
||||||
dcr_mining_addr = "SsYbXyjkKAEXXcGdFgr4u4bo4L8RkCxwQpH"
|
dcr_mining_addr = "SsYbXyjkKAEXXcGdFgr4u4bo4L8RkCxwQpH"
|
||||||
extra_wait_time = 0
|
extra_wait_time = 0
|
||||||
|
max_fee: int = 10000
|
||||||
|
|
||||||
hex_seeds = [
|
hex_seeds = [
|
||||||
"e8574b2a94404ee62d8acc0258cab4c0defcfab8a5dfc2f4954c1f9d7e09d72a",
|
"e8574b2a94404ee62d8acc0258cab4c0defcfab8a5dfc2f4954c1f9d7e09d72a",
|
||||||
|
|
|
@ -11,67 +11,38 @@ basicswap]$ python tests/basicswap/extended/test_nmc.py
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import json
|
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import shutil
|
import random
|
||||||
import signal
|
|
||||||
import sys
|
import sys
|
||||||
import threading
|
|
||||||
import time
|
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
import basicswap.config as cfg
|
import basicswap.config as cfg
|
||||||
from basicswap.basicswap import (
|
from basicswap.basicswap import (
|
||||||
BasicSwap,
|
|
||||||
Coins,
|
Coins,
|
||||||
SwapTypes,
|
|
||||||
BidStates,
|
|
||||||
TxStates,
|
|
||||||
)
|
)
|
||||||
from basicswap.util import (
|
from basicswap.util import (
|
||||||
COIN,
|
toBool,
|
||||||
)
|
|
||||||
from basicswap.basicswap_util import (
|
|
||||||
TxLockTypes,
|
|
||||||
)
|
|
||||||
from basicswap.util.address import (
|
|
||||||
toWIF,
|
|
||||||
)
|
|
||||||
from basicswap.rpc import (
|
|
||||||
callrpc_cli,
|
|
||||||
)
|
|
||||||
from basicswap.contrib.key import (
|
|
||||||
ECKey,
|
|
||||||
)
|
)
|
||||||
|
from basicswap.bin.run import startDaemon
|
||||||
from basicswap.contrib.rpcauth import generate_salt, password_to_hmac
|
from basicswap.contrib.rpcauth import generate_salt, password_to_hmac
|
||||||
from basicswap.http_server import (
|
|
||||||
HttpThread,
|
|
||||||
)
|
|
||||||
from tests.basicswap.util import (
|
|
||||||
read_json_api,
|
|
||||||
)
|
|
||||||
from tests.basicswap.common import (
|
from tests.basicswap.common import (
|
||||||
checkForks,
|
|
||||||
stopDaemons,
|
stopDaemons,
|
||||||
wait_for_offer,
|
|
||||||
wait_for_bid,
|
|
||||||
wait_for_bid_tx_state,
|
|
||||||
wait_for_in_progress,
|
|
||||||
TEST_HTTP_HOST,
|
|
||||||
TEST_HTTP_PORT,
|
|
||||||
BASE_PORT,
|
|
||||||
BASE_RPC_PORT,
|
|
||||||
BASE_ZMQ_PORT,
|
|
||||||
PREFIX_SECRET_KEY_REGTEST,
|
|
||||||
waitForRPC,
|
waitForRPC,
|
||||||
make_rpc_func,
|
make_rpc_func,
|
||||||
)
|
)
|
||||||
from basicswap.bin.run import startDaemon
|
|
||||||
|
from tests.basicswap.test_btc_xmr import BasicSwapTest, test_delay_event
|
||||||
|
from tests.basicswap.test_xmr import NUM_NODES
|
||||||
|
from tests.basicswap.extended.test_dcr import (
|
||||||
|
run_test_success_path,
|
||||||
|
run_test_bad_ptx,
|
||||||
|
run_test_itx_refund,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger()
|
logger = logging.getLogger("BSX Tests")
|
||||||
logger.level = logging.DEBUG
|
|
||||||
if not len(logger.handlers):
|
if not len(logger.handlers):
|
||||||
logger.addHandler(logging.StreamHandler(sys.stdout))
|
logger.addHandler(logging.StreamHandler(sys.stdout))
|
||||||
|
|
||||||
|
@ -83,19 +54,14 @@ NAMECOIND = os.getenv("NAMECOIND", "namecoind" + cfg.bin_suffix)
|
||||||
NAMECOIN_CLI = os.getenv("NAMECOIN_CLI", "namecoin-cli" + cfg.bin_suffix)
|
NAMECOIN_CLI = os.getenv("NAMECOIN_CLI", "namecoin-cli" + cfg.bin_suffix)
|
||||||
NAMECOIN_TX = os.getenv("NAMECOIN_TX", "namecoin-tx" + cfg.bin_suffix)
|
NAMECOIN_TX = os.getenv("NAMECOIN_TX", "namecoin-tx" + cfg.bin_suffix)
|
||||||
|
|
||||||
|
USE_DESCRIPTOR_WALLETS = toBool(os.getenv("USE_DESCRIPTOR_WALLETS", False))
|
||||||
|
|
||||||
NMC_BASE_PORT = 8136
|
NMC_BASE_PORT = 8136
|
||||||
NMC_BASE_RPC_PORT= 8146
|
NMC_BASE_RPC_PORT = 8146
|
||||||
|
|
||||||
NUM_NODES = 3
|
|
||||||
NMC_NODE = 3
|
|
||||||
BTC_NODE = 4
|
|
||||||
|
|
||||||
delay_event = threading.Event()
|
|
||||||
stop_test = False
|
|
||||||
|
|
||||||
|
|
||||||
def prepareOtherDir(datadir, nodeId, conf_file="namecoin.conf"):
|
def prepareNMCDataDir(datadir, nodeId, conf_file="namecoin.conf"):
|
||||||
node_dir = os.path.join(datadir, str(nodeId))
|
node_dir = os.path.join(datadir, "nmc_" + str(nodeId))
|
||||||
if not os.path.exists(node_dir):
|
if not os.path.exists(node_dir):
|
||||||
os.makedirs(node_dir)
|
os.makedirs(node_dir)
|
||||||
filePath = os.path.join(node_dir, conf_file)
|
filePath = os.path.join(node_dir, conf_file)
|
||||||
|
@ -104,20 +70,16 @@ def prepareOtherDir(datadir, nodeId, conf_file="namecoin.conf"):
|
||||||
fp.write("regtest=1\n")
|
fp.write("regtest=1\n")
|
||||||
fp.write("[regtest]\n")
|
fp.write("[regtest]\n")
|
||||||
|
|
||||||
if conf_file == "bitcoin.conf":
|
fp.write("port=" + str(NMC_BASE_PORT + nodeId) + "\n")
|
||||||
fp.write("port=" + str(BASE_PORT + nodeId) + "\n")
|
fp.write("rpcport=" + str(NMC_BASE_RPC_PORT + nodeId) + "\n")
|
||||||
fp.write("rpcport=" + str(BASE_RPC_PORT + nodeId) + "\n")
|
salt = generate_salt(16)
|
||||||
else:
|
fp.write(
|
||||||
fp.write("port=" + str(NMC_BASE_PORT + nodeId) + "\n")
|
"rpcauth={}:{}${}\n".format(
|
||||||
fp.write("rpcport=" + str(NMC_BASE_RPC_PORT + nodeId) + "\n")
|
"test" + str(nodeId),
|
||||||
salt = generate_salt(16)
|
salt,
|
||||||
fp.write(
|
password_to_hmac(salt, "test_pass" + str(nodeId)),
|
||||||
"rpcauth={}:{}${}\n".format(
|
|
||||||
"test" + str(nodeId),
|
|
||||||
salt,
|
|
||||||
password_to_hmac(salt, "test_pass" + str(nodeId)),
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
)
|
||||||
|
|
||||||
fp.write("daemon=0\n")
|
fp.write("daemon=0\n")
|
||||||
fp.write("printtoconsole=0\n")
|
fp.write("printtoconsole=0\n")
|
||||||
|
@ -125,592 +87,171 @@ def prepareOtherDir(datadir, nodeId, conf_file="namecoin.conf"):
|
||||||
fp.write("discover=0\n")
|
fp.write("discover=0\n")
|
||||||
fp.write("listenonion=0\n")
|
fp.write("listenonion=0\n")
|
||||||
fp.write("bind=127.0.0.1\n")
|
fp.write("bind=127.0.0.1\n")
|
||||||
fp.write("findpeers=0\n")
|
|
||||||
fp.write("debug=1\n")
|
fp.write("debug=1\n")
|
||||||
fp.write("debugexclude=libevent\n")
|
fp.write("debugexclude=libevent\n")
|
||||||
|
|
||||||
fp.write("fallbackfee=0.01\n")
|
fp.write("fallbackfee=0.01\n")
|
||||||
fp.write("acceptnonstdtxn=0\n")
|
fp.write("acceptnonstdtxn=0\n")
|
||||||
fp.write("deprecatedrpc=create_bdb\n")
|
fp.write("deprecatedrpc=create_bdb\n")
|
||||||
fp.write("wallet=wallet.dat\n")
|
fp.write("addresstype=bech32\n")
|
||||||
|
fp.write("changetype=bech32\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")
|
|
||||||
|
|
||||||
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("acceptnonstdtxn=0\n")
|
|
||||||
fp.write("minstakeinterval=5\n")
|
|
||||||
fp.write("smsgsregtestadjust=0\n")
|
|
||||||
|
|
||||||
for i in range(0, NUM_NODES):
|
for i in range(0, NUM_NODES):
|
||||||
if nodeId == i:
|
if nodeId == i:
|
||||||
continue
|
continue
|
||||||
fp.write("addnode=127.0.0.1:%d\n" % (BASE_PORT + i))
|
fp.write("addnode=127.0.0.1:{}\n".format(NMC_BASE_PORT + i))
|
||||||
|
|
||||||
if nodeId < 2:
|
|
||||||
fp.write("spentindex=1\n")
|
|
||||||
fp.write("txindex=1\n")
|
|
||||||
|
|
||||||
basicswap_dir = os.path.join(datadir, str(nodeId), "basicswap")
|
|
||||||
if not os.path.exists(basicswap_dir):
|
|
||||||
os.makedirs(basicswap_dir)
|
|
||||||
|
|
||||||
nmcdatadir = os.path.join(datadir, str(NMC_NODE))
|
|
||||||
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
|
|
||||||
},
|
|
||||||
"namecoin": {
|
|
||||||
"connection_type": "rpc",
|
|
||||||
"manage_daemon": False,
|
|
||||||
"rpcport": NMC_BASE_RPC_PORT + NMC_NODE,
|
|
||||||
"datadir": nmcdatadir,
|
|
||||||
"bindir": NAMECOIN_BINDIR,
|
|
||||||
"use_csv": True,
|
|
||||||
"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,
|
|
||||||
}
|
|
||||||
with open(settings_path, "w") as fp:
|
|
||||||
json.dump(settings, fp, indent=4)
|
|
||||||
|
|
||||||
|
|
||||||
def partRpc(cmd, node_id=0):
|
class TestNMC(BasicSwapTest):
|
||||||
return callrpc_cli(
|
__test__ = True
|
||||||
cfg.PARTICL_BINDIR,
|
test_coin = Coins.NMC
|
||||||
os.path.join(cfg.TEST_DATADIRS, str(node_id)),
|
test_coin_from = Coins.NMC
|
||||||
"regtest",
|
nmc_daemons = []
|
||||||
cmd,
|
start_ltc_nodes = False
|
||||||
cfg.PARTICL_CLI,
|
start_xmr_nodes = True
|
||||||
)
|
base_rpc_port = NMC_BASE_RPC_PORT
|
||||||
|
nmc_addr = None
|
||||||
|
max_fee: int = 200000
|
||||||
|
test_fee_rate: int = 10000 # sats/kvB
|
||||||
|
|
||||||
|
def mineBlock(self, num_blocks: int = 1) -> None:
|
||||||
def btcRpc(cmd):
|
self.callnoderpc("generatetoaddress", [num_blocks, self.nmc_addr])
|
||||||
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(
|
|
||||||
NAMECOIN_BINDIR,
|
|
||||||
os.path.join(cfg.TEST_DATADIRS, str(NMC_NODE)),
|
|
||||||
"regtest",
|
|
||||||
cmd,
|
|
||||||
NAMECOIN_CLI,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def signal_handler(sig, frame):
|
|
||||||
global stop_test
|
|
||||||
os.write(sys.stdout.fileno(), f"Signal {sig} detected.\n".encode("utf-8"))
|
|
||||||
stop_test = True
|
|
||||||
delay_event.set()
|
|
||||||
|
|
||||||
|
|
||||||
def run_coins_loop(cls):
|
|
||||||
while not stop_test:
|
|
||||||
try:
|
|
||||||
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))
|
|
||||||
time.sleep(1.0)
|
|
||||||
|
|
||||||
|
|
||||||
def run_loop(self):
|
|
||||||
while not stop_test:
|
|
||||||
for c in self.swap_clients:
|
|
||||||
c.update()
|
|
||||||
time.sleep(1)
|
|
||||||
|
|
||||||
|
|
||||||
def make_part_cli_rpc_func(node_id):
|
|
||||||
node_id = node_id
|
|
||||||
|
|
||||||
def rpc_func(method, params=None, wallet=None):
|
|
||||||
cmd = method
|
|
||||||
if params:
|
|
||||||
for p in params:
|
|
||||||
cmd += ' "' + p + '"'
|
|
||||||
return partRpc(cmd, node_id)
|
|
||||||
|
|
||||||
return rpc_func
|
|
||||||
|
|
||||||
|
|
||||||
class Test(unittest.TestCase):
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def setUpClass(cls):
|
def tearDownClass(cls):
|
||||||
super(Test, cls).setUpClass()
|
logging.info("Finalising Namecoin Test")
|
||||||
|
stopDaemons(cls.nmc_daemons)
|
||||||
|
cls.nmc_daemons.clear()
|
||||||
|
|
||||||
eckey = ECKey()
|
super(TestNMC, cls).tearDownClass()
|
||||||
eckey.generate()
|
|
||||||
cls.network_key = toWIF(PREFIX_SECRET_KEY_REGTEST, eckey.get_bytes())
|
|
||||||
cls.network_pubkey = eckey.get_pubkey().get_bytes().hex()
|
|
||||||
|
|
||||||
if os.path.isdir(cfg.TEST_DATADIRS):
|
@classmethod
|
||||||
logging.info("Removing " + cfg.TEST_DATADIRS)
|
def coins_loop(cls):
|
||||||
shutil.rmtree(cfg.TEST_DATADIRS)
|
super(TestNMC, cls).coins_loop()
|
||||||
|
ci0 = cls.swap_clients[0].ci(cls.test_coin)
|
||||||
|
try:
|
||||||
|
if cls.nmc_addr is not None:
|
||||||
|
ci0.rpc_wallet("generatetoaddress", [1, cls.nmc_addr])
|
||||||
|
except Exception as e:
|
||||||
|
logging.warning(f"coins_loop generate {e}")
|
||||||
|
|
||||||
for i in range(NUM_NODES):
|
@classmethod
|
||||||
prepareDir(cfg.TEST_DATADIRS, i, cls.network_key, cls.network_pubkey)
|
def prepareExtraDataDir(cls, i: int) -> None:
|
||||||
|
if not cls.restore_instance:
|
||||||
|
prepareNMCDataDir(cfg.TEST_DATADIRS, i)
|
||||||
|
|
||||||
prepareOtherDir(cfg.TEST_DATADIRS, NMC_NODE)
|
cls.nmc_daemons.append(
|
||||||
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",
|
|
||||||
)
|
|
||||||
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(
|
startDaemon(
|
||||||
os.path.join(cfg.TEST_DATADIRS, str(NMC_NODE)),
|
os.path.join(cfg.TEST_DATADIRS, "nmc_" + str(i)),
|
||||||
NAMECOIN_BINDIR,
|
NAMECOIN_BINDIR,
|
||||||
NAMECOIND,
|
NAMECOIND,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
logging.info("Started %s %d", NAMECOIND, cls.daemons[-1].handle.pid)
|
logging.info("Started {} {}".format(NAMECOIND, cls.nmc_daemons[-1].handle.pid))
|
||||||
nmcRpc2 = make_rpc_func(NMC_NODE, base_rpc_port=NMC_BASE_RPC_PORT)
|
|
||||||
waitForRPC(nmcRpc2, delay_event, rpc_command="getblockchaininfo")
|
|
||||||
if len(nmcRpc2("listwallets")) < 1:
|
|
||||||
nmcRpc2("createwallet", ["wallet.dat", False, False, "", False, False])
|
|
||||||
|
|
||||||
for i in range(NUM_NODES):
|
nmc_rpc = make_rpc_func(i, base_rpc_port=NMC_BASE_RPC_PORT)
|
||||||
data_dir = os.path.join(cfg.TEST_DATADIRS, str(i))
|
waitForRPC(
|
||||||
if os.path.exists(os.path.join(cfg.PARTICL_BINDIR, "particl-wallet")):
|
nmc_rpc,
|
||||||
callrpc_cli(
|
test_delay_event,
|
||||||
cfg.PARTICL_BINDIR,
|
rpc_command="getnetworkinfo",
|
||||||
data_dir,
|
max_tries=12,
|
||||||
"regtest",
|
)
|
||||||
"-wallet=wallet.dat -legacy create",
|
waitForRPC(nmc_rpc, test_delay_event, rpc_command="getblockchaininfo")
|
||||||
"particl-wallet",
|
if len(nmc_rpc("listwallets")) < 1:
|
||||||
)
|
nmc_rpc(
|
||||||
cls.daemons.append(startDaemon(data_dir, cfg.PARTICL_BINDIR, cfg.PARTICLD))
|
"createwallet",
|
||||||
logging.info("Started %s %d", cfg.PARTICLD, cls.daemons[-1].handle.pid)
|
["wallet.dat", False, False, "", False, USE_DESCRIPTOR_WALLETS],
|
||||||
|
|
||||||
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"
|
|
||||||
],
|
|
||||||
)
|
|
||||||
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")
|
|
||||||
else:
|
|
||||||
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"
|
|
||||||
)
|
|
||||||
settings_path = os.path.join(basicswap_dir, cfg.CONFIG_FILENAME)
|
|
||||||
with open(settings_path) as fs:
|
|
||||||
settings = json.load(fs)
|
|
||||||
sc = BasicSwap(
|
|
||||||
basicswap_dir, settings, "regtest", log_name="BasicSwap{}".format(i)
|
|
||||||
)
|
|
||||||
cls.swap_clients.append(sc)
|
|
||||||
|
|
||||||
sc.setDaemonPID(Coins.BTC, cls.daemons[0].handle.pid)
|
|
||||||
sc.setDaemonPID(Coins.NMC, cls.daemons[1].handle.pid)
|
|
||||||
sc.setDaemonPID(Coins.PART, cls.daemons[2 + i].handle.pid)
|
|
||||||
sc.start()
|
|
||||||
|
|
||||||
t = HttpThread(TEST_HTTP_HOST, TEST_HTTP_PORT + i, False, sc)
|
|
||||||
cls.http_threads.append(t)
|
|
||||||
t.start()
|
|
||||||
|
|
||||||
num_blocks = 500
|
|
||||||
logging.info("Mining %d namecoin blocks", num_blocks)
|
|
||||||
cls.nmc_addr = nmcRpc("getnewaddress mining_addr bech32")
|
|
||||||
nmcRpc("generatetoaddress {} {}".format(num_blocks, cls.nmc_addr))
|
|
||||||
|
|
||||||
ro = nmcRpc("getblockchaininfo")
|
|
||||||
try:
|
|
||||||
assert ro["bip9_softforks"]["csv"]["status"] == "active"
|
|
||||||
except Exception:
|
|
||||||
logging.info("nmc: csv is not active")
|
|
||||||
try:
|
|
||||||
assert ro["bip9_softforks"]["segwit"]["status"] == "active"
|
|
||||||
except Exception:
|
|
||||||
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))
|
|
||||||
|
|
||||||
ro = btcRpc("getblockchaininfo")
|
|
||||||
checkForks(ro)
|
|
||||||
|
|
||||||
ro = nmcRpc("getwalletinfo")
|
|
||||||
print("nmcRpc", ro)
|
|
||||||
|
|
||||||
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.start()
|
|
||||||
|
|
||||||
# Wait for height, or sequencelock is thrown off by genesis blocktime
|
|
||||||
num_blocks = 3
|
|
||||||
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)
|
|
||||||
if particl_blocks >= num_blocks:
|
|
||||||
break
|
|
||||||
delay_event.wait(1)
|
|
||||||
assert particl_blocks >= num_blocks
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def tearDownClass(cls):
|
def addPIDInfo(cls, sc, i):
|
||||||
global stop_test
|
sc.setDaemonPID(Coins.DCR, cls.nmc_daemons[i].handle.pid)
|
||||||
logging.info("Finalising")
|
|
||||||
stop_test = True
|
|
||||||
cls.update_thread.join()
|
|
||||||
cls.coins_update_thread.join()
|
|
||||||
for t in cls.http_threads:
|
|
||||||
t.stop()
|
|
||||||
t.join()
|
|
||||||
for c in cls.swap_clients:
|
|
||||||
c.finalise()
|
|
||||||
|
|
||||||
stopDaemons(cls.daemons)
|
@classmethod
|
||||||
cls.http_threads.clear()
|
def addCoinSettings(cls, settings, datadir, node_id):
|
||||||
cls.swap_clients.clear()
|
settings["chainclients"]["namecoin"] = {
|
||||||
cls.daemons.clear()
|
"connection_type": "rpc",
|
||||||
|
"manage_daemon": False,
|
||||||
|
"rpcport": NMC_BASE_RPC_PORT + node_id,
|
||||||
|
"rpcuser": "test" + str(node_id),
|
||||||
|
"rpcpassword": "test_pass" + str(node_id),
|
||||||
|
"datadir": os.path.join(datadir, "nmc_" + str(node_id)),
|
||||||
|
"bindir": NAMECOIN_BINDIR,
|
||||||
|
"use_csv": True,
|
||||||
|
"use_segwit": True,
|
||||||
|
"blocks_confirmed": 1,
|
||||||
|
}
|
||||||
|
|
||||||
super(Test, cls).tearDownClass()
|
@classmethod
|
||||||
|
def prepareExtraCoins(cls):
|
||||||
def test_02_part_nmc(self):
|
ci0 = cls.swap_clients[0].ci(cls.test_coin)
|
||||||
logging.info("---------- Test PART to NMC")
|
if not cls.restore_instance:
|
||||||
swap_clients = self.swap_clients
|
cls.nmc_addr = ci0.rpc_wallet("getnewaddress", ["mining_addr", "bech32"])
|
||||||
|
else:
|
||||||
offer_id = swap_clients[0].postOffer(
|
addrs = ci0.rpc_wallet(
|
||||||
Coins.PART,
|
"getaddressesbylabel",
|
||||||
Coins.NMC,
|
[
|
||||||
100 * COIN,
|
"mining_addr",
|
||||||
0.1 * COIN,
|
],
|
||||||
100 * COIN,
|
|
||||||
SwapTypes.SELLER_FIRST
|
|
||||||
)
|
|
||||||
|
|
||||||
wait_for_offer(delay_event, swap_clients[1], offer_id)
|
|
||||||
offer = swap_clients[1].getOffer(offer_id)
|
|
||||||
bid_id = swap_clients[1].postBid(offer_id, offer.amount_from)
|
|
||||||
|
|
||||||
wait_for_bid(delay_event, swap_clients[0], bid_id)
|
|
||||||
|
|
||||||
swap_clients[0].acceptBid(bid_id)
|
|
||||||
|
|
||||||
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_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
|
|
||||||
|
|
||||||
def test_03_nmc_part(self):
|
|
||||||
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
|
|
||||||
)
|
|
||||||
|
|
||||||
wait_for_offer(delay_event, swap_clients[0], offer_id)
|
|
||||||
offer = swap_clients[0].getOffer(offer_id)
|
|
||||||
bid_id = swap_clients[0].postBid(offer_id, offer.amount_from)
|
|
||||||
|
|
||||||
wait_for_bid(delay_event, swap_clients[1], bid_id)
|
|
||||||
swap_clients[1].acceptBid(bid_id)
|
|
||||||
|
|
||||||
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
|
|
||||||
)
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
def test_04_nmc_btc(self):
|
|
||||||
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
|
|
||||||
)
|
|
||||||
|
|
||||||
wait_for_offer(delay_event, swap_clients[1], offer_id)
|
|
||||||
offer = swap_clients[1].getOffer(offer_id)
|
|
||||||
bid_id = swap_clients[1].postBid(offer_id, offer.amount_from)
|
|
||||||
|
|
||||||
wait_for_bid(delay_event, swap_clients[0], bid_id)
|
|
||||||
swap_clients[0].acceptBid(bid_id)
|
|
||||||
|
|
||||||
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_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
|
|
||||||
|
|
||||||
def test_05_refund(self):
|
|
||||||
# Seller submits initiate txn, buyer doesn't respond
|
|
||||||
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.SEQUENCE_LOCK_BLOCKS,
|
|
||||||
10,
|
|
||||||
)
|
|
||||||
|
|
||||||
wait_for_offer(delay_event, swap_clients[1], offer_id)
|
|
||||||
offer = swap_clients[1].getOffer(offer_id)
|
|
||||||
bid_id = swap_clients[1].postBid(offer_id, offer.amount_from)
|
|
||||||
|
|
||||||
wait_for_bid(delay_event, swap_clients[0], bid_id)
|
|
||||||
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,
|
|
||||||
)
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
def test_06_self_bid(self):
|
|
||||||
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
|
|
||||||
)
|
|
||||||
|
|
||||||
wait_for_offer(delay_event, swap_clients[0], offer_id)
|
|
||||||
offer = swap_clients[0].getOffer(offer_id)
|
|
||||||
bid_id = swap_clients[0].postBid(offer_id, offer.amount_from)
|
|
||||||
|
|
||||||
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
|
|
||||||
)
|
|
||||||
|
|
||||||
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
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_07_error(self):
|
|
||||||
logging.info("---------- Test error, BTC to NMC, set fee above bid value")
|
|
||||||
swap_clients = self.swap_clients
|
|
||||||
|
|
||||||
offer_id = swap_clients[0].postOffer(
|
|
||||||
Coins.NMC,
|
|
||||||
Coins.BTC,
|
|
||||||
0.01 * COIN,
|
|
||||||
1.0 * COIN,
|
|
||||||
0.01 * COIN,
|
|
||||||
SwapTypes.SELLER_FIRST
|
|
||||||
)
|
|
||||||
|
|
||||||
wait_for_offer(delay_event, swap_clients[0], offer_id)
|
|
||||||
offer = swap_clients[0].getOffer(offer_id)
|
|
||||||
bid_id = swap_clients[0].postBid(offer_id, offer.amount_from)
|
|
||||||
|
|
||||||
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"] = 100.0
|
|
||||||
swap_clients[0].getChainClientSettings(Coins.NMC)["override_feerate"] = 100.0
|
|
||||||
wait_for_bid(
|
|
||||||
delay_event, swap_clients[0], bid_id, BidStates.BID_ERROR, wait_for=60
|
|
||||||
)
|
)
|
||||||
swap_clients[0].abandonBid(bid_id)
|
cls.nmc_addr = addrs.keys()[0]
|
||||||
finally:
|
|
||||||
del swap_clients[0].getChainClientSettings(Coins.BTC)["override_feerate"]
|
|
||||||
del swap_clients[0].getChainClientSettings(Coins.NMC)["override_feerate"]
|
|
||||||
|
|
||||||
def pass_99_delay(self):
|
num_blocks: int = 500
|
||||||
global stop_test
|
if ci0.rpc("getblockcount") < num_blocks:
|
||||||
logging.info("Delay")
|
logging.info(f"Mining {num_blocks} Namecoin blocks to {cls.nmc_addr}")
|
||||||
for i in range(60 * 5):
|
ci0.rpc("generatetoaddress", [num_blocks, cls.nmc_addr])
|
||||||
if stop_test:
|
logging.info("NMC blocks: {}".format(ci0.rpc("getblockcount")))
|
||||||
break
|
|
||||||
time.sleep(1)
|
def test_007_hdwallet(self):
|
||||||
print("delay", i)
|
logging.info("---------- Test {} hdwallet".format(self.test_coin_from.name))
|
||||||
stop_test = True
|
|
||||||
|
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, False, False, "", False, USE_DESCRIPTOR_WALLETS],
|
||||||
|
)
|
||||||
|
self.callnoderpc("sethdseed", [True, test_wif], wallet=new_wallet_name)
|
||||||
|
addr = self.callnoderpc(
|
||||||
|
"getnewaddress", ["add test", "bech32"], wallet=new_wallet_name
|
||||||
|
)
|
||||||
|
self.callnoderpc("unloadwallet", [new_wallet_name])
|
||||||
|
assert addr == "ncrt1qps7hnjd866e9ynxadgseprkc2l56m00dxkl7pk"
|
||||||
|
|
||||||
|
def test_012_p2sh_p2wsh(self):
|
||||||
|
# Fee rate
|
||||||
|
pass
|
||||||
|
|
||||||
|
def test_02_sh_part_coin(self):
|
||||||
|
self.prepare_balance(self.test_coin, 200.0, 1801, 1800)
|
||||||
|
run_test_success_path(self, Coins.PART, self.test_coin)
|
||||||
|
|
||||||
|
def test_03_sh_coin_part(self):
|
||||||
|
run_test_success_path(self, self.test_coin, Coins.PART)
|
||||||
|
|
||||||
|
def test_04_sh_part_coin_bad_ptx(self):
|
||||||
|
self.prepare_balance(self.test_coin, 200.0, 1801, 1800)
|
||||||
|
run_test_bad_ptx(self, Coins.PART, self.test_coin)
|
||||||
|
|
||||||
|
def test_05_sh_coin_part_bad_ptx(self):
|
||||||
|
self.prepare_balance(self.test_coin, 200.0, 1801, 1800)
|
||||||
|
run_test_bad_ptx(self, self.test_coin, Coins.PART)
|
||||||
|
|
||||||
|
def test_06_sh_part_coin_itx_refund(self):
|
||||||
|
run_test_itx_refund(self, Coins.PART, self.test_coin)
|
||||||
|
|
||||||
|
def test_07_sh_coin_part_itx_refund(self):
|
||||||
|
self.prepare_balance(self.test_coin, 200.0, 1801, 1800)
|
||||||
|
run_test_itx_refund(self, self.test_coin, Coins.PART)
|
||||||
|
|
||||||
|
def test_01_b_full_swap_reverse(self):
|
||||||
|
self.prepare_balance(self.test_coin, 100.0, 1801, 1800)
|
||||||
|
self.do_test_01_full_swap(Coins.XMR, self.test_coin_from)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
|
@ -59,7 +59,6 @@ from basicswap.contrib.test_framework.script import (
|
||||||
from .test_xmr import BaseTest, test_delay_event, callnoderpc
|
from .test_xmr import BaseTest, test_delay_event, callnoderpc
|
||||||
|
|
||||||
logger = logging.getLogger()
|
logger = logging.getLogger()
|
||||||
|
|
||||||
test_seed = "8e54a313e6df8918df6d758fafdbf127a115175fdd2238d0e908dd8093c9ac3b"
|
test_seed = "8e54a313e6df8918df6d758fafdbf127a115175fdd2238d0e908dd8093c9ac3b"
|
||||||
|
|
||||||
|
|
||||||
|
@ -666,7 +665,7 @@ class TestFunctions(BaseTest):
|
||||||
balance_from_before: float = self.getBalance(jsw, coin_from)
|
balance_from_before: float = self.getBalance(jsw, coin_from)
|
||||||
self.prepare_balance(
|
self.prepare_balance(
|
||||||
coin_to,
|
coin_to,
|
||||||
balance_from_before + 1,
|
balance_from_before * 3,
|
||||||
1800 + id_bidder,
|
1800 + id_bidder,
|
||||||
1801 if coin_to in (Coins.XMR,) else 1800,
|
1801 if coin_to in (Coins.XMR,) else 1800,
|
||||||
)
|
)
|
||||||
|
@ -718,6 +717,7 @@ class TestFunctions(BaseTest):
|
||||||
assert False, "Should fail"
|
assert False, "Should fail"
|
||||||
|
|
||||||
amt_swap -= ci_from.make_int(1)
|
amt_swap -= ci_from.make_int(1)
|
||||||
|
rate_swap = ci_to.make_int(1.0, r=1)
|
||||||
offer_id = swap_clients[id_offerer].postOffer(
|
offer_id = swap_clients[id_offerer].postOffer(
|
||||||
coin_from,
|
coin_from,
|
||||||
coin_to,
|
coin_to,
|
||||||
|
@ -770,6 +770,8 @@ class TestFunctions(BaseTest):
|
||||||
|
|
||||||
class BasicSwapTest(TestFunctions):
|
class BasicSwapTest(TestFunctions):
|
||||||
|
|
||||||
|
test_fee_rate: int = 1000 # sats/kvB
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def setUpClass(cls):
|
def setUpClass(cls):
|
||||||
super(BasicSwapTest, cls).setUpClass()
|
super(BasicSwapTest, cls).setUpClass()
|
||||||
|
@ -1236,12 +1238,7 @@ class BasicSwapTest(TestFunctions):
|
||||||
swap_client = self.swap_clients[0]
|
swap_client = self.swap_clients[0]
|
||||||
ci = swap_client.ci(self.test_coin_from)
|
ci = swap_client.ci(self.test_coin_from)
|
||||||
|
|
||||||
addr_1 = ci.rpc_wallet(
|
addr_1 = ci.getNewAddress(True, "gettxout test 1")
|
||||||
"getnewaddress",
|
|
||||||
[
|
|
||||||
"gettxout test 1",
|
|
||||||
],
|
|
||||||
)
|
|
||||||
txid = ci.rpc_wallet("sendtoaddress", [addr_1, 1.0])
|
txid = ci.rpc_wallet("sendtoaddress", [addr_1, 1.0])
|
||||||
assert len(txid) == 64
|
assert len(txid) == 64
|
||||||
|
|
||||||
|
@ -1266,12 +1263,7 @@ class BasicSwapTest(TestFunctions):
|
||||||
else:
|
else:
|
||||||
assert addr_1 in txout["scriptPubKey"]["addresses"]
|
assert addr_1 in txout["scriptPubKey"]["addresses"]
|
||||||
# Spend
|
# Spend
|
||||||
addr_2 = ci.rpc_wallet(
|
addr_2 = ci.getNewAddress(True, "gettxout test 2")
|
||||||
"getnewaddress",
|
|
||||||
[
|
|
||||||
"gettxout test 2",
|
|
||||||
],
|
|
||||||
)
|
|
||||||
tx_funded = ci.rpc(
|
tx_funded = ci.rpc(
|
||||||
"createrawtransaction",
|
"createrawtransaction",
|
||||||
[[{"txid": utxo["txid"], "vout": utxo["vout"]}], {addr_2: 0.99}],
|
[[{"txid": utxo["txid"], "vout": utxo["vout"]}], {addr_2: 0.99}],
|
||||||
|
@ -1297,12 +1289,7 @@ class BasicSwapTest(TestFunctions):
|
||||||
logging.info("---------- Test {} scantxoutset".format(self.test_coin_from.name))
|
logging.info("---------- Test {} scantxoutset".format(self.test_coin_from.name))
|
||||||
ci = self.swap_clients[0].ci(self.test_coin_from)
|
ci = self.swap_clients[0].ci(self.test_coin_from)
|
||||||
|
|
||||||
addr_1 = ci.rpc_wallet(
|
addr_1 = ci.getNewAddress(True, "scantxoutset test")
|
||||||
"getnewaddress",
|
|
||||||
[
|
|
||||||
"scantxoutset test",
|
|
||||||
],
|
|
||||||
)
|
|
||||||
txid = ci.rpc_wallet("sendtoaddress", [addr_1, 1.0])
|
txid = ci.rpc_wallet("sendtoaddress", [addr_1, 1.0])
|
||||||
assert len(txid) == 64
|
assert len(txid) == 64
|
||||||
|
|
||||||
|
@ -1324,9 +1311,6 @@ class BasicSwapTest(TestFunctions):
|
||||||
# Record unspents before createSCLockTx as the used ones will be locked
|
# Record unspents before createSCLockTx as the used ones will be locked
|
||||||
unspents = ci.rpc_wallet("listunspent")
|
unspents = ci.rpc_wallet("listunspent")
|
||||||
|
|
||||||
# fee_rate is in sats/kvB
|
|
||||||
fee_rate: int = 1000
|
|
||||||
|
|
||||||
a = ci.getNewRandomKey()
|
a = ci.getNewRandomKey()
|
||||||
b = ci.getNewRandomKey()
|
b = ci.getNewRandomKey()
|
||||||
|
|
||||||
|
@ -1335,7 +1319,7 @@ class BasicSwapTest(TestFunctions):
|
||||||
lock_tx_script = pi.genScriptLockTxScript(ci, A, B)
|
lock_tx_script = pi.genScriptLockTxScript(ci, A, B)
|
||||||
|
|
||||||
lock_tx = ci.createSCLockTx(amount, lock_tx_script)
|
lock_tx = ci.createSCLockTx(amount, lock_tx_script)
|
||||||
lock_tx = ci.fundSCLockTx(lock_tx, fee_rate)
|
lock_tx = ci.fundSCLockTx(lock_tx, self.test_fee_rate)
|
||||||
lock_tx = ci.signTxWithWallet(lock_tx)
|
lock_tx = ci.signTxWithWallet(lock_tx)
|
||||||
|
|
||||||
unspents_after = ci.rpc_wallet("listunspent")
|
unspents_after = ci.rpc_wallet("listunspent")
|
||||||
|
@ -1345,7 +1329,7 @@ class BasicSwapTest(TestFunctions):
|
||||||
txid = tx_decoded["txid"]
|
txid = tx_decoded["txid"]
|
||||||
|
|
||||||
vsize = tx_decoded["vsize"]
|
vsize = tx_decoded["vsize"]
|
||||||
expect_fee_int = round(fee_rate * vsize / 1000)
|
expect_fee_int = round(self.test_fee_rate * vsize / 1000)
|
||||||
|
|
||||||
out_value: int = 0
|
out_value: int = 0
|
||||||
for txo in tx_decoded["vout"]:
|
for txo in tx_decoded["vout"]:
|
||||||
|
@ -1372,7 +1356,7 @@ class BasicSwapTest(TestFunctions):
|
||||||
pkh_out = ci.decodeAddress(addr_out)
|
pkh_out = ci.decodeAddress(addr_out)
|
||||||
fee_info = {}
|
fee_info = {}
|
||||||
lock_spend_tx = ci.createSCLockSpendTx(
|
lock_spend_tx = ci.createSCLockSpendTx(
|
||||||
lock_tx, lock_tx_script, pkh_out, fee_rate, fee_info=fee_info
|
lock_tx, lock_tx_script, pkh_out, self.test_fee_rate, fee_info=fee_info
|
||||||
)
|
)
|
||||||
vsize_estimated: int = fee_info["vsize"]
|
vsize_estimated: int = fee_info["vsize"]
|
||||||
|
|
||||||
|
@ -1400,11 +1384,11 @@ class BasicSwapTest(TestFunctions):
|
||||||
v = ci.getNewRandomKey()
|
v = ci.getNewRandomKey()
|
||||||
s = ci.getNewRandomKey()
|
s = ci.getNewRandomKey()
|
||||||
S = ci.getPubkey(s)
|
S = ci.getPubkey(s)
|
||||||
lock_tx_b_txid = ci.publishBLockTx(v, S, amount, fee_rate)
|
lock_tx_b_txid = ci.publishBLockTx(v, S, amount, self.test_fee_rate)
|
||||||
|
|
||||||
addr_out = ci.getNewAddress(True)
|
addr_out = ci.getNewAddress(True)
|
||||||
lock_tx_b_spend_txid = ci.spendBLockTx(
|
lock_tx_b_spend_txid = ci.spendBLockTx(
|
||||||
lock_tx_b_txid, addr_out, v, s, amount, fee_rate, 0
|
lock_tx_b_txid, addr_out, v, s, amount, self.test_fee_rate, 0
|
||||||
)
|
)
|
||||||
lock_tx_b_spend = ci.getTransaction(lock_tx_b_spend_txid)
|
lock_tx_b_spend = ci.getTransaction(lock_tx_b_spend_txid)
|
||||||
if lock_tx_b_spend is None:
|
if lock_tx_b_spend is None:
|
||||||
|
@ -1635,7 +1619,9 @@ class BasicSwapTest(TestFunctions):
|
||||||
wallet=new_wallet_name,
|
wallet=new_wallet_name,
|
||||||
)
|
)
|
||||||
|
|
||||||
addr = self.callnoderpc("getnewaddress", wallet=new_wallet_name)
|
addr = self.callnoderpc(
|
||||||
|
"getnewaddress", ["test descriptors"], wallet=new_wallet_name
|
||||||
|
)
|
||||||
addr_info = self.callnoderpc(
|
addr_info = self.callnoderpc(
|
||||||
"getaddressinfo",
|
"getaddressinfo",
|
||||||
[
|
[
|
||||||
|
@ -1645,7 +1631,8 @@ class BasicSwapTest(TestFunctions):
|
||||||
)
|
)
|
||||||
assert addr_info["hdmasterfingerprint"] == "a55b7ea9"
|
assert addr_info["hdmasterfingerprint"] == "a55b7ea9"
|
||||||
assert addr_info["hdkeypath"] == "m/0h/0h/0h"
|
assert addr_info["hdkeypath"] == "m/0h/0h/0h"
|
||||||
assert addr == "bcrt1qps7hnjd866e9ynxadgseprkc2l56m00dvwargr"
|
if self.test_coin_from == Coins.BTC:
|
||||||
|
assert addr == "bcrt1qps7hnjd866e9ynxadgseprkc2l56m00dvwargr"
|
||||||
|
|
||||||
addr_change = self.callnoderpc("getrawchangeaddress", wallet=new_wallet_name)
|
addr_change = self.callnoderpc("getrawchangeaddress", wallet=new_wallet_name)
|
||||||
addr_info = self.callnoderpc(
|
addr_info = self.callnoderpc(
|
||||||
|
@ -1657,7 +1644,8 @@ class BasicSwapTest(TestFunctions):
|
||||||
)
|
)
|
||||||
assert addr_info["hdmasterfingerprint"] == "a55b7ea9"
|
assert addr_info["hdmasterfingerprint"] == "a55b7ea9"
|
||||||
assert addr_info["hdkeypath"] == "m/0h/1h/0h"
|
assert addr_info["hdkeypath"] == "m/0h/1h/0h"
|
||||||
assert addr_change == "bcrt1qdl9ryxkqjltv42lhfnqgdjf9tagxsjpp2xak9a"
|
if self.test_coin_from == Coins.BTC:
|
||||||
|
assert addr_change == "bcrt1qdl9ryxkqjltv42lhfnqgdjf9tagxsjpp2xak9a"
|
||||||
|
|
||||||
desc_watch = descsum_create(f"addr({addr})")
|
desc_watch = descsum_create(f"addr({addr})")
|
||||||
self.callnoderpc(
|
self.callnoderpc(
|
||||||
|
@ -1683,7 +1671,13 @@ class BasicSwapTest(TestFunctions):
|
||||||
|
|
||||||
# Test that addresses can be generated beyond range in listdescriptors
|
# Test that addresses can be generated beyond range in listdescriptors
|
||||||
for i in range(2000):
|
for i in range(2000):
|
||||||
self.callnoderpc("getnewaddress", wallet=new_wallet_name)
|
self.callnoderpc(
|
||||||
|
"getnewaddress",
|
||||||
|
[
|
||||||
|
f"t{i}",
|
||||||
|
],
|
||||||
|
wallet=new_wallet_name,
|
||||||
|
)
|
||||||
|
|
||||||
self.callnoderpc("unloadwallet", [new_wallet_name])
|
self.callnoderpc("unloadwallet", [new_wallet_name])
|
||||||
self.callnoderpc("unloadwallet", [new_watch_wallet_name])
|
self.callnoderpc("unloadwallet", [new_watch_wallet_name])
|
||||||
|
|
Loading…
Reference in a new issue