Skip to content

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

Open
@KarolTrzeszczkowski

Description

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).

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions