ui: Expose bid valid for.

Set smsgsregtestadjust to false in tests.
Fix offer smsg valid for.
Set active_ind on bid records.
api: All times returned should be in unix-time.
This commit is contained in:
tecnovert 2021-02-15 15:34:47 +02:00
parent 1953820cd1
commit 5beb1d17b9
No known key found for this signature in database
GPG key ID: 8ED6D8750C4E3F93
15 changed files with 145 additions and 73 deletions

View file

@ -100,12 +100,6 @@ import basicswap.network as bsn
import basicswap.protocols.atomic_swap_1 as atomic_swap_1
MIN_OFFER_VALID_TIME = 60 * 10
MAX_OFFER_VALID_TIME = 60 * 60 * 48
MIN_BID_VALID_TIME = 60 * 10
MAX_BID_VALID_TIME = 60 * 60 * 48
class MessageTypes(IntEnum):
OFFER = auto()
BID = auto()
@ -228,9 +222,6 @@ class DebugTypes(IntEnum):
MAKE_INVALID_PTX = auto()
INITIATE_TX_TIMEOUT = 40 * 60 # TODO: make variable per coin
def strOfferState(state):
if state == OfferStates.OFFER_SENT:
return 'Sent'
@ -477,7 +468,7 @@ class BasicSwap(BaseApp):
self.swaps_in_progress = dict()
self.SMSG_SECONDS_IN_HOUR = 60 * 2 if self.chain == 'regtest' else 60 * 60
self.SMSG_SECONDS_IN_HOUR = 60 * 60 # Note: Set smsgsregtestadjust=0 for regtest
self.delay_event = threading.Event()
self.threads = []
@ -1102,12 +1093,20 @@ class BasicSwap(BaseApp):
else:
raise ValueError('Unknown locktype')
def validateOfferValidTime(self, coin_from, coin_to, valid_for_seconds):
if valid_for_seconds < 60 * 60: # SMSG_MIN_TTL
def validateOfferValidTime(self, offer_type, coin_from, coin_to, valid_for_seconds):
# TODO: adjust
if valid_for_seconds < 10 * 60:
raise ValueError('Offer TTL too low')
if valid_for_seconds > 48 * 60 * 60:
raise ValueError('Offer TTL too high')
def validateBidValidTime(self, offer_type, coin_from, coin_to, valid_for_seconds):
# TODO: adjust
if valid_for_seconds < 10 * 60:
raise ValueError('Bid TTL too low')
if valid_for_seconds > 24 * 60 * 60:
raise ValueError('Bid TTL too high')
def postOffer(self, coin_from, coin_to, amount, rate, min_bid_amount, swap_type,
lock_type=SEQUENCE_LOCK_TIME, lock_value=48 * 60 * 60, auto_accept_bids=False, addr_send_from=None, extra_options={}):
# Offer to send offer.amount_from of coin_from in exchange for offer.amount_from * offer.rate of coin_to
@ -1129,7 +1128,7 @@ class BasicSwap(BaseApp):
self.validateSwapType(coin_from_t, coin_to_t, swap_type)
self.validateOfferAmounts(coin_from_t, coin_to_t, amount, rate, min_bid_amount)
self.validateOfferLockValue(coin_from_t, coin_to_t, lock_type, lock_value)
self.validateOfferValidTime(coin_from_t, coin_to_t, valid_for_seconds)
self.validateOfferValidTime(swap_type, coin_from_t, coin_to_t, valid_for_seconds)
self.mxDB.acquire()
session = None
@ -1196,7 +1195,7 @@ class BasicSwap(BaseApp):
self.callrpc('smsgaddlocaladdress', [offer_addr]) # Enable receiving smsg
options = {'decodehex': True, 'ttl_is_seconds': True}
msg_valid = self.SMSG_SECONDS_IN_HOUR * 1
msg_valid = max(self.SMSG_SECONDS_IN_HOUR * 1, valid_for_seconds)
ro = self.callrpc('smsgsend', [offer_addr, self.network_addr, payload_hex, False, msg_valid, False, options])
msg_id = ro['msgid']
@ -1725,13 +1724,16 @@ class BasicSwap(BaseApp):
assert(offer.expire_at > int(time.time())), 'Offer has expired'
if offer.swap_type == SwapTypes.XMR_SWAP:
return self.postXmrBid(offer_id, amount, addr_send_from)
return self.postXmrBid(offer_id, amount, addr_send_from, extra_options)
valid_for_seconds = extra_options.get('valid_for_seconds', 60 * 10)
self.validateBidValidTime(offer.swap_type, offer.coin_from, offer.coin_to, valid_for_seconds)
self.mxDB.acquire()
try:
msg_buf = BidMessage()
msg_buf.offer_msg_id = offer_id
msg_buf.time_valid = extra_options.get('time_valid', 60 * 10)
msg_buf.time_valid = valid_for_seconds
msg_buf.amount = int(amount) # amount of coin_from
coin_from = Coins(offer.coin_from)
@ -1762,12 +1764,13 @@ class BasicSwap(BaseApp):
bid_addr = addr_send_from
self.callrpc('smsgaddlocaladdress', [bid_addr]) # Enable receiving smsg
options = {'decodehex': True, 'ttl_is_seconds': True}
msg_valid = self.SMSG_SECONDS_IN_HOUR * 1
msg_valid = max(self.SMSG_SECONDS_IN_HOUR * 1, valid_for_seconds)
ro = self.callrpc('smsgsend', [bid_addr, offer.addr_from, payload_hex, False, msg_valid, False, options])
msg_id = ro['msgid']
bid_id = bytes.fromhex(msg_id)
bid = Bid(
active_ind=1,
bid_id=bid_id,
offer_id=offer_id,
amount=msg_buf.amount,
@ -2031,7 +2034,7 @@ class BasicSwap(BaseApp):
self.saveBid(bid_id, bid)
self.swaps_in_progress[bid_id] = (bid, offer)
def postXmrBid(self, offer_id, amount, addr_send_from=None):
def postXmrBid(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
# Send MSG1L F -> L
self.log.debug('postXmrBid %s', offer_id.hex())
@ -2044,6 +2047,9 @@ class BasicSwap(BaseApp):
assert(xmr_offer), 'XMR offer not found: {}.'.format(offer_id.hex())
assert(offer.expire_at > int(time.time())), 'Offer has expired'
valid_for_seconds = extra_options.get('valid_for_seconds', 60 * 10)
self.validateBidValidTime(offer.swap_type, offer.coin_from, offer.coin_to, valid_for_seconds)
coin_from = Coins(offer.coin_from)
coin_to = Coins(offer.coin_to)
ci_from = self.ci(coin_from)
@ -2053,7 +2059,7 @@ class BasicSwap(BaseApp):
msg_buf = XmrBidMessage()
msg_buf.offer_msg_id = offer_id
msg_buf.time_valid = 60 * 10
msg_buf.time_valid = valid_for_seconds
msg_buf.amount = int(amount) # Amount of coin_from
address_out = self.getReceiveAddressFromPool(coin_from, offer_id, TxTypes.XMR_SWAP_A_LOCK)
@ -2110,7 +2116,7 @@ class BasicSwap(BaseApp):
bid_addr = addr_send_from
self.callrpc('smsgaddlocaladdress', [bid_addr]) # Enable receiving smsg
options = {'decodehex': True, 'ttl_is_seconds': True}
msg_valid = self.SMSG_SECONDS_IN_HOUR * 1
msg_valid = max(self.SMSG_SECONDS_IN_HOUR * 1, valid_for_seconds)
ro = self.callrpc('smsgsend', [bid_addr, offer.addr_from, payload_hex, False, msg_valid, False, options])
xmr_swap.bid_id = bytes.fromhex(ro['msgid'])
@ -2138,6 +2144,7 @@ class BasicSwap(BaseApp):
xmr_swap.bid_msg_id3 = bytes.fromhex(ro['msgid'])
bid = Bid(
active_ind=1,
bid_id=xmr_swap.bid_id,
offer_id=offer_id,
amount=msg_buf.amount,
@ -3135,7 +3142,7 @@ class BasicSwap(BaseApp):
# Bid times out if buyer doesn't see tx in chain within INITIATE_TX_TIMEOUT seconds
if bid.initiate_tx is None and \
bid.state_time + INITIATE_TX_TIMEOUT < int(time.time()):
bid.state_time + atomic_swap_1.INITIATE_TX_TIMEOUT < int(time.time()):
self.log.info('Swap timed out waiting for initiate tx for bid %s', bid_id.hex())
bid.setState(BidStates.SWAP_TIMEDOUT, 'Timed out waiting for initiate tx')
self.saveBid(bid_id, bid)
@ -3630,9 +3637,8 @@ class BasicSwap(BaseApp):
self.validateSwapType(coin_from, coin_to, offer_data.swap_type)
self.validateOfferAmounts(coin_from, coin_to, offer_data.amount_from, offer_data.rate, offer_data.min_bid_amount)
self.validateOfferLockValue(coin_from, coin_to, offer_data.lock_type, offer_data.lock_value)
self.validateOfferValidTime(coin_from, coin_to, offer_data.time_valid)
self.validateOfferValidTime(offer_data.swap_type, coin_from, coin_to, offer_data.time_valid)
assert(offer_data.time_valid >= MIN_OFFER_VALID_TIME and offer_data.time_valid <= MAX_OFFER_VALID_TIME), 'Invalid time_valid'
assert(msg['sent'] + offer_data.time_valid >= now), 'Offer expired'
if offer_data.swap_type == SwapTypes.SELLER_FIRST:
@ -3752,17 +3758,17 @@ class BasicSwap(BaseApp):
# Validate data
assert(len(bid_data.offer_msg_id) == 28), 'Bad offer_id length'
assert(bid_data.time_valid >= MIN_BID_VALID_TIME and bid_data.time_valid <= MAX_BID_VALID_TIME), 'Invalid time_valid'
offer_id = bid_data.offer_msg_id
offer = self.getOffer(offer_id, sent=True)
assert(offer and offer.was_sent), 'Unknown offerid'
assert(offer and offer.was_sent), 'Unknown offer'
assert(offer.state == OfferStates.OFFER_RECEIVED), 'Bad offer state'
assert(msg['to'] == offer.addr_from), 'Received on incorrect address'
assert(now <= offer.expire_at), 'Offer expired'
assert(bid_data.amount >= offer.min_bid_amount), 'Bid amount below minimum'
assert(bid_data.amount <= offer.amount_from), 'Bid amount above offer amount'
self.validateBidValidTime(offer.swap_type, offer.coin_from, offer.coin_to, bid_data.time_valid)
assert(now <= msg['sent'] + bid_data.time_valid), 'Bid expired'
# TODO: Allow higher bids
@ -3800,6 +3806,7 @@ class BasicSwap(BaseApp):
bid = self.getBid(bid_id)
if bid is None:
bid = Bid(
active_ind=1,
bid_id=bid_id,
offer_id=offer_id,
amount=bid_data.amount,
@ -3885,7 +3892,7 @@ class BasicSwap(BaseApp):
if offer.lock_type == ABS_LOCK_BLOCKS:
self.log.warning('TODO: validate absolute lock values')
else:
assert(script_lock_value <= bid.created_at + offer.lock_value + INITIATE_TX_TIMEOUT), 'script lock time too high'
assert(script_lock_value <= bid.created_at + offer.lock_value + atomic_swap_1.INITIATE_TX_TIMEOUT), 'script lock time too high'
assert(script_lock_value >= bid.created_at + offer.lock_value), 'script lock time too low'
assert(len(scriptvalues[3]) == 40), 'pkhash_refund bad length'
@ -4033,12 +4040,12 @@ class BasicSwap(BaseApp):
# Validate data
assert(len(bid_data.offer_msg_id) == 28), 'Bad offer_id length'
assert(bid_data.time_valid >= MIN_BID_VALID_TIME and bid_data.time_valid <= MAX_BID_VALID_TIME), 'Invalid time_valid'
offer_id = bid_data.offer_msg_id
offer, xmr_offer = self.getXmrOffer(offer_id, sent=True)
assert(offer and offer.was_sent), 'Offer not found: {}.'.format(offer_id.hex())
assert(xmr_offer), 'XMR offer not found: {}.'.format(offer_id.hex())
ci_from = self.ci(offer.coin_from)
ci_to = self.ci(offer.coin_to)
@ -4047,10 +4054,9 @@ class BasicSwap(BaseApp):
assert(now <= offer.expire_at), 'Offer expired'
assert(bid_data.amount >= offer.min_bid_amount), 'Bid amount below minimum'
assert(bid_data.amount <= offer.amount_from), 'Bid amount above offer amount'
self.validateBidValidTime(offer.swap_type, offer.coin_from, offer.coin_to, bid_data.time_valid)
assert(now <= msg['sent'] + bid_data.time_valid), 'Bid expired'
self.log.debug('TODO: xmr bid validation')
assert(ci_to.verifyKey(bid_data.kbvf))
assert(ci_from.verifyPubkey(bid_data.pkaf))
@ -4059,6 +4065,7 @@ class BasicSwap(BaseApp):
bid, xmr_swap = self.getXmrBid(bid_id)
if bid is None:
bid = Bid(
active_ind=1,
bid_id=bid_id,
offer_id=offer_id,
amount=bid_data.amount,
@ -4839,6 +4846,8 @@ class BasicSwap(BaseApp):
if now - self._last_checked_watched >= self.check_watched_seconds:
for k, c in self.coin_clients.items():
if k == Coins.PART_ANON:
continue
if len(c['watched_outputs']) > 0:
self.checkForSpends(k, c)
self._last_checked_watched = now
@ -5132,25 +5141,29 @@ class BasicSwap(BaseApp):
session.remove()
self.mxDB.release()
def listBids(self, sent=False, offer_id=None, for_html=False):
def listBids(self, sent=False, offer_id=None, for_html=False, filters={}):
self.mxDB.acquire()
try:
rv = []
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, offers.coin_from FROM bids ' + \
query_str = 'SELECT bids.created_at, bids.expire_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)
query_str += 'WHERE bids.active_ind = 1 '
filter_bid_id = filters.get('bid_id', None)
if filter_bid_id is not None:
query_str += 'AND bids.bid_id = x\'{}\' '.format(filter_bid_id.hex())
if offer_id is not None:
query_str += 'WHERE bids.offer_id = x\'{}\' '.format(offer_id.hex())
query_str += 'AND bids.offer_id = x\'{}\' '.format(offer_id.hex())
elif sent:
query_str += 'WHERE bids.was_sent = 1 '
query_str += 'AND bids.was_sent = 1 '
else:
query_str += 'WHERE bids.was_received = 1 '
query_str += 'ORDER BY bids.created_at DESC'
query_str += 'AND bids.was_received = 1 '
query_str += ' ORDER BY bids.created_at DESC'
q = session.execute(query_str)
for row in q:

View file

@ -633,6 +633,9 @@ class HttpHandler(BaseHTTPRequestHandler):
offer, xmr_offer = swap_client.getXmrOffer(offer_id)
assert(offer), 'Unknown offer ID'
extend_data = { # Defaults
'nb_validmins': 10,
}
messages = []
sent_bid_id = None
show_bid_form = None
@ -643,15 +646,26 @@ class HttpHandler(BaseHTTPRequestHandler):
swap_client.revokeOffer(offer_id)
messages.append('Offer revoked')
except Exception as ex:
messages.append('Revoke offer failed ' + str(ex))
messages.append('Revoke offer failed: ' + str(ex))
elif b'newbid' in form_data:
show_bid_form = True
elif b'sendbid' in form_data:
try:
addr_from = form_data[b'addr_from'][0].decode('utf-8')
extend_data['nb_addr_from'] = addr_from
if addr_from == '-1':
addr_from = None
sent_bid_id = swap_client.postBid(offer_id, offer.amount_from, addr_send_from=addr_from).hex()
minutes_valid = int(form_data[b'validmins'][0].decode('utf-8'))
extend_data['nb_validmins'] = minutes_valid
extra_options = {
'valid_for_seconds': minutes_valid * 60,
}
sent_bid_id = swap_client.postBid(offer_id, offer.amount_from, addr_send_from=addr_from, extra_options=extra_options).hex()
except Exception as ex:
messages.append('Error: Send bid failed: ' + str(ex))
show_bid_form = True
ci_from = swap_client.ci(Coins(offer.coin_from))
ci_to = swap_client.ci(Coins(offer.coin_to))
@ -674,6 +688,7 @@ class HttpHandler(BaseHTTPRequestHandler):
'was_revoked': 'True' if offer.active_ind == 2 else 'False',
'show_bid_form': show_bid_form,
}
data.update(extend_data)
if xmr_offer:
int_fee_rate_now, fee_source = ci_from.get_fee_rate()
@ -700,7 +715,7 @@ class HttpHandler(BaseHTTPRequestHandler):
sent_bid_id=sent_bid_id,
messages=messages,
data=data,
bids=[(b[1].hex(), ci_from.format_amount(b[3]), strBidState(b[4]), strTxState(b[6]), strTxState(b[7])) for b in bids],
bids=[(b[2].hex(), ci_from.format_amount(b[4]), strBidState(b[5]), strTxState(b[7]), strTxState(b[8])) for b in bids],
addrs=None if show_bid_form is None else swap_client.listSmsgAddresses('bid'),
form_id=os.urandom(8).hex(),
), 'UTF-8')
@ -875,7 +890,7 @@ class HttpHandler(BaseHTTPRequestHandler):
h2=self.server.title,
page_type='Sent' if sent else 'Received',
bids=[(format_timestamp(b[0]),
b[1].hex(), b[2].hex(), strBidState(b[4]), strTxState(b[6]), strTxState(b[7])) for b in bids],
b[2].hex(), b[3].hex(), strBidState(b[5]), strTxState(b[7]), strTxState(b[8])) for b in bids],
), 'UTF-8')
def page_watched(self, url_split, post_string):

