mirror of
https://github.com/basicswap/basicswap.git
synced 2025-03-23 07:38:52 +00:00
Switch BCH from using wallet watchonly to watching scripts in BSX.
Using wallet watchonly to find the lock transactions only seems to work with rescanblockchain.
This commit is contained in:
parent
c561efaba0
commit
3a5e40187a
5 changed files with 123 additions and 68 deletions
|
@ -46,6 +46,7 @@ from .util import (
|
||||||
format_timestamp,
|
format_timestamp,
|
||||||
DeserialiseNum,
|
DeserialiseNum,
|
||||||
h2b,
|
h2b,
|
||||||
|
hex_or_none,
|
||||||
i2b,
|
i2b,
|
||||||
zeroIfNone,
|
zeroIfNone,
|
||||||
make_int,
|
make_int,
|
||||||
|
@ -3775,7 +3776,7 @@ class BasicSwap(BaseApp):
|
||||||
bid_changed = False
|
bid_changed = False
|
||||||
|
|
||||||
found_tx = None
|
found_tx = None
|
||||||
if ci_to.coin_type() in (Coins.DCR, ):
|
if ci_to.watch_blocks_for_scripts():
|
||||||
if bid.xmr_b_lock_tx is None or bid.xmr_b_lock_tx.txid is None:
|
if bid.xmr_b_lock_tx is None or bid.xmr_b_lock_tx.txid is None:
|
||||||
# Watching chain for dest_address with WatchedScript
|
# Watching chain for dest_address with WatchedScript
|
||||||
pass
|
pass
|
||||||
|
@ -3794,15 +3795,20 @@ class BasicSwap(BaseApp):
|
||||||
if found_tx['height'] != 0 and (bid.xmr_b_lock_tx is None or not bid.xmr_b_lock_tx.chain_height):
|
if found_tx['height'] != 0 and (bid.xmr_b_lock_tx is None or not bid.xmr_b_lock_tx.chain_height):
|
||||||
self.logBidEvent(bid.bid_id, EventLogTypes.LOCK_TX_B_SEEN, '', session)
|
self.logBidEvent(bid.bid_id, EventLogTypes.LOCK_TX_B_SEEN, '', session)
|
||||||
|
|
||||||
if bid.xmr_b_lock_tx is None or bid.xmr_b_lock_tx.chain_height is None:
|
found_txid = bytes.fromhex(found_tx['txid'])
|
||||||
self.log.debug('Found {} lock tx in chain'.format(ci_to.coin_name()))
|
if bid.xmr_b_lock_tx is None or bid.xmr_b_lock_tx.chain_height is None or xmr_swap.b_lock_tx_id != found_txid:
|
||||||
xmr_swap.b_lock_tx_id = bytes.fromhex(found_tx['txid'])
|
self.log.debug('Found lock tx B in {} chain'.format(ci_to.coin_name()))
|
||||||
|
xmr_swap.b_lock_tx_id = found_txid
|
||||||
if bid.xmr_b_lock_tx is None:
|
if bid.xmr_b_lock_tx is None:
|
||||||
bid.xmr_b_lock_tx = SwapTx(
|
bid.xmr_b_lock_tx = SwapTx(
|
||||||
bid_id=bid.bid_id,
|
bid_id=bid.bid_id,
|
||||||
tx_type=TxTypes.XMR_SWAP_B_LOCK,
|
tx_type=TxTypes.XMR_SWAP_B_LOCK,
|
||||||
txid=xmr_swap.b_lock_tx_id,
|
txid=xmr_swap.b_lock_tx_id,
|
||||||
)
|
)
|
||||||
|
if bid.xmr_b_lock_tx.txid != found_txid:
|
||||||
|
self.log.debug('Updating {} lock txid: {}'.format(ci_to.coin_name(), found_txid.hex()))
|
||||||
|
bid.xmr_b_lock_tx.txid = found_txid
|
||||||
|
|
||||||
bid.xmr_b_lock_tx.chain_height = found_tx['height']
|
bid.xmr_b_lock_tx.chain_height = found_tx['height']
|
||||||
bid_changed = True
|
bid_changed = True
|
||||||
return bid_changed
|
return bid_changed
|
||||||
|
@ -3950,7 +3956,7 @@ class BasicSwap(BaseApp):
|
||||||
self.createActionInSession(delay, ActionTypes.RECOVER_XMR_SWAP_LOCK_TX_B, bid_id, session)
|
self.createActionInSession(delay, ActionTypes.RECOVER_XMR_SWAP_LOCK_TX_B, bid_id, session)
|
||||||
session.commit()
|
session.commit()
|
||||||
elif state == BidStates.XMR_SWAP_MSG_SCRIPT_LOCK_SPEND_TX:
|
elif state == BidStates.XMR_SWAP_MSG_SCRIPT_LOCK_SPEND_TX:
|
||||||
if bid.xmr_a_lock_tx is None:
|
if bid.xmr_a_lock_tx is None or bid.xmr_a_lock_tx.txid is None:
|
||||||
return rv
|
return rv
|
||||||
|
|
||||||
# TODO: Timeout waiting for transactions
|
# TODO: Timeout waiting for transactions
|
||||||
|
@ -3961,10 +3967,9 @@ class BasicSwap(BaseApp):
|
||||||
if lock_tx_chain_info is None:
|
if lock_tx_chain_info is None:
|
||||||
return rv
|
return rv
|
||||||
|
|
||||||
if 'txid' in lock_tx_chain_info and lock_tx_chain_info['txid'] != b2h(xmr_swap.a_lock_tx_id):
|
if 'txid' in lock_tx_chain_info and (xmr_swap.a_lock_tx_id is None or lock_tx_chain_info['txid'] != b2h(xmr_swap.a_lock_tx_id)):
|
||||||
# if we find that txid was changed (by funding or otherwise), we need to update it to track correctly
|
# BCH: If we find that txid was changed (by funding or otherwise), we need to update it to track correctly
|
||||||
xmr_swap.a_lock_tx_id = h2b(lock_tx_chain_info['txid'])
|
xmr_swap.a_lock_tx_id = h2b(lock_tx_chain_info['txid'])
|
||||||
xmr_swap.a_lock_tx = h2b(lock_tx_chain_info['txhex'])
|
|
||||||
|
|
||||||
tx = ci_from.loadTx(xmr_swap.a_lock_refund_tx)
|
tx = ci_from.loadTx(xmr_swap.a_lock_refund_tx)
|
||||||
tx.vin[0].prevout.hash = b2i(xmr_swap.a_lock_tx_id)
|
tx.vin[0].prevout.hash = b2i(xmr_swap.a_lock_tx_id)
|
||||||
|
@ -3981,7 +3986,9 @@ 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
|
||||||
|
|
||||||
# update watcher
|
# Update watcher
|
||||||
|
self.removeWatchedOutput(ci_from.coin_type(), bid.bid_id, None)
|
||||||
|
self.removeWatchedOutput(ci_to.coin_type(), bid.bid_id, None)
|
||||||
self.watchXmrSwap(bid, offer, xmr_swap, session)
|
self.watchXmrSwap(bid, offer, xmr_swap, session)
|
||||||
bid_changed = True
|
bid_changed = True
|
||||||
|
|
||||||
|
@ -4321,7 +4328,7 @@ class BasicSwap(BaseApp):
|
||||||
del self.coin_clients[coin_type]['watched_outputs'][i]
|
del self.coin_clients[coin_type]['watched_outputs'][i]
|
||||||
self.log.debug('Removed watched output %s %s %s', Coins(coin_type).name, bid_id.hex(), wo.txid_hex)
|
self.log.debug('Removed watched output %s %s %s', Coins(coin_type).name, bid_id.hex(), wo.txid_hex)
|
||||||
|
|
||||||
def addWatchedScript(self, coin_type, bid_id, script, tx_type, swap_type=None):
|
def addWatchedScript(self, coin_type, bid_id, script: bytes, tx_type, swap_type=None):
|
||||||
self.log.debug('Adding watched script %s bid %s type %s', Coins(coin_type).name, bid_id.hex(), tx_type)
|
self.log.debug('Adding watched script %s bid %s type %s', Coins(coin_type).name, bid_id.hex(), tx_type)
|
||||||
|
|
||||||
watched = self.coin_clients[coin_type]['watched_scripts']
|
watched = self.coin_clients[coin_type]['watched_scripts']
|
||||||
|
@ -4627,7 +4634,16 @@ class BasicSwap(BaseApp):
|
||||||
self.saveBid(watched_script.bid_id, bid)
|
self.saveBid(watched_script.bid_id, bid)
|
||||||
else:
|
else:
|
||||||
self.log.warning('Could not find active bid for found watched script: {}'.format(watched_script.bid_id.hex()))
|
self.log.warning('Could not find active bid for found watched script: {}'.format(watched_script.bid_id.hex()))
|
||||||
|
elif watched_script.tx_type == TxTypes.XMR_SWAP_A_LOCK:
|
||||||
|
self.log.info('Found chain A lock txid {} for bid: {}'.format(txid.hex(), watched_script.bid_id.hex()))
|
||||||
|
bid = self.swaps_in_progress[watched_script.bid_id][0]
|
||||||
|
if bid.xmr_a_lock_tx.txid != txid:
|
||||||
|
self.log.debug('Updating xmr_a_lock_tx from {} to {}'.format(hex_or_none(bid.xmr_a_lock_tx.txid), txid.hex()))
|
||||||
|
bid.xmr_a_lock_tx.txid = txid
|
||||||
|
bid.xmr_b_lock_tx.vout = vout
|
||||||
|
self.saveBid(watched_script.bid_id, bid)
|
||||||
elif watched_script.tx_type == TxTypes.XMR_SWAP_B_LOCK:
|
elif watched_script.tx_type == TxTypes.XMR_SWAP_B_LOCK:
|
||||||
|
self.log.info('Found chain B lock txid {} for bid: {}'.format(txid.hex(), watched_script.bid_id.hex()))
|
||||||
bid = self.swaps_in_progress[watched_script.bid_id][0]
|
bid = self.swaps_in_progress[watched_script.bid_id][0]
|
||||||
bid.xmr_b_lock_tx = SwapTx(
|
bid.xmr_b_lock_tx = SwapTx(
|
||||||
bid_id=watched_script.bid_id,
|
bid_id=watched_script.bid_id,
|
||||||
|
@ -4635,6 +4651,9 @@ class BasicSwap(BaseApp):
|
||||||
txid=txid,
|
txid=txid,
|
||||||
vout=vout,
|
vout=vout,
|
||||||
)
|
)
|
||||||
|
if bid.xmr_b_lock_tx.txid != txid:
|
||||||
|
self.log.debug('Updating xmr_b_lock_tx from {} to {}'.format(hex_or_none(bid.xmr_b_lock_tx.txid), txid.hex()))
|
||||||
|
bid.xmr_b_lock_tx.txid = txid
|
||||||
bid.xmr_b_lock_tx.setState(TxStates.TX_IN_CHAIN)
|
bid.xmr_b_lock_tx.setState(TxStates.TX_IN_CHAIN)
|
||||||
self.saveBid(watched_script.bid_id, bid)
|
self.saveBid(watched_script.bid_id, bid)
|
||||||
else:
|
else:
|
||||||
|
@ -4783,7 +4802,7 @@ class BasicSwap(BaseApp):
|
||||||
if s.tx_type == TxTypes.BCH_MERCY:
|
if s.tx_type == TxTypes.BCH_MERCY:
|
||||||
self.processMercyTx(coin_type, s, bytes.fromhex(tx['txid']), i, tx)
|
self.processMercyTx(coin_type, s, bytes.fromhex(tx['txid']), i, tx)
|
||||||
else:
|
else:
|
||||||
self.processFoundScript(coin_type, s, bytes.fromhex(tx['txid']), i, tx)
|
self.processFoundScript(coin_type, s, bytes.fromhex(tx['txid']), i)
|
||||||
|
|
||||||
for o in c['watched_outputs']:
|
for o in c['watched_outputs']:
|
||||||
for i, inp in enumerate(tx['vin']):
|
for i, inp in enumerate(tx['vin']):
|
||||||
|
@ -5808,12 +5827,20 @@ class BasicSwap(BaseApp):
|
||||||
reverse_bid: bool = self.is_reverse_ads_bid(offer.coin_from, offer.coin_to)
|
reverse_bid: bool = self.is_reverse_ads_bid(offer.coin_from, offer.coin_to)
|
||||||
coin_from = Coins(offer.coin_to if reverse_bid else offer.coin_from)
|
coin_from = Coins(offer.coin_to if reverse_bid else offer.coin_from)
|
||||||
self.setLastHeightCheckedStart(coin_from, bid.chain_a_height_start, session)
|
self.setLastHeightCheckedStart(coin_from, bid.chain_a_height_start, session)
|
||||||
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)
|
|
||||||
|
|
||||||
lock_refund_vout = self.ci(coin_from).getLockRefundTxSwapOutput(xmr_swap)
|
if bid.xmr_a_lock_tx.txid:
|
||||||
self.addWatchedOutput(coin_from, bid.bid_id, xmr_swap.a_lock_refund_tx_id.hex(), lock_refund_vout, TxTypes.XMR_SWAP_A_LOCK_REFUND, SwapTypes.XMR_SWAP)
|
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)
|
||||||
|
|
||||||
|
if xmr_swap.a_lock_refund_tx_id:
|
||||||
|
lock_refund_vout = self.ci(coin_from).getLockRefundTxSwapOutput(xmr_swap)
|
||||||
|
self.addWatchedOutput(coin_from, bid.bid_id, xmr_swap.a_lock_refund_tx_id.hex(), lock_refund_vout, TxTypes.XMR_SWAP_A_LOCK_REFUND, SwapTypes.XMR_SWAP)
|
||||||
bid.in_progress = 1
|
bid.in_progress = 1
|
||||||
|
|
||||||
|
# Watch outputs for chain A lock tx if txid is unknown (BCH)
|
||||||
|
if bid.xmr_a_lock_tx and bid.xmr_a_lock_tx.txid is None:
|
||||||
|
find_script: bytes = self.ci(coin_from).getScriptDest(xmr_swap.a_lock_tx_script)
|
||||||
|
self.addWatchedScript(coin_from, bid.bid_id, find_script, TxTypes.XMR_SWAP_A_LOCK)
|
||||||
|
|
||||||
def sendXmrBidTxnSigsFtoL(self, bid_id, session) -> None:
|
def sendXmrBidTxnSigsFtoL(self, bid_id, session) -> None:
|
||||||
# F -> L: Sending MSG3L
|
# F -> L: Sending MSG3L
|
||||||
self.log.debug('Signing adaptor-sig bid lock txns %s', bid_id.hex())
|
self.log.debug('Signing adaptor-sig bid lock txns %s', bid_id.hex())
|
||||||
|
@ -5859,9 +5886,21 @@ class BasicSwap(BaseApp):
|
||||||
self.addMessageLink(Concepts.BID, bid_id, MessageTypes.XMR_BID_TXN_SIGS_FL, coin_a_lock_tx_sigs_l_msg_id, session=session)
|
self.addMessageLink(Concepts.BID, bid_id, MessageTypes.XMR_BID_TXN_SIGS_FL, coin_a_lock_tx_sigs_l_msg_id, session=session)
|
||||||
self.log.info('Sent XMR_BID_TXN_SIGS_FL %s for bid %s', coin_a_lock_tx_sigs_l_msg_id.hex(), bid_id.hex())
|
self.log.info('Sent XMR_BID_TXN_SIGS_FL %s for bid %s', coin_a_lock_tx_sigs_l_msg_id.hex(), bid_id.hex())
|
||||||
|
|
||||||
a_lock_tx_id = ci_from.getTxid(xmr_swap.a_lock_tx)
|
if ci_from.watch_blocks_for_scripts() and self.isBchXmrSwap(offer):
|
||||||
|
# BCH doesn't have segwit
|
||||||
|
# Lock txid will change when signed.
|
||||||
|
# TODO: BCH Watchonly: Remove when BCH watchonly works.
|
||||||
|
a_lock_tx_id = None
|
||||||
|
else:
|
||||||
|
a_lock_tx_id = ci_from.getTxid(xmr_swap.a_lock_tx)
|
||||||
a_lock_tx_vout = ci_from.getTxOutputPos(xmr_swap.a_lock_tx, xmr_swap.a_lock_tx_script)
|
a_lock_tx_vout = ci_from.getTxOutputPos(xmr_swap.a_lock_tx, xmr_swap.a_lock_tx_script)
|
||||||
self.log.debug('Waiting for lock txn %s to %s chain for bid %s', a_lock_tx_id.hex(), ci_from.coin_name(), bid_id.hex())
|
|
||||||
|
if a_lock_tx_id:
|
||||||
|
self.log.debug('Waiting for lock tx A {} to {} chain for bid {}'.format(a_lock_tx_id.hex(), ci_from.coin_name(), bid_id.hex()))
|
||||||
|
else:
|
||||||
|
find_script: bytes = ci_from.getScriptDest(xmr_swap.a_lock_tx_script)
|
||||||
|
self.log.debug('Waiting for lock tx A with script {} to {} chain for bid {}'.format(find_script.hex(), ci_from.coin_name(), bid_id.hex()))
|
||||||
|
|
||||||
if bid.xmr_a_lock_tx is None:
|
if bid.xmr_a_lock_tx is None:
|
||||||
bid.xmr_a_lock_tx = SwapTx(
|
bid.xmr_a_lock_tx = SwapTx(
|
||||||
bid_id=bid_id,
|
bid_id=bid_id,
|
||||||
|
|
|
@ -9,7 +9,7 @@ from typing import Union
|
||||||
from basicswap.contrib.test_framework.messages import COutPoint, CTransaction, CTxIn
|
from basicswap.contrib.test_framework.messages import COutPoint, CTransaction, CTxIn
|
||||||
from basicswap.util import b2h, b2i, ensure, i2h
|
from basicswap.util import b2h, b2i, ensure, i2h
|
||||||
from basicswap.util.script import decodePushData, decodeScriptNum
|
from basicswap.util.script import decodePushData, decodeScriptNum
|
||||||
from .btc import BTCInterface, ensure_op, find_vout_for_address_from_txobj, findOutput
|
from .btc import BTCInterface, ensure_op, findOutput
|
||||||
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
|
||||||
|
@ -67,6 +67,11 @@ class BCHInterface(BTCInterface):
|
||||||
def xmr_swap_a_lock_spend_tx_vsize() -> int:
|
def xmr_swap_a_lock_spend_tx_vsize() -> int:
|
||||||
return 302
|
return 302
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def watch_blocks_for_scripts() -> bool:
|
||||||
|
# TODO: BCH Watchonly: Remove when BCH watchonly works.
|
||||||
|
return True
|
||||||
|
|
||||||
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
|
||||||
|
@ -116,6 +121,9 @@ class BCHInterface(BTCInterface):
|
||||||
|
|
||||||
return address
|
return address
|
||||||
|
|
||||||
|
def importWatchOnlyAddress(self, address: str, label: str):
|
||||||
|
self.rpc_wallet('importaddress', [address, label, False, True])
|
||||||
|
|
||||||
def createRawFundedTransaction(self, addr_to: str, amount: int, sub_fee: bool = False, lock_unspents: bool = True) -> str:
|
def createRawFundedTransaction(self, addr_to: str, amount: int, sub_fee: bool = False, lock_unspents: bool = True) -> str:
|
||||||
txn = self.rpc('createrawtransaction', [[], {addr_to: self.format_amount(amount)}])
|
txn = self.rpc('createrawtransaction', [[], {addr_to: self.format_amount(amount)}])
|
||||||
|
|
||||||
|
@ -177,57 +185,53 @@ class BCHInterface(BTCInterface):
|
||||||
return {'txid': txid_hex, 'amount': 0, 'height': block_height}
|
return {'txid': txid_hex, 'amount': 0, 'height': block_height}
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def getLockTxHeight(self, txid, dest_address, bid_amount, rescan_from, find_index: bool = False, vout: int = -1):
|
def getLockTxHeight(self, txid: bytes, dest_address: str, bid_amount: int, rescan_from: int, find_index: bool = False, vout: int = -1):
|
||||||
# Add watchonly address and rescan if required
|
|
||||||
txid = None
|
|
||||||
|
|
||||||
# first lookup by dest_address
|
'''
|
||||||
if not self.isAddressMine(dest_address, or_watch_only=False):
|
TODO: BCH Watchonly
|
||||||
self.importWatchOnlyAddress(dest_address, 'bid')
|
Replace with importWatchOnlyAddress when it works again
|
||||||
self._log.info('Imported watch-only addr: {}'.format(dest_address))
|
Currently importing the watchonly address only works if rescanblockchain is run on every iteration
|
||||||
self._log.info('Rescanning {} chain from height: {}'.format(self.coin_name(), rescan_from))
|
'''
|
||||||
self.rpc_wallet('rescanblockchain', [rescan_from])
|
if txid is None:
|
||||||
|
self._log.debug('TODO: getLockTxHeight')
|
||||||
return_txid = True
|
|
||||||
|
|
||||||
txns = self.rpc_wallet('listunspent', [0, 9999999, [dest_address, ]])
|
|
||||||
for tx in txns:
|
|
||||||
if self.make_int(tx['amount']) == bid_amount:
|
|
||||||
txid = bytes.fromhex(tx['txid'])
|
|
||||||
break
|
|
||||||
|
|
||||||
# try to look up in past transactions
|
|
||||||
if not txid:
|
|
||||||
txns = self.rpc_wallet('listtransactions', ["*", 100000, 0, True])
|
|
||||||
for tx in txns:
|
|
||||||
if self.make_int(tx['amount']) == bid_amount and tx['category'] == 'send' and tx.get('address', '_NONE_') == dest_address:
|
|
||||||
txid = bytes.fromhex(tx['txid'])
|
|
||||||
break
|
|
||||||
|
|
||||||
try:
|
|
||||||
# set `include_watchonly` explicitly to `True` to get transactions for watchonly addresses also in BCH
|
|
||||||
tx = self.rpc_wallet('gettransaction', [txid.hex(), True])
|
|
||||||
|
|
||||||
block_height = 0
|
|
||||||
if 'blockhash' in tx:
|
|
||||||
block_header = self.rpc('getblockheader', [tx['blockhash']])
|
|
||||||
block_height = block_header['height']
|
|
||||||
|
|
||||||
rv = {
|
|
||||||
'depth': 0 if 'confirmations' not in tx else tx['confirmations'],
|
|
||||||
'height': block_height}
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
# self._log.debug('getLockTxHeight gettransaction failed: %s, %s', txid.hex(), str(e))
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
if find_index:
|
found_vout = None
|
||||||
tx_obj = self.rpc('decoderawtransaction', [tx['hex']])
|
# Search for txo at vout 0 and 1 if vout is not known
|
||||||
rv['index'] = find_vout_for_address_from_txobj(tx_obj, dest_address)
|
if vout is None:
|
||||||
|
test_range = range(2)
|
||||||
|
else:
|
||||||
|
test_range = (vout, )
|
||||||
|
for try_vout in test_range:
|
||||||
|
try:
|
||||||
|
txout = self.rpc('gettxout', [txid.hex(), try_vout, True])
|
||||||
|
addresses = txout['scriptPubKey']['addresses']
|
||||||
|
if len(addresses) != 1 or addresses[0] != dest_address:
|
||||||
|
continue
|
||||||
|
if self.make_int(txout['value']) != bid_amount:
|
||||||
|
self._log.warning('getLockTxHeight found txout {} with incorrect amount {}'.format(txid.hex(), txout['value']))
|
||||||
|
continue
|
||||||
|
found_vout = try_vout
|
||||||
|
break
|
||||||
|
except Exception as e:
|
||||||
|
# self._log.warning('gettxout {}'.format(e))
|
||||||
|
return None
|
||||||
|
|
||||||
if return_txid:
|
if found_vout is None:
|
||||||
rv['txid'] = txid.hex()
|
return None
|
||||||
rv['txhex'] = tx['hex']
|
|
||||||
|
block_height: int = 0
|
||||||
|
confirmations: int = 0 if 'confirmations' not in txout else txout['confirmations']
|
||||||
|
|
||||||
|
# TODO: Better way?
|
||||||
|
if confirmations > 0:
|
||||||
|
block_height = self.getChainHeight() - confirmations
|
||||||
|
|
||||||
|
rv = {
|
||||||
|
'txid': txid.hex(),
|
||||||
|
'depth': confirmations,
|
||||||
|
'index': found_vout,
|
||||||
|
'height': block_height}
|
||||||
|
|
||||||
return rv
|
return rv
|
||||||
|
|
||||||
|
|
|
@ -1092,14 +1092,18 @@ class BTCInterface(Secp256k1Interface):
|
||||||
return 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, lock_tx_vout=None) -> bytes:
|
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, lock_tx_vout=None) -> bytes:
|
||||||
self._log.info('spendBLockTx %s:\n', chain_b_lock_txid.hex())
|
self._log.info('spendBLockTx: {} {}\n'.format(chain_b_lock_txid.hex(), lock_tx_vout))
|
||||||
wtx = self.rpc_wallet('gettransaction', [chain_b_lock_txid.hex(), ])
|
locked_n = lock_tx_vout
|
||||||
lock_tx = self.loadTx(bytes.fromhex(wtx['hex']))
|
|
||||||
|
|
||||||
Kbs = self.getPubkey(kbs)
|
Kbs = self.getPubkey(kbs)
|
||||||
script_pk = self.getPkDest(Kbs)
|
script_pk = self.getPkDest(Kbs)
|
||||||
locked_n = findOutput(lock_tx, script_pk)
|
|
||||||
|
if locked_n is None:
|
||||||
|
wtx = self.rpc_wallet('gettransaction', [chain_b_lock_txid.hex(), ])
|
||||||
|
lock_tx = self.loadTx(bytes.fromhex(wtx['hex']))
|
||||||
|
locked_n = findOutput(lock_tx, script_pk)
|
||||||
ensure(locked_n is not None, 'Output not found in tx')
|
ensure(locked_n is not None, 'Output not found in tx')
|
||||||
|
|
||||||
pkh_to = self.decodeAddress(address_to)
|
pkh_to = self.decodeAddress(address_to)
|
||||||
|
|
||||||
tx = CTransaction()
|
tx = CTransaction()
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
# Copyright (c) 2018-2023 tecnovert
|
# Copyright (c) 2018-2023 tecnovert
|
||||||
|
# Copyright (c) 2024 The Basicswap developers
|
||||||
# Distributed under the MIT software license, see the accompanying
|
# Distributed under the MIT software license, see the accompanying
|
||||||
# file LICENSE or http://www.opensource.org/licenses/mit-license.php.
|
# file LICENSE or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
@ -215,3 +216,9 @@ def zeroIfNone(value) -> int:
|
||||||
if value is None:
|
if value is None:
|
||||||
return 0
|
return 0
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
|
||||||
|
def hex_or_none(value: bytes) -> str:
|
||||||
|
if value is None:
|
||||||
|
return 'None'
|
||||||
|
return value.hex()
|
||||||
|
|
|
@ -349,6 +349,7 @@ class TestFunctions(BaseTest):
|
||||||
|
|
||||||
amt_swap = ci_from.make_int(random.uniform(0.1, 2.0), r=1)
|
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)
|
rate_swap = ci_to.make_int(random.uniform(0.2, 20.0), r=1)
|
||||||
|
logging.info(f'amount from, rate, amount to: {amt_swap}, {rate_swap}, {amt_swap * rate_swap}')
|
||||||
offer_id = swap_clients[id_offerer].postOffer(
|
offer_id = swap_clients[id_offerer].postOffer(
|
||||||
coin_from, coin_to, amt_swap, rate_swap, amt_swap, SwapTypes.XMR_SWAP,
|
coin_from, coin_to, amt_swap, rate_swap, amt_swap, SwapTypes.XMR_SWAP,
|
||||||
lock_type=TxLockTypes.SEQUENCE_LOCK_BLOCKS, lock_value=lock_value)
|
lock_type=TxLockTypes.SEQUENCE_LOCK_BLOCKS, lock_value=lock_value)
|
||||||
|
|
Loading…
Reference in a new issue