mirror of
https://github.com/basicswap/basicswap.git
synced 2025-01-22 02:24:31 +00:00
Watch for spends to function without txindex.
BTC -> XMR works.
This commit is contained in:
parent
9b4a0dd276
commit
4913ac7a2b
4 changed files with 225 additions and 138 deletions
|
@ -349,6 +349,7 @@ def replaceAddrPrefix(addr, coin_type, chain_name, addr_type='pubkey_address'):
|
||||||
|
|
||||||
|
|
||||||
class WatchedOutput():
|
class WatchedOutput():
|
||||||
|
# Watch for spends
|
||||||
def __init__(self, bid_id, txid_hex, vout, tx_type, swap_type):
|
def __init__(self, bid_id, txid_hex, vout, tx_type, swap_type):
|
||||||
self.bid_id = bid_id
|
self.bid_id = bid_id
|
||||||
self.txid_hex = txid_hex
|
self.txid_hex = txid_hex
|
||||||
|
@ -357,6 +358,15 @@ class WatchedOutput():
|
||||||
self.swap_type = swap_type
|
self.swap_type = swap_type
|
||||||
|
|
||||||
|
|
||||||
|
class WatchedTransaction():
|
||||||
|
# Watch for presense in mempool (getrawtransaction)
|
||||||
|
def __init__(self, bid_id, txid_hex, tx_type, swap_type):
|
||||||
|
self.bid_id = bid_id
|
||||||
|
self.txid_hex = txid_hex
|
||||||
|
self.tx_type = tx_type
|
||||||
|
self.swap_type = swap_type
|
||||||
|
|
||||||
|
|
||||||
class BasicSwap(BaseApp):
|
class BasicSwap(BaseApp):
|
||||||
def __init__(self, fp, data_dir, settings, chain, log_name='BasicSwap'):
|
def __init__(self, fp, data_dir, settings, chain, log_name='BasicSwap'):
|
||||||
super().__init__(fp, data_dir, settings, chain, log_name)
|
super().__init__(fp, data_dir, settings, chain, log_name)
|
||||||
|
@ -583,8 +593,10 @@ class BasicSwap(BaseApp):
|
||||||
self.log.info('%s Core version %d', chainparams[c]['name'].capitalize(), core_version)
|
self.log.info('%s Core version %d', chainparams[c]['name'].capitalize(), core_version)
|
||||||
self.coin_clients[c]['core_version'] = core_version
|
self.coin_clients[c]['core_version'] = core_version
|
||||||
|
|
||||||
# Sanity checks
|
|
||||||
if c == Coins.PART:
|
if c == Coins.PART:
|
||||||
|
self.coin_clients[c]['have_spent_index'] = self.coin_clients[c]['interface'].haveSpentIndex()
|
||||||
|
|
||||||
|
# Sanity checks
|
||||||
if self.callcoinrpc(c, 'getstakinginfo')['enabled'] is not False:
|
if self.callcoinrpc(c, 'getstakinginfo')['enabled'] is not False:
|
||||||
self.log.warning('%s staking is not disabled.', chainparams[c]['name'].capitalize())
|
self.log.warning('%s staking is not disabled.', chainparams[c]['name'].capitalize())
|
||||||
|
|
||||||
|
@ -684,6 +696,7 @@ class BasicSwap(BaseApp):
|
||||||
self.addWatchedOutput(coin_to, bid.bid_id, bid.participate_tx.txid.hex(), bid.participate_tx.vout, BidStates.SWAP_PARTICIPATING)
|
self.addWatchedOutput(coin_to, bid.bid_id, bid.participate_tx.txid.hex(), bid.participate_tx.vout, BidStates.SWAP_PARTICIPATING)
|
||||||
|
|
||||||
# TODO: watch for xmr bid outputs
|
# TODO: watch for xmr bid outputs
|
||||||
|
|
||||||
if self.coin_clients[coin_from]['last_height_checked'] < 1:
|
if self.coin_clients[coin_from]['last_height_checked'] < 1:
|
||||||
if bid.initiate_tx and bid.initiate_tx.chain_height:
|
if bid.initiate_tx and bid.initiate_tx.chain_height:
|
||||||
self.coin_clients[coin_from]['last_height_checked'] = bid.initiate_tx.chain_height
|
self.coin_clients[coin_from]['last_height_checked'] = bid.initiate_tx.chain_height
|
||||||
|
@ -1440,7 +1453,7 @@ class BasicSwap(BaseApp):
|
||||||
msg_buf = XmrBidMessage()
|
msg_buf = XmrBidMessage()
|
||||||
msg_buf.offer_msg_id = offer_id
|
msg_buf.offer_msg_id = offer_id
|
||||||
msg_buf.time_valid = 60 * 10
|
msg_buf.time_valid = 60 * 10
|
||||||
msg_buf.amount = int(amount) # amount of coin_from
|
msg_buf.amount = int(amount) # Amount of coin_from
|
||||||
|
|
||||||
address_out = self.getReceiveAddressFromPool(coin_from, offer_id, TxTypes.XMR_SWAP_A_LOCK)
|
address_out = self.getReceiveAddressFromPool(coin_from, offer_id, TxTypes.XMR_SWAP_A_LOCK)
|
||||||
msg_buf.dest_af = ci_from.decodeAddress(address_out)
|
msg_buf.dest_af = ci_from.decodeAddress(address_out)
|
||||||
|
@ -1608,6 +1621,7 @@ class BasicSwap(BaseApp):
|
||||||
xmr_swap.pkaf,
|
xmr_swap.pkaf,
|
||||||
xmr_offer.a_fee_rate
|
xmr_offer.a_fee_rate
|
||||||
)
|
)
|
||||||
|
xmr_swap.a_lock_refund_tx_id = ci_from.getTxHash(xmr_swap.a_lock_refund_tx)
|
||||||
|
|
||||||
xmr_swap.al_lock_refund_tx_sig = ci_from.signTx(karl, xmr_swap.a_lock_refund_tx, 0, xmr_swap.a_lock_tx_script, bid.amount)
|
xmr_swap.al_lock_refund_tx_sig = ci_from.signTx(karl, xmr_swap.a_lock_refund_tx, 0, xmr_swap.a_lock_tx_script, bid.amount)
|
||||||
v = ci_from.verifyTxSig(xmr_swap.a_lock_refund_tx, xmr_swap.al_lock_refund_tx_sig, xmr_swap.pkarl, 0, xmr_swap.a_lock_tx_script, bid.amount)
|
v = ci_from.verifyTxSig(xmr_swap.a_lock_refund_tx, xmr_swap.al_lock_refund_tx_sig, xmr_swap.pkarl, 0, xmr_swap.a_lock_tx_script, bid.amount)
|
||||||
|
@ -1721,11 +1735,12 @@ class BasicSwap(BaseApp):
|
||||||
session.remove()
|
session.remove()
|
||||||
self.mxDB.release()
|
self.mxDB.release()
|
||||||
|
|
||||||
def setBidError(self, bid_id, bid, error_str):
|
def setBidError(self, bid_id, bid, error_str, save_bid=True):
|
||||||
self.log.error('Bid %s - Error: %s', bid_id.hex(), error_str)
|
self.log.error('Bid %s - Error: %s', bid_id.hex(), error_str)
|
||||||
bid.setState(BidStates.BID_ERROR)
|
bid.setState(BidStates.BID_ERROR)
|
||||||
bid.state_note = 'error msg: ' + error_str
|
bid.state_note = 'error msg: ' + error_str
|
||||||
self.saveBid(bid_id, bid)
|
if save_bid:
|
||||||
|
self.saveBid(bid_id, bid)
|
||||||
|
|
||||||
def createInitiateTxn(self, coin_type, bid_id, bid, initiate_script):
|
def createInitiateTxn(self, coin_type, bid_id, bid, initiate_script):
|
||||||
if self.coin_clients[coin_type]['connection_type'] != 'rpc':
|
if self.coin_clients[coin_type]['connection_type'] != 'rpc':
|
||||||
|
@ -2226,62 +2241,6 @@ class BasicSwap(BaseApp):
|
||||||
xmr_swap = session.query(XmrSwap).filter_by(bid_id=bid.bid_id).first()
|
xmr_swap = session.query(XmrSwap).filter_by(bid_id=bid.bid_id).first()
|
||||||
assert(xmr_swap), 'XMR swap not found: {}.'.format(bid.bid_id.hex())
|
assert(xmr_swap), 'XMR swap not found: {}.'.format(bid.bid_id.hex())
|
||||||
|
|
||||||
if bid.was_sent and not TxTypes.XMR_SWAP_A_LOCK_REFUND_SPEND in bid.txns:
|
|
||||||
found_tx = ci_from.getTransaction(xmr_swap.a_lock_refund_spend_tx_id)
|
|
||||||
if found_tx is not None:
|
|
||||||
self.log.debug('Found coin a lock refund spend tx')
|
|
||||||
xmr_swap.a_lock_refund_spend_tx = found_tx # Replace with fully signed tx
|
|
||||||
|
|
||||||
bid.txns[TxTypes.XMR_SWAP_A_LOCK_REFUND_SPEND] = SwapTx(
|
|
||||||
bid_id=bid_id,
|
|
||||||
tx_type=TxTypes.XMR_SWAP_A_LOCK_REFUND_SPEND,
|
|
||||||
txid=xmr_swap.a_lock_refund_spend_tx_id,
|
|
||||||
)
|
|
||||||
|
|
||||||
if bid.was_sent:
|
|
||||||
if bid.xmr_b_lock_tx is not None:
|
|
||||||
delay = random.randrange(self.min_delay_auto_accept, self.max_delay_auto_accept)
|
|
||||||
self.log.info('Recovering xmr swap chain B lock tx for bid %s in %d seconds', bid_id.hex(), delay)
|
|
||||||
self.createEventInSession(delay, EventTypes.RECOVER_XMR_SWAP_LOCK_TX_B, bid_id, session)
|
|
||||||
else:
|
|
||||||
rv = True # Remove from swaps_in_progress
|
|
||||||
bid.setState(BidStates.XMR_SWAP_FAILED_REFUNDED)
|
|
||||||
|
|
||||||
self.saveBidInSession(bid_id, bid, session, xmr_swap)
|
|
||||||
session.commit()
|
|
||||||
return rv
|
|
||||||
|
|
||||||
|
|
||||||
if TxTypes.XMR_SWAP_A_LOCK_REFUND_SWIPE in bid.txns:
|
|
||||||
swipe_tx = bid.txns[TxTypes.XMR_SWAP_A_LOCK_REFUND_SWIPE]
|
|
||||||
|
|
||||||
# TODO: explorer or getrawtransaction for each block after swap begins
|
|
||||||
found_tx = ci_from.getTransaction(swipe_tx.txid)
|
|
||||||
if found_tx is not None:
|
|
||||||
# TODO: Check depth
|
|
||||||
rv = True
|
|
||||||
bid.setState(BidStates.XMR_SWAP_FAILED_SWIPED)
|
|
||||||
self.saveBidInSession(bid_id, bid, session, xmr_swap)
|
|
||||||
session.commit()
|
|
||||||
return rv
|
|
||||||
|
|
||||||
if bid.was_received and TxTypes.XMR_SWAP_A_LOCK_REFUND_SPEND in bid.txns:
|
|
||||||
refund_spend_tx = bid.txns[TxTypes.XMR_SWAP_A_LOCK_REFUND_SPEND]
|
|
||||||
|
|
||||||
# TODO: explorer or getrawtransaction for each block after swap begins
|
|
||||||
found_tx = ci_from.getTransaction(refund_spend_tx.txid)
|
|
||||||
if found_tx is not None:
|
|
||||||
# TODO: Check depth
|
|
||||||
#if bid.was_received and TxTypes.XMR_SWAP_B_LOCK in bid.txns:
|
|
||||||
if bid.was_sent and bid.xmr_b_lock_tx is not None:
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
rv = True
|
|
||||||
bid.setState(BidStates.XMR_SWAP_FAILED_REFUNDED)
|
|
||||||
self.saveBidInSession(bid_id, bid, session, xmr_swap)
|
|
||||||
session.commit()
|
|
||||||
return rv
|
|
||||||
|
|
||||||
if TxTypes.XMR_SWAP_A_LOCK_REFUND in bid.txns:
|
if TxTypes.XMR_SWAP_A_LOCK_REFUND in bid.txns:
|
||||||
refund_tx = bid.txns[TxTypes.XMR_SWAP_A_LOCK_REFUND]
|
refund_tx = bid.txns[TxTypes.XMR_SWAP_A_LOCK_REFUND]
|
||||||
if bid.was_received:
|
if bid.was_received:
|
||||||
|
@ -2292,20 +2251,21 @@ class BasicSwap(BaseApp):
|
||||||
self.saveBidInSession(bid_id, bid, session, xmr_swap)
|
self.saveBidInSession(bid_id, bid, session, xmr_swap)
|
||||||
session.commit()
|
session.commit()
|
||||||
return rv
|
return rv
|
||||||
try:
|
|
||||||
txid = ci_from.publishTx(xmr_swap.a_lock_refund_spend_tx)
|
|
||||||
|
|
||||||
self.log.info('Submitted coin a lock refund spend tx for bid {}'.format(bid_id.hex()))
|
if TxTypes.XMR_SWAP_A_LOCK_REFUND_SPEND not in bid.txns:
|
||||||
bid.txns[TxTypes.XMR_SWAP_A_LOCK_REFUND_SPEND] = SwapTx(
|
try:
|
||||||
bid_id=bid_id,
|
txid = ci_from.publishTx(xmr_swap.a_lock_refund_spend_tx)
|
||||||
tx_type=TxTypes.XMR_SWAP_A_LOCK_REFUND_SPEND,
|
|
||||||
txid=bytes.fromhex(txid),
|
|
||||||
)
|
|
||||||
self.saveBidInSession(bid_id, bid, session, xmr_swap)
|
|
||||||
session.commit()
|
|
||||||
except Exception as ex:
|
|
||||||
logging.debug('Trying to publish coin a lock refund spend tx: %s', str(ex))
|
|
||||||
|
|
||||||
|
self.log.info('Submitted coin a lock refund spend tx for bid {}'.format(bid_id.hex()))
|
||||||
|
bid.txns[TxTypes.XMR_SWAP_A_LOCK_REFUND_SPEND] = SwapTx(
|
||||||
|
bid_id=bid_id,
|
||||||
|
tx_type=TxTypes.XMR_SWAP_A_LOCK_REFUND_SPEND,
|
||||||
|
txid=bytes.fromhex(txid),
|
||||||
|
)
|
||||||
|
self.saveBidInSession(bid_id, bid, session, xmr_swap)
|
||||||
|
session.commit()
|
||||||
|
except Exception as ex:
|
||||||
|
logging.debug('Trying to publish coin a lock refund spend tx: %s', str(ex))
|
||||||
|
|
||||||
if bid.was_sent:
|
if bid.was_sent:
|
||||||
if xmr_swap.a_lock_refund_swipe_tx is None:
|
if xmr_swap.a_lock_refund_swipe_tx is None:
|
||||||
|
@ -2313,18 +2273,19 @@ class BasicSwap(BaseApp):
|
||||||
self.saveBidInSession(bid_id, bid, session, xmr_swap)
|
self.saveBidInSession(bid_id, bid, session, xmr_swap)
|
||||||
session.commit()
|
session.commit()
|
||||||
|
|
||||||
try:
|
if TxTypes.XMR_SWAP_A_LOCK_REFUND_SWIPE not in bid.txns:
|
||||||
txid = ci_from.publishTx(xmr_swap.a_lock_refund_swipe_tx)
|
try:
|
||||||
self.log.info('Submitted coin a lock refund swipe tx for bid {}'.format(bid_id.hex()))
|
txid = ci_from.publishTx(xmr_swap.a_lock_refund_swipe_tx)
|
||||||
bid.txns[TxTypes.XMR_SWAP_A_LOCK_REFUND_SWIPE] = SwapTx(
|
self.log.info('Submitted coin a lock refund swipe tx for bid {}'.format(bid_id.hex()))
|
||||||
bid_id=bid_id,
|
bid.txns[TxTypes.XMR_SWAP_A_LOCK_REFUND_SWIPE] = SwapTx(
|
||||||
tx_type=TxTypes.XMR_SWAP_A_LOCK_REFUND_SWIPE,
|
bid_id=bid_id,
|
||||||
txid=bytes.fromhex(txid),
|
tx_type=TxTypes.XMR_SWAP_A_LOCK_REFUND_SWIPE,
|
||||||
)
|
txid=bytes.fromhex(txid),
|
||||||
self.saveBidInSession(bid_id, bid, session, xmr_swap)
|
)
|
||||||
session.commit()
|
self.saveBidInSession(bid_id, bid, session, xmr_swap)
|
||||||
except Exception as ex:
|
session.commit()
|
||||||
logging.debug('Trying to publish coin a lock refund swipe tx: %s', str(ex))
|
except Exception as ex:
|
||||||
|
logging.debug('Trying to publish coin a lock refund swipe tx: %s', str(ex))
|
||||||
|
|
||||||
if BidStates(bid.state) == BidStates.XMR_SWAP_NOSCRIPT_TX_RECOVERED:
|
if BidStates(bid.state) == BidStates.XMR_SWAP_NOSCRIPT_TX_RECOVERED:
|
||||||
txid_hex = bid.xmr_b_lock_tx.spend_txid.hex()
|
txid_hex = bid.xmr_b_lock_tx.spend_txid.hex()
|
||||||
|
@ -2365,7 +2326,14 @@ class BasicSwap(BaseApp):
|
||||||
return rv
|
return rv
|
||||||
|
|
||||||
state = BidStates(bid.state)
|
state = BidStates(bid.state)
|
||||||
if state == BidStates.XMR_SWAP_HAVE_SCRIPT_COIN_SPEND_TX:
|
#rv = True # Remove from swaps_in_progress
|
||||||
|
if state == BidStates.SWAP_COMPLETED:
|
||||||
|
rv = True # Remove from swaps_in_progress
|
||||||
|
elif state == BidStates.XMR_SWAP_FAILED_REFUNDED:
|
||||||
|
rv = True # Remove from swaps_in_progress
|
||||||
|
elif state == BidStates.XMR_SWAP_FAILED_SWIPED:
|
||||||
|
rv = True # Remove from swaps_in_progress
|
||||||
|
elif state == BidStates.XMR_SWAP_HAVE_SCRIPT_COIN_SPEND_TX:
|
||||||
if bid.xmr_a_lock_tx is None:
|
if bid.xmr_a_lock_tx is None:
|
||||||
return rv
|
return rv
|
||||||
|
|
||||||
|
@ -2430,23 +2398,7 @@ class BasicSwap(BaseApp):
|
||||||
elif state == BidStates.XMR_SWAP_SECRET_SHARED:
|
elif state == BidStates.XMR_SWAP_SECRET_SHARED:
|
||||||
# Wait for script spend tx to confirm
|
# Wait for script spend tx to confirm
|
||||||
# TODO: Use explorer to get tx / block hash for getrawtransaction
|
# TODO: Use explorer to get tx / block hash for getrawtransaction
|
||||||
found_tx = ci_from.getTransaction(xmr_swap.a_lock_spend_tx_id)
|
pass
|
||||||
if found_tx is not None:
|
|
||||||
xmr_swap.a_lock_spend_tx = found_tx
|
|
||||||
|
|
||||||
#bid.xmr_a_lock_spend_tx.setState(TxStates.TX_CONFIRMED)
|
|
||||||
bid.setState(BidStates.XMR_SWAP_SCRIPT_TX_REDEEMED) # TODO: Wait for confirmation?
|
|
||||||
|
|
||||||
if not bid.was_received:
|
|
||||||
rv = True # Remove from swaps_in_progress
|
|
||||||
bid.setState(BidStates.SWAP_COMPLETED)
|
|
||||||
self.saveBidInSession(bid_id, bid, session, xmr_swap)
|
|
||||||
if bid.was_received:
|
|
||||||
delay = random.randrange(self.min_delay_auto_accept, self.max_delay_auto_accept)
|
|
||||||
self.log.info('Redeeming coin b lock tx for bid %s in %d seconds', bid_id.hex(), delay)
|
|
||||||
self.createEventInSession(delay, EventTypes.REDEEM_XMR_SWAP_LOCK_TX_B, bid_id, session)
|
|
||||||
|
|
||||||
session.commit()
|
|
||||||
elif state == BidStates.XMR_SWAP_SCRIPT_TX_REDEEMED:
|
elif state == BidStates.XMR_SWAP_SCRIPT_TX_REDEEMED:
|
||||||
#txid_hex = bid.txns[TxTypes.XMR_SWAP_B_LOCK].spend_txid.hex()
|
#txid_hex = bid.txns[TxTypes.XMR_SWAP_B_LOCK].spend_txid.hex()
|
||||||
txid_hex = bid.xmr_b_lock_tx.spend_txid.hex()
|
txid_hex = bid.xmr_b_lock_tx.spend_txid.hex()
|
||||||
|
@ -2458,22 +2410,6 @@ class BasicSwap(BaseApp):
|
||||||
bid.setState(BidStates.SWAP_COMPLETED)
|
bid.setState(BidStates.SWAP_COMPLETED)
|
||||||
self.saveBidInSession(bid_id, bid, session, xmr_swap)
|
self.saveBidInSession(bid_id, bid, session, xmr_swap)
|
||||||
session.commit()
|
session.commit()
|
||||||
'''
|
|
||||||
elif state == BidStates.XMR_SWAP_NOSCRIPT_TX_RECOVERED:
|
|
||||||
print('[rm] waiting for coin b lock tx recover tx to confirm')
|
|
||||||
|
|
||||||
txid_hex = bid.xmr_b_lock_tx.spend_txid.hex()
|
|
||||||
|
|
||||||
found_tx = ci_to.findTxnByHash(txid_hex)
|
|
||||||
if found_tx is not None:
|
|
||||||
self.log.info('Found coin b lock recover tx bid %s', bid_id.hex())
|
|
||||||
rv = True # Remove from swaps_in_progress
|
|
||||||
bid.setState(BidStates.XMR_SWAP_FAILED_REFUNDED)
|
|
||||||
print('[rm] saveBidInSession 9.1')
|
|
||||||
self.saveBidInSession(bid_id, bid, session, xmr_swap)
|
|
||||||
session.commit()
|
|
||||||
'''
|
|
||||||
|
|
||||||
|
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
raise ex
|
raise ex
|
||||||
|
@ -2484,7 +2420,6 @@ class BasicSwap(BaseApp):
|
||||||
self.mxDB.release()
|
self.mxDB.release()
|
||||||
return rv
|
return rv
|
||||||
|
|
||||||
|
|
||||||
def checkBidState(self, bid_id, bid, offer):
|
def checkBidState(self, bid_id, bid, offer):
|
||||||
# assert(self.mxDB.locked())
|
# assert(self.mxDB.locked())
|
||||||
# Return True to remove bid from in-progress list
|
# Return True to remove bid from in-progress list
|
||||||
|
@ -2729,8 +2664,122 @@ class BasicSwap(BaseApp):
|
||||||
self.removeWatchedOutput(coin_to, bid_id, bid.participate_tx.txid.hex())
|
self.removeWatchedOutput(coin_to, bid_id, bid.participate_tx.txid.hex())
|
||||||
self.saveBid(bid_id, bid)
|
self.saveBid(bid_id, bid)
|
||||||
|
|
||||||
|
def process_XMR_SWAP_A_LOCK_tx_spend(self, bid_id, spend_txid_hex, spend_txn):
|
||||||
|
self.log.debug('Detected spend of XMR swap coin a lock tx for bid %s', bid_id.hex())
|
||||||
|
self.mxDB.acquire()
|
||||||
|
try:
|
||||||
|
session = scoped_session(self.session_factory)
|
||||||
|
bid, xmr_swap = self.getXmrBid(bid_id)
|
||||||
|
assert(bid), 'Bid not found: {}.'.format(bid_id.hex())
|
||||||
|
assert(xmr_swap), 'XMR swap not found: {}.'.format(bid_id.hex())
|
||||||
|
|
||||||
|
offer, xmr_offer = self.getXmrOffer(bid.offer_id, sent=False)
|
||||||
|
assert(offer), 'Offer not found: {}.'.format(bid.offer_id.hex())
|
||||||
|
assert(xmr_offer), 'XMR offer not found: {}.'.format(bid.offer_id.hex())
|
||||||
|
coin_from = Coins(offer.coin_from)
|
||||||
|
coin_to = Coins(offer.coin_to)
|
||||||
|
|
||||||
|
state = BidStates(bid.state)
|
||||||
|
spending_txid = bytes.fromhex(spend_txid_hex)
|
||||||
|
|
||||||
|
if spending_txid == xmr_swap.a_lock_spend_tx_id:
|
||||||
|
if state == BidStates.XMR_SWAP_SECRET_SHARED:
|
||||||
|
xmr_swap.a_lock_spend_tx = bytes.fromhex(spend_txn['hex'])
|
||||||
|
bid.setState(BidStates.XMR_SWAP_SCRIPT_TX_REDEEMED) # TODO: Wait for confirmation?
|
||||||
|
|
||||||
|
if not bid.was_received:
|
||||||
|
#rv = True # Remove from swaps_in_progress
|
||||||
|
bid.setState(BidStates.SWAP_COMPLETED)
|
||||||
|
self.saveBidInSession(bid_id, bid, session, xmr_swap)
|
||||||
|
if bid.was_received:
|
||||||
|
delay = random.randrange(self.min_delay_auto_accept, self.max_delay_auto_accept)
|
||||||
|
self.log.info('Redeeming coin b lock tx for bid %s in %d seconds', bid_id.hex(), delay)
|
||||||
|
self.createEventInSession(delay, EventTypes.REDEEM_XMR_SWAP_LOCK_TX_B, bid_id, session)
|
||||||
|
else:
|
||||||
|
# Could already be processed if spend was detected in the mempool
|
||||||
|
self.log.warning('Coin a lock tx spend ignored due to bid state for bid {}'.format(bid_id.hex()))
|
||||||
|
|
||||||
|
elif spending_txid == xmr_swap.a_lock_refund_tx_id:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
self.setBidError(bid.bid_id, bid, 'Unexpected txn spent coin a lock tx: {}'.format(spend_txid_hex), save_bid=False)
|
||||||
|
|
||||||
|
self.saveBidInSession(bid_id, bid, session, xmr_swap)
|
||||||
|
# Update copy of bid in swaps_in_progress
|
||||||
|
self.swaps_in_progress[bid_id] = (bid, offer)
|
||||||
|
session.commit()
|
||||||
|
except Exception as ex:
|
||||||
|
self.log.error('process_XMR_SWAP_A_LOCK_tx_spend %s', str(ex))
|
||||||
|
if self.debug:
|
||||||
|
traceback.print_exc()
|
||||||
|
finally:
|
||||||
|
session.close()
|
||||||
|
session.remove()
|
||||||
|
self.mxDB.release()
|
||||||
|
|
||||||
|
def process_XMR_SWAP_A_LOCK_REFUND_tx_spend(self, bid_id, spend_txid_hex, spend_txn):
|
||||||
|
self.log.debug('Detected spend of XMR swap coin a lock refund tx for bid %s', bid_id.hex())
|
||||||
|
self.mxDB.acquire()
|
||||||
|
try:
|
||||||
|
session = scoped_session(self.session_factory)
|
||||||
|
bid, xmr_swap = self.getXmrBid(bid_id)
|
||||||
|
assert(bid), 'Bid not found: {}.'.format(bid_id.hex())
|
||||||
|
assert(xmr_swap), 'XMR swap not found: {}.'.format(bid_id.hex())
|
||||||
|
|
||||||
|
offer, xmr_offer = self.getXmrOffer(bid.offer_id, sent=False)
|
||||||
|
assert(offer), 'Offer not found: {}.'.format(bid.offer_id.hex())
|
||||||
|
assert(xmr_offer), 'XMR offer not found: {}.'.format(bid.offer_id.hex())
|
||||||
|
coin_from = Coins(offer.coin_from)
|
||||||
|
coin_to = Coins(offer.coin_to)
|
||||||
|
|
||||||
|
state = BidStates(bid.state)
|
||||||
|
spending_txid = bytes.fromhex(spend_txid_hex)
|
||||||
|
|
||||||
|
if spending_txid == xmr_swap.a_lock_refund_spend_tx_id:
|
||||||
|
self.log.info('Found coin a lock refund spend tx, bid {}'.format(bid_id.hex()))
|
||||||
|
|
||||||
|
if bid.was_sent:
|
||||||
|
xmr_swap.a_lock_refund_spend_tx = bytes.fromhex(spend_txn['hex']) # Replace with fully signed tx
|
||||||
|
if TxTypes.XMR_SWAP_A_LOCK_REFUND_SPEND not in bid.txns:
|
||||||
|
bid.txns[TxTypes.XMR_SWAP_A_LOCK_REFUND_SPEND] = SwapTx(
|
||||||
|
bid_id=bid_id,
|
||||||
|
tx_type=TxTypes.XMR_SWAP_A_LOCK_REFUND_SPEND,
|
||||||
|
txid=xmr_swap.a_lock_refund_spend_tx_id,
|
||||||
|
)
|
||||||
|
if bid.xmr_b_lock_tx is not None:
|
||||||
|
delay = random.randrange(self.min_delay_auto_accept, self.max_delay_auto_accept)
|
||||||
|
self.log.info('Recovering xmr swap chain B lock tx for bid %s in %d seconds', bid_id.hex(), delay)
|
||||||
|
self.createEventInSession(delay, EventTypes.RECOVER_XMR_SWAP_LOCK_TX_B, bid_id, session)
|
||||||
|
else:
|
||||||
|
#rv = True # Remove from swaps_in_progress
|
||||||
|
bid.setState(BidStates.XMR_SWAP_FAILED_REFUNDED)
|
||||||
|
|
||||||
|
if bid.was_received:
|
||||||
|
if not bid.was_sent:
|
||||||
|
bid.setState(BidStates.XMR_SWAP_FAILED_REFUNDED)
|
||||||
|
|
||||||
|
else:
|
||||||
|
self.log.info('Coin a lock refund spent by unknown tx, bid {}'.format(bid_id.hex()))
|
||||||
|
|
||||||
|
self.saveBidInSession(bid_id, bid, session, xmr_swap)
|
||||||
|
# Update copy of bid in swaps_in_progress
|
||||||
|
self.swaps_in_progress[bid_id] = (bid, offer)
|
||||||
|
session.commit()
|
||||||
|
except Exception as ex:
|
||||||
|
self.log.error('process_XMR_SWAP_A_LOCK_REFUND_tx_spend %s', str(ex))
|
||||||
|
if self.debug:
|
||||||
|
traceback.print_exc()
|
||||||
|
finally:
|
||||||
|
session.close()
|
||||||
|
session.remove()
|
||||||
|
self.mxDB.release()
|
||||||
|
|
||||||
def processSpentOutput(self, coin_type, watched_output, spend_txid_hex, spend_n, spend_txn):
|
def processSpentOutput(self, coin_type, watched_output, spend_txid_hex, spend_n, spend_txn):
|
||||||
if watched_output.swap_type == SwapTypes.XMR_SWAP:
|
if watched_output.swap_type == SwapTypes.XMR_SWAP:
|
||||||
|
if watched_output.tx_type == TxTypes.XMR_SWAP_A_LOCK:
|
||||||
|
self.process_XMR_SWAP_A_LOCK_tx_spend(watched_output.bid_id, spend_txid_hex, spend_txn)
|
||||||
|
elif watched_output.tx_type == TxTypes.XMR_SWAP_A_LOCK_REFUND:
|
||||||
|
self.process_XMR_SWAP_A_LOCK_REFUND_tx_spend(watched_output.bid_id, spend_txid_hex, spend_txn)
|
||||||
|
|
||||||
self.removeWatchedOutput(coin_type, watched_output.bid_id, watched_output.txid_hex)
|
self.removeWatchedOutput(coin_type, watched_output.bid_id, watched_output.txid_hex)
|
||||||
return
|
return
|
||||||
|
@ -2744,7 +2793,7 @@ class BasicSwap(BaseApp):
|
||||||
# assert(self.mxDB.locked()) self.log.debug('checkForSpends %s', coin_type)
|
# assert(self.mxDB.locked()) self.log.debug('checkForSpends %s', coin_type)
|
||||||
self.log.debug('checkForSpends %s', coin_type)
|
self.log.debug('checkForSpends %s', coin_type)
|
||||||
|
|
||||||
if coin_type == Coins.PART:
|
if coin_type == Coins.PART and self.coin_clients[coin_type]['have_spent_index']:
|
||||||
# TODO: batch getspentinfo
|
# TODO: batch getspentinfo
|
||||||
for o in c['watched_outputs']:
|
for o in c['watched_outputs']:
|
||||||
found_spend = None
|
found_spend = None
|
||||||
|
@ -3322,7 +3371,8 @@ class BasicSwap(BaseApp):
|
||||||
xmr_swap.a_lock_refund_spend_tx_id = ci_from.getTxHash(xmr_swap.a_lock_refund_spend_tx)
|
xmr_swap.a_lock_refund_spend_tx_id = ci_from.getTxHash(xmr_swap.a_lock_refund_spend_tx)
|
||||||
xmr_swap.al_lock_refund_tx_sig = msg_data.al_lock_refund_tx_sig
|
xmr_swap.al_lock_refund_tx_sig = msg_data.al_lock_refund_tx_sig
|
||||||
|
|
||||||
check_a_lock_tx_inputs = True
|
# TODO: check_a_lock_tx_inputs without txindex
|
||||||
|
check_a_lock_tx_inputs = False
|
||||||
xmr_swap.a_lock_tx_id, xmr_swap.a_lock_tx_vout = ci_from.verifyLockTx(
|
xmr_swap.a_lock_tx_id, xmr_swap.a_lock_tx_vout = ci_from.verifyLockTx(
|
||||||
xmr_swap.a_lock_tx, xmr_swap.a_lock_tx_script,
|
xmr_swap.a_lock_tx, xmr_swap.a_lock_tx_script,
|
||||||
bid.amount,
|
bid.amount,
|
||||||
|
@ -3334,9 +3384,7 @@ class BasicSwap(BaseApp):
|
||||||
)
|
)
|
||||||
a_lock_tx_dest = ci_from.getScriptDest(xmr_swap.a_lock_tx_script)
|
a_lock_tx_dest = ci_from.getScriptDest(xmr_swap.a_lock_tx_script)
|
||||||
|
|
||||||
self.addWatchedOutput(coin_from, bid.bid_id, xmr_swap.a_lock_tx_id, xmr_swap.a_lock_tx_vout, TxTypes.XMR_SWAP_A_LOCK, SwapTypes.XMR_SWAP)
|
xmr_swap.a_lock_refund_tx_id, xmr_swap.a_swap_refund_value = ci_from.verifyLockRefundTx(
|
||||||
|
|
||||||
lock_refund_tx_id, xmr_swap.a_swap_refund_value = ci_from.verifyLockRefundTx(
|
|
||||||
xmr_swap.a_lock_refund_tx, xmr_swap.a_lock_refund_tx_script,
|
xmr_swap.a_lock_refund_tx, xmr_swap.a_lock_refund_tx_script,
|
||||||
xmr_swap.a_lock_tx_id, xmr_swap.a_lock_tx_vout, xmr_offer.lock_time_1, xmr_swap.a_lock_tx_script,
|
xmr_swap.a_lock_tx_id, xmr_swap.a_lock_tx_vout, xmr_offer.lock_time_1, xmr_swap.a_lock_tx_script,
|
||||||
xmr_swap.pkarl, xmr_swap.pkarf,
|
xmr_swap.pkarl, xmr_swap.pkarf,
|
||||||
|
@ -3347,7 +3395,7 @@ class BasicSwap(BaseApp):
|
||||||
|
|
||||||
ci_from.verifyLockRefundSpendTx(
|
ci_from.verifyLockRefundSpendTx(
|
||||||
xmr_swap.a_lock_refund_spend_tx,
|
xmr_swap.a_lock_refund_spend_tx,
|
||||||
lock_refund_tx_id, xmr_swap.a_lock_refund_tx_script,
|
xmr_swap.a_lock_refund_tx_id, xmr_swap.a_lock_refund_tx_script,
|
||||||
xmr_swap.pkal,
|
xmr_swap.pkal,
|
||||||
xmr_swap.a_swap_refund_value, xmr_offer.a_fee_rate
|
xmr_swap.a_swap_refund_value, xmr_offer.a_fee_rate
|
||||||
)
|
)
|
||||||
|
@ -3362,6 +3410,12 @@ class BasicSwap(BaseApp):
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
self.setBidError(bid.bid_id, bid, str(ex))
|
self.setBidError(bid.bid_id, bid, str(ex))
|
||||||
|
|
||||||
|
def watchXmrSwap(self, bid, offer, xmr_swap):
|
||||||
|
self.log.debug('XMR swap in progress, bid %s', bid.bid_id.hex())
|
||||||
|
self.swaps_in_progress[bid.bid_id] = (bid, offer)
|
||||||
|
self.addWatchedOutput(Coins(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)
|
||||||
|
self.addWatchedOutput(Coins(offer.coin_from), bid.bid_id, xmr_swap.a_lock_refund_tx_id.hex(), 0, TxTypes.XMR_SWAP_A_LOCK_REFUND, SwapTypes.XMR_SWAP)
|
||||||
|
|
||||||
def sendXmrBidTxnSigsFtoL(self, bid_id, session):
|
def sendXmrBidTxnSigsFtoL(self, bid_id, session):
|
||||||
# F -> L: Sending MSG3L
|
# F -> L: Sending MSG3L
|
||||||
self.log.debug('Signing xmr bid lock txns %s', bid_id.hex())
|
self.log.debug('Signing xmr bid lock txns %s', bid_id.hex())
|
||||||
|
@ -3404,17 +3458,20 @@ class BasicSwap(BaseApp):
|
||||||
self.log.info('Sent XMR_BID_TXN_SIGS_FL %s', xmr_swap.coin_a_lock_tx_sigs_l_msg_id.hex())
|
self.log.info('Sent XMR_BID_TXN_SIGS_FL %s', xmr_swap.coin_a_lock_tx_sigs_l_msg_id.hex())
|
||||||
|
|
||||||
a_lock_tx_id = ci_from.getTxHash(xmr_swap.a_lock_tx)
|
a_lock_tx_id = ci_from.getTxHash(xmr_swap.a_lock_tx)
|
||||||
|
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(), chainparams[coin_from]['name'], bid_id.hex())
|
self.log.debug('Waiting for lock txn %s to %s chain for bid %s', a_lock_tx_id.hex(), chainparams[coin_from]['name'], bid_id.hex())
|
||||||
bid.xmr_a_lock_tx = SwapTx(
|
bid.xmr_a_lock_tx = SwapTx(
|
||||||
bid_id=bid_id,
|
bid_id=bid_id,
|
||||||
tx_type=TxTypes.XMR_SWAP_A_LOCK,
|
tx_type=TxTypes.XMR_SWAP_A_LOCK,
|
||||||
txid=a_lock_tx_id,
|
txid=a_lock_tx_id,
|
||||||
|
vout=a_lock_tx_vout,
|
||||||
)
|
)
|
||||||
bid.xmr_a_lock_tx.setState(TxStates.TX_NONE)
|
bid.xmr_a_lock_tx.setState(TxStates.TX_NONE)
|
||||||
|
|
||||||
bid.setState(BidStates.BID_ACCEPTED) # XMR
|
bid.setState(BidStates.BID_ACCEPTED) # XMR
|
||||||
self.saveBidInSession(bid_id, bid, session, xmr_swap)
|
self.saveBidInSession(bid_id, bid, session, xmr_swap)
|
||||||
self.swaps_in_progress[bid_id] = (bid, offer)
|
|
||||||
|
self.watchXmrSwap(bid, offer, xmr_swap)
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
if self.debug:
|
if self.debug:
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
|
@ -3465,17 +3522,22 @@ class BasicSwap(BaseApp):
|
||||||
lock_tx_signed = ci_from.signTxWithWallet(xmr_swap.a_lock_tx)
|
lock_tx_signed = ci_from.signTxWithWallet(xmr_swap.a_lock_tx)
|
||||||
txid_hex = ci_from.publishTx(lock_tx_signed)
|
txid_hex = ci_from.publishTx(lock_tx_signed)
|
||||||
|
|
||||||
|
vout_pos = ci_from.getTxOutputPos(xmr_swap.a_lock_tx, xmr_swap.a_lock_tx_script)
|
||||||
|
|
||||||
self.log.debug('Submitted lock txn %s to %s chain for bid %s', txid_hex, chainparams[coin_from]['name'], bid_id.hex())
|
self.log.debug('Submitted lock txn %s to %s chain for bid %s', txid_hex, chainparams[coin_from]['name'], bid_id.hex())
|
||||||
|
|
||||||
bid.xmr_a_lock_tx = SwapTx(
|
bid.xmr_a_lock_tx = SwapTx(
|
||||||
bid_id=bid_id,
|
bid_id=bid_id,
|
||||||
tx_type=TxTypes.XMR_SWAP_A_LOCK,
|
tx_type=TxTypes.XMR_SWAP_A_LOCK,
|
||||||
txid=bytes.fromhex(txid_hex),
|
txid=bytes.fromhex(txid_hex),
|
||||||
|
vout=vout_pos,
|
||||||
)
|
)
|
||||||
bid.xmr_a_lock_tx.setState(TxStates.TX_SENT)
|
bid.xmr_a_lock_tx.setState(TxStates.TX_SENT)
|
||||||
|
|
||||||
bid.setState(BidStates.XMR_SWAP_HAVE_SCRIPT_COIN_SPEND_TX)
|
bid.setState(BidStates.XMR_SWAP_HAVE_SCRIPT_COIN_SPEND_TX)
|
||||||
self.saveBidInSession(bid_id, bid, session, xmr_swap)
|
self.saveBidInSession(bid_id, bid, session, xmr_swap)
|
||||||
self.swaps_in_progress[bid_id] = (bid, offer)
|
|
||||||
|
self.watchXmrSwap(bid, offer, xmr_swap)
|
||||||
|
|
||||||
def sendXmrBidCoinBLockTx(self, bid_id, session):
|
def sendXmrBidCoinBLockTx(self, bid_id, session):
|
||||||
# Follower sending coin B lock tx
|
# Follower sending coin B lock tx
|
||||||
|
|
|
@ -154,8 +154,7 @@ class BTCInterface(CoinInterface):
|
||||||
def decodeAddress(self, address):
|
def decodeAddress(self, address):
|
||||||
bech32_prefix = chainparams[self.coin_type()][self._network]['hrp']
|
bech32_prefix = chainparams[self.coin_type()][self._network]['hrp']
|
||||||
if address.startswith(bech32_prefix):
|
if address.startswith(bech32_prefix):
|
||||||
ignr, pkhash = segwit_addr.decode(bech32_prefix, address)
|
return bytes(segwit_addr.decode(bech32_prefix, address)[1])
|
||||||
return pkhash
|
|
||||||
return decodeAddress(address)[1:]
|
return decodeAddress(address)[1:]
|
||||||
|
|
||||||
def getNewSecretKey(self):
|
def getNewSecretKey(self):
|
||||||
|
@ -734,6 +733,12 @@ class BTCInterface(CoinInterface):
|
||||||
tx.rehash()
|
tx.rehash()
|
||||||
return i2b(tx.sha256)
|
return i2b(tx.sha256)
|
||||||
|
|
||||||
|
def getTxOutputPos(self, tx, script):
|
||||||
|
if isinstance(tx, bytes):
|
||||||
|
tx = self.loadTx(tx)
|
||||||
|
script_pk = CScript([OP_0, hashlib.sha256(script).digest()])
|
||||||
|
return findOutput(tx, script_pk)
|
||||||
|
|
||||||
def getPubkeyHash(self, K):
|
def getPubkeyHash(self, K):
|
||||||
return hash160(self.encodePubkey(K))
|
return hash160(self.encodePubkey(K))
|
||||||
|
|
||||||
|
@ -753,6 +758,13 @@ class BTCInterface(CoinInterface):
|
||||||
# TODO: filter errors
|
# TODO: filter errors
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def getWalletTransaction(self, txid):
|
||||||
|
try:
|
||||||
|
return bytes.fromhex(self.rpc_callback('gettransaction', [txid.hex()]))
|
||||||
|
except Exception as ex:
|
||||||
|
# TODO: filter errors
|
||||||
|
return None
|
||||||
|
|
||||||
def setTxSignature(self, tx_bytes, stack):
|
def setTxSignature(self, tx_bytes, stack):
|
||||||
tx = self.loadTx(tx_bytes)
|
tx = self.loadTx(tx_bytes)
|
||||||
tx.wit.vtxinwit.clear()
|
tx.wit.vtxinwit.clear()
|
||||||
|
@ -833,8 +845,12 @@ class BTCInterface(CoinInterface):
|
||||||
def getOutput(self, txid, dest_script, expect_value):
|
def getOutput(self, txid, dest_script, expect_value):
|
||||||
# TODO: Use getrawtransaction if txindex is active
|
# TODO: Use getrawtransaction if txindex is active
|
||||||
utxos = self.rpc_callback('scantxoutset', ['start', ['raw({})'.format(dest_script.hex())]])
|
utxos = self.rpc_callback('scantxoutset', ['start', ['raw({})'.format(dest_script.hex())]])
|
||||||
print('utxos', utxos)
|
'''
|
||||||
|
bech32_prefix = chainparams[self.coin_type()][self._network]['hrp']
|
||||||
|
address = segwit_addr.encode(bech32_prefix, 0, list(dest_script[2:]))
|
||||||
|
print('[rm] address', address)
|
||||||
|
utxos = self.rpc_callback('scantxoutset', ['start', ['addr({})'.format(address)]])
|
||||||
|
'''
|
||||||
chain_height = utxos['height']
|
chain_height = utxos['height']
|
||||||
rv = []
|
rv = []
|
||||||
for utxo in utxos['unspents']:
|
for utxo in utxos['unspents']:
|
||||||
|
|
|
@ -35,3 +35,8 @@ class PARTInterface(BTCInterface):
|
||||||
|
|
||||||
def getNewAddress(self, use_segwit):
|
def getNewAddress(self, use_segwit):
|
||||||
return self.rpc_callback('getnewaddress', ['swap_receive'])
|
return self.rpc_callback('getnewaddress', ['swap_receive'])
|
||||||
|
|
||||||
|
def haveSpentIndex(self):
|
||||||
|
version = self.getDaemonVersion()
|
||||||
|
index_info = self.rpc_callback('getinsightinfo' if int(str(version)[:2]) > 19 else 'getindexinfo')
|
||||||
|
return index_info['spentindex']
|
||||||
|
|
|
@ -71,9 +71,9 @@ BASE_PORT = 14792
|
||||||
BASE_RPC_PORT = 19792
|
BASE_RPC_PORT = 19792
|
||||||
BASE_ZMQ_PORT = 20792
|
BASE_ZMQ_PORT = 20792
|
||||||
|
|
||||||
BTC_BASE_PORT = 114792
|
BTC_BASE_PORT = 31792
|
||||||
BTC_BASE_RPC_PORT = 119792
|
BTC_BASE_RPC_PORT = 32792
|
||||||
BTC_BASE_ZMQ_PORT = 120792
|
BTC_BASE_ZMQ_PORT = 33792
|
||||||
|
|
||||||
XMR_BASE_P2P_PORT = 17792
|
XMR_BASE_P2P_PORT = 17792
|
||||||
XMR_BASE_RPC_PORT = 21792
|
XMR_BASE_RPC_PORT = 21792
|
||||||
|
@ -512,9 +512,11 @@ class Test(unittest.TestCase):
|
||||||
def callxmrnodewallet(self, node_id, method, params=None):
|
def callxmrnodewallet(self, node_id, method, params=None):
|
||||||
return callrpc_xmr(XMR_BASE_WALLET_RPC_PORT + node_id, self.xmr_wallet_auth[node_id], method, params)
|
return callrpc_xmr(XMR_BASE_WALLET_RPC_PORT + node_id, self.xmr_wallet_auth[node_id], method, params)
|
||||||
|
|
||||||
def wait_for_offer(self, swap_client, offer_id):
|
def wait_for_offer(self, swap_client, offer_id, wait_for=20):
|
||||||
logging.info('wait_for_offer %s', offer_id.hex())
|
logging.info('wait_for_offer %s', offer_id.hex())
|
||||||
for i in range(20):
|
for i in range(wait_for):
|
||||||
|
if stop_test:
|
||||||
|
raise ValueError('Test stopped.')
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
offers = swap_client.listOffers()
|
offers = swap_client.listOffers()
|
||||||
for offer in offers:
|
for offer in offers:
|
||||||
|
@ -525,6 +527,8 @@ class Test(unittest.TestCase):
|
||||||
def wait_for_bid(self, swap_client, bid_id, state=None, sent=False, wait_for=20):
|
def wait_for_bid(self, swap_client, bid_id, state=None, sent=False, wait_for=20):
|
||||||
logging.info('wait_for_bid %s', bid_id.hex())
|
logging.info('wait_for_bid %s', bid_id.hex())
|
||||||
for i in range(wait_for):
|
for i in range(wait_for):
|
||||||
|
if stop_test:
|
||||||
|
raise ValueError('Test stopped.')
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
bids = swap_client.listBids(sent=sent)
|
bids = swap_client.listBids(sent=sent)
|
||||||
for bid in bids:
|
for bid in bids:
|
||||||
|
@ -624,7 +628,7 @@ class Test(unittest.TestCase):
|
||||||
swap_clients[0].acceptXmrBid(bid_id)
|
swap_clients[0].acceptXmrBid(bid_id)
|
||||||
|
|
||||||
self.wait_for_bid(swap_clients[0], bid_id, BidStates.BID_ABANDONED, wait_for=180)
|
self.wait_for_bid(swap_clients[0], bid_id, BidStates.BID_ABANDONED, wait_for=180)
|
||||||
self.wait_for_bid(swap_clients[1], bid_id, BidStates.XMR_SWAP_FAILED_SWIPED, sent=True)
|
self.wait_for_bid(swap_clients[1], bid_id, BidStates.XMR_SWAP_FAILED_SWIPED, wait_for=80, sent=True)
|
||||||
|
|
||||||
js_w0_after = json.loads(urlopen('http://localhost:1800/json/wallets').read())
|
js_w0_after = json.loads(urlopen('http://localhost:1800/json/wallets').read())
|
||||||
|
|
||||||
|
@ -655,7 +659,7 @@ class Test(unittest.TestCase):
|
||||||
def test_05_btc_xmr(self):
|
def test_05_btc_xmr(self):
|
||||||
logging.info('---------- Test BTC to XMR')
|
logging.info('---------- Test BTC to XMR')
|
||||||
swap_clients = self.swap_clients
|
swap_clients = self.swap_clients
|
||||||
offer_id = swap_clients[0].postOffer(Coins.BTC, Coins.XMR, 10 * COIN, 100 * XMR_COIN, 100 * COIN, SwapTypes.XMR_SWAP)
|
offer_id = swap_clients[0].postOffer(Coins.BTC, Coins.XMR, 10 * COIN, 100 * XMR_COIN, 10 * COIN, SwapTypes.XMR_SWAP)
|
||||||
self.wait_for_offer(swap_clients[1], offer_id)
|
self.wait_for_offer(swap_clients[1], offer_id)
|
||||||
offers = swap_clients[1].listOffers(filters={'offer_id': offer_id})
|
offers = swap_clients[1].listOffers(filters={'offer_id': offer_id})
|
||||||
offer = offers[0]
|
offer = offers[0]
|
||||||
|
|
Loading…
Reference in a new issue