From 19724eac7789172a1ef13f92e90d40c9612e12eb Mon Sep 17 00:00:00 2001 From: Mark Veidemanis Date: Sat, 1 Jan 2022 19:20:20 +0000 Subject: [PATCH] Implement looking up trade by partial reference message or amount/currency --- handler/transactions.py | 76 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 70 insertions(+), 6 deletions(-) diff --git a/handler/transactions.py b/handler/transactions.py index 7aef36a..64fd660 100644 --- a/handler/transactions.py +++ b/handler/transactions.py @@ -76,8 +76,47 @@ class Transactions(object): self.log.info("Transaction processed: {formatted}", formatted=dumps(to_store, indent=2)) r.hmset(f"tx.{txid}", to_store) self.irc.sendmsg(f"AUTO Incoming transaction: {amount}{currency} ({reference}) - {state} - {description}") - # Try getting the trade by the reference ID given - stored_trade = self.get_ref(reference) + # Account for silly people not removing the default string + # Split the reference into parts + ref_split = reference.split(" ") + # Get all existing references + existing_refs = self.get_refs() + print("Existing references:", existing_refs) + # Get all parts of the given reference split that match the existing references + stored_trade_reference = set(existing_refs).intersection(set(ref_split)) + if len(stored_trade_reference) > 1: + self.log.error("Multiple references valid for TXID {txid}: {reference}", txid=txid, reference=reference) + self.irc.sendmsg(f"Multiple references valid for TXID {txid}: {reference}") + return + print("Stored trade reference:", stored_trade_reference) + + stored_trade = False + if not stored_trade_reference: + self.log.info(f"No reference in DB refs for {reference}", reference=reference) + self.irc.sendmsg(f"No reference in DB refs for {reference}") + # Try checking just amount and currency, as some people (usually people buying small amounts) + # are unable to put in a reference properly. + + self.log.info("Checking against amount and currency for TXID {txid}", txid=txid) + self.irc.sendmsg(f"Checking against amount and currency for TXID {txid}") + stored_trade = self.find_trade(txid, currency, amount) + if not stored_trade: + self.log.info( + "Failed to get reference by amount and currency: {txid} {currency} {amount}", + txid=txid, + currency=currency, + amount=amount, + ) + self.irc.sendmsg(f"Failed to get reference by amount and currency: {txid} {currency} {amount}") + return + if amount > settings.Agora.AcceptableAltLookupUSD: + self.log.info("Not checking against amount and currency as amount exceeds MAX") + self.irc.sendmsg(f"Not checking against amount and currency as amount exceeds MAX") + # Close here if the amount exceeds the allowable limit for no reference + return + if not stored_trade: + stored_trade = self.get_ref(stored_trade_reference.pop()) + print("Stored trade:", stored_trade) if not stored_trade: self.log.info(f"No reference in DB for {reference}", reference=reference) self.irc.sendmsg(f"No reference in DB for {reference}") @@ -103,10 +142,11 @@ class Transactions(object): if not account_type == "revolut": self.irc.sendmsg(f"Account type is not Revolut: {account_type}") return - self.irc.sendmsg(f"All checks passed, releasing funds for {stored_trade['id']} / {reference}") - rtrn = self.agora.release_funds(stored_trade["id"]) - self.agora.agora.contact_message_post(stored_trade["id"], "Thanks! Releasing now :)") - self.irc.sendmsg(dumps(rtrn)) + # self.irc.sendmsg(f"All checks passed, releasing funds for {stored_trade['id']} / {reference}") + # rtrn = self.agora.release_funds(stored_trade["id"]) + # self.agora.agora.contact_message_post(stored_trade["id"], "Thanks! Releasing now :)") + # self.irc.sendmsg(dumps(rtrn)) + self.irc.sendmsg(f"DRY RUN releasing funds for {stored_trade['id']} / {reference}") def new_trade(self, trade_id, buyer, currency, amount, amount_xmr): """ @@ -156,6 +196,30 @@ class Transactions(object): return "AMOUNT_INVALID" return False + def find_trade(self, txid, currency, amount): + """ + Get a trade reference that matches the given currency and amount. + Only works if there is one result. + :param txid: Revolut transaction ID + :param currency: currency + :param amount: amount + :type txid: string + :type currency: string + :type amount: int + :return: matching trade object or False + :rtype: dict or bool + """ + refs = self.get_refs() + matching_refs = [] + for ref in refs: + stored_trade = self.get_ref(ref) + if stored_trade["currency"] == currency and stored_trade["amount"] == amount: + matching_refs.append(stored_trade) + if len(matching_refs) != 1: + self.log.error("Find trade returned multiple results for TXID {txid}: {matching_refs}", txid=txid, matching_refs=matching_refs) + return False + return matching_refs[0] + def get_refs(self): """ Get all reference IDs for trades.