ui: Show bids that can be accepted.

2024-05-20_merge
tecnovert 3 years ago
parent 0edcf249aa
commit 3ed6eca95f
No known key found for this signature in database
GPG Key ID: 8ED6D8750C4E3F93
  1. 37
      basicswap/basicswap.py
  2. 2
      basicswap/basicswap_util.py
  3. 29
      basicswap/http_server.py
  4. 17
      basicswap/interface_xmr.py
  5. 13
      basicswap/templates/bids.html
  6. 1
      basicswap/templates/index.html
  7. 4
      tests/basicswap/extended/test_xmr_persistent.py
  8. 2
      tests/basicswap/test_xmr.py

@ -5210,21 +5210,24 @@ class BasicSwap(BaseApp):
continue continue
num_watched_outputs += len(v['watched_outputs']) num_watched_outputs += len(v['watched_outputs'])
bids_sent = 0
bids_received = 0
q = self.engine.execute('SELECT was_sent, was_received, COUNT(*) FROM bids GROUP BY was_sent, was_received ')
for r in q:
if r[0]:
bids_sent += r[2]
if r[1]:
bids_received += r[2]
now = int(time.time()) now = int(time.time())
q = self.engine.execute('SELECT COUNT(*) FROM offers WHERE active_ind = 1 AND expire_at > {}'.format(now)).first() q_str = '''SELECT
COUNT(CASE WHEN was_sent THEN 1 ELSE NULL END) AS count_sent,
COUNT(CASE WHEN was_received THEN 1 ELSE NULL END) AS count_received,
COUNT(CASE WHEN was_received AND state = {} AND expire_at > {} THEN 1 ELSE NULL END) AS count_available
FROM bids WHERE active_ind = 1'''.format(BidStates.BID_RECEIVED, now)
q = self.engine.execute(q_str).first()
bids_sent = q[0]
bids_received = q[1]
bids_available = q[2]
q_str = '''SELECT
COUNT(CASE WHEN expire_at > {} THEN 1 ELSE NULL END) AS count_active,
COUNT(CASE WHEN was_sent THEN 1 ELSE NULL END) AS count_sent
FROM offers WHERE active_ind = 1'''.format(now)
q = self.engine.execute(q_str).first()
num_offers = q[0] num_offers = q[0]
num_sent_offers = q[1]
q = self.engine.execute('SELECT COUNT(*) FROM offers WHERE was_sent = 1').first()
num_sent_offers = q[0]
rv = { rv = {
'network': self.chain, 'network': self.chain,
@ -5233,6 +5236,7 @@ class BasicSwap(BaseApp):
'num_sent_offers': num_sent_offers, 'num_sent_offers': num_sent_offers,
'num_recv_bids': bids_received, 'num_recv_bids': bids_received,
'num_sent_bids': bids_sent, 'num_sent_bids': bids_sent,
'num_available_bids': bids_available,
'num_watched_outputs': num_watched_outputs, 'num_watched_outputs': num_watched_outputs,
} }
return rv return rv
@ -5455,6 +5459,13 @@ class BasicSwap(BaseApp):
else: else:
query_str += 'AND bids.was_received = 1 ' query_str += 'AND bids.was_received = 1 '
bid_state_ind = filters.get('bid_state_ind', -1)
if bid_state_ind != -1:
query_str += 'AND bids.state = {} '.format(bid_state_ind)
with_expired = filters.get('with_expired', True)
if with_expired is not True:
query_str += 'AND bids.expire_at > {} '.format(now)
sort_dir = filters.get('sort_dir', 'DESC').upper() sort_dir = filters.get('sort_dir', 'DESC').upper()
sort_by = filters.get('sort_by', 'created_at') sort_by = filters.get('sort_by', 'created_at')
query_str += f' ORDER BY bids.{sort_by} {sort_dir}' query_str += f' ORDER BY bids.{sort_by} {sort_dir}'

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (c) 2021 tecnovert # Copyright (c) 2021-2022 tecnovert
# Distributed under the MIT software license, see the accompanying # Distributed under the MIT software license, see the accompanying
# file LICENSE or http://www.opensource.org/licenses/mit-license.php. # file LICENSE or http://www.opensource.org/licenses/mit-license.php.

