Browse Source

Increase version, add test for bids sent while recipient is offline.

pivx
tecnovert 3 years ago
parent
commit
60b477e3c0
No known key found for this signature in database GPG Key ID: 8ED6D8750C4E3F93
  1. 1
      .travis.yml
  2. 2
      basicswap/__init__.py
  3. 241
      basicswap/basicswap.py
  4. 2
      basicswap/db.py
  5. 2
      basicswap/http_server.py
  6. 2
      basicswap/interface_btc.py
  7. 2
      basicswap/interface_part.py
  8. 4
      basicswap/interface_xmr.py
  9. 12
      basicswap/js_server.py
  10. 30
      bin/basicswap_prepare.py
  11. 2
      tests/basicswap/common.py
  12. 8
      tests/basicswap/extended/test_network.py
  13. 26
      tests/basicswap/extended/test_nmc.py
  14. 0
      tests/basicswap/extended/test_prepare.py
  15. 14
      tests/basicswap/extended/test_wallet_init.py
  16. 37
      tests/basicswap/test_reload.py
  17. 137
      tests/basicswap/test_reload_xmr.py
  18. 30
      tests/basicswap/test_run.py
  19. 20
      tests/basicswap/test_xmr.py
  20. 2
      tox.ini

1
.travis.yml

@ -29,6 +29,7 @@ before_script:
- python3 setup.py install --force
script:
- cd $TRAVIS_BUILD_DIR
- python3 setup.py install
- basicswap-prepare --bindir=${BIN_DIRS} --preparebinonly --withcoins=particl,bitcoin,litecoin,monero
- export DATADIRS="${TEST_DIR}"
- mkdir -p "${DATADIRS}/bin"

2
basicswap/__init__.py

@ -1,3 +1,3 @@
name = "basicswap"
__version__ = "0.0.9"
__version__ = "0.0.10"

241
basicswap/basicswap.py

