mirror of
https://github.com/basicswap/basicswap.git
synced 2025-01-19 00:54:35 +00:00
refactor: Rename EventQueue table to Action
This commit is contained in:
parent
d47a69c7cb
commit
d909115ea4
8 changed files with 172 additions and 86 deletions
|
@ -77,7 +77,7 @@ from .messages_pb2 import (
|
||||||
)
|
)
|
||||||
from .db import (
|
from .db import (
|
||||||
CURRENT_DB_VERSION,
|
CURRENT_DB_VERSION,
|
||||||
TableTypes,
|
Concepts,
|
||||||
Base,
|
Base,
|
||||||
DBKVInt,
|
DBKVInt,
|
||||||
DBKVString,
|
DBKVString,
|
||||||
|
@ -87,7 +87,7 @@ from .db import (
|
||||||
PooledAddress,
|
PooledAddress,
|
||||||
SentOffer,
|
SentOffer,
|
||||||
SmsgAddress,
|
SmsgAddress,
|
||||||
EventQueue,
|
Action,
|
||||||
EventLog,
|
EventLog,
|
||||||
XmrOffer,
|
XmrOffer,
|
||||||
XmrSwap,
|
XmrSwap,
|
||||||
|
@ -117,7 +117,7 @@ from .basicswap_util import (
|
||||||
BidStates,
|
BidStates,
|
||||||
TxStates,
|
TxStates,
|
||||||
TxTypes,
|
TxTypes,
|
||||||
EventTypes,
|
ActionTypes,
|
||||||
EventLogTypes,
|
EventLogTypes,
|
||||||
XmrSplitMsgTypes,
|
XmrSplitMsgTypes,
|
||||||
DebugTypes,
|
DebugTypes,
|
||||||
|
@ -205,14 +205,14 @@ class BasicSwap(BaseApp):
|
||||||
self.check_progress_seconds = self.settings.get('check_progress_seconds', 60)
|
self.check_progress_seconds = self.settings.get('check_progress_seconds', 60)
|
||||||
self.check_watched_seconds = self.settings.get('check_watched_seconds', 60)
|
self.check_watched_seconds = self.settings.get('check_watched_seconds', 60)
|
||||||
self.check_expired_seconds = self.settings.get('check_expired_seconds', 60 * 5)
|
self.check_expired_seconds = self.settings.get('check_expired_seconds', 60 * 5)
|
||||||
self.check_events_seconds = self.settings.get('check_events_seconds', 10)
|
self.check_actions_seconds = self.settings.get('check_actions_seconds', 10)
|
||||||
self.check_xmr_swaps_seconds = self.settings.get('check_xmr_swaps_seconds', 20)
|
self.check_xmr_swaps_seconds = self.settings.get('check_xmr_swaps_seconds', 20)
|
||||||
self.startup_tries = self.settings.get('startup_tries', 21) # Seconds waited for will be (x(1 + x+1) / 2
|
self.startup_tries = self.settings.get('startup_tries', 21) # Seconds waited for will be (x(1 + x+1) / 2
|
||||||
self.debug_ui = self.settings.get('debug_ui', False)
|
self.debug_ui = self.settings.get('debug_ui', False)
|
||||||
self._last_checked_progress = 0
|
self._last_checked_progress = 0
|
||||||
self._last_checked_watched = 0
|
self._last_checked_watched = 0
|
||||||
self._last_checked_expired = 0
|
self._last_checked_expired = 0
|
||||||
self._last_checked_events = 0
|
self._last_checked_actions = 0
|
||||||
self._last_checked_xmr_swaps = 0
|
self._last_checked_xmr_swaps = 0
|
||||||
self._possibly_revoked_offers = collections.deque([], maxlen=48) # TODO: improve
|
self._possibly_revoked_offers = collections.deque([], maxlen=48) # TODO: improve
|
||||||
self._updating_wallets_info = {}
|
self._updating_wallets_info = {}
|
||||||
|
@ -793,9 +793,9 @@ class BasicSwap(BaseApp):
|
||||||
|
|
||||||
# Remove any delayed events
|
# Remove any delayed events
|
||||||
if self.debug:
|
if self.debug:
|
||||||
use_session.execute('UPDATE eventqueue SET active_ind = 2 WHERE linked_id = x\'{}\' '.format(bid.bid_id.hex()))
|
use_session.execute('UPDATE actions SET active_ind = 2 WHERE linked_id = x\'{}\' '.format(bid.bid_id.hex()))
|
||||||
else:
|
else:
|
||||||
use_session.execute('DELETE FROM eventqueue WHERE linked_id = x\'{}\' '.format(bid.bid_id.hex()))
|
use_session.execute('DELETE FROM actions WHERE linked_id = x\'{}\' '.format(bid.bid_id.hex()))
|
||||||
|
|
||||||
# Unlock locked inputs (TODO)
|
# Unlock locked inputs (TODO)
|
||||||
if offer.swap_type == SwapTypes.XMR_SWAP:
|
if offer.swap_type == SwapTypes.XMR_SWAP:
|
||||||
|
@ -1090,7 +1090,7 @@ class BasicSwap(BaseApp):
|
||||||
if automation_id != -1:
|
if automation_id != -1:
|
||||||
auto_link = AutomationLink(
|
auto_link = AutomationLink(
|
||||||
active_ind=1,
|
active_ind=1,
|
||||||
linked_type=TableTypes.OFFER,
|
linked_type=Concepts.OFFER,
|
||||||
linked_id=offer_id,
|
linked_id=offer_id,
|
||||||
strategy_id=automation_id,
|
strategy_id=automation_id,
|
||||||
created_at=offer_created_at,
|
created_at=offer_created_at,
|
||||||
|
@ -1549,36 +1549,35 @@ class BasicSwap(BaseApp):
|
||||||
session.remove()
|
session.remove()
|
||||||
self.mxDB.release()
|
self.mxDB.release()
|
||||||
|
|
||||||
def createEventInSession(self, delay, event_type, linked_id, session):
|
def createActionInSession(self, delay, action_type, linked_id, session):
|
||||||
self.log.debug('createEvent %d %s', event_type, linked_id.hex())
|
self.log.debug('createAction %d %s', action_type, linked_id.hex())
|
||||||
now = int(time.time())
|
now = int(time.time())
|
||||||
event = EventQueue(
|
action = Action(
|
||||||
active_ind=1,
|
active_ind=1,
|
||||||
created_at=now,
|
created_at=now,
|
||||||
trigger_at=now + delay,
|
trigger_at=now + delay,
|
||||||
event_type=event_type,
|
action_type=action_type,
|
||||||
linked_id=linked_id)
|
linked_id=linked_id)
|
||||||
session.add(event)
|
session.add(action)
|
||||||
|
|
||||||
def createEvent(self, delay, event_type, linked_id):
|
def createAction(self, delay, action_type, linked_id):
|
||||||
# self.log.debug('createEvent %d %s', event_type, linked_id.hex())
|
# self.log.debug('createAction %d %s', action_type, linked_id.hex())
|
||||||
self.mxDB.acquire()
|
self.mxDB.acquire()
|
||||||
try:
|
try:
|
||||||
session = scoped_session(self.session_factory)
|
session = scoped_session(self.session_factory)
|
||||||
self.createEventInSession(delay, event_type, linked_id, session)
|
self.createActionInSession(delay, action_type, linked_id, session)
|
||||||
session.commit()
|
session.commit()
|
||||||
finally:
|
finally:
|
||||||
session.close()
|
session.close()
|
||||||
session.remove()
|
session.remove()
|
||||||
self.mxDB.release()
|
self.mxDB.release()
|
||||||
|
|
||||||
def logBidEvent(self, bid_id, event_type, event_msg, session):
|
def logEvent(self, linked_type, linked_id, event_type, event_msg, session):
|
||||||
self.log.debug('logBidEvent %s %s', bid_id.hex(), event_type)
|
|
||||||
entry = EventLog(
|
entry = EventLog(
|
||||||
active_ind=1,
|
active_ind=1,
|
||||||
created_at=int(time.time()),
|
created_at=int(time.time()),
|
||||||
linked_type=TableTypes.BID,
|
linked_type=linked_type,
|
||||||
linked_id=bid_id,
|
linked_id=linked_id,
|
||||||
event_type=int(event_type),
|
event_type=int(event_type),
|
||||||
event_msg=event_msg)
|
event_msg=event_msg)
|
||||||
|
|
||||||
|
@ -1595,10 +1594,27 @@ class BasicSwap(BaseApp):
|
||||||
session.remove()
|
session.remove()
|
||||||
self.mxDB.release()
|
self.mxDB.release()
|
||||||
|
|
||||||
|
def logBidEvent(self, bid_id, event_type, event_msg, session):
|
||||||
|
self.log.debug('logBidEvent %s %s', bid_id.hex(), event_type)
|
||||||
|
self.logEvent(Concepts.BID, bid_id, event_type, event_msg, session)
|
||||||
|
|
||||||
def countBidEvents(self, bid, event_type, session):
|
def countBidEvents(self, bid, event_type, session):
|
||||||
q = session.execute('SELECT COUNT(*) FROM eventlog WHERE linked_type = {} AND linked_id = x\'{}\' AND event_type = {}'.format(int(TableTypes.BID), bid.bid_id.hex(), int(event_type))).first()
|
q = session.execute('SELECT COUNT(*) FROM eventlog WHERE linked_type = {} AND linked_id = x\'{}\' AND event_type = {}'.format(int(Concepts.BID), bid.bid_id.hex(), int(event_type))).first()
|
||||||
return q[0]
|
return q[0]
|
||||||
|
|
||||||
|
def getEvents(self, linked_type, linked_id):
|
||||||
|
events = []
|
||||||
|
self.mxDB.acquire()
|
||||||
|
try:
|
||||||
|
session = scoped_session(self.session_factory)
|
||||||
|
for entry in session.query(EventLog).filter(sa.and_(EventLog.linked_type == linked_type, EventLog.linked_id == linked_id)):
|
||||||
|
events.append(entry)
|
||||||
|
return events
|
||||||
|
finally:
|
||||||
|
session.close()
|
||||||
|
session.remove()
|
||||||
|
self.mxDB.release()
|
||||||
|
|
||||||
def postBid(self, offer_id, amount, addr_send_from=None, extra_options={}):
|
def postBid(self, offer_id, amount, addr_send_from=None, extra_options={}):
|
||||||
# Bid to send bid.amount * bid.rate of coin_to in exchange for bid.amount of coin_from
|
# Bid to send bid.amount * bid.rate of coin_to in exchange for bid.amount of coin_from
|
||||||
self.log.debug('postBid %s', offer_id.hex())
|
self.log.debug('postBid %s', offer_id.hex())
|
||||||
|
@ -1838,13 +1854,13 @@ class BasicSwap(BaseApp):
|
||||||
|
|
||||||
def list_bid_events(self, bid_id, session):
|
def list_bid_events(self, bid_id, session):
|
||||||
query_str = 'SELECT created_at, event_type, event_msg FROM eventlog ' + \
|
query_str = 'SELECT created_at, event_type, event_msg FROM eventlog ' + \
|
||||||
'WHERE active_ind = 1 AND linked_type = {} AND linked_id = x\'{}\' '.format(TableTypes.BID, bid_id.hex())
|
'WHERE active_ind = 1 AND linked_type = {} AND linked_id = x\'{}\' '.format(Concepts.BID, bid_id.hex())
|
||||||
q = session.execute(query_str)
|
q = session.execute(query_str)
|
||||||
events = []
|
events = []
|
||||||
for row in q:
|
for row in q:
|
||||||
events.append({'at': row[0], 'desc': describeEventEntry(row[1], row[2])})
|
events.append({'at': row[0], 'desc': describeEventEntry(row[1], row[2])})
|
||||||
|
|
||||||
query_str = 'SELECT created_at, trigger_at FROM eventqueue ' + \
|
query_str = 'SELECT created_at, trigger_at FROM actions ' + \
|
||||||
'WHERE active_ind = 1 AND linked_id = x\'{}\' '.format(bid_id.hex())
|
'WHERE active_ind = 1 AND linked_id = x\'{}\' '.format(bid_id.hex())
|
||||||
q = session.execute(query_str)
|
q = session.execute(query_str)
|
||||||
for row in q:
|
for row in q:
|
||||||
|
@ -1962,21 +1978,21 @@ class BasicSwap(BaseApp):
|
||||||
ensure(xmr_offer, 'XMR offer not found: {}.'.format(offer_id.hex()))
|
ensure(xmr_offer, 'XMR offer not found: {}.'.format(offer_id.hex()))
|
||||||
ensure(offer.expire_at > int(time.time()), 'Offer has expired')
|
ensure(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_from = Coins(offer.coin_from)
|
||||||
coin_to = Coins(offer.coin_to)
|
coin_to = Coins(offer.coin_to)
|
||||||
ci_from = self.ci(coin_from)
|
ci_from = self.ci(coin_from)
|
||||||
ci_to = self.ci(coin_to)
|
ci_to = self.ci(coin_to)
|
||||||
|
|
||||||
|
valid_for_seconds = extra_options.get('valid_for_seconds', 60 * 10)
|
||||||
bid_rate = extra_options.get('bid_rate', offer.rate)
|
bid_rate = extra_options.get('bid_rate', offer.rate)
|
||||||
|
amount_to = int((int(amount) * bid_rate) // ci_from.COIN())
|
||||||
|
|
||||||
|
if not (self.debug and extra_options.get('debug_skip_validation', False)):
|
||||||
|
self.validateBidValidTime(offer.swap_type, offer.coin_from, offer.coin_to, valid_for_seconds)
|
||||||
self.validateBidAmount(offer, amount, bid_rate)
|
self.validateBidAmount(offer, amount, bid_rate)
|
||||||
|
|
||||||
self.checkSynced(coin_from, coin_to)
|
self.checkSynced(coin_from, coin_to)
|
||||||
|
|
||||||
amount_to = int((int(amount) * bid_rate) // ci_from.COIN())
|
|
||||||
|
|
||||||
balance_to = ci_to.getSpendableBalance()
|
balance_to = ci_to.getSpendableBalance()
|
||||||
ensure(balance_to > amount_to, '{} spendable balance is too low: {}'.format(ci_to.coin_name(), ci_to.format_amount(balance_to)))
|
ensure(balance_to > amount_to, '{} spendable balance is too low: {}'.format(ci_to.coin_name(), ci_to.format_amount(balance_to)))
|
||||||
|
|
||||||
|
@ -2954,7 +2970,7 @@ class BasicSwap(BaseApp):
|
||||||
if bid.was_sent:
|
if bid.was_sent:
|
||||||
delay = random.randrange(self.min_delay_event, self.max_delay_event)
|
delay = random.randrange(self.min_delay_event, self.max_delay_event)
|
||||||
self.log.info('Sending xmr swap chain B lock tx for bid %s in %d seconds', bid_id.hex(), delay)
|
self.log.info('Sending xmr swap chain B lock tx for bid %s in %d seconds', bid_id.hex(), delay)
|
||||||
self.createEventInSession(delay, EventTypes.SEND_XMR_SWAP_LOCK_TX_B, bid_id, session)
|
self.createActionInSession(delay, ActionTypes.SEND_XMR_SWAP_LOCK_TX_B, bid_id, session)
|
||||||
# bid.setState(BidStates.SWAP_DELAYING)
|
# bid.setState(BidStates.SWAP_DELAYING)
|
||||||
|
|
||||||
if bid_changed:
|
if bid_changed:
|
||||||
|
@ -3001,7 +3017,7 @@ class BasicSwap(BaseApp):
|
||||||
if bid.was_received:
|
if bid.was_received:
|
||||||
delay = random.randrange(self.min_delay_event, self.max_delay_event)
|
delay = random.randrange(self.min_delay_event, self.max_delay_event)
|
||||||
self.log.info('Releasing xmr script coin lock tx for bid %s in %d seconds', bid_id.hex(), delay)
|
self.log.info('Releasing xmr script coin lock tx for bid %s in %d seconds', bid_id.hex(), delay)
|
||||||
self.createEventInSession(delay, EventTypes.SEND_XMR_LOCK_RELEASE, bid_id, session)
|
self.createActionInSession(delay, ActionTypes.SEND_XMR_LOCK_RELEASE, bid_id, session)
|
||||||
|
|
||||||
if bid_changed:
|
if bid_changed:
|
||||||
self.saveBidInSession(bid_id, bid, session, xmr_swap)
|
self.saveBidInSession(bid_id, bid, session, xmr_swap)
|
||||||
|
@ -3018,11 +3034,11 @@ class BasicSwap(BaseApp):
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.log.debug('getrawtransaction lock spend tx failed: %s', str(e))
|
self.log.debug('getrawtransaction lock spend tx failed: %s', str(e))
|
||||||
elif state == BidStates.XMR_SWAP_SCRIPT_TX_REDEEMED:
|
elif state == BidStates.XMR_SWAP_SCRIPT_TX_REDEEMED:
|
||||||
if bid.was_received and self.countQueuedEvents(session, bid_id, EventTypes.REDEEM_XMR_SWAP_LOCK_TX_B) < 1:
|
if bid.was_received and self.countQueuedActions(session, bid_id, ActionTypes.REDEEM_XMR_SWAP_LOCK_TX_B) < 1:
|
||||||
bid.setState(BidStates.SWAP_DELAYING)
|
bid.setState(BidStates.SWAP_DELAYING)
|
||||||
delay = random.randrange(self.min_delay_event, self.max_delay_event)
|
delay = random.randrange(self.min_delay_event, self.max_delay_event)
|
||||||
self.log.info('Redeeming coin b lock tx for bid %s in %d seconds', bid_id.hex(), delay)
|
self.log.info('Redeeming coin b lock tx for bid %s in %d seconds', bid_id.hex(), delay)
|
||||||
self.createEventInSession(delay, EventTypes.REDEEM_XMR_SWAP_LOCK_TX_B, bid_id, session)
|
self.createActionInSession(delay, ActionTypes.REDEEM_XMR_SWAP_LOCK_TX_B, bid_id, session)
|
||||||
self.saveBidInSession(bid_id, bid, session, xmr_swap)
|
self.saveBidInSession(bid_id, bid, session, xmr_swap)
|
||||||
session.commit()
|
session.commit()
|
||||||
elif state == BidStates.XMR_SWAP_NOSCRIPT_TX_REDEEMED:
|
elif state == BidStates.XMR_SWAP_NOSCRIPT_TX_REDEEMED:
|
||||||
|
@ -3411,7 +3427,7 @@ class BasicSwap(BaseApp):
|
||||||
if bid.xmr_b_lock_tx is not None:
|
if bid.xmr_b_lock_tx is not None:
|
||||||
delay = random.randrange(self.min_delay_event, self.max_delay_event)
|
delay = random.randrange(self.min_delay_event, self.max_delay_event)
|
||||||
self.log.info('Recovering xmr swap chain B lock tx for bid %s in %d seconds', bid_id.hex(), delay)
|
self.log.info('Recovering xmr swap chain B lock tx for bid %s in %d seconds', bid_id.hex(), delay)
|
||||||
self.createEventInSession(delay, EventTypes.RECOVER_XMR_SWAP_LOCK_TX_B, bid_id, session)
|
self.createActionInSession(delay, ActionTypes.RECOVER_XMR_SWAP_LOCK_TX_B, bid_id, session)
|
||||||
else:
|
else:
|
||||||
bid.setState(BidStates.XMR_SWAP_FAILED_REFUNDED)
|
bid.setState(BidStates.XMR_SWAP_FAILED_REFUNDED)
|
||||||
|
|
||||||
|
@ -3524,49 +3540,49 @@ class BasicSwap(BaseApp):
|
||||||
finally:
|
finally:
|
||||||
self.mxDB.release()
|
self.mxDB.release()
|
||||||
|
|
||||||
def countQueuedEvents(self, session, bid_id, event_type):
|
def countQueuedActions(self, session, bid_id, action_type):
|
||||||
q = session.query(EventQueue).filter(sa.and_(EventQueue.active_ind == 1, EventQueue.linked_id == bid_id, EventQueue.event_type == event_type))
|
q = session.query(Action).filter(sa.and_(Action.active_ind == 1, Action.linked_id == bid_id, Action.action_type == action_type))
|
||||||
return q.count()
|
return q.count()
|
||||||
|
|
||||||
def checkEvents(self):
|
def checkQueuedActions(self):
|
||||||
self.mxDB.acquire()
|
self.mxDB.acquire()
|
||||||
now = int(time.time())
|
now = int(time.time())
|
||||||
session = None
|
session = None
|
||||||
try:
|
try:
|
||||||
session = scoped_session(self.session_factory)
|
session = scoped_session(self.session_factory)
|
||||||
|
|
||||||
q = session.query(EventQueue).filter(sa.and_(EventQueue.active_ind == 1, EventQueue.trigger_at <= now))
|
q = session.query(Action).filter(sa.and_(Action.active_ind == 1, Action.trigger_at <= now))
|
||||||
for row in q:
|
for row in q:
|
||||||
try:
|
try:
|
||||||
if row.event_type == EventTypes.ACCEPT_BID:
|
if row.action_type == ActionTypes.ACCEPT_BID:
|
||||||
self.acceptBid(row.linked_id)
|
self.acceptBid(row.linked_id)
|
||||||
elif row.event_type == EventTypes.ACCEPT_XMR_BID:
|
elif row.action_type == ActionTypes.ACCEPT_XMR_BID:
|
||||||
self.acceptXmrBid(row.linked_id)
|
self.acceptXmrBid(row.linked_id)
|
||||||
elif row.event_type == EventTypes.SIGN_XMR_SWAP_LOCK_TX_A:
|
elif row.action_type == ActionTypes.SIGN_XMR_SWAP_LOCK_TX_A:
|
||||||
self.sendXmrBidTxnSigsFtoL(row.linked_id, session)
|
self.sendXmrBidTxnSigsFtoL(row.linked_id, session)
|
||||||
elif row.event_type == EventTypes.SEND_XMR_SWAP_LOCK_TX_A:
|
elif row.action_type == ActionTypes.SEND_XMR_SWAP_LOCK_TX_A:
|
||||||
self.sendXmrBidCoinALockTx(row.linked_id, session)
|
self.sendXmrBidCoinALockTx(row.linked_id, session)
|
||||||
elif row.event_type == EventTypes.SEND_XMR_SWAP_LOCK_TX_B:
|
elif row.action_type == ActionTypes.SEND_XMR_SWAP_LOCK_TX_B:
|
||||||
self.sendXmrBidCoinBLockTx(row.linked_id, session)
|
self.sendXmrBidCoinBLockTx(row.linked_id, session)
|
||||||
elif row.event_type == EventTypes.SEND_XMR_LOCK_RELEASE:
|
elif row.action_type == ActionTypes.SEND_XMR_LOCK_RELEASE:
|
||||||
self.sendXmrBidLockRelease(row.linked_id, session)
|
self.sendXmrBidLockRelease(row.linked_id, session)
|
||||||
elif row.event_type == EventTypes.REDEEM_XMR_SWAP_LOCK_TX_A:
|
elif row.action_type == ActionTypes.REDEEM_XMR_SWAP_LOCK_TX_A:
|
||||||
self.redeemXmrBidCoinALockTx(row.linked_id, session)
|
self.redeemXmrBidCoinALockTx(row.linked_id, session)
|
||||||
elif row.event_type == EventTypes.REDEEM_XMR_SWAP_LOCK_TX_B:
|
elif row.action_type == ActionTypes.REDEEM_XMR_SWAP_LOCK_TX_B:
|
||||||
self.redeemXmrBidCoinBLockTx(row.linked_id, session)
|
self.redeemXmrBidCoinBLockTx(row.linked_id, session)
|
||||||
elif row.event_type == EventTypes.RECOVER_XMR_SWAP_LOCK_TX_B:
|
elif row.action_type == ActionTypes.RECOVER_XMR_SWAP_LOCK_TX_B:
|
||||||
self.recoverXmrBidCoinBLockTx(row.linked_id, session)
|
self.recoverXmrBidCoinBLockTx(row.linked_id, session)
|
||||||
else:
|
else:
|
||||||
self.log.warning('Unknown event type: %d', row.event_type)
|
self.log.warning('Unknown event type: %d', row.event_type)
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
if self.debug:
|
if self.debug:
|
||||||
self.log.error(traceback.format_exc())
|
self.log.error(traceback.format_exc())
|
||||||
self.log.error('checkEvents failed: {}'.format(str(ex)))
|
self.log.error('checkQueuedActions failed: {}'.format(str(ex)))
|
||||||
|
|
||||||
if self.debug:
|
if self.debug:
|
||||||
session.execute('UPDATE eventqueue SET active_ind = 2 WHERE trigger_at <= {}'.format(now))
|
session.execute('UPDATE actions SET active_ind = 2 WHERE trigger_at <= {}'.format(now))
|
||||||
else:
|
else:
|
||||||
session.execute('DELETE FROM eventqueue WHERE trigger_at <= {}'.format(now))
|
session.execute('DELETE FROM actions WHERE trigger_at <= {}'.format(now))
|
||||||
|
|
||||||
session.commit()
|
session.commit()
|
||||||
finally:
|
finally:
|
||||||
|
@ -3778,7 +3794,7 @@ class BasicSwap(BaseApp):
|
||||||
self.mxDB.acquire()
|
self.mxDB.acquire()
|
||||||
use_session = scoped_session(self.session_factory)
|
use_session = scoped_session(self.session_factory)
|
||||||
|
|
||||||
link = use_session.query(AutomationLink).filter_by(active_ind=1, linked_type=TableTypes.OFFER, linked_id=offer.offer_id).first()
|
link = use_session.query(AutomationLink).filter_by(active_ind=1, linked_type=Concepts.OFFER, linked_id=offer.offer_id).first()
|
||||||
if not link:
|
if not link:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@ -3787,11 +3803,20 @@ class BasicSwap(BaseApp):
|
||||||
|
|
||||||
self.log.debug('Evaluating against strategy {}'.format(strategy.record_id))
|
self.log.debug('Evaluating against strategy {}'.format(strategy.record_id))
|
||||||
|
|
||||||
if opts.get('full_amount_only', False) is True:
|
if not offer.amount_negotiable:
|
||||||
if bid.amount != offer.amount_from:
|
if bid.amount != offer.amount_from:
|
||||||
self.log.info('Not auto accepting bid %s, want exact amount match', bid.bid_id.hex())
|
self.log.info('Not auto accepting bid %s, want exact amount match', bid.bid_id.hex())
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
if bid.amount < offer.min_bid_amount:
|
||||||
|
self.log.info('Not auto accepting bid %s, bid amount below minimum', bid.bid_id.hex())
|
||||||
|
return False
|
||||||
|
|
||||||
|
if opts.get('exact_rate_only', False) is True:
|
||||||
|
if bid.rate != offer.rate:
|
||||||
|
self.log.info('Not auto accepting bid %s, want exact rate match', bid.bid_id.hex())
|
||||||
|
return False
|
||||||
|
|
||||||
max_bids = opts.get('max_bids', 1)
|
max_bids = opts.get('max_bids', 1)
|
||||||
# Auto accept bid if set and no other non-abandoned bid for this order exists
|
# Auto accept bid if set and no other non-abandoned bid for this order exists
|
||||||
if self.countAcceptedBids(offer.offer_id) >= max_bids:
|
if self.countAcceptedBids(offer.offer_id) >= max_bids:
|
||||||
|
@ -3909,7 +3934,7 @@ class BasicSwap(BaseApp):
|
||||||
if self.shouldAutoAcceptBid(offer, bid):
|
if self.shouldAutoAcceptBid(offer, bid):
|
||||||
delay = random.randrange(self.min_delay_event, self.max_delay_event)
|
delay = random.randrange(self.min_delay_event, self.max_delay_event)
|
||||||
self.log.info('Auto accepting bid %s in %d seconds', bid_id.hex(), delay)
|
self.log.info('Auto accepting bid %s in %d seconds', bid_id.hex(), delay)
|
||||||
self.createEvent(delay, EventTypes.ACCEPT_BID, bid_id)
|
self.createAction(delay, ActionTypes.ACCEPT_BID, bid_id)
|
||||||
|
|
||||||
def processBidAccept(self, msg):
|
def processBidAccept(self, msg):
|
||||||
self.log.debug('Processing bid accepted msg %s', msg['msgid'])
|
self.log.debug('Processing bid accepted msg %s', msg['msgid'])
|
||||||
|
@ -4029,7 +4054,7 @@ class BasicSwap(BaseApp):
|
||||||
if self.shouldAutoAcceptBid(offer, bid, session):
|
if self.shouldAutoAcceptBid(offer, bid, session):
|
||||||
delay = random.randrange(self.min_delay_event, self.max_delay_event)
|
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)
|
self.log.info('Auto accepting xmr bid %s in %d seconds', bid.bid_id.hex(), delay)
|
||||||
self.createEventInSession(delay, EventTypes.ACCEPT_XMR_BID, bid.bid_id, session)
|
self.createActionInSession(delay, ActionTypes.ACCEPT_XMR_BID, bid.bid_id, session)
|
||||||
bid.setState(BidStates.SWAP_DELAYING)
|
bid.setState(BidStates.SWAP_DELAYING)
|
||||||
|
|
||||||
self.saveBidInSession(bid.bid_id, bid, session, xmr_swap)
|
self.saveBidInSession(bid.bid_id, bid, session, xmr_swap)
|
||||||
|
@ -4087,7 +4112,7 @@ class BasicSwap(BaseApp):
|
||||||
|
|
||||||
delay = random.randrange(self.min_delay_event, self.max_delay_event)
|
delay = random.randrange(self.min_delay_event, self.max_delay_event)
|
||||||
self.log.info('Responding to xmr bid accept %s in %d seconds', bid.bid_id.hex(), delay)
|
self.log.info('Responding to xmr bid accept %s in %d seconds', bid.bid_id.hex(), delay)
|
||||||
self.createEventInSession(delay, EventTypes.SIGN_XMR_SWAP_LOCK_TX_A, bid.bid_id, session)
|
self.createActionInSession(delay, ActionTypes.SIGN_XMR_SWAP_LOCK_TX_A, bid.bid_id, session)
|
||||||
|
|
||||||
def processXmrBid(self, msg):
|
def processXmrBid(self, msg):
|
||||||
# MSG1L
|
# MSG1L
|
||||||
|
@ -4437,7 +4462,7 @@ class BasicSwap(BaseApp):
|
||||||
if num_retries < 5 and (ci_to.is_transient_error(ex) or self.is_transient_error(ex)):
|
if num_retries < 5 and (ci_to.is_transient_error(ex) or self.is_transient_error(ex)):
|
||||||
delay = random.randrange(self.min_delay_retry, self.max_delay_retry)
|
delay = random.randrange(self.min_delay_retry, self.max_delay_retry)
|
||||||
self.log.info('Retrying sending xmr swap chain B lock tx for bid %s in %d seconds', bid_id.hex(), delay)
|
self.log.info('Retrying sending xmr swap chain B lock tx for bid %s in %d seconds', bid_id.hex(), delay)
|
||||||
self.createEventInSession(delay, EventTypes.SEND_XMR_SWAP_LOCK_TX_B, bid_id, session)
|
self.createActionInSession(delay, ActionTypes.SEND_XMR_SWAP_LOCK_TX_B, bid_id, session)
|
||||||
else:
|
else:
|
||||||
self.setBidError(bid_id, bid, 'publishBLockTx failed: ' + str(ex), save_bid=False)
|
self.setBidError(bid_id, bid, 'publishBLockTx failed: ' + str(ex), save_bid=False)
|
||||||
self.saveBidInSession(bid_id, bid, session, xmr_swap, save_in_progress=offer)
|
self.saveBidInSession(bid_id, bid, session, xmr_swap, save_in_progress=offer)
|
||||||
|
@ -4585,7 +4610,7 @@ class BasicSwap(BaseApp):
|
||||||
if num_retries < 100 and (ci_to.is_transient_error(ex) or self.is_transient_error(ex)):
|
if num_retries < 100 and (ci_to.is_transient_error(ex) or self.is_transient_error(ex)):
|
||||||
delay = random.randrange(self.min_delay_retry, self.max_delay_retry)
|
delay = random.randrange(self.min_delay_retry, self.max_delay_retry)
|
||||||
self.log.info('Retrying sending xmr swap chain B spend tx for bid %s in %d seconds', bid_id.hex(), delay)
|
self.log.info('Retrying sending xmr swap chain B spend tx for bid %s in %d seconds', bid_id.hex(), delay)
|
||||||
self.createEventInSession(delay, EventTypes.REDEEM_XMR_SWAP_LOCK_TX_B, bid_id, session)
|
self.createActionInSession(delay, ActionTypes.REDEEM_XMR_SWAP_LOCK_TX_B, bid_id, session)
|
||||||
else:
|
else:
|
||||||
self.setBidError(bid_id, bid, 'spendBLockTx failed: ' + str(ex), save_bid=False)
|
self.setBidError(bid_id, bid, 'spendBLockTx failed: ' + str(ex), save_bid=False)
|
||||||
self.saveBidInSession(bid_id, bid, session, xmr_swap, save_in_progress=offer)
|
self.saveBidInSession(bid_id, bid, session, xmr_swap, save_in_progress=offer)
|
||||||
|
@ -4644,7 +4669,7 @@ class BasicSwap(BaseApp):
|
||||||
if num_retries < 100 and (ci_to.is_transient_error(ex) or self.is_transient_error(ex)):
|
if num_retries < 100 and (ci_to.is_transient_error(ex) or self.is_transient_error(ex)):
|
||||||
delay = random.randrange(self.min_delay_retry, self.max_delay_retry)
|
delay = random.randrange(self.min_delay_retry, self.max_delay_retry)
|
||||||
self.log.info('Retrying sending xmr swap chain B refund tx for bid %s in %d seconds', bid_id.hex(), delay)
|
self.log.info('Retrying sending xmr swap chain B refund tx for bid %s in %d seconds', bid_id.hex(), delay)
|
||||||
self.createEventInSession(delay, EventTypes.RECOVER_XMR_SWAP_LOCK_TX_B, bid_id, session)
|
self.createActionInSession(delay, ActionTypes.RECOVER_XMR_SWAP_LOCK_TX_B, bid_id, session)
|
||||||
else:
|
else:
|
||||||
self.setBidError(bid_id, bid, 'spendBLockTx for refund failed: ' + str(ex), save_bid=False)
|
self.setBidError(bid_id, bid, 'spendBLockTx for refund failed: ' + str(ex), save_bid=False)
|
||||||
self.saveBidInSession(bid_id, bid, session, xmr_swap, save_in_progress=offer)
|
self.saveBidInSession(bid_id, bid, session, xmr_swap, save_in_progress=offer)
|
||||||
|
@ -4710,7 +4735,7 @@ class BasicSwap(BaseApp):
|
||||||
|
|
||||||
delay = random.randrange(self.min_delay_event, self.max_delay_event)
|
delay = random.randrange(self.min_delay_event, self.max_delay_event)
|
||||||
self.log.info('Sending coin A lock tx for xmr bid %s in %d seconds', bid_id.hex(), delay)
|
self.log.info('Sending coin A lock tx for xmr bid %s in %d seconds', bid_id.hex(), delay)
|
||||||
self.createEvent(delay, EventTypes.SEND_XMR_SWAP_LOCK_TX_A, bid_id)
|
self.createAction(delay, ActionTypes.SEND_XMR_SWAP_LOCK_TX_A, bid_id)
|
||||||
|
|
||||||
bid.setState(BidStates.SWAP_DELAYING)
|
bid.setState(BidStates.SWAP_DELAYING)
|
||||||
self.saveBid(bid_id, bid, xmr_swap=xmr_swap)
|
self.saveBid(bid_id, bid, xmr_swap=xmr_swap)
|
||||||
|
@ -4829,7 +4854,7 @@ class BasicSwap(BaseApp):
|
||||||
|
|
||||||
delay = random.randrange(self.min_delay_event, self.max_delay_event)
|
delay = random.randrange(self.min_delay_event, self.max_delay_event)
|
||||||
self.log.info('Redeeming coin A lock tx for xmr bid %s in %d seconds', bid_id.hex(), delay)
|
self.log.info('Redeeming coin A lock tx for xmr bid %s in %d seconds', bid_id.hex(), delay)
|
||||||
self.createEvent(delay, EventTypes.REDEEM_XMR_SWAP_LOCK_TX_A, bid_id)
|
self.createAction(delay, ActionTypes.REDEEM_XMR_SWAP_LOCK_TX_A, bid_id)
|
||||||
|
|
||||||
bid.setState(BidStates.XMR_SWAP_LOCK_RELEASED)
|
bid.setState(BidStates.XMR_SWAP_LOCK_RELEASED)
|
||||||
self.saveBid(bid_id, bid, xmr_swap=xmr_swap)
|
self.saveBid(bid_id, bid, xmr_swap=xmr_swap)
|
||||||
|
@ -4866,6 +4891,12 @@ class BasicSwap(BaseApp):
|
||||||
self.log.error('processMsg %s', str(ex))
|
self.log.error('processMsg %s', str(ex))
|
||||||
if self.debug:
|
if self.debug:
|
||||||
self.log.error(traceback.format_exc())
|
self.log.error(traceback.format_exc())
|
||||||
|
self.logEvent(Concepts.NETWORK_MESSAGE,
|
||||||
|
bytes.fromhex(msg['msgid']),
|
||||||
|
EventLogTypes.ERROR,
|
||||||
|
str(ex),
|
||||||
|
None)
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
self.mxDB.release()
|
self.mxDB.release()
|
||||||
|
|
||||||
|
@ -4940,9 +4971,9 @@ class BasicSwap(BaseApp):
|
||||||
self.expireMessages()
|
self.expireMessages()
|
||||||
self._last_checked_expired = now
|
self._last_checked_expired = now
|
||||||
|
|
||||||
if now - self._last_checked_events >= self.check_events_seconds:
|
if now - self._last_checked_actions >= self.check_actions_seconds:
|
||||||
self.checkEvents()
|
self.checkQueuedActions()
|
||||||
self._last_checked_events = now
|
self._last_checked_actions = now
|
||||||
|
|
||||||
if now - self._last_checked_xmr_swaps >= self.check_xmr_swaps_seconds:
|
if now - self._last_checked_xmr_swaps >= self.check_xmr_swaps_seconds:
|
||||||
self.checkXmrSwaps()
|
self.checkXmrSwaps()
|
||||||
|
|
|
@ -122,7 +122,7 @@ class TxTypes(IntEnum):
|
||||||
XMR_SWAP_B_LOCK = auto()
|
XMR_SWAP_B_LOCK = auto()
|
||||||
|
|
||||||
|
|
||||||
class EventTypes(IntEnum):
|
class ActionTypes(IntEnum):
|
||||||
ACCEPT_BID = auto()
|
ACCEPT_BID = auto()
|
||||||
ACCEPT_XMR_BID = auto()
|
ACCEPT_XMR_BID = auto()
|
||||||
SIGN_XMR_SWAP_LOCK_TX_A = auto()
|
SIGN_XMR_SWAP_LOCK_TX_A = auto()
|
||||||
|
@ -155,6 +155,7 @@ class EventLogTypes(IntEnum):
|
||||||
LOCK_TX_B_SPEND_TX_PUBLISHED = auto()
|
LOCK_TX_B_SPEND_TX_PUBLISHED = auto()
|
||||||
LOCK_TX_A_REFUND_TX_SEEN = auto()
|
LOCK_TX_A_REFUND_TX_SEEN = auto()
|
||||||
LOCK_TX_A_REFUND_SPEND_TX_SEEN = auto()
|
LOCK_TX_A_REFUND_SPEND_TX_SEEN = auto()
|
||||||
|
ERROR = auto()
|
||||||
|
|
||||||
|
|
||||||
class XmrSplitMsgTypes(IntEnum):
|
class XmrSplitMsgTypes(IntEnum):
|
||||||
|
@ -331,6 +332,8 @@ def describeEventEntry(event_type, event_msg):
|
||||||
return 'Lock tx A refund spend tx seen in chain'
|
return 'Lock tx A refund spend tx seen in chain'
|
||||||
if event_type == EventLogTypes.SYSTEM_WARNING:
|
if event_type == EventLogTypes.SYSTEM_WARNING:
|
||||||
return 'Warning: ' + event_msg
|
return 'Warning: ' + event_msg
|
||||||
|
if event_type == EventLogTypes.ERROR:
|
||||||
|
return 'Error: ' + event_msg
|
||||||
|
|
||||||
|
|
||||||
def getVoutByAddress(txjs, p2sh):
|
def getVoutByAddress(txjs, p2sh):
|
||||||
|
|
|
@ -17,16 +17,19 @@ CURRENT_DB_DATA_VERSION = 1
|
||||||
Base = declarative_base()
|
Base = declarative_base()
|
||||||
|
|
||||||
|
|
||||||
class TableTypes(IntEnum):
|
class Concepts(IntEnum):
|
||||||
OFFER = auto()
|
OFFER = auto()
|
||||||
BID = auto()
|
BID = auto()
|
||||||
|
NETWORK_MESSAGE = auto()
|
||||||
|
|
||||||
|
|
||||||
def strTableTypes(state):
|
def strConcepts(state):
|
||||||
if state == TableTypes.OFFER:
|
if state == Concepts.OFFER:
|
||||||
return 'Offer'
|
return 'Offer'
|
||||||
if state == TableTypes.BID:
|
if state == Concepts.BID:
|
||||||
return 'Bid'
|
return 'Bid'
|
||||||
|
if state == Concepts.NETWORK_MESSAGE:
|
||||||
|
return 'Network Message'
|
||||||
return 'Unknown'
|
return 'Unknown'
|
||||||
|
|
||||||
|
|
||||||
|
@ -245,16 +248,16 @@ class SmsgAddress(Base):
|
||||||
note = sa.Column(sa.String)
|
note = sa.Column(sa.String)
|
||||||
|
|
||||||
|
|
||||||
class EventQueue(Base):
|
class Action(Base):
|
||||||
__tablename__ = 'eventqueue'
|
__tablename__ = 'actions'
|
||||||
|
|
||||||
event_id = sa.Column(sa.Integer, primary_key=True, autoincrement=True)
|
action_id = sa.Column(sa.Integer, primary_key=True, autoincrement=True)
|
||||||
active_ind = sa.Column(sa.Integer)
|
active_ind = sa.Column(sa.Integer)
|
||||||
created_at = sa.Column(sa.BigInteger)
|
created_at = sa.Column(sa.BigInteger)
|
||||||
trigger_at = sa.Column(sa.BigInteger)
|
trigger_at = sa.Column(sa.BigInteger)
|
||||||
linked_id = sa.Column(sa.LargeBinary)
|
linked_id = sa.Column(sa.LargeBinary)
|
||||||
event_type = sa.Column(sa.Integer)
|
action_type = sa.Column(sa.Integer)
|
||||||
event_data = sa.Column(sa.LargeBinary)
|
action_data = sa.Column(sa.LargeBinary)
|
||||||
|
|
||||||
|
|
||||||
class EventLog(Base):
|
class EventLog(Base):
|
||||||
|
|
|
@ -8,7 +8,7 @@ import json
|
||||||
|
|
||||||
from sqlalchemy.orm import scoped_session
|
from sqlalchemy.orm import scoped_session
|
||||||
from .db import (
|
from .db import (
|
||||||
TableTypes,
|
Concepts,
|
||||||
AutomationStrategy,
|
AutomationStrategy,
|
||||||
CURRENT_DB_VERSION,
|
CURRENT_DB_VERSION,
|
||||||
CURRENT_DB_DATA_VERSION)
|
CURRENT_DB_DATA_VERSION)
|
||||||
|
@ -27,15 +27,15 @@ def upgradeDatabaseData(self, data_version):
|
||||||
session.add(AutomationStrategy(
|
session.add(AutomationStrategy(
|
||||||
active_ind=1,
|
active_ind=1,
|
||||||
label='Accept All',
|
label='Accept All',
|
||||||
type_ind=TableTypes.OFFER,
|
type_ind=Concepts.OFFER,
|
||||||
data=json.dumps({'full_amount_only': True,
|
data=json.dumps({'exact_rate_only': True,
|
||||||
'max_bids': 1}).encode('utf-8'),
|
'max_bids': 1}).encode('utf-8'),
|
||||||
only_known_identities=False))
|
only_known_identities=False))
|
||||||
session.add(AutomationStrategy(
|
session.add(AutomationStrategy(
|
||||||
active_ind=1,
|
active_ind=1,
|
||||||
label='Accept Known',
|
label='Accept Known',
|
||||||
type_ind=TableTypes.OFFER,
|
type_ind=Concepts.OFFER,
|
||||||
data=json.dumps({'full_amount_only': True,
|
data=json.dumps({'exact_rate_only': True,
|
||||||
'max_bids': 1}).encode('utf-8'),
|
'max_bids': 1}).encode('utf-8'),
|
||||||
only_known_identities=True,
|
only_known_identities=True,
|
||||||
note='Accept bids from identities with previously successful swaps only'))
|
note='Accept bids from identities with previously successful swaps only'))
|
||||||
|
@ -168,6 +168,7 @@ def upgradeDatabase(self, db_version):
|
||||||
|
|
||||||
session.execute('ALTER TABLE wallets ADD COLUMN active_ind INTEGER')
|
session.execute('ALTER TABLE wallets ADD COLUMN active_ind INTEGER')
|
||||||
session.execute('ALTER TABLE knownidentities ADD COLUMN active_ind INTEGER')
|
session.execute('ALTER TABLE knownidentities ADD COLUMN active_ind INTEGER')
|
||||||
|
session.execute('ALTER TABLE eventqueue RENAME TO actions')
|
||||||
|
|
||||||
if current_version != db_version:
|
if current_version != db_version:
|
||||||
self.db_version = db_version
|
self.db_version = db_version
|
||||||
|
|
|
@ -16,7 +16,7 @@ from basicswap.util import (
|
||||||
ensure,
|
ensure,
|
||||||
)
|
)
|
||||||
from basicswap.db import (
|
from basicswap.db import (
|
||||||
strTableTypes,
|
strConcepts,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@ def page_automation_strategies(self, url_split, post_string):
|
||||||
|
|
||||||
formatted_strategies = []
|
formatted_strategies = []
|
||||||
for s in swap_client.listAutomationStrategies(filters):
|
for s in swap_client.listAutomationStrategies(filters):
|
||||||
formatted_strategies.append((s[0], s[1], strTableTypes(s[2])))
|
formatted_strategies.append((s[0], s[1], strConcepts(s[2])))
|
||||||
|
|
||||||
template = server.env.get_template('automation_strategies.html')
|
template = server.env.get_template('automation_strategies.html')
|
||||||
return bytes(template.render(
|
return bytes(template.render(
|
||||||
|
@ -93,7 +93,7 @@ def page_automation_strategy(self, url_split, post_string):
|
||||||
|
|
||||||
formatted_strategy = {
|
formatted_strategy = {
|
||||||
'label': strategy.label,
|
'label': strategy.label,
|
||||||
'type': strTableTypes(strategy.type_ind),
|
'type': strConcepts(strategy.type_ind),
|
||||||
'only_known_identities': 'True' if strategy.only_known_identities is True else 'False',
|
'only_known_identities': 'True' if strategy.only_known_identities is True else 'False',
|
||||||
'data': strategy.data,
|
'data': strategy.data,
|
||||||
'note': strategy.note,
|
'note': strategy.note,
|
||||||
|
|
|
@ -19,7 +19,7 @@ from .util import (
|
||||||
set_pagination_filters,
|
set_pagination_filters,
|
||||||
)
|
)
|
||||||
from basicswap.db import (
|
from basicswap.db import (
|
||||||
TableTypes,
|
Concepts,
|
||||||
)
|
)
|
||||||
from basicswap.util import (
|
from basicswap.util import (
|
||||||
ensure,
|
ensure,
|
||||||
|
@ -305,7 +305,7 @@ def page_newoffer(self, url_split, post_string):
|
||||||
|
|
||||||
automation_filters = {}
|
automation_filters = {}
|
||||||
automation_filters['sort_by'] = 'label'
|
automation_filters['sort_by'] = 'label'
|
||||||
automation_filters['type_ind'] = TableTypes.OFFER
|
automation_filters['type_ind'] = Concepts.OFFER
|
||||||
automation_strategies = swap_client.listAutomationStrategies(automation_filters)
|
automation_strategies = swap_client.listAutomationStrategies(automation_filters)
|
||||||
|
|
||||||
return bytes(template.render(
|
return bytes(template.render(
|
||||||
|
@ -454,7 +454,7 @@ def page_offer(self, url_split, post_string):
|
||||||
|
|
||||||
if offer.was_sent:
|
if offer.was_sent:
|
||||||
try:
|
try:
|
||||||
strategy = swap_client.getLinkedStrategy(TableTypes.OFFER, offer_id)
|
strategy = swap_client.getLinkedStrategy(Concepts.OFFER, offer_id)
|
||||||
data['automation_strat_id'] = strategy[0]
|
data['automation_strat_id'] = strategy[0]
|
||||||
data['automation_strat_label'] = strategy[1]
|
data['automation_strat_label'] = strategy[1]
|
||||||
except Exception:
|
except Exception:
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
# Copyright (c) 2020-2021 tecnovert
|
# Copyright (c) 2020-2022 tecnovert
|
||||||
# Distributed under the MIT software license, see the accompanying
|
# Distributed under the MIT software license, see the accompanying
|
||||||
# file LICENSE.txt or http://www.opensource.org/licenses/mit-license.php.
|
# file LICENSE.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
@ -140,6 +140,19 @@ def wait_for_bid_tx_state(delay_event, swap_client, bid_id, initiate_state, part
|
||||||
raise ValueError('wait_for_bid_tx_state timed out.')
|
raise ValueError('wait_for_bid_tx_state timed out.')
|
||||||
|
|
||||||
|
|
||||||
|
def wait_for_event(delay_event, swap_client, linked_type, linked_id, wait_for=20):
|
||||||
|
logging.info('wait_for_event')
|
||||||
|
|
||||||
|
for i in range(wait_for):
|
||||||
|
if delay_event.is_set():
|
||||||
|
raise ValueError('Test stopped.')
|
||||||
|
delay_event.wait(1)
|
||||||
|
rv = swap_client.getEvents(linked_type, linked_id)
|
||||||
|
if len(rv) > 0:
|
||||||
|
return rv
|
||||||
|
raise ValueError('wait_for_event timed out.')
|
||||||
|
|
||||||
|
|
||||||
def wait_for_offer(delay_event, swap_client, offer_id, wait_for=20):
|
def wait_for_offer(delay_event, swap_client, offer_id, wait_for=20):
|
||||||
logging.info('wait_for_offer %s', offer_id.hex())
|
logging.info('wait_for_offer %s', offer_id.hex())
|
||||||
for i in range(wait_for):
|
for i in range(wait_for):
|
||||||
|
|
|
@ -19,6 +19,9 @@ import subprocess
|
||||||
from urllib.request import urlopen
|
from urllib.request import urlopen
|
||||||
|
|
||||||
import basicswap.config as cfg
|
import basicswap.config as cfg
|
||||||
|
from basicswap.db import (
|
||||||
|
Concepts,
|
||||||
|
)
|
||||||
from basicswap.basicswap import (
|
from basicswap.basicswap import (
|
||||||
BasicSwap,
|
BasicSwap,
|
||||||
Coins,
|
Coins,
|
||||||
|
@ -61,6 +64,7 @@ from tests.basicswap.common import (
|
||||||
checkForks,
|
checkForks,
|
||||||
stopDaemons,
|
stopDaemons,
|
||||||
wait_for_bid,
|
wait_for_bid,
|
||||||
|
wait_for_event,
|
||||||
wait_for_offer,
|
wait_for_offer,
|
||||||
wait_for_no_offer,
|
wait_for_no_offer,
|
||||||
wait_for_none_active,
|
wait_for_none_active,
|
||||||
|
@ -845,7 +849,9 @@ class Test(BaseTest):
|
||||||
def test_09_auto_accept(self):
|
def test_09_auto_accept(self):
|
||||||
logging.info('---------- Test BTC to XMR auto accept')
|
logging.info('---------- Test BTC to XMR auto accept')
|
||||||
swap_clients = self.swap_clients
|
swap_clients = self.swap_clients
|
||||||
offer_id = swap_clients[0].postOffer(Coins.BTC, Coins.XMR, 11 * COIN, 101 * XMR_COIN, 10 * COIN, SwapTypes.XMR_SWAP, auto_accept_bids=True)
|
amt_swap = make_int(random.uniform(0.01, 11.0), scale=8, r=1)
|
||||||
|
rate_swap = make_int(random.uniform(10.0, 101.0), scale=12, r=1)
|
||||||
|
offer_id = swap_clients[0].postOffer(Coins.BTC, Coins.XMR, amt_swap, rate_swap, amt_swap, SwapTypes.XMR_SWAP, auto_accept_bids=True)
|
||||||
wait_for_offer(test_delay_event, swap_clients[1], offer_id)
|
wait_for_offer(test_delay_event, swap_clients[1], offer_id)
|
||||||
offer = swap_clients[1].listOffers(filters={'offer_id': offer_id})[0]
|
offer = swap_clients[1].listOffers(filters={'offer_id': offer_id})[0]
|
||||||
|
|
||||||
|
@ -853,6 +859,35 @@ class Test(BaseTest):
|
||||||
wait_for_bid(test_delay_event, swap_clients[0], bid_id, BidStates.SWAP_COMPLETED, wait_for=180)
|
wait_for_bid(test_delay_event, swap_clients[0], bid_id, BidStates.SWAP_COMPLETED, wait_for=180)
|
||||||
wait_for_bid(test_delay_event, swap_clients[1], bid_id, BidStates.SWAP_COMPLETED, sent=True)
|
wait_for_bid(test_delay_event, swap_clients[1], bid_id, BidStates.SWAP_COMPLETED, sent=True)
|
||||||
|
|
||||||
|
def test_09_1_auto_accept_multiple(self):
|
||||||
|
logging.info('---------- Test BTC to XMR auto accept multiple bids')
|
||||||
|
swap_clients = self.swap_clients
|
||||||
|
amt_swap = make_int(10, scale=8, r=1)
|
||||||
|
rate_swap = make_int(100, scale=12, r=1)
|
||||||
|
min_bid = make_int(1, scale=8, r=1)
|
||||||
|
|
||||||
|
extra_options = {
|
||||||
|
'amount_negotiable': True,
|
||||||
|
'automation_id': 1,
|
||||||
|
}
|
||||||
|
offer_id = swap_clients[0].postOffer(Coins.BTC, Coins.XMR, amt_swap, rate_swap, min_bid, SwapTypes.XMR_SWAP, extra_options=extra_options)
|
||||||
|
wait_for_offer(test_delay_event, swap_clients[1], offer_id)
|
||||||
|
offer = swap_clients[1].listOffers(filters={'offer_id': offer_id})[0]
|
||||||
|
|
||||||
|
below_min_bid = min_bid - 1
|
||||||
|
try:
|
||||||
|
bid_id = swap_clients[1].postBid(offer_id, below_min_bid)
|
||||||
|
except Exception as e:
|
||||||
|
assert('Bid amount below minimum' in str(e))
|
||||||
|
extra_bid_options = {
|
||||||
|
'debug_skip_validation': True,
|
||||||
|
}
|
||||||
|
bid_id = swap_clients[1].postBid(offer_id, below_min_bid, extra_options=extra_bid_options)
|
||||||
|
|
||||||
|
events = wait_for_event(test_delay_event, swap_clients[0], Concepts.NETWORK_MESSAGE, bid_id)
|
||||||
|
assert('Bid amount below minimum' in events[0].event_msg)
|
||||||
|
# TODO
|
||||||
|
|
||||||
def test_10_locked_refundtx(self):
|
def test_10_locked_refundtx(self):
|
||||||
logging.info('---------- Test Refund tx is locked')
|
logging.info('---------- Test Refund tx is locked')
|
||||||
swap_clients = self.swap_clients
|
swap_clients = self.swap_clients
|
||||||
|
|
Loading…
Reference in a new issue