diff --git a/basicswap/basicswap.py b/basicswap/basicswap.py index ca1d2b6..fcfc08f 100644 --- a/basicswap/basicswap.py +++ b/basicswap/basicswap.py @@ -3199,18 +3199,14 @@ class BasicSwap(BaseApp): if state > BidStates.BID_ACCEPTED: # Wait for spend of all known swap txns - if (bid.getITxState() is None or bid.getITxState() >= TxStates.TX_REDEEMED) and \ - (bid.getPTxState() is None or bid.getPTxState() >= TxStates.TX_REDEEMED): + itx_state = bid.getITxState() + ptx_state = bid.getPTxState() + if (itx_state is None or itx_state >= TxStates.TX_REDEEMED) and \ + (ptx_state is None or ptx_state >= TxStates.TX_REDEEMED): self.log.info('Swap completed for bid %s', bid_id.hex()) - if bid.getITxState() == TxStates.TX_REDEEMED: - self.returnAddressToPool(bid_id, TxTypes.ITX_REFUND) - else: - self.returnAddressToPool(bid_id, TxTypes.ITX_REDEEM) - if bid.getPTxState() == TxStates.TX_REDEEMED: - self.returnAddressToPool(bid_id, TxTypes.PTX_REFUND) - else: - self.returnAddressToPool(bid_id, TxTypes.PTX_REDEEM) + self.returnAddressToPool(bid_id, TxTypes.ITX_REFUND if itx_state == TxStates.TX_REDEEMED else TxTypes.PTX_REDEEM) + self.returnAddressToPool(bid_id, TxTypes.ITX_REFUND if ptx_state == TxStates.TX_REDEEMED else TxTypes.PTX_REDEEM) bid.setState(BidStates.SWAP_COMPLETED) self.saveBid(bid_id, bid) @@ -3219,8 +3215,11 @@ class BasicSwap(BaseApp): if save_bid: self.saveBid(bid_id, bid) + if bid.debug_ind == DebugTypes.SKIP_LOCK_TX_REFUND: + return False # Bid is still active + # Try refund, keep trying until sent tx is spent - if (bid.getITxState() == TxStates.TX_SENT or bid.getITxState() == TxStates.TX_CONFIRMED) \ + if bid.getITxState() in (TxStates.TX_SENT, TxStates.TX_CONFIRMED) \ and bid.initiate_txn_refund is not None: try: txid = ci_from.publishTx(bid.initiate_txn_refund) @@ -3230,7 +3229,7 @@ class BasicSwap(BaseApp): if 'non-BIP68-final' not in str(ex) and 'non-final' not in str(ex): self.log.warning('Error trying to submit initiate refund txn: %s', str(ex)) - if (bid.getPTxState() == TxStates.TX_SENT or bid.getPTxState() == TxStates.TX_CONFIRMED) \ + if bid.getPTxState() in (TxStates.TX_SENT, TxStates.TX_CONFIRMED) \ and bid.participate_txn_refund is not None: try: txid = ci_to.publishTx(bid.participate_txn_refund) @@ -5790,6 +5789,12 @@ class BasicSwap(BaseApp): self.log.debug('Bid %s Setting debug flag: %s', bid_id.hex(), debug_ind) bid = self.getBid(bid_id) bid.debug_ind = debug_ind + + # Update in memory copy. TODO: Improve + bid_in_progress = self.swaps_in_progress.get(bid_id, None) + if bid_in_progress: + bid_in_progress[0].debug_ind = debug_ind + self.saveBid(bid_id, bid) def storeOfferRevoke(self, offer_id, sig): diff --git a/basicswap/basicswap_util.py b/basicswap/basicswap_util.py index ad50cf6..1b3d588 100644 --- a/basicswap/basicswap_util.py +++ b/basicswap/basicswap_util.py @@ -170,12 +170,14 @@ class XmrSplitMsgTypes(IntEnum): class DebugTypes(IntEnum): + NONE = 0 BID_STOP_AFTER_COIN_A_LOCK = auto() BID_DONT_SPEND_COIN_A_LOCK_REFUND = auto() CREATE_INVALID_COIN_B_LOCK = auto() BUYER_STOP_AFTER_ITX = auto() MAKE_INVALID_PTX = auto() DONT_SPEND_ITX = auto() + SKIP_LOCK_TX_REFUND = auto() def strOfferState(state): diff --git a/tests/basicswap/test_run.py b/tests/basicswap/test_run.py index 97d5446..352dcf5 100644 --- a/tests/basicswap/test_run.py +++ b/tests/basicswap/test_run.py @@ -314,7 +314,7 @@ class Test(BaseTest): swap_value = make_int(random.uniform(0.001, 10.0), scale=8, r=1) logging.info('swap_value {}'.format(format_amount(swap_value, 8))) offer_id = swap_clients[0].postOffer(Coins.LTC, Coins.BTC, swap_value, 0.1 * COIN, swap_value, SwapTypes.SELLER_FIRST, - TxLockTypes.SEQUENCE_LOCK_BLOCKS, 10) + TxLockTypes.SEQUENCE_LOCK_BLOCKS, 18) wait_for_offer(test_delay_event, swap_clients[1], offer_id) offer = swap_clients[1].getOffer(offer_id) @@ -405,7 +405,7 @@ class Test(BaseTest): swap_value = make_int(random.uniform(2.0, 20.0), scale=8, r=1) logging.info('swap_value {}'.format(format_amount(swap_value, 8))) offer_id = swap_clients[0].postOffer(Coins.LTC, Coins.BTC, swap_value, 0.5 * COIN, swap_value, SwapTypes.SELLER_FIRST, - TxLockTypes.SEQUENCE_LOCK_BLOCKS, 16) + TxLockTypes.SEQUENCE_LOCK_BLOCKS, 18) wait_for_offer(test_delay_event, swap_clients[1], offer_id) offer = swap_clients[1].getOffer(offer_id) @@ -413,7 +413,12 @@ class Test(BaseTest): swap_clients[1].setBidDebugInd(bid_id, DebugTypes.DONT_SPEND_ITX) wait_for_bid(test_delay_event, swap_clients[0], bid_id) + + # For testing: Block refunding the ITX until PTX has been redeemed, else ITX refund can become spendable before PTX confirms + swap_clients[0].setBidDebugInd(bid_id, DebugTypes.SKIP_LOCK_TX_REFUND) swap_clients[0].acceptBid(bid_id) + wait_for_bid_tx_state(test_delay_event, swap_clients[0], bid_id, TxStates.TX_CONFIRMED, TxStates.TX_REDEEMED, wait_for=60) + swap_clients[0].setBidDebugInd(bid_id, DebugTypes.NONE) wait_for_bid_tx_state(test_delay_event, swap_clients[0], bid_id, TxStates.TX_REFUNDED, TxStates.TX_REDEEMED, wait_for=60)