From 4bde19fe33429e95eaeffdc3bcdf147a868d6644 Mon Sep 17 00:00:00 2001 From: tecnovert Date: Wed, 9 Dec 2020 21:30:21 +0200 Subject: [PATCH] Record the coin b lock tx before it's confirmed. --- basicswap/basicswap.py | 39 ++++++++++++++++++++++++-------- basicswap/interface_xmr.py | 13 +++++++---- basicswap/templates/bid_xmr.html | 4 ++-- basicswap/ui.py | 5 +++- 4 files changed, 44 insertions(+), 17 deletions(-) diff --git a/basicswap/basicswap.py b/basicswap/basicswap.py index a539509..fb3bef8 100644 --- a/basicswap/basicswap.py +++ b/basicswap/basicswap.py @@ -187,6 +187,8 @@ class EventLogTypes(IntEnum): LOCK_TX_A_PUBLISHED = auto() LOCK_TX_B_PUBLISHED = auto() FAILED_TX_B_SPEND = auto() + LOCK_TX_B_SEEN = auto() + LOCK_TX_B_CONFIRMED = auto() class XmrSplitMsgTypes(IntEnum): @@ -319,6 +321,10 @@ def describeEventEntry(event_type, event_msg): return 'Lock tx b published' if event_type == EventLogTypes.FAILED_TX_B_SPEND: return 'Failed to publish lock tx b spend' + if event_type == EventLogTypes.LOCK_TX_B_SEEN: + return 'Lock tx b seen in chain' + if event_type == EventLogTypes.LOCK_TX_B_CONFIRMED: + return 'Lock tx b confirmed in chain' def getExpectedSequence(lockType, lockVal, coin_type): @@ -569,6 +575,7 @@ class BasicSwap(BaseApp): 'conf_target': chain_client_settings.get('conf_target', 2), 'watched_outputs': [], 'last_height_checked': last_height_checked, + 'last_height': None, 'use_segwit': chain_client_settings.get('use_segwit', False), 'use_csv': chain_client_settings.get('use_csv', True), 'core_version_group': chain_client_settings.get('core_version_group', 0), @@ -2643,27 +2650,41 @@ class BasicSwap(BaseApp): if bid.was_sent and bid.xmr_b_lock_tx is None: return rv + bid_changed = False + # Have to use findTxB instead of relying on the first seen height to detect chain reorgs found_tx = ci_to.findTxB(xmr_swap.vkbv, xmr_swap.pkbs, bid.amount_to, ci_to.blocks_confirmed, xmr_swap.b_restore_height) if found_tx is not None: - self.log.debug('Found {} lock tx in chain'.format(ci_to.coin_name())) if bid.xmr_b_lock_tx is None: + self.log.debug('Found {} lock tx in chain'.format(ci_to.coin_name())) + self.logBidEvent(bid, EventLogTypes.LOCK_TX_B_SEEN, '', session) b_lock_tx_id = bytes.fromhex(found_tx['txid']) bid.xmr_b_lock_tx = SwapTx( bid_id=bid_id, tx_type=TxTypes.XMR_SWAP_B_LOCK, txid=b_lock_tx_id, + chain_height=found_tx['height'], ) + bid_changed = True + else: + bid.xmr_b_lock_tx.chain_height = found_tx['height'] + bid_changed = True - bid.xmr_b_lock_tx.setState(TxStates.TX_CONFIRMED) + if bid.xmr_b_lock_tx and bid.xmr_b_lock_tx.chain_height is not None and bid.xmr_b_lock_tx.chain_height > 0: + chain_height = ci_to.getChainHeight() + self.coin_clients[ci_to.coin_type()]['last_height'] = chain_height - bid.setState(BidStates.XMR_SWAP_NOSCRIPT_COIN_LOCKED) + if chain_height - bid.xmr_b_lock_tx.chain_height >= ci_to.blocks_confirmed: + self.logBidEvent(bid, EventLogTypes.LOCK_TX_B_CONFIRMED, '', session) + bid.xmr_b_lock_tx.setState(TxStates.TX_CONFIRMED) + bid.setState(BidStates.XMR_SWAP_NOSCRIPT_COIN_LOCKED) + + if bid.was_received: + delay = random.randrange(self.min_delay_event, self.max_delay_event) + self.log.info('Releasing xmr swap secret for bid %s in %d seconds', bid_id.hex(), delay) + self.createEventInSession(delay, EventTypes.SEND_XMR_SECRET, bid_id, session) + + if bid_changed: self.saveBidInSession(bid_id, bid, session, xmr_swap) - - if bid.was_received: - delay = random.randrange(self.min_delay_event, self.max_delay_event) - self.log.info('Releasing xmr swap secret for bid %s in %d seconds', bid_id.hex(), delay) - self.createEventInSession(delay, EventTypes.SEND_XMR_SECRET, bid_id, session) - session.commit() elif state == BidStates.XMR_SWAP_SECRET_SHARED: # Wait for script spend tx to confirm diff --git a/basicswap/interface_xmr.py b/basicswap/interface_xmr.py index 2f0f94b..7a3d8d8 100644 --- a/basicswap/interface_xmr.py +++ b/basicswap/interface_xmr.py @@ -232,21 +232,24 @@ class XMRInterface(CoinInterface): rv = self.rpc_wallet_cb('refresh') + ''' # Debug try: - current_height = self.rpc_cb('get_block_count')['count'] + current_height = self.rpc_wallet_cb('get_block_count')['count'] logging.info('findTxB XMR current_height %d\nAddress: %s', current_height, address_b58) except Exception as e: logging.info('rpc_cb failed %s', str(e)) current_height = None # If the transfer is available it will be deep enough - + ''' params = {'transfer_type': 'available'} rv = self.rpc_wallet_cb('incoming_transfers', params) if 'transfers' in rv: for transfer in rv['transfers']: - if transfer['amount'] == cb_swap_value \ - and (current_height is None or current_height - transfer['block_height'] > cb_block_confirmed): - return {'txid': transfer['tx_hash'], 'amount': transfer['amount'], 'height': transfer['block_height']} + if transfer['amount'] == cb_swap_value: + # and (current_height is None or current_height - transfer['block_height'] > cb_block_confirmed): + return {'txid': transfer['tx_hash'], 'amount': transfer['amount'], 'height': 0 if 'block_height' not in transfer else transfer['block_height']} + else: + logging.warning('Incorrect amount detected for coin b lock txn: {}'.format(transfer['tx_hash'])) return None diff --git a/basicswap/templates/bid_xmr.html b/basicswap/templates/bid_xmr.html index d32016c..afa08dc 100644 --- a/basicswap/templates/bid_xmr.html +++ b/basicswap/templates/bid_xmr.html @@ -24,9 +24,9 @@ {% if data.show_txns %}

