tests: Fix NMC tests.

This commit is contained in:
tecnovert 2022-07-04 22:29:49 +02:00
parent 02bd90053a
commit 0580f9ebac
No known key found for this signature in database
GPG key ID: 8ED6D8750C4E3F93
7 changed files with 66 additions and 38 deletions

View file

@ -1942,7 +1942,7 @@ class BasicSwap(BaseApp):
refund_txn = self.createRefundTxn(coin_from, txn, offer, bid, script) refund_txn = self.createRefundTxn(coin_from, txn, offer, bid, script)
bid.initiate_txn_refund = bytes.fromhex(refund_txn) bid.initiate_txn_refund = bytes.fromhex(refund_txn)
txid = self.submitTxn(coin_from, txn) txid = ci_from.publishTx(bytes.fromhex(txn))
self.log.debug('Submitted initiate txn %s to %s chain for bid %s', txid, ci_from.coin_name(), bid_id.hex()) self.log.debug('Submitted initiate txn %s to %s chain for bid %s', txid, ci_from.coin_name(), bid_id.hex())
bid.initiate_tx = SwapTx( bid.initiate_tx = SwapTx(
bid_id=bid_id, bid_id=bid_id,
@ -1955,7 +1955,7 @@ class BasicSwap(BaseApp):
# Check non-bip68 final # Check non-bip68 final
try: try:
txid = self.submitTxn(coin_from, bid.initiate_txn_refund.hex()) txid = ci_from.publishTx(bid.initiate_txn_refund)
self.log.error('Submit refund_txn unexpectedly worked: ' + txid) self.log.error('Submit refund_txn unexpectedly worked: ' + txid)
except Exception as ex: except Exception as ex:
if 'non-BIP68-final' not in str(ex) and 'non-final' not in str(ex): if 'non-BIP68-final' not in str(ex) and 'non-final' not in str(ex):
@ -2664,14 +2664,6 @@ class BasicSwap(BaseApp):
return refund_txn return refund_txn
def submitTxn(self, coin_type, txn):
# self.log.debug('submitTxn %s', str(coin_type))
if txn is None:
return None
if self.coin_clients[coin_type]['connection_type'] != 'rpc':
return None
return self.callcoinrpc(coin_type, 'sendrawtransaction', [txn])
def initiateTxnConfirmed(self, bid_id, bid, offer): def initiateTxnConfirmed(self, bid_id, bid, offer):
self.log.debug('initiateTxnConfirmed for bid %s', bid_id.hex()) self.log.debug('initiateTxnConfirmed for bid %s', bid_id.hex())
bid.setState(BidStates.SWAP_INITIATED) bid.setState(BidStates.SWAP_INITIATED)
@ -2693,7 +2685,7 @@ class BasicSwap(BaseApp):
coin_to = Coins(offer.coin_to) coin_to = Coins(offer.coin_to)
txn = self.createParticipateTxn(bid_id, bid, offer, participate_script) txn = self.createParticipateTxn(bid_id, bid, offer, participate_script)
txid = self.submitTxn(coin_to, txn) txid = self.ci(coin_to).publishTx(bytes.fromhex(txn))
self.log.debug('Submitted participate txn %s to %s chain for bid %s', txid, chainparams[coin_to]['name'], bid_id.hex()) self.log.debug('Submitted participate txn %s to %s chain for bid %s', txid, chainparams[coin_to]['name'], bid_id.hex())
bid.setPTxState(TxStates.TX_SENT) bid.setPTxState(TxStates.TX_SENT)
else: else:
@ -2745,10 +2737,10 @@ class BasicSwap(BaseApp):
# Seller redeems from participate txn # Seller redeems from participate txn
if bid.was_received: if bid.was_received:
coin_to = Coins(offer.coin_to) ci_to = self.ci(offer.coin_to)
txn = self.createRedeemTxn(coin_to, bid) txn = self.createRedeemTxn(ci_to.coin_type(), bid)
txid = self.submitTxn(coin_to, txn) txid = ci_to.publishTx(bytes.fromhex(txn))
self.log.debug('Submitted participate redeem txn %s to %s chain for bid %s', txid, chainparams[coin_to]['name'], bid_id.hex()) self.log.debug('Submitted participate redeem txn %s to %s chain for bid %s', txid, ci_to.coin_name(), bid_id.hex())
# TX_REDEEMED will be set when spend is detected # TX_REDEEMED will be set when spend is detected
# TODO: Wait for depth? # TODO: Wait for depth?
@ -3230,7 +3222,7 @@ class BasicSwap(BaseApp):
if (bid.getITxState() == TxStates.TX_SENT or bid.getITxState() == TxStates.TX_CONFIRMED) \ if (bid.getITxState() == TxStates.TX_SENT or bid.getITxState() == TxStates.TX_CONFIRMED) \
and bid.initiate_txn_refund is not None: and bid.initiate_txn_refund is not None:
try: try:
txid = self.submitTxn(coin_from, bid.initiate_txn_refund.hex()) txid = ci_from.publishTx(bid.initiate_txn_refund)
self.log.debug('Submitted initiate refund txn %s to %s chain for bid %s', txid, chainparams[coin_from]['name'], bid_id.hex()) self.log.debug('Submitted initiate refund txn %s to %s chain for bid %s', txid, chainparams[coin_from]['name'], bid_id.hex())
# State will update when spend is detected # State will update when spend is detected
except Exception as ex: except Exception as ex:
@ -3240,7 +3232,7 @@ class BasicSwap(BaseApp):
if (bid.getPTxState() == TxStates.TX_SENT or bid.getPTxState() == TxStates.TX_CONFIRMED) \ if (bid.getPTxState() == TxStates.TX_SENT or bid.getPTxState() == TxStates.TX_CONFIRMED) \
and bid.participate_txn_refund is not None: and bid.participate_txn_refund is not None:
try: try:
txid = self.submitTxn(coin_to, bid.participate_txn_refund.hex()) txid = ci_to.publishTx(bid.participate_txn_refund)
self.log.debug('Submitted participate refund txn %s to %s chain for bid %s', txid, chainparams[coin_to]['name'], bid_id.hex()) self.log.debug('Submitted participate refund txn %s to %s chain for bid %s', txid, chainparams[coin_to]['name'], bid_id.hex())
# State will update when spend is detected # State will update when spend is detected
except Exception as ex: except Exception as ex:

View file

@ -988,7 +988,7 @@ class BTCInterface(CoinInterface):
if not addr_info['iswatchonly']: if not addr_info['iswatchonly']:
ro = self.rpc_callback('importaddress', [dest_address, 'bid', False]) ro = self.rpc_callback('importaddress', [dest_address, 'bid', False])
self._log.info('Imported watch-only addr: {}'.format(dest_address)) self._log.info('Imported watch-only addr: {}'.format(dest_address))
self._log.info('Rescanning chain from height: {}'.format(rescan_from)) self._log.info('Rescanning {} chain from height: {}'.format(self.coin_name(), rescan_from))
self.rpc_callback('rescanblockchain', [rescan_from]) self.rpc_callback('rescanblockchain', [rescan_from])
return_txid = True if txid is None else False return_txid = True if txid is None else False

View file

@ -1,12 +1,15 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (c) 2020-2021 tecnovert # Copyright (c) 2020-2022 tecnovert
# 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.
from .interface_btc import BTCInterface from .interface_btc import BTCInterface
from .chainparams import Coins from .chainparams import Coins
from .util import (
make_int,
)
class NMCInterface(BTCInterface): class NMCInterface(BTCInterface):
@ -15,4 +18,25 @@ class NMCInterface(BTCInterface):
return Coins.NMC return Coins.NMC
def getLockTxHeight(self, txid, dest_address, bid_amount, rescan_from, find_index=False): def getLockTxHeight(self, txid, dest_address, bid_amount, rescan_from, find_index=False):
raise ValueError('TODO: Use scantxoutset') self._log.debug('[rm] scantxoutset start') # scantxoutset is slow
ro = self.rpc_callback('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 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']}
if o['height'] > 0:
rv['depth'] = ro['height'] - o['height']
if find_index:
rv['index'] = o['vout']
if return_txid:
rv['txid'] = o['txid']
return rv

View file

@ -667,7 +667,7 @@ class PARTInterfaceAnon(PARTInterface):
wif_scan_key = toWIF(wif_prefix, kbv) wif_scan_key = toWIF(wif_prefix, kbv)
self.rpc_callback('importstealthaddress', [wif_scan_key, Kbs.hex()]) self.rpc_callback('importstealthaddress', [wif_scan_key, Kbs.hex()])
self._log.info('Imported watch-only sx_addr: {}'.format(sx_addr)) self._log.info('Imported watch-only sx_addr: {}'.format(sx_addr))
self._log.info('Rescanning chain from height: {}'.format(restore_height)) self._log.info('Rescanning {} chain from height: {}'.format(self.coin_name(), restore_height))
self.rpc_callback('rescanblockchain', [restore_height]) self.rpc_callback('rescanblockchain', [restore_height])
params = [{'include_watchonly': True, 'search': sx_addr}] params = [{'include_watchonly': True, 'search': sx_addr}]
@ -700,7 +700,7 @@ class PARTInterfaceAnon(PARTInterface):
wif_spend_key = toWIF(wif_prefix, kbs) wif_spend_key = toWIF(wif_prefix, kbs)
self.rpc_callback('importstealthaddress', [wif_scan_key, wif_spend_key]) self.rpc_callback('importstealthaddress', [wif_scan_key, wif_spend_key])
self._log.info('Imported spend key for sx_addr: {}'.format(sx_addr)) self._log.info('Imported spend key for sx_addr: {}'.format(sx_addr))
self._log.info('Rescanning chain from height: {}'.format(restore_height)) self._log.info('Rescanning {} chain from height: {}'.format(self.coin_name(), restore_height))
self.rpc_callback('rescanblockchain', [restore_height]) self.rpc_callback('rescanblockchain', [restore_height])
autxos = self.rpc_callback('listunspentanon', [1, 9999999, [sx_addr]]) autxos = self.rpc_callback('listunspentanon', [1, 9999999, [sx_addr]])

View file

@ -54,7 +54,7 @@ def redeemITx(self, bid_id, session):
ci_from = self.ci(offer.coin_from) ci_from = self.ci(offer.coin_from)
txn = self.createRedeemTxn(ci_from.coin_type(), bid, for_txn_type='initiate') txn = self.createRedeemTxn(ci_from.coin_type(), bid, for_txn_type='initiate')
txid = self.submitTxn(ci_from.coin_type(), txn) txid = ci_from.publishTx(bytes.fromhex(txn))
bid.initiate_tx.spend_txid = bytes.fromhex(txid) bid.initiate_tx.spend_txid = bytes.fromhex(txid)
self.log.debug('Submitted initiate redeem txn %s to %s chain for bid %s', txid, ci_from.coin_name(), bid_id.hex()) self.log.debug('Submitted initiate redeem txn %s to %s chain for bid %s', txid, ci_from.coin_name(), bid_id.hex())

View file

@ -27,12 +27,13 @@ from basicswap.basicswap import (
SwapTypes, SwapTypes,
BidStates, BidStates,
TxStates, TxStates,
ABS_LOCK_BLOCKS,
ABS_LOCK_TIME,
) )
from basicswap.util import ( from basicswap.util import (
COIN, COIN,
) )
from basicswap.basicswap_util import (
TxLockTypes,
)
from basicswap.util.address import ( from basicswap.util.address import (
toWIF, toWIF,
) )
@ -99,8 +100,12 @@ def prepareOtherDir(datadir, nodeId, conf_file='namecoin.conf'):
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('acceptnonstdtxn=0\n') fp.write('acceptnonstdtxn=0\n')
if conf_file == 'bitcoin.conf':
fp.write('wallet=wallet.dat\n')
def prepareDir(datadir, nodeId, network_key, network_pubkey): def prepareDir(datadir, nodeId, network_key, network_pubkey):
node_dir = os.path.join(datadir, str(nodeId)) node_dir = os.path.join(datadir, str(nodeId))
@ -124,6 +129,8 @@ def prepareDir(datadir, nodeId, network_key, network_pubkey):
fp.write('debug=1\n') fp.write('debug=1\n')
fp.write('debugexclude=libevent\n') fp.write('debugexclude=libevent\n')
fp.write('zmqpubsmsg=tcp://127.0.0.1:' + str(BASE_ZMQ_PORT + nodeId) + '\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('acceptnonstdtxn=0\n')
fp.write('minstakeinterval=5\n') fp.write('minstakeinterval=5\n')
@ -262,13 +269,19 @@ class Test(unittest.TestCase):
cls.swap_clients = [] cls.swap_clients = []
cls.http_threads = [] cls.http_threads = []
cls.daemons.append(startDaemon(os.path.join(cfg.TEST_DATADIRS, str(BTC_NODE)), cfg.BITCOIN_BINDIR, cfg.BITCOIND)) 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 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].pid) logging.info('Started %s %d', cfg.BITCOIND, cls.daemons[-1].pid)
cls.daemons.append(startDaemon(os.path.join(cfg.TEST_DATADIRS, str(NMC_NODE)), cfg.NAMECOIN_BINDIR, cfg.NAMECOIND)) 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].pid) logging.info('Started %s %d', cfg.NAMECOIND, cls.daemons[-1].pid)
for i in range(NUM_NODES): for i in range(NUM_NODES):
cls.daemons.append(startDaemon(os.path.join(cfg.TEST_DATADIRS, str(i)), cfg.PARTICL_BINDIR, cfg.PARTICLD)) 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 create', 'particl-wallet')
cls.daemons.append(startDaemon(data_dir, cfg.PARTICL_BINDIR, cfg.PARTICLD))
logging.info('Started %s %d', cfg.PARTICLD, cls.daemons[-1].pid) logging.info('Started %s %d', cfg.PARTICLD, cls.daemons[-1].pid)
for i in range(NUM_NODES): for i in range(NUM_NODES):
@ -361,11 +374,11 @@ class Test(unittest.TestCase):
super(Test, cls).tearDownClass() super(Test, cls).tearDownClass()
def test_02_part_ltc(self): def test_02_part_nmc(self):
logging.info('---------- Test PART to NMC') logging.info('---------- Test PART to NMC')
swap_clients = self.swap_clients 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, 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) wait_for_offer(delay_event, swap_clients[1], offer_id)
offers = swap_clients[1].listOffers() offers = swap_clients[1].listOffers()
@ -392,7 +405,7 @@ class Test(unittest.TestCase):
logging.info('---------- Test NMC to PART') logging.info('---------- Test NMC to PART')
swap_clients = self.swap_clients 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, 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) wait_for_offer(delay_event, swap_clients[0], offer_id)
offers = swap_clients[0].listOffers() offers = swap_clients[0].listOffers()
@ -417,7 +430,7 @@ class Test(unittest.TestCase):
logging.info('---------- Test NMC to BTC') logging.info('---------- Test NMC to BTC')
swap_clients = self.swap_clients 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, 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) wait_for_offer(delay_event, swap_clients[1], offer_id)
offers = swap_clients[1].listOffers() offers = swap_clients[1].listOffers()
@ -447,7 +460,7 @@ class Test(unittest.TestCase):
swap_clients = self.swap_clients 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, offer_id = swap_clients[0].postOffer(Coins.NMC, Coins.BTC, 10 * COIN, 0.1 * COIN, 10 * COIN, SwapTypes.SELLER_FIRST,
ABS_LOCK_BLOCKS, 10) TxLockTypes.ABS_LOCK_BLOCKS, 10)
wait_for_offer(delay_event, swap_clients[1], offer_id) wait_for_offer(delay_event, swap_clients[1], offer_id)
offers = swap_clients[1].listOffers() offers = swap_clients[1].listOffers()
@ -473,7 +486,7 @@ class Test(unittest.TestCase):
js_0_before = read_json_api(1800) 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, 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) wait_for_offer(delay_event, swap_clients[0], offer_id)
offers = swap_clients[0].listOffers() offers = swap_clients[0].listOffers()
@ -497,7 +510,7 @@ class Test(unittest.TestCase):
js_0_before = read_json_api(1800) 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, 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) wait_for_offer(delay_event, swap_clients[0], offer_id)
offers = swap_clients[0].listOffers() offers = swap_clients[0].listOffers()
@ -507,9 +520,8 @@ class Test(unittest.TestCase):
wait_for_bid(delay_event, swap_clients[0], bid_id) wait_for_bid(delay_event, swap_clients[0], bid_id)
swap_clients[0].acceptBid(bid_id) swap_clients[0].acceptBid(bid_id)
swap_clients[0].coin_clients[Coins.BTC]['override_feerate'] = 10.0 swap_clients[0].getChainClientSettings(Coins.BTC)['override_feerate'] = 10.0
swap_clients[0].coin_clients[Coins.NMC]['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) wait_for_bid(delay_event, swap_clients[0], bid_id, BidStates.BID_ERROR, wait_for=60)
def pass_99_delay(self): def pass_99_delay(self):

View file

@ -22,6 +22,6 @@ commands =
[pytest] [pytest]
addopts = -v -s addopts = -v -s
norecursedirs = tests/basicswap/extended norecursedirs = tests/basicswap/extended tests/basicswap/selenium
testpaths = testpaths =
tests tests