atomicDEX-API icon indicating copy to clipboard operation
atomicDEX-API copied to clipboard

Bug: When working too fast, orders stay on the market even when they aren't registered on the node

Open KarolTrzeszczkowski opened this issue 2 years ago • 3 comments

Describe the bug I'm running a bot that is doing market making . Over time weird things start to happen on some markets it is covers. Although I should only have two orders on each market, I see multiple of them and they are from my address.

I'm verifying I only have two orders on one of the markets:

$ lib/clients/atomicdex_bashscripts/myorders.sh |jq '. | .result[][] | .base + .rel'  | grep 'XRG' |grep 'USDT'
"USDT-BEP20XRG"
"XRGUSDT-BEP20"

but the wallet app shows there are many of them present and all of them are from my address signal-2023-03-17-115120

I'm using mm2-6e4de5d21-Linux-Release, placing orders with setprice method, though I'm going very fast from time to time. I'm making sure to only send one request at a time (see the mutex lock I'm using in my code snippet below). The weird orders seem to accumulate most when I cancel right after setting the price.

When I start a swap on mobile with one of the non-existent orders it just jumps out to the dex screen, reporting no error and nothing shows up in order history nor in on my node log.

Please answer following questions and attach requested info - it'll help to solve issue faster

  • What OS do you use? Ubuntu 20.04.5 LTS (Focal Fossa)
  • What marketmaker version do you run? beta-2.1.8741
  • Attach your coins.json config.
  • Provide your enable script with response.
./start_all_coins.sh 
#! /bin/bash
./KMDconnect.sh
./MATICconnect.sh
./BCHconnect.sh
./BNBconnect.sh
./AVAXconnect.sh
./XRGconnect.sh
./FIROconnect.sh
./DOGEconnect.sh
./LTCconnect.sh
./BUSDconnect.sh
./USDTconnect.sh

{"result":"success","address":redacted,"balance":redacted,"unspendable_balance":"0","coin":"KMD","required_confirmations":2,"requires_notarization":true,"mature_confirmations":100}{"result":"success","address":redacted,"balance":redacted,"unspendable_balance":"0","coin":"MATIC","required_confirmations":3,"requires_notarization":false}{"result":"success","address":redacted,"balance":redacted,"unspendable_balance":"0","coin":"BCH","required_confirmations":1,"requires_notarization":false,"mature_confirmations":100}{"result":"success","address":redacted,"balance":redacted,"unspendable_balance":"0","coin":"BNB","required_confirmations":3,"requires_notarization":false}{"result":"success","address":redacted,"balance":redacted,"unspendable_balance":"0","coin":"AVAX","required_confirmations":3,"requires_notarization":false}{"result":"success","address":"redacted,"balance":redacted,"unspendable_balance":"0","coin":"XRG","required_confirmations":2,"requires_notarization":false,"mature_confirmations":100}{"result":"success","address":redacted,"balance":redacted,"unspendable_balance":"0","coin":"FIRO","required_confirmations":1,"requires_notarization":false,"mature_confirmations":100}{"result":"success","address":redacted,"balance":redacted,"unspendable_balance":"0","coin":"DOGE","required_confirmations":2,"requires_notarization":false,"mature_confirmations":100}{"result":"success","address":redacted,"balance":redacted,"unspendable_balance":"0","coin":"LTC","required_confirmations":2,"requires_notarization":false,"mature_confirmations":100} {"result":"success","address":redacted, "balance":"redacted"unspendable_balance":"0","coin":"BUSD-BEP20","required_confirmations":3,"requires_notarization":false}{"result":"success","address":redacted,"balance":redacted"unspendable_balance":"0","coin":"USDT-BEP20","required_confirmations":3,"requires_notarization":false}

  • Provide other curl scripts (with responses) which were executed prior to error. I'm using python aiohttp not curl. Relevant snippets:
    async def post(self, data):
        async with self.busy: # mutex lock, asyncio.Lock 
            data = json.dumps(data)
            async with self.session.post(self.url, data=data) as resp:
                response = await resp.text()
                return self.response_to_dict(response)
   async def cancel_coins_orders(self, coins):
        req = []
        for coin in coins:
            data = deepcopy(self.template)      #self.template = {"userpass": userpass, "method": None}
            data['method'] = "cancel_all_orders" 
            data['cancel_by'] = {"type": "Coin",
                                 "data": {
                                     'ticker': local_name[coin],
                                 }}
            req.append(data)
        await self.post(req)
        orders = await self.get_my_orders() # verifying the cancel
        coins_orders = [
            uuid for uuid, data in orders.items()
            if global_name[data['base']] in coins or global_name[data['rel']] in coins
        ]
        return not bool(coins_orders)

    async def create_limit_orders(self, orderbooks, coins):
        req=[]
        for market, orderbook in orderbooks.items():
            if market.exchange != self.name:
                continue
            if not market.intersection(coins):
                continue
            for side in (BUY, SELL):
                for order in orderbook[side]:
                    req.append(
                        self.limit_order_data(
                            market,
                            side,
                            f'{order.price:.{market.precision.price}f}',
                            f'{order.amount:.{market.precision.amount}f}'
                        )
                    )
        return await self.post(req)

  • Attach full marketmaker console logs (start collecting right after marketmaker execution). nohup_from_last_restart.txt

  • Provide info for all nodes involved (e.g. if error occurs during atomic swap you should provide info for both Bob and Alice).

KarolTrzeszczkowski avatar Mar 20 '23 12:03 KarolTrzeszczkowski

seeing lots of this errors in log file, after start

18 18:58:39, common:log:283] ERROR my_orders_storage:125] !delete_active_maker_order: my_orders_storage:274] fs:103] Error saving an order: could not remove file `DB/e152f43f85d12668e8adb564ec75219a24d33c75/ORDERS/MY/MAKER/84875bdf-e147-42bb-b3af-c95ad29b4dab.json`
18 18:58:39, common:log:283] ERROR my_orders_storage:125] !delete_active_maker_order: my_orders_storage:274] fs:103] Error saving an order: could not remove file `DB/e152f43f85d12668e8adb564ec75219a24d33c75/ORDERS/MY/MAKER/2949fcf3-f3ee-44e4-b0b6-27a1668f6e76.json`

is the user running mm2 allowed to write to that directory?

cipig avatar Mar 20 '23 13:03 cipig

Yes, the user has all the permissions.

KarolTrzeszczkowski avatar Mar 20 '23 16:03 KarolTrzeszczkowski

The weird orders seem to accumulate most when I cancel right after setting the price.

Facing the same issue in test_cancel_all_orders unit test. It's due to p2p messages arriving at some nodes out of order, so cancel sometimes arrive before the message that created the order that should have been cancelled. I have a simple fix for this that I will work on.

shamardy avatar Sep 28 '24 03:09 shamardy