From 5ea1ff94d1317f9ea130a36333c27a7dc7a61186 Mon Sep 17 00:00:00 2001 From: Anthony Date: Mon, 17 Feb 2020 14:00:56 +0700 Subject: [PATCH] rpc: fix issue with multiple subscriptions (#4406) Using the WebSocket server, when the same client calls multiple time the subscribe method, only the last subscription receives all the events of the previous ones. example: subscription1 = tm.event = 'NewBlock' subscription2 = tm.event = 'Tx' In this case, subscription2 will receive the new blocks but subscription1 will not. This came from the WebSocket handler that had the declaration of the rpcrequest moved and so overridden for every request and given in the JSONReq client context (so the id of the subscription was not the right one). This fixes the issue by simply declaring the rpcrequest inside the loop so every request will create a new object without overwriting the previous one. --- CHANGELOG_PENDING.md | 2 ++ rpc/lib/server/ws_handler.go | 5 ++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/CHANGELOG_PENDING.md b/CHANGELOG_PENDING.md index bf41c1b5b..3eea4b2a0 100644 --- a/CHANGELOG_PENDING.md +++ b/CHANGELOG_PENDING.md @@ -20,3 +20,5 @@ program](https://hackerone.com/tendermint). ### IMPROVEMENTS: ### BUG FIXES: + +- [rpc] [\#4406](https://github.com/tendermint/tendermint/pull/4406) Fix issue with multiple subscriptions on the websocket (@antho1404) diff --git a/rpc/lib/server/ws_handler.go b/rpc/lib/server/ws_handler.go index 548a244cb..07f424b48 100644 --- a/rpc/lib/server/ws_handler.go +++ b/rpc/lib/server/ws_handler.go @@ -299,8 +299,6 @@ func (wsc *wsConnection) Context() context.Context { // Read from the socket and subscribe to or unsubscribe from events func (wsc *wsConnection) readRoutine() { - var request types.RPCRequest - defer func() { if r := recover(); r != nil { err, ok := r.(error) @@ -308,7 +306,7 @@ func (wsc *wsConnection) readRoutine() { err = fmt.Errorf("WSJSONRPC: %v", r) } wsc.Logger.Error("Panic in WSJSONRPC handler", "err", err, "stack", string(debug.Stack())) - wsc.WriteRPCResponse(types.RPCInternalError(request.ID, err)) + wsc.WriteRPCResponse(types.RPCInternalError(types.JSONRPCIntID(-1), err)) go wsc.readRoutine() } }() @@ -339,6 +337,7 @@ func (wsc *wsConnection) readRoutine() { return } + var request types.RPCRequest err = json.Unmarshal(in, &request) if err != nil { wsc.WriteRPCResponse(types.RPCParseError(errors.Wrap(err, "error unmarshaling request")))