@ -440,12 +440,7 @@ class BasicSwap(BaseApp):
self.swaps_in_progress = dict()
if self.chain == 'regtest':
self.SMSG_SECONDS_IN_DAY = 600
self.SMSG_SECONDS_IN_HOUR = 60 * 2
else:
self.SMSG_SECONDS_IN_DAY = 86400
self.SMSG_SECONDS_IN_HOUR = 60 * 60
self.SMSG_SECONDS_IN_HOUR = 60 * 2 if self.chain == 'regtest' else 60 * 60
# Encode key to match network
wif_prefix = chainparams[Coins.PART][self.chain]['key_prefix']
@ -579,7 +574,7 @@ class BasicSwap(BaseApp):
if self.coin_clients[coin]['connection_type'] == 'rpc':
if coin == Coins.XMR:
self.coin_clients[coin]['walletrpchost'] = chain_client_settings.get('walletrpchost', 'localhost')
self.coin_clients[coin]['walletrpchost'] = chain_client_settings.get('walletrpchost', '127.0.0.1')
self.coin_clients[coin]['walletrpcport'] = chain_client_settings.get('walletrpcport', chainparams[coin][self.chain]['walletrpcport'])
if 'walletrpcpassword' in chain_client_settings:
self.coin_clients[coin]['walletrpcauth'] = (chain_client_settings['walletrpcuser'], chain_client_settings['walletrpcpassword'])
@ -803,9 +798,9 @@ class BasicSwap(BaseApp):
kv.value = int_val
session.add(kv)
session.commit()
finally:
session.close()
session.remove()
finally:
self.mxDB.release()
def setStringKV(self, str_key, str_val):
@ -819,9 +814,9 @@ class BasicSwap(BaseApp):
kv.value = str_val
session.add(kv)
session.commit()
finally:
session.close()
session.remove()
finally:
self.mxDB.release()
def getStringKV(self, str_key):
@ -963,12 +958,15 @@ class BasicSwap(BaseApp):
self.loadFromDB()
# Scan inbox
options = {'encoding': 'hex'}
# TODO: Redundant? small window for zmq messages to go unnoticed during startup?
# options = {'encoding': 'hex'}
options = {'encoding': 'none'}
ro = self.callrpc('smsginbox', ['unread', '', options])
nm = 0
for msg in ro['messages']:
msg['hex'] += '00' # Add nullbtye to match output from 'smsg' cmd - TODO: make consistent
self.processMsg(msg)
# TODO: Remove workaround for smsginbox bug
get_msg = self.callrpc('smsg', [msg['msgid'], {'encoding': 'hex', 'setread': True}])
self.processMsg(get_msg)
nm += 1
self.log.info('Scanned %d unread messages.', nm)
@ -1024,6 +1022,7 @@ class BasicSwap(BaseApp):
self.validateOfferLockValue(coin_from_t, coin_to_t, lock_type, lock_value)
self.mxDB.acquire()
session = None
try:
self.checkSynced(coin_from_t, coin_to_t)
# TODO: require proof of funds on offers?
@ -1123,9 +1122,11 @@ class BasicSwap(BaseApp):
if addr_send_from is None:
session.add(SmsgAddress(addr=offer_addr, use_type=MessageTypes.OFFER))
session.commit()
session.close()
session.remove()
finally:
if session:
session.close()
session.remove()
self.mxDB.release()
self.log.info('Sent OFFER %s', offer_id.hex())
return offer_id
@ -1262,9 +1263,9 @@ class BasicSwap(BaseApp):
addr = record.addr
session.add(record)
session.commit()
finally:
session.close()
session.remove()
finally:
self.mxDB.release()
return addr
@ -1280,9 +1281,9 @@ class BasicSwap(BaseApp):
session.commit()
except Exception as ex:
pass
finally:
session.close()
session.remove()
finally:
self.mxDB.release()
def getReceiveAddressForCoin(self, coin_type):
@ -1380,9 +1381,9 @@ class BasicSwap(BaseApp):
value=addr
))
session.commit()
finally:
session.close()
session.remove()
finally:
self.mxDB.release()
return addr
@ -1391,11 +1392,11 @@ class BasicSwap(BaseApp):
try:
self._contract_count += 1
session = scoped_session(self.session_factory)
self.engine.execute('UPDATE kv_int SET value = {} WHERE KEY="contract_count"'.format(self._contract_count))
session.execute('UPDATE kv_int SET value = {} WHERE KEY="contract_count"'.format(self._contract_count))
session.commit()
finally:
session.close()
session.remove()
finally:
self.mxDB.release()
return self._contract_count
@ -1458,9 +1459,9 @@ class BasicSwap(BaseApp):
session = scoped_session(self.session_factory)
self.saveBidInSession(bid_id, bid, session, xmr_swap)
session.commit()
finally:
session.close()
session.remove()
finally:
self.mxDB.release()
def saveToDB(self, db_record):
@ -1469,9 +1470,9 @@ class BasicSwap(BaseApp):
session = scoped_session(self.session_factory)
session.add(db_record)
session.commit()
finally:
session.close()
session.remove()
finally:
self.mxDB.release()
def createEventInSession(self, delay, event_type, linked_id, session):
@ -1492,9 +1493,9 @@ class BasicSwap(BaseApp):
session = scoped_session(self.session_factory)
self.createEventInSession(delay, event_type, linked_id, session)
session.commit()
finally:
session.close()
session.remove()
finally:
self.mxDB.release()
def logBidEvent(self, bid, event_type, event_msg, session):
@ -1577,13 +1578,15 @@ class BasicSwap(BaseApp):
)
bid.setState(BidStates.BID_SENT)
session = scoped_session(self.session_factory)
self.saveBidInSession(bid_id, bid, session)
if addr_send_from is None:
session.add(SmsgAddress(addr=bid_addr, use_type=MessageTypes.BID))
session.commit()
session.close()
session.remove()
try:
session = scoped_session(self.session_factory)
self.saveBidInSession(bid_id, bid, session)
if addr_send_from is None:
session.add(SmsgAddress(addr=bid_addr, use_type=MessageTypes.BID))
session.commit()
finally:
session.close()
session.remove()
self.log.info('Sent BID %s', bid_id.hex())
return bid_id
@ -1712,17 +1715,16 @@ class BasicSwap(BaseApp):
self.mxDB.release()
def list_bid_events(self, bid_id, session):
session = scoped_session(self.session_factory)
query_str = 'SELECT created_at, event_type, event_msg FROM eventlog ' + \
'WHERE active_ind = 1 AND linked_type = {} AND linked_id = x\'{}\' '.format(TableTypes.BID, bid_id.hex())
q = self.engine.execute(query_str)
q = session.execute(query_str)
events = []
for row in q:
events.append({'at': row[0], 'desc': describeEventEntry(row[1], row[2])})
query_str = 'SELECT created_at, trigger_at FROM eventqueue ' + \
'WHERE active_ind = 1 AND linked_id = x\'{}\' '.format(bid_id.hex())
q = self.engine.execute(query_str)
q = session.execute(query_str)
events = []
for row in q:
events.append({'at': row[0], 'desc': 'Delaying until: {}'.format(format_timestamp(row[1]))})
@ -1736,13 +1738,13 @@ class BasicSwap(BaseApp):
assert(bid), 'Bid not found'
assert(offer), 'Offer not found'
if offer.swap_type == SwapTypes.XMR_SWAP:
return self.acceptXmrBid(bid_id)
# Ensure bid is still valid
now = int(time.time())
assert(bid.expire_at > now), 'Bid expired'
assert(bid.state == BidStates.BID_RECEIVED), 'Wrong bid state: {}'.format(BidStates(bid.state))
assert(bid.state == BidStates.BID_RECEIVED), 'Wrong bid state: {}'.format(str(BidStates(bid.state)))
if offer.swap_type == SwapTypes.XMR_SWAP:
return self.acceptXmrBid(bid_id)
if bid.contract_count is None:
bid.contract_count = self.getNewContractId()
@ -1934,13 +1936,15 @@ class BasicSwap(BaseApp):
)
bid.setState(BidStates.BID_SENT)
session = scoped_session(self.session_factory)
self.saveBidInSession(xmr_swap.bid_id, bid, session, xmr_swap)
if addr_send_from is None:
session.add(SmsgAddress(addr=bid_addr, use_type=MessageTypes.BID))
session.commit()
session.close()
session.remove()
try:
session = scoped_session(self.session_factory)
self.saveBidInSession(xmr_swap.bid_id, bid, session, xmr_swap)
if addr_send_from is None:
session.add(SmsgAddress(addr=bid_addr, use_type=MessageTypes.BID))
session.commit()
finally:
session.close()
session.remove()
self.log.info('Sent XMR_BID_FL %s', xmr_swap.bid_id.hex())
return xmr_swap.bid_id
@ -1957,7 +1961,8 @@ class BasicSwap(BaseApp):
bid, xmr_swap = self.getXmrBid(bid_id)
assert(bid), 'Bid not found: {}.'.format(bid_id.hex())
assert(xmr_swap), 'XMR swap not found: {}.'.format(bid_id.hex())
assert(bid.expire_at > now), 'Offer has expired'
assert(bid.expire_at > now), 'Bid expired'
assert(bid.state == BidStates.BID_RECEIVED), 'Wrong bid state: {}'.format(str(BidStates(bid.state)))
offer, xmr_offer = self.getXmrOffer(bid.offer_id)
assert(offer), 'Offer not found: {}.'.format(bid.offer_id.hex())
@ -2066,11 +2071,7 @@ class BasicSwap(BaseApp):
bid.setState(BidStates.BID_ACCEPTED)
session = scoped_session(self.session_factory)
self.saveBidInSession(bid_id, bid, session, xmr_swap)
session.commit()
session.close()
session.remove()
self.saveBid(bid_id, bid, xmr_swap=xmr_swap)
# Add to swaps_in_progress only when waiting on txns
self.log.info('Sent XMR_BID_ACCEPT_LF %s', bid_id.hex())
@ -3182,7 +3183,7 @@ class BasicSwap(BaseApp):
self.initiateTxnSpent(watched_output.bid_id, spend_txid_hex, spend_n, spend_txn)
def checkForSpends(self, coin_type, c):
# assert(self.mxDB.locked()) self.log.debug('checkForSpends %s', coin_type)
# assert(self.mxDB.locked())
self.log.debug('checkForSpends %s', coin_type)
if coin_type == Coins.PART and self.coin_clients[coin_type]['have_spent_index']:
@ -3236,11 +3237,18 @@ class BasicSwap(BaseApp):
now = int(time.time())
options = {'encoding': 'none'}
ro = self.callrpc('smsginbox', ['all', '', options])
num_messages = 0
num_removed = 0
for msg in ro['messages']:
expire_at = msg['sent'] + msg['daysretention'] * self.SMSG_SECONDS_IN_DAY
num_messages += 1
expire_at = msg['sent'] + msg['ttl']
if expire_at < now:
options = {'encoding': 'none', 'delete': True}
del_msg = self.callrpc('smsg', [msg['msgid'], options])
num_removed += 1
if num_messages + num_removed > 0:
logging.info('Expired {} / {} messages.'.format(num_removed, num_messages))
logging.debug('TODO: Expire records from db')
@ -3303,7 +3311,7 @@ class BasicSwap(BaseApp):
session = scoped_session(self.session_factory)
q = session.query(Bid).filter(Bid.state == BidStates.BID_RECEIVING)
for bid in q:
q = self.engine.execute('SELECT COUNT(*) FROM xmr_split_data WHERE bid_id = x\'{}\' AND msg_type = {}'.format(bid.bid_id.hex(), XmrSplitMsgTypes.BID)).first()
q = session.execute('SELECT COUNT(*) FROM xmr_split_data WHERE bid_id = x\'{}\' AND msg_type = {}'.format(bid.bid_id.hex(), XmrSplitMsgTypes.BID)).first()
num_segments = q[0]
if num_segments > 1:
try:
@ -3321,7 +3329,7 @@ class BasicSwap(BaseApp):
q = session.query(Bid).filter(Bid.state == BidStates.BID_RECEIVING_ACC)
for bid in q:
q = self.engine.execute('SELECT COUNT(*) FROM xmr_split_data WHERE bid_id = x\'{}\' AND msg_type = {}'.format(bid.bid_id.hex(), XmrSplitMsgTypes.BID_ACCEPT)).first()
q = session.execute('SELECT COUNT(*) FROM xmr_split_data WHERE bid_id = x\'{}\' AND msg_type = {}'.format(bid.bid_id.hex(), XmrSplitMsgTypes.BID_ACCEPT)).first()
num_segments = q[0]
if num_segments > 1:
try:
@ -3330,6 +3338,7 @@ class BasicSwap(BaseApp):
self.log.info('Verify xmr bid accept {} failed: {}'.format(bid.bid_id.hex(), str(ex)))
bid.setState(BidStates.BID_ERROR, 'Failed accept validation: ' + str(ex))
session.add(bid)
self.updateBidInProgress(bid)
continue
if bid.created_at + ttl_xmr_split_messages < now:
self.log.debug('Expiring partially received bid accept: {}'.format(bid.bid_id.hex()))
@ -3388,49 +3397,51 @@ class BasicSwap(BaseApp):
raise ValueError('Offer has been revoked {}.'.format(offer_id.hex()))
session = scoped_session(self.session_factory)
# Check for sent
existing_offer = self.getOffer(offer_id)
if existing_offer is None:
offer = Offer(
offer_id=offer_id,
active_ind=1,
coin_from=offer_data.coin_from,
coin_to=offer_data.coin_to,
amount_from=offer_data.amount_from,
rate=offer_data.rate,
min_bid_amount=offer_data.min_bid_amount,
time_valid=offer_data.time_valid,
lock_type=int(offer_data.lock_type),
lock_value=offer_data.lock_value,
swap_type=offer_data.swap_type,
addr_from=msg['from'],
created_at=msg['sent'],
expire_at=msg['sent'] + offer_data.time_valid,
was_sent=False)
offer.setState(OfferStates.OFFER_RECEIVED)
session.add(offer)
if offer.swap_type == SwapTypes.XMR_SWAP:
xmr_offer = XmrOffer()
xmr_offer.offer_id = offer_id
xmr_offer.lock_time_1 = getExpectedSequence(offer_data.lock_type, offer_data.lock_value, coin_from)
xmr_offer.lock_time_2 = getExpectedSequence(offer_data.lock_type, offer_data.lock_value, coin_from)
xmr_offer.a_fee_rate = offer_data.fee_rate_from
xmr_offer.b_fee_rate = offer_data.fee_rate_to
session.add(xmr_offer)
self.log.debug('Received new offer %s', offer_id.hex())
else:
existing_offer.setState(OfferStates.OFFER_RECEIVED)
session.add(existing_offer)
session.commit()
session.close()
session.remove()
try:
# Check for sent
existing_offer = self.getOffer(offer_id)
if existing_offer is None:
offer = Offer(
offer_id=offer_id,
active_ind=1,
coin_from=offer_data.coin_from,
coin_to=offer_data.coin_to,
amount_from=offer_data.amount_from,
rate=offer_data.rate,
min_bid_amount=offer_data.min_bid_amount,
time_valid=offer_data.time_valid,
lock_type=int(offer_data.lock_type),
lock_value=offer_data.lock_value,
swap_type=offer_data.swap_type,
addr_from=msg['from'],
created_at=msg['sent'],
expire_at=msg['sent'] + offer_data.time_valid,
was_sent=False)
offer.setState(OfferStates.OFFER_RECEIVED)
session.add(offer)
if offer.swap_type == SwapTypes.XMR_SWAP:
xmr_offer = XmrOffer()
xmr_offer.offer_id = offer_id
xmr_offer.lock_time_1 = getExpectedSequence(offer_data.lock_type, offer_data.lock_value, coin_from)
xmr_offer.lock_time_2 = getExpectedSequence(offer_data.lock_type, offer_data.lock_value, coin_from)
xmr_offer.a_fee_rate = offer_data.fee_rate_from
xmr_offer.b_fee_rate = offer_data.fee_rate_to
session.add(xmr_offer)
self.log.debug('Received new offer %s', offer_id.hex())
else:
existing_offer.setState(OfferStates.OFFER_RECEIVED)
session.add(existing_offer)
session.commit()
finally:
session.close()
session.remove()
def processOfferRevoke(self, msg):
assert(msg['to'] == self.network_addr), 'Message received on wrong address'
@ -3540,6 +3551,7 @@ class BasicSwap(BaseApp):
was_received=True,
)
else:
assert(bid.state == BidStates.BID_SENT), 'Wrong bid state: {}'.format(str(BidStates(bid.state)))
bid.created_at = msg['sent']
bid.expire_at = msg['sent'] + bid_data.time_valid
bid.was_received = True
@ -3585,7 +3597,7 @@ class BasicSwap(BaseApp):
if bid.was_received: # Sent to self
self.log.info('Received valid bid accept %s for bid %s sent to self', bid.accept_msg_id.hex(), bid_id.hex())
return
raise ValueError('Wrong bid state: {}'.format(str(BidStates(bid.state))))
raise ValueError('Wrong bid state: {}'.format(str(BidStates(str(BidStates(bid.state))))))
use_csv = True if offer.lock_type < ABS_LOCK_BLOCKS else False
@ -3784,6 +3796,7 @@ class BasicSwap(BaseApp):
xmr_swap.b_restore_height = ci_to._restore_height
self.log.warning('XMR swap restore height clamped to {}'.format(ci_to._restore_height))
else:
assert(bid.state == BidStates.BID_SENT), 'Wrong bid state: {}'.format(str(BidStates(bid.state)))
bid.created_at = msg['sent']
bid.expire_at = msg['sent'] + bid_data.time_valid
bid.was_received = True
@ -4336,13 +4349,25 @@ class BasicSwap(BaseApp):
assert(len(msg_data.msg_id) == 28), 'Bad msg_id length'
if msg_data.msg_type == XmrSplitMsgTypes.BID or msg_data.msg_type == XmrSplitMsgTypes.BID_ACCEPT:
dbr = XmrSplitData()
dbr.bid_id = msg_data.msg_id
dbr.msg_type = msg_data.msg_type
dbr.msg_sequence = msg_data.sequence
dbr.dleag = msg_data.dleag
dbr.created_at = now
self.saveToDB(dbr)
try:
session = scoped_session(self.session_factory)
q = session.execute('SELECT COUNT(*) FROM xmr_split_data WHERE bid_id = x\'{}\' AND msg_type = {} AND msg_sequence = {}'.format(msg_data.msg_id.hex(), msg_data.msg_type, msg_data.sequence)).first()
num_exists = q[0]
if num_exists > 0:
self.log.warning('Ignoring duplicate xmr_split_data entry: ({}, {}, {})'.format(msg_data.msg_id.hex(), msg_data.msg_type, msg_data.sequence))
return
dbr = XmrSplitData()
dbr.bid_id = msg_data.msg_id
dbr.msg_type = msg_data.msg_type
dbr.msg_sequence = msg_data.sequence
dbr.dleag = msg_data.dleag
dbr.created_at = now
session.add(dbr)
session.commit()
finally:
session.close()
session.remove()
def processXmrLockReleaseMessage(self, msg):
self.log.debug('Processing xmr secret msg %s', msg['msgid'])
@ -4640,9 +4665,9 @@ class BasicSwap(BaseApp):
try:
session = scoped_session(self.session_factory)
if offer_id:
q = self.engine.execute('SELECT COUNT(*) FROM bids WHERE state >= {} AND offer_id = x\'{}\''.format(BidStates.BID_ACCEPTED, offer_id.hex())).first()
q = session.execute('SELECT COUNT(*) FROM bids WHERE state >= {} AND offer_id = x\'{}\''.format(BidStates.BID_ACCEPTED, offer_id.hex())).first()
else:
q = self.engine.execute('SELECT COUNT(*) FROM bids WHERE state >= {}'.format(BidStates.BID_ACCEPTED)).first()
q = session.execute('SELECT COUNT(*) FROM bids WHERE state >= {}'.format(BidStates.BID_ACCEPTED)).first()
return q[0]
finally:
session.close()
@ -4712,7 +4737,7 @@ class BasicSwap(BaseApp):
query_str += 'WHERE bids.was_received = 1 '
query_str += 'ORDER BY bids.created_at DESC'
q = self.engine.execute(query_str)
q = session.execute(query_str)
for row in q:
rv.append(row)
return rv
@ -4751,7 +4776,7 @@ class BasicSwap(BaseApp):
try:
session = scoped_session(self.session_factory)
rv = []
q = self.engine.execute('SELECT addr FROM smsgaddresses WHERE use_type = {} ORDER BY addr_id DESC'.format(use_type))
q = session.execute('SELECT addr FROM smsgaddresses WHERE use_type = {} ORDER BY addr_id DESC'.format(use_type))
for row in q:
rv.append(row[0])
return rv

