From 247c1d8dc8e62196283ca7d34273817a5073fba1 Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Fri, 15 Sep 2023 15:59:37 -0700 Subject: [PATCH] lnrpc: increase max message size for ws proxy In this commit, we increase the max message size for the ws proxy. We have a similar setting for the normal gRPC server which was tuned to be able to support decoding `GetNetworkInfo` as the channel graph got larger. We keep the default buffer size of 64 KB, but allow that to be expanded to up to 4 MB (current value) to decode larger messages. One alternative would be to modify the `Split` function to break up larger lines into smaller ones. We'd need to double check that the libraries at a higher level of abstraction can handle the chunks. The scan function would look something like: ```go splitFunc := func(data []byte, eof bool) (int, []byte, error) { if len(data) >= chunkSize { return chunkSize, data[:chunkSize], nil } return bufio.ScanLines(data, eof)) } scanner.Split(splitFunc) ``` --- docs/release-notes/release-notes-0.17.0.md | 5 +++++ lnrpc/websocket_proxy.go | 16 +++++++++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/docs/release-notes/release-notes-0.17.0.md b/docs/release-notes/release-notes-0.17.0.md index 3f4cf7ceba..8bb2b17a50 100644 --- a/docs/release-notes/release-notes-0.17.0.md +++ b/docs/release-notes/release-notes-0.17.0.md @@ -228,6 +228,11 @@ None * The [WalletBalance](https://github.com/lightningnetwork/lnd/pull/7857) RPC (lncli walletbalance) now supports showing the balance for a specific account. + +* The [websockets proxy now uses a larger default max + message](https://github.com/lightningnetwork/lnd/pull/7991) size to support + proxying larger messages. + ## lncli Updates * Added ability to use [environment variables to override `lncli` global diff --git a/lnrpc/websocket_proxy.go b/lnrpc/websocket_proxy.go index 7aaa9b1f28..4a46929657 100644 --- a/lnrpc/websocket_proxy.go +++ b/lnrpc/websocket_proxy.go @@ -38,6 +38,11 @@ const ( // an arbitrary non-empty message that has no deeper meaning but should // be sent back by the client in the pong message. PingContent = "are you there?" + + // MaxWsMsgSize is the largest websockets message we'll attempt to + // decode in the gRPC <-> WS proxy. gRPC has a similar setting used + // elsewhere. + MaxWsMsgSize = 4 * 1024 * 1024 ) var ( @@ -413,9 +418,18 @@ func (r *requestForwardingReader) CloseWriter() { // what's written to it and presents it through a bufio.Scanner interface. func newResponseForwardingWriter() *responseForwardingWriter { r, w := io.Pipe() + + scanner := bufio.NewScanner(r) + + // We pass in a custom buffer for the bufio scanner to use. We'll keep + // with a normal 64KB buffer, but allow a larger max message size, + // which may cause buffer expansion when needed. + buf := make([]byte, 0, bufio.MaxScanTokenSize) + scanner.Buffer(buf, MaxWsMsgSize) + return &responseForwardingWriter{ Writer: w, - Scanner: bufio.NewScanner(r), + Scanner: scanner, pipeR: r, pipeW: w, header: http.Header{},