mirror of
https://github.com/basicswap/basicswap.git
synced 2024-11-17 00:07:56 +00:00
Poll chainstates.
Litecoin download link changed. Fix fee comparison tx weight difference. Remove format8. New stalled for test bid state. Moved sequence code to coin interfaces. Display estimated time lock refund tx will be valid.
This commit is contained in:
parent
c66160fb09
commit
deb71856e8
13 changed files with 180 additions and 103 deletions
|
@ -16,6 +16,7 @@ import struct
|
|||
import hashlib
|
||||
import secrets
|
||||
import datetime as dt
|
||||
import threading
|
||||
import traceback
|
||||
import sqlalchemy as sa
|
||||
import collections
|
||||
|
@ -33,7 +34,6 @@ from .interface_bitcore_btc import BitcoreBTCInterface
|
|||
from . import __version__
|
||||
from .util import (
|
||||
pubkeyToAddress,
|
||||
format8,
|
||||
format_amount,
|
||||
format_timestamp,
|
||||
encodeAddress,
|
||||
|
@ -89,6 +89,11 @@ from .explorers import (
|
|||
ExplorerBitAps,
|
||||
ExplorerChainz,
|
||||
)
|
||||
from .types import (
|
||||
SEQUENCE_LOCK_BLOCKS,
|
||||
SEQUENCE_LOCK_TIME,
|
||||
ABS_LOCK_BLOCKS,
|
||||
ABS_LOCK_TIME)
|
||||
import basicswap.config as cfg
|
||||
import basicswap.network as bsn
|
||||
import basicswap.protocols.atomic_swap_1 as atomic_swap_1
|
||||
|
@ -152,6 +157,7 @@ class BidStates(IntEnum):
|
|||
SWAP_TIMEDOUT = auto()
|
||||
BID_ABANDONED = auto() # Bid will no longer be processed
|
||||
BID_ERROR = auto() # An error occurred
|
||||
BID_STALLED_FOR_TEST = auto()
|
||||
|
||||
|
||||
class TxStates(IntEnum):
|
||||
|
@ -221,14 +227,6 @@ class DebugTypes(IntEnum):
|
|||
MAKE_INVALID_PTX = auto()
|
||||
|
||||
|
||||
SEQUENCE_LOCK_BLOCKS = 1
|
||||
SEQUENCE_LOCK_TIME = 2
|
||||
ABS_LOCK_BLOCKS = 3
|
||||
ABS_LOCK_TIME = 4
|
||||
|
||||
SEQUENCE_LOCKTIME_GRANULARITY = 9 # 512 seconds
|
||||
SEQUENCE_LOCKTIME_TYPE_FLAG = (1 << 22)
|
||||
SEQUENCE_LOCKTIME_MASK = 0x0000ffff
|
||||
INITIATE_TX_TIMEOUT = 40 * 60 # TODO: make variable per coin
|
||||
|
||||
|
||||
|
@ -263,6 +261,8 @@ def strBidState(state):
|
|||
return 'Timed-out'
|
||||
if state == BidStates.BID_ABANDONED:
|
||||
return 'Abandoned'
|
||||
if state == BidStates.BID_STALLED_FOR_TEST:
|
||||
return 'Stalled (debug)'
|
||||
if state == BidStates.BID_ERROR:
|
||||
return 'Error'
|
||||
if state == BidStates.XMR_SWAP_SCRIPT_COIN_LOCKED:
|
||||
|
@ -366,27 +366,6 @@ def describeEventEntry(event_type, event_msg):
|
|||
return 'Lock tx B refund tx published'
|
||||
|
||||
|
||||
def getExpectedSequence(lockType, lockVal, coin_type):
|
||||
assert(lockVal >= 1), 'Bad lockVal'
|
||||
if lockType == SEQUENCE_LOCK_BLOCKS:
|
||||
return lockVal
|
||||
if lockType == SEQUENCE_LOCK_TIME:
|
||||
secondsLocked = lockVal
|
||||
# Ensure the locked time is never less than lockVal
|
||||
if secondsLocked % (1 << SEQUENCE_LOCKTIME_GRANULARITY) != 0:
|
||||
secondsLocked += (1 << SEQUENCE_LOCKTIME_GRANULARITY)
|
||||
secondsLocked >>= SEQUENCE_LOCKTIME_GRANULARITY
|
||||
return secondsLocked | SEQUENCE_LOCKTIME_TYPE_FLAG
|
||||
raise ValueError('Unknown lock type')
|
||||
|
||||
|
||||
def decodeSequence(lock_value):
|
||||
# Return the raw value
|
||||
if lock_value & SEQUENCE_LOCKTIME_TYPE_FLAG:
|
||||
return (lock_value & SEQUENCE_LOCKTIME_MASK) << SEQUENCE_LOCKTIME_GRANULARITY
|
||||
return lock_value & SEQUENCE_LOCKTIME_MASK
|
||||
|
||||
|
||||
def getVoutByAddress(txjs, p2sh):
|
||||
for o in txjs['vout']:
|
||||
try:
|
||||
|
@ -420,6 +399,29 @@ def getOfferProofOfFundsHash(offer_msg, offer_addr):
|
|||
return h.digest()
|
||||
|
||||
|
||||
def threadPollChainState(swap_client, coin_type):
|
||||
while not swap_client.delay_event.is_set():
|
||||
try:
|
||||
ci = swap_client.ci(coin_type)
|
||||
if coin_type == Coins.XMR:
|
||||
new_height = ci.getChainHeight()
|
||||
if new_height != swap_client.coin_clients[coin_type]['chain_height']:
|
||||
swap_client.log.debug('New {} block at height: {}'.format(str(coin_type), new_height))
|
||||
with swap_client.mxDB:
|
||||
swap_client.coin_clients[coin_type]['chain_height'] = new_height
|
||||
else:
|
||||
chain_state = ci.getBlockchainInfo()
|
||||
if chain_state['bestblockhash'] != swap_client.coin_clients[coin_type]['chain_best_block']:
|
||||
swap_client.log.debug('New {} block at height: {}'.format(str(coin_type), chain_state['blocks']))
|
||||
with swap_client.mxDB:
|
||||
swap_client.coin_clients[coin_type]['chain_height'] = chain_state['blocks']
|
||||
swap_client.coin_clients[coin_type]['chain_best_block'] = chain_state['bestblockhash']
|
||||
swap_client.coin_clients[coin_type]['chain_median_time'] = chain_state['mediantime']
|
||||
except Exception as e:
|
||||
swap_client.log.warning('threadPollChainState error: {}'.format(str(e)))
|
||||
swap_client.delay_event.wait(random.randrange(20, 30)) # random to stagger updates
|
||||
|
||||
|
||||
class WatchedOutput(): # Watch for spends
|
||||
__slots__ = ('bid_id', 'txid_hex', 'vout', 'tx_type', 'swap_type')
|
||||
|
||||
|
@ -476,6 +478,9 @@ class BasicSwap(BaseApp):
|
|||
|
||||
self.SMSG_SECONDS_IN_HOUR = 60 * 2 if self.chain == 'regtest' else 60 * 60
|
||||
|
||||
self.delay_event = threading.Event()
|
||||
self.threads = []
|
||||
|
||||
# Encode key to match network
|
||||
wif_prefix = chainparams[Coins.PART][self.chain]['key_prefix']
|
||||
self.network_key = toWIF(wif_prefix, decodeWif(self.settings['network_key']))
|
||||
|
@ -551,11 +556,15 @@ class BasicSwap(BaseApp):
|
|||
|
||||
with self.mxDB:
|
||||
self.is_running = False
|
||||
self.delay_event.set()
|
||||
|
||||
if self._network:
|
||||
self._network.stopNetwork()
|
||||
self._network = None
|
||||
|
||||
for t in self.threads:
|
||||
t.join()
|
||||
|
||||
def setCoinConnectParams(self, coin):
|
||||
# Set anything that does not require the daemon to be running
|
||||
chain_client_settings = self.getChainClientSettings(coin)
|
||||
|
@ -594,7 +603,6 @@ class BasicSwap(BaseApp):
|
|||
'conf_target': chain_client_settings.get('conf_target', 2),
|
||||
'watched_outputs': [],
|
||||
'last_height_checked': last_height_checked,
|
||||
'last_height': None,
|
||||
'use_segwit': chain_client_settings.get('use_segwit', False),
|
||||
'use_csv': chain_client_settings.get('use_csv', True),
|
||||
'core_version_group': chain_client_settings.get('core_version_group', 0),
|
||||
|
@ -604,6 +612,11 @@ class BasicSwap(BaseApp):
|
|||
'chain_lookups': chain_client_settings.get('chain_lookups', 'local'),
|
||||
'restore_height': chain_client_settings.get('restore_height', 0),
|
||||
'fee_priority': chain_client_settings.get('fee_priority', 0),
|
||||
|
||||
# Chain state
|
||||
'chain_height': None,
|
||||
'chain_best_block': None,
|
||||
'chain_median_time': None,
|
||||
}
|
||||
|
||||
if self.coin_clients[coin]['connection_type'] == 'rpc':
|
||||
|
@ -697,6 +710,10 @@ class BasicSwap(BaseApp):
|
|||
self.log.info('%s Core version %d', ci.coin_name(), core_version)
|
||||
self.coin_clients[c]['core_version'] = core_version
|
||||
|
||||
t = threading.Thread(target=threadPollChainState, args=(self, c))
|
||||
self.threads.append(t)
|
||||
t.start()
|
||||
|
||||
if c == Coins.PART:
|
||||
self.coin_clients[c]['have_spent_index'] = ci.haveSpentIndex()
|
||||
|
||||
|
@ -1065,10 +1082,12 @@ class BasicSwap(BaseApp):
|
|||
assert(coin_from != coin_to), 'coin_from == coin_to'
|
||||
try:
|
||||
coin_from_t = Coins(coin_from)
|
||||
ci_from = self.ci(coin_from_t)
|
||||
except Exception:
|
||||
raise ValueError('Unknown coin from type')
|
||||
try:
|
||||
coin_to_t = Coins(coin_to)
|
||||
ci_to = self.ci(coin_to_t)
|
||||
except Exception:
|
||||
raise ValueError('Unknown coin to type')
|
||||
|
||||
|
@ -1124,10 +1143,10 @@ class BasicSwap(BaseApp):
|
|||
xmr_offer = XmrOffer()
|
||||
|
||||
# Delay before the chain a lock refund tx can be mined
|
||||
xmr_offer.lock_time_1 = getExpectedSequence(lock_type, lock_value, coin_from)
|
||||
xmr_offer.lock_time_1 = ci_from.getExpectedSequence(lock_type, lock_value)
|
||||
|
||||
# Delay before the follower can spend from the chain a lock refund tx
|
||||
xmr_offer.lock_time_2 = getExpectedSequence(lock_type, lock_value, coin_from)
|
||||
xmr_offer.lock_time_2 = ci_from.getExpectedSequence(lock_type, lock_value)
|
||||
|
||||
xmr_offer.a_fee_rate = msg_buf.fee_rate_from
|
||||
xmr_offer.b_fee_rate = msg_buf.fee_rate_to # Unused: TODO - Set priority?
|
||||
|
@ -1359,7 +1378,8 @@ class BasicSwap(BaseApp):
|
|||
return self.callcoinrpc(coin_type, 'getnetworkinfo')['relayfee']
|
||||
|
||||
def getFeeRateForCoin(self, coin_type, conf_target=2):
|
||||
override_feerate = self.coin_clients[coin_type].get('override_feerate', None)
|
||||
chain_client_settings = self.getChainClientSettings(coin_type)
|
||||
override_feerate = chain_client_settings.get('override_feerate', None)
|
||||
if override_feerate:
|
||||
self.log.debug('Fee rate override used for %s: %f', str(coin_type), override_feerate)
|
||||
return override_feerate, 'override_feerate'
|
||||
|
@ -1592,7 +1612,7 @@ class BasicSwap(BaseApp):
|
|||
|
||||
def postBid(self, offer_id, amount, addr_send_from=None, extra_options={}):
|
||||
# Bid to send bid.amount * offer.rate of coin_to in exchange for bid.amount of coin_from
|
||||
self.log.debug('postBid %s %s', offer_id.hex(), format8(amount))
|
||||
self.log.debug('postBid %s', offer_id.hex())
|
||||
|
||||
offer = self.getOffer(offer_id)
|
||||
assert(offer), 'Offer not found: {}.'.format(offer_id.hex())
|
||||
|
@ -1828,6 +1848,7 @@ class BasicSwap(BaseApp):
|
|||
bid.contract_count = self.getNewContractId()
|
||||
|
||||
coin_from = Coins(offer.coin_from)
|
||||
ci_from = self.ci(coin_from)
|
||||
bid_date = dt.datetime.fromtimestamp(bid.created_at).date()
|
||||
|
||||
secret = self.getContractSecret(bid_date, bid.contract_count)
|
||||
|
@ -1842,7 +1863,7 @@ class BasicSwap(BaseApp):
|
|||
script = bid.initiate_tx.script
|
||||
else:
|
||||
if offer.lock_type < ABS_LOCK_BLOCKS:
|
||||
sequence = getExpectedSequence(offer.lock_type, offer.lock_value, coin_from)
|
||||
sequence = ci_from.getExpectedSequence(offer.lock_type, offer.lock_value)
|
||||
script = atomic_swap_1.buildContractScript(sequence, secret_hash, bid.pkhash_buyer, pkhash_refund)
|
||||
else:
|
||||
if offer.lock_type == ABS_LOCK_BLOCKS:
|
||||
|
@ -1907,7 +1928,7 @@ class BasicSwap(BaseApp):
|
|||
def postXmrBid(self, offer_id, amount, addr_send_from=None):
|
||||
# Bid to send bid.amount * offer.rate of coin_to in exchange for bid.amount of coin_from
|
||||
# Send MSG1L F -> L
|
||||
self.log.debug('postXmrBid %s %s', offer_id.hex(), format8(amount))
|
||||
self.log.debug('postXmrBid %s', offer_id.hex())
|
||||
|
||||
self.mxDB.acquire()
|
||||
try:
|
||||
|
@ -2187,13 +2208,14 @@ class BasicSwap(BaseApp):
|
|||
def createInitiateTxn(self, coin_type, bid_id, bid, initiate_script):
|
||||
if self.coin_clients[coin_type]['connection_type'] != 'rpc':
|
||||
return None
|
||||
ci = self.ci(coin_type)
|
||||
|
||||
if self.coin_clients[coin_type]['use_segwit']:
|
||||
addr_to = self.encodeSegwitP2WSH(coin_type, getP2WSH(initiate_script))
|
||||
else:
|
||||
addr_to = self.getScriptAddress(coin_type, initiate_script)
|
||||
self.log.debug('Create initiate txn for coin %s to %s for bid %s', str(coin_type), addr_to, bid_id.hex())
|
||||
txn = self.callcoinrpc(coin_type, 'createrawtransaction', [[], {addr_to: format8(bid.amount)}])
|
||||
txn = self.callcoinrpc(coin_type, 'createrawtransaction', [[], {addr_to: ci.format_amount(bid.amount)}])
|
||||
|
||||
options = {
|
||||
'lockUnspents': True,
|
||||
|
@ -2207,6 +2229,7 @@ class BasicSwap(BaseApp):
|
|||
self.log.debug('deriveParticipateScript for bid %s', bid_id.hex())
|
||||
|
||||
coin_to = Coins(offer.coin_to)
|
||||
ci_to = self.ci(coin_to)
|
||||
|
||||
bid_date = dt.datetime.fromtimestamp(bid.created_at).date()
|
||||
|
||||
|
@ -2217,7 +2240,7 @@ class BasicSwap(BaseApp):
|
|||
# Participate txn is locked for half the time of the initiate txn
|
||||
lock_value = offer.lock_value // 2
|
||||
if offer.lock_type < ABS_LOCK_BLOCKS:
|
||||
sequence = getExpectedSequence(offer.lock_type, lock_value, coin_to)
|
||||
sequence = ci_to.getExpectedSequence(offer.lock_type, lock_value)
|
||||
participate_script = atomic_swap_1.buildContractScript(sequence, secret_hash, pkhash_seller, pkhash_buyer_refund)
|
||||
else:
|
||||
# Lock from the height or time of the block containing the initiate txn
|
||||
|
@ -2259,6 +2282,7 @@ class BasicSwap(BaseApp):
|
|||
|
||||
if self.coin_clients[coin_to]['connection_type'] != 'rpc':
|
||||
return None
|
||||
ci = self.ci(coin_to)
|
||||
|
||||
amount_to = bid.amount_to
|
||||
# Check required?
|
||||
|
@ -2275,7 +2299,7 @@ class BasicSwap(BaseApp):
|
|||
else:
|
||||
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: ci.format_amount(amount_to)}])
|
||||
options = {
|
||||
'lockUnspents': True,
|
||||
'conf_target': self.coin_clients[coin_to]['conf_target'],
|
||||
|
@ -2311,6 +2335,7 @@ class BasicSwap(BaseApp):
|
|||
|
||||
def createRedeemTxn(self, coin_type, bid, for_txn_type='participate', addr_redeem_out=None, fee_rate=None):
|
||||
self.log.debug('createRedeemTxn for coin %s', str(coin_type))
|
||||
ci = self.ci(coin_type)
|
||||
|
||||
if for_txn_type == 'participate':
|
||||
prev_txnid = bid.participate_tx.txid.hex()
|
||||
|
@ -2334,7 +2359,7 @@ class BasicSwap(BaseApp):
|
|||
'vout': prev_n,
|
||||
'scriptPubKey': script_pub_key,
|
||||
'redeemScript': txn_script.hex(),
|
||||
'amount': format8(prev_amount)}
|
||||
'amount': ci.format_amount(prev_amount)}
|
||||
|
||||
bid_date = dt.datetime.fromtimestamp(bid.created_at).date()
|
||||
wif_prefix = chainparams[Coins.PART][self.chain]['key_prefix']
|
||||
|
@ -2357,7 +2382,6 @@ class BasicSwap(BaseApp):
|
|||
tx_vsize = self.getContractSpendTxVSize(coin_type)
|
||||
tx_fee = (fee_rate * tx_vsize) / 1000
|
||||
|
||||
ci = self.ci(coin_type)
|
||||
self.log.debug('Redeem tx fee %s, rate %s', ci.format_amount(tx_fee, conv_int=True, r=1), str(fee_rate))
|
||||
|
||||
amount_out = prev_amount - ci.make_int(tx_fee, r=1)
|
||||
|
@ -2373,7 +2397,7 @@ class BasicSwap(BaseApp):
|
|||
else:
|
||||
addr_redeem_out = replaceAddrPrefix(addr_redeem_out, Coins.PART, self.chain)
|
||||
self.log.debug('addr_redeem_out %s', addr_redeem_out)
|
||||
output_to = ' outaddr={}:{}'.format(format8(amount_out), addr_redeem_out)
|
||||
output_to = ' outaddr={}:{}'.format(ci.format_amount(amount_out), addr_redeem_out)
|
||||
if coin_type == Coins.PART:
|
||||
redeem_txn = self.calltx('-create' + prevout_s + output_to)
|
||||
else:
|
||||
|
@ -2471,7 +2495,7 @@ class BasicSwap(BaseApp):
|
|||
addr_refund_out = replaceAddrPrefix(addr_refund_out, Coins.PART, self.chain)
|
||||
self.log.debug('addr_refund_out %s', addr_refund_out)
|
||||
|
||||
output_to = ' outaddr={}:{}'.format(format8(amount_out), addr_refund_out)
|
||||
output_to = ' outaddr={}:{}'.format(ci.format_amount(amount_out), addr_refund_out)
|
||||
if coin_type == Coins.PART:
|
||||
refund_txn = self.calltx('-create' + prevout_s + output_to)
|
||||
else:
|
||||
|
@ -2700,8 +2724,8 @@ class BasicSwap(BaseApp):
|
|||
refund_tx = bid.txns[TxTypes.XMR_SWAP_A_LOCK_REFUND]
|
||||
if bid.was_received:
|
||||
if bid.debug_ind == DebugTypes.BID_DONT_SPEND_COIN_A_LOCK_REFUND:
|
||||
self.log.debug('XMR bid %s: Abandoning bid for testing: %d.', bid_id.hex(), bid.debug_ind)
|
||||
bid.setState(BidStates.BID_ABANDONED)
|
||||
self.log.debug('XMR bid %s: Stalling bid for testing: %d.', bid_id.hex(), bid.debug_ind)
|
||||
bid.setState(BidStates.BID_STALLED_FOR_TEST)
|
||||
rv = True
|
||||
self.saveBidInSession(bid_id, bid, session, xmr_swap)
|
||||
self.logBidEvent(bid, EventLogTypes.DEBUG_TWEAK_APPLIED, 'ind {}'.format(bid.debug_ind), session)
|
||||
|
@ -2799,7 +2823,6 @@ class BasicSwap(BaseApp):
|
|||
bid_changed = False
|
||||
a_lock_tx_dest = ci_from.getScriptDest(xmr_swap.a_lock_tx_script)
|
||||
utxos, chain_height = ci_from.getOutput(bid.xmr_a_lock_tx.txid, a_lock_tx_dest, bid.amount)
|
||||
self.coin_clients[ci_from.coin_type()]['last_height'] = chain_height
|
||||
|
||||
if len(utxos) < 1:
|
||||
return rv
|
||||
|
@ -2869,7 +2892,6 @@ class BasicSwap(BaseApp):
|
|||
|
||||
if bid.xmr_b_lock_tx and bid.xmr_b_lock_tx.chain_height is not None and bid.xmr_b_lock_tx.chain_height > 0:
|
||||
chain_height = ci_to.getChainHeight()
|
||||
self.coin_clients[ci_to.coin_type()]['last_height'] = chain_height
|
||||
|
||||
if chain_height - bid.xmr_b_lock_tx.chain_height >= ci_to.blocks_confirmed:
|
||||
self.logBidEvent(bid, EventLogTypes.LOCK_TX_B_CONFIRMED, '', session)
|
||||
|
@ -3476,7 +3498,9 @@ class BasicSwap(BaseApp):
|
|||
# Validate data
|
||||
now = int(time.time())
|
||||
coin_from = Coins(offer_data.coin_from)
|
||||
ci_from = self.ci(coin_from)
|
||||
coin_to = Coins(offer_data.coin_to)
|
||||
ci_to = self.ci(coin_to)
|
||||
chain_from = chainparams[coin_from][self.chain]
|
||||
assert(offer_data.coin_from != offer_data.coin_to), 'coin_from == coin_to'
|
||||
|
||||
|
@ -3536,8 +3560,8 @@ class BasicSwap(BaseApp):
|
|||
xmr_offer = XmrOffer()
|
||||
|
||||
xmr_offer.offer_id = offer_id
|
||||
xmr_offer.lock_time_1 = getExpectedSequence(offer_data.lock_type, offer_data.lock_value, coin_from)
|
||||
xmr_offer.lock_time_2 = getExpectedSequence(offer_data.lock_type, offer_data.lock_value, coin_from)
|
||||
xmr_offer.lock_time_1 = ci_from.getExpectedSequence(offer_data.lock_type, offer_data.lock_value)
|
||||
xmr_offer.lock_time_2 = ci_from.getExpectedSequence(offer_data.lock_type, offer_data.lock_value)
|
||||
|
||||
xmr_offer.a_fee_rate = offer_data.fee_rate_from
|
||||
xmr_offer.b_fee_rate = offer_data.fee_rate_to
|
||||
|
@ -3705,6 +3729,7 @@ class BasicSwap(BaseApp):
|
|||
assert(bid is not None and bid.was_sent is True), 'Unknown bidid'
|
||||
assert(offer), 'Offer not found ' + bid.offer_id.hex()
|
||||
coin_from = Coins(offer.coin_from)
|
||||
ci_from = self.ci(coin_from)
|
||||
|
||||
assert(bid.expire_at > now + self._bid_expired_leeway), 'Bid expired'
|
||||
|
||||
|
@ -3730,7 +3755,7 @@ class BasicSwap(BaseApp):
|
|||
|
||||
script_lock_value = int(scriptvalues[2])
|
||||
if use_csv:
|
||||
expect_sequence = getExpectedSequence(offer.lock_type, offer.lock_value, coin_from)
|
||||
expect_sequence = ci_from.getExpectedSequence(offer.lock_type, offer.lock_value)
|
||||
assert(script_lock_value == expect_sequence), 'sequence mismatch'
|
||||
else:
|
||||
if offer.lock_type == ABS_LOCK_BLOCKS:
|
||||
|
@ -3803,7 +3828,7 @@ class BasicSwap(BaseApp):
|
|||
if self.countAcceptedBids(bid.offer_id) > 0:
|
||||
self.log.info('Not auto accepting bid %s, already have', bid.bid_id.hex())
|
||||
elif bid.amount != offer.amount_from:
|
||||
self.log.info('Not auto accepting bid %s, want exact amount match', bid_id.hex())
|
||||
self.log.info('Not auto accepting bid %s, want exact amount match', bid.bid_id.hex())
|
||||
else:
|
||||
delay = random.randrange(self.min_delay_event, self.max_delay_event)
|
||||
self.log.info('Auto accepting xmr bid %s in %d seconds', bid.bid_id.hex(), delay)
|
||||
|
@ -4155,8 +4180,8 @@ class BasicSwap(BaseApp):
|
|||
ci_to = self.ci(coin_to)
|
||||
|
||||
if bid.debug_ind == DebugTypes.BID_STOP_AFTER_COIN_A_LOCK:
|
||||
self.log.debug('XMR bid %s: Abandoning bid for testing: %d.', bid_id.hex(), bid.debug_ind)
|
||||
bid.setState(BidStates.BID_ABANDONED)
|
||||
self.log.debug('XMR bid %s: Stalling bid for testing: %d.', bid_id.hex(), bid.debug_ind)
|
||||
bid.setState(BidStates.BID_STALLED_FOR_TEST)
|
||||
self.saveBidInSession(bid_id, bid, session, xmr_swap, save_in_progress=offer)
|
||||
self.logBidEvent(bid, EventLogTypes.DEBUG_TWEAK_APPLIED, 'ind {}'.format(bid.debug_ind), session)
|
||||
return
|
||||
|
@ -4890,7 +4915,8 @@ class BasicSwap(BaseApp):
|
|||
now = int(time.time())
|
||||
session = scoped_session(self.session_factory)
|
||||
|
||||
query_str = 'SELECT bids.created_at, bids.bid_id, bids.offer_id, bids.amount, bids.state, bids.was_received, tx1.state, tx2.state FROM bids ' + \
|
||||
query_str = 'SELECT bids.created_at, bids.bid_id, bids.offer_id, bids.amount, bids.state, bids.was_received, tx1.state, tx2.state, offers.coin_from FROM bids ' + \
|
||||
'LEFT JOIN offers ON offers.offer_id = bids.offer_id ' + \
|
||||
'LEFT JOIN transactions AS tx1 ON tx1.bid_id = bids.bid_id AND tx1.tx_type = {} '.format(TxTypes.ITX) + \
|
||||
'LEFT JOIN transactions AS tx2 ON tx2.bid_id = bids.bid_id AND tx2.tx_type = {} '.format(TxTypes.PTX)
|
||||
|
||||
|
|
|
@ -10,28 +10,29 @@ CONFIG_FILENAME = 'basicswap.json'
|
|||
DEFAULT_DATADIR = '~/.basicswap'
|
||||
DEFAULT_ALLOW_CORS = False
|
||||
TEST_DATADIRS = os.path.expanduser(os.getenv('DATADIRS', '/tmp/basicswap'))
|
||||
DEFAULT_TEST_BINDIR = os.path.expanduser(os.getenv('DEFAULT_TEST_BINDIR', '~/tmp/bin'))
|
||||
|
||||
bin_suffix = ('.exe' if os.name == 'nt' else '')
|
||||
PARTICL_BINDIR = os.path.expanduser(os.getenv('PARTICL_BINDIR', ''))
|
||||
PARTICL_BINDIR = os.path.expanduser(os.getenv('PARTICL_BINDIR', os.path.join(DEFAULT_TEST_BINDIR, 'particl')))
|
||||
PARTICLD = os.getenv('PARTICLD', 'particld' + bin_suffix)
|
||||
PARTICL_CLI = os.getenv('PARTICL_CLI', 'particl-cli' + bin_suffix)
|
||||
PARTICL_TX = os.getenv('PARTICL_TX', 'particl-tx' + bin_suffix)
|
||||
|
||||
BITCOIN_BINDIR = os.path.expanduser(os.getenv('BITCOIN_BINDIR', ''))
|
||||
BITCOIN_BINDIR = os.path.expanduser(os.getenv('BITCOIN_BINDIR', os.path.join(DEFAULT_TEST_BINDIR, 'bitcoin')))
|
||||
BITCOIND = os.getenv('BITCOIND', 'bitcoind' + bin_suffix)
|
||||
BITCOIN_CLI = os.getenv('BITCOIN_CLI', 'bitcoin-cli' + bin_suffix)
|
||||
BITCOIN_TX = os.getenv('BITCOIN_TX', 'bitcoin-tx' + bin_suffix)
|
||||
|
||||
LITECOIN_BINDIR = os.path.expanduser(os.getenv('LITECOIN_BINDIR', ''))
|
||||
LITECOIN_BINDIR = os.path.expanduser(os.getenv('LITECOIN_BINDIR', os.path.join(DEFAULT_TEST_BINDIR, 'litecoin')))
|
||||
LITECOIND = os.getenv('LITECOIND', 'litecoind' + bin_suffix)
|
||||
LITECOIN_CLI = os.getenv('LITECOIN_CLI', 'litecoin-cli' + bin_suffix)
|
||||
LITECOIN_TX = os.getenv('LITECOIN_TX', 'litecoin-tx' + bin_suffix)
|
||||
|
||||
NAMECOIN_BINDIR = os.path.expanduser(os.getenv('NAMECOIN_BINDIR', ''))
|
||||
NAMECOIN_BINDIR = os.path.expanduser(os.getenv('NAMECOIN_BINDIR', os.path.join(DEFAULT_TEST_BINDIR, 'namecoin')))
|
||||
NAMECOIND = os.getenv('NAMECOIND', 'namecoind' + bin_suffix)
|
||||
NAMECOIN_CLI = os.getenv('NAMECOIN_CLI', 'namecoin-cli' + bin_suffix)
|
||||
NAMECOIN_TX = os.getenv('NAMECOIN_TX', 'namecoin-tx' + bin_suffix)
|
||||
|
||||
XMR_BINDIR = os.path.expanduser(os.getenv('XMR_BINDIR', ''))
|
||||
XMR_BINDIR = os.path.expanduser(os.getenv('XMR_BINDIR', os.path.join(DEFAULT_TEST_BINDIR, 'monero')))
|
||||
XMRD = os.getenv('XMRD', 'monerod' + bin_suffix)
|
||||
XMR_WALLET_RPC = os.getenv('XMR_WALLET_RPC', 'monero-wallet-rpc' + bin_suffix)
|
||||
|
|
|
@ -62,10 +62,19 @@ from .contrib.test_framework.script import (
|
|||
SegwitV0SignatureHash,
|
||||
hash160)
|
||||
|
||||
from .types import (
|
||||
SEQUENCE_LOCK_BLOCKS,
|
||||
SEQUENCE_LOCK_TIME)
|
||||
|
||||
from .chainparams import CoinInterface, Coins, chainparams
|
||||
from .rpc import make_rpc_func
|
||||
|
||||
|
||||
SEQUENCE_LOCKTIME_GRANULARITY = 9 # 512 seconds
|
||||
SEQUENCE_LOCKTIME_TYPE_FLAG = (1 << 22)
|
||||
SEQUENCE_LOCKTIME_MASK = 0x0000ffff
|
||||
|
||||
|
||||
def findOutput(tx, script_pk):
|
||||
for i in range(len(tx.vout)):
|
||||
if tx.vout[i].scriptPubKey == script_pk:
|
||||
|
@ -121,6 +130,27 @@ class BTCInterface(CoinInterface):
|
|||
def txoType():
|
||||
return CTxOut
|
||||
|
||||
@staticmethod
|
||||
def getExpectedSequence(lockType, lockVal):
|
||||
assert(lockVal >= 1), 'Bad lockVal'
|
||||
if lockType == SEQUENCE_LOCK_BLOCKS:
|
||||
return lockVal
|
||||
if lockType == SEQUENCE_LOCK_TIME:
|
||||
secondsLocked = lockVal
|
||||
# Ensure the locked time is never less than lockVal
|
||||
if secondsLocked % (1 << SEQUENCE_LOCKTIME_GRANULARITY) != 0:
|
||||
secondsLocked += (1 << SEQUENCE_LOCKTIME_GRANULARITY)
|
||||
secondsLocked >>= SEQUENCE_LOCKTIME_GRANULARITY
|
||||
return secondsLocked | SEQUENCE_LOCKTIME_TYPE_FLAG
|
||||
raise ValueError('Unknown lock type')
|
||||
|
||||
@staticmethod
|
||||
def decodeSequence(lock_value):
|
||||
# Return the raw value
|
||||
if lock_value & SEQUENCE_LOCKTIME_TYPE_FLAG:
|
||||
return (lock_value & SEQUENCE_LOCKTIME_MASK) << SEQUENCE_LOCKTIME_GRANULARITY
|
||||
return lock_value & SEQUENCE_LOCKTIME_MASK
|
||||
|
||||
def __init__(self, coin_settings, network, swap_client=None):
|
||||
super().__init__()
|
||||
rpc_host = coin_settings.get('rpchost', '127.0.0.1')
|
||||
|
@ -129,7 +159,7 @@ class BTCInterface(CoinInterface):
|
|||
self.blocks_confirmed = coin_settings['blocks_confirmed']
|
||||
self.setConfTarget(coin_settings['conf_target'])
|
||||
self._sc = swap_client
|
||||
self._log = self._sc.log if self._sc.log else logging
|
||||
self._log = self._sc.log if self._sc and self._sc.log else logging
|
||||
|
||||
def setConfTarget(self, new_conf_target):
|
||||
assert(new_conf_target >= 1 and new_conf_target < 33), 'Invalid conf_target value'
|
||||
|
@ -154,6 +184,9 @@ class BTCInterface(CoinInterface):
|
|||
block_hash = self.rpc_callback('getblockhash', [height])
|
||||
return self.rpc_callback('getblockheader', [block_hash])
|
||||
|
||||
def getBlockHeader(self, block_hash):
|
||||
return self.rpc_callback('getblockheader', [block_hash])
|
||||
|
||||
def initialiseWallet(self, key_bytes):
|
||||
wif_prefix = chainparams[self.coin_type()][self._network]['key_prefix']
|
||||
key_wif = toWIF(wif_prefix, key_bytes)
|
||||
|
@ -363,7 +396,7 @@ class BTCInterface(CoinInterface):
|
|||
tx.vout.append(self.txoType()(locked_coin, self.getScriptForPubkeyHash(pkh_refund_to)))
|
||||
|
||||
witness_bytes = len(script_lock_refund)
|
||||
witness_bytes += 73 * 2 # 2 signatures (72 + 1 byte size)
|
||||
witness_bytes += 74 * 2 # 2 signatures (72 + 1 byte sighashtype + 1 byte size) - Use maximum txn size for estimate
|
||||
witness_bytes += 4 # 1 empty, 1 true witness stack values
|
||||
witness_bytes += getCompactSizeLen(witness_bytes)
|
||||
vsize = self.getTxVSize(tx, add_witness_bytes=witness_bytes)
|
||||
|
@ -398,7 +431,7 @@ class BTCInterface(CoinInterface):
|
|||
tx.vout.append(self.txoType()(locked_coin, self.getScriptForPubkeyHash(pkh_dest)))
|
||||
|
||||
witness_bytes = len(script_lock_refund)
|
||||
witness_bytes += 73 # signature (72 + 1 byte size)
|
||||
witness_bytes += 74 # 2 signatures (72 + 1 byte sighashtype + 1 byte size) - Use maximum txn size for estimate
|
||||
witness_bytes += 1 # 1 empty stack value
|
||||
witness_bytes += getCompactSizeLen(witness_bytes)
|
||||
vsize = self.getTxVSize(tx, add_witness_bytes=witness_bytes)
|
||||
|
@ -429,7 +462,7 @@ class BTCInterface(CoinInterface):
|
|||
|
||||
witness_bytes = len(script_lock)
|
||||
witness_bytes += 33 # sv, size
|
||||
witness_bytes += 73 * 2 # 2 signatures (72 + 1 byte size)
|
||||
witness_bytes += 74 * 2 # 2 signatures (72 + 1 byte sighashtype + 1 byte size) - Use maximum txn size for estimate
|
||||
witness_bytes += 4 # 1 empty, 1 true witness stack values
|
||||
witness_bytes += getCompactSizeLen(witness_bytes)
|
||||
vsize = self.getTxVSize(tx, add_witness_bytes=witness_bytes)
|
||||
|
@ -546,7 +579,7 @@ class BTCInterface(CoinInterface):
|
|||
assert(fee_paid > 0)
|
||||
|
||||
witness_bytes = len(prevout_script)
|
||||
witness_bytes += 73 * 2 # 2 signatures (72 + 1 byts size)
|
||||
witness_bytes += 74 * 2 # 2 signatures (72 + 1 byte sighashtype + 1 byte size) - Use maximum txn size for estimate
|
||||
witness_bytes += 2 # 2 empty witness stack values
|
||||
witness_bytes += getCompactSizeLen(witness_bytes)
|
||||
vsize = self.getTxVSize(tx, add_witness_bytes=witness_bytes)
|
||||
|
@ -555,7 +588,7 @@ class BTCInterface(CoinInterface):
|
|||
self._log.info('tx amount, vsize, feerate: %ld, %ld, %ld', locked_coin, vsize, fee_rate_paid)
|
||||
|
||||
if not self.compareFeeRates(fee_rate_paid, feerate):
|
||||
raise ValueError('Bad fee rate')
|
||||
raise ValueError('Bad fee rate, expected: {}'.format(feerate))
|
||||
|
||||
return tx_hash, locked_coin
|
||||
|
||||
|
@ -592,7 +625,7 @@ class BTCInterface(CoinInterface):
|
|||
assert(fee_paid > 0)
|
||||
|
||||
witness_bytes = len(prevout_script)
|
||||
witness_bytes += 73 * 2 # 2 signatures (72 + 1 byts size)
|
||||
witness_bytes += 74 * 2 # 2 signatures (72 + 1 byte sighashtype + 1 byte size) - Use maximum txn size for estimate
|
||||
witness_bytes += 4 # 1 empty, 1 true witness stack values
|
||||
witness_bytes += getCompactSizeLen(witness_bytes)
|
||||
vsize = self.getTxVSize(tx, add_witness_bytes=witness_bytes)
|
||||
|
@ -601,7 +634,7 @@ class BTCInterface(CoinInterface):
|
|||
self._log.info('tx amount, vsize, feerate: %ld, %ld, %ld', tx_value, vsize, fee_rate_paid)
|
||||
|
||||
if not self.compareFeeRates(fee_rate_paid, feerate):
|
||||
raise ValueError('Bad fee rate')
|
||||
raise ValueError('Bad fee rate, expected: {}'.format(feerate))
|
||||
|
||||
return True
|
||||
|
||||
|
@ -641,7 +674,7 @@ class BTCInterface(CoinInterface):
|
|||
|
||||
witness_bytes = len(lock_tx_script)
|
||||
witness_bytes += 33 # sv, size
|
||||
witness_bytes += 73 * 2 # 2 signatures (72 + 1 byts size)
|
||||
witness_bytes += 74 * 2 # 2 signatures (72 + 1 byte sighashtype + 1 byte size) - Use maximum txn size for estimate
|
||||
witness_bytes += 4 # 1 empty, 1 true witness stack values
|
||||
witness_bytes += getCompactSizeLen(witness_bytes)
|
||||
vsize = self.getTxVSize(tx, add_witness_bytes=witness_bytes)
|
||||
|
@ -650,7 +683,7 @@ class BTCInterface(CoinInterface):
|
|||
self._log.info('tx amount, vsize, feerate: %ld, %ld, %ld', tx.vout[0].nValue, vsize, fee_rate_paid)
|
||||
|
||||
if not self.compareFeeRates(fee_rate_paid, feerate):
|
||||
raise ValueError('Bad fee rate')
|
||||
raise ValueError('Bad fee rate, expected: {}'.format(feerate))
|
||||
|
||||
return True
|
||||
|
||||
|
|
|
@ -69,7 +69,7 @@ class XMRInterface(CoinInterface):
|
|||
self._restore_height = coin_settings.get('restore_height', 0)
|
||||
self.setFeePriority(coin_settings.get('fee_priority', 0))
|
||||
self._sc = swap_client
|
||||
self._log = self._sc.log if self._sc.log else logging
|
||||
self._log = self._sc.log if self._sc and self._sc.log else logging
|
||||
|
||||
def setFeePriority(self, new_priority):
|
||||
assert(new_priority >= 0 and new_priority < 4), 'Invalid fee_priority value'
|
||||
|
|
|
@ -8,7 +8,6 @@ import json
|
|||
import urllib.parse
|
||||
|
||||
from .util import (
|
||||
format8,
|
||||
format_timestamp,
|
||||
)
|
||||
from .basicswap import (
|
||||
|
@ -174,7 +173,8 @@ def js_bids(self, url_split, post_string, is_json):
|
|||
'bid_id': b[1].hex(),
|
||||
'offer_id': b[2].hex(),
|
||||
'created_at': format_timestamp(b[0]),
|
||||
'amount_from': format8(b[3]),
|
||||
'coin_from': b[8],
|
||||
'amount_from': swap_client.ci(b[8]).format_amount(b[3]),
|
||||
'bid_state': strBidState(b[4])
|
||||
} for b in bids]), 'UTF-8')
|
||||
|
||||
|
|
|
@ -23,6 +23,11 @@
|
|||
<tr><td>Expired At</td><td>{{ data.expired_at }}</td></tr>
|
||||
<tr><td>Sent</td><td>{{ data.was_sent }}</td></tr>
|
||||
<tr><td>Received</td><td>{{ data.was_received }}</td></tr>
|
||||
{% if data.coin_a_lock_refund_tx_est_final != 'None' %}
|
||||
<tr><td>{{ data.ticker_from }} lock refund tx valid at</td><td>{{ data.coin_a_lock_refund_tx_est_final | formatts }}</td></tr>
|
||||
<tr><td>{{ data.ticker_from }} chain median time</td><td>{{ data.coin_a_last_median_time | formatts }}</td></tr>
|
||||
{% endif %}
|
||||
|
||||
</table>
|
||||
|
||||
<form method="post">
|
||||
|
|
10
basicswap/types.py
Normal file
10
basicswap/types.py
Normal file
|
@ -0,0 +1,10 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright (c) 2021 tecnovert
|
||||
# Distributed under the MIT software license, see the accompanying
|
||||
# file LICENSE or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
SEQUENCE_LOCK_BLOCKS = 1
|
||||
SEQUENCE_LOCK_TIME = 2
|
||||
ABS_LOCK_BLOCKS = 3
|
||||
ABS_LOCK_TIME = 4
|
|
@ -20,6 +20,9 @@ from .basicswap import (
|
|||
strBidState,
|
||||
strTxState,
|
||||
)
|
||||
from .types import (
|
||||
SEQUENCE_LOCK_TIME,
|
||||
)
|
||||
|
||||
PAGE_LIMIT = 50
|
||||
|
||||
|
@ -186,15 +189,15 @@ def describeBid(swap_client, bid, xmr_swap, offer, xmr_offer, bid_events, edit_b
|
|||
txns = []
|
||||
if bid.xmr_a_lock_tx:
|
||||
confirms = None
|
||||
if swap_client.coin_clients[ci_from.coin_type()]['last_height'] and bid.xmr_a_lock_tx.chain_height:
|
||||
confirms = (swap_client.coin_clients[ci_from.coin_type()]['last_height'] - bid.xmr_a_lock_tx.chain_height) + 1
|
||||
if swap_client.coin_clients[ci_from.coin_type()]['chain_height'] and bid.xmr_a_lock_tx.chain_height:
|
||||
confirms = (swap_client.coin_clients[ci_from.coin_type()]['chain_height'] - bid.xmr_a_lock_tx.chain_height) + 1
|
||||
txns.append({'type': 'Chain A Lock', 'txid': bid.xmr_a_lock_tx.txid.hex(), 'confirms': confirms})
|
||||
if bid.xmr_a_lock_spend_tx:
|
||||
txns.append({'type': 'Chain A Lock Spend', 'txid': bid.xmr_a_lock_spend_tx.txid.hex()})
|
||||
if bid.xmr_b_lock_tx:
|
||||
confirms = None
|
||||
if swap_client.coin_clients[ci_to.coin_type()]['last_height'] and bid.xmr_b_lock_tx.chain_height:
|
||||
confirms = (swap_client.coin_clients[ci_to.coin_type()]['last_height'] - bid.xmr_b_lock_tx.chain_height) + 1
|
||||
if swap_client.coin_clients[ci_to.coin_type()]['chain_height'] and bid.xmr_b_lock_tx.chain_height:
|
||||
confirms = (swap_client.coin_clients[ci_to.coin_type()]['chain_height'] - bid.xmr_b_lock_tx.chain_height) + 1
|
||||
txns.append({'type': 'Chain B Lock', 'txid': bid.xmr_b_lock_tx.txid.hex(), 'confirms': confirms})
|
||||
if bid.xmr_b_lock_tx and bid.xmr_b_lock_tx.spend_txid:
|
||||
txns.append({'type': 'Chain B Lock Spend', 'txid': bid.xmr_b_lock_tx.spend_txid.hex()})
|
||||
|
@ -214,6 +217,15 @@ def describeBid(swap_client, bid, xmr_swap, offer, xmr_offer, bid_events, edit_b
|
|||
data['participate_tx_spend'] = getTxSpendHex(bid, TxTypes.PTX)
|
||||
|
||||
if offer.swap_type == SwapTypes.XMR_SWAP:
|
||||
|
||||
data['coin_a_lock_refund_tx_est_final'] = 'None'
|
||||
if bid.xmr_a_lock_tx and bid.xmr_a_lock_tx.block_time:
|
||||
if offer.lock_type == SEQUENCE_LOCK_TIME:
|
||||
raw_sequence = ci_from.getExpectedSequence(offer.lock_type, offer.lock_value)
|
||||
seconds_locked = ci_from.decodeSequence(raw_sequence)
|
||||
data['coin_a_lock_refund_tx_est_final'] = bid.xmr_a_lock_tx.block_time + seconds_locked
|
||||
data['coin_a_last_median_time'] = swap_client.coin_clients[offer.coin_from]['chain_median_time']
|
||||
|
||||
if view_tx_ind:
|
||||
data['view_tx_ind'] = view_tx_ind
|
||||
view_tx_id = bytes.fromhex(view_tx_ind)
|
||||
|
|
|
@ -27,16 +27,6 @@ def assert_cond(v, err='Bad opcode'):
|
|||
raise ValueError(err)
|
||||
|
||||
|
||||
def format8(i):
|
||||
n = abs(i)
|
||||
quotient = n // COIN
|
||||
remainder = n % COIN
|
||||
rv = "%d.%08d" % (quotient, remainder)
|
||||
if i < 0:
|
||||
rv = '-' + rv
|
||||
return rv
|
||||
|
||||
|
||||
def toBool(s):
|
||||
return s.lower() in ["1", "true"]
|
||||
|
||||
|
|
|
@ -205,7 +205,7 @@ def prepareCore(coin, version, settings, data_dir):
|
|||
assert_url = 'https://raw.githubusercontent.com/tecnovert/gitian.sigs/master/%s-%s/%s/%s' % (version, os_dir_name, signing_key_name, assert_filename)
|
||||
elif coin == 'litecoin':
|
||||
signing_key_name = 'thrasher'
|
||||
release_url = 'https://download.litecoin.org/litecoin-{}/{}/{}'.format(version, os_name, release_filename)
|
||||
release_url = 'https://download2.litecoin.org/litecoin-{}/{}/{}'.format(version, os_name, release_filename)
|
||||
assert_filename = '{}-{}-{}-build.assert'.format(coin, os_name, version.rsplit('.', 1)[0])
|
||||
assert_url = 'https://raw.githubusercontent.com/litecoin-project/gitian.sigs.ltc/master/%s-%s/%s/%s' % (version, os_dir_name, signing_key_name, assert_filename)
|
||||
elif coin == 'bitcoin':
|
||||
|
|
|
@ -30,10 +30,7 @@ from basicswap.util import (
|
|||
make_int,
|
||||
format_amount,
|
||||
validate_amount)
|
||||
from basicswap.basicswap import (
|
||||
Coins,
|
||||
getExpectedSequence,
|
||||
decodeSequence,
|
||||
from basicswap.types import (
|
||||
SEQUENCE_LOCK_BLOCKS,
|
||||
SEQUENCE_LOCK_TIME)
|
||||
|
||||
|
@ -57,21 +54,24 @@ class Test(unittest.TestCase):
|
|||
test_case(4194642)
|
||||
|
||||
def test_sequence(self):
|
||||
coin_settings = {'rpcport': 0, 'rpcauth': 'none', 'blocks_confirmed': 1, 'conf_target': 1}
|
||||
ci = BTCInterface(coin_settings, 'regtest')
|
||||
|
||||
time_val = 48 * 60 * 60
|
||||
encoded = getExpectedSequence(SEQUENCE_LOCK_TIME, time_val, Coins.PART)
|
||||
decoded = decodeSequence(encoded)
|
||||
encoded = ci.getExpectedSequence(SEQUENCE_LOCK_TIME, time_val)
|
||||
decoded = ci.decodeSequence(encoded)
|
||||
assert(decoded >= time_val)
|
||||
assert(decoded <= time_val + 512)
|
||||
|
||||
time_val = 24 * 60
|
||||
encoded = getExpectedSequence(SEQUENCE_LOCK_TIME, time_val, Coins.PART)
|
||||
decoded = decodeSequence(encoded)
|
||||
encoded = ci.getExpectedSequence(SEQUENCE_LOCK_TIME, time_val)
|
||||
decoded = ci.decodeSequence(encoded)
|
||||
assert(decoded >= time_val)
|
||||
assert(decoded <= time_val + 512)
|
||||
|
||||
blocks_val = 123
|
||||
encoded = getExpectedSequence(SEQUENCE_LOCK_BLOCKS, blocks_val, Coins.PART)
|
||||
decoded = decodeSequence(encoded)
|
||||
encoded = ci.getExpectedSequence(SEQUENCE_LOCK_BLOCKS, blocks_val)
|
||||
decoded = ci.decodeSequence(encoded)
|
||||
assert(decoded == blocks_val)
|
||||
|
||||
def test_make_int(self):
|
||||
|
|
|
@ -554,14 +554,14 @@ class Test(unittest.TestCase):
|
|||
|
||||
wait_for_bid(delay_event, swap_clients[0], bid_id)
|
||||
swap_clients[0].acceptBid(bid_id)
|
||||
swap_clients[0].coin_clients[Coins.BTC]['override_feerate'] = 10.0
|
||||
swap_clients[0].coin_clients[Coins.LTC]['override_feerate'] = 10.0
|
||||
swap_clients[0].getChainClientSettings(Coins.BTC)['override_feerate'] = 10.0
|
||||
swap_clients[0].getChainClientSettings(Coins.LTC)['override_feerate'] = 10.0
|
||||
|
||||
wait_for_bid(delay_event, swap_clients[0], bid_id, BidStates.BID_ERROR, wait_for=60)
|
||||
|
||||
swap_clients[0].abandonBid(bid_id)
|
||||
del swap_clients[0].coin_clients[Coins.BTC]['override_feerate']
|
||||
del swap_clients[0].coin_clients[Coins.LTC]['override_feerate']
|
||||
del swap_clients[0].getChainClientSettings(Coins.BTC)['override_feerate']
|
||||
del swap_clients[0].getChainClientSettings(Coins.LTC)['override_feerate']
|
||||
|
||||
def test_08_part_ltc_buyer_first(self):
|
||||
logging.info('---------- Test PART to LTC, buyer first')
|
||||
|
|
|
@ -515,7 +515,7 @@ class Test(unittest.TestCase):
|
|||
|
||||
swap_clients[0].acceptXmrBid(bid_id)
|
||||
|
||||
wait_for_bid(delay_event, swap_clients[0], bid_id, BidStates.BID_ABANDONED, wait_for=180)
|
||||
wait_for_bid(delay_event, swap_clients[0], bid_id, BidStates.BID_STALLED_FOR_TEST, wait_for=180)
|
||||
wait_for_bid(delay_event, swap_clients[1], bid_id, BidStates.XMR_SWAP_FAILED_SWIPED, wait_for=80, sent=True)
|
||||
|
||||
js_w0_after = json.loads(urlopen('http://127.0.0.1:1800/json/wallets').read())
|
||||
|
|
Loading…
Reference in a new issue