2
basicswap/db.py

@ -330,6 +330,8 @@ class XmrSplitData(Base):
dleag = sa.Column(sa.LargeBinary)
created_at = sa.Column(sa.BigInteger)
__table_args__ = (sa.UniqueConstraint('bid_id', 'msg_type', 'msg_sequence', name='uc_1'),)
class RevokedMessage(Base):
__tablename__ = 'revoked_messages'

2
basicswap/http_server.py

@ -39,6 +39,7 @@ from .js_server import (
js_bids,
js_sentbids,
js_network,
js_revokeoffer,
js_index,
)
from .ui import (
@ -821,6 +822,7 @@ class HttpHandler(BaseHTTPRequestHandler):
'bids': js_bids,
'sentbids': js_sentbids,
'network': js_network,
'revokeoffer': js_revokeoffer,
}.get(url_split[2], js_index)
return func(self, url_split, post_string)
except Exception as ex:

2
basicswap/interface_btc.py

@ -117,7 +117,7 @@ class BTCInterface(CoinInterface):
def __init__(self, coin_settings, network):
super().__init__()
rpc_host = coin_settings.get('rpchost', 'localhost')
rpc_host = coin_settings.get('rpchost', '127.0.0.1')
self.rpc_callback = make_rpc_func(coin_settings['rpcport'], coin_settings['rpcauth'], host=rpc_host)
self.txoType = CTxOut
self._network = network

2
basicswap/interface_part.py

@ -36,7 +36,7 @@ class PARTInterface(BTCInterface):
return 213
def __init__(self, coin_settings, network):
rpc_host = coin_settings.get('rpchost', 'localhost')
rpc_host = coin_settings.get('rpchost', '127.0.0.1')
self.rpc_callback = make_rpc_func(coin_settings['rpcport'], coin_settings['rpcauth'], host=rpc_host)
self.txoType = CTxOutPart
self._network = network

