diff --git a/basicswap/basicswap.py b/basicswap/basicswap.py index c6e8cdd..b159f8b 100644 --- a/basicswap/basicswap.py +++ b/basicswap/basicswap.py @@ -3890,6 +3890,15 @@ class BasicSwap(BaseApp): try: txid = ci_from.publishTx(xmr_swap.a_lock_refund_tx) + # bch txids change + if self.isBchXmrSwap(offer): + self.log.debug('Recomputing refund spend transaction and txid after submitting lock tx spend.') + + tx = ci_from.loadTx(xmr_swap.a_lock_refund_spend_tx) + tx.vin[0].prevout.hash = b2i(xmr_swap.a_lock_refund_tx_id) + xmr_swap.a_lock_refund_spend_tx = tx.serialize_without_witness() + xmr_swap.a_lock_refund_spend_tx_id = ci_from.getTxid(xmr_swap.a_lock_refund_spend_tx) + self.log.info('Submitted coin a lock refund tx for bid {}'.format(bid_id.hex())) self.logBidEvent(bid.bid_id, EventLogTypes.LOCK_TX_A_REFUND_TX_PUBLISHED, '', session) bid.txns[TxTypes.XMR_SWAP_A_LOCK_REFUND] = SwapTx( @@ -4437,7 +4446,7 @@ class BasicSwap(BaseApp): self.log.debug('Coin a lock tx spent by lock refund tx.') # bch txids change if self.isBchXmrSwap(offer): - self.log.debug('Recomputing refund spend transaction and txid after lock tx spend.') + self.log.debug('Recomputing refund spend transaction and txid after lock tx spent.') xmr_swap.a_lock_refund_tx_id = spending_txid xmr_swap.a_lock_refund_tx = bytes.fromhex(spend_txn_hex) @@ -5823,7 +5832,7 @@ class BasicSwap(BaseApp): lock_tx_signed = ci_from.signTxWithWallet(xmr_swap.a_lock_tx) txid_hex = ci_from.publishTx(lock_tx_signed) if txid_hex != b2h(xmr_swap.a_lock_tx_id): - self.log.info('Recomputing lock refund and lock spend transactions and txids after lock tx publish') + self.log.info('Recomputing refund transactions and txids after lock tx publish') xmr_swap.a_lock_tx = lock_tx_signed xmr_swap.a_lock_tx_id = bytes.fromhex(txid_hex) diff --git a/basicswap/interface/bch.py b/basicswap/interface/bch.py index b9f8ed5..72854ac 100644 --- a/basicswap/interface/bch.py +++ b/basicswap/interface/bch.py @@ -57,17 +57,15 @@ from coincurve.ecdsaotves import ( ecdsaotves_rec_enc_key, ) -def findOutput(tx, script_pk: bytes): - for i in range(len(tx.vout)): - if tx.vout[i].scriptPubKey == script_pk: - return i - return None - class BCHInterface(BTCInterface): @staticmethod def coin_type(): return Coins.BCH + @staticmethod + def xmr_swap_a_lock_spend_tx_vsize() -> int: + return 302 + def __init__(self, coin_settings, network, swap_client=None): super(BCHInterface, self).__init__(coin_settings, network, swap_client) # No multiwallet support @@ -85,6 +83,17 @@ class BCHInterface(BTCInterface): args = [label] return self.rpc_wallet('getnewaddress', args) + def getUnspentsByAddr(self): + unspent_addr = dict() + unspent = self.rpc_wallet('listunspent') + for u in unspent: + if u.get('spendable', False) is False: + continue + if 'address' not in u: + continue + unspent_addr[u['address']] = unspent_addr.get(u['address'], 0) + self.make_int(u['amount'], r=1) + return unspent_addr + # returns pkh def decodeAddress(self, address: str) -> bytes: return bytes(Address.from_string(address).payload) diff --git a/tests/basicswap/test_bch_xmr.py b/tests/basicswap/test_bch_xmr.py index 90d8f47..178c7de 100644 --- a/tests/basicswap/test_bch_xmr.py +++ b/tests/basicswap/test_bch_xmr.py @@ -7,51 +7,28 @@ import random import logging -import unittest from basicswap.chainparams import XMR_COIN -from basicswap.db import ( - Concepts, -) from basicswap.basicswap import ( BidStates, Coins, - DebugTypes, SwapTypes, ) -from basicswap.basicswap_util import ( - TxLockTypes, - EventLogTypes, -) from basicswap.util import ( COIN, - make_int, - format_amount, ) -from basicswap.interface.base import Curves from basicswap.util.crypto import sha256 from tests.basicswap.test_btc_xmr import BasicSwapTest -from tests.basicswap.util import ( - read_json_api, -) from tests.basicswap.common import ( BCH_BASE_RPC_PORT, - abandon_all_swaps, wait_for_bid, - wait_for_event, wait_for_offer, - wait_for_balance, - wait_for_unspent, - wait_for_none_active, - BTC_BASE_RPC_PORT, ) from basicswap.contrib.test_framework.messages import ( ToHex, - FromHex, CTxIn, COutPoint, CTransaction, - CTxInWitness, ) from basicswap.contrib.test_framework.script import ( CScript, @@ -64,8 +41,7 @@ from .test_xmr import BaseTest, test_delay_event, callnoderpc from coincurve.ecdsaotves import ( ecdsaotves_enc_sign, ecdsaotves_enc_verify, - ecdsaotves_dec_sig, - ecdsaotves_rec_enc_key + ecdsaotves_dec_sig ) logger = logging.getLogger() @@ -283,7 +259,7 @@ class TestBCH(BasicSwapTest): def test_009_scantxoutset(self): super().test_009_scantxoutset() - def test_010_bch_txn_size(self): + def test_010_txn_size(self): logging.info('---------- Test {} txn_size'.format(Coins.BCH)) swap_clients = self.swap_clients @@ -335,7 +311,6 @@ class TestBCH(BasicSwapTest): lock_tx = ci.fundSCLockTx(lock_tx, fee_rate) lock_tx = ci.signTxWithWallet(lock_tx) print(lock_tx.hex()) - return unspents_after = ci.rpc('listunspent') assert (len(unspents) > len(unspents_after)) @@ -399,23 +374,6 @@ class TestBCH(BasicSwapTest): assert (expect_size >= vsize_actual) assert (expect_size - vsize_actual < 10) - # Test chain b (no-script) lock tx size - v = ci.getNewSecretKey() - s = ci.getNewSecretKey() - S = ci.getPubkey(s) - lock_tx_b_txid = ci.publishBLockTx(v, S, amount, fee_rate) - - addr_out = ci.getNewAddress(True) - lock_tx_b_spend_txid = ci.spendBLockTx(lock_tx_b_txid, addr_out, v, s, amount, fee_rate, 0) - lock_tx_b_spend = ci.getTransaction(lock_tx_b_spend_txid) - if lock_tx_b_spend is None: - lock_tx_b_spend = ci.getWalletTransaction(lock_tx_b_spend_txid) - lock_tx_b_spend_decoded = ci.rpc('decoderawtransaction', [lock_tx_b_spend.hex()]) - - expect_size: int = ci.xmr_swap_b_lock_spend_tx_vsize() - assert (expect_size >= lock_tx_b_spend_decoded['size']) - assert (expect_size - lock_tx_b_spend_decoded['size'] < 10) - def test_011_p2sh(self): # Not used in bsx for native-segwit coins logging.info('---------- Test {} p2sh'.format(self.test_coin_from.name)) @@ -548,7 +506,44 @@ class TestBCH(BasicSwapTest): def test_04_a_follower_recover_b_lock_tx(self): super().test_04_a_follower_recover_b_lock_tx() - # does not work yet - # def test_04_b_follower_recover_b_lock_tx_reverse(self): - # self.prepare_balance(Coins.BCH, 100.0, 1801, 1800) - # super().test_04_b_follower_recover_b_lock_tx_reverse() \ No newline at end of file + def test_04_b_follower_recover_b_lock_tx_reverse(self): + self.prepare_balance(Coins.BCH, 100.0, 1801, 1800) + super().test_04_b_follower_recover_b_lock_tx_reverse() + + def test_04_c_follower_recover_b_lock_tx_to_part(self): + super().test_04_c_follower_recover_b_lock_tx_to_part() + + def test_04_d_follower_recover_b_lock_tx_from_part(self): + self.prepare_balance(Coins.BCH, 100.0, 1801, 1800) + super().test_04_d_follower_recover_b_lock_tx_from_part() + + def test_05_self_bid(self): + self.prepare_balance(Coins.BCH, 100.0, 1801, 1800) + super().test_05_self_bid() + + def test_05_self_bid_to_part(self): + self.prepare_balance(Coins.BCH, 100.0, 1801, 1800) + super().test_05_self_bid_to_part() + + def test_05_self_bid_from_part(self): + self.prepare_balance(Coins.BCH, 100.0, 1801, 1800) + super().test_05_self_bid_from_part() + + def test_05_self_bid_rev(self): + self.prepare_balance(Coins.BCH, 100.0, 1801, 1800) + super().test_05_self_bid_rev() + + def test_06_preselect_inputs(self): + tla_from = self.test_coin_from.name + logging.info('---------- Test {} Preselected inputs'.format(tla_from)) + logging.info('Skipped') + + def test_07_expire_stuck_accepted(self): + super().test_07_expire_stuck_accepted() + + def test_08_insufficient_funds(self): + super().test_08_insufficient_funds() + + def test_08_insufficient_funds_rev(self): + self.prepare_balance(Coins.BCH, 100.0, 1801, 1800) + super().test_08_insufficient_funds_rev() \ No newline at end of file