From 2979b3e244aeef4eb5181613a44bce69e23a8246 Mon Sep 17 00:00:00 2001 From: tecnovert Date: Thu, 10 Dec 2020 16:37:26 +0200 Subject: [PATCH] Show coin a lock tx blocks confirmed. --- basicswap/basicswap.py | 43 ++++++++++++++++------------ basicswap/interface_btc.py | 8 ++---- basicswap/protocols/atomic_swap_1.py | 4 +++ basicswap/ui.py | 6 ++-- basicswap/util.py | 10 +++++++ 5 files changed, 45 insertions(+), 26 deletions(-) diff --git a/basicswap/basicswap.py b/basicswap/basicswap.py index a3caf09..5b6ef33 100644 --- a/basicswap/basicswap.py +++ b/basicswap/basicswap.py @@ -41,6 +41,8 @@ from .util import ( toWIF, getKeyID, make_int, + getP2SHScriptForHash, + getP2WSH, ) from .chainparams import ( chainparams, @@ -190,6 +192,8 @@ class EventLogTypes(IntEnum): LOCK_TX_A_PUBLISHED = auto() LOCK_TX_B_PUBLISHED = auto() FAILED_TX_B_SPEND = auto() + LOCK_TX_A_SEEN = auto() + LOCK_TX_A_CONFIRMED = auto() LOCK_TX_B_SEEN = auto() LOCK_TX_B_CONFIRMED = auto() @@ -324,6 +328,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_A_SEEN: + return 'Lock tx a seen in chain' + if event_type == EventLogTypes.LOCK_TX_A_CONFIRMED: + return 'Lock tx a confirmed in chain' if event_type == EventLogTypes.LOCK_TX_B_SEEN: return 'Lock tx b seen in chain' if event_type == EventLogTypes.LOCK_TX_B_CONFIRMED: @@ -351,10 +359,6 @@ def decodeSequence(lock_value): return lock_value & SEQUENCE_LOCKTIME_MASK -def extractScriptSecretHash(script): - return script[7:39] - - def getVoutByAddress(txjs, p2sh): for o in txjs['vout']: try: @@ -375,16 +379,6 @@ def getVoutByP2WSH(txjs, p2wsh_hex): raise ValueError('P2WSH output not found in txn') -def getP2SHScriptForHash(p2sh): - return bytearray([OpCodes.OP_HASH160, 0x14]) \ - + p2sh \ - + bytearray([OpCodes.OP_EQUAL]) - - -def getP2WSH(script): - return bytearray([OpCodes.OP_0, 0x20]) + hashlib.sha256(script).digest() - - def replaceAddrPrefix(addr, coin_type, chain_name, addr_type='pubkey_address'): return encodeAddress(bytes((chainparams[coin_type][chain_name][addr_type],)) + decodeAddress(addr)[1:]) @@ -566,7 +560,7 @@ class BasicSwap(BaseApp): else: raise ValueError('Missing XMR wallet rpc credentials.') - def ci(self, coin): # coin interface + def ci(self, coin): # Coin interface return self.coin_clients[coin]['interface'] def createInterface(self, coin): @@ -611,7 +605,7 @@ class BasicSwap(BaseApp): except Exception: time.sleep(0.5) try: - if os.name != 'nt' or cc['core_version_group'] > 17: # litecoin on windows doesn't write a pid file + if os.name != 'nt' or cc['core_version_group'] > 17: # Litecoin on windows doesn't write a pid file assert(datadir_pid == cc['pid']), 'Mismatched pid' with open(authcookiepath, 'rb') as fp: cc['rpcauth'] = fp.read().decode('utf-8') @@ -2025,7 +2019,7 @@ class BasicSwap(BaseApp): bid_date = dt.datetime.fromtimestamp(bid.created_at).date() - secret_hash = extractScriptSecretHash(bid.initiate_tx.script) + secret_hash = atomic_swap_1.extractScriptSecretHash(bid.initiate_tx.script) pkhash_seller = bid.pkhash_seller pkhash_buyer_refund = bid.pkhash_buyer @@ -2594,9 +2588,10 @@ class BasicSwap(BaseApp): return rv # TODO: Timeout waiting for transactions - + bid_changed = False a_lock_tx_dest = ci_from.getScriptDest(xmr_swap.a_lock_tx_script) - utxos = ci_from.getOutput(bid.xmr_a_lock_tx.txid, a_lock_tx_dest, bid.amount) + utxos, chain_height = ci_from.getOutput(bid.xmr_a_lock_tx.txid, a_lock_tx_dest, bid.amount) + self.coin_clients[ci_from.coin_type()]['last_height'] = chain_height if len(utxos) < 1: return rv @@ -2605,7 +2600,15 @@ class BasicSwap(BaseApp): raise ValueError('Too many outputs for chain A lock tx') utxo = utxos[0] + if not bid.xmr_a_lock_tx.chain_height and utxo['height'] != 0: + self.logBidEvent(bid, EventLogTypes.LOCK_TX_A_SEEN, '', session) + bid_changed = True + if bid.xmr_a_lock_tx.chain_height != utxo['height'] and utxo['height'] != 0: + bid.xmr_a_lock_tx.chain_height = utxo['height'] + bid_changed = True + if utxo['depth'] >= ci_from.blocks_confirmed: + self.logBidEvent(bid, EventLogTypes.LOCK_TX_A_CONFIRMED, '', session) bid.xmr_a_lock_tx.setState(TxStates.TX_CONFIRMED) bid.setState(BidStates.XMR_SWAP_SCRIPT_COIN_LOCKED) self.saveBidInSession(bid_id, bid, session, xmr_swap) @@ -2615,7 +2618,9 @@ class BasicSwap(BaseApp): self.log.info('Sending xmr swap chain B lock tx for bid %s in %d seconds', bid_id.hex(), delay) self.createEventInSession(delay, EventTypes.SEND_XMR_SWAP_LOCK_TX_B, bid_id, session) # bid.setState(BidStates.SWAP_DELAYING) + bid_changed = True + if bid_changed: session.commit() elif state == BidStates.XMR_SWAP_SCRIPT_COIN_LOCKED: diff --git a/basicswap/interface_btc.py b/basicswap/interface_btc.py index 0026e6b..6bd2651 100644 --- a/basicswap/interface_btc.py +++ b/basicswap/interface_btc.py @@ -874,9 +874,6 @@ class BTCInterface(CoinInterface): chain_height = utxos['height'] rv = [] for utxo in utxos['unspents']: - print('utxo', utxo) - depth = 0 if 'height' not in utxo else utxos['height'] - utxo['height'] - if txid and txid.hex() != utxo['txid']: continue @@ -884,11 +881,12 @@ class BTCInterface(CoinInterface): continue rv.append({ - 'depth': depth, + 'depth': 0 if 'height' not in utxo else chain_height - utxo['height'], + 'height': 0 if 'height' not in utxo else utxo['height'], 'amount': utxo['amount'] * COIN, 'txid': utxo['txid'], 'vout': utxo['vout']}) - return rv + return rv, chain_height def withdrawCoin(self, value, addr_to, subfee): params = [addr_to, value, '', '', subfee, True, self._conf_target] diff --git a/basicswap/protocols/atomic_swap_1.py b/basicswap/protocols/atomic_swap_1.py index 9490be6..8c664fc 100644 --- a/basicswap/protocols/atomic_swap_1.py +++ b/basicswap/protocols/atomic_swap_1.py @@ -41,3 +41,7 @@ def buildContractScript(lock_val, secret_hash, pkh_redeem, pkh_refund, op_lock=O OpCodes.OP_EQUALVERIFY, OpCodes.OP_CHECKSIG]) return script + + +def extractScriptSecretHash(script): + return script[7:39] diff --git a/basicswap/ui.py b/basicswap/ui.py index 1490136..c9bbd38 100644 --- a/basicswap/ui.py +++ b/basicswap/ui.py @@ -152,7 +152,10 @@ def describeBid(swap_client, bid, offer, edit_bid, show_txns): if offer.swap_type == SwapTypes.XMR_SWAP: txns = [] if bid.xmr_a_lock_tx: - txns.append({'type': 'Chain A Lock', 'txid': bid.xmr_a_lock_tx.txid.hex()}) + confirms = None + if swap_client.coin_clients[ci_from.coin_type()]['last_height'] and bid.xmr_a_lock_tx.chain_height: + confirms = swap_client.coin_clients[ci_from.coin_type()]['last_height'] - bid.xmr_a_lock_tx.chain_height + txns.append({'type': 'Chain A Lock', 'txid': bid.xmr_a_lock_tx.txid.hex(), 'confirms': confirms}) 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: @@ -162,7 +165,6 @@ def describeBid(swap_client, bid, offer, edit_bid, show_txns): 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()}) - for tx_type, tx in bid.txns.items(): txns.append({'type': strTxType(tx_type), 'txid': tx.txid.hex()}) data['txns'] = txns diff --git a/basicswap/util.py b/basicswap/util.py index b8316b1..ca38354 100644 --- a/basicswap/util.py +++ b/basicswap/util.py @@ -301,3 +301,13 @@ def format_amount(i, display_scale, scale=None): if i < 0: rv = '-' + rv return rv + + +def getP2SHScriptForHash(p2sh): + return bytes([OpCodes.OP_HASH160, 0x14]) \ + + p2sh \ + + bytes([OpCodes.OP_EQUAL]) + + +def getP2WSH(script): + return bytes([OpCodes.OP_0, 0x20]) + hashlib.sha256(script).digest()