@ -18,6 +18,7 @@ from . import __version__
from .util import ( from .util import (
dumpj, dumpj,
ensure, ensure,
toBool,
format_timestamp, format_timestamp,
) )
from .chainparams import ( from .chainparams import (
@ -26,6 +27,7 @@ from .chainparams import (
getCoinIdFromTicker, getCoinIdFromTicker,
) )
from .basicswap_util import ( from .basicswap_util import (
BidStates,
SwapTypes, SwapTypes,
DebugTypes, DebugTypes,
strBidState, strBidState,
@ -50,6 +52,7 @@ from .ui.util import (
PAGE_LIMIT, PAGE_LIMIT,
describeBid, describeBid,
getCoinName, getCoinName,
listBidStates,
get_data_entry, get_data_entry,
have_data_entry, have_data_entry,
get_data_entry_or, get_data_entry_or,
@ -716,15 +719,21 @@ class HttpHandler(BaseHTTPRequestHandler):
old_states=old_states, old_states=old_states,
), 'UTF-8') ), 'UTF-8')
def page_bids(self, url_split, post_string, sent=False): def page_bids(self, url_split, post_string, sent=False, available=False):
swap_client = self.server.swap_client swap_client = self.server.swap_client
filters = { filters = {
'page_no': 1, 'page_no': 1,
'bid_state_ind': -1,
'with_expired': True,
'limit': PAGE_LIMIT, 'limit': PAGE_LIMIT,
'sort_by': 'created_at', 'sort_by': 'created_at',
'sort_dir': 'desc', 'sort_dir': 'desc',
} }
if available:
filters['bid_state_ind'] = BidStates.BID_RECEIVED
filters['with_expired'] = False
messages = [] messages = []
form_data = self.checkForm(post_string, 'bids', messages) form_data = self.checkForm(post_string, 'bids', messages)
if form_data and have_data_entry(form_data, 'applyfilters'): if form_data and have_data_entry(form_data, 'applyfilters'):
@ -736,11 +745,26 @@ class HttpHandler(BaseHTTPRequestHandler):
sort_dir = get_data_entry(form_data, 'sort_dir') sort_dir = get_data_entry(form_data, 'sort_dir')
ensure(sort_dir in ['asc', 'desc'], 'Invalid sort dir') ensure(sort_dir in ['asc', 'desc'], 'Invalid sort dir')
filters['sort_dir'] = sort_dir filters['sort_dir'] = sort_dir
if have_data_entry(form_data, 'state'):
state_ind = get_data_entry(form_data, 'state')
if state_ind != -1:
try:
state = BidStates(state_ind)
except Exception:
raise ValueError('Invalid state')
filters['bid_state_ind'] = state_ind
if have_data_entry(form_data, 'with_expired'):
with_expired = toBool(get_data_entry(form_data, 'with_expired'))
filters['with_expired'] = with_expired
set_pagination_filters(form_data, filters) set_pagination_filters(form_data, filters)
bids = swap_client.listBids(sent=sent, filters=filters) bids = swap_client.listBids(sent=sent, filters=filters)
page_data = {
'bid_states': listBidStates()
}
template = env.get_template('bids.html') template = env.get_template('bids.html')
return bytes(template.render( return bytes(template.render(
title=self.server.title, title=self.server.title,
@ -748,6 +772,7 @@ class HttpHandler(BaseHTTPRequestHandler):
page_type='Sent' if sent else 'Received', page_type='Sent' if sent else 'Received',
messages=messages, messages=messages,
filters=filters, filters=filters,
data=page_data,
bids=[(format_timestamp(b[0]), bids=[(format_timestamp(b[0]),
b[2].hex(), b[3].hex(), strBidState(b[5]), strTxState(b[7]), strTxState(b[8]), b[11]) for b in bids], b[2].hex(), b[3].hex(), strBidState(b[5]), strTxState(b[7]), strTxState(b[8]), b[11]) for b in bids],
form_id=os.urandom(8).hex(), form_id=os.urandom(8).hex(),
@ -1003,6 +1028,8 @@ class HttpHandler(BaseHTTPRequestHandler):
return self.page_bids(url_split, post_string) return self.page_bids(url_split, post_string)
if url_split[1] == 'sentbids': if url_split[1] == 'sentbids':
return self.page_bids(url_split, post_string, sent=True) return self.page_bids(url_split, post_string, sent=True)
if url_split[1] == 'availablebids':
return self.page_bids(url_split, post_string, available=True)
if url_split[1] == 'watched': if url_split[1] == 'watched':
return self.page_watched(url_split, post_string) return self.page_watched(url_split, post_string)
if url_split[1] == 'smsgaddresses': if url_split[1] == 'smsgaddresses':

@ -12,19 +12,21 @@ import basicswap.contrib.ed25519_fast as edf
import basicswap.ed25519_fast_util as edu import basicswap.ed25519_fast_util as edu
import basicswap.util_xmr as xmr_util import basicswap.util_xmr as xmr_util
from coincurve.ed25519 import ( from coincurve.ed25519 import (
ed25519_add,
ed25519_get_pubkey, ed25519_get_pubkey,
ed25519_scalar_add, ed25519_scalar_add,
ed25519_add) )
from coincurve.keys import PrivateKey from coincurve.keys import PrivateKey
from coincurve.dleag import ( from coincurve.dleag import (
verify_ed25519_point, dleag_prove,
dleag_proof_len,
dleag_verify, dleag_verify,
dleag_prove) dleag_proof_len,
verify_ed25519_point,
)
from .util import ( from .util import (
ensure,
dumpj, dumpj,
ensure,
make_int, make_int,
TemporaryError) TemporaryError)
from .rpc_xmr import ( from .rpc_xmr import (
@ -33,9 +35,7 @@ from .rpc_xmr import (
make_xmr_wallet_rpc_func) make_xmr_wallet_rpc_func)
from .util import ( from .util import (
b2i, b2h) b2i, b2h)
from .chainparams import CoinInterface, Coins from .chainparams import XMR_COIN, CoinInterface, Coins
XMR_COIN = 10 ** 12
class XMRInterface(CoinInterface): class XMRInterface(CoinInterface):
@ -155,7 +155,6 @@ class XMRInterface(CoinInterface):
def getNewAddress(self, placeholder): def getNewAddress(self, placeholder):
with self._mx_wallet: with self._mx_wallet:
self._log.warning('TODO - subaddress?')
self.rpc_wallet_cb('open_wallet', {'filename': self._wallet_filename}) self.rpc_wallet_cb('open_wallet', {'filename': self._wallet_filename})
return self.rpc_wallet_cb('create_address', {'account_index': 0})['address'] return self.rpc_wallet_cb('create_address', {'account_index': 0})['address']

@ -20,6 +20,19 @@
<option value="desc"{% if filters.sort_dir=='desc' %} selected{% endif %}>Descending</option> <option value="desc"{% if filters.sort_dir=='desc' %} selected{% endif %}>Descending</option>
</select> </select>
</td></tr> </td></tr>
<tr><td>State</td><td>
<select name="state">
<option value="-1"{% if filters.bid_state_ind==-1 %} selected{% endif %}>-- Any --</option>
{% for s in data.bid_states %}
<option value="{{ s[0] }}"{% if filters.bid_state_ind==s[0] %} selected{% endif %}>{{ s[1] }}</option>
{% endfor %}
</select>
<tr><td>Include Expired</td><td>
<select name="with_expired">
<option value="true"{% if filters.with_expired==true %} selected{% endif %}>Include</option>
<option value="false"{% if filters.with_expired==false %} selected{% endif %}>Exclude</option>
</select>
</td></tr>
<tr><td><input type="submit" name='applyfilters' value="Apply Filters"></td><td><input type="submit" name='clearfilters' value="Clear Filters"></td></tr> <tr><td><input type="submit" name='applyfilters' value="Apply Filters"></td><td><input type="submit" name='clearfilters' value="Clear Filters"></td></tr>
<tr><td><input type="submit" name='pageback' value="Page Back"></td><td>Page: {{ filters.page_no }}</td><td><input type="submit" name='pageforwards' value="Page Forwards"></td></tr> <tr><td><input type="submit" name='pageback' value="Page Back"></td><td>Page: {{ filters.page_no }}</td><td><input type="submit" name='pageforwards' value="Page Forwards"></td></tr>

@ -16,6 +16,7 @@ Version: {{ version }}
<a href="/active">Swaps in Progress: {{ summary.num_swapping }}</a><br/> <a href="/active">Swaps in Progress: {{ summary.num_swapping }}</a><br/>
<a href="/offers">Network Offers: {{ summary.num_network_offers }}</a><br/> <a href="/offers">Network Offers: {{ summary.num_network_offers }}</a><br/>
<a href="/sentoffers">Sent Offers: {{ summary.num_sent_offers }}</a><br/> <a href="/sentoffers">Sent Offers: {{ summary.num_sent_offers }}</a><br/>
<a href="/availablebids">Available Bids: {{ summary.num_available_bids }}</a><br/>
<a href="/bids">Received Bids: {{ summary.num_recv_bids }}</a><br/> <a href="/bids">Received Bids: {{ summary.num_recv_bids }}</a><br/>
<a href="/sentbids">Sent Bids: {{ summary.num_sent_bids }}</a><br/> <a href="/sentbids">Sent Bids: {{ summary.num_sent_bids }}</a><br/>
<a href="/watched">Watched Outputs: {{ summary.num_watched_outputs }}</a><br/> <a href="/watched">Watched Outputs: {{ summary.num_watched_outputs }}</a><br/>

@ -9,8 +9,8 @@
export RESET_TEST=true export RESET_TEST=true
export TEST_PATH=/tmp/test_persistent export TEST_PATH=/tmp/test_persistent
mkdir -p ${TEST_PATH}/bin/{particl,monero,bitcoin} mkdir -p ${TEST_PATH}/bin/{particl,monero,bitcoin}
cp ~/tmp/particl-0.21.2.9-x86_64-linux-gnu.tar.gz ${TEST_PATH}/bin/particl cp ~/tmp/particl-0.21.2.9-x86_64-linux-gnu_nousb.tar.gz ${TEST_PATH}/bin/particl
cp ~/tmp/bitcoin-0.21.1-x86_64-linux-gnu.tar.gz ${TEST_PATH}/bin/bitcoin cp ~/tmp/bitcoin-22.0-x86_64-linux-gnu.tar.gz ${TEST_PATH}/bin/bitcoin
cp ~/tmp/monero-linux-x64-v0.17.3.0.tar.bz2 ${TEST_PATH}/bin/monero/monero-0.17.3.0-x86_64-linux-gnu.tar.bz2 cp ~/tmp/monero-linux-x64-v0.17.3.0.tar.bz2 ${TEST_PATH}/bin/monero/monero-0.17.3.0-x86_64-linux-gnu.tar.bz2
export PYTHONPATH=$(pwd) export PYTHONPATH=$(pwd)
python tests/basicswap/extended/test_xmr_persistent.py python tests/basicswap/extended/test_xmr_persistent.py

@ -46,8 +46,8 @@ from basicswap.rpc import (
waitForRPC, waitForRPC,
) )
from basicswap.rpc_xmr import ( from basicswap.rpc_xmr import (
callrpc_xmr_na,
callrpc_xmr, callrpc_xmr,
callrpc_xmr_na,
) )
from basicswap.interface_xmr import ( from basicswap.interface_xmr import (
XMR_COIN, XMR_COIN,

Loading…
Cancel
Save