Refactor participate_tx

This commit is contained in:
tecnovert 2019-07-27 21:50:50 +02:00
parent 4a07c891f6
commit 7ccf191192
No known key found for this signature in database
GPG key ID: 8ED6D8750C4E3F93
7 changed files with 100 additions and 82 deletions

View file

@ -11,13 +11,11 @@ import datetime as dt
import zmq import zmq
import threading import threading
import traceback import traceback
import struct
import hashlib import hashlib
import subprocess import subprocess
import logging import logging
import sqlalchemy as sa import sqlalchemy as sa
from sqlalchemy.orm import sessionmaker, scoped_session from sqlalchemy.orm import sessionmaker, scoped_session
from sqlalchemy.ext.declarative import declarative_base
from enum import IntEnum, auto from enum import IntEnum, auto
from . import __version__ from . import __version__
@ -504,8 +502,8 @@ class BasicSwap():
offer = session.query(Offer).filter_by(offer_id=bid.offer_id).first() offer = session.query(Offer).filter_by(offer_id=bid.offer_id).first()
assert(offer), 'Offer not found' assert(offer), 'Offer not found'
bid.initiate_tx = session.query(SwapTx).filter(sa.and_(SwapTx.bid_id == bid_id, SwapTx.tx_type == TxTypes.ITX)).first() bid.initiate_tx = session.query(SwapTx).filter(sa.and_(SwapTx.bid_id == bid.bid_id, SwapTx.tx_type == TxTypes.ITX)).first()
bid.participate_tx = session.query(SwapTx).filter(sa.and_(SwapTx.bid_id == bid_id, SwapTx.tx_type == TxTypes.PTX)).first() bid.participate_tx = session.query(SwapTx).filter(sa.and_(SwapTx.bid_id == bid.bid_id, SwapTx.tx_type == TxTypes.PTX)).first()
self.swaps_in_progress[bid.bid_id] = (bid, offer) self.swaps_in_progress[bid.bid_id] = (bid, offer)
@ -513,13 +511,13 @@ class BasicSwap():
coin_to = Coins(offer.coin_to) coin_to = Coins(offer.coin_to)
if bid.initiate_tx: if bid.initiate_tx:
self.addWatchedOutput(coin_from, bid.bid_id, bid.initiate_tx.txid.hex(), bid.initiate_tx.vout, BidStates.SWAP_INITIATED) self.addWatchedOutput(coin_from, bid.bid_id, bid.initiate_tx.txid.hex(), bid.initiate_tx.vout, BidStates.SWAP_INITIATED)
if bid.participate_txid: if bid.participate_tx:
self.addWatchedOutput(coin_to, bid.bid_id, bid.participate_txid.hex(), bid.participate_txn_n, BidStates.SWAP_PARTICIPATING) self.addWatchedOutput(coin_to, bid.bid_id, bid.participate_tx.txid.hex(), bid.participate_tx.vout, BidStates.SWAP_PARTICIPATING)
if self.coin_clients[coin_from]['last_height_checked'] < 1: if self.coin_clients[coin_from]['last_height_checked'] < 1:
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
if self.coin_clients[coin_to]['last_height_checked'] < 1: if self.coin_clients[coin_to]['last_height_checked'] < 1:
self.coin_clients[coin_to]['last_height_checked'] = bid.participate_txn_height self.coin_clients[coin_to]['last_height_checked'] = bid.participate_tx.chain_height
finally: finally:
session.close() session.close()
@ -1023,7 +1021,6 @@ class BasicSwap():
p2sh = self.callcoinrpc(Coins.PART, 'decodescript', [script.hex()])['p2sh'] p2sh = self.callcoinrpc(Coins.PART, 'decodescript', [script.hex()])['p2sh']
#bid.initiate_script = script
bid.pkhash_seller = pkhash_refund bid.pkhash_seller = pkhash_refund
txn = self.createInitiateTxn(coin_from, bid_id, bid, script) txn = self.createInitiateTxn(coin_from, bid_id, bid, script)
@ -1064,7 +1061,6 @@ class BasicSwap():
accept_msg_id = bytes.fromhex(msg_id) accept_msg_id = bytes.fromhex(msg_id)
bid.accept_msg_id = accept_msg_id bid.accept_msg_id = accept_msg_id
#bid.initiate_txid = bytes.fromhex(txid)
bid.setState(BidStates.BID_ACCEPTED) bid.setState(BidStates.BID_ACCEPTED)
self.log.info('Sent BID_ACCEPT %s', accept_msg_id.hex()) self.log.info('Sent BID_ACCEPT %s', accept_msg_id.hex())
@ -1116,9 +1112,9 @@ class BasicSwap():
self.returnAddressToPool(bid_id, TxTypes.ITX_REDEEM) self.returnAddressToPool(bid_id, TxTypes.ITX_REDEEM)
if bid.getITxState() != TxStates.TX_REFUNDED: if bid.getITxState() != TxStates.TX_REFUNDED:
self.returnAddressToPool(bid_id, TxTypes.ITX_REFUND) self.returnAddressToPool(bid_id, TxTypes.ITX_REFUND)
if bid.participate_txn_state != TxStates.TX_REDEEMED: if bid.getPTxState() != TxStates.TX_REDEEMED:
self.returnAddressToPool(bid_id, TxTypes.PTX_REDEEM) self.returnAddressToPool(bid_id, TxTypes.PTX_REDEEM)
if bid.participate_txn_state != TxStates.TX_REFUNDED: if bid.getPTxState() != TxStates.TX_REFUNDED:
self.returnAddressToPool(bid_id, TxTypes.PTX_REFUND) self.returnAddressToPool(bid_id, TxTypes.PTX_REFUND)
finally: finally:
session.close() session.close()
@ -1176,7 +1172,7 @@ class BasicSwap():
lock_value = offer.lock_value // 2 lock_value = offer.lock_value // 2
if offer.lock_type < ABS_LOCK_BLOCKS: if offer.lock_type < ABS_LOCK_BLOCKS:
sequence = getExpectedSequence(offer.lock_type, lock_value, coin_to) sequence = getExpectedSequence(offer.lock_type, lock_value, coin_to)
bid.participate_script = buildContractScript(sequence, secret_hash, pkhash_seller, pkhash_buyer_refund) participate_script = buildContractScript(sequence, secret_hash, pkhash_seller, pkhash_buyer_refund)
else: else:
# Lock from the height or time of the block containing the initiate txn # Lock from the height or time of the block containing the initiate txn
coin_from = Coins(offer.coin_from) coin_from = Coins(offer.coin_from)
@ -1207,9 +1203,10 @@ class BasicSwap():
self.log.debug('Setting lock value from time of block %s %s', coin_from, initiate_tx_block_hash) self.log.debug('Setting lock value from time of block %s %s', coin_from, initiate_tx_block_hash)
contract_lock_value = initiate_tx_block_time + lock_value contract_lock_value = initiate_tx_block_time + lock_value
self.log.debug('participate %s lock_value %d %d', coin_to, lock_value, contract_lock_value) self.log.debug('participate %s lock_value %d %d', coin_to, lock_value, contract_lock_value)
bid.participate_script = buildContractScript(contract_lock_value, secret_hash, pkhash_seller, pkhash_buyer_refund, OpCodes.OP_CHECKLOCKTIMEVERIFY) participate_script = buildContractScript(contract_lock_value, secret_hash, pkhash_seller, pkhash_buyer_refund, OpCodes.OP_CHECKLOCKTIMEVERIFY)
return participate_script
def createParticipateTxn(self, bid_id, bid, offer): def createParticipateTxn(self, bid_id, bid, offer, participate_script):
self.log.debug('createParticipateTxn') self.log.debug('createParticipateTxn')
offer_id = bid.offer_id offer_id = bid.offer_id
@ -1223,10 +1220,10 @@ class BasicSwap():
assert(amount_to == (bid.amount * offer.rate) // COIN) assert(amount_to == (bid.amount * offer.rate) // COIN)
if self.coin_clients[coin_to]['use_segwit']: if self.coin_clients[coin_to]['use_segwit']:
p2wsh = getP2WSH(bid.participate_script) p2wsh = getP2WSH(participate_script)
addr_to = self.encodeSegwitP2WSH(coin_to, p2wsh) addr_to = self.encodeSegwitP2WSH(coin_to, p2wsh)
else: else:
addr_to = self.getScriptAddress(coin_to, bid.participate_script) addr_to = self.getScriptAddress(coin_to, participate_script)
txn = self.callcoinrpc(coin_to, 'createrawtransaction', [[], {addr_to: format8(amount_to)}]) txn = self.callcoinrpc(coin_to, 'createrawtransaction', [[], {addr_to: format8(amount_to)}])
options = { options = {
@ -1236,7 +1233,7 @@ class BasicSwap():
txn_funded = self.callcoinrpc(coin_to, 'fundrawtransaction', [txn, options])['hex'] txn_funded = self.callcoinrpc(coin_to, 'fundrawtransaction', [txn, options])['hex']
txn_signed = self.callcoinrpc(coin_to, 'signrawtransactionwithwallet', [txn_funded])['hex'] txn_signed = self.callcoinrpc(coin_to, 'signrawtransactionwithwallet', [txn_funded])['hex']
refund_txn = self.createRefundTxn(coin_to, txn_signed, offer, bid, bid.participate_script, tx_type=TxTypes.PTX_REFUND) refund_txn = self.createRefundTxn(coin_to, txn_signed, offer, bid, participate_script, tx_type=TxTypes.PTX_REFUND)
bid.participate_txn_refund = bytes.fromhex(refund_txn) bid.participate_txn_refund = bytes.fromhex(refund_txn)
chain_height = self.callcoinrpc(coin_to, 'getblockchaininfo')['blocks'] chain_height = self.callcoinrpc(coin_to, 'getblockchaininfo')['blocks']
@ -1248,6 +1245,7 @@ class BasicSwap():
else: else:
vout = getVoutByAddress(txjs, addr_to) vout = getVoutByAddress(txjs, addr_to)
self.addParticipateTxn(bid_id, bid, coin_to, txid, vout, chain_height) self.addParticipateTxn(bid_id, bid, coin_to, txid, vout, chain_height)
bid.participate_tx.script = participate_script
return txn_signed return txn_signed
@ -1265,9 +1263,9 @@ class BasicSwap():
self.log.debug('createRedeemTxn for coin %s', str(coin_type)) self.log.debug('createRedeemTxn for coin %s', str(coin_type))
if for_txn_type == 'participate': if for_txn_type == 'participate':
prev_txnid = bid.participate_txid.hex() prev_txnid = bid.participate_tx.txid.hex()
prev_n = bid.participate_txn_n prev_n = bid.participate_tx.vout
txn_script = bid.participate_script txn_script = bid.participate_tx.script
prev_amount = bid.amount_to prev_amount = bid.amount_to
else: else:
prev_txnid = bid.initiate_tx.txid.hex() prev_txnid = bid.initiate_tx.txid.hex()
@ -1478,15 +1476,21 @@ class BasicSwap():
bid.setITxState(TxStates.TX_CONFIRMED) bid.setITxState(TxStates.TX_CONFIRMED)
# Seller first mode, buyer participates # Seller first mode, buyer participates
self.deriveParticipateScript(bid_id, bid, offer) participate_script = self.deriveParticipateScript(bid_id, bid, offer)
if bid.was_sent: if bid.was_sent:
self.log.debug('Preparing participate txn for bid %s', bid_id.hex()) self.log.debug('Preparing participate txn for bid %s', bid_id.hex())
coin_to = Coins(offer.coin_to) coin_to = Coins(offer.coin_to)
txn = self.createParticipateTxn(bid_id, bid, offer) txn = self.createParticipateTxn(bid_id, bid, offer, participate_script)
txid = self.submitTxn(coin_to, txn) txid = self.submitTxn(coin_to, txn)
self.log.debug('Submitted participate txn %s to %s chain for bid %s', txid, chainparams[coin_to]['name'], bid_id.hex()) self.log.debug('Submitted participate txn %s to %s chain for bid %s', txid, chainparams[coin_to]['name'], bid_id.hex())
bid.setPTxState(TxStates.TX_SENT) bid.setPTxState(TxStates.TX_SENT)
else:
bid.participate_tx = SwapTx(
bid_id=bid_id,
tx_type=TxTypes.PTX,
script=participate_script,
)
# bid saved in checkBidState # bid saved in checkBidState
@ -1506,16 +1510,21 @@ class BasicSwap():
return tx_height return tx_height
def addParticipateTxn(self, bid_id, bid, coin_type, txid_hex, vout, tx_height): def addParticipateTxn(self, bid_id, bid, coin_type, txid_hex, vout, tx_height):
bid.participate_txid = bytes.fromhex(txid_hex)
bid.participate_txn_n = vout
# Start checking for spends of participate_txn before fully confirmed
chain_name = chainparams[coin_type]['name']
self.log.debug('Watching %s chain for spend of output %s %d', chain_name, txid_hex, vout)
# TODO: Check connection type # TODO: Check connection type
bid.participate_txn_height = self.setLastHeightChecked(coin_type, tx_height) participate_txn_height = self.setLastHeightChecked(coin_type, tx_height)
if bid.participate_tx is None:
bid.participate_tx = SwapTx(
bid_id=bid_id,
tx_type=TxTypes.PTX,
)
bid.participate_tx.txid = bytes.fromhex(txid_hex)
bid.participate_tx.vout = vout
bid.participate_tx.chain_height = participate_txn_height
# Start checking for spends of participate_txn before fully confirmed
self.log.debug('Watching %s chain for spend of output %s %d', chainparams[coin_type]['name'], txid_hex, vout)
self.addWatchedOutput(coin_type, bid_id, txid_hex, vout, BidStates.SWAP_PARTICIPATING) self.addWatchedOutput(coin_type, bid_id, txid_hex, vout, BidStates.SWAP_PARTICIPATING)
def participateTxnConfirmed(self, bid_id, bid, offer): def participateTxnConfirmed(self, bid_id, bid, offer):
@ -1642,25 +1651,25 @@ class BasicSwap():
elif state == BidStates.SWAP_INITIATED: elif state == BidStates.SWAP_INITIATED:
# Waiting for participate txn to be confirmed in 'to' chain # Waiting for participate txn to be confirmed in 'to' chain
if self.coin_clients[coin_to]['use_segwit']: if self.coin_clients[coin_to]['use_segwit']:
addr = self.encodeSegwitP2WSH(coin_to, getP2WSH(bid.participate_script)) addr = self.encodeSegwitP2WSH(coin_to, getP2WSH(bid.participate_tx.script))
else: else:
addr = self.getScriptAddress(coin_to, bid.participate_script) addr = self.getScriptAddress(coin_to, bid.participate_tx.script)
found = self.lookupUnspentByAddress(coin_to, addr, assert_amount=bid.amount_to) found = self.lookupUnspentByAddress(coin_to, addr, assert_amount=bid.amount_to)
if found: if found:
if bid.participate_txn_conf != found['n_conf']: if bid.participate_tx.conf != found['n_conf']:
save_bid = True save_bid = True
bid.participate_txn_conf = found['n_conf'] bid.participate_tx.conf = found['n_conf']
index = found['index'] index = found['index']
if bid.participate_txid is None: if bid.participate_tx is None or bid.participate_tx.txid is None:
self.log.debug('Found bid %s participate txn %s in chain %s', bid_id.hex(), found['txid'], coin_to) self.log.debug('Found bid %s participate txn %s in chain %s', bid_id.hex(), found['txid'], coin_to)
self.addParticipateTxn(bid_id, bid, coin_to, found['txid'], found['index'], found['height']) self.addParticipateTxn(bid_id, bid, coin_to, found['txid'], found['index'], found['height'])
bid.setPTxState(TxStates.TX_SENT) bid.setPTxState(TxStates.TX_SENT)
save_bid = True save_bid = True
if bid.participate_txn_conf is not None: if bid.participate_tx.conf is not None:
self.log.debug('participate_txid %s confirms %d', bid.participate_txid.hex(), bid.participate_txn_conf) self.log.debug('participate txid %s confirms %d', bid.participate_tx.txid.hex(), bid.participate_tx.conf)
if bid.participate_txn_conf >= self.coin_clients[coin_to]['blocks_confirmed']: if bid.participate_tx.conf >= self.coin_clients[coin_to]['blocks_confirmed']:
self.participateTxnConfirmed(bid_id, bid, offer) self.participateTxnConfirmed(bid_id, bid, offer)
save_bid = True save_bid = True
elif state == BidStates.SWAP_PARTICIPATING: elif state == BidStates.SWAP_PARTICIPATING:
@ -1672,14 +1681,14 @@ class BasicSwap():
if state > BidStates.BID_ACCEPTED: if state > BidStates.BID_ACCEPTED:
# Wait for spend of all known swap txns # Wait for spend of all known swap txns
if (bid.getITxState() is None or bid.getITxState() >= TxStates.TX_REDEEMED) \ if (bid.getITxState() is None or bid.getITxState() >= TxStates.TX_REDEEMED) \
and (bid.participate_txn_state is None or bid.participate_txn_state >= TxStates.TX_REDEEMED): and (bid.getPTxState() is None or bid.getPTxState() >= TxStates.TX_REDEEMED):
self.log.info('Swap completed for bid %s', bid_id.hex()) self.log.info('Swap completed for bid %s', bid_id.hex())
if bid.getITxState() == TxStates.TX_REDEEMED: if bid.getITxState() == TxStates.TX_REDEEMED:
self.returnAddressToPool(bid_id, TxTypes.ITX_REFUND) self.returnAddressToPool(bid_id, TxTypes.ITX_REFUND)
else: else:
self.returnAddressToPool(bid_id, TxTypes.ITX_REDEEM) self.returnAddressToPool(bid_id, TxTypes.ITX_REDEEM)
if bid.participate_txn_state == TxStates.TX_REDEEMED: if bid.getPTxState() == TxStates.TX_REDEEMED:
self.returnAddressToPool(bid_id, TxTypes.PTX_REFUND) self.returnAddressToPool(bid_id, TxTypes.PTX_REFUND)
else: else:
self.returnAddressToPool(bid_id, TxTypes.PTX_REDEEM) self.returnAddressToPool(bid_id, TxTypes.PTX_REDEEM)
@ -1701,7 +1710,7 @@ class BasicSwap():
except Exception as ex: except Exception as ex:
if 'non-BIP68-final (code 64)' not in str(ex) and 'non-final' not in str(ex): if 'non-BIP68-final (code 64)' not in str(ex) and 'non-final' not in str(ex):
self.log.warning('Error trying to submit initiate refund txn: %s', str(ex)) self.log.warning('Error trying to submit initiate refund txn: %s', str(ex))
if (bid.participate_txn_state == TxStates.TX_SENT or bid.participate_txn_state == TxStates.TX_CONFIRMED) \ if (bid.getPTxState() == TxStates.TX_SENT or bid.getPTxState() == TxStates.TX_CONFIRMED) \
and bid.participate_txn_refund is not None: and bid.participate_txn_refund is not None:
try: try:
txid = self.submitTxn(coin_to, bid.participate_txn_refund.hex()) txid = self.submitTxn(coin_to, bid.participate_txn_refund.hex())
@ -1773,8 +1782,8 @@ class BasicSwap():
bid = self.swaps_in_progress[bid_id][0] bid = self.swaps_in_progress[bid_id][0]
offer = self.swaps_in_progress[bid_id][1] offer = self.swaps_in_progress[bid_id][1]
bid.participate_spend_txid = bytes.fromhex(spend_txid) bid.participate_tx.spend_txid = bytes.fromhex(spend_txid)
bid.participate_spend_n = spend_n bid.participate_tx.spend_n = spend_n
spend_in = spend_txn['vin'][spend_n] spend_in = spend_txn['vin'][spend_n]
coin_from = Coins(offer.coin_from) coin_from = Coins(offer.coin_from)
@ -1801,7 +1810,7 @@ class BasicSwap():
# TODO: Wait for depth? new state SWAP_TXI_REDEEM_SENT? # TODO: Wait for depth? new state SWAP_TXI_REDEEM_SENT?
self.removeWatchedOutput(coin_to, bid_id, bid.participate_txid.hex()) self.removeWatchedOutput(coin_to, bid_id, bid.participate_tx.txid.hex())
self.saveBid(bid_id, bid) self.saveBid(bid_id, bid)
def checkForSpends(self, coin_type, c): def checkForSpends(self, coin_type, c):
@ -2075,8 +2084,6 @@ class BasicSwap():
assert(bid.accept_msg_id is None), 'Bid already accepted' assert(bid.accept_msg_id is None), 'Bid already accepted'
bid.accept_msg_id = bytes.fromhex(msg['msgid']) bid.accept_msg_id = bytes.fromhex(msg['msgid'])
#bid.initiate_txid = bid_accept_data.initiate_txid
#bid.initiate_script = bid_accept_data.contract_script
bid.initiate_tx = SwapTx( bid.initiate_tx = SwapTx(
bid_id=bid_id, bid_id=bid_id,
tx_type=TxTypes.ITX, tx_type=TxTypes.ITX,

View file

@ -7,7 +7,6 @@
import struct import struct
import time import time
import sqlalchemy as sa import sqlalchemy as sa
from sqlalchemy.orm import sessionmaker, scoped_session
from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.ext.declarative import declarative_base
CURRENT_DB_VERSION = 1 CURRENT_DB_VERSION = 1
@ -89,22 +88,12 @@ class Bid(Base):
accept_msg_id = sa.Column(sa.LargeBinary) accept_msg_id = sa.Column(sa.LargeBinary)
pkhash_seller = sa.Column(sa.LargeBinary) pkhash_seller = sa.Column(sa.LargeBinary)
initiate_txn_redeem = sa.Column(sa.LargeBinary)
initiate_txn_refund = sa.Column(sa.LargeBinary) initiate_txn_refund = sa.Column(sa.LargeBinary)
participate_script = sa.Column(sa.LargeBinary)
participate_txid = sa.Column(sa.LargeBinary)
participate_txn_n = sa.Column(sa.Integer)
participate_txn_conf = sa.Column(sa.Integer)
participate_txn_redeem = sa.Column(sa.LargeBinary) participate_txn_redeem = sa.Column(sa.LargeBinary)
participate_txn_refund = sa.Column(sa.LargeBinary) participate_txn_refund = sa.Column(sa.LargeBinary)
participate_spend_txid = sa.Column(sa.LargeBinary)
participate_spend_n = sa.Column(sa.Integer)
participate_txn_height = sa.Column(sa.Integer)
participate_txn_state = sa.Column(sa.Integer)
participate_txn_states = sa.Column(sa.LargeBinary) # Packed states and times
state = sa.Column(sa.Integer) state = sa.Column(sa.Integer)
state_time = sa.Column(sa.BigInteger) # timestamp of last state change state_time = sa.Column(sa.BigInteger) # timestamp of last state change
states = sa.Column(sa.LargeBinary) # Packed states and times states = sa.Column(sa.LargeBinary) # Packed states and times
@ -134,12 +123,6 @@ class Bid(Base):
self.participate_tx.state = new_state self.participate_tx.state = new_state
self.participate_tx.states = (self.participate_tx.states if self.participate_tx.states is not None else bytes()) + struct.pack('<iq', new_state, int(time.time())) self.participate_tx.states = (self.participate_tx.states if self.participate_tx.states is not None else bytes()) + struct.pack('<iq', new_state, int(time.time()))
self.participate_txn_state = new_state
if self.participate_txn_states is None:
self.participate_txn_states = struct.pack('<iq', new_state, int(time.time()))
else:
self.participate_txn_states += struct.pack('<iq', new_state, int(time.time()))
def setState(self, new_state): def setState(self, new_state):
now = int(time.time()) now = int(time.time())
self.state = new_state self.state = new_state
@ -190,4 +173,3 @@ class SentOffer(Base):
__tablename__ = 'sentoffers' __tablename__ = 'sentoffers'
offer_id = sa.Column(sa.LargeBinary, primary_key=True) offer_id = sa.Column(sa.LargeBinary, primary_key=True)

View file

@ -28,6 +28,7 @@ from .basicswap import (
SwapTypes, SwapTypes,
BidStates, BidStates,
TxStates, TxStates,
TxTypes,
strOfferState, strOfferState,
strBidState, strBidState,
strTxState, strTxState,
@ -49,6 +50,36 @@ def getCoinName(c):
return chainparams[c]['name'].capitalize() return chainparams[c]['name'].capitalize()
def getTxIdHex(bid, tx_type, prefix):
if tx_type == TxTypes.ITX:
obj = bid.initiate_tx
elif tx_type == TxTypes.PTX:
obj = bid.participate_tx
else:
return 'Unknown Type'
if not obj:
return None
if not obj.txid:
return None
return obj.txid.hex() + prefix
def getTxSpendHex(bid, tx_type):
if tx_type == TxTypes.ITX:
obj = bid.initiate_tx
elif tx_type == TxTypes.PTX:
obj = bid.participate_tx
else:
return 'Unknown Type'
if not obj:
return None
if not obj.spend_txid:
return None
obj.spend_txid.hex() + ' {}'.format(obj.spend_n)
def html_content_start(title, h2=None, refresh=None): def html_content_start(title, h2=None, refresh=None):
content = '<!DOCTYPE html><html lang="en">\n<head>' \ content = '<!DOCTYPE html><html lang="en">\n<head>' \
+ '<meta charset="UTF-8">' \ + '<meta charset="UTF-8">' \
@ -275,7 +306,7 @@ class HttpHandler(BaseHTTPRequestHandler):
sent_bid_id=sent_bid_id, sent_bid_id=sent_bid_id,
messages=messages, messages=messages,
data=data, data=data,
bids=[(b.bid_id.hex(), format8(b.amount), strBidState(b.state), strTxState(b.getITxState()), strTxState(b.participate_txn_state)) for b in bids], bids=[(b.bid_id.hex(), format8(b.amount), strBidState(b.state), strTxState(b.getITxState()), strTxState(b.getPTxState())) for b in bids],
form_id=os.urandom(8).hex(), form_id=os.urandom(8).hex(),
), 'UTF-8') ), 'UTF-8')
@ -364,10 +395,10 @@ class HttpHandler(BaseHTTPRequestHandler):
state_description = 'Waiting for initiate txn to be spent in {} chain'.format(ticker_from) state_description = 'Waiting for initiate txn to be spent in {} chain'.format(ticker_from)
elif bid.state == BidStates.SWAP_COMPLETED: elif bid.state == BidStates.SWAP_COMPLETED:
state_description = 'Swap completed' state_description = 'Swap completed'
if bid.getITxState() == TxStates.TX_REDEEMED and bid.participate_txn_state == TxStates.TX_REDEEMED: if bid.getITxState() == TxStates.TX_REDEEMED and bid.getPTxState() == TxStates.TX_REDEEMED:
state_description += ' successfully' state_description += ' successfully'
else: else:
state_description += ', ITX ' + strTxState(bid.getITxState() + ', PTX ' + strTxState(bid.participate_txn_state)) state_description += ', ITX ' + strTxState(bid.getITxState() + ', PTX ' + strTxState(bid.getPTxState()))
elif bid.state == BidStates.SWAP_TIMEDOUT: elif bid.state == BidStates.SWAP_TIMEDOUT:
state_description = 'Timed out waiting for initiate txn' state_description = 'Timed out waiting for initiate txn'
elif bid.state == BidStates.BID_ABANDONED: elif bid.state == BidStates.BID_ABANDONED:
@ -385,7 +416,7 @@ class HttpHandler(BaseHTTPRequestHandler):
'bid_state': strBidState(bid.state), 'bid_state': strBidState(bid.state),
'state_description': state_description, 'state_description': state_description,
'itx_state': strTxState(bid.getITxState()), 'itx_state': strTxState(bid.getITxState()),
'ptx_state': strTxState(bid.participate_txn_state), 'ptx_state': strTxState(bid.getPTxState()),
'offer_id': bid.offer_id.hex(), 'offer_id': bid.offer_id.hex(),
'addr_from': bid.bid_addr, 'addr_from': bid.bid_addr,
'addr_fund_proof': bid.proof_address, 'addr_fund_proof': bid.proof_address,
@ -393,18 +424,18 @@ class HttpHandler(BaseHTTPRequestHandler):
'expired_at': time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(bid.expire_at)), 'expired_at': time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(bid.expire_at)),
'was_sent': 'True' if bid.was_sent else 'False', 'was_sent': 'True' if bid.was_sent else 'False',
'was_received': 'True' if bid.was_received else 'False', 'was_received': 'True' if bid.was_received else 'False',
'initiate_tx': 'None' if not bid.initiate_tx else (bid.initiate_tx.txid.hex() + ' ' + ticker_from), 'initiate_tx': getTxIdHex(bid, TxTypes.ITX, ' ' + ticker_from),
'initiate_conf': 'None' if (not bid.initiate_tx or not bid.initiate_tx.conf) else bid.initiate_tx.conf, 'initiate_conf': 'None' if (not bid.initiate_tx or not bid.initiate_tx.conf) else bid.initiate_tx.conf,
'participate_tx': 'None' if not bid.participate_tx else (bid.participate_tx.txid.hex() + ' ' + ticker_to), 'participate_tx': getTxIdHex(bid, TxTypes.PTX, ' ' + ticker_to),
'participate_conf': 'None' if not bid.participate_txn_conf else bid.participate_txn_conf, 'participate_conf': 'None' if (not bid.participate_tx or not bid.participate_tx.conf) else bid.participate_tx.conf,
'show_txns': show_txns, 'show_txns': show_txns,
} }
if show_txns: if show_txns:
data['initiate_tx_refund'] = 'None' if not bid.initiate_txn_refund else bid.initiate_txn_refund.hex() data['initiate_tx_refund'] = 'None' if not bid.initiate_txn_refund else bid.initiate_txn_refund.hex()
data['participate_tx_refund'] = 'None' if not bid.participate_txn_refund else bid.participate_txn_refund.hex() data['participate_tx_refund'] = 'None' if not bid.participate_txn_refund else bid.participate_txn_refund.hex()
data['initiate_tx_spend'] = 'None' if not bid.initiate_spend_txid else (bid.initiate_spend_txid.hex() + ' {}'.format(bid.initiate_spend_n)) data['initiate_tx_spend'] = getTxSpendHex(bid, TxTypes.ITX),
data['participate_tx_spend'] = 'None' if not bid.participate_spend_txid else (bid.participate_spend_txid.hex() + ' {}'.format(bid.participate_spend_n)) data['participate_tx_spend'] = getTxSpendHex(bid, TxTypes.PTX),
old_states = [] old_states = []
num_states = len(bid.states) // 12 num_states = len(bid.states) // 12
@ -416,10 +447,10 @@ class HttpHandler(BaseHTTPRequestHandler):
for i in range(num_states): for i in range(num_states):
up = struct.unpack_from('<iq', bid.initiate_tx.states[i * 12:(i + 1) * 12]) up = struct.unpack_from('<iq', bid.initiate_tx.states[i * 12:(i + 1) * 12])
old_states.append((up[1], 'ITX ' + strTxState(up[0]))) old_states.append((up[1], 'ITX ' + strTxState(up[0])))
if bid.participate_txn_states is not None: if bid.participate_tx and bid.participate_tx.states is not None:
num_states = len(bid.participate_txn_states) // 12 num_states = len(bid.participate_tx.states) // 12
for i in range(num_states): for i in range(num_states):
up = struct.unpack_from('<iq', bid.participate_txn_states[i * 12:(i + 1) * 12]) up = struct.unpack_from('<iq', bid.participate_tx.states[i * 12:(i + 1) * 12])
old_states.append((up[1], 'PTX ' + strTxState(up[0]))) old_states.append((up[1], 'PTX ' + strTxState(up[0])))
if len(old_states) > 0: if len(old_states) > 0:
old_states.sort(key=lambda x: x[0]) old_states.sort(key=lambda x: x[0])
@ -445,7 +476,7 @@ class HttpHandler(BaseHTTPRequestHandler):
h2=self.server.title, h2=self.server.title,
page_type='Sent' if sent else 'Received', page_type='Sent' if sent else 'Received',
bids=[(time.strftime('%Y-%m-%d %H:%M', time.localtime(b.created_at)), bids=[(time.strftime('%Y-%m-%d %H:%M', time.localtime(b.created_at)),
b.bid_id.hex(), b.offer_id.hex(), strBidState(b.state), strTxState(b.getITxState()), strTxState(b.participate_txn_state)) for b in bids], b.bid_id.hex(), b.offer_id.hex(), strBidState(b.state), strTxState(b.getITxState()), strTxState(b.getPTxState())) for b in bids],
), 'UTF-8') ), 'UTF-8')
def page_watched(self, url_split, post_string): def page_watched(self, url_split, post_string):

