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