mirror of
https://github.com/basicswap/basicswap.git
synced 2025-11-05 18:38:09 +01:00
Decred: Secret hash swap tests.
This commit is contained in:
@@ -389,7 +389,7 @@ def extract_states_from_xu_file(file_path, prefix):
|
||||
return states
|
||||
|
||||
|
||||
def compare_bid_states(states, expect_states, exact_match=True):
|
||||
def compare_bid_states(states, expect_states, exact_match: bool = True) -> bool:
|
||||
|
||||
for i in range(len(states) - 1, -1, -1):
|
||||
if states[i][1] == 'Bid Delaying':
|
||||
@@ -417,3 +417,19 @@ def compare_bid_states(states, expect_states, exact_match=True):
|
||||
logging.info('Have states: {}'.format(json.dumps(states, indent=4)))
|
||||
raise e
|
||||
return True
|
||||
|
||||
|
||||
def compare_bid_states_unordered(states, expect_states) -> bool:
|
||||
for i in range(len(states) - 1, -1, -1):
|
||||
if states[i][1] == 'Bid Delaying':
|
||||
del states[i]
|
||||
|
||||
try:
|
||||
assert len(states) == len(expect_states)
|
||||
for state in expect_states:
|
||||
assert (any(state in s[1] for s in states))
|
||||
except Exception as e:
|
||||
logging.info('Expecting states: {}'.format(json.dumps(expect_states, indent=4)))
|
||||
logging.info('Have states: {}'.format(json.dumps(states, indent=4)))
|
||||
raise e
|
||||
return True
|
||||
|
||||
@@ -5,8 +5,13 @@
|
||||
# Distributed under the MIT software license, see the accompanying
|
||||
# file LICENSE or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
# TODO
|
||||
# - Occasionally DCR simnet chain stalls.
|
||||
|
||||
import copy
|
||||
import logging
|
||||
import os
|
||||
import random
|
||||
import select
|
||||
import subprocess
|
||||
import unittest
|
||||
@@ -14,7 +19,14 @@ import unittest
|
||||
import basicswap.config as cfg
|
||||
|
||||
from basicswap.basicswap import (
|
||||
BidStates,
|
||||
Coins,
|
||||
DebugTypes,
|
||||
SwapTypes,
|
||||
TxStates,
|
||||
)
|
||||
from basicswap.basicswap_util import (
|
||||
TxLockTypes,
|
||||
)
|
||||
from basicswap.util.crypto import (
|
||||
hash160
|
||||
@@ -27,9 +39,14 @@ from basicswap.interface.dcr.messages import (
|
||||
TxSerializeType,
|
||||
)
|
||||
from tests.basicswap.common import (
|
||||
compare_bid_states,
|
||||
compare_bid_states_unordered,
|
||||
stopDaemons,
|
||||
waitForRPC,
|
||||
wait_for_balance,
|
||||
wait_for_bid,
|
||||
wait_for_bid_tx_state,
|
||||
wait_for_offer,
|
||||
waitForRPC,
|
||||
)
|
||||
from tests.basicswap.util import (
|
||||
read_json_api,
|
||||
@@ -63,6 +80,176 @@ def make_rpc_func(node_id, base_rpc_port):
|
||||
return rpc_func
|
||||
|
||||
|
||||
def test_success_path(self, coin_from: Coins, coin_to: Coins):
|
||||
logging.info(f'---------- Test {coin_from.name} to {coin_to.name}')
|
||||
|
||||
node_from = 0
|
||||
node_to = 1
|
||||
swap_clients = self.swap_clients
|
||||
ci_from = swap_clients[node_from].ci(coin_from)
|
||||
ci_to = swap_clients[node_to].ci(coin_to)
|
||||
|
||||
self.prepare_balance(coin_to, 100.0, 1801, 1800)
|
||||
self.prepare_balance(coin_from, 100.0, 1800, 1801)
|
||||
|
||||
amt_swap = ci_from.make_int(random.uniform(0.1, 5.0), r=1)
|
||||
rate_swap = ci_to.make_int(random.uniform(0.2, 10.0), r=1)
|
||||
|
||||
offer_id = swap_clients[node_from].postOffer(coin_from, coin_to, amt_swap, rate_swap, amt_swap, SwapTypes.SELLER_FIRST)
|
||||
|
||||
wait_for_offer(test_delay_event, swap_clients[node_to], offer_id)
|
||||
|
||||
offer = swap_clients[node_to].getOffer(offer_id)
|
||||
bid_id = swap_clients[node_to].postBid(offer_id, offer.amount_from)
|
||||
|
||||
wait_for_bid(test_delay_event, swap_clients[node_from], bid_id)
|
||||
swap_clients[node_from].acceptBid(bid_id)
|
||||
|
||||
wait_for_bid(test_delay_event, swap_clients[node_from], bid_id, BidStates.SWAP_COMPLETED, wait_for=120)
|
||||
wait_for_bid(test_delay_event, swap_clients[node_to], bid_id, BidStates.SWAP_COMPLETED, sent=True, wait_for=120)
|
||||
|
||||
# Verify lock tx spends are found in the expected wallets
|
||||
bid, offer = swap_clients[node_from].getBidAndOffer(bid_id)
|
||||
max_fee: int = 10000
|
||||
itx_spend = bid.initiate_tx.spend_txid.hex()
|
||||
node_to_ci_from = swap_clients[node_to].ci(coin_from)
|
||||
wtx = node_to_ci_from.rpc_wallet('gettransaction', [itx_spend,])
|
||||
assert (amt_swap - node_to_ci_from.make_int(wtx['details'][0]['amount']) < max_fee)
|
||||
|
||||
node_from_ci_to = swap_clients[node_from].ci(coin_to)
|
||||
ptx_spend = bid.participate_tx.spend_txid.hex()
|
||||
wtx = node_from_ci_to.rpc_wallet('gettransaction', [ptx_spend,])
|
||||
assert (bid.amount_to - node_from_ci_to.make_int(wtx['details'][0]['amount']) < max_fee)
|
||||
|
||||
js_0 = read_json_api(1800 + node_from)
|
||||
js_1 = read_json_api(1800 + node_to)
|
||||
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)
|
||||
|
||||
bid_id_hex = bid_id.hex()
|
||||
path = f'bids/{bid_id_hex}/states'
|
||||
offerer_states = read_json_api(1800 + node_from, path)
|
||||
bidder_states = read_json_api(1800 + node_to, path)
|
||||
|
||||
expect_states = copy.deepcopy(self.states_offerer_sh[0])
|
||||
# Will miss PTX Sent event as PTX is found by searching the chain.
|
||||
if coin_to == Coins.DCR:
|
||||
expect_states[5] = 'PTX In Chain'
|
||||
assert (compare_bid_states(offerer_states, expect_states) is True)
|
||||
assert (compare_bid_states(bidder_states, self.states_bidder_sh[0]) is True)
|
||||
|
||||
|
||||
def test_bad_ptx(self, coin_from: Coins, coin_to: Coins):
|
||||
# Invalid PTX sent, swap should stall and ITx and PTx should be reclaimed by senders
|
||||
logging.info(f'---------- Test bad ptx {coin_from.name} to {coin_to.name}')
|
||||
|
||||
node_from = 0
|
||||
node_to = 1
|
||||
swap_clients = self.swap_clients
|
||||
ci_from = swap_clients[node_from].ci(coin_from)
|
||||
ci_to = swap_clients[node_to].ci(coin_to)
|
||||
|
||||
self.prepare_balance(coin_to, 100.0, 1801, 1800)
|
||||
self.prepare_balance(coin_from, 100.0, 1800, 1801)
|
||||
|
||||
amt_swap = ci_from.make_int(random.uniform(1.1, 10.0), r=1)
|
||||
rate_swap = ci_to.make_int(random.uniform(0.1, 2.0), r=1)
|
||||
|
||||
offer_id = swap_clients[node_from].postOffer(coin_from, coin_to, amt_swap, rate_swap, amt_swap, SwapTypes.SELLER_FIRST,
|
||||
TxLockTypes.SEQUENCE_LOCK_BLOCKS, 10, auto_accept_bids=True)
|
||||
|
||||
wait_for_offer(test_delay_event, swap_clients[node_to], offer_id)
|
||||
offer = swap_clients[node_to].getOffer(offer_id)
|
||||
bid_id = swap_clients[node_to].postBid(offer_id, offer.amount_from)
|
||||
swap_clients[node_to].setBidDebugInd(bid_id, DebugTypes.MAKE_INVALID_PTX)
|
||||
|
||||
wait_for_bid(test_delay_event, swap_clients[node_from], bid_id, BidStates.SWAP_COMPLETED, wait_for=120)
|
||||
wait_for_bid(test_delay_event, swap_clients[node_to], bid_id, BidStates.SWAP_COMPLETED, sent=True, wait_for=120)
|
||||
|
||||
js_0_bid = read_json_api(1800 + node_from, 'bids/{}'.format(bid_id.hex()))
|
||||
js_1_bid = read_json_api(1800 + node_to, 'bids/{}'.format(bid_id.hex()))
|
||||
assert (js_0_bid['itx_state'] == 'Refunded')
|
||||
assert (js_1_bid['ptx_state'] == 'Refunded')
|
||||
|
||||
# Verify lock tx spends are found in the expected wallets
|
||||
bid, offer = swap_clients[node_from].getBidAndOffer(bid_id)
|
||||
max_fee: int = 10000
|
||||
itx_spend = bid.initiate_tx.spend_txid.hex()
|
||||
node_from_ci_from = swap_clients[node_from].ci(coin_from)
|
||||
wtx = node_from_ci_from.rpc_wallet('gettransaction', [itx_spend,])
|
||||
assert (amt_swap - node_from_ci_from.make_int(wtx['details'][0]['amount']) < max_fee)
|
||||
|
||||
node_to_ci_to = swap_clients[node_to].ci(coin_to)
|
||||
bid, offer = swap_clients[node_to].getBidAndOffer(bid_id)
|
||||
ptx_spend = bid.participate_tx.spend_txid.hex()
|
||||
wtx = node_to_ci_to.rpc_wallet('gettransaction', [ptx_spend,])
|
||||
assert (bid.amount_to - node_to_ci_to.make_int(wtx['details'][0]['amount']) < max_fee)
|
||||
|
||||
bid_id_hex = bid_id.hex()
|
||||
path = f'bids/{bid_id_hex}/states'
|
||||
offerer_states = read_json_api(1800 + node_from, path)
|
||||
bidder_states = read_json_api(1800 + node_to, path)
|
||||
|
||||
# Hard to get the timing right
|
||||
assert (compare_bid_states_unordered(offerer_states, self.states_offerer_sh[1]) is True)
|
||||
assert (compare_bid_states_unordered(bidder_states, self.states_bidder_sh[1]) is True)
|
||||
|
||||
js_0 = read_json_api(1800 + node_from)
|
||||
js_1 = read_json_api(1800 + node_to)
|
||||
assert (js_0['num_swapping'] == 0 and js_0['num_watched_outputs'] == 0)
|
||||
assert (js_1['num_swapping'] == 0 and js_1['num_watched_outputs'] == 0)
|
||||
|
||||
|
||||
def test_itx_refund(self, coin_from: Coins, coin_to: Coins):
|
||||
# Offerer claims PTX and refunds ITX after lock expires
|
||||
# Bidder loses PTX value without gaining ITX value
|
||||
logging.info(f'---------- Test itx refund {coin_from.name} to {coin_to.name}')
|
||||
|
||||
node_from = 0
|
||||
node_to = 1
|
||||
swap_clients = self.swap_clients
|
||||
ci_from = swap_clients[node_from].ci(coin_from)
|
||||
ci_to = swap_clients[node_to].ci(coin_to)
|
||||
|
||||
self.prepare_balance(coin_to, 100.0, 1801, 1800)
|
||||
self.prepare_balance(coin_from, 100.0, 1800, 1801)
|
||||
|
||||
swap_value = ci_from.make_int(random.uniform(2.0, 20.0), r=1)
|
||||
rate_swap = ci_to.make_int(0.5, r=1)
|
||||
offer_id = swap_clients[node_from].postOffer(coin_from, coin_to, swap_value, rate_swap, swap_value, SwapTypes.SELLER_FIRST,
|
||||
TxLockTypes.SEQUENCE_LOCK_BLOCKS, 12)
|
||||
|
||||
wait_for_offer(test_delay_event, swap_clients[node_to], offer_id)
|
||||
offer = swap_clients[node_to].getOffer(offer_id)
|
||||
bid_id = swap_clients[node_to].postBid(offer_id, offer.amount_from)
|
||||
swap_clients[node_to].setBidDebugInd(bid_id, DebugTypes.DONT_SPEND_ITX)
|
||||
|
||||
wait_for_bid(test_delay_event, swap_clients[node_from], bid_id)
|
||||
|
||||
# For testing: Block refunding the ITX until PTX has been redeemed, else ITX refund can become spendable before PTX confirms
|
||||
swap_clients[node_from].setBidDebugInd(bid_id, DebugTypes.SKIP_LOCK_TX_REFUND)
|
||||
swap_clients[node_from].acceptBid(bid_id)
|
||||
wait_for_bid_tx_state(test_delay_event, swap_clients[node_from], bid_id, TxStates.TX_CONFIRMED, TxStates.TX_REDEEMED, wait_for=120)
|
||||
swap_clients[node_from].setBidDebugInd(bid_id, DebugTypes.NONE)
|
||||
|
||||
wait_for_bid_tx_state(test_delay_event, swap_clients[node_from], bid_id, TxStates.TX_REFUNDED, TxStates.TX_REDEEMED, wait_for=90)
|
||||
|
||||
wait_for_bid(test_delay_event, swap_clients[0], bid_id, BidStates.SWAP_COMPLETED, wait_for=60)
|
||||
|
||||
# Verify lock tx spends are found in the expected wallets
|
||||
bid, offer = swap_clients[node_from].getBidAndOffer(bid_id)
|
||||
max_fee: int = 10000
|
||||
itx_spend = bid.initiate_tx.spend_txid.hex()
|
||||
node_from_ci_from = swap_clients[node_from].ci(coin_from)
|
||||
wtx = node_from_ci_from.rpc_wallet('gettransaction', [itx_spend,])
|
||||
assert (swap_value - node_from_ci_from.make_int(wtx['details'][0]['amount']) < max_fee)
|
||||
|
||||
node_from_ci_to = swap_clients[node_from].ci(coin_to)
|
||||
ptx_spend = bid.participate_tx.spend_txid.hex()
|
||||
wtx = node_from_ci_to.rpc_wallet('gettransaction', [ptx_spend,])
|
||||
assert (bid.amount_to - node_from_ci_to.make_int(wtx['details'][0]['amount']) < max_fee)
|
||||
|
||||
|
||||
def prepareDCDDataDir(datadir, node_id, conf_file, dir_prefix, num_nodes=3):
|
||||
node_dir = os.path.join(datadir, dir_prefix + str(node_id))
|
||||
if not os.path.exists(node_dir):
|
||||
@@ -326,7 +513,7 @@ class Test(BaseTest):
|
||||
swap_clients = self.swap_clients
|
||||
ci0 = swap_clients[0].ci(self.test_coin)
|
||||
|
||||
utxos = ci0.getNewAddress()
|
||||
utxos = ci0.rpc_wallet('listunspent')
|
||||
addr_out = ci0.rpc_wallet('getnewaddress')
|
||||
rtx = ci0.rpc_wallet('createrawtransaction', [[], {addr_out: 2.0}])
|
||||
|
||||
@@ -530,7 +717,8 @@ class Test(BaseTest):
|
||||
assert (len(unspents) == 1)
|
||||
utxo = unspents[0]
|
||||
|
||||
txout = ci0.rpc('gettxout', [utxo['txid'], utxo['vout'], utxo['tree']])
|
||||
include_mempool: bool = False
|
||||
txout = ci0.rpc('gettxout', [utxo['txid'], utxo['vout'], utxo['tree'], include_mempool])
|
||||
|
||||
# Lock utxo so it's not spent for tickets, while waiting for depth
|
||||
rv = ci0.rpc_wallet('lockunspent', [False, [utxo, ]])
|
||||
@@ -538,7 +726,7 @@ class Test(BaseTest):
|
||||
def wait_for_depth():
|
||||
for i in range(20):
|
||||
logging.info('Waiting for txout depth, iter {}'.format(i))
|
||||
txout = ci0.rpc('gettxout', [utxo['txid'], utxo['vout'], utxo['tree']])
|
||||
txout = ci0.rpc('gettxout', [utxo['txid'], utxo['vout'], utxo['tree'], True])
|
||||
if txout['confirmations'] > 0:
|
||||
return txout
|
||||
test_delay_event.wait(1)
|
||||
@@ -555,11 +743,11 @@ class Test(BaseTest):
|
||||
sent_txid = ci0.rpc_wallet('sendrawtransaction', [stx['hex'], ])
|
||||
|
||||
# NOTE: UTXO is still found when spent in the mempool (tested in loop, not delay from wallet to core)
|
||||
txout = ci0.rpc('gettxout', [utxo['txid'], utxo['vout'], utxo['tree']])
|
||||
txout = ci0.rpc('gettxout', [utxo['txid'], utxo['vout'], utxo['tree'], include_mempool])
|
||||
assert (addr in txout['scriptPubKey']['addresses'])
|
||||
|
||||
for i in range(20):
|
||||
txout = ci0.rpc('gettxout', [utxo['txid'], utxo['vout'], utxo['tree']])
|
||||
txout = ci0.rpc('gettxout', [utxo['txid'], utxo['vout'], utxo['tree'], include_mempool])
|
||||
if txout is None:
|
||||
logging.info('txout spent, height before spent {}, height spent {}'.format(chain_height_before_send, ci0.getChainHeight()))
|
||||
break
|
||||
@@ -574,6 +762,24 @@ class Test(BaseTest):
|
||||
amount_proved = ci0.verifyProofOfFunds(funds_proof[0], funds_proof[1], funds_proof[2], 'test'.encode('utf-8'))
|
||||
assert (amount_proved >= require_amount)
|
||||
|
||||
def test_02_part_coin(self):
|
||||
test_success_path(self, Coins.PART, self.test_coin)
|
||||
|
||||
def test_03_coin_part(self):
|
||||
test_success_path(self, self.test_coin, Coins.PART)
|
||||
|
||||
def test_04_part_coin_bad_ptx(self):
|
||||
test_bad_ptx(self, Coins.PART, self.test_coin)
|
||||
|
||||
def test_05_coin_part_bad_ptx(self):
|
||||
test_bad_ptx(self, self.test_coin, Coins.PART)
|
||||
|
||||
def test_06_part_coin_itx_refund(self):
|
||||
test_itx_refund(self, Coins.PART, self.test_coin)
|
||||
|
||||
def test_07_coin_part_itx_refund(self):
|
||||
test_itx_refund(self, self.test_coin, Coins.PART)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
@@ -319,7 +319,6 @@ class Test(unittest.TestCase):
|
||||
ci_btc = BTCInterface(coin_settings, 'regtest')
|
||||
|
||||
for i in range(10000):
|
||||
|
||||
test_pairs = random.randint(0, 3)
|
||||
if test_pairs == 0:
|
||||
ci_from = ci_btc
|
||||
@@ -425,6 +424,9 @@ class Test(unittest.TestCase):
|
||||
msg_buf_v2.ParseFromString(serialised_msg)
|
||||
assert (msg_buf_v2.protocol_version == 2)
|
||||
assert (msg_buf_v2.time_valid == 1024)
|
||||
assert (msg_buf_v2.amount == 0)
|
||||
assert (msg_buf_v2.pkhash_buyer is not None)
|
||||
assert (len(msg_buf_v2.pkhash_buyer) == 0)
|
||||
|
||||
# Decode only the first field
|
||||
msg_buf_v2.ParseFromString(serialised_msg[:2])
|
||||
|
||||
@@ -13,17 +13,16 @@ $ pytest -v -s tests/basicswap/test_run.py::Test::test_04_ltc_btc
|
||||
|
||||
"""
|
||||
|
||||
import os
|
||||
import random
|
||||
import logging
|
||||
import unittest
|
||||
|
||||
from basicswap.basicswap import (
|
||||
Coins,
|
||||
SwapTypes,
|
||||
BidStates,
|
||||
TxStates,
|
||||
Coins,
|
||||
DebugTypes,
|
||||
SwapTypes,
|
||||
TxStates,
|
||||
)
|
||||
from basicswap.basicswap_util import (
|
||||
TxLockTypes,
|
||||
@@ -40,24 +39,23 @@ from tests.basicswap.util import (
|
||||
read_json_api,
|
||||
)
|
||||
from tests.basicswap.common import (
|
||||
wait_for_offer,
|
||||
wait_for_bid,
|
||||
wait_for_balance,
|
||||
wait_for_unspent,
|
||||
wait_for_bid_tx_state,
|
||||
wait_for_in_progress,
|
||||
TEST_HTTP_PORT,
|
||||
LTC_BASE_RPC_PORT,
|
||||
BTC_BASE_RPC_PORT,
|
||||
compare_bid_states,
|
||||
extract_states_from_xu_file,
|
||||
LTC_BASE_RPC_PORT,
|
||||
TEST_HTTP_PORT,
|
||||
wait_for_balance,
|
||||
wait_for_bid,
|
||||
wait_for_bid_tx_state,
|
||||
wait_for_in_progress,
|
||||
wait_for_offer,
|
||||
wait_for_unspent,
|
||||
)
|
||||
from basicswap.contrib.test_framework.messages import (
|
||||
ToHex,
|
||||
CTxIn,
|
||||
COutPoint,
|
||||
CTransaction,
|
||||
CTxIn,
|
||||
CTxInWitness,
|
||||
ToHex,
|
||||
)
|
||||
from basicswap.contrib.test_framework.script import (
|
||||
CScript,
|
||||
@@ -88,10 +86,6 @@ class Test(BaseTest):
|
||||
wait_for_balance(test_delay_event, 'http://127.0.0.1:1801/json/wallets/btc', 'balance', 1000.0)
|
||||
wait_for_balance(test_delay_event, 'http://127.0.0.1:1801/json/wallets/ltc', 'balance', 1000.0)
|
||||
|
||||
diagrams_dir = 'doc/protocols/sequence_diagrams'
|
||||
cls.states_bidder = extract_states_from_xu_file(os.path.join(diagrams_dir, 'bidder.alt.xu'), 'B')
|
||||
cls.states_offerer = extract_states_from_xu_file(os.path.join(diagrams_dir, 'offerer.alt.xu'), 'O')
|
||||
|
||||
# Wait for height, or sequencelock is thrown off by genesis blocktime
|
||||
cls.waitForParticlHeight(3)
|
||||
|
||||
@@ -329,7 +323,8 @@ class Test(BaseTest):
|
||||
logging.info('---------- Test PART to LTC')
|
||||
swap_clients = self.swap_clients
|
||||
|
||||
offer_id = swap_clients[0].postOffer(Coins.PART, Coins.LTC, 100 * COIN, 0.1 * COIN, 100 * COIN, SwapTypes.SELLER_FIRST)
|
||||
swap_value = 100 * COIN
|
||||
offer_id = swap_clients[0].postOffer(Coins.PART, Coins.LTC, swap_value, 0.1 * COIN, swap_value, SwapTypes.SELLER_FIRST)
|
||||
|
||||
wait_for_offer(test_delay_event, swap_clients[1], offer_id)
|
||||
offer = swap_clients[1].getOffer(offer_id)
|
||||
@@ -341,21 +336,34 @@ class Test(BaseTest):
|
||||
|
||||
wait_for_in_progress(test_delay_event, swap_clients[1], bid_id, sent=True)
|
||||
|
||||
wait_for_bid(test_delay_event, swap_clients[0], bid_id, BidStates.SWAP_COMPLETED, wait_for=60)
|
||||
wait_for_bid(test_delay_event, swap_clients[1], bid_id, BidStates.SWAP_COMPLETED, sent=True, wait_for=60)
|
||||
wait_for_bid(test_delay_event, swap_clients[0], bid_id, BidStates.SWAP_COMPLETED, wait_for=80)
|
||||
wait_for_bid(test_delay_event, swap_clients[1], bid_id, BidStates.SWAP_COMPLETED, sent=True, wait_for=80)
|
||||
|
||||
js_0 = read_json_api(1800)
|
||||
js_1 = read_json_api(1801)
|
||||
assert (js_0['num_swapping'] == 0 and js_0['num_watched_outputs'] == 0)
|
||||
assert (js_1['num_swapping'] == 0 and js_1['num_watched_outputs'] == 0)
|
||||
# Verify lock tx spends are found in the expected wallets
|
||||
bid, offer = swap_clients[0].getBidAndOffer(bid_id)
|
||||
max_fee: int = 1000
|
||||
itx_spend = bid.initiate_tx.spend_txid.hex()
|
||||
ci_node_1_from = swap_clients[1].ci(Coins.PART)
|
||||
wtx = ci_node_1_from.rpc_wallet('gettransaction', [itx_spend,])
|
||||
assert (swap_value - ci_node_1_from.make_int(wtx['details'][0]['amount']) < max_fee)
|
||||
|
||||
ci_node_0_to = swap_clients[0].ci(Coins.LTC)
|
||||
ptx_spend = bid.participate_tx.spend_txid.hex()
|
||||
wtx = ci_node_0_to.rpc_wallet('gettransaction', [ptx_spend,])
|
||||
assert (bid.amount_to - ci_node_0_to.make_int(wtx['details'][0]['amount']) < max_fee)
|
||||
|
||||
bid_id_hex = bid_id.hex()
|
||||
path = f'bids/{bid_id_hex}/states'
|
||||
offerer_states = read_json_api(1800, path)
|
||||
bidder_states = read_json_api(1801, path)
|
||||
|
||||
assert (compare_bid_states(offerer_states, self.states_offerer[0]) is True)
|
||||
assert (compare_bid_states(bidder_states, self.states_bidder[0]) is True)
|
||||
assert (compare_bid_states(offerer_states, self.states_offerer_sh[0]) is True)
|
||||
assert (compare_bid_states(bidder_states, self.states_bidder_sh[0]) is True)
|
||||
|
||||
js_0 = read_json_api(1800)
|
||||
js_1 = read_json_api(1801)
|
||||
assert (js_0['num_swapping'] == 0 and js_0['num_watched_outputs'] == 0)
|
||||
assert (js_1['num_swapping'] == 0 and js_1['num_watched_outputs'] == 0)
|
||||
|
||||
def test_03_ltc_part(self):
|
||||
logging.info('---------- Test LTC to PART')
|
||||
@@ -372,8 +380,8 @@ class Test(BaseTest):
|
||||
|
||||
wait_for_in_progress(test_delay_event, swap_clients[0], bid_id, sent=True)
|
||||
|
||||
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)
|
||||
wait_for_bid(test_delay_event, swap_clients[0], bid_id, BidStates.SWAP_COMPLETED, sent=True, wait_for=80)
|
||||
wait_for_bid(test_delay_event, swap_clients[1], bid_id, BidStates.SWAP_COMPLETED, wait_for=80)
|
||||
|
||||
js_0 = read_json_api(1800)
|
||||
js_1 = read_json_api(1801)
|
||||
@@ -395,8 +403,8 @@ class Test(BaseTest):
|
||||
|
||||
wait_for_in_progress(test_delay_event, swap_clients[1], bid_id, sent=True)
|
||||
|
||||
wait_for_bid(test_delay_event, swap_clients[0], bid_id, BidStates.SWAP_COMPLETED, wait_for=60)
|
||||
wait_for_bid(test_delay_event, swap_clients[1], bid_id, BidStates.SWAP_COMPLETED, sent=True, wait_for=60)
|
||||
wait_for_bid(test_delay_event, swap_clients[0], bid_id, BidStates.SWAP_COMPLETED, wait_for=80)
|
||||
wait_for_bid(test_delay_event, swap_clients[1], bid_id, BidStates.SWAP_COMPLETED, sent=True, wait_for=80)
|
||||
|
||||
js_0 = read_json_api(1800)
|
||||
js_1 = read_json_api(1801)
|
||||
@@ -419,8 +427,8 @@ class Test(BaseTest):
|
||||
read_json_api(1801, 'bids/{}'.format(bid_id.hex()), {'abandon': True})
|
||||
swap_clients[0].acceptBid(bid_id)
|
||||
|
||||
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)
|
||||
wait_for_bid(test_delay_event, swap_clients[0], bid_id, BidStates.SWAP_COMPLETED, wait_for=80)
|
||||
wait_for_bid(test_delay_event, swap_clients[1], bid_id, BidStates.BID_ABANDONED, sent=True, wait_for=80)
|
||||
|
||||
js_0_bid = read_json_api(1800, 'bids/{}'.format(bid_id.hex()))
|
||||
js_1_bid = read_json_api(1801, 'bids/{}'.format(bid_id.hex()))
|
||||
@@ -437,7 +445,7 @@ class Test(BaseTest):
|
||||
offerer_states = read_json_api(1800, path)
|
||||
bidder_states = read_json_api(1801, path)
|
||||
|
||||
assert (compare_bid_states(offerer_states, self.states_offerer[1]) is True)
|
||||
assert (compare_bid_states(offerer_states, self.states_offerer_sh[1]) is True)
|
||||
assert (bidder_states[-1][1] == 'Bid Abandoned')
|
||||
|
||||
def test_06_self_bid(self):
|
||||
@@ -455,8 +463,8 @@ class Test(BaseTest):
|
||||
wait_for_bid(test_delay_event, swap_clients[0], bid_id)
|
||||
swap_clients[0].acceptBid(bid_id)
|
||||
|
||||
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)
|
||||
wait_for_bid_tx_state(test_delay_event, swap_clients[0], bid_id, TxStates.TX_REDEEMED, TxStates.TX_REDEEMED, wait_for=80)
|
||||
wait_for_bid(test_delay_event, swap_clients[0], bid_id, BidStates.SWAP_COMPLETED, wait_for=80)
|
||||
|
||||
js_0 = read_json_api(1800)
|
||||
assert (js_0['num_swapping'] == 0 and js_0['num_watched_outputs'] == 0)
|
||||
@@ -504,8 +512,8 @@ class Test(BaseTest):
|
||||
offer = swap_clients[1].getOffer(offer_id)
|
||||
bid_id = swap_clients[1].postBid(offer_id, offer.amount_from)
|
||||
|
||||
wait_for_bid(test_delay_event, swap_clients[0], bid_id, BidStates.SWAP_COMPLETED, wait_for=60)
|
||||
wait_for_bid(test_delay_event, swap_clients[1], bid_id, BidStates.SWAP_COMPLETED, sent=True, wait_for=60)
|
||||
wait_for_bid(test_delay_event, swap_clients[0], bid_id, BidStates.SWAP_COMPLETED, wait_for=80)
|
||||
wait_for_bid(test_delay_event, swap_clients[1], bid_id, BidStates.SWAP_COMPLETED, sent=True, wait_for=80)
|
||||
|
||||
def test_10_bad_ptx(self):
|
||||
# Invalid PTX sent, swap should stall and ITx and PTx should be reclaimed by senders
|
||||
@@ -543,8 +551,8 @@ class Test(BaseTest):
|
||||
offerer_states = read_json_api(1800, path)
|
||||
bidder_states = read_json_api(1801, path)
|
||||
|
||||
assert (compare_bid_states(offerer_states, self.states_offerer[1]) is True)
|
||||
assert (compare_bid_states(bidder_states, self.states_bidder[1]) is True)
|
||||
assert (compare_bid_states(offerer_states, self.states_offerer_sh[1]) is True)
|
||||
assert (compare_bid_states(bidder_states, self.states_bidder_sh[1]) is True)
|
||||
|
||||
'''
|
||||
def test_11_refund(self):
|
||||
@@ -654,8 +662,8 @@ class Test(BaseTest):
|
||||
offerer_states = read_json_api(1800, path)
|
||||
bidder_states = read_json_api(1801, path)
|
||||
|
||||
assert (compare_bid_states(offerer_states, self.states_offerer[2]) is True)
|
||||
assert (compare_bid_states(bidder_states, self.states_bidder[2], exact_match=False) is True)
|
||||
assert (compare_bid_states(offerer_states, self.states_offerer_sh[2]) is True)
|
||||
assert (compare_bid_states(bidder_states, self.states_bidder_sh[2], exact_match=False) is True)
|
||||
|
||||
def test_14_sweep_balance(self):
|
||||
logging.info('---------- Test sweep balance offer')
|
||||
@@ -718,8 +726,8 @@ class Test(BaseTest):
|
||||
wait_for_bid(test_delay_event, swap_clients[2], bid_id)
|
||||
swap_clients[2].acceptBid(bid_id)
|
||||
|
||||
wait_for_bid(test_delay_event, swap_clients[2], bid_id, BidStates.SWAP_COMPLETED, wait_for=60)
|
||||
wait_for_bid(test_delay_event, swap_clients[1], bid_id, BidStates.SWAP_COMPLETED, sent=True, wait_for=60)
|
||||
wait_for_bid(test_delay_event, swap_clients[2], bid_id, BidStates.SWAP_COMPLETED, wait_for=80)
|
||||
wait_for_bid(test_delay_event, swap_clients[1], bid_id, BidStates.SWAP_COMPLETED, sent=True, wait_for=80)
|
||||
|
||||
# Verify expected inputs were used
|
||||
bid, offer = swap_clients[2].getBidAndOffer(bid_id)
|
||||
@@ -753,8 +761,8 @@ class Test(BaseTest):
|
||||
|
||||
wait_for_in_progress(test_delay_event, swap_clients[0], bid_id, sent=True)
|
||||
|
||||
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)
|
||||
wait_for_bid(test_delay_event, swap_clients[0], bid_id, BidStates.SWAP_COMPLETED, sent=True, wait_for=80)
|
||||
wait_for_bid(test_delay_event, swap_clients[1], bid_id, BidStates.SWAP_COMPLETED, wait_for=80)
|
||||
|
||||
def pass_99_delay(self):
|
||||
logging.info('Delay')
|
||||
|
||||
@@ -334,6 +334,9 @@ class BaseTest(unittest.TestCase):
|
||||
cls.states_bidder = extract_states_from_xu_file(os.path.join(diagrams_dir, 'ads.bidder.alt.xu'), 'B')
|
||||
cls.states_offerer = extract_states_from_xu_file(os.path.join(diagrams_dir, 'ads.offerer.alt.xu'), 'O')
|
||||
|
||||
cls.states_bidder_sh = extract_states_from_xu_file(os.path.join(diagrams_dir, 'bidder.alt.xu'), 'B')
|
||||
cls.states_offerer_sh = extract_states_from_xu_file(os.path.join(diagrams_dir, 'offerer.alt.xu'), 'O')
|
||||
|
||||
if os.path.isdir(TEST_DIR):
|
||||
if RESET_TEST:
|
||||
logging.info('Removing ' + TEST_DIR)
|
||||
|
||||
Reference in New Issue
Block a user