Transactions

- + {% for tx in data.txns %} - + {% endfor %}
Tx TypeTx ID
Tx TypeTx IDBlocks Deep
{{ tx.type }}{{ tx.txid }}
{{ tx.type }}{{ tx.txid }}{{ tx.confirms }}
{% endif %} diff --git a/basicswap/ui.py b/basicswap/ui.py index 79dd50e..1490136 100644 --- a/basicswap/ui.py +++ b/basicswap/ui.py @@ -156,7 +156,10 @@ def describeBid(swap_client, bid, offer, edit_bid, show_txns): if bid.xmr_a_lock_spend_tx: txns.append({'type': 'Chain A Lock Spend', 'txid': bid.xmr_a_lock_spend_tx.txid.hex()}) if bid.xmr_b_lock_tx: - txns.append({'type': 'Chain B Lock', 'txid': bid.xmr_b_lock_tx.txid.hex()}) + confirms = None + if swap_client.coin_clients[ci_to.coin_type()]['last_height'] and bid.xmr_b_lock_tx.chain_height: + confirms = swap_client.coin_clients[ci_to.coin_type()]['last_height'] - bid.xmr_b_lock_tx.chain_height + txns.append({'type': 'Chain B Lock', 'txid': bid.xmr_b_lock_tx.txid.hex(), 'confirms': confirms}) if bid.xmr_b_lock_tx and bid.xmr_b_lock_tx.spend_txid: txns.append({'type': 'Chain B Lock Spend', 'txid': bid.xmr_b_lock_tx.spend_txid.hex()})