View file

@ -371,7 +371,7 @@ class Test(unittest.TestCase):
time.sleep(1) time.sleep(1)
bid = swap_client.getBid(bid_id) bid = swap_client.getBid(bid_id)
if (initiate_state is None or bid.getITxState() == initiate_state) \ if (initiate_state is None or bid.getITxState() == initiate_state) \
and (participate_state is None or bid.participate_txn_state == participate_state): and (participate_state is None or bid.getPTxState() == participate_state):
return return
raise ValueError('wait_for_bid_tx_state timed out.') raise ValueError('wait_for_bid_tx_state timed out.')

View file

@ -30,7 +30,7 @@ class Test(unittest.TestCase):
shutil.rmtree(test_path) shutil.rmtree(test_path)
except Exception as ex: except Exception as ex:
logger.warning('tearDownClass %s', str(ex)) logger.warning('tearDownClass %s', str(ex))
super(Test, cls).tearDownClass() super(Test, self).tearDownClass()
def test(self): def test(self):
testargs = ['basicswap-prepare', '-datadir=' + test_path] testargs = ['basicswap-prepare', '-datadir=' + test_path]

View file

@ -20,10 +20,8 @@ import sys
import time import time
import unittest import unittest
from unittest.mock import patch from unittest.mock import patch
from io import StringIO
import logging import logging
import shutil import shutil
import json
import threading import threading
import bin.basicswap_prepare as prepareSystem import bin.basicswap_prepare as prepareSystem

View file

@ -367,7 +367,7 @@ class Test(unittest.TestCase):
time.sleep(1) time.sleep(1)
bid = swap_client.getBid(bid_id) bid = swap_client.getBid(bid_id)
if (initiate_state is None or bid.getITxState() == initiate_state) \ if (initiate_state is None or bid.getITxState() == initiate_state) \
and (participate_state is None or bid.participate_txn_state == participate_state): and (participate_state is None or bid.getPTxState() == participate_state):
return return
raise ValueError('wait_for_bid_tx_state timed out.') raise ValueError('wait_for_bid_tx_state timed out.')