View file

@ -9,7 +9,6 @@ import urllib.parse
from .util import (
toBool,
format_timestamp,
)
from .basicswap import (
strBidState,
@ -131,7 +130,8 @@ def js_offers(self, url_split, post_string, is_json, sent=False):
ci_to = self.server.swap_client.ci(o.coin_to)
rv.append({
'offer_id': o.offer_id.hex(),
'created_at': format_timestamp(o.created_at),
'created_at': o.created_at,
'expire_at': o.expire_at,
'coin_from': ci_from.coin_name(),
'coin_to': ci_to.coin_name(),
'amount_from': ci_from.format_amount(o.amount_from),
@ -173,10 +173,20 @@ def js_bids(self, url_split, post_string, is_json):
if addr_from == '-1':
addr_from = None
if offer.swap_type == SwapTypes.XMR_SWAP:
bid_id = swap_client.postXmrBid(offer_id, amount_from, addr_send_from=addr_from)
if have_data_entry(post_data, 'validmins'):
valid_for_seconds = int(get_data_entry(post_data, 'validmins')) * 60
elif have_data_entry(post_data, 'valid_for_seconds'):
valid_for_seconds = int(get_data_entry(post_data, 'valid_for_seconds'))
else:
bid_id = swap_client.postBid(offer_id, amount_from, addr_send_from=addr_from)
valid_for_seconds = 10 * 60
extra_options = {
'valid_for_seconds': valid_for_seconds,
}
if offer.swap_type == SwapTypes.XMR_SWAP:
bid_id = swap_client.postXmrBid(offer_id, amount_from, addr_send_from=addr_from, extra_options=extra_options)
else:
bid_id = swap_client.postBid(offer_id, amount_from, addr_send_from=addr_from, extra_options=extra_options)
if have_data_entry(post_data, 'debugind'):
swap_client.setBidDebugInd(bid_id, int(get_data_entry(post_data, 'debugind')))
@ -203,18 +213,18 @@ def js_bids(self, url_split, post_string, is_json):
edit_bid = False
show_txns = False
data = describeBid(swap_client, bid, xmr_swap, offer, xmr_offer, events, edit_bid, show_txns)
data = describeBid(swap_client, bid, xmr_swap, offer, xmr_offer, events, edit_bid, show_txns, for_api=True)
return bytes(json.dumps(data), 'UTF-8')
bids = swap_client.listBids()
return bytes(json.dumps([{
'bid_id': b[1].hex(),
'offer_id': b[2].hex(),
'created_at': format_timestamp(b[0]),
'coin_from': b[8],
'amount_from': swap_client.ci(b[8]).format_amount(b[3]),
'bid_state': strBidState(b[4])
'bid_id': b[2].hex(),
'offer_id': b[3].hex(),
'created_at': b[0],
'expire_at': b[1],
'coin_from': b[9],
'amount_from': swap_client.ci(b[9]).format_amount(b[4]),
'bid_state': strBidState(b[5])
} for b in bids]), 'UTF-8')

View file

@ -12,6 +12,9 @@ from basicswap.script import (
)
INITIATE_TX_TIMEOUT = 40 * 60 # TODO: make variable per coin
def buildContractScript(lock_val, secret_hash, pkh_redeem, pkh_refund, op_lock=OpCodes.OP_CHECKSEQUENCEVERIFY):
script = bytearray([
OpCodes.OP_IF,

View file

@ -52,11 +52,12 @@
<tr><td>Send From Address</td><td>
<select name="addr_from">
{% for a in addrs %}
<option value="{{ a }}">{{ a }}</option>
<option value="{{ a }}" {% if data.nb_addr_from==a %} selected{% endif %}>{{ a }}</option>
{% endfor %}
<option value="-1">-- New Address --</option>
<option value="-1" {% if data.nb_addr_from=="-1" %} selected{% endif %}>-- New Address --</option>
</select>
</td></tr>
<tr><td>Minutes valid</td><td><input type="number" name="validmins" min="10" max="1440" value="{{ data.nb_validmins }}"></td></tr>
<tr><td><input type="submit" name="sendbid" value="Send Bid"><input type="submit" name="cancel" value="Cancel"></td></tr>
</table>

View file

@ -127,7 +127,7 @@ def listBidStates():
return rv
def describeBid(swap_client, bid, xmr_swap, offer, xmr_offer, bid_events, edit_bid, show_txns, view_tx_ind=None):
def describeBid(swap_client, bid, xmr_swap, offer, xmr_offer, bid_events, edit_bid, show_txns, view_tx_ind=None, for_api=False):
ci_from = swap_client.ci(Coins(offer.coin_from))
ci_to = swap_client.ci(Coins(offer.coin_to))
ticker_from = ci_from.ticker()
@ -176,8 +176,8 @@ def describeBid(swap_client, bid, xmr_swap, offer, xmr_offer, bid_events, edit_b
'offer_id': bid.offer_id.hex(),
'addr_from': bid.bid_addr,
'addr_fund_proof': bid.proof_address,
'created_at': format_timestamp(bid.created_at, with_seconds=True),
'expired_at': format_timestamp(bid.expire_at, with_seconds=True),
'created_at': bid.created_at if for_api else format_timestamp(bid.created_at, with_seconds=True),
'expired_at': bid.expire_at if for_api else format_timestamp(bid.expire_at, with_seconds=True),
'was_sent': 'True' if bid.was_sent else 'False',
'was_received': 'True' if bid.was_received else 'False',
'initiate_tx': getTxIdHex(bid, TxTypes.ITX, ' ' + ticker_from),
@ -226,7 +226,6 @@ 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:

View file

@ -61,13 +61,13 @@ def prepareDataDir(datadir, node_id, conf_file, dir_prefix, base_p2p_port=BASE_P
fp.write('acceptnonstdtxn=0\n')
fp.write('txindex=1\n')
fp.write('wallet=wallet.dat\n')
fp.write('findpeers=0\n')
# minstakeinterval=5 # Using walletsettings stakelimit instead
fp.write('stakethreadconddelayms=1000\n')
if base_p2p_port == BASE_PORT: # Particl
fp.write('zmqpubsmsg=tcp://127.0.0.1:{}\n'.format(BASE_ZMQ_PORT + node_id))
# minstakeinterval=5 # Using walletsettings stakelimit instead
fp.write('stakethreadconddelayms=1000\n')
fp.write('smsgsregtestadjust=0\n')
for i in range(0, num_nodes):
if node_id == i:
@ -109,10 +109,15 @@ def wait_for_bid(delay_event, swap_client, bid_id, state=None, sent=False, wait_
if delay_event.is_set():
raise ValueError('Test stopped.')
delay_event.wait(1)
bids = swap_client.listBids(sent=sent)
filters = {
'bid_id': bid_id,
}
bids = swap_client.listBids(sent=sent, filters=filters)
assert(len(bids) < 2)
for bid in bids:
if bid[1] == bid_id:
if state is not None and state != bid[4]:
if bid[2] == bid_id:
if state is not None and state != bid[5]:
continue
return
raise ValueError('wait_for_bid timed out.')
@ -235,7 +240,6 @@ def wait_for_balance(delay_event, url, balance_key, expect_amount, iterations=20
i = 0
while not delay_event.is_set():
rv_js = json.loads(urlopen(url).read())
print("[rm] rv_js", rv_js)
if float(rv_js[balance_key]) >= expect_amount:
break
delay_event.wait(delay_time)

View file

@ -99,6 +99,7 @@ class XmrTestBase(unittest.TestCase):
fp.write('listenonion=0\n')
fp.write('upnp=0\n')
fp.write('minstakeinterval=5\n')
fp.write('smsgsregtestadjust=0\n')
for ip in range(3):
if ip != i:
fp.write('connect=127.0.0.1:{}\n'.format(PARTICL_PORT_BASE + ip))

View file

@ -1,7 +1,7 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright (c) 2020 tecnovert
# Copyright (c) 2020-2021 tecnovert
# Distributed under the MIT software license, see the accompanying
# file LICENSE or http://www.opensource.org/licenses/mit-license.php.
@ -218,7 +218,9 @@ class Test(unittest.TestCase):
rpc('walletsettings', ['stakingoptions', {'stakecombinethreshold': 100, 'stakesplitthreshold': 200}])
for i in range(NUM_BTC_NODES):
prepareDataDir(TEST_DIR, i, 'bitcoin.conf', 'btc_', base_p2p_port=BTC_BASE_PORT, base_rpc_port=BTC_BASE_RPC_PORT)
data_dir = prepareDataDir(TEST_DIR, i, 'bitcoin.conf', 'btc_', base_p2p_port=BTC_BASE_PORT, base_rpc_port=BTC_BASE_RPC_PORT)
if os.path.exists(os.path.join(cfg.BITCOIN_BINDIR, 'bitcoin-wallet')):
callrpc_cli(cfg.BITCOIN_BINDIR, data_dir, 'regtest', '-wallet=wallet.dat create', 'bitcoin-wallet')
cls.btc_daemons.append(startDaemon(os.path.join(TEST_DIR, 'btc_' + str(i)), cfg.BITCOIN_BINDIR, cfg.BITCOIND))
logging.info('Started %s %d', cfg.BITCOIND, cls.part_daemons[-1].pid)

View file

@ -125,6 +125,7 @@ def prepareDir(datadir, nodeId, network_key, network_pubkey):
fp.write('acceptnonstdtxn=0\n')
fp.write('minstakeinterval=5\n')
fp.write('smsgsregtestadjust=0\n')
for i in range(0, NUM_NODES):
if nodeId == i:

View file

@ -99,6 +99,7 @@ class Test(unittest.TestCase):
fp.write('listenonion=0\n')
fp.write('upnp=0\n')
fp.write('minstakeinterval=5\n')
fp.write('smsgsregtestadjust=0\n')
for ip in range(3):
if ip != i:
fp.write('connect=127.0.0.1:{}\n'.format(PARTICL_PORT_BASE + ip))

View file

@ -180,6 +180,7 @@ class Test(unittest.TestCase):
fp.write('listenonion=0\n')
fp.write('upnp=0\n')
fp.write('minstakeinterval=5\n')
fp.write('smsgsregtestadjust=0\n')
salt = generate_salt(16)
fp.write('rpcauth={}:{}${}\n'.format('test_part_' + str(i), salt, password_to_hmac(salt, 'test_part_pwd_' + str(i))))
for ip in range(NUM_NODES):

View file

@ -103,6 +103,7 @@ class Test(unittest.TestCase):
fp.write('listenonion=0\n')
fp.write('upnp=0\n')
fp.write('minstakeinterval=5\n')
fp.write('smsgsregtestadjust=0\n')
for ip in range(3):
if ip != i:
fp.write('connect=127.0.0.1:{}\n'.format(PARTICL_PORT_BASE + ip))

View file

@ -135,6 +135,7 @@ def prepareDir(datadir, nodeId, network_key, network_pubkey):
fp.write('acceptnonstdtxn=0\n')
fp.write('minstakeinterval=2\n')
fp.write('smsgsregtestadjust=0\n')
fp.write('stakethreadconddelayms=1000\n')
for i in range(0, NUM_NODES):

View file

@ -68,11 +68,29 @@ class Test(XmrTestBase):
offers = json.loads(urlopen('http://127.0.0.1:12701/json/offers').read())
offer = offers[0]
data = parse.urlencode({
data = {
'offer_id': offer['offer_id'],
'amount_from': offer['amount_from']}).encode()
'amount_from': offer['amount_from']}
bid_id = json.loads(urlopen('http://127.0.0.1:12701/json/bids/new', data=data).read())
data['valid_for_seconds'] = 24 * 60 * 60 + 1
bid = json.loads(urlopen('http://127.0.0.1:12701/json/bids/new', data=parse.urlencode(data).encode()).read())
assert(bid['error'] == 'Bid TTL too high')
del data['valid_for_seconds']
data['validmins'] = 24 * 60 + 1
bid = json.loads(urlopen('http://127.0.0.1:12701/json/bids/new', data=parse.urlencode(data).encode()).read())
assert(bid['error'] == 'Bid TTL too high')
del data['validmins']
data['valid_for_seconds'] = 10
bid = json.loads(urlopen('http://127.0.0.1:12701/json/bids/new', data=parse.urlencode(data).encode()).read())
assert(bid['error'] == 'Bid TTL too low')
del data['valid_for_seconds']
data['validmins'] = 1
bid = json.loads(urlopen('http://127.0.0.1:12701/json/bids/new', data=parse.urlencode(data).encode()).read())
assert(bid['error'] == 'Bid TTL too low')
data['validmins'] = 60
bid_id = json.loads(urlopen('http://127.0.0.1:12701/json/bids/new', data=parse.urlencode(data).encode()).read())
waitForNumBids(self.delay_event, 12700, 1)
@ -82,6 +100,7 @@ class Test(XmrTestBase):
if bid['bid_state'] == 'Received':
break
self.delay_event.wait(1)
assert(bid['expire_at'] == bid['created_at'] + data['validmins'] * 60)
data = parse.urlencode({
'accept': True