4
basicswap/interface_xmr.py

@ -57,8 +57,8 @@ class XMRInterface(CoinInterface):
def __init__(self, coin_settings, network):
super().__init__()
self.rpc_cb = make_xmr_rpc_func(coin_settings['rpcport'], host=coin_settings.get('rpchost', 'localhost'))
self.rpc_cb2 = make_xmr_rpc2_func(coin_settings['rpcport'], host=coin_settings.get('rpchost', 'localhost')) # non-json endpoint
self.rpc_cb = make_xmr_rpc_func(coin_settings['rpcport'], host=coin_settings.get('rpchost', '127.0.0.1'))
self.rpc_cb2 = make_xmr_rpc2_func(coin_settings['rpcport'], host=coin_settings.get('rpchost', '127.0.0.1')) # non-json endpoint
self.rpc_wallet_cb = make_xmr_wallet_rpc_func(coin_settings['walletrpcport'], coin_settings['walletrpcauth'])
self._network = network

12
basicswap/js_server.py

@ -34,6 +34,7 @@ def js_wallets(self, url_split, post_string):
def js_offers(self, url_split, post_string, sent=False):
offer_id = None
if len(url_split) > 3:
if url_split[3] == 'new':
if post_string == '':
@ -52,6 +53,10 @@ def js_offers(self, url_split, post_string, sent=False):
'sort_by': 'created_at',
'sort_dir': 'desc',
}
if offer_id:
filters['offer_id'] = offer_id
if post_string != '':
post_data = urllib.parse.parse_qs(post_string)
filters['coin_from'] = setCoinFilter(form_data, b'coin_from')
@ -160,5 +165,12 @@ def js_network(self, url_split, post_string):
return bytes(json.dumps(self.server.swap_client.get_network_info()), 'UTF-8')
def js_revokeoffer(self, url_split, post_string):
offer_id = bytes.fromhex(url_split[3])
assert(len(offer_id) == 28)
self.server.swap_client.revokeOffer(offer_id)
return bytes(json.dumps({'revoked_offer': offer_id.hex()}), 'UTF-8')
def js_index(self, url_split, post_string):
return bytes(json.dumps(self.server.swap_client.getSummary()), 'UTF-8')

30
bin/basicswap_prepare.py

