api: Add withdraw.

This commit is contained in:
tecnovert 2021-02-07 12:01:58 +02:00
parent b1ea76dcb6
commit c4fc2c70dc
No known key found for this signature in database
GPG key ID: 8ED6D8750C4E3F93
9 changed files with 221 additions and 122 deletions

View file

@ -712,7 +712,7 @@ class BasicSwap(BaseApp):
self.upgradeDatabase(self.db_version)
for c in Coins:
if not c in chainparams:
if c not in chainparams:
continue
self.setCoinRunParams(c)
self.createCoinInterface(c)
@ -780,7 +780,7 @@ class BasicSwap(BaseApp):
def stopDaemons(self):
for c in Coins:
if not c in chainparams:
if c not in chainparams:
continue
chain_client_settings = self.getChainClientSettings(c)
if self.coin_clients[c]['connection_type'] == 'rpc' and chain_client_settings['manage_daemon'] is True:
@ -4893,8 +4893,9 @@ class BasicSwap(BaseApp):
}
if coin == Coins.PART:
rv['stealth_address'] = self.getCachedStealthAddressForCoin(Coins.PART)
rv['anon_balance'] = walletinfo['anon_balance']
rv['anon_unconfirmed'] = walletinfo['unconfirmed_anon']
rv['anon_pending'] = walletinfo['unconfirmed_anon'] + walletinfo['immature_anon_balance']
rv['blind_balance'] = walletinfo['blind_balance']
rv['blind_unconfirmed'] = walletinfo['unconfirmed_blind']
@ -4903,7 +4904,7 @@ class BasicSwap(BaseApp):
def getWalletsInfo(self, opts=None):
rv = {}
for c in Coins:
if not c in chainparams:
if c not in chainparams:
continue
if self.coin_clients[c]['connection_type'] == 'rpc':
try:

View file

@ -76,7 +76,7 @@ def extractDomain(url):
def listAvailableExplorers(swap_client):
explorers = []
for c in Coins:
if not c in chainparams:
if c not in chainparams:
continue
for i, e in enumerate(swap_client.coin_clients[c]['explorers']):
explorers.append(('{}_{}'.format(int(c), i), swap_client.coin_clients[c]['name'].capitalize() + ' - ' + extractDomain(e.base_url)))
@ -220,7 +220,7 @@ class HttpHandler(BaseHTTPRequestHandler):
form_data = self.checkForm(post_string, 'wallets', messages)
if form_data:
for c in Coins:
if not c in chainparams:
if c not in chainparams:
continue
cid = str(int(c))
@ -304,13 +304,12 @@ class HttpHandler(BaseHTTPRequestHandler):
wf['unconfirmed'] = w['unconfirmed']
if k == Coins.PART:
wf['stealth_address'] = swap_client.getCachedStealthAddressForCoin(Coins.PART)
wf['blind_balance'] = w['blind_balance']
if float(w['blind_unconfirmed']) > 0.0:
wf['blind_unconfirmed'] = w['blind_unconfirmed']
wf['anon_balance'] = w['anon_balance']
if float(w['anon_unconfirmed']) > 0.0:
wf['anon_unconfirmed'] = w['anon_unconfirmed']
if float(w['anon_pending']) > 0.0:
wf['anon_pending'] = w['anon_pending']
if 'wd_type_from_' + cid in page_data:
wf['wd_type_from'] = page_data['wd_type_from_' + cid]

View file

@ -97,4 +97,3 @@ class PARTInterfaceAnon(PARTInterface):
@staticmethod
def balance_type():
return BalanceTypes.ANON

View file

@ -8,19 +8,25 @@ import json
import urllib.parse
from .util import (
toBool,
format_timestamp,
)
from .basicswap import (
strBidState,
SwapTypes,
)
from .chainparams import (
Coins,
)
from .ui import (
PAGE_LIMIT,
inputAmount,
describeBid,
setCoinFilter,
get_data_entry,
get_data_entry_or,
have_data_entry,
tickerToCoinId,
)
@ -29,8 +35,40 @@ def js_error(self, error_str):
return bytes(error_str_json, 'UTF-8')
def withdraw_coin(swap_client, coin_type, post_string, is_json):
if is_json:
post_data = json.loads(post_string)
post_data['is_json'] = True
else:
post_data = urllib.parse.parse_qs(post_string)
value = get_data_entry(post_data, 'value')
address = get_data_entry(post_data, 'address')
subfee = get_data_entry(post_data, 'subfee')
if not isinstance(subfee, bool):
subfee = toBool(subfee)
if coin_type == Coins.PART:
type_from = get_data_entry_or(post_data, 'type_from', 'plain')
type_to = get_data_entry_or(post_data, 'type_to', 'plain')
txid_hex = swap_client.withdrawParticl(type_from, type_to, value, address, subfee)
else:
txid_hex = swap_client.withdrawCoin(coin_type, value, address, subfee)
return {'txid': txid_hex}
def js_wallets(self, url_split, post_string, is_json):
# TODO: Withdrawals
if len(url_split) > 3:
ticker_str = url_split[3]
coin_type = tickerToCoinId(ticker_str)
if len(url_split) > 4:
cmd = url_split[4]
if cmd == 'withdraw':
return bytes(json.dumps(withdraw_coin(self.server.swap_client, coin_type, post_string, is_json)), 'UTF-8')
raise ValueError('Unknown command')
return bytes(json.dumps(self.server.swap_client.getWalletInfo(coin_type)), 'UTF-8')
return bytes(json.dumps(self.server.swap_client.getWalletsInfo()), 'UTF-8')

