aloysius-pgast / bittrex-signalr-client

Node.js implementation of SignalR protocol tailored for Bittrex exchange
39 stars 14 forks source link

There was an error invoking Hub method 'c2.queryexchangestate'.' #17

Open ze97286 opened 5 years ago

ze97286 commented 5 years ago

Hello,

When calling client.subscribeToMarkets(['BTC-ETH']) many times it fails (not always though) with the following error:

Could not query exchange for pair 'BTC-ETH' (might be an invalid pair) : err = 'There was an error invoking Hub method 'c2.queryexchangestate'.'

Any idea why?

Thanks, Z

aloysius-pgast commented 5 years ago

Hi What do you mean with many times ? Could you provide sample code to reproduce the problem ? Thanks

ze97286 commented 5 years ago

'use strict'

const util = require('util'); const SignalRClient = require('bittrex-signalr-client/lib/client.js');

let client = new SignalRClient({ verbose: true, logger: console, auth: { key: 'my_key', secret: 'my_secret' }, pingTimeout:10000, watchdog:{ // automatically reconnect if we don't receive markets data for 30min (this is the default) markets:{ timeout:1800000, reconnect:true } }, // use cloud scraper to bypass Cloud Fare (default) useCloudScraper:true });

client.on('orderBook', function(data){ console.log("parsed order book: ",data) });

client.on('orderBookUpdate', function(data){ console.log(util.format("Got order book update for pair '%s' :",data.pair)); });

//-- start subscription console.log("=== Subscribing to 'BTC-ETH' pair"); client.subscribeToMarkets(['BTC-ETH'], true);

ze97286 commented 5 years ago

When running, in most of the times it would print:

=== Subscribing to 'BTC-ETH' pair Connection (bittrex|1|0d9d9518-5469-46ba-9936-ca21d33ca815) connected Could not query exchange for pair 'BTC-ETH' (might be an invalid pair) : err = 'There was an error invoking Hub method 'c2.queryexchangestate'.'

However, in some cases it would print: === Subscribing to 'BTC-ETH' pair Connection (bittrex|1|d3127039-7577-45c5-bc25-f36ab6f6d43c) connected parsed order book: { exchangeName: 'bittrex', symbol: 'BTC-ETH', base: 'BTC', quote: 'ETH', bids: [ { price: 0.03450362, size: 0.16845992 }, { price: 0.03449, size: 1.10566585 }, { price: 0.03445649, size: 10.02495844 }, { price: 0.03445017, size: 0.80089838 }, { price: 0.03443756, size: 40.518 }, { price: 0.03443755, size: 110.999 }, { price: 0.0344366, size: 7.26041449 }, { price: 0.03442804, size: 143.25793744 }, { price: 0.03437666, size: 96.36947786 }, { price: 0.03437, size: 7.4427 } ], asks: [ { price: 0.03450669, size: 0.42454355 }, { price: 0.03451264, size: 0.96053396 }, { price: 0.034515, size: 1 }, { price: 0.03451513, size: 0.10017552 }, { price: 0.03451997, size: 11.271 }, { price: 0.03451998, size: 110.999 }, { price: 0.03452, size: 1.00730411 }, { price: 0.0345223, size: 0.06 }, { price: 0.03452548, size: 10.02495844 }, { price: 0.03453652, size: 2 } ], confidence: 1, nonce: 228742 } ...

ze97286 commented 5 years ago

Also, I'm wondering if this has been done before (I'm sure it has but haven't seen an example), what I'd really like to do is to have a stream of latest order book, i.e. have a subcscibeOrderBook that returns a stream of the latest order book (by getting the full state and applying updates on it).

aloysius-pgast commented 5 years ago

This message There was an error invoking Hub method 'c2.queryexchangestate' is generated by Bittrex. I didn't manage to reproduce the problem with your sample code. Could you try to run your code with

DEBUG=BittrexSignalRClient:Connection node

To see if it gives more information ?

Also, calling client.logAllWsMessages(true); after creating the client should log all received WS messages

aloysius-pgast commented 5 years ago

And regarding your other question (latest order book). You need to do the following :

ze97286 commented 5 years ago

And regarding your other question (latest order book). You need to do the following :

  • when receiving orderBook event, replace order book with event data
  • when receiving orderBookUpdate :

    • if update == action => update order book entry for rate
    • if remove == action => remove order book entry for rate This will ensure you have an up-to-date full order book

Sure, thanks, I know what to do, I was just wondering if anyone has already done it as it seems quite useful and common.

ze97286 commented 5 years ago

This message There was an error invoking Hub method 'c2.queryexchangestate' is generated by Bittrex. I didn't manage to reproduce the problem with your sample code. Could you try to run your code with

DEBUG=BittrexSignalRClient:Connection node

To see if it gives more information ?

Also, calling client.logAllWsMessages(true); after creating the client should log all received WS messages

I think I found the issue. I have another connection to bittrex not using the ws client that is sending a request every second for a full order book, after shutting it down and only running the code above I don't get the error at all. Sorry about that, and thanks for your prompt response and assistance!

aloysius-pgast commented 5 years ago

And regarding your other question (latest order book). You need to do the following :

  • when receiving orderBook event, replace order book with event data
  • when receiving orderBookUpdate :

    • if update == action => update order book entry for rate
    • if remove == action => remove order book entry for rate This will ensure you have an up-to-date full order book

Sure, thanks, I know what to do, I was just wondering if anyone has already done it as it seems quite useful and common.

Can be easily implemented using a Map() where keys are the rate. To obtain the full order book, you just need to sort the map keys & build a new array. Might not be the best from a performances point of view but seems to be ok for my needs. This is what I did for https://github.com/aloysius-pgast/crypto-exchanges-gateway. See https://mpe-demo.crazyme.net/ui/#/exchanges/bittrex/orderBooks/BTC-ETH

devops398 commented 5 years ago

@aloysius-pgast

hello, I'm trying to use your library, first of all, thank you very much for all the hard work of managing signalR and all edge cases, but looks like for me it doesn't work as smooth as it should be, when I start listening to all markets in ~4-5 minutes I get this:

10:04:30 PM bittrex.1 |  2019-06-20T19:04:30.048Z BittrexSignalRClient:Client Method 'subscribeToMarkets' will trigger following changes : {"subscribe":[{"entity":"market","pair":"ETH-BCC"}],"unsubscribe":[],"resync":[{"entity":"orderBook","pair":"ETH-BCC"}]}
10:04:30 PM bittrex.1 |  2019-06-20T19:04:30.049Z BittrexSignalRClient:Client Watchdog for 'tickers' will be disabled since we don't have any remaining subscription
10:04:30 PM bittrex.1 |  2019-06-20T19:04:30.049Z BittrexSignalRClient:Client Watchdog for 'orders' will be disabled since we don't have a subscription
10:04:30 PM bittrex.1 |  2019-06-20T19:04:30.300Z BittrexSignalRClient:Connection Got an error for message 329 : err = 'There was an error invoking Hub method 'c2.queryexchangestate'.'
10:04:30 PM bittrex.1 |  2019-06-20T19:04:30.300Z BittrexSignalRClient:Client Could not query exchange for pair 'ETH-BCC' (might be an invalid pair) : err = 'There was an error invoking Hub method 'c2.queryexchangestate'.'

I forked your library to catch that event and re-subscribe, but it doesnt help, after some point these errors just keep appearing, any idea how to fix or what can be the reason?

here is my constructor:

  const client = new SignalRClient({
    // websocket will be automatically reconnected if server does not respond to ping after 10s
    pingTimeout: 15000,
    retryCount: {
      negotiate: 20,
      connect: 50
    },
    reconnectAfterUnsubscribingFromMarkets: {
      reconnect: true,
      after: 4
    },
    watchdog: {
      markets: {
        timeout: 1500000,
        reconnect: true,
      },
    },
    // use cloud scraper to bypass Cloud Fare (default)
    useCloudScraper: true,
  });
aloysius-pgast commented 5 years ago

Hi @igorlimansky Could you try to add client.logAllWsMessages(true); and also run your code with DEBUG=BittrexSignalRClient:Connection node ? Could you also provide the code used to subscribe ? Thanks

devops398 commented 5 years ago

@aloysius-pgast hey, thanks for reply!

attached logs, hope it can help..

https://pastebin.com/3TgDTv4C

aloysius-pgast commented 5 years ago

@aloysius-pgast hey, thanks for reply!

attached logs, hope it can help..

https://pastebin.com/3TgDTv4C

Could you also paste the code used to subscribe ?

devops398 commented 5 years ago

@aloysius-pgast oh, sorry, I forgot here:

const connectToClient = async (client, pairs) => {
  const bittrexPairs = pairs.map(pair => adaptPairToBittrexFormat(pair));
  console.log('init bittrex markets', bittrexPairs.length);
  for (var i = 0; i < bittrexPairs.length; ++i) {
    client.subscribeToMarkets([bittrexPairs[i]]);

    await new Promise(r => setTimeout(r, 1000));
  }
};

I used to subscribe to all pairs at once, but it doesnt work at all then

aloysius-pgast commented 5 years ago

Do you also have the list of pairs you're using ?

aloysius-pgast commented 5 years ago

In https://github.com/aloysius-pgast/bittrex-signalr-client/issues/17#issuecomment-504316501, I see you're getting an error got ETH-BCC. There is no support for BCC on Bittrex. You probably want to use ETH-BCH instead

aloysius-pgast commented 5 years ago

Symbol was changed on June 15, 2018 https://bittrex.zendesk.com/hc/en-us/articles/360004823112-Rebranding-and-ticker-symbol-changes-Bitcoin-Cash-BCC-Legends-LGD-and-Bitswift-SWIFT-

devops398 commented 5 years ago

good catch! I'll disable that pair and try again

https://pastebin.com/C66YZykP other than that, I'm just subscribing to all bittrex pairs and even live pairs get that error

aloysius-pgast commented 5 years ago

Could you provide a more user-friendly pair list (ie: json-based only) ;) ?

aloysius-pgast commented 5 years ago

I attached the list of pairs which are currently supported (357 pairs) pairs.json.txt

aloysius-pgast commented 5 years ago

Following pairs are not online right now so they will probably return an error when trying to subscribe

["THC-BTC","NEOS-BTC","TKS-BTC","LUN-BTC","ITM-BTC"]
devops398 commented 5 years ago

@aloysius-pgast

Thanks for your help, I really appreciate it. So I removed subscribing to disabled pairs and now it works a bit longer ~13 mins, so I returned back resubscribing on queryexchange error (via emitting custom event in my fork) and looks like it doesnt help much, some pairs just silently turn off without error, you can see it from attached data (number is how many seconds since last update for each pair): https://pastebin.com/SQbzCYGF pairs are in my internal common format

and here is runtime logs: https://pastebin.com/QSq4uxc0

as you see there were no errors for dead pairs (pairs which didnt receive any updates since long time), I'll attach full logs with client.logAllWsMessages(true) a bit later, maybe they can tell more what happened

aloysius-pgast commented 5 years ago

I tested with the pairs from https://github.com/aloysius-pgast/bittrex-signalr-client/files/3314074/pairs.json.txt and it has been working correctly without QueryExchangeState error for almost 2 hours How do you handle the event and resubscribe ?

aloysius-pgast commented 5 years ago

I finally got an error on QueryExchangeState after 2h30. I pushed a new version on master, inspired by your fork. I also added a new constructor option resyncOrderBooksAutomatically you might want to set to false to disable automatic resync of order books (ie: in case an order book update has been missed)

aloysius-pgast commented 5 years ago

Got the same error again, after 1h30. I'll try again with resyncOrderBooksAutomatically = false to see if behaviour is better. Let me know if it's better on your side

devops398 commented 5 years ago

Wow, that was really fast! Sorry for pause, was validating I did everything right. Thank you so much, I spent plenty of time before reaching out..

But so far locally it seems to be working (after ~1h of testing), I deployed it to servers and monitoring hows going, will write more tomorrow about results of testing.

devops398 commented 5 years ago

@aloysius-pgast Hi, I tested your update, thank you very much, it works and I'm resubscribing on error, but looks like there is also another problem: https://pastebin.com/G7NtRqZf

As you see connection works just for few minutes and then dies without any notice so resubscribing happens only on timeout

Meanwhile I'm trying to get more logs from websocket channel to understand whats happens, but it produces too much noise and I get ~6mb logs after 10mins of running and hard to follow what I need to find there

P.S. I'm subscribing only to hardcoded markets from here: https://github.com/aloysius-pgast/bittrex-signalr-client/files/3314074/pairs.json.txt

const connectToClient = async (client) => {
bittrexPairs = [/* from link https://github.com/aloysius-pgast/bittrex-signalr-client/files/3314074/pairs.json.txt */]
ded = ["THC-BTC","NEOS-BTC","TKS-BTC","LUN-BTC","ITM-BTC"]
  for (var i = 0; i < bittrexPairs.length; ++i) {
    if (ded.includes(bittrexPairs[i])) {
      continue;
    }
    //    console.log(bittrexPairs[i])
    client.subscribeToMarkets([bittrexPairs[i]]);
    await new Promise(r => setTimeout(r, 100));
  }
}
aloysius-pgast commented 5 years ago

Hi. Unfortunately, watchdog was added because sometimes Bittrex silently stops sending data without any disconnection or anything. Maybe I should check if it's possible to define a per-pair watchdog

devops398 commented 5 years ago

Thanks a lot for help, looks like I managed to make it work with my internal watchdog, also I checked out your implementation of watchdog and see that its not that hard to implement per-pair watch, I can do a PR Also I think you can close this issue now, since we figured out how to process this error at least, even though reasons for such behaviour are still unknown and highly likely coming because of bittrex, not client library

aloysius-pgast commented 5 years ago

Great. A PR which lets user defined per-pair watchdog without breaking backward compatiblity (global watchdog) is welcome. Thanks

devops398 commented 5 years ago

hey, its been a while... sorry I got stuck with side task and still busy, just wanted to notice I didnt forget and will get back to this soon in a week or so :)

aloysius-pgast commented 5 years ago

For the record, c2.queryexchangestate error is a known error related to Bittrex implementation https://github.com/Bittrex/bittrex.github.io/issues/50#issuecomment-480890809