@ -53,11 +53,11 @@ logger.level = logging.DEBUG
if not len(logger.handlers):
logger.addHandler(logging.StreamHandler(sys.stdout))
XMR_RPC_HOST = os.getenv('XMR_RPC_HOST', 'localhost')
XMR_RPC_HOST = os.getenv('XMR_RPC_HOST', '127.0.0.1')
BASE_XMR_RPC_PORT = int(os.getenv('BASE_XMR_RPC_PORT', 29798))
BASE_XMR_ZMQ_PORT = int(os.getenv('BASE_XMR_ZMQ_PORT', 30898))
BASE_XMR_WALLET_PORT = int(os.getenv('BASE_XMR_WALLET_PORT', 29998))
XMR_WALLET_RPC_HOST = os.getenv('XMR_WALLET_RPC_HOST', 'localhost')
XMR_WALLET_RPC_HOST = os.getenv('XMR_WALLET_RPC_HOST', '127.0.0.1')
XMR_WALLET_RPC_USER = os.getenv('XMR_WALLET_RPC_USER', 'xmr_wallet_user')
XMR_WALLET_RPC_PWD = os.getenv('XMR_WALLET_RPC_PWD', 'xmr_wallet_pwd')
XMR_SITE_COMMIT = 'd27c1eee9fe0e8daa011d07baae8b67dd2b62a04' # Lock hashes.txt to monero version
@ -65,10 +65,10 @@ XMR_SITE_COMMIT = 'd27c1eee9fe0e8daa011d07baae8b67dd2b62a04' # Lock hashes.txt
DEFAULT_XMR_RESTORE_HEIGHT = 2245107
PART_RPC_HOST = os.getenv('PART_RPC_HOST', 'localhost')
LTC_RPC_HOST = os.getenv('LTC_RPC_HOST', 'localhost')
BTC_RPC_HOST = os.getenv('BTC_RPC_HOST', 'localhost')
NMC_RPC_HOST = os.getenv('NMC_RPC_HOST', 'localhost')
PART_RPC_HOST = os.getenv('PART_RPC_HOST', '127.0.0.1')
LTC_RPC_HOST = os.getenv('LTC_RPC_HOST', '127.0.0.1')
BTC_RPC_HOST = os.getenv('BTC_RPC_HOST', '127.0.0.1')
NMC_RPC_HOST = os.getenv('NMC_RPC_HOST', '127.0.0.1')
extract_core_overwrite = True
@ -82,7 +82,7 @@ def make_reporthook():
nonlocal last_percent_str
read += blocksize
if totalsize > 0:
percent_str = '%5.1f%%' % (read * 1e2 / totalsize)
percent_str = '%5.0f%%' % (read * 1e2 / totalsize)
if percent_str != last_percent_str:
logger.info(percent_str)
last_percent_str = percent_str
@ -393,7 +393,7 @@ def printHelp():
logger.info('--preparebinonly Don\'t prepare settings or datadirs.')
logger.info('--nocores Don\'t download and extract any coin clients.')
logger.info('--portoffset=n Raise all ports by n.')
logger.info('--htmlhost= Interface to host on, default:localhost.')
logger.info('--htmlhost= Interface to host on, default:127.0.0.1.')
logger.info('--xmrrestoreheight=n Block height to restore Monero wallet from, default:{}.'.format(DEFAULT_XMR_RESTORE_HEIGHT))
logger.info('--noextractover Prevent extracting cores if files exist. Speeds up tests')
@ -431,7 +431,7 @@ def main():
with_coins = {'particl'}
add_coin = ''
disable_coin = ''
htmlhost = 'localhost'
htmlhost = '127.0.0.1'
xmr_restore_height = DEFAULT_XMR_RESTORE_HEIGHT
for v in sys.argv[1:]:
@ -535,7 +535,7 @@ def main():
chainclients = {
'particl': {
'connection_type': 'rpc',
'manage_daemon': True if ('particl' in with_coins and PART_RPC_HOST == 'localhost') else False,
'manage_daemon': True if ('particl' in with_coins and PART_RPC_HOST == '127.0.0.1') else False,
'rpchost': PART_RPC_HOST,
'rpcport': 19792 + port_offset,
'datadir': os.getenv('PART_DATA_DIR', os.path.join(data_dir, 'particl')),
@ -548,7 +548,7 @@ def main():
},
'litecoin': {
'connection_type': 'rpc' if 'litecoin' in with_coins else 'none',
'manage_daemon': True if ('litecoin' in with_coins and LTC_RPC_HOST == 'localhost') else False,
'manage_daemon': True if ('litecoin' in with_coins and LTC_RPC_HOST == '127.0.0.1') else False,
'rpchost': LTC_RPC_HOST,
'rpcport': 19795 + port_offset,
'datadir': os.getenv('LTC_DATA_DIR', os.path.join(data_dir, 'litecoin')),
@ -561,7 +561,7 @@ def main():
},
'bitcoin': {
'connection_type': 'rpc' if 'bitcoin' in with_coins else 'none',
'manage_daemon': True if ('bitcoin' in with_coins and BTC_RPC_HOST == 'localhost') else False,
'manage_daemon': True if ('bitcoin' in with_coins and BTC_RPC_HOST == '127.0.0.1') else False,
'rpchost': BTC_RPC_HOST,
'rpcport': 19796 + port_offset,
'datadir': os.getenv('BTC_DATA_DIR', os.path.join(data_dir, 'bitcoin')),
@ -574,7 +574,7 @@ def main():
},
'namecoin': {
'connection_type': 'rpc' if 'namecoin' in with_coins else 'none',
'manage_daemon': True if ('namecoin' in with_coins and NMC_RPC_HOST == 'localhost') else False,
'manage_daemon': True if ('namecoin' in with_coins and NMC_RPC_HOST == '127.0.0.1') else False,
'rpchost': NMC_RPC_HOST,
'rpcport': 19798 + port_offset,
'datadir': os.getenv('NMC_DATA_DIR', os.path.join(data_dir, 'namecoin')),
@ -588,8 +588,8 @@ def main():
},
'monero': {
'connection_type': 'rpc' if 'monero' in with_coins else 'none',
'manage_daemon': True if ('monero' in with_coins and XMR_RPC_HOST == 'localhost') else False,
'manage_wallet_daemon': True if ('monero' in with_coins and XMR_WALLET_RPC_HOST == 'localhost') else False,
'manage_daemon': True if ('monero' in with_coins and XMR_RPC_HOST == '127.0.0.1') else False,
'manage_wallet_daemon': True if ('monero' in with_coins and XMR_WALLET_RPC_HOST == '127.0.0.1') else False,
'rpcport': BASE_XMR_RPC_PORT + port_offset,
'zmqport': BASE_XMR_ZMQ_PORT + port_offset,
'walletrpcport': BASE_XMR_WALLET_PORT + port_offset,

2
tests/basicswap/common.py

@ -162,7 +162,7 @@ def wait_for_none_active(delay_event, port, wait_for=30):
if delay_event.is_set():
raise ValueError('Test stopped.')
delay_event.wait(1)
js = json.loads(urlopen('http://localhost:{}/json'.format(port)).read())
js = json.loads(urlopen('http://127.0.0.1:{}/json'.format(port)).read())
if js['num_swapping'] == 0 and js['num_watched_outputs'] == 0:
return
raise ValueError('wait_for_none_active timed out.')

8
tests/basicswap/extended/test_network.py

@ -79,7 +79,7 @@ def prepare_swapclient_dir(datadir, node_id, network_key, network_pubkey):
'p2p_port': BASE_P2P_PORT + node_id,
'zmqhost': 'tcp://127.0.0.1',
'zmqport': BASE_ZMQ_PORT + node_id,
'htmlhost': 'localhost',
'htmlhost': '127.0.0.1',
'htmlport': TEST_HTTP_PORT + node_id,
'network_key': network_key,
'network_pubkey': network_pubkey,
@ -298,7 +298,7 @@ class Test(unittest.TestCase):
for i in range(wait_for):
if delay_event.is_set():
raise ValueError('Test stopped.')
js = json.loads(urlopen('http://localhost:{}/json/network'.format(port)).read())
js = json.loads(urlopen('http://127.0.0.1:{}/json/network'.format(port)).read())
num_nodes = 0
for p in js['peers']:
if p['ready'] is True:
@ -313,7 +313,7 @@ class Test(unittest.TestCase):
logging.info('---------- Test Network')
swap_clients = self.swap_clients
js_1 = json.loads(urlopen('http://localhost:1801/json/wallets').read())
js_1 = json.loads(urlopen('http://127.0.0.1:1801/json/wallets').read())
offer_id = swap_clients[0].postOffer(Coins.PART, Coins.BTC, 100 * COIN, 0.1 * COIN, 100 * COIN, SwapTypes.SELLER_FIRST)
@ -322,7 +322,7 @@ class Test(unittest.TestCase):
self.wait_for_num_nodes(1800, 2)
js_n0 = json.loads(urlopen('http://localhost:1800/json/network').read())
js_n0 = json.loads(urlopen('http://127.0.0.1:1800/json/network').read())
print(dumpj(js_n0))
path = [swap_clients[0]._network._network_pubkey, swap_clients[2]._network._network_pubkey]

26
tests/basicswap/extended/test_nmc.py

@ -146,7 +146,7 @@ def prepareDir(datadir, nodeId, network_key, network_pubkey):
'debug': True,
'zmqhost': 'tcp://127.0.0.1',
'zmqport': BASE_ZMQ_PORT + nodeId,
'htmlhost': 'localhost',
'htmlhost': '127.0.0.1',
'htmlport': 12700 + nodeId,
'network_key': network_key,
'network_pubkey': network_pubkey,
@ -380,8 +380,8 @@ class Test(unittest.TestCase):
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 = json.loads(urlopen('http://localhost:1800/json').read())
js_1 = json.loads(urlopen('http://localhost:1801/json').read())
js_0 = json.loads(urlopen('http://127.0.0.1:1800/json').read())
js_1 = json.loads(urlopen('http://127.0.0.1:1801/json').read())
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)
@ -405,8 +405,8 @@ class Test(unittest.TestCase):
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 = json.loads(urlopen('http://localhost:1800/json').read())
js_1 = json.loads(urlopen('http://localhost:1801/json').read())
js_0 = json.loads(urlopen('http://127.0.0.1:1800/json').read())
js_1 = json.loads(urlopen('http://127.0.0.1:1801/json').read())
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)
@ -430,10 +430,10 @@ class Test(unittest.TestCase):
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 = json.loads(urlopen('http://localhost:1800/json/bids/{}'.format(bid_id.hex())).read())
js_0bid = json.loads(urlopen('http://127.0.0.1:1800/json/bids/{}'.format(bid_id.hex())).read())
js_0 = json.loads(urlopen('http://localhost:1800/json').read())
js_1 = json.loads(urlopen('http://localhost:1801/json').read())
js_0 = json.loads(urlopen('http://127.0.0.1:1800/json').read())
js_1 = json.loads(urlopen('http://127.0.0.1:1801/json').read())
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)
@ -459,8 +459,8 @@ class Test(unittest.TestCase):
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 = json.loads(urlopen('http://localhost:1800/json').read())
js_1 = json.loads(urlopen('http://localhost:1801/json').read())
js_0 = json.loads(urlopen('http://127.0.0.1:1800/json').read())
js_1 = json.loads(urlopen('http://127.0.0.1:1801/json').read())
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)
@ -468,7 +468,7 @@ class Test(unittest.TestCase):
logging.info('---------- Test same client, BTC to NMC')
swap_clients = self.swap_clients
js_0_before = json.loads(urlopen('http://localhost:1800/json').read())
js_0_before = json.loads(urlopen('http://127.0.0.1:1800/json').read())
offer_id = swap_clients[0].postOffer(Coins.NMC, Coins.BTC, 10 * COIN, 10 * COIN, 10 * COIN, SwapTypes.SELLER_FIRST, ABS_LOCK_TIME)
@ -484,7 +484,7 @@ class Test(unittest.TestCase):
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 = json.loads(urlopen('http://localhost:1800/json').read())
js_0 = json.loads(urlopen('http://127.0.0.1:1800/json').read())
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)
@ -492,7 +492,7 @@ class Test(unittest.TestCase):
logging.info('---------- Test error, BTC to NMC, set fee above bid value')
swap_clients = self.swap_clients
js_0_before = json.loads(urlopen('http://localhost:1800/json').read())
js_0_before = json.loads(urlopen('http://127.0.0.1:1800/json').read())
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)

0
tests/basicswap/test_prepare.py → tests/basicswap/extended/test_prepare.py

14
tests/basicswap/extended/test_wallet_init.py

@ -55,10 +55,10 @@ def waitForServer(port):
for i in range(20):
try:
time.sleep(1)
summary = json.loads(urlopen('http://localhost:{}/json'.format(port)).read())
summary = json.loads(urlopen('http://127.0.0.1:{}/json'.format(port)).read())
break
except Exception:
traceback.print_exc()
except Exception as e:
print('waitForServer, error:', str(e))
class Test(unittest.TestCase):
@ -98,7 +98,7 @@ class Test(unittest.TestCase):
fp.write('minstakeinterval=5\n')
for ip in range(3):
if ip != i:
fp.write('connect=localhost:{}\n'.format(PARTICL_PORT_BASE + ip))
fp.write('connect=127.0.0.1:{}\n'.format(PARTICL_PORT_BASE + ip))
# Pruned nodes don't provide blocks
with open(os.path.join(client_path, 'bitcoin', 'bitcoin.conf'), 'r') as fp:
@ -115,7 +115,7 @@ class Test(unittest.TestCase):
fp.write('bind=127.0.0.1\n')
for ip in range(3):
if ip != i:
fp.write('connect=localhost:{}\n'.format(BITCOIN_PORT_BASE + ip))
fp.write('connect=127.0.0.1:{}\n'.format(BITCOIN_PORT_BASE + ip))
with open(os.path.join(client_path, 'monero', 'monerod.conf'), 'a') as fp:
fp.write('p2p-bind-ip=127.0.0.1\n')
@ -145,12 +145,12 @@ class Test(unittest.TestCase):
try:
waitForServer(12700)
wallets_0 = json.loads(urlopen('http://localhost:12700/json/wallets').read())
wallets_0 = json.loads(urlopen('http://127.0.0.1:12700/json/wallets').read())
assert(wallets_0['1']['expected_seed'] is True)
assert(wallets_0['6']['expected_seed'] is True)
waitForServer(12701)
wallets_1 = json.loads(urlopen('http://localhost:12701/json/wallets').read())
wallets_1 = json.loads(urlopen('http://127.0.0.1:12701/json/wallets').read())
assert(wallets_0['1']['expected_seed'] is True)
assert(wallets_1['6']['expected_seed'] is True)

37
tests/basicswap/test_reload.py

@ -59,16 +59,16 @@ def waitForServer(port):
for i in range(20):
try:
time.sleep(1)
summary = json.loads(urlopen('http://localhost:{}/json'.format(port)).read())
summary = json.loads(urlopen('http://127.0.0.1:{}/json'.format(port)).read())
return
except Exception:
traceback.print_exc()
except Exception as e:
print('waitForServer, error:', str(e))
raise ValueError('waitForServer failed')
def waitForNumOffers(port, offers):
for i in range(20):
summary = json.loads(urlopen('http://localhost:{}/json'.format(port)).read())
summary = json.loads(urlopen('http://127.0.0.1:{}/json'.format(port)).read())
if summary['num_network_offers'] >= offers:
return
time.sleep(1)
@ -77,7 +77,7 @@ def waitForNumOffers(port, offers):
def waitForNumBids(port, bids):
for i in range(20):
summary = json.loads(urlopen('http://localhost:{}/json'.format(port)).read())
summary = json.loads(urlopen('http://127.0.0.1:{}/json'.format(port)).read())
if summary['num_recv_bids'] >= bids:
return
time.sleep(1)
@ -86,7 +86,7 @@ def waitForNumBids(port, bids):
def waitForNumSwapping(port, bids):
for i in range(20):
summary = json.loads(urlopen('http://localhost:{}/json'.format(port)).read())
summary = json.loads(urlopen('http://127.0.0.1:{}/json'.format(port)).read())
if summary['num_swapping'] >= bids:
return
time.sleep(1)
@ -135,7 +135,7 @@ class Test(unittest.TestCase):
fp.write('minstakeinterval=5\n')
for ip in range(3):
if ip != i:
fp.write('connect=localhost:{}\n'.format(PARTICL_PORT_BASE + ip))
fp.write('connect=127.0.0.1:{}\n'.format(PARTICL_PORT_BASE + ip))
# Pruned nodes don't provide blocks
with open(os.path.join(client_path, 'bitcoin', 'bitcoin.conf'), 'r') as fp:
@ -152,7 +152,7 @@ class Test(unittest.TestCase):
fp.write('bind=127.0.0.1\n')
for ip in range(3):
if ip != i:
fp.write('connect=localhost:{}\n'.format(BITCOIN_PORT_BASE + ip))
fp.write('connect=127.0.0.1:{}\n'.format(BITCOIN_PORT_BASE + ip))
assert(os.path.exists(config_path))
@ -180,9 +180,10 @@ class Test(unittest.TestCase):
for i in range(20):
blocks = btcRpc(0, 'getblockchaininfo')['blocks']
if blocks >= 500:
if blocks >= num_blocks:
break
assert(blocks >= 500)
time.sleep(2)
assert(blocks >= num_blocks)
data = parse.urlencode({
'addr_from': '-1',
@ -192,8 +193,8 @@ class Test(unittest.TestCase):
'amt_to': '1',
'lockhrs': '24'}).encode()
offer_id = json.loads(urlopen('http://localhost:12700/json/offers/new', data=data).read())
summary = json.loads(urlopen('http://localhost:12700/json').read())
offer_id = json.loads(urlopen('http://127.0.0.1:12700/json/offers/new', data=data).read())
summary = json.loads(urlopen('http://127.0.0.1:12700/json').read())
assert(summary['num_sent_offers'] == 1)
except Exception:
traceback.print_exc()
@ -201,24 +202,24 @@ class Test(unittest.TestCase):
logger.info('Waiting for offer:')
waitForNumOffers(12701, 1)
offers = json.loads(urlopen('http://localhost:12701/json/offers').read())
offers = json.loads(urlopen('http://127.0.0.1:12701/json/offers').read())
offer = offers[0]
data = parse.urlencode({
'offer_id': offer['offer_id'],
'amount_from': offer['amount_from']}).encode()
bid_id = json.loads(urlopen('http://localhost:12701/json/bids/new', data=data).read())
bid_id = json.loads(urlopen('http://127.0.0.1:12701/json/bids/new', data=data).read())
waitForNumBids(12700, 1)
bids = json.loads(urlopen('http://localhost:12700/json/bids').read())
bids = json.loads(urlopen('http://127.0.0.1:12700/json/bids').read())
bid = bids[0]
data = parse.urlencode({
'accept': True
}).encode()
rv = json.loads(urlopen('http://localhost:12700/json/bids/{}'.format(bid['bid_id']), data=data).read())
rv = json.loads(urlopen('http://127.0.0.1:12700/json/bids/{}'.format(bid['bid_id']), data=data).read())
assert(rv['bid_state'] == 'Accepted')
waitForNumSwapping(12701, 1)
@ -231,7 +232,7 @@ class Test(unittest.TestCase):
processes[1].start()
waitForServer(12701)
rv = json.loads(urlopen('http://localhost:12701/json').read())
rv = json.loads(urlopen('http://127.0.0.1:12701/json').read())
assert(rv['num_swapping'] == 1)
update_thread = threading.Thread(target=updateThread)
@ -241,7 +242,7 @@ class Test(unittest.TestCase):
for i in range(240):
time.sleep(5)
rv = json.loads(urlopen('http://localhost:12700/json/bids/{}'.format(bid['bid_id'])).read())
rv = json.loads(urlopen('http://127.0.0.1:12700/json/bids/{}'.format(bid['bid_id'])).read())
print(rv)
if rv['bid_state'] == 'Completed':
break

137
tests/basicswap/test_reload_xmr.py

@ -60,10 +60,10 @@ def waitForServer(port, wait_for=20):
raise ValueError('Test stopped.')
try:
delay_event.wait(1)
summary = json.loads(urlopen('http://localhost:{}/json'.format(port)).read())
summary = json.loads(urlopen('http://127.0.0.1:{}/json'.format(port)).read())
return
except Exception:
traceback.print_exc()
except Exception as e:
print('waitForServer, error:', str(e))
raise ValueError('waitForServer failed')
@ -71,7 +71,7 @@ def waitForNumOffers(port, offers, wait_for=20):
for i in range(wait_for):
if delay_event.is_set():
raise ValueError('Test stopped.')
summary = json.loads(urlopen('http://localhost:{}/json'.format(port)).read())
summary = json.loads(urlopen('http://127.0.0.1:{}/json'.format(port)).read())
if summary['num_network_offers'] >= offers:
return
delay_event.wait(1)
@ -82,7 +82,7 @@ def waitForNumBids(port, bids, wait_for=20):
for i in range(wait_for):
if delay_event.is_set():
raise ValueError('Test stopped.')
summary = json.loads(urlopen('http://localhost:{}/json'.format(port)).read())
summary = json.loads(urlopen('http://127.0.0.1:{}/json'.format(port)).read())
if summary['num_recv_bids'] >= bids:
return
delay_event.wait(1)
@ -93,13 +93,25 @@ def waitForNumSwapping(port, bids, wait_for=60):
for i in range(wait_for):
if delay_event.is_set():
raise ValueError('Test stopped.')
summary = json.loads(urlopen('http://localhost:{}/json'.format(port)).read())
summary = json.loads(urlopen('http://127.0.0.1:{}/json'.format(port)).read())
if summary['num_swapping'] >= bids:
return
delay_event.wait(1)
raise ValueError('waitForNumSwapping failed')
def waitForBidState(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())
print('[rm] bid', bid)
if bid['bid_state'] == state_str:
return
delay_event.wait(1)
raise ValueError('waitForBidState failed')
def updateThread(xmr_addr):
while not delay_event.is_set():
try:
@ -154,7 +166,7 @@ class Test(unittest.TestCase):
fp.write('minstakeinterval=5\n')
for ip in range(3):
if ip != i:
fp.write('connect=localhost:{}\n'.format(PARTICL_PORT_BASE + ip))
fp.write('connect=127.0.0.1:{}\n'.format(PARTICL_PORT_BASE + ip))
with open(os.path.join(client_path, 'monero', 'monerod.conf'), 'a') as fp:
fp.write('p2p-bind-ip=127.0.0.1\n')
@ -196,7 +208,7 @@ class Test(unittest.TestCase):
try:
waitForServer(12701)
wallets = json.loads(urlopen('http://localhost:12701/json/wallets').read())
wallets = json.loads(urlopen('http://127.0.0.1:12701/json/wallets').read())
xmr_addr1 = wallets['6']['deposit_address']
num_blocks = 100
@ -229,7 +241,7 @@ class Test(unittest.TestCase):
try:
waitForServer(12700)
waitForServer(12701)
wallets1 = json.loads(urlopen('http://localhost:12701/json/wallets').read())
wallets1 = json.loads(urlopen('http://127.0.0.1:12701/json/wallets').read())
assert(float(wallets1['6']['balance']) > 0.0)
data = parse.urlencode({
@ -240,26 +252,26 @@ class Test(unittest.TestCase):
'amt_to': '1',
'lockhrs': '24'}).encode()
offer_id = json.loads(urlopen('http://localhost:12700/json/offers/new', data=data).read())
summary = json.loads(urlopen('http://localhost:12700/json').read())
offer_id = json.loads(urlopen('http://127.0.0.1:12700/json/offers/new', data=data).read())['offer_id']
summary = json.loads(urlopen('http://127.0.0.1:12700/json').read())
assert(summary['num_sent_offers'] == 1)
logger.info('Waiting for offer')
waitForNumOffers(12701, 1)
offers = json.loads(urlopen('http://localhost:12701/json/offers').read())
offers = json.loads(urlopen('http://127.0.0.1:12701/json/offers').read())
offer = offers[0]
data = parse.urlencode({
'offer_id': offer['offer_id'],
'amount_from': offer['amount_from']}).encode()
bid_id = json.loads(urlopen('http://localhost:12701/json/bids/new', data=data).read())
bid_id = json.loads(urlopen('http://127.0.0.1:12701/json/bids/new', data=data).read())
waitForNumBids(12700, 1)
for i in range(10):
bids = json.loads(urlopen('http://localhost:12700/json/bids').read())
bids = json.loads(urlopen('http://127.0.0.1:12700/json/bids').read())
bid = bids[0]
if bid['bid_state'] == 'Received':
break
@ -268,7 +280,7 @@ class Test(unittest.TestCase):
data = parse.urlencode({
'accept': True
}).encode()
rv = json.loads(urlopen('http://localhost:12700/json/bids/{}'.format(bid['bid_id']), data=data).read())
rv = json.loads(urlopen('http://127.0.0.1:12700/json/bids/{}'.format(bid['bid_id']), data=data).read())
assert(rv['bid_state'] == 'Accepted')
waitForNumSwapping(12701, 1)
@ -281,19 +293,27 @@ class Test(unittest.TestCase):
self.processes[1].start()
waitForServer(12701)
rv = json.loads(urlopen('http://localhost:12701/json').read())
rv = json.loads(urlopen('http://127.0.0.1:12701/json').read())
assert(rv['num_swapping'] == 1)
rv = json.loads(urlopen('http://127.0.0.1:12700/json/revokeoffer/{}'.format(offer_id)).read())
assert(rv['revoked_offer'] == offer_id)
logger.info('Completing swap')
for i in range(240):
if delay_event.is_set():
raise ValueError('Test stopped.')
delay_event.wait(4)
rv = json.loads(urlopen('http://localhost:12700/json/bids/{}'.format(bid['bid_id'])).read())
rv = json.loads(urlopen('http://127.0.0.1:12700/json/bids/{}'.format(bid['bid_id'])).read())
if rv['bid_state'] == 'Completed':
break
assert(rv['bid_state'] == 'Completed')
# Ensure offer was revoked
summary = json.loads(urlopen('http://127.0.0.1:12700/json').read())
assert(summary['num_network_offers'] == 0)
except Exception as e:
traceback.print_exc()
raise(e)
@ -307,10 +327,89 @@ class Test(unittest.TestCase):
try:
waitForServer(12700)
waitForServer(12701)
wallets1 = json.loads(urlopen('http://localhost:12701/json/wallets').read())
print('wallets 1', json.dumps(wallets1, indent=4))
wallets1 = json.loads(urlopen('http://127.0.0.1:12701/json/wallets').read())
assert(float(wallets1['6']['balance']) > 0.0)
offer_data = {
'addr_from': '-1',
'coin_from': '1',
'coin_to': '6',
'amt_from': '1',
'amt_to': '1',
'lockhrs': '24',
'autoaccept': True}
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']
summary = json.loads(urlopen('http://127.0.0.1:12700/json').read())
assert(summary['num_sent_offers'] > 1)
logger.info('Waiting for offer')
waitForNumOffers(12701, 2)
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)
offer0 = offers[0]
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']
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']}
bid1_id = json.loads(urlopen('http://127.0.0.1:12701/json/bids/new', data=parse.urlencode(bid_data).encode()).read())['bid_id']
delay_event.wait(5)
logger.info('Starting node 0')
self.processes[0] = multiprocessing.Process(target=self.run_thread, args=(0,))
self.processes[0].start()
waitForServer(12700)
waitForNumBids(12700, 2)
waitForBidState(12700, bid0_id, 'Received')
waitForBidState(12700, bid1_id, 'Received')
# Manually accept on top of auto-accept for extra chaos
data = parse.urlencode({
'accept': True
}).encode()
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(bid1_id), data=data).read())
assert(rv['bid_state'] == 'Accepted')
logger.info('Completing swap')
for i in range(240):
if delay_event.is_set():
raise ValueError('Test stopped.')
delay_event.wait(4)
rv0 = json.loads(urlopen('http://127.0.0.1:12700/json/bids/{}'.format(bid0_id)).read())
rv1 = json.loads(urlopen('http://127.0.0.1:12700/json/bids/{}'.format(bid1_id)).read())
if rv0['bid_state'] == 'Completed' and rv1['bid_state'] == 'Completed':
break
assert(rv0['bid_state'] == 'Completed')
assert(rv1['bid_state'] == 'Completed')
except Exception as e:
traceback.print_exc()
raise(e)

30
tests/basicswap/test_run.py

