mirror of
https://github.com/basicswap/basicswap.git
synced 2024-11-17 08:18:04 +00:00
tests: Add prefunded itx and xmr protocol tests
This commit is contained in:
parent
80df3b1a34
commit
6860279faa
15 changed files with 564 additions and 39 deletions
|
@ -1194,15 +1194,21 @@ class BasicSwap(BaseApp):
|
|||
ensure(amount_to > ci_to.min_amount(), 'To amount below min value for chain')
|
||||
ensure(amount_to < ci_to.max_amount(), 'To amount above max value for chain')
|
||||
|
||||
def validateOfferLockValue(self, coin_from, coin_to, lock_type, lock_value):
|
||||
def validateOfferLockValue(self, swap_type, coin_from, coin_to, lock_type, lock_value):
|
||||
coin_from_has_csv = self.coin_clients[coin_from]['use_csv']
|
||||
coin_to_has_csv = self.coin_clients[coin_to]['use_csv']
|
||||
|
||||
if lock_type == OfferMessage.SEQUENCE_LOCK_TIME:
|
||||
ensure(lock_value >= self.min_sequence_lock_seconds and lock_value <= self.max_sequence_lock_seconds, 'Invalid lock_value time')
|
||||
if swap_type == SwapTypes.XMR_SWAP:
|
||||
ensure(coin_from_has_csv, 'Coin from needs CSV activated.')
|
||||
else:
|
||||
ensure(coin_from_has_csv and coin_to_has_csv, 'Both coins need CSV activated.')
|
||||
elif lock_type == OfferMessage.SEQUENCE_LOCK_BLOCKS:
|
||||
ensure(lock_value >= 5 and lock_value <= 1000, 'Invalid lock_value blocks')
|
||||
if swap_type == SwapTypes.XMR_SWAP:
|
||||
ensure(coin_from_has_csv, 'Coin from needs CSV activated.')
|
||||
else:
|
||||
ensure(coin_from_has_csv and coin_to_has_csv, 'Both coins need CSV activated.')
|
||||
elif lock_type == TxLockTypes.ABS_LOCK_TIME:
|
||||
# TODO: range?
|
||||
|
@ -1262,7 +1268,7 @@ class BasicSwap(BaseApp):
|
|||
|
||||
self.validateSwapType(coin_from_t, coin_to_t, swap_type)
|
||||
self.validateOfferAmounts(coin_from_t, coin_to_t, amount, rate, min_bid_amount)
|
||||
self.validateOfferLockValue(coin_from_t, coin_to_t, lock_type, lock_value)
|
||||
self.validateOfferLockValue(swap_type, coin_from_t, coin_to_t, lock_type, lock_value)
|
||||
self.validateOfferValidTime(swap_type, coin_from_t, coin_to_t, valid_for_seconds)
|
||||
|
||||
offer_addr_to = self.getOfferAddressTo(extra_options)
|
||||
|
@ -3916,7 +3922,7 @@ class BasicSwap(BaseApp):
|
|||
|
||||
self.validateSwapType(coin_from, coin_to, offer_data.swap_type)
|
||||
self.validateOfferAmounts(coin_from, coin_to, offer_data.amount_from, offer_data.rate, offer_data.min_bid_amount)
|
||||
self.validateOfferLockValue(coin_from, coin_to, offer_data.lock_type, offer_data.lock_value)
|
||||
self.validateOfferLockValue(offer_data.swap_type, coin_from, coin_to, offer_data.lock_type, offer_data.lock_value)
|
||||
self.validateOfferValidTime(offer_data.swap_type, coin_from, coin_to, offer_data.time_valid)
|
||||
|
||||
ensure(msg['sent'] + offer_data.time_valid >= now, 'Offer expired')
|
||||
|
|
|
@ -321,7 +321,7 @@ chainparams = {
|
|||
'rpcport': 28888,
|
||||
'pubkey_address': 65,
|
||||
'script_address': 178,
|
||||
'key_prefix': 185,
|
||||
'key_prefix': 239,
|
||||
'hrp': '',
|
||||
'bip44': 1,
|
||||
'min_amount': 1000,
|
||||
|
|
|
@ -92,7 +92,7 @@ def findOutput(tx, script_pk: bytes):
|
|||
return None
|
||||
|
||||
|
||||
def find_vout_for_address_from_txobj(tx_obj, addr) -> int:
|
||||
def find_vout_for_address_from_txobj(tx_obj, addr: str) -> int:
|
||||
"""
|
||||
Locate the vout index of the given transaction sending to the
|
||||
given address. Raises runtime error exception if not found.
|
||||
|
@ -1033,7 +1033,15 @@ class BTCInterface(CoinInterface):
|
|||
return None
|
||||
'''
|
||||
|
||||
def getBLockSpendTxFee(self, tx, fee_rate: int) -> int:
|
||||
witness_bytes = 109
|
||||
vsize = self.getTxVSize(tx, add_witness_bytes=witness_bytes)
|
||||
pay_fee = int(fee_rate * vsize // 1000)
|
||||
self._log.info(f'BLockSpendTx fee_rate, vsize, fee: {fee_rate}, {vsize}, {pay_fee}.')
|
||||
return pay_fee
|
||||
|
||||
def spendBLockTx(self, chain_b_lock_txid: bytes, address_to: str, kbv: bytes, kbs: bytes, cb_swap_value: int, b_fee: int, restore_height: int) -> bytes:
|
||||
self._log.info('spendBLockTx %s:\n', chain_b_lock_txid.hex())
|
||||
wtx = self.rpc_callback('gettransaction', [chain_b_lock_txid.hex(), ])
|
||||
lock_tx = self.loadTx(bytes.fromhex(wtx['hex']))
|
||||
|
||||
|
@ -1054,12 +1062,8 @@ class BTCInterface(CoinInterface):
|
|||
scriptSig=self.getScriptScriptSig(script_lock)))
|
||||
tx.vout.append(self.txoType()(cb_swap_value, self.getScriptForPubkeyHash(pkh_to)))
|
||||
|
||||
witness_bytes = 109
|
||||
vsize = self.getTxVSize(tx, add_witness_bytes=witness_bytes)
|
||||
pay_fee = int(b_fee * vsize // 1000)
|
||||
pay_fee = self.getBLockSpendTxFee(tx, b_fee)
|
||||
tx.vout[0].nValue = cb_swap_value - pay_fee
|
||||
self._log.info('spendBLockTx %s:\n fee_rate, vsize, fee: %ld, %ld, %ld.',
|
||||
chain_b_lock_txid.hex(), b_fee, vsize, pay_fee)
|
||||
|
||||
b_lock_spend_tx = tx.serialize()
|
||||
b_lock_spend_tx = self.signTxWithKey(b_lock_spend_tx, kbs)
|
||||
|
@ -1366,10 +1370,8 @@ class BTCInterface(CoinInterface):
|
|||
except Exception as ex:
|
||||
self._log.debug('findTxnByHash getrawtransaction failed: {}'.format(txid_hex))
|
||||
return None
|
||||
|
||||
if 'confirmations' in rv and rv['confirmations'] >= self.blocks_confirmed:
|
||||
return {'txid': txid_hex, 'amount': 0, 'height': rv['blockheight']}
|
||||
|
||||
return None
|
||||
|
||||
|
||||
|
|
|
@ -9,6 +9,10 @@ from .btc import BTCInterface
|
|||
from basicswap.chainparams import Coins
|
||||
from basicswap.util.address import decodeAddress
|
||||
from mnemonic import Mnemonic
|
||||
from basicswap.contrib.test_framework.script import (
|
||||
CScript,
|
||||
OP_DUP, OP_HASH160, OP_EQUALVERIFY, OP_CHECKSIG
|
||||
)
|
||||
|
||||
|
||||
class DASHInterface(BTCInterface):
|
||||
|
@ -37,8 +41,32 @@ class DASHInterface(BTCInterface):
|
|||
return False
|
||||
|
||||
def withdrawCoin(self, value, addr_to, subfee):
|
||||
params = [addr_to, value, '', '', subfee]
|
||||
params = [addr_to, value, '', '', subfee, False, False, self._conf_target]
|
||||
return self.rpc_callback('sendtoaddress', params)
|
||||
|
||||
def getSpendableBalance(self):
|
||||
return self.make_int(self.rpc_callback('getwalletinfo')['balance'])
|
||||
|
||||
def getScriptForPubkeyHash(self, pkh: bytes) -> bytearray:
|
||||
# Return P2PKH
|
||||
return CScript([OP_DUP, OP_HASH160, pkh, OP_EQUALVERIFY, OP_CHECKSIG])
|
||||
|
||||
def getBLockSpendTxFee(self, tx, fee_rate: int) -> int:
|
||||
add_bytes = 107
|
||||
size = len(tx.serialize_with_witness()) + add_bytes
|
||||
pay_fee = int(fee_rate * size // 1000)
|
||||
self._log.info(f'BLockSpendTx fee_rate, size, fee: {fee_rate}, {size}, {pay_fee}.')
|
||||
return pay_fee
|
||||
|
||||
def findTxnByHash(self, txid_hex: str):
|
||||
# Only works for wallet txns
|
||||
try:
|
||||
rv = self.rpc_callback('gettransaction', [txid_hex])
|
||||
except Exception as ex:
|
||||
self._log.debug('findTxnByHash getrawtransaction failed: {}'.format(txid_hex))
|
||||
return None
|
||||
if 'confirmations' in rv and rv['confirmations'] >= self.blocks_confirmed:
|
||||
block_height = self.getBlockHeader(rv['blockhash'])['height']
|
||||
return {'txid': txid_hex, 'amount': 0, 'height': block_height}
|
||||
|
||||
return None
|
||||
|
|
|
@ -151,7 +151,6 @@ class FIROInterface(BTCInterface):
|
|||
|
||||
def getScriptForPubkeyHash(self, pkh: bytes) -> bytearray:
|
||||
# Return P2PKH
|
||||
|
||||
return CScript([OP_DUP, OP_HASH160, pkh, OP_EQUALVERIFY, OP_CHECKSIG])
|
||||
|
||||
def getScriptDest(self, script: bytearray) -> bytearray:
|
||||
|
@ -184,3 +183,27 @@ class FIROInterface(BTCInterface):
|
|||
|
||||
def getSpendableBalance(self):
|
||||
return self.make_int(self.rpc_callback('getwalletinfo')['balance'])
|
||||
|
||||
def getBLockSpendTxFee(self, tx, fee_rate: int) -> int:
|
||||
add_bytes = 107
|
||||
size = len(tx.serialize_with_witness()) + add_bytes
|
||||
pay_fee = int(fee_rate * size // 1000)
|
||||
self._log.info(f'BLockSpendTx fee_rate, size, fee: {fee_rate}, {size}, {pay_fee}.')
|
||||
return pay_fee
|
||||
|
||||
def signTxWithKey(self, tx: bytes, key: bytes) -> bytes:
|
||||
key_wif = self.encodeKey(key)
|
||||
rv = self.rpc_callback('signrawtransaction', [tx.hex(), [], [key_wif, ]])
|
||||
return bytes.fromhex(rv['hex'])
|
||||
|
||||
def findTxnByHash(self, txid_hex: str):
|
||||
# Only works for wallet txns
|
||||
try:
|
||||
rv = self.rpc_callback('gettransaction', [txid_hex])
|
||||
except Exception as ex:
|
||||
self._log.debug('findTxnByHash getrawtransaction failed: {}'.format(txid_hex))
|
||||
return None
|
||||
if 'confirmations' in rv and rv['confirmations'] >= self.blocks_confirmed:
|
||||
block_height = self.getBlockHeader(rv['blockhash'])['height']
|
||||
return {'txid': txid_hex, 'amount': 0, 'height': block_height}
|
||||
return None
|
||||
|
|
|
@ -15,6 +15,13 @@ from .contrib.pivx_test_framework.messages import (
|
|||
ToHex,
|
||||
FromHex,
|
||||
CTransaction)
|
||||
from basicswap.contrib.test_framework.script import (
|
||||
CScript,
|
||||
OP_DUP,
|
||||
OP_HASH160,
|
||||
OP_CHECKSIG,
|
||||
OP_EQUALVERIFY,
|
||||
)
|
||||
|
||||
|
||||
class PIVXInterface(BTCInterface):
|
||||
|
@ -80,3 +87,31 @@ class PIVXInterface(BTCInterface):
|
|||
tx = CTransaction()
|
||||
tx.deserialize(BytesIO(tx_bytes))
|
||||
return tx
|
||||
|
||||
def getScriptForPubkeyHash(self, pkh: bytes) -> bytearray:
|
||||
# Return P2PKH
|
||||
return CScript([OP_DUP, OP_HASH160, pkh, OP_EQUALVERIFY, OP_CHECKSIG])
|
||||
|
||||
def getBLockSpendTxFee(self, tx, fee_rate: int) -> int:
|
||||
add_bytes = 107
|
||||
size = len(tx.serialize_with_witness()) + add_bytes
|
||||
pay_fee = int(fee_rate * size // 1000)
|
||||
self._log.info(f'BLockSpendTx fee_rate, size, fee: {fee_rate}, {size}, {pay_fee}.')
|
||||
return pay_fee
|
||||
|
||||
def signTxWithKey(self, tx: bytes, key: bytes) -> bytes:
|
||||
key_wif = self.encodeKey(key)
|
||||
rv = self.rpc_callback('signrawtransaction', [tx.hex(), [], [key_wif, ]])
|
||||
return bytes.fromhex(rv['hex'])
|
||||
|
||||
def findTxnByHash(self, txid_hex: str):
|
||||
# Only works for wallet txns
|
||||
try:
|
||||
rv = self.rpc_callback('gettransaction', [txid_hex])
|
||||
except Exception as ex:
|
||||
self._log.debug('findTxnByHash getrawtransaction failed: {}'.format(txid_hex))
|
||||
return None
|
||||
if 'confirmations' in rv and rv['confirmations'] >= self.blocks_confirmed:
|
||||
block_height = self.getBlockHeader(rv['blockhash'])['height']
|
||||
return {'txid': txid_hex, 'amount': 0, 'height': block_height}
|
||||
return None
|
||||
|
|
|
@ -7,6 +7,9 @@
|
|||
from basicswap.script import (
|
||||
OpCodes,
|
||||
)
|
||||
from basicswap.util.script import (
|
||||
getP2WSH,
|
||||
)
|
||||
|
||||
|
||||
class ProtocolInterface:
|
||||
|
@ -22,3 +25,7 @@ class ProtocolInterface:
|
|||
def getMockScriptScriptPubkey(self, ci) -> bytearray:
|
||||
script = self.getMockScript()
|
||||
return ci.get_p2wsh_script_pubkey(script) if ci._use_segwit else ci.get_p2sh_script_pubkey(script)
|
||||
|
||||
def getMockAddrTo(self, ci):
|
||||
script = self.getMockScript()
|
||||
return ci.encode_p2wsh(getP2WSH(script)) if ci._use_segwit else ci.encode_p2sh(script)
|
||||
|
|
|
@ -10,9 +10,6 @@ from basicswap.db import (
|
|||
from basicswap.util import (
|
||||
SerialiseNum,
|
||||
)
|
||||
from basicswap.util.script import (
|
||||
getP2WSH,
|
||||
)
|
||||
from basicswap.script import (
|
||||
OpCodes,
|
||||
)
|
||||
|
@ -77,8 +74,7 @@ class AtomicSwapInterface(ProtocolInterface):
|
|||
swap_type = SwapTypes.SELLER_FIRST
|
||||
|
||||
def getFundedInitiateTxTemplate(self, ci, amount: int, sub_fee: bool) -> bytes:
|
||||
script = self.getMockScript()
|
||||
addr_to = ci.encode_p2wsh(getP2WSH(script)) if ci._use_segwit else ci.encode_p2sh(script)
|
||||
addr_to = self.getMockAddrTo(ci)
|
||||
funded_tx = ci.createRawFundedTransaction(addr_to, amount, sub_fee, lock_unspents=False)
|
||||
|
||||
return bytes.fromhex(funded_tx)
|
||||
|
|
|
@ -9,9 +9,6 @@ from sqlalchemy.orm import scoped_session
|
|||
from basicswap.util import (
|
||||
ensure,
|
||||
)
|
||||
from basicswap.util.script import (
|
||||
getP2WSH,
|
||||
)
|
||||
from basicswap.chainparams import (
|
||||
Coins,
|
||||
)
|
||||
|
@ -104,8 +101,7 @@ class XmrSwapInterface(ProtocolInterface):
|
|||
return CScript([2, Kal_enc, Kaf_enc, 2, CScriptOp(OP_CHECKMULTISIG)])
|
||||
|
||||
def getFundedInitiateTxTemplate(self, ci, amount: int, sub_fee: bool) -> bytes:
|
||||
script = self.getMockScript()
|
||||
addr_to = ci.encode_p2wsh(getP2WSH(script)) if ci._use_segwit else ci.encode_p2sh(script)
|
||||
addr_to = self.getMockAddrTo(ci)
|
||||
funded_tx = ci.createRawFundedTransaction(addr_to, amount, sub_fee, lock_unspents=False)
|
||||
|
||||
return bytes.fromhex(funded_tx)
|
||||
|
|
15
doc/protocols/sequence_diagrams/notes.txt
Normal file
15
doc/protocols/sequence_diagrams/notes.txt
Normal file
|
@ -0,0 +1,15 @@
|
|||
nvm use 14
|
||||
npm install -g mscgenjs-cli
|
||||
|
||||
mscgenjs -T svg -i bidder.alt.xu -o bidder.alt.xu.svg
|
||||
mscgenjs -T svg -i offerer.alt.xu -o offerer.alt.xu.svg
|
||||
mscgenjs -T svg -i xmr.bidder.alt.xu -o xmr.bidder.alt.xu.svg
|
||||
mscgenjs -T svg -i xmr.offerer.alt.xu -o xmr.offerer.alt.xu.svg
|
||||
|
||||
|
||||
npm -g install svgo
|
||||
|
||||
svgo --pretty bidder.alt.xu.svg -o bidder.alt.xu.min.svg
|
||||
svgo --pretty offerer.alt.xu.svg -o offerer.alt.xu.min.svg
|
||||
svgo --pretty xmr.bidder.alt.xu.svg -o xmr.bidder.alt.xu.min.svg
|
||||
svgo --pretty xmr.offerer.alt.xu.svg -o xmr.offerer.alt.xu.min.svg
|
|
@ -25,9 +25,10 @@ import basicswap.config as cfg
|
|||
from basicswap.basicswap import (
|
||||
BasicSwap,
|
||||
Coins,
|
||||
TxStates,
|
||||
SwapTypes,
|
||||
BidStates,
|
||||
TxStates,
|
||||
DebugTypes,
|
||||
)
|
||||
from basicswap.util import (
|
||||
COIN,
|
||||
|
@ -56,6 +57,8 @@ from tests.basicswap.common import (
|
|||
stopDaemons,
|
||||
wait_for_offer,
|
||||
wait_for_bid,
|
||||
wait_for_balance,
|
||||
wait_for_unspent,
|
||||
wait_for_bid_tx_state,
|
||||
wait_for_in_progress,
|
||||
TEST_HTTP_HOST,
|
||||
|
@ -192,7 +195,15 @@ def prepareDir(datadir, nodeId, network_key, network_pubkey):
|
|||
},
|
||||
'check_progress_seconds': 2,
|
||||
'check_watched_seconds': 4,
|
||||
'check_expired_seconds': 60
|
||||
'check_expired_seconds': 60,
|
||||
'check_events_seconds': 1,
|
||||
'check_xmr_swaps_seconds': 1,
|
||||
'min_delay_event': 1,
|
||||
'max_delay_event': 3,
|
||||
'min_delay_event_short': 1,
|
||||
'max_delay_event_short': 3,
|
||||
'min_delay_retry': 2,
|
||||
'max_delay_retry': 10
|
||||
}
|
||||
with open(settings_path, 'w') as fp:
|
||||
json.dump(settings, fp, indent=4)
|
||||
|
@ -305,8 +316,8 @@ class Test(unittest.TestCase):
|
|||
rpc('rescanblockchain')
|
||||
else:
|
||||
rpc('extkeyimportmaster', [rpc('mnemonic', ['new'])['master']])
|
||||
rpc('walletsettings', ['stakingoptions', {'stakecombinethreshold': 100, 'stakesplitthreshold': 200}])
|
||||
rpc('reservebalance', [False])
|
||||
rpc('walletsettings', ['stakingoptions', json.dumps({'stakecombinethreshold': 100, 'stakesplitthreshold': 200}).replace('"', '\\"')])
|
||||
rpc('reservebalance', ['false'])
|
||||
|
||||
basicswap_dir = os.path.join(os.path.join(cfg.TEST_DATADIRS, str(i)), 'basicswap')
|
||||
settings_path = os.path.join(basicswap_dir, cfg.CONFIG_FILENAME)
|
||||
|
@ -564,6 +575,133 @@ class Test(unittest.TestCase):
|
|||
dashRpc('unloadwallet', wallet=new_wallet_name)
|
||||
assert (addr_test == addr)
|
||||
|
||||
def test_10_prefunded_itx(self):
|
||||
logging.info('---------- Test prefunded itx offer')
|
||||
|
||||
swap_clients = self.swap_clients
|
||||
coin_from = Coins.DASH
|
||||
coin_to = Coins.BTC
|
||||
swap_type = SwapTypes.SELLER_FIRST
|
||||
ci_from = swap_clients[2].ci(coin_from)
|
||||
ci_to = swap_clients[1].ci(coin_to)
|
||||
tla_from = coin_from.name
|
||||
|
||||
# Prepare balance
|
||||
js_w2 = read_json_api(1802, 'wallets')
|
||||
if float(js_w2[tla_from]['balance']) < 100.0:
|
||||
post_json = {
|
||||
'value': 100,
|
||||
'address': js_w2[tla_from]['deposit_address'],
|
||||
'subfee': False,
|
||||
}
|
||||
json_rv = read_json_api(1800, 'wallets/{}/withdraw'.format(tla_from.lower()), post_json)
|
||||
assert (len(json_rv['txid']) == 64)
|
||||
wait_for_balance(delay_event, 'http://127.0.0.1:1802/json/wallets/{}'.format(tla_from.lower()), 'balance', 100.0)
|
||||
|
||||
js_w2 = read_json_api(1802, 'wallets')
|
||||
assert (float(js_w2[tla_from]['balance']) >= 100.0)
|
||||
|
||||
js_w2 = read_json_api(1802, 'wallets')
|
||||
post_json = {
|
||||
'value': 100.0,
|
||||
'address': read_json_api(1802, 'wallets/{}/nextdepositaddr'.format(tla_from.lower())),
|
||||
'subfee': True,
|
||||
}
|
||||
json_rv = read_json_api(1802, 'wallets/{}/withdraw'.format(tla_from.lower()), post_json)
|
||||
wait_for_balance(delay_event, 'http://127.0.0.1:1802/json/wallets/{}'.format(tla_from.lower()), 'balance', 10.0)
|
||||
assert (len(json_rv['txid']) == 64)
|
||||
|
||||
# Create prefunded ITX
|
||||
pi = swap_clients[2].pi(SwapTypes.XMR_SWAP)
|
||||
js_w2 = read_json_api(1802, 'wallets')
|
||||
swap_value = 100.0
|
||||
if float(js_w2[tla_from]['balance']) < swap_value:
|
||||
swap_value = js_w2[tla_from]['balance']
|
||||
swap_value = ci_from.make_int(swap_value)
|
||||
assert (swap_value > ci_from.make_int(95))
|
||||
|
||||
itx = pi.getFundedInitiateTxTemplate(ci_from, swap_value, True)
|
||||
itx_decoded = ci_from.describeTx(itx.hex())
|
||||
value_after_subfee = ci_from.make_int(itx_decoded['vout'][0]['value'])
|
||||
assert (value_after_subfee < swap_value)
|
||||
swap_value = value_after_subfee
|
||||
wait_for_unspent(delay_event, ci_from, swap_value)
|
||||
|
||||
extra_options = {'prefunded_itx': itx}
|
||||
rate_swap = ci_to.make_int(random.uniform(0.2, 20.0), r=1)
|
||||
offer_id = swap_clients[2].postOffer(coin_from, coin_to, swap_value, rate_swap, swap_value, swap_type, extra_options=extra_options)
|
||||
|
||||
wait_for_offer(delay_event, swap_clients[1], offer_id)
|
||||
offer = swap_clients[1].getOffer(offer_id)
|
||||
bid_id = swap_clients[1].postBid(offer_id, offer.amount_from)
|
||||
|
||||
wait_for_bid(delay_event, swap_clients[2], bid_id, BidStates.BID_RECEIVED)
|
||||
swap_clients[2].acceptBid(bid_id)
|
||||
|
||||
wait_for_bid(delay_event, swap_clients[2], 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)
|
||||
|
||||
# Verify expected inputs were used
|
||||
bid, offer = swap_clients[2].getBidAndOffer(bid_id)
|
||||
assert (bid.initiate_tx)
|
||||
wtx = ci_from.rpc_callback('gettransaction', [bid.initiate_tx.txid.hex(),])
|
||||
itx_after = ci_from.describeTx(wtx['hex'])
|
||||
assert (len(itx_after['vin']) == len(itx_decoded['vin']))
|
||||
for i, txin in enumerate(itx_decoded['vin']):
|
||||
assert (txin['txid'] == itx_after['vin'][i]['txid'])
|
||||
assert (txin['vout'] == itx_after['vin'][i]['vout'])
|
||||
|
||||
def test_11_xmrswap_to(self):
|
||||
logging.info('---------- Test xmr swap protocol to')
|
||||
|
||||
swap_clients = self.swap_clients
|
||||
coin_from = Coins.BTC
|
||||
coin_to = Coins.DASH
|
||||
swap_type = SwapTypes.XMR_SWAP
|
||||
ci_from = swap_clients[0].ci(coin_from)
|
||||
ci_to = swap_clients[1].ci(coin_to)
|
||||
|
||||
swap_value = ci_from.make_int(random.uniform(0.2, 20.0), r=1)
|
||||
rate_swap = ci_to.make_int(random.uniform(0.2, 20.0), r=1)
|
||||
offer_id = swap_clients[0].postOffer(coin_from, coin_to, swap_value, rate_swap, swap_value, swap_type)
|
||||
|
||||
wait_for_offer(delay_event, swap_clients[1], offer_id)
|
||||
offer = swap_clients[1].getOffer(offer_id)
|
||||
bid_id = swap_clients[1].postBid(offer_id, offer.amount_from)
|
||||
|
||||
wait_for_bid(delay_event, swap_clients[0], bid_id, BidStates.BID_RECEIVED)
|
||||
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)
|
||||
|
||||
def test_12_xmrswap_to_recover_b_lock_tx(self):
|
||||
coin_from = Coins.BTC
|
||||
coin_to = Coins.DASH
|
||||
logging.info('---------- Test {} to {} follower recovers coin b lock tx'.format(coin_from.name, coin_to.name))
|
||||
|
||||
swap_clients = self.swap_clients
|
||||
ci_from = swap_clients[0].ci(coin_from)
|
||||
ci_to = swap_clients[1].ci(coin_to)
|
||||
|
||||
amt_swap = ci_from.make_int(random.uniform(0.1, 2.0), r=1)
|
||||
rate_swap = ci_to.make_int(random.uniform(0.2, 20.0), r=1)
|
||||
offer_id = swap_clients[0].postOffer(
|
||||
coin_from, coin_to, amt_swap, rate_swap, amt_swap, SwapTypes.XMR_SWAP,
|
||||
lock_type=TxLockTypes.SEQUENCE_LOCK_BLOCKS, lock_value=32)
|
||||
wait_for_offer(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)
|
||||
|
||||
bid, xmr_swap = swap_clients[0].getXmrBid(bid_id)
|
||||
swap_clients[1].setBidDebugInd(bid_id, DebugTypes.CREATE_INVALID_COIN_B_LOCK)
|
||||
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)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
|
|
@ -16,6 +16,7 @@ from basicswap.basicswap import (
|
|||
TxStates,
|
||||
SwapTypes,
|
||||
BidStates,
|
||||
DebugTypes,
|
||||
)
|
||||
from basicswap.basicswap_util import (
|
||||
TxLockTypes,
|
||||
|
@ -38,6 +39,8 @@ from tests.basicswap.common import (
|
|||
make_rpc_func,
|
||||
TEST_HTTP_PORT,
|
||||
wait_for_offer,
|
||||
wait_for_balance,
|
||||
wait_for_unspent,
|
||||
wait_for_in_progress,
|
||||
wait_for_bid_tx_state,
|
||||
)
|
||||
|
@ -420,6 +423,135 @@ class Test(BaseTest):
|
|||
json_rv = read_json_api(TEST_HTTP_PORT + 0, 'wallets/{}/createutxo'.format(self.test_coin_from.name.lower()), post_json)
|
||||
assert (len(json_rv['txid']) == 64)
|
||||
|
||||
def ensure_balance(self, coin_type, node_id, amount):
|
||||
tla = coin_type.name
|
||||
js_w = read_json_api(1800 + node_id, 'wallets')
|
||||
if float(js_w[tla]['balance']) < amount:
|
||||
post_json = {
|
||||
'value': amount,
|
||||
'address': js_w[tla]['deposit_address'],
|
||||
'subfee': False,
|
||||
}
|
||||
json_rv = read_json_api(1800, 'wallets/{}/withdraw'.format(tla.lower()), post_json)
|
||||
assert (len(json_rv['txid']) == 64)
|
||||
wait_for_balance(test_delay_event, 'http://127.0.0.1:{}/json/wallets/{}'.format(1800 + node_id, tla.lower()), 'balance', amount)
|
||||
|
||||
def test_10_prefunded_itx(self):
|
||||
logging.info('---------- Test prefunded itx offer')
|
||||
|
||||
swap_clients = self.swap_clients
|
||||
coin_from = Coins.FIRO
|
||||
coin_to = Coins.BTC
|
||||
swap_type = SwapTypes.SELLER_FIRST
|
||||
ci_from = swap_clients[2].ci(coin_from)
|
||||
ci_to = swap_clients[1].ci(coin_to)
|
||||
tla_from = coin_from.name
|
||||
|
||||
# Prepare balance
|
||||
self.ensure_balance(coin_from, 2, 10.0)
|
||||
self.ensure_balance(coin_to, 1, 100.0)
|
||||
|
||||
js_w2 = read_json_api(1802, 'wallets')
|
||||
post_json = {
|
||||
'value': 10.0,
|
||||
'address': read_json_api(1802, 'wallets/{}/nextdepositaddr'.format(tla_from.lower())),
|
||||
'subfee': True,
|
||||
}
|
||||
json_rv = read_json_api(1802, 'wallets/{}/withdraw'.format(tla_from.lower()), post_json)
|
||||
wait_for_balance(test_delay_event, 'http://127.0.0.1:1802/json/wallets/{}'.format(tla_from.lower()), 'balance', 9.0)
|
||||
assert (len(json_rv['txid']) == 64)
|
||||
|
||||
# Create prefunded ITX
|
||||
pi = swap_clients[2].pi(SwapTypes.XMR_SWAP)
|
||||
js_w2 = read_json_api(1802, 'wallets')
|
||||
swap_value = 10.0
|
||||
if float(js_w2[tla_from]['balance']) < swap_value:
|
||||
swap_value = js_w2[tla_from]['balance']
|
||||
swap_value = ci_from.make_int(swap_value)
|
||||
assert (swap_value > ci_from.make_int(9))
|
||||
|
||||
itx = pi.getFundedInitiateTxTemplate(ci_from, swap_value, True)
|
||||
itx_decoded = ci_from.describeTx(itx.hex())
|
||||
value_after_subfee = ci_from.make_int(itx_decoded['vout'][0]['value'])
|
||||
assert (value_after_subfee < swap_value)
|
||||
swap_value = value_after_subfee
|
||||
wait_for_unspent(test_delay_event, ci_from, swap_value)
|
||||
|
||||
extra_options = {'prefunded_itx': itx}
|
||||
rate_swap = ci_to.make_int(random.uniform(0.2, 10.0), r=1)
|
||||
offer_id = swap_clients[2].postOffer(coin_from, coin_to, swap_value, rate_swap, swap_value, swap_type, extra_options=extra_options)
|
||||
|
||||
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(test_delay_event, swap_clients[2], bid_id, BidStates.BID_RECEIVED)
|
||||
swap_clients[2].acceptBid(bid_id)
|
||||
|
||||
wait_for_bid(test_delay_event, swap_clients[2], 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)
|
||||
|
||||
# Verify expected inputs were used
|
||||
bid, offer = swap_clients[2].getBidAndOffer(bid_id)
|
||||
assert (bid.initiate_tx)
|
||||
wtx = ci_from.rpc_callback('gettransaction', [bid.initiate_tx.txid.hex(),])
|
||||
itx_after = ci_from.describeTx(wtx['hex'])
|
||||
assert (len(itx_after['vin']) == len(itx_decoded['vin']))
|
||||
for i, txin in enumerate(itx_decoded['vin']):
|
||||
assert (txin['txid'] == itx_after['vin'][i]['txid'])
|
||||
assert (txin['vout'] == itx_after['vin'][i]['vout'])
|
||||
|
||||
def test_11_xmrswap_to(self):
|
||||
logging.info('---------- Test xmr swap protocol to')
|
||||
|
||||
swap_clients = self.swap_clients
|
||||
coin_from = Coins.BTC
|
||||
coin_to = Coins.FIRO
|
||||
swap_type = SwapTypes.XMR_SWAP
|
||||
ci_from = swap_clients[0].ci(coin_from)
|
||||
ci_to = swap_clients[1].ci(coin_to)
|
||||
|
||||
swap_value = ci_from.make_int(random.uniform(0.2, 20.0), r=1)
|
||||
rate_swap = ci_to.make_int(random.uniform(0.2, 20.0), r=1)
|
||||
offer_id = swap_clients[0].postOffer(coin_from, coin_to, swap_value, rate_swap, swap_value, swap_type)
|
||||
|
||||
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(test_delay_event, swap_clients[0], bid_id, BidStates.BID_RECEIVED)
|
||||
swap_clients[0].acceptBid(bid_id)
|
||||
|
||||
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)
|
||||
|
||||
def test_12_xmrswap_to_recover_b_lock_tx(self):
|
||||
coin_from = Coins.BTC
|
||||
coin_to = Coins.FIRO
|
||||
logging.info('---------- Test {} to {} follower recovers coin b lock tx'.format(coin_from.name, coin_to.name))
|
||||
|
||||
swap_clients = self.swap_clients
|
||||
ci_from = swap_clients[0].ci(coin_from)
|
||||
ci_to = swap_clients[1].ci(coin_to)
|
||||
|
||||
amt_swap = ci_from.make_int(random.uniform(0.1, 2.0), r=1)
|
||||
rate_swap = ci_to.make_int(random.uniform(0.2, 20.0), r=1)
|
||||
offer_id = swap_clients[0].postOffer(
|
||||
coin_from, coin_to, amt_swap, rate_swap, amt_swap, SwapTypes.XMR_SWAP,
|
||||
lock_type=TxLockTypes.SEQUENCE_LOCK_BLOCKS, lock_value=32)
|
||||
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(test_delay_event, swap_clients[0], bid_id, BidStates.BID_RECEIVED)
|
||||
|
||||
bid, xmr_swap = swap_clients[0].getXmrBid(bid_id)
|
||||
swap_clients[1].setBidDebugInd(bid_id, DebugTypes.CREATE_INVALID_COIN_B_LOCK)
|
||||
swap_clients[0].acceptXmrBid(bid_id)
|
||||
|
||||
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_101_full_swap(self):
|
||||
logging.info('---------- Test {} to XMR'.format(self.test_coin_from.name))
|
||||
if not self.test_xmr:
|
||||
|
|
|
@ -220,8 +220,8 @@ class Test(unittest.TestCase):
|
|||
else:
|
||||
rpc('extkeyimportmaster', [rpc('mnemonic', ['new'])['master']])
|
||||
# Lower output split threshold for more stakeable outputs
|
||||
rpc('walletsettings', ['stakingoptions', {'stakecombinethreshold': 100, 'stakesplitthreshold': 200}])
|
||||
rpc('reservebalance', [False])
|
||||
rpc('walletsettings', ['stakingoptions', json.dumps({'stakecombinethreshold': 100, 'stakesplitthreshold': 200}).replace('"', '\\"')])
|
||||
rpc('reservebalance', ['false'])
|
||||
|
||||
for i in range(NUM_BTC_NODES):
|
||||
data_dir = prepareDataDir(TEST_DIR, i, 'bitcoin.conf', 'btc_', base_p2p_port=BTC_BASE_PORT, base_rpc_port=BTC_BASE_RPC_PORT)
|
||||
|
|
|
@ -297,8 +297,8 @@ class Test(unittest.TestCase):
|
|||
rpc('rescanblockchain')
|
||||
else:
|
||||
rpc('extkeyimportmaster', [rpc('mnemonic', ['new'])['master']])
|
||||
rpc('walletsettings', ['stakingoptions', {'stakecombinethreshold': 100, 'stakesplitthreshold': 200}])
|
||||
rpc('reservebalance', [False])
|
||||
rpc('walletsettings', ['stakingoptions', json.dumps({'stakecombinethreshold': 100, 'stakesplitthreshold': 200}).replace('"', '\\"')])
|
||||
rpc('reservebalance', ['false'])
|
||||
|
||||
basicswap_dir = os.path.join(os.path.join(cfg.TEST_DATADIRS, str(i)), 'basicswap')
|
||||
settings_path = os.path.join(basicswap_dir, cfg.CONFIG_FILENAME)
|
||||
|
|
|
@ -14,6 +14,7 @@ import os
|
|||
import sys
|
||||
import json
|
||||
import time
|
||||
import random
|
||||
import shutil
|
||||
import signal
|
||||
import logging
|
||||
|
@ -27,6 +28,7 @@ from basicswap.basicswap import (
|
|||
SwapTypes,
|
||||
BidStates,
|
||||
TxStates,
|
||||
DebugTypes,
|
||||
)
|
||||
from basicswap.util import (
|
||||
COIN,
|
||||
|
@ -47,16 +49,21 @@ from basicswap.contrib.key import (
|
|||
from basicswap.http_server import (
|
||||
HttpThread,
|
||||
)
|
||||
from basicswap.interface.btc import (
|
||||
find_vout_for_address_from_txobj,
|
||||
)
|
||||
from tests.basicswap.util import (
|
||||
read_json_api,
|
||||
)
|
||||
from tests.basicswap.common import (
|
||||
checkForks,
|
||||
stopDaemons,
|
||||
wait_for_offer,
|
||||
wait_for_bid,
|
||||
wait_for_bid_tx_state,
|
||||
wait_for_offer,
|
||||
wait_for_balance,
|
||||
wait_for_unspent,
|
||||
wait_for_in_progress,
|
||||
wait_for_bid_tx_state,
|
||||
TEST_HTTP_HOST,
|
||||
TEST_HTTP_PORT,
|
||||
BASE_PORT,
|
||||
|
@ -197,7 +204,15 @@ def prepareDir(datadir, nodeId, network_key, network_pubkey):
|
|||
},
|
||||
'check_progress_seconds': 2,
|
||||
'check_watched_seconds': 4,
|
||||
'check_expired_seconds': 60
|
||||
'check_expired_seconds': 60,
|
||||
'check_events_seconds': 1,
|
||||
'check_xmr_swaps_seconds': 1,
|
||||
'min_delay_event': 1,
|
||||
'max_delay_event': 3,
|
||||
'min_delay_event_short': 1,
|
||||
'max_delay_event_short': 3,
|
||||
'min_delay_retry': 2,
|
||||
'max_delay_retry': 10
|
||||
}
|
||||
with open(settings_path, 'w') as fp:
|
||||
json.dump(settings, fp, indent=4)
|
||||
|
@ -317,8 +332,8 @@ class Test(unittest.TestCase):
|
|||
rpc('rescanblockchain')
|
||||
else:
|
||||
rpc('extkeyimportmaster', [rpc('mnemonic', ['new'])['master']])
|
||||
rpc('walletsettings', ['stakingoptions', {'stakecombinethreshold': 100, 'stakesplitthreshold': 200}])
|
||||
rpc('reservebalance', [False])
|
||||
rpc('walletsettings', ['stakingoptions', json.dumps({'stakecombinethreshold': 100, 'stakesplitthreshold': 200}).replace('"', '\\"')])
|
||||
rpc('reservebalance', ['false'])
|
||||
|
||||
basicswap_dir = os.path.join(os.path.join(cfg.TEST_DATADIRS, str(i)), 'basicswap')
|
||||
settings_path = os.path.join(basicswap_dir, cfg.CONFIG_FILENAME)
|
||||
|
@ -581,6 +596,138 @@ class Test(unittest.TestCase):
|
|||
break
|
||||
assert found
|
||||
|
||||
def ensure_balance(self, coin_type, node_id, amount):
|
||||
tla = coin_type.name
|
||||
js_w = read_json_api(1800 + node_id, 'wallets')
|
||||
if float(js_w[tla]['balance']) < amount:
|
||||
post_json = {
|
||||
'value': amount,
|
||||
'address': js_w[tla]['deposit_address'],
|
||||
'subfee': False,
|
||||
}
|
||||
json_rv = read_json_api(1800, 'wallets/{}/withdraw'.format(tla.lower()), post_json)
|
||||
assert (len(json_rv['txid']) == 64)
|
||||
wait_for_balance(delay_event, 'http://127.0.0.1:{}/json/wallets/{}'.format(1800 + node_id, tla.lower()), 'balance', amount)
|
||||
|
||||
def test_10_prefunded_itx(self):
|
||||
logging.info('---------- Test prefunded itx offer')
|
||||
|
||||
swap_clients = self.swap_clients
|
||||
coin_from = Coins.PIVX
|
||||
coin_to = Coins.BTC
|
||||
swap_type = SwapTypes.SELLER_FIRST
|
||||
ci_from = swap_clients[2].ci(coin_from)
|
||||
ci_to = swap_clients[1].ci(coin_to)
|
||||
tla_from = coin_from.name
|
||||
|
||||
# Prepare balance
|
||||
self.ensure_balance(coin_from, 2, 10.0)
|
||||
self.ensure_balance(coin_to, 1, 100.0)
|
||||
|
||||
js_w2 = read_json_api(1802, 'wallets')
|
||||
post_json = {
|
||||
'value': 10.0,
|
||||
'address': read_json_api(1802, 'wallets/{}/nextdepositaddr'.format(tla_from.lower())),
|
||||
'subfee': True,
|
||||
}
|
||||
json_rv = read_json_api(1802, 'wallets/{}/withdraw'.format(tla_from.lower()), post_json)
|
||||
wait_for_balance(delay_event, 'http://127.0.0.1:1802/json/wallets/{}'.format(tla_from.lower()), 'balance', 9.0)
|
||||
assert (len(json_rv['txid']) == 64)
|
||||
|
||||
# Create prefunded ITX
|
||||
pi = swap_clients[2].pi(SwapTypes.XMR_SWAP)
|
||||
js_w2 = read_json_api(1802, 'wallets')
|
||||
swap_value = 10.0
|
||||
if float(js_w2[tla_from]['balance']) < swap_value:
|
||||
swap_value = js_w2[tla_from]['balance']
|
||||
swap_value = ci_from.make_int(swap_value)
|
||||
assert (swap_value > ci_from.make_int(9))
|
||||
|
||||
itx = pi.getFundedInitiateTxTemplate(ci_from, swap_value, True)
|
||||
itx_decoded = ci_from.describeTx(itx.hex())
|
||||
|
||||
mock_addr = pi.getMockAddrTo(ci_from)
|
||||
n = find_vout_for_address_from_txobj(itx_decoded, mock_addr)
|
||||
value_after_subfee = ci_from.make_int(itx_decoded['vout'][n]['value'])
|
||||
assert (value_after_subfee < swap_value)
|
||||
swap_value = value_after_subfee
|
||||
wait_for_unspent(delay_event, ci_from, swap_value)
|
||||
|
||||
extra_options = {'prefunded_itx': itx}
|
||||
rate_swap = ci_to.make_int(random.uniform(0.2, 10.0), r=1)
|
||||
offer_id = swap_clients[2].postOffer(coin_from, coin_to, swap_value, rate_swap, swap_value, swap_type, TxLockTypes.ABS_LOCK_TIME, extra_options=extra_options)
|
||||
|
||||
wait_for_offer(delay_event, swap_clients[1], offer_id)
|
||||
offer = swap_clients[1].getOffer(offer_id)
|
||||
bid_id = swap_clients[1].postBid(offer_id, offer.amount_from)
|
||||
|
||||
wait_for_bid(delay_event, swap_clients[2], bid_id, BidStates.BID_RECEIVED)
|
||||
swap_clients[2].acceptBid(bid_id)
|
||||
|
||||
wait_for_bid(delay_event, swap_clients[2], 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)
|
||||
|
||||
# Verify expected inputs were used
|
||||
bid, offer = swap_clients[2].getBidAndOffer(bid_id)
|
||||
assert (bid.initiate_tx)
|
||||
wtx = ci_from.rpc_callback('gettransaction', [bid.initiate_tx.txid.hex(),])
|
||||
itx_after = ci_from.describeTx(wtx['hex'])
|
||||
assert (len(itx_after['vin']) == len(itx_decoded['vin']))
|
||||
for i, txin in enumerate(itx_decoded['vin']):
|
||||
assert (txin['txid'] == itx_after['vin'][i]['txid'])
|
||||
assert (txin['vout'] == itx_after['vin'][i]['vout'])
|
||||
|
||||
def test_11_xmrswap_to(self):
|
||||
logging.info('---------- Test xmr swap protocol to')
|
||||
|
||||
swap_clients = self.swap_clients
|
||||
coin_from = Coins.BTC
|
||||
coin_to = Coins.PIVX
|
||||
swap_type = SwapTypes.XMR_SWAP
|
||||
ci_from = swap_clients[0].ci(coin_from)
|
||||
ci_to = swap_clients[1].ci(coin_to)
|
||||
|
||||
swap_value = ci_from.make_int(random.uniform(0.2, 20.0), r=1)
|
||||
rate_swap = ci_to.make_int(random.uniform(0.2, 20.0), r=1)
|
||||
offer_id = swap_clients[0].postOffer(coin_from, coin_to, swap_value, rate_swap, swap_value, swap_type)
|
||||
|
||||
wait_for_offer(delay_event, swap_clients[1], offer_id)
|
||||
offer = swap_clients[1].getOffer(offer_id)
|
||||
bid_id = swap_clients[1].postBid(offer_id, offer.amount_from)
|
||||
|
||||
wait_for_bid(delay_event, swap_clients[0], bid_id, BidStates.BID_RECEIVED)
|
||||
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)
|
||||
|
||||
def test_12_xmrswap_to_recover_b_lock_tx(self):
|
||||
coin_from = Coins.BTC
|
||||
coin_to = Coins.PIVX
|
||||
logging.info('---------- Test {} to {} follower recovers coin b lock tx'.format(coin_from.name, coin_to.name))
|
||||
|
||||
swap_clients = self.swap_clients
|
||||
ci_from = swap_clients[0].ci(coin_from)
|
||||
ci_to = swap_clients[1].ci(coin_to)
|
||||
|
||||
amt_swap = ci_from.make_int(random.uniform(0.1, 2.0), r=1)
|
||||
rate_swap = ci_to.make_int(random.uniform(0.2, 20.0), r=1)
|
||||
offer_id = swap_clients[0].postOffer(
|
||||
coin_from, coin_to, amt_swap, rate_swap, amt_swap, SwapTypes.XMR_SWAP,
|
||||
lock_type=TxLockTypes.SEQUENCE_LOCK_BLOCKS, lock_value=32)
|
||||
wait_for_offer(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)
|
||||
|
||||
bid, xmr_swap = swap_clients[0].getXmrBid(bid_id)
|
||||
swap_clients[1].setBidDebugInd(bid_id, DebugTypes.CREATE_INVALID_COIN_B_LOCK)
|
||||
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)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
|
Loading…
Reference in a new issue