Bug: When working too fast, orders stay on the market even when they aren't registered on the node
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

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).
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?
Yes, the user has all the permissions.
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.