View file

@ -22,7 +22,7 @@
{% if w.cid == '1' %}
<tr><td>Blind Balance:</td><td>{{ w.blind_balance }}</td>{% if w.blind_unconfirmed %}<td>Blind Unconfirmed:</td><td>{{ w.blind_unconfirmed }}</td>{% endif %}</tr>
<tr><td>Anon Balance:</td><td>{{ w.anon_balance }}</td>{% if w.anon_unconfirmed %}<td>Anon Unconfirmed:</td><td>{{ w.anon_unconfirmed }}</td>{% endif %}</tr>
<tr><td>Anon Balance:</td><td>{{ w.anon_balance }}</td>{% if w.anon_pending %}<td>Anon Pending:</td><td>{{ w.anon_pending }}</td>{% endif %}</tr>
{% endif %}

View file

@ -56,6 +56,15 @@ def inputAmount(amount_str, ci):
return make_int(amount_str, ci.exp())
def get_data_entry_or(post_data, name, default):
if 'is_json' in post_data:
return post_data.get(name, default)
key_bytes = name.encode('utf-8')
if key_bytes in post_data:
return post_data[key_bytes][0].decode('utf-8')
return default
def get_data_entry(post_data, name):
if 'is_json' in post_data:
return post_data[name]

View file

@ -9,6 +9,7 @@ import os
import json
import signal
import logging
import urllib
from urllib.request import urlopen
from basicswap.rpc import callrpc
@ -230,6 +231,26 @@ def waitForNumSwapping(delay_event, port, bids, wait_for=60):
raise ValueError('waitForNumSwapping failed')
def wait_for_balance(delay_event, url, balance_key, expect_amount, iterations=20, delay_time=3):
i = 0
while not delay_event.is_set():
rv_js = json.loads(urlopen(url).read())
if float(rv_js[balance_key]) >= expect_amount:
break
delay_event.wait(delay_time)
i += 1
if i > iterations:
raise ValueError('Expect {} {}'.format(balance_key, expect_amount))
def post_json_req(url, json_data):
req = urllib.request.Request(url)
req.add_header('Content-Type', 'application/json; charset=utf-8')
post_bytes = json.dumps(json_data).encode('utf-8')
req.add_header('Content-Length', len(post_bytes))
return urlopen(req, post_bytes).read()
def delay_for(delay_event, delay_for=60):
logging.info('Delaying for {} seconds.'.format(delay_for))
delay_event.wait(delay_for)

View file

