mirror of
https://github.com/basicswap/basicswap.git
synced 2024-12-23 03:49:25 +00:00
Continue extending bch interface and test coverage
Support reverse swap happy path
This commit is contained in:
parent
68256fdcf7
commit
52e6e2b586
4 changed files with 320 additions and 33 deletions
|
@ -2987,7 +2987,7 @@ class BasicSwap(BaseApp):
|
||||||
refundExtraArgs = dict()
|
refundExtraArgs = dict()
|
||||||
lockExtraArgs = dict()
|
lockExtraArgs = dict()
|
||||||
if self.isBchXmrSwap(offer):
|
if self.isBchXmrSwap(offer):
|
||||||
pkh_refund_to = ci_from.decodeAddress(self.getCachedAddressForCoin(offer.coin_from, use_session))
|
pkh_refund_to = ci_from.decodeAddress(self.getCachedAddressForCoin(coin_from, use_session))
|
||||||
pkh_dest = xmr_swap.dest_af
|
pkh_dest = xmr_swap.dest_af
|
||||||
# refund script
|
# refund script
|
||||||
refundExtraArgs['mining_fee'] = 1000
|
refundExtraArgs['mining_fee'] = 1000
|
||||||
|
@ -3957,7 +3957,8 @@ class BasicSwap(BaseApp):
|
||||||
bid.xmr_a_lock_tx.tx_data = xmr_swap.a_lock_tx
|
bid.xmr_a_lock_tx.tx_data = xmr_swap.a_lock_tx
|
||||||
bid.xmr_a_lock_tx.spend_txid = xmr_swap.a_lock_spend_tx_id
|
bid.xmr_a_lock_tx.spend_txid = xmr_swap.a_lock_spend_tx_id
|
||||||
|
|
||||||
self.addWatchedOutput(offer.coin_from, bid.bid_id, bid.xmr_a_lock_tx.txid.hex(), bid.xmr_a_lock_tx.vout, TxTypes.XMR_SWAP_A_LOCK, SwapTypes.XMR_SWAP)
|
coin_from = Coins(offer.coin_to if reverse_bid else offer.coin_from)
|
||||||
|
self.addWatchedOutput(coin_from, bid.bid_id, bid.xmr_a_lock_tx.txid.hex(), bid.xmr_a_lock_tx.vout, TxTypes.XMR_SWAP_A_LOCK, SwapTypes.XMR_SWAP)
|
||||||
bid_changed = True
|
bid_changed = True
|
||||||
|
|
||||||
if bid.xmr_a_lock_tx.state == TxStates.TX_NONE and lock_tx_chain_info['height'] == 0:
|
if bid.xmr_a_lock_tx.state == TxStates.TX_NONE and lock_tx_chain_info['height'] == 0:
|
||||||
|
@ -4922,11 +4923,10 @@ class BasicSwap(BaseApp):
|
||||||
raise ValueError('TODO')
|
raise ValueError('TODO')
|
||||||
elif offer_data.swap_type == SwapTypes.XMR_SWAP:
|
elif offer_data.swap_type == SwapTypes.XMR_SWAP:
|
||||||
ensure(offer_data.protocol_version >= MINPROTO_VERSION_ADAPTOR_SIG, 'Invalid protocol version')
|
ensure(offer_data.protocol_version >= MINPROTO_VERSION_ADAPTOR_SIG, 'Invalid protocol version')
|
||||||
if Coins.BCH not in (coin_from, coin_to):
|
if reverse_bid:
|
||||||
if reverse_bid:
|
ensure(ci_to.has_segwit(), 'Coin-to must support segwit for reverse bid offers')
|
||||||
ensure(ci_to.has_segwit(), 'Coin-to must support segwit for reverse bid offers')
|
else:
|
||||||
else:
|
ensure(ci_from.has_segwit(), 'Coin-from must support segwit')
|
||||||
ensure(ci_from.has_segwit(), 'Coin-from must support segwit')
|
|
||||||
ensure(len(offer_data.proof_address) == 0, 'Unexpected data')
|
ensure(len(offer_data.proof_address) == 0, 'Unexpected data')
|
||||||
ensure(len(offer_data.proof_signature) == 0, 'Unexpected data')
|
ensure(len(offer_data.proof_signature) == 0, 'Unexpected data')
|
||||||
ensure(len(offer_data.pkhash_seller) == 0, 'Unexpected data')
|
ensure(len(offer_data.pkhash_seller) == 0, 'Unexpected data')
|
||||||
|
|
|
@ -13,7 +13,7 @@ from .btc import BTCInterface, ensure_op, find_vout_for_address_from_txobj, find
|
||||||
from basicswap.rpc import make_rpc_func
|
from basicswap.rpc import make_rpc_func
|
||||||
from basicswap.chainparams import Coins
|
from basicswap.chainparams import Coins
|
||||||
from basicswap.interface.contrib.bch_test_framework.cashaddress import Address
|
from basicswap.interface.contrib.bch_test_framework.cashaddress import Address
|
||||||
from basicswap.util.crypto import sha256
|
from basicswap.util.crypto import hash160, sha256
|
||||||
from basicswap.interface.contrib.bch_test_framework.script import (
|
from basicswap.interface.contrib.bch_test_framework.script import (
|
||||||
OP_TXINPUTCOUNT,
|
OP_TXINPUTCOUNT,
|
||||||
OP_1,
|
OP_1,
|
||||||
|
@ -71,8 +71,13 @@ class BCHInterface(BTCInterface):
|
||||||
def __init__(self, coin_settings, network, swap_client=None):
|
def __init__(self, coin_settings, network, swap_client=None):
|
||||||
super(BCHInterface, self).__init__(coin_settings, network, swap_client)
|
super(BCHInterface, self).__init__(coin_settings, network, swap_client)
|
||||||
# No multiwallet support
|
# No multiwallet support
|
||||||
|
self.swap_client = swap_client
|
||||||
self.rpc_wallet = make_rpc_func(self._rpcport, self._rpcauth, host=self._rpc_host)
|
self.rpc_wallet = make_rpc_func(self._rpcport, self._rpcauth, host=self._rpc_host)
|
||||||
|
|
||||||
|
def has_segwit(self) -> bool:
|
||||||
|
# bch does not have segwit, but we return true here to avoid extra checks in basicswap.py
|
||||||
|
return True
|
||||||
|
|
||||||
def getExchangeName(self, exchange_name):
|
def getExchangeName(self, exchange_name):
|
||||||
return 'bch'
|
return 'bch'
|
||||||
|
|
||||||
|
@ -148,7 +153,7 @@ class BCHInterface(BTCInterface):
|
||||||
return CScript([OP_HASH256, script_hash, OP_EQUAL])
|
return CScript([OP_HASH256, script_hash, OP_EQUAL])
|
||||||
|
|
||||||
def withdrawCoin(self, value: float, addr_to: str, subfee: bool):
|
def withdrawCoin(self, value: float, addr_to: str, subfee: bool):
|
||||||
params = [addr_to, value, '', '', subfee, True, True]
|
params = [addr_to, value, '', '', subfee, 0, False]
|
||||||
return self.rpc_wallet('sendtoaddress', params)
|
return self.rpc_wallet('sendtoaddress', params)
|
||||||
|
|
||||||
def getSpendableBalance(self) -> int:
|
def getSpendableBalance(self) -> int:
|
||||||
|
@ -321,16 +326,19 @@ class BCHInterface(BTCInterface):
|
||||||
address.prefix = prefix
|
address.prefix = prefix
|
||||||
return address.cash_address()
|
return address.cash_address()
|
||||||
|
|
||||||
|
def encodeSharedAddress(self, Kbv, Kbs):
|
||||||
|
return self.pkh_to_address(hash160(Kbs))
|
||||||
|
|
||||||
def addressToLockingBytecode(self, address: str) -> bytes:
|
def addressToLockingBytecode(self, address: str) -> bytes:
|
||||||
return b'\x76\xa9\x14' + bytes(Address.from_string(address).payload) + b'\x88\xac'
|
return b'\x76\xa9\x14' + bytes(Address.from_string(address).payload) + b'\x88\xac'
|
||||||
|
|
||||||
|
def getSpendableBalance(self) -> int:
|
||||||
|
return self.make_int(self.rpc_wallet('getbalance', ["*", 1, False]))
|
||||||
|
|
||||||
def getScriptDest(self, script):
|
def getScriptDest(self, script):
|
||||||
return self.scriptToP2SH32LockingBytecode(script)
|
return self.scriptToP2SH32LockingBytecode(script)
|
||||||
|
|
||||||
def scriptToP2SH32LockingBytecode(self, script: Union[bytes, str]) -> bytes:
|
def scriptToP2SH32LockingBytecode(self, script: Union[bytes, str]) -> bytes:
|
||||||
if isinstance(script, str):
|
|
||||||
script = bytes.fromhex(script)
|
|
||||||
|
|
||||||
return CScript([
|
return CScript([
|
||||||
OP_HASH256,
|
OP_HASH256,
|
||||||
sha256(sha256(script)),
|
sha256(sha256(script)),
|
||||||
|
|
|
@ -210,7 +210,7 @@ class Address:
|
||||||
|
|
||||||
if address.upper() != address and address.lower() != address:
|
if address.upper() != address and address.lower() != address:
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
"Cash address contains uppercase and lowercase characters"
|
"Cash address contains uppercase and lowercase characters: " + address
|
||||||
)
|
)
|
||||||
|
|
||||||
address = address.lower()
|
address = address.lower()
|
||||||
|
|
|
@ -30,10 +30,12 @@ from basicswap.util import (
|
||||||
)
|
)
|
||||||
from basicswap.interface.base import Curves
|
from basicswap.interface.base import Curves
|
||||||
from basicswap.util.crypto import sha256
|
from basicswap.util.crypto import sha256
|
||||||
|
from tests.basicswap.test_btc_xmr import BasicSwapTest
|
||||||
from tests.basicswap.util import (
|
from tests.basicswap.util import (
|
||||||
read_json_api,
|
read_json_api,
|
||||||
)
|
)
|
||||||
from tests.basicswap.common import (
|
from tests.basicswap.common import (
|
||||||
|
BCH_BASE_RPC_PORT,
|
||||||
abandon_all_swaps,
|
abandon_all_swaps,
|
||||||
wait_for_bid,
|
wait_for_bid,
|
||||||
wait_for_event,
|
wait_for_event,
|
||||||
|
@ -70,20 +72,216 @@ logger = logging.getLogger()
|
||||||
|
|
||||||
|
|
||||||
class TestFunctions(BaseTest):
|
class TestFunctions(BaseTest):
|
||||||
__test__ = True
|
__test__ = False
|
||||||
start_bch_nodes = True
|
start_bch_nodes = True
|
||||||
base_rpc_port = None
|
base_rpc_port = BCH_BASE_RPC_PORT
|
||||||
extra_wait_time = 0
|
extra_wait_time = 0
|
||||||
|
test_coin_from = Coins.BCH
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def callnoderpc(self, method, params=[], wallet=None, node_id=0):
|
def callnoderpc(self, method, params=[], wallet=None, node_id=0):
|
||||||
return callnoderpc(node_id, method, params, wallet, self.base_rpc_port)
|
return callnoderpc(node_id, method, params, wallet, self.base_rpc_port)
|
||||||
|
|
||||||
def mineBlock(self, num_blocks=1):
|
def mineBlock(self, num_blocks=1):
|
||||||
self.callnoderpc('generatetoaddress', [num_blocks, self.btc_addr])
|
self.callnoderpc('generatetoaddress', [num_blocks, self.bch_addr])
|
||||||
|
|
||||||
|
def test_05_bch_xmr(self):
|
||||||
|
logging.info('---------- Test BCH to XMR')
|
||||||
|
swap_clients = self.swap_clients
|
||||||
|
offer_id = swap_clients[0].postOffer(Coins.BCH, Coins.XMR, 10 * COIN, 100 * XMR_COIN, 10 * COIN, SwapTypes.XMR_SWAP)
|
||||||
|
wait_for_offer(test_delay_event, swap_clients[1], offer_id)
|
||||||
|
offers = swap_clients[1].listOffers(filters={'offer_id': offer_id})
|
||||||
|
offer = offers[0]
|
||||||
|
|
||||||
|
swap_clients[1].ci(Coins.XMR).setFeePriority(3)
|
||||||
|
|
||||||
|
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)
|
||||||
|
assert (xmr_swap)
|
||||||
|
|
||||||
|
swap_clients[0].acceptXmrBid(bid_id)
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
class TestBCH(BasicSwapTest):
|
||||||
|
__test__ = True
|
||||||
|
test_coin_from = Coins.BCH
|
||||||
|
start_bch_nodes = True
|
||||||
|
base_rpc_port = BCH_BASE_RPC_PORT
|
||||||
|
|
||||||
|
def mineBlock(self, num_blocks=1):
|
||||||
|
self.callnoderpc('generatetoaddress', [num_blocks, self.bch_addr])
|
||||||
|
|
||||||
def check_softfork_active(self, feature_name):
|
def check_softfork_active(self, feature_name):
|
||||||
deploymentinfo = self.callnoderpc('getdeploymentinfo')
|
return True
|
||||||
assert (deploymentinfo['deployments'][feature_name]['active'] is True)
|
|
||||||
|
def test_001_nested_segwit(self):
|
||||||
|
logging.info('---------- Test {} p2sh nested segwit'.format(self.test_coin_from.name))
|
||||||
|
logging.info('Skipped')
|
||||||
|
|
||||||
|
def test_002_native_segwit(self):
|
||||||
|
logging.info('---------- Test {} p2sh native segwit'.format(self.test_coin_from.name))
|
||||||
|
logging.info('Skipped')
|
||||||
|
|
||||||
|
def test_003_cltv(self):
|
||||||
|
logging.info('---------- Test {} cltv'.format(self.test_coin_from.name))
|
||||||
|
|
||||||
|
ci = self.swap_clients[0].ci(self.test_coin_from)
|
||||||
|
|
||||||
|
self.check_softfork_active('bip65')
|
||||||
|
|
||||||
|
chain_height = self.callnoderpc('getblockcount')
|
||||||
|
script = CScript([chain_height + 3, OP_CHECKLOCKTIMEVERIFY, ])
|
||||||
|
|
||||||
|
script_dest = ci.getScriptDest(script)
|
||||||
|
tx = CTransaction()
|
||||||
|
tx.nVersion = ci.txVersion()
|
||||||
|
tx.vout.append(ci.txoType()(ci.make_int(1.1), script_dest))
|
||||||
|
tx_hex = ToHex(tx)
|
||||||
|
tx_funded = ci.rpc_wallet('fundrawtransaction', [tx_hex])
|
||||||
|
utxo_pos = 0 if tx_funded['changepos'] == 1 else 1
|
||||||
|
tx_signed = ci.rpc_wallet('signrawtransactionwithwallet', [tx_funded['hex'], ])['hex']
|
||||||
|
txid = ci.rpc('sendrawtransaction', [tx_signed, ])
|
||||||
|
|
||||||
|
addr_out = ci.rpc_wallet('getnewaddress', ['cltv test'])
|
||||||
|
pkh = ci.decodeAddress(addr_out)
|
||||||
|
script_out = ci.getScriptForPubkeyHash(pkh)
|
||||||
|
|
||||||
|
tx_spend = CTransaction()
|
||||||
|
tx_spend.nVersion = ci.txVersion()
|
||||||
|
tx_spend.nLockTime = chain_height + 3
|
||||||
|
tx_spend.vin.append(CTxIn(COutPoint(int(txid, 16), utxo_pos), scriptSig=CScript([script,])))
|
||||||
|
tx_spend.vout.append(ci.txoType()(ci.make_int(1.0999), script_out))
|
||||||
|
tx_spend_hex = ToHex(tx_spend)
|
||||||
|
|
||||||
|
tx_spend.nLockTime = chain_height + 2
|
||||||
|
tx_spend_invalid_hex = ToHex(tx_spend)
|
||||||
|
|
||||||
|
for tx_hex in [tx_spend_invalid_hex, tx_spend_hex]:
|
||||||
|
try:
|
||||||
|
txid = self.callnoderpc('sendrawtransaction', [tx_hex, ])
|
||||||
|
except Exception as e:
|
||||||
|
assert ('non-final' in str(e))
|
||||||
|
else:
|
||||||
|
assert False, 'Should fail'
|
||||||
|
|
||||||
|
self.mineBlock(5)
|
||||||
|
try:
|
||||||
|
txid = ci.rpc('sendrawtransaction', [tx_spend_invalid_hex, ])
|
||||||
|
except Exception as e:
|
||||||
|
assert ('Locktime requirement not satisfied' in str(e))
|
||||||
|
else:
|
||||||
|
assert False, 'Should fail'
|
||||||
|
|
||||||
|
txid = ci.rpc('sendrawtransaction', [tx_spend_hex, ])
|
||||||
|
self.mineBlock()
|
||||||
|
ro = ci.rpc_wallet('listreceivedbyaddress', [0, ])
|
||||||
|
sum_addr = 0
|
||||||
|
for entry in ro:
|
||||||
|
if entry['address'] == addr_out:
|
||||||
|
sum_addr += entry['amount']
|
||||||
|
assert (sum_addr == 1.0999)
|
||||||
|
|
||||||
|
# Ensure tx was mined
|
||||||
|
tx_wallet = ci.rpc_wallet('gettransaction', [txid, ])
|
||||||
|
assert (len(tx_wallet['blockhash']) == 64)
|
||||||
|
|
||||||
|
def test_004_csv(self):
|
||||||
|
logging.info('---------- Test {} csv'.format(self.test_coin_from.name))
|
||||||
|
|
||||||
|
swap_clients = self.swap_clients
|
||||||
|
ci = self.swap_clients[0].ci(self.test_coin_from)
|
||||||
|
|
||||||
|
self.check_softfork_active('csv')
|
||||||
|
|
||||||
|
script = CScript([3, OP_CHECKSEQUENCEVERIFY, ])
|
||||||
|
|
||||||
|
script_dest = ci.getScriptDest(script)
|
||||||
|
tx = CTransaction()
|
||||||
|
tx.nVersion = ci.txVersion()
|
||||||
|
tx.vout.append(ci.txoType()(ci.make_int(1.1), script_dest))
|
||||||
|
tx_hex = ToHex(tx)
|
||||||
|
tx_funded = ci.rpc_wallet('fundrawtransaction', [tx_hex])
|
||||||
|
utxo_pos = 0 if tx_funded['changepos'] == 1 else 1
|
||||||
|
tx_signed = ci.rpc_wallet('signrawtransactionwithwallet', [tx_funded['hex'], ])['hex']
|
||||||
|
txid = ci.rpc('sendrawtransaction', [tx_signed, ])
|
||||||
|
|
||||||
|
addr_out = ci.rpc_wallet('getnewaddress', ['csv test'])
|
||||||
|
pkh = ci.decodeAddress(addr_out)
|
||||||
|
script_out = ci.getScriptForPubkeyHash(pkh)
|
||||||
|
|
||||||
|
# Double check output type
|
||||||
|
prev_tx = ci.rpc('decoderawtransaction', [tx_signed, ])
|
||||||
|
assert (prev_tx['vout'][utxo_pos]['scriptPubKey']['type'] == 'scripthash')
|
||||||
|
|
||||||
|
tx_spend = CTransaction()
|
||||||
|
tx_spend.nVersion = ci.txVersion()
|
||||||
|
tx_spend.vin.append(CTxIn(COutPoint(int(txid, 16), utxo_pos),
|
||||||
|
nSequence=3,
|
||||||
|
scriptSig=CScript([script,])))
|
||||||
|
tx_spend.vout.append(ci.txoType()(ci.make_int(1.0999), script_out))
|
||||||
|
tx_spend_hex = ToHex(tx_spend)
|
||||||
|
try:
|
||||||
|
txid = ci.rpc('sendrawtransaction', [tx_spend_hex, ])
|
||||||
|
except Exception as e:
|
||||||
|
assert ('non-BIP68-final' in str(e))
|
||||||
|
else:
|
||||||
|
assert False, 'Should fail'
|
||||||
|
|
||||||
|
self.mineBlock(3)
|
||||||
|
txid = ci.rpc('sendrawtransaction', [tx_spend_hex, ])
|
||||||
|
self.mineBlock(1)
|
||||||
|
ro = ci.rpc_wallet('listreceivedbyaddress', [0, ])
|
||||||
|
sum_addr = 0
|
||||||
|
for entry in ro:
|
||||||
|
if entry['address'] == addr_out:
|
||||||
|
sum_addr += entry['amount']
|
||||||
|
assert (sum_addr == 1.0999)
|
||||||
|
|
||||||
|
# Ensure tx was mined
|
||||||
|
tx_wallet = ci.rpc_wallet('gettransaction', [txid, ])
|
||||||
|
assert (len(tx_wallet['blockhash']) == 64)
|
||||||
|
|
||||||
|
def test_005_watchonly(self):
|
||||||
|
logging.info('---------- Test {} watchonly'.format(self.test_coin_from.name))
|
||||||
|
ci = self.swap_clients[0].ci(self.test_coin_from)
|
||||||
|
ci1 = self.swap_clients[1].ci(self.test_coin_from)
|
||||||
|
|
||||||
|
addr = ci.rpc_wallet('getnewaddress', ['watchonly test'])
|
||||||
|
ro = ci1.rpc_wallet('importaddress', [addr, '', False])
|
||||||
|
txid = ci.rpc_wallet('sendtoaddress', [addr, 1.0])
|
||||||
|
tx_hex = ci.rpc('getrawtransaction', [txid, ])
|
||||||
|
ci1.rpc_wallet('sendrawtransaction', [tx_hex, ])
|
||||||
|
ro = ci1.rpc_wallet('gettransaction', [txid, ])
|
||||||
|
assert (ro['txid'] == txid)
|
||||||
|
|
||||||
|
def test_006_getblock_verbosity(self):
|
||||||
|
super().test_006_getblock_verbosity()
|
||||||
|
|
||||||
|
def test_007_hdwallet(self):
|
||||||
|
logging.info('---------- Test {} hdwallet'.format(self.test_coin_from.name))
|
||||||
|
|
||||||
|
test_seed = '8e54a313e6df8918df6d758fafdbf127a115175fdd2238d0e908dd8093c9ac3b'
|
||||||
|
test_wif = self.swap_clients[0].ci(self.test_coin_from).encodeKey(bytes.fromhex(test_seed))
|
||||||
|
new_wallet_name = random.randbytes(10).hex()
|
||||||
|
self.callnoderpc('createwallet', [new_wallet_name])
|
||||||
|
self.callnoderpc('sethdseed', [True, test_wif], wallet=new_wallet_name)
|
||||||
|
addr = self.callnoderpc('getnewaddress', wallet=new_wallet_name)
|
||||||
|
self.callnoderpc('unloadwallet', [new_wallet_name])
|
||||||
|
assert (addr == 'bchreg:qqxr67wf5ltty5jvm44zryywmpt7ntdaa50carjt59')
|
||||||
|
|
||||||
|
def test_008_gettxout(self):
|
||||||
|
super().test_008_gettxout()
|
||||||
|
|
||||||
|
def test_009_scantxoutset(self):
|
||||||
|
super().test_009_scantxoutset()
|
||||||
|
|
||||||
def test_010_bch_txn_size(self):
|
def test_010_bch_txn_size(self):
|
||||||
logging.info('---------- Test {} txn_size'.format(Coins.BCH))
|
logging.info('---------- Test {} txn_size'.format(Coins.BCH))
|
||||||
|
@ -218,26 +416,107 @@ class TestFunctions(BaseTest):
|
||||||
assert (expect_size >= lock_tx_b_spend_decoded['size'])
|
assert (expect_size >= lock_tx_b_spend_decoded['size'])
|
||||||
assert (expect_size - lock_tx_b_spend_decoded['size'] < 10)
|
assert (expect_size - lock_tx_b_spend_decoded['size'] < 10)
|
||||||
|
|
||||||
def test_05_bch_xmr(self):
|
def test_011_p2sh(self):
|
||||||
logging.info('---------- Test BCH to XMR')
|
# Not used in bsx for native-segwit coins
|
||||||
|
logging.info('---------- Test {} p2sh'.format(self.test_coin_from.name))
|
||||||
|
|
||||||
swap_clients = self.swap_clients
|
swap_clients = self.swap_clients
|
||||||
offer_id = swap_clients[0].postOffer(Coins.BCH, Coins.XMR, 10 * COIN, 100 * XMR_COIN, 10 * COIN, SwapTypes.XMR_SWAP)
|
ci = self.swap_clients[0].ci(self.test_coin_from)
|
||||||
wait_for_offer(test_delay_event, swap_clients[1], offer_id)
|
|
||||||
offers = swap_clients[1].listOffers(filters={'offer_id': offer_id})
|
|
||||||
offer = offers[0]
|
|
||||||
|
|
||||||
swap_clients[1].ci(Coins.XMR).setFeePriority(3)
|
script = CScript([2, 2, OP_EQUAL, ])
|
||||||
|
|
||||||
bid_id = swap_clients[1].postXmrBid(offer_id, offer.amount_from)
|
script_dest = ci.get_p2sh_script_pubkey(script)
|
||||||
|
tx = CTransaction()
|
||||||
|
tx.nVersion = ci.txVersion()
|
||||||
|
tx.vout.append(ci.txoType()(ci.make_int(1.1), script_dest))
|
||||||
|
tx_hex = ToHex(tx)
|
||||||
|
tx_funded = ci.rpc_wallet('fundrawtransaction', [tx_hex])
|
||||||
|
utxo_pos = 0 if tx_funded['changepos'] == 1 else 1
|
||||||
|
tx_signed = ci.rpc_wallet('signrawtransactionwithwallet', [tx_funded['hex'], ])['hex']
|
||||||
|
txid = ci.rpc('sendrawtransaction', [tx_signed, ])
|
||||||
|
|
||||||
wait_for_bid(test_delay_event, swap_clients[0], bid_id, BidStates.BID_RECEIVED)
|
addr_out = ci.rpc_wallet('getnewaddress', ['csv test'])
|
||||||
|
pkh = ci.decodeAddress(addr_out)
|
||||||
|
script_out = ci.getScriptForPubkeyHash(pkh)
|
||||||
|
|
||||||
bid, xmr_swap = swap_clients[0].getXmrBid(bid_id)
|
# Double check output type
|
||||||
assert (xmr_swap)
|
prev_tx = ci.rpc('decoderawtransaction', [tx_signed, ])
|
||||||
|
assert (prev_tx['vout'][utxo_pos]['scriptPubKey']['type'] == 'scripthash')
|
||||||
|
|
||||||
swap_clients[0].acceptXmrBid(bid_id)
|
tx_spend = CTransaction()
|
||||||
|
tx_spend.nVersion = ci.txVersion()
|
||||||
|
tx_spend.vin.append(CTxIn(COutPoint(int(txid, 16), utxo_pos),
|
||||||
|
scriptSig=CScript([script,])))
|
||||||
|
tx_spend.vout.append(ci.txoType()(ci.make_int(1.0999), script_out))
|
||||||
|
tx_spend_hex = ToHex(tx_spend)
|
||||||
|
|
||||||
wait_for_bid(test_delay_event, swap_clients[0], bid_id, BidStates.SWAP_COMPLETED, wait_for=180)
|
txid = ci.rpc('sendrawtransaction', [tx_spend_hex, ])
|
||||||
wait_for_bid(test_delay_event, swap_clients[1], bid_id, BidStates.SWAP_COMPLETED, sent=True)
|
self.mineBlock(1)
|
||||||
|
ro = ci.rpc_wallet('listreceivedbyaddress', [0, ])
|
||||||
|
sum_addr = 0
|
||||||
|
for entry in ro:
|
||||||
|
if entry['address'] == addr_out:
|
||||||
|
sum_addr += entry['amount']
|
||||||
|
assert (sum_addr == 1.0999)
|
||||||
|
|
||||||
swap_clients[1].ci(Coins.XMR).setFeePriority(0)
|
# Ensure tx was mined
|
||||||
|
tx_wallet = ci.rpc_wallet('gettransaction', [txid, ])
|
||||||
|
assert (len(tx_wallet['blockhash']) == 64)
|
||||||
|
|
||||||
|
def test_011_p2sh32(self):
|
||||||
|
# Not used in bsx for native-segwit coins
|
||||||
|
logging.info('---------- Test {} p2sh32'.format(self.test_coin_from.name))
|
||||||
|
|
||||||
|
swap_clients = self.swap_clients
|
||||||
|
ci = self.swap_clients[0].ci(self.test_coin_from)
|
||||||
|
|
||||||
|
script = CScript([2, 2, OP_EQUAL, ])
|
||||||
|
|
||||||
|
script_dest = ci.scriptToP2SH32LockingBytecode(script)
|
||||||
|
tx = CTransaction()
|
||||||
|
tx.nVersion = ci.txVersion()
|
||||||
|
tx.vout.append(ci.txoType()(ci.make_int(1.1), script_dest))
|
||||||
|
tx_hex = ToHex(tx)
|
||||||
|
tx_funded = ci.rpc_wallet('fundrawtransaction', [tx_hex])
|
||||||
|
utxo_pos = 0 if tx_funded['changepos'] == 1 else 1
|
||||||
|
tx_signed = ci.rpc_wallet('signrawtransactionwithwallet', [tx_funded['hex'], ])['hex']
|
||||||
|
txid = ci.rpc('sendrawtransaction', [tx_signed, ])
|
||||||
|
|
||||||
|
addr_out = ci.rpc_wallet('getnewaddress', ['csv test'])
|
||||||
|
pkh = ci.decodeAddress(addr_out)
|
||||||
|
script_out = ci.getScriptForPubkeyHash(pkh)
|
||||||
|
|
||||||
|
# Double check output type
|
||||||
|
prev_tx = ci.rpc('decoderawtransaction', [tx_signed, ])
|
||||||
|
assert (prev_tx['vout'][utxo_pos]['scriptPubKey']['type'] == 'scripthash')
|
||||||
|
|
||||||
|
tx_spend = CTransaction()
|
||||||
|
tx_spend.nVersion = ci.txVersion()
|
||||||
|
tx_spend.vin.append(CTxIn(COutPoint(int(txid, 16), utxo_pos),
|
||||||
|
scriptSig=CScript([script,])))
|
||||||
|
tx_spend.vout.append(ci.txoType()(ci.make_int(1.0999), script_out))
|
||||||
|
tx_spend_hex = ToHex(tx_spend)
|
||||||
|
|
||||||
|
txid = ci.rpc('sendrawtransaction', [tx_spend_hex, ])
|
||||||
|
self.mineBlock(1)
|
||||||
|
ro = ci.rpc_wallet('listreceivedbyaddress', [0, ])
|
||||||
|
sum_addr = 0
|
||||||
|
for entry in ro:
|
||||||
|
if entry['address'] == addr_out:
|
||||||
|
sum_addr += entry['amount']
|
||||||
|
assert (sum_addr == 1.0999)
|
||||||
|
|
||||||
|
# Ensure tx was mined
|
||||||
|
tx_wallet = ci.rpc_wallet('gettransaction', [txid, ])
|
||||||
|
assert (len(tx_wallet['blockhash']) == 64)
|
||||||
|
|
||||||
|
def test_012_p2sh_p2wsh(self):
|
||||||
|
logging.info('---------- Test {} p2sh-p2wsh'.format(self.test_coin_from.name))
|
||||||
|
logging.info('Skipped')
|
||||||
|
|
||||||
|
def test_01_a_full_swap(self):
|
||||||
|
super().test_01_a_full_swap()
|
||||||
|
|
||||||
|
def test_01_b_full_swap_reverse(self):
|
||||||
|
self.prepare_balance(Coins.BCH, 100.0, 1801, 1800)
|
||||||
|
super().test_01_b_full_swap_reverse()
|
Loading…
Reference in a new issue