@ -152,7 +152,7 @@ def prepareDir(datadir, nodeId, network_key, network_pubkey):
'debug': True,
'zmqhost': 'tcp://127.0.0.1',
'zmqport': BASE_ZMQ_PORT + nodeId,
'htmlhost': 'localhost',
'htmlhost': '127.0.0.1',
'htmlport': 12700 + nodeId,
'network_key': network_key,
'network_pubkey': network_pubkey,
@ -423,8 +423,8 @@ class Test(unittest.TestCase):
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 = json.loads(urlopen('http://localhost:1800/json').read())
js_1 = json.loads(urlopen('http://localhost:1801/json').read())
js_0 = json.loads(urlopen('http://127.0.0.1:1800/json').read())
js_1 = json.loads(urlopen('http://127.0.0.1:1801/json').read())
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)
@ -448,8 +448,8 @@ class Test(unittest.TestCase):
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 = json.loads(urlopen('http://localhost:1800/json').read())
js_1 = json.loads(urlopen('http://localhost:1801/json').read())
js_0 = json.loads(urlopen('http://127.0.0.1:1800/json').read())
js_1 = json.loads(urlopen('http://127.0.0.1:1801/json').read())
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)
@ -473,10 +473,10 @@ class Test(unittest.TestCase):
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 = json.loads(urlopen('http://localhost:1800/json/bids/{}'.format(bid_id.hex())).read())
js_0bid = json.loads(urlopen('http://127.0.0.1:1800/json/bids/{}'.format(bid_id.hex())).read())
js_0 = json.loads(urlopen('http://localhost:1800/json').read())
js_1 = json.loads(urlopen('http://localhost:1801/json').read())
js_0 = json.loads(urlopen('http://127.0.0.1:1800/json').read())
js_1 = json.loads(urlopen('http://127.0.0.1:1801/json').read())
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)
@ -502,8 +502,8 @@ class Test(unittest.TestCase):
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 = json.loads(urlopen('http://localhost:1800/json').read())
js_1 = json.loads(urlopen('http://localhost:1801/json').read())
js_0 = json.loads(urlopen('http://127.0.0.1:1800/json').read())
js_1 = json.loads(urlopen('http://127.0.0.1:1801/json').read())
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)
@ -511,7 +511,7 @@ class Test(unittest.TestCase):
logging.info('---------- Test same client, BTC to LTC')
swap_clients = self.swap_clients
js_0_before = json.loads(urlopen('http://localhost:1800/json').read())
js_0_before = json.loads(urlopen('http://127.0.0.1:1800/json').read())
offer_id = swap_clients[0].postOffer(Coins.BTC, Coins.LTC, 10 * COIN, 10 * COIN, 10 * COIN, SwapTypes.SELLER_FIRST)
@ -527,7 +527,7 @@ class Test(unittest.TestCase):
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 = json.loads(urlopen('http://localhost:1800/json').read())
js_0 = json.loads(urlopen('http://127.0.0.1:1800/json').read())
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)
@ -535,7 +535,7 @@ class Test(unittest.TestCase):
logging.info('---------- Test error, BTC to LTC, set fee above bid value')
swap_clients = self.swap_clients
js_0_before = json.loads(urlopen('http://localhost:1800/json').read())
js_0_before = json.loads(urlopen('http://127.0.0.1:1800/json').read())
offer_id = swap_clients[0].postOffer(Coins.BTC, Coins.LTC, 0.001 * COIN, 1.0 * COIN, 0.001 * COIN, SwapTypes.SELLER_FIRST)
@ -580,8 +580,8 @@ class Test(unittest.TestCase):
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 = json.loads(urlopen('http://localhost:1800/json').read())
js_1 = json.loads(urlopen('http://localhost:1801/json').read())
js_0 = json.loads(urlopen('http://127.0.0.1:1800/json').read())
js_1 = json.loads(urlopen('http://127.0.0.1:1801/json').read())
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)

20
tests/basicswap/test_xmr.py

@ -119,7 +119,7 @@ def startXmrWalletRPC(node_dir, bin_dir, wallet_bin, node_id, opts=[]):
data_dir = os.path.expanduser(node_dir)
args = [daemon_bin]
args += ['--non-interactive']
args += ['--daemon-address=localhost:{}'.format(XMR_BASE_RPC_PORT + node_id)]
args += ['--daemon-address=127.0.0.1:{}'.format(XMR_BASE_RPC_PORT + node_id)]
args += ['--no-dns']
args += ['--rpc-bind-port={}'.format(XMR_BASE_WALLET_RPC_PORT + node_id)]
args += ['--wallet-dir={}'.format(os.path.join(data_dir, 'wallets'))]
@ -145,7 +145,7 @@ def prepare_swapclient_dir(datadir, node_id, network_key, network_pubkey):
'debug': True,
'zmqhost': 'tcp://127.0.0.1',
'zmqport': BASE_ZMQ_PORT + node_id,
'htmlhost': 'localhost',
'htmlhost': '127.0.0.1',
'htmlport': TEST_HTTP_PORT + node_id,
'network_key': network_key,
'network_pubkey': network_pubkey,
@ -431,7 +431,7 @@ class Test(unittest.TestCase):
logging.info('---------- Test PART to XMR')
swap_clients = self.swap_clients
js_1 = json.loads(urlopen('http://localhost:1801/json/wallets').read())
js_1 = json.loads(urlopen('http://127.0.0.1:1801/json/wallets').read())
assert(make_int(js_1[str(int(Coins.XMR))]['balance'], scale=12) > 0)
assert(make_int(js_1[str(int(Coins.XMR))]['unconfirmed'], scale=12) > 0)
@ -453,7 +453,7 @@ class Test(unittest.TestCase):
wait_for_bid(delay_event, swap_clients[0], bid_id, BidStates.SWAP_COMPLETED, wait_for=180)
wait_for_bid(delay_event, swap_clients[1], bid_id, BidStates.SWAP_COMPLETED, sent=True)
js_0_end = json.loads(urlopen('http://localhost:1800/json/wallets').read())
js_0_end = json.loads(urlopen('http://127.0.0.1:1800/json/wallets').read())
end_xmr = float(js_0_end['6']['balance']) + float(js_0_end['6']['unconfirmed'])
assert(end_xmr > 10.9 and end_xmr < 11.0)
@ -461,7 +461,7 @@ class Test(unittest.TestCase):
logging.info('---------- Test PART to XMR leader recovers coin a lock tx')
swap_clients = self.swap_clients
js_w0_before = json.loads(urlopen('http://localhost:1800/json/wallets').read())
js_w0_before = json.loads(urlopen('http://127.0.0.1:1800/json/wallets').read())
offer_id = swap_clients[0].postOffer(
Coins.PART, Coins.XMR, 101 * COIN, 0.12 * XMR_COIN, 101 * COIN, SwapTypes.XMR_SWAP,
@ -483,7 +483,7 @@ class Test(unittest.TestCase):
wait_for_bid(delay_event, swap_clients[0], bid_id, BidStates.XMR_SWAP_FAILED_REFUNDED, wait_for=180)
wait_for_bid(delay_event, swap_clients[1], bid_id, BidStates.XMR_SWAP_FAILED_REFUNDED, sent=True)
js_w0_after = json.loads(urlopen('http://localhost:1800/json/wallets').read())
js_w0_after = json.loads(urlopen('http://127.0.0.1:1800/json/wallets').read())
print('[rm] js_w0_before', json.dumps(js_w0_before))
print('[rm] js_w0_after', json.dumps(js_w0_after))
@ -491,7 +491,7 @@ class Test(unittest.TestCase):
logging.info('---------- Test PART to XMR follower recovers coin a lock tx')
swap_clients = self.swap_clients
js_w0_before = json.loads(urlopen('http://localhost:1800/json/wallets').read())
js_w0_before = json.loads(urlopen('http://127.0.0.1:1800/json/wallets').read())
offer_id = swap_clients[0].postOffer(
Coins.PART, Coins.XMR, 101 * COIN, 0.13 * XMR_COIN, 101 * COIN, SwapTypes.XMR_SWAP,
@ -514,7 +514,7 @@ class Test(unittest.TestCase):
wait_for_bid(delay_event, swap_clients[0], bid_id, BidStates.BID_ABANDONED, wait_for=180)
wait_for_bid(delay_event, swap_clients[1], bid_id, BidStates.XMR_SWAP_FAILED_SWIPED, wait_for=80, sent=True)
js_w0_after = json.loads(urlopen('http://localhost:1800/json/wallets').read())
js_w0_after = json.loads(urlopen('http://127.0.0.1:1800/json/wallets').read())
wait_for_none_active(delay_event, 1800)
wait_for_none_active(delay_event, 1801)
@ -629,11 +629,11 @@ class Test(unittest.TestCase):
def test_08_withdraw(self):
logging.info('---------- Test xmr withdrawals')
swap_clients = self.swap_clients
js_0 = json.loads(urlopen('http://localhost:1800/json/wallets').read())
js_0 = json.loads(urlopen('http://127.0.0.1:1800/json/wallets').read())
print('js_0 debug', js_0)
address_to = js_0[str(int(Coins.XMR))]['deposit_address']
js_1 = json.loads(urlopen('http://localhost:1801/json/wallets').read())
js_1 = json.loads(urlopen('http://127.0.0.1:1801/json/wallets').read())
assert(float(js_1[str(int(Coins.XMR))]['balance']) > 0.0)
swap_clients[1].withdrawCoin(Coins.XMR, 1.1, address_to, False)

2
tox.ini

@ -9,6 +9,8 @@ passenv =
BITCOIN_BINDIR
LITECOIN_BINDIR
XMR_BINDIR
TEST_PREPARE_PATH
TEST_RELOAD_PATH
deps =
pytest
-rrequirements.txt

Loading…
Cancel
Save