diff --git a/basicswap/basicswap.py b/basicswap/basicswap.py
index 91ca90b..17d783d 100644
--- a/basicswap/basicswap.py
+++ b/basicswap/basicswap.py
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
-# Copyright (c) 2019-2020 tecnovert
+# Copyright (c) 2019-2021 tecnovert
# Distributed under the MIT software license, see the accompanying
# file LICENSE or http://www.opensource.org/licenses/mit-license.php.
@@ -36,6 +36,7 @@ from .util import (
pubkeyToAddress,
format8,
format_amount,
+ format_timestamp,
encodeAddress,
decodeAddress,
DeserialiseNum,
@@ -895,6 +896,12 @@ class BasicSwap(BaseApp):
if ptx_state is not None and ptx_state != TxStates.TX_REFUNDED:
self.returnAddressToPool(bid.bid_id, TxTypes.PTX_REFUND)
+ # Remove any delayed events
+ if self.debug:
+ session.execute('UPDATE eventqueue SET active_ind = 2 WHERE linked_id = {}'.format(bid.bid_id))
+ else:
+ session.execute('DELETE FROM eventqueue WHERE linked_id = {}'.format(bid.bid_id))
+
def loadFromDB(self):
self.log.info('Loading data from db')
self.mxDB.acquire()
@@ -955,7 +962,7 @@ class BasicSwap(BaseApp):
def validateOfferLockValue(self, coin_from, coin_to, lock_type, lock_value):
if lock_type == OfferMessage.SEQUENCE_LOCK_TIME:
- assert(lock_value >= 2 * 60 * 60 and lock_value <= 96 * 60 * 60), 'Invalid lock_value time'
+ assert(lock_value >= 1 * 60 * 60 and lock_value <= 96 * 60 * 60), 'Invalid lock_value time'
assert(self.coin_clients[coin_from]['use_csv'] and self.coin_clients[coin_to]['use_csv']), 'Both coins need CSV activated.'
elif lock_type == OfferMessage.SEQUENCE_LOCK_BLOCKS:
assert(lock_value >= 5 and lock_value <= 1000), 'Invalid lock_value blocks'
@@ -1681,11 +1688,19 @@ class BasicSwap(BaseApp):
def list_bid_events(self, bid_id, session):
session = scoped_session(self.session_factory)
query_str = 'SELECT created_at, event_type, event_msg FROM eventlog ' + \
- 'WHERE linked_type = {} AND linked_id = x\'{}\' '.format(TableTypes.BID, bid_id.hex())
+ 'WHERE active_ind = 1 AND linked_type = {} AND linked_id = x\'{}\' '.format(TableTypes.BID, bid_id.hex())
q = self.engine.execute(query_str)
events = []
for row in q:
events.append({'at': row[0], 'desc': describeEventEntry(row[1], row[2])})
+
+ query_str = 'SELECT created_at, trigger_at FROM eventqueue ' + \
+ 'WHERE active_ind = 1 AND linked_id = x\'{}\' '.format(bid_id.hex())
+ q = self.engine.execute(query_str)
+ events = []
+ for row in q:
+ events.append({'at': row[0], 'desc': 'Delaying until: {}'.format(format_timestamp(row[1]))})
+
return events
def acceptBid(self, bid_id):
@@ -2037,24 +2052,6 @@ class BasicSwap(BaseApp):
finally:
self.mxDB.release()
- def abandonOffer(self, offer_id):
- self.log.info('Abandoning Offer %s', offer_id.hex())
- self.mxDB.acquire()
- try:
- session = scoped_session(self.session_factory)
- offer = session.query(Offer).filter_by(offer_id=offer_id).first()
- assert(offer), 'Offer not found'
-
- # TODO: abandon linked bids?
-
- # Mark bid as abandoned, no further processing will be done
- offer.setState(OfferStates.OFFER_ABANDONED)
- session.commit()
- finally:
- session.close()
- session.remove()
- self.mxDB.release()
-
def abandonBid(self, bid_id):
self.log.info('Abandoning Bid %s', bid_id.hex())
self.mxDB.acquire()
@@ -3289,6 +3286,7 @@ class BasicSwap(BaseApp):
self.log.info('Verify xmr bid {} failed: {}'.format(bid.bid_id.hex(), str(ex)))
bid.setState(BidStates.BID_ERROR, 'Failed validation: ' + str(ex))
session.add(bid)
+ self.updateBidInProgress(bid)
continue
if bid.created_at + ttl_xmr_split_messages < now:
self.log.debug('Expiring partially received bid: {}'.format(bid.bid_id.hex()))
@@ -4500,7 +4498,7 @@ class BasicSwap(BaseApp):
else:
self.log.debug('TODO - determine in-progress for manualBidUpdate')
if offer.swap_type == SwapTypes.XMR_SWAP:
- if bid.state and bid.state in (BidStates.XMR_SWAP_HAVE_SCRIPT_COIN_SPEND_TX, BidStates.XMR_SWAP_SCRIPT_COIN_LOCKED, BidStates.XMR_SWAP_LOCK_RELEASED, BidStates.XMR_SWAP_NOSCRIPT_TX_REDEEMED):
+ if bid.state and bid.state in (BidStates.XMR_SWAP_HAVE_SCRIPT_COIN_SPEND_TX, BidStates.XMR_SWAP_SCRIPT_COIN_LOCKED, BidStates.XMR_SWAP_NOSCRIPT_COIN_LOCKED, BidStates.XMR_SWAP_LOCK_RELEASED, BidStates.XMR_SWAP_NOSCRIPT_TX_REDEEMED):
activate_bid = True
if activate_bid:
@@ -4792,6 +4790,12 @@ class BasicSwap(BaseApp):
return True if passed is True else False # _possibly_revoked_offers should not contain duplicates
return False
+ def updateBidInProgress(self, bid):
+ swap_in_progress = self.swaps_in_progress.get(bid.bid_id, None)
+ if swap_in_progress is None:
+ return
+ self.swaps_in_progress[bid.bid_id] = (bid, swap_in_progress[1])
+
def add_connection(self, host, port, peer_pubkey):
self.log.info('add_connection %s %d %s', host, port, peer_pubkey.hex())
self._network.add_connection(host, port, peer_pubkey)
diff --git a/basicswap/http_server.py b/basicswap/http_server.py
index b2dec48..deb4d40 100644
--- a/basicswap/http_server.py
+++ b/basicswap/http_server.py
@@ -1,11 +1,10 @@
# -*- coding: utf-8 -*-
-# Copyright (c) 2019 tecnovert
+# Copyright (c) 2019-2021 tecnovert
# Distributed under the MIT software license, see the accompanying
# file LICENSE or http://www.opensource.org/licenses/mit-license.php.
import os
-import time
import struct
import traceback
import threading
@@ -16,6 +15,7 @@ from jinja2 import Environment, PackageLoader
from . import __version__
from .util import (
+ format_timestamp,
dumpj,
)
from .chainparams import (
@@ -49,10 +49,6 @@ from .ui import (
)
-def format_timestamp(value):
- return time.strftime('%Y-%m-%d %H:%M', time.localtime(value))
-
-
env = Environment(loader=PackageLoader('basicswap', 'templates'))
env.filters['formatts'] = format_timestamp
@@ -635,7 +631,7 @@ class HttpHandler(BaseHTTPRequestHandler):
ci_from = swap_client.ci(Coins(o.coin_from))
ci_to = swap_client.ci(Coins(o.coin_to))
formatted_offers.append((
- time.strftime('%Y-%m-%d %H:%M', time.localtime(o.created_at)),
+ format_timestamp(o.created_at),
o.offer_id.hex(),
ci_from.coin_name(), ci_to.coin_name(),
ci_from.format_amount(o.amount_from),
@@ -758,7 +754,7 @@ class HttpHandler(BaseHTTPRequestHandler):
title=self.server.title,
h2=self.server.title,
page_type='Sent' if sent else 'Received',
- bids=[(time.strftime('%Y-%m-%d %H:%M', time.localtime(b[0])),
+ bids=[(format_timestamp(b[0]),
b[1].hex(), b[2].hex(), strBidState(b[4]), strTxState(b[6]), strTxState(b[7])) for b in bids],
), 'UTF-8')
diff --git a/basicswap/js_server.py b/basicswap/js_server.py
index cb4339e..65d3f9c 100644
--- a/basicswap/js_server.py
+++ b/basicswap/js_server.py
@@ -1,6 +1,6 @@
# -*- 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.
@@ -8,7 +8,10 @@ import json
import time
import urllib.parse
-from .util import format8
+from .util import (
+ format8,
+ format_timestamp,
+)
from .basicswap import (
strBidState,
SwapTypes,
@@ -143,7 +146,7 @@ def js_bids(self, url_split, post_string):
return bytes(json.dumps([{
'bid_id': b[1].hex(),
'offer_id': b[2].hex(),
- 'created_at': time.strftime('%Y-%m-%d %H:%M', time.localtime(b[0])),
+ 'created_at': format_timestamp(b[0]),
'amount_from': format8(b[3]),
'bid_state': strBidState(b[4])
} for b in bids]), 'UTF-8')
diff --git a/basicswap/templates/bid_xmr.html b/basicswap/templates/bid_xmr.html
index b09241a..609cd49 100644
--- a/basicswap/templates/bid_xmr.html
+++ b/basicswap/templates/bid_xmr.html
@@ -40,10 +40,10 @@
{% else %}
{% if data.was_received == 'True' %}
-
+
{% endif %}
{% if data.can_abandon == true %}
-
+
{% endif %}
{% if data.show_txns %}
diff --git a/basicswap/templates/offer_new_2.html b/basicswap/templates/offer_new_2.html
index 26902ea..b3394c1 100644
--- a/basicswap/templates/offer_new_2.html
+++ b/basicswap/templates/offer_new_2.html
@@ -51,7 +51,7 @@
{% endif %}
-