@ -16,7 +16,6 @@ $ pytest -v -s tests/basicswap/test_run.py::Test::test_04_ltc_btc
import os
import sys
import json
import time
import random
import shutil
import signal
@ -73,8 +72,7 @@ NUM_NODES = 3
LTC_NODE = 3
BTC_NODE = 4
delay_event = threading.Event()
stop_test = False
test_delay_event = threading.Event()
logger = logging.getLogger()
@ -215,27 +213,25 @@ def ltcRpc(cmd):
def signal_handler(sig, frame):
global stop_test
print('signal {} detected.'.format(sig))
stop_test = True
delay_event.set()
test_delay_event.set()
def run_coins_loop(cls):
while not stop_test:
while not test_delay_event.is_set():
try:
ltcRpc('generatetoaddress 1 {}'.format(cls.ltc_addr))
btcRpc('generatetoaddress 1 {}'.format(cls.btc_addr))
except Exception as e:
logging.warning('run_coins_loop ' + str(e))
time.sleep(1.0)
test_delay_event.wait(1.0)
def run_loop(cls):
while not stop_test:
while not test_delay_event.is_set():
for c in cls.swap_clients:
c.update()
time.sleep(1)
test_delay_event.wait(1)
def make_part_cli_rpc_func(node_id):
@ -358,14 +354,13 @@ class Test(unittest.TestCase):
print('particl_blocks', particl_blocks)
if particl_blocks >= num_blocks:
break
delay_event.wait(1)
test_delay_event.wait(1)
assert(particl_blocks >= num_blocks)
@classmethod
def tearDownClass(cls):
global stop_test
logging.info('Finalising')
stop_test = True
test_delay_event.set()
cls.update_thread.join()
cls.coins_update_thread.join()
for t in cls.http_threads:
@ -418,21 +413,21 @@ class Test(unittest.TestCase):
offer_id = swap_clients[0].postOffer(Coins.PART, Coins.LTC, 100 * COIN, 0.1 * COIN, 100 * COIN, SwapTypes.SELLER_FIRST)
wait_for_offer(delay_event, swap_clients[1], offer_id)
wait_for_offer(test_delay_event, swap_clients[1], offer_id)
offers = swap_clients[1].listOffers()
assert(len(offers) == 1)
for offer in offers:
if offer.offer_id == offer_id:
bid_id = swap_clients[1].postBid(offer_id, offer.amount_from)
wait_for_bid(delay_event, swap_clients[0], bid_id)
wait_for_bid(test_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_in_progress(test_delay_event, swap_clients[1], bid_id, sent=True)
wait_for_bid(delay_event, swap_clients[0], bid_id, BidStates.SWAP_COMPLETED, wait_for=60)
wait_for_bid(delay_event, swap_clients[1], bid_id, BidStates.SWAP_COMPLETED, sent=True, wait_for=60)
wait_for_bid(test_delay_event, swap_clients[0], bid_id, BidStates.SWAP_COMPLETED, wait_for=60)
wait_for_bid(test_delay_event, swap_clients[1], bid_id, BidStates.SWAP_COMPLETED, sent=True, wait_for=60)
js_0 = json.loads(urlopen('http://127.0.0.1:1800/json').read())
js_1 = json.loads(urlopen('http://127.0.0.1:1801/json').read())
@ -445,17 +440,17 @@ class Test(unittest.TestCase):
offer_id = swap_clients[1].postOffer(Coins.LTC, Coins.PART, 10 * COIN, 9.0 * COIN, 10 * COIN, SwapTypes.SELLER_FIRST)
wait_for_offer(delay_event, swap_clients[0], offer_id)
wait_for_offer(test_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)
wait_for_bid(test_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_in_progress(test_delay_event, swap_clients[0], bid_id, sent=True)
wait_for_bid(delay_event, swap_clients[0], bid_id, BidStates.SWAP_COMPLETED, sent=True, wait_for=60)
wait_for_bid(delay_event, swap_clients[1], bid_id, BidStates.SWAP_COMPLETED, wait_for=60)
wait_for_bid(test_delay_event, swap_clients[0], bid_id, BidStates.SWAP_COMPLETED, sent=True, wait_for=60)
wait_for_bid(test_delay_event, swap_clients[1], bid_id, BidStates.SWAP_COMPLETED, wait_for=60)
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())
@ -468,17 +463,17 @@ class Test(unittest.TestCase):
offer_id = swap_clients[0].postOffer(Coins.LTC, Coins.BTC, 10 * COIN, 0.1 * COIN, 10 * COIN, SwapTypes.SELLER_FIRST)
wait_for_offer(delay_event, swap_clients[1], offer_id)
wait_for_offer(test_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)
wait_for_bid(test_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_in_progress(test_delay_event, swap_clients[1], bid_id, sent=True)
wait_for_bid(delay_event, swap_clients[0], bid_id, BidStates.SWAP_COMPLETED, wait_for=60)
wait_for_bid(delay_event, swap_clients[1], bid_id, BidStates.SWAP_COMPLETED, sent=True, wait_for=60)
wait_for_bid(test_delay_event, swap_clients[0], bid_id, BidStates.SWAP_COMPLETED, wait_for=60)
wait_for_bid(test_delay_event, swap_clients[1], bid_id, BidStates.SWAP_COMPLETED, sent=True, wait_for=60)
js_0bid = json.loads(urlopen('http://127.0.0.1:1800/json/bids/{}'.format(bid_id.hex())).read())
@ -496,16 +491,16 @@ class Test(unittest.TestCase):
offer_id = swap_clients[0].postOffer(Coins.LTC, Coins.BTC, 10 * COIN, 0.1 * COIN, 10 * COIN, SwapTypes.SELLER_FIRST,
SEQUENCE_LOCK_BLOCKS, 10)
wait_for_offer(delay_event, swap_clients[1], offer_id)
wait_for_offer(test_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)
wait_for_bid(test_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)
wait_for_bid(test_delay_event, swap_clients[0], bid_id, BidStates.SWAP_COMPLETED, wait_for=60)
wait_for_bid(test_delay_event, swap_clients[1], bid_id, BidStates.BID_ABANDONED, sent=True, wait_for=60)
js_0_bid = json.loads(urlopen('http://127.0.0.1:1800/json/bids/{}'.format(bid_id.hex())).read())
js_1_bid = json.loads(urlopen('http://127.0.0.1:1801/json/bids/{}'.format(bid_id.hex())).read())
@ -525,16 +520,16 @@ class Test(unittest.TestCase):
offer_id = swap_clients[0].postOffer(Coins.BTC, Coins.LTC, 10 * COIN, 10 * COIN, 10 * COIN, SwapTypes.SELLER_FIRST)
wait_for_offer(delay_event, swap_clients[0], offer_id)
wait_for_offer(test_delay_event, swap_clients[0], offer_id)
offer = swap_clients[0].getOffer(offer_id)
offers = swap_clients[0].listOffers()
bid_id = swap_clients[0].postBid(offer_id, offer.amount_from)
wait_for_bid(delay_event, swap_clients[0], bid_id)
wait_for_bid(test_delay_event, swap_clients[0], bid_id)
swap_clients[0].acceptBid(bid_id)
wait_for_bid_tx_state(delay_event, swap_clients[0], bid_id, TxStates.TX_REDEEMED, TxStates.TX_REDEEMED, wait_for=60)
wait_for_bid(delay_event, swap_clients[0], bid_id, BidStates.SWAP_COMPLETED, wait_for=60)
wait_for_bid_tx_state(test_delay_event, swap_clients[0], bid_id, TxStates.TX_REDEEMED, TxStates.TX_REDEEMED, wait_for=60)
wait_for_bid(test_delay_event, swap_clients[0], bid_id, BidStates.SWAP_COMPLETED, wait_for=60)
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)
@ -548,16 +543,16 @@ class Test(unittest.TestCase):
offer_id = swap_clients[0].postOffer(Coins.BTC, Coins.LTC, 0.001 * COIN, 1.0 * COIN, 0.001 * COIN, SwapTypes.SELLER_FIRST)
wait_for_offer(delay_event, swap_clients[0], offer_id)
wait_for_offer(test_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)
wait_for_bid(test_delay_event, swap_clients[0], bid_id)
swap_clients[0].acceptBid(bid_id)
swap_clients[0].getChainClientSettings(Coins.BTC)['override_feerate'] = 10.0
swap_clients[0].getChainClientSettings(Coins.LTC)['override_feerate'] = 10.0
wait_for_bid(delay_event, swap_clients[0], bid_id, BidStates.BID_ERROR, wait_for=60)
wait_for_bid(test_delay_event, swap_clients[0], bid_id, BidStates.BID_ERROR, wait_for=60)
swap_clients[0].abandonBid(bid_id)
del swap_clients[0].getChainClientSettings(Coins.BTC)['override_feerate']
@ -577,15 +572,15 @@ class Test(unittest.TestCase):
offer_id = swap_clients[0].postOffer(Coins.PART, Coins.LTC, 100 * COIN, 0.1 * COIN, 100 * COIN, SwapTypes.SELLER_FIRST, auto_accept_bids=True)
wait_for_offer(delay_event, swap_clients[1], offer_id)
wait_for_offer(test_delay_event, swap_clients[1], offer_id)
offers = swap_clients[1].listOffers()
assert(len(offers) >= 1)
for offer in offers:
if offer.offer_id == offer_id:
bid_id = swap_clients[1].postBid(offer_id, offer.amount_from)
wait_for_bid(delay_event, swap_clients[0], bid_id, BidStates.SWAP_COMPLETED, wait_for=60)
wait_for_bid(delay_event, swap_clients[1], bid_id, BidStates.SWAP_COMPLETED, sent=True, wait_for=60)
wait_for_bid(test_delay_event, swap_clients[0], bid_id, BidStates.SWAP_COMPLETED, wait_for=60)
wait_for_bid(test_delay_event, swap_clients[1], bid_id, BidStates.SWAP_COMPLETED, sent=True, wait_for=60)
def test_10_bad_ptx(self):
# Invalid PTX sent, swap should stall and ITx and PTx should be reclaimed by senders
@ -597,16 +592,16 @@ class Test(unittest.TestCase):
offer_id = swap_clients[0].postOffer(Coins.LTC, Coins.BTC, swap_value, 0.1 * COIN, swap_value, SwapTypes.SELLER_FIRST,
SEQUENCE_LOCK_BLOCKS, 10)
wait_for_offer(delay_event, swap_clients[1], offer_id)
wait_for_offer(test_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)
swap_clients[1].setBidDebugInd(bid_id, DebugTypes.MAKE_INVALID_PTX)
wait_for_bid(delay_event, swap_clients[0], bid_id)
wait_for_bid(test_delay_event, swap_clients[0], bid_id)
swap_clients[0].acceptBid(bid_id)
wait_for_bid(delay_event, swap_clients[0], bid_id, BidStates.SWAP_COMPLETED, wait_for=120)
wait_for_bid(delay_event, swap_clients[1], bid_id, BidStates.SWAP_COMPLETED, sent=True, wait_for=120)
wait_for_bid(test_delay_event, swap_clients[0], bid_id, BidStates.SWAP_COMPLETED, wait_for=120)
wait_for_bid(test_delay_event, swap_clients[1], bid_id, BidStates.SWAP_COMPLETED, sent=True, wait_for=120)
js_0_bid = json.loads(urlopen('http://127.0.0.1:1800/json/bids/{}'.format(bid_id.hex())).read())
js_1_bid = json.loads(urlopen('http://127.0.0.1:1801/json/bids/{}'.format(bid_id.hex())).read())
@ -629,16 +624,16 @@ class Test(unittest.TestCase):
offer_id = swap_clients[0].postOffer(Coins.LTC, Coins.BTC, swap_value, 0.1 * COIN, swap_value, SwapTypes.SELLER_FIRST,
SEQUENCE_LOCK_BLOCKS, 10)
wait_for_offer(delay_event, swap_clients[1], offer_id)
wait_for_offer(test_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)
swap_clients[1].setBidDebugInd(bid_id, DebugTypes.BUYER_STOP_AFTER_ITX)
wait_for_bid(delay_event, swap_clients[0], bid_id)
wait_for_bid(test_delay_event, swap_clients[0], bid_id)
swap_clients[0].acceptBid(bid_id)
wait_for_bid(delay_event, swap_clients[0], bid_id, BidStates.SWAP_COMPLETED, wait_for=120)
wait_for_bid(delay_event, swap_clients[1], bid_id, BidStates.BID_ABANDONED, sent=True, wait_for=120)
wait_for_bid(test_delay_event, swap_clients[0], bid_id, BidStates.SWAP_COMPLETED, wait_for=120)
wait_for_bid(test_delay_event, swap_clients[1], bid_id, BidStates.BID_ABANDONED, sent=True, wait_for=120)
js_0_bid = json.loads(urlopen('http://127.0.0.1:1800/json/bids/{}'.format(bid_id.hex())).read())
js_1_bid = json.loads(urlopen('http://127.0.0.1:1801/json/bids/{}'.format(bid_id.hex())).read())
@ -652,20 +647,17 @@ class Test(unittest.TestCase):
'''
def pass_99_delay(self):
global stop_test
logging.info('Delay')
for i in range(60 * 10):
if stop_test:
if test_delay_event.is_set():
break
time.sleep(1)
test_delay_event.wait(1)
print('delay', i)
if i % 2 == 0:
offer_id = self.swap_clients[0].postOffer(Coins.BTC, Coins.LTC, 0.001 * (i + 1) * COIN, 1.0 * (i + 1) * COIN, 0.001 * (i + 1) * COIN, SwapTypes.SELLER_FIRST)
else:
offer_id = self.swap_clients[1].postOffer(Coins.LTC, Coins.BTC, 0.001 * (i + 1) * COIN, 1.0 * (i + 1) * COIN, 0.001 * COIN, SwapTypes.SELLER_FIRST)
stop_test = True
if __name__ == '__main__':
unittest.main()

View file

@ -59,6 +59,8 @@ from tests.basicswap.common import (
wait_for_offer,
wait_for_no_offer,
wait_for_none_active,
wait_for_balance,
post_json_req,
TEST_HTTP_HOST,
TEST_HTTP_PORT,
BASE_RPC_PORT,
@ -82,8 +84,7 @@ XMR_BASE_RPC_PORT = 21792
XMR_BASE_ZMQ_PORT = 22792
XMR_BASE_WALLET_RPC_PORT = 23792
delay_event = threading.Event()
stop_test = False
test_delay_event = threading.Event()
def prepareXmrDataDir(datadir, node_id, conf_file):
@ -203,10 +204,8 @@ def btcRpc(cmd, node_id=0):
def signal_handler(sig, frame):
global stop_test
logging.info('signal {} detected.'.format(sig))
stop_test = True
delay_event.set()
test_delay_event.set()
def waitForXMRNode(rpc_offset, max_tries=7):
@ -239,7 +238,7 @@ def callnoderpc(node_id, method, params=[], wallet=None, base_rpc_port=BASE_RPC_
def run_coins_loop(cls):
while not stop_test:
while not test_delay_event.is_set():
try:
if cls.btc_addr is not None:
btcRpc('generatetoaddress 1 {}'.format(cls.btc_addr))
@ -247,14 +246,14 @@ def run_coins_loop(cls):
callrpc_xmr_na(XMR_BASE_RPC_PORT + 1, 'generateblocks', {'wallet_address': cls.xmr_addr, 'amount_of_blocks': 1})
except Exception as e:
logging.warning('run_coins_loop ' + str(e))
time.sleep(1.0)
test_delay_event.wait(1.0)
def run_loop(cls):
while not stop_test:
while not test_delay_event.is_set():
for c in cls.swap_clients:
c.update()
time.sleep(1.0)
test_delay_event.wait(1.0)
class Test(unittest.TestCase):
@ -401,9 +400,8 @@ class Test(unittest.TestCase):
@classmethod
def tearDownClass(cls):
global stop_test
logging.info('Finalising')
stop_test = True
test_delay_event.set()
if cls.update_thread is not None:
try:
cls.update_thread.join()
@ -440,22 +438,22 @@ class Test(unittest.TestCase):
assert(make_int(js_1[str(int(Coins.XMR))]['unconfirmed'], scale=12) > 0)
offer_id = swap_clients[0].postOffer(Coins.PART, Coins.XMR, 100 * COIN, 0.11 * XMR_COIN, 100 * COIN, SwapTypes.XMR_SWAP)
wait_for_offer(delay_event, swap_clients[1], offer_id)
wait_for_offer(test_delay_event, swap_clients[1], offer_id)
offers = swap_clients[1].listOffers(filters={'offer_id': offer_id})
assert(len(offers) == 1)
offer = offers[0]
bid_id = swap_clients[1].postXmrBid(offer_id, offer.amount_from)
wait_for_bid(delay_event, swap_clients[0], bid_id, BidStates.BID_RECEIVED)
wait_for_bid(test_delay_event, swap_clients[0], bid_id, BidStates.BID_RECEIVED)
bid, xmr_swap = swap_clients[0].getXmrBid(bid_id)
assert(xmr_swap)
swap_clients[0].acceptXmrBid(bid_id)
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)
wait_for_bid(test_delay_event, swap_clients[0], bid_id, BidStates.SWAP_COMPLETED, wait_for=180)
wait_for_bid(test_delay_event, swap_clients[1], bid_id, BidStates.SWAP_COMPLETED, sent=True)
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'])
@ -470,12 +468,12 @@ class Test(unittest.TestCase):
offer_id = swap_clients[0].postOffer(
Coins.PART, Coins.XMR, 101 * COIN, 0.12 * XMR_COIN, 101 * COIN, SwapTypes.XMR_SWAP,
lock_type=SEQUENCE_LOCK_BLOCKS, lock_value=12)
wait_for_offer(delay_event, swap_clients[1], offer_id)
wait_for_offer(test_delay_event, swap_clients[1], offer_id)
offer = swap_clients[1].getOffer(offer_id)
bid_id = swap_clients[1].postXmrBid(offer_id, offer.amount_from)
wait_for_bid(delay_event, swap_clients[0], bid_id, BidStates.BID_RECEIVED)
wait_for_bid(test_delay_event, swap_clients[0], bid_id, BidStates.BID_RECEIVED)
bid, xmr_swap = swap_clients[0].getXmrBid(bid_id)
assert(xmr_swap)
@ -484,8 +482,8 @@ class Test(unittest.TestCase):
swap_clients[0].acceptXmrBid(bid_id)
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)
wait_for_bid(test_delay_event, swap_clients[0], bid_id, BidStates.XMR_SWAP_FAILED_REFUNDED, wait_for=180)
wait_for_bid(test_delay_event, swap_clients[1], bid_id, BidStates.XMR_SWAP_FAILED_REFUNDED, sent=True)
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))
@ -500,12 +498,12 @@ class Test(unittest.TestCase):
offer_id = swap_clients[0].postOffer(
Coins.PART, Coins.XMR, 101 * COIN, 0.13 * XMR_COIN, 101 * COIN, SwapTypes.XMR_SWAP,
lock_type=SEQUENCE_LOCK_BLOCKS, lock_value=12)
wait_for_offer(delay_event, swap_clients[1], offer_id)
wait_for_offer(test_delay_event, swap_clients[1], offer_id)
offer = swap_clients[1].getOffer(offer_id)
bid_id = swap_clients[1].postXmrBid(offer_id, offer.amount_from)
wait_for_bid(delay_event, swap_clients[0], bid_id, BidStates.BID_RECEIVED)
wait_for_bid(test_delay_event, swap_clients[0], bid_id, BidStates.BID_RECEIVED)
bid, xmr_swap = swap_clients[0].getXmrBid(bid_id)
assert(xmr_swap)
@ -515,13 +513,13 @@ class Test(unittest.TestCase):
swap_clients[0].acceptXmrBid(bid_id)
wait_for_bid(delay_event, swap_clients[0], bid_id, BidStates.BID_STALLED_FOR_TEST, wait_for=180)
wait_for_bid(delay_event, swap_clients[1], bid_id, BidStates.XMR_SWAP_FAILED_SWIPED, wait_for=80, sent=True)
wait_for_bid(test_delay_event, swap_clients[0], bid_id, BidStates.BID_STALLED_FOR_TEST, wait_for=180)
wait_for_bid(test_delay_event, swap_clients[1], bid_id, BidStates.XMR_SWAP_FAILED_SWIPED, wait_for=80, sent=True)
js_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)
wait_for_none_active(test_delay_event, 1800)
wait_for_none_active(test_delay_event, 1801)
def test_04_follower_recover_b_lock_tx(self):
logging.info('---------- Test PART to XMR follower recovers coin b lock tx')
@ -531,12 +529,12 @@ class Test(unittest.TestCase):
offer_id = swap_clients[0].postOffer(
Coins.PART, Coins.XMR, 101 * COIN, 0.14 * XMR_COIN, 101 * COIN, SwapTypes.XMR_SWAP,
lock_type=SEQUENCE_LOCK_BLOCKS, lock_value=18)
wait_for_offer(delay_event, swap_clients[1], offer_id)
wait_for_offer(test_delay_event, swap_clients[1], offer_id)
offer = swap_clients[1].getOffer(offer_id)
bid_id = swap_clients[1].postXmrBid(offer_id, offer.amount_from)
wait_for_bid(delay_event, swap_clients[0], bid_id, BidStates.BID_RECEIVED)
wait_for_bid(test_delay_event, swap_clients[0], bid_id, BidStates.BID_RECEIVED)
bid, xmr_swap = swap_clients[0].getXmrBid(bid_id)
assert(xmr_swap)
@ -545,14 +543,14 @@ class Test(unittest.TestCase):
swap_clients[0].acceptXmrBid(bid_id)
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)
wait_for_bid(test_delay_event, swap_clients[0], bid_id, BidStates.XMR_SWAP_FAILED_REFUNDED, wait_for=180)
wait_for_bid(test_delay_event, swap_clients[1], bid_id, BidStates.XMR_SWAP_FAILED_REFUNDED, sent=True)
def test_05_btc_xmr(self):
logging.info('---------- Test BTC to XMR')
swap_clients = self.swap_clients
offer_id = swap_clients[0].postOffer(Coins.BTC, Coins.XMR, 10 * COIN, 100 * XMR_COIN, 10 * COIN, SwapTypes.XMR_SWAP)
wait_for_offer(delay_event, swap_clients[1], offer_id)
wait_for_offer(test_delay_event, swap_clients[1], offer_id)
offers = swap_clients[1].listOffers(filters={'offer_id': offer_id})
offer = offers[0]
@ -560,15 +558,15 @@ class Test(unittest.TestCase):
bid_id = swap_clients[1].postXmrBid(offer_id, offer.amount_from)
wait_for_bid(delay_event, swap_clients[0], bid_id, BidStates.BID_RECEIVED)
wait_for_bid(test_delay_event, swap_clients[0], bid_id, BidStates.BID_RECEIVED)
bid, xmr_swap = swap_clients[0].getXmrBid(bid_id)
assert(xmr_swap)
swap_clients[0].acceptXmrBid(bid_id)
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)
wait_for_bid(test_delay_event, swap_clients[0], bid_id, BidStates.SWAP_COMPLETED, wait_for=180)
wait_for_bid(test_delay_event, swap_clients[1], bid_id, BidStates.SWAP_COMPLETED, sent=True)
swap_clients[1].ci(Coins.XMR).setFeePriority(0)
@ -590,9 +588,9 @@ class Test(unittest.TestCase):
offer1_id = swap_clients[0].postOffer(Coins.BTC, Coins.XMR, amt_1, rate_1, amt_1, SwapTypes.XMR_SWAP)
offer2_id = swap_clients[0].postOffer(Coins.PART, Coins.XMR, amt_2, rate_2, amt_2, SwapTypes.XMR_SWAP)
wait_for_offer(delay_event, swap_clients[1], offer1_id)
wait_for_offer(test_delay_event, swap_clients[1], offer1_id)
offer1 = swap_clients[1].getOffer(offer1_id)
wait_for_offer(delay_event, swap_clients[1], offer2_id)
wait_for_offer(test_delay_event, swap_clients[1], offer2_id)
offer2 = swap_clients[1].getOffer(offer2_id)
bid1_id = swap_clients[1].postXmrBid(offer1_id, offer1.amount_from)
@ -600,30 +598,30 @@ class Test(unittest.TestCase):
offer3_id = swap_clients[0].postOffer(Coins.PART, Coins.XMR, 11 * COIN, 0.15 * XMR_COIN, 11 * COIN, SwapTypes.XMR_SWAP)
wait_for_bid(delay_event, swap_clients[0], bid1_id, BidStates.BID_RECEIVED)
wait_for_bid(test_delay_event, swap_clients[0], bid1_id, BidStates.BID_RECEIVED)
swap_clients[0].acceptXmrBid(bid1_id)
wait_for_offer(delay_event, swap_clients[1], offer3_id)
wait_for_offer(test_delay_event, swap_clients[1], offer3_id)
offer3 = swap_clients[1].getOffer(offer3_id)
bid3_id = swap_clients[1].postXmrBid(offer3_id, offer3.amount_from)
wait_for_bid(delay_event, swap_clients[0], bid2_id, BidStates.BID_RECEIVED)
wait_for_bid(test_delay_event, swap_clients[0], bid2_id, BidStates.BID_RECEIVED)
swap_clients[0].acceptXmrBid(bid2_id)
wait_for_bid(delay_event, swap_clients[0], bid3_id, BidStates.BID_RECEIVED)
wait_for_bid(test_delay_event, swap_clients[0], bid3_id, BidStates.BID_RECEIVED)
swap_clients[0].acceptXmrBid(bid3_id)
wait_for_bid(delay_event, swap_clients[0], bid1_id, BidStates.SWAP_COMPLETED, wait_for=180)
wait_for_bid(delay_event, swap_clients[1], bid1_id, BidStates.SWAP_COMPLETED, sent=True)
wait_for_bid(test_delay_event, swap_clients[0], bid1_id, BidStates.SWAP_COMPLETED, wait_for=180)
wait_for_bid(test_delay_event, swap_clients[1], bid1_id, BidStates.SWAP_COMPLETED, sent=True)
wait_for_bid(delay_event, swap_clients[0], bid2_id, BidStates.SWAP_COMPLETED, wait_for=120)
wait_for_bid(delay_event, swap_clients[1], bid2_id, BidStates.SWAP_COMPLETED, sent=True)
wait_for_bid(test_delay_event, swap_clients[0], bid2_id, BidStates.SWAP_COMPLETED, wait_for=120)
wait_for_bid(test_delay_event, swap_clients[1], bid2_id, BidStates.SWAP_COMPLETED, sent=True)
wait_for_bid(delay_event, swap_clients[0], bid3_id, BidStates.SWAP_COMPLETED, wait_for=120)
wait_for_bid(delay_event, swap_clients[1], bid3_id, BidStates.SWAP_COMPLETED, sent=True)
wait_for_bid(test_delay_event, swap_clients[0], bid3_id, BidStates.SWAP_COMPLETED, wait_for=120)
wait_for_bid(test_delay_event, swap_clients[1], bid3_id, BidStates.SWAP_COMPLETED, sent=True)
wait_for_none_active(delay_event, 1800)
wait_for_none_active(delay_event, 1801)
wait_for_none_active(test_delay_event, 1800)
wait_for_none_active(test_delay_event, 1801)
js_w0_after = json.loads(urlopen('http://127.0.0.1:1800/json/wallets').read())
js_w1_after = json.loads(urlopen('http://127.0.0.1:1801/json/wallets').read())
@ -636,11 +634,11 @@ class Test(unittest.TestCase):
logging.info('---------- Test offer revocaction')
swap_clients = self.swap_clients
offer_id = swap_clients[0].postOffer(Coins.BTC, Coins.XMR, 10 * COIN, 100 * XMR_COIN, 10 * COIN, SwapTypes.XMR_SWAP)
wait_for_offer(delay_event, swap_clients[1], offer_id)
wait_for_offer(test_delay_event, swap_clients[1], offer_id)
swap_clients[0].revokeOffer(offer_id)
wait_for_no_offer(delay_event, swap_clients[1], offer_id)
wait_for_no_offer(test_delay_event, swap_clients[1], offer_id)
def test_08_withdraw(self):
logging.info('---------- Test xmr withdrawals')
@ -658,24 +656,24 @@ class Test(unittest.TestCase):
logging.info('---------- Test BTC to XMR auto accept')
swap_clients = self.swap_clients
offer_id = swap_clients[0].postOffer(Coins.BTC, Coins.XMR, 11 * COIN, 101 * XMR_COIN, 10 * COIN, SwapTypes.XMR_SWAP, auto_accept_bids=True)
wait_for_offer(delay_event, swap_clients[1], offer_id)
wait_for_offer(test_delay_event, swap_clients[1], offer_id)
offer = swap_clients[1].listOffers(filters={'offer_id': offer_id})[0]
bid_id = swap_clients[1].postXmrBid(offer_id, offer.amount_from)
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)
wait_for_bid(test_delay_event, swap_clients[0], bid_id, BidStates.SWAP_COMPLETED, wait_for=180)
wait_for_bid(test_delay_event, swap_clients[1], bid_id, BidStates.SWAP_COMPLETED, sent=True)
def test_10_locked_refundtx(self):
logging.info('---------- Test Refund tx is locked')
swap_clients = self.swap_clients
offer_id = swap_clients[0].postOffer(Coins.BTC, Coins.XMR, 10 * COIN, 100 * XMR_COIN, 10 * COIN, SwapTypes.XMR_SWAP)
wait_for_offer(delay_event, swap_clients[1], offer_id)
wait_for_offer(test_delay_event, swap_clients[1], offer_id)
offers = swap_clients[1].listOffers(filters={'offer_id': offer_id})
offer = offers[0]
bid_id = swap_clients[1].postXmrBid(offer_id, offer.amount_from)
wait_for_bid(delay_event, swap_clients[0], bid_id, BidStates.BID_RECEIVED)
wait_for_bid(test_delay_event, swap_clients[0], bid_id, BidStates.BID_RECEIVED)
bid, xmr_swap = swap_clients[0].getXmrBid(bid_id)
assert(xmr_swap)
@ -684,7 +682,7 @@ class Test(unittest.TestCase):
swap_clients[0].acceptXmrBid(bid_id)
wait_for_bid(delay_event, swap_clients[0], bid_id, BidStates.XMR_SWAP_SCRIPT_COIN_LOCKED, wait_for=180)
wait_for_bid(test_delay_event, swap_clients[0], bid_id, BidStates.XMR_SWAP_SCRIPT_COIN_LOCKED, wait_for=180)
bid, xmr_swap = swap_clients[0].getXmrBid(bid_id)
assert(xmr_swap)
@ -695,6 +693,48 @@ class Test(unittest.TestCase):
except Exception as e:
assert('non-BIP68-final' in str(e))
def test_11_particl_anon(self):
logging.info('---------- Test Particl anon transactions')
swap_clients = self.swap_clients
js_0 = json.loads(urlopen('http://127.0.0.1:1800/json/wallets/part').read())
assert(float(js_0['anon_balance']) == 0.0)
js_1 = json.loads(urlopen('http://127.0.0.1:1801/json/wallets/part').read())
assert(float(js_1['balance']) > 200.0)
post_json = {
'value': 100,
'address': js_0['stealth_address'],
'subfee': False,
'type_to': 'anon',
}
json_rv = json.loads(post_json_req('http://127.0.0.1:1801/json/wallets/part/withdraw', post_json))
assert(len(json_rv['txid']) == 64)
post_json['value'] = 0.5
for i in range(22):
json_rv = json.loads(post_json_req('http://127.0.0.1:1801/json/wallets/part/withdraw', post_json))
assert(len(json_rv['txid']) == 64)
logging.info('Waiting for anon balance')
wait_for_balance(test_delay_event, 'http://127.0.0.1:1800/json/wallets/part', 'anon_balance', 110.0)
post_json = {
'value': 10,
'address': js_0['stealth_address'],
'subfee': True,
'type_from': 'anon',
'type_to': 'blind',
}
json_rv = json.loads(post_json_req('http://127.0.0.1:1800/json/wallets/part/withdraw', post_json))
assert(len(json_rv['txid']) == 64)
logging.info('Waiting for blind balance')
wait_for_balance(test_delay_event, 'http://127.0.0.1:1800/json/wallets/part', 'blind_balance', 9.8)
if float(js_0['blind_balance']) >= 10.0:
raise ValueError('Expect blind balance < 10')
if __name__ == '__main__':
unittest.main()