From 343fd6efbc9b7ff417ba9736494373fcf64d8956 Mon Sep 17 00:00:00 2001 From: tecnovert Date: Mon, 15 Apr 2024 00:16:46 +0200 Subject: [PATCH] Constrain protocol versions, fix error showing old offers. --- basicswap/basicswap.py | 11 +++++++++++ basicswap/ui/page_offers.py | 21 +++++++++++++++++---- doc/release-notes.md | 4 ++++ 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/basicswap/basicswap.py b/basicswap/basicswap.py index 962203b..b9b9d6a 100644 --- a/basicswap/basicswap.py +++ b/basicswap/basicswap.py @@ -153,6 +153,8 @@ MINPROTO_VERSION_SECRET_HASH = 4 PROTOCOL_VERSION_ADAPTOR_SIG = 4 MINPROTO_VERSION_ADAPTOR_SIG = 4 +MINPROTO_VERSION = min(MINPROTO_VERSION_SECRET_HASH, MINPROTO_VERSION_ADAPTOR_SIG) +MAXPROTO_VERSION = 10 def validOfferStateToReceiveBid(offer_state): if offer_state == OfferStates.OFFER_RECEIVED: @@ -2265,6 +2267,7 @@ class BasicSwap(BaseApp): if offer.swap_type == SwapTypes.XMR_SWAP: return self.postXmrBid(offer_id, amount, addr_send_from, extra_options) + ensure(offer.protocol_version >= MINPROTO_VERSION_SECRET_HASH, 'Incompatible offer protocol version') 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) @@ -2516,11 +2519,13 @@ class BasicSwap(BaseApp): ensure(bid.state in (BidStates.BID_RECEIVED, ), 'Wrong bid state: {}'.format(BidStates(bid.state).name)) if offer.swap_type == SwapTypes.XMR_SWAP: + ensure(bid.protocol_version >= MINPROTO_VERSION_ADAPTOR_SIG, 'Incompatible bid protocol version') reverse_bid: bool = self.is_reverse_ads_bid(offer.coin_from) if reverse_bid: return self.acceptADSReverseBid(bid_id) return self.acceptXmrBid(bid_id) + ensure(bid.protocol_version >= MINPROTO_VERSION_SECRET_HASH, 'Incompatible bid protocol version') if bid.contract_count is None: bid.contract_count = self.getNewContractId() @@ -2633,6 +2638,7 @@ class BasicSwap(BaseApp): ensure(offer, 'Offer not found: {}.'.format(offer_id.hex())) ensure(xmr_offer, 'Adaptor-sig offer not found: {}.'.format(offer_id.hex())) + ensure(offer.protocol_version >= MINPROTO_VERSION_ADAPTOR_SIG, 'Incompatible offer protocol version') ensure(offer.expire_at > self.getTime(), 'Offer has expired') coin_from = Coins(offer.coin_from) @@ -4544,7 +4550,12 @@ class BasicSwap(BaseApp): def processOffer(self, msg) -> None: offer_bytes = bytes.fromhex(msg['hex'][2:-2]) + offer_data = OfferMessage() + offer_data.ParseFromString(offer_bytes[:2]) + if offer_data.protocol_version < MINPROTO_VERSION or offer_data.protocol_version > MAXPROTO_VERSION: + self.log.warning(f'Incoming offer invalid protocol version: {offer_data.protocol_version} ') + return offer_data.ParseFromString(offer_bytes) # Validate data diff --git a/basicswap/ui/page_offers.py b/basicswap/ui/page_offers.py index 7682040..c020c93 100644 --- a/basicswap/ui/page_offers.py +++ b/basicswap/ui/page_offers.py @@ -352,6 +352,10 @@ def offer_to_post_string(self, swap_client, offer_id): ci_from = swap_client.ci(offer.coin_from) ci_to = swap_client.ci(offer.coin_to) + + amount_to: int = offer.amount_to + if amount_to is None: + amount_to = (offer.amount_from * offer.rate) // ci_from.COIN() offer_data = { 'formid': self.generate_form_id(), 'addr_to': offer.addr_to, @@ -364,7 +368,7 @@ def offer_to_post_string(self, swap_client, offer_id): 'amt_from': ci_from.format_amount(offer.amount_from), 'amt_bid_min': ci_from.format_amount(offer.min_bid_amount), 'rate': ci_to.format_amount(offer.rate), - 'amt_to': ci_to.format_amount(offer.amount_to), + 'amt_to': ci_to.format_amount(amount_to), 'validhrs': offer.time_valid // (60 * 60), 'swap_type': strSwapType(offer.swap_type), } @@ -575,6 +579,9 @@ def page_offer(self, url_split, post_string): err_messages.append('Send bid failed: ' + str(ex)) show_bid_form = True + amount_to: int = offer.amount_to + if amount_to is None: + amount_to = (offer.amount_from * offer.rate) // ci_from.COIN() now: int = swap_client.getTime() data = { 'tla_from': ci_from.ticker(), @@ -585,7 +592,7 @@ def page_offer(self, url_split, post_string): 'coin_from_ind': int(ci_from.coin_type()), 'coin_to_ind': int(ci_to.coin_type()), 'amt_from': ci_from.format_amount(offer.amount_from), - 'amt_to': ci_to.format_amount(offer.amount_to), + 'amt_to': ci_to.format_amount(amount_to), 'amt_bid_min': ci_from.format_amount(offer.min_bid_amount), 'rate': ci_to.format_amount(offer.rate), 'lock_type': getLockName(offer.lock_type), @@ -781,13 +788,16 @@ def page_offers(self, url_split, post_string, sent=False): formatted_expired_at = format_timestamp(o.expire_at, with_ago=False, is_expired=True) tla_from = ci_from.ticker() tla_to = ci_to.ticker() + amount_to: int = o.amount_to + if amount_to is None: + amount_to = (o.amount_from * o.rate) // ci_from.COIN() formatted_offers.append(( formatted_created_at, o.offer_id.hex(), ci_from.coin_name(), ci_to.coin_name(), ci_from.format_amount(o.amount_from), - ci_to.format_amount(o.amount_to), + ci_to.format_amount(amount_to), ci_to.format_amount(o.rate), 'Public' if o.addr_to == swap_client.network_addr else o.addr_to, o.addr_from, @@ -824,7 +834,10 @@ def page_offers(self, url_split, post_string, sent=False): for coin_id in swap_client.coin_clients: if not swap_client.isCoinActive(coin_id): continue - enabled_ticker = swap_client.ci(coin_id).ticker_mainnet() + try: + enabled_ticker = swap_client.ci(coin_id).ticker_mainnet() + except Exception: + continue if enabled_ticker not in enabled_chart_coins and enabled_ticker in known_chart_coins: enabled_chart_coins.append(enabled_ticker) else: diff --git a/doc/release-notes.md b/doc/release-notes.md index 9c009e4..bc0198b 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -6,6 +6,10 @@ - Bid and offer states change when expired. - bid amounts are specified directly and not constructed from rate. - Breaks compatibility with prior versions. +- Added enabled_chart_coins setting for which coins to show on the offers page. + - Blank/unset for active coins. + - All for all known coins. + - Comma separated list of coin tickers to show. 0.12.7