simpleledgerinc / grpc-bchrpc-node

A BCHD gRPC client for node.js
11 stars 10 forks source link

When subscribing to transactions/block the client gets disconnected after 10 minutes #10

Open elderapo opened 3 years ago

elderapo commented 3 years ago

Basically what the title says... This is the error:

Error: 1 CANCELLED: Received http2 header with status: 504
    at Object.exports.createStatusError (/usr/src/app/node_modules/grpc/src/common.js:91:15)
    at ClientReadableStream._emitStatusIfDone (/usr/src/app/node_modules/grpc/src/client.js:233:26)
    at ClientReadableStream._receiveStatus (/usr/src/app/node_modules/grpc/src/client.js:211:8)
    at Object.onReceiveStatus (/usr/src/app/node_modules/grpc/src/client_interceptors.js:1277:15)
    at InterceptingListener._callNext (/usr/src/app/node_modules/grpc/src/client_interceptors.js:568:42)
    at InterceptingListener.onReceiveStatus (/usr/src/app/node_modules/grpc/src/client_interceptors.js:618:8)
    at /usr/src/app/node_modules/grpc/src/client_interceptors.js:1033:24
[ERROR] 17:03:06 Error: 1 CANCELLED: Received http2 header with status: 504
elderapo commented 3 years ago

Actually, I think the issue is not with this library but with bchd.fountainhead.cash:443. Seems like it's behind some reverse proxy that timeouts after 10 minutes.

jcramer commented 3 years ago

Correct, it times out after 10 minutes of no activity, you need to create a self-healing stream like this:

https://github.com/jcramer/bitcore-lib-fun/blob/20cbb9d8a39e68efe3e7c8f13406d67c1921d62e/src/slpwallet/Network/BchdNetwork.ts#L55

elderapo commented 3 years ago

Hmm... Reconnecting on disconnect seems like a good idea but for some reason my stream never "emits" any events besides data:

transactionsStream.on("close", () => console.log("close"));
transactionsStream.on("data", () => console.log("data"));
transactionsStream.on("end", () => console.log("end"));
transactionsStream.on("error", () => console.log("error"));
transactionsStream.on("pause", () => console.log("pause"));

In my test, I set up a transactions stream, waited for some data events, disconnected wifi from my laptop, reconnected wifi. I expected to get either close or end events but they never got emitted :thinking:

jcramer commented 3 years ago

What happens if you apply this patch:

index f971817..ec22ace 100644
--- a/src/client.ts
+++ b/src/client.ts
@@ -364,7 +364,7 @@ export class GrpcClient {

             req.setSubscribe(filter);
             try {
-                resolve(this.client.subscribeTransactions(req));
+                resolve(this.client.subscribeTransactionStream(req));
             } catch (err) {
                 reject(err);
             }
@@ -386,7 +386,7 @@ export class GrpcClient {
             includeTxnData ? req.setFullTransactions(true) : req.setFullTransactions(false);
             includeSerializedBlock ? req.setSerializeBlock(true) : req.setSerializeBlock(false);
             try {
-                resolve(this.client.subscribeBlocks(req));
+                resolve(this.client.subscribeTransactionStream(req));
             } catch (err) {
                 reject(err);
             }
elderapo commented 3 years ago

After switching from subscribeTransactions to subscribeTransactionStream I no longer get any events (not even data ones).

elderapo commented 3 years ago

Is it working for you?

jcramer commented 3 years ago

I haven't tried the patch, I just saw that it was an alternative in the bchrpc.proto file so thought it would be work the try. We may need to search on some gRPC related topics in order to get to the bottom of the issue. I'm not able to look into it at the moment.

elderapo commented 3 years ago

I've found a funny workaround. After creating a client I instantly start listening for txs, and if there is no tx notification in x seconds I treat that client as "disconnected". It causes my container to become unhealthy and it gets restarted :)