fix(grpc-web): set ReadTimeout, WriteTimeout, IdleTimeout, and MaxOpenConnections#3605
fix(grpc-web): set ReadTimeout, WriteTimeout, IdleTimeout, and MaxOpenConnections#3605amir-deris wants to merge 11 commits into
Conversation
PR SummaryMedium Risk Overview Configuration adds Startup now binds an explicit TCP listener and serves with Reviewed by Cursor Bugbot for commit 19c77a3. Bugbot is set up for automated code reviews on this repo. Configure here. |
|
The latest Buf updates on your PR. Results from workflow Buf / buf (pull_request).
|
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #3605 +/- ##
==========================================
- Coverage 59.02% 58.14% -0.88%
==========================================
Files 2215 2141 -74
Lines 182521 173986 -8535
==========================================
- Hits 107731 101165 -6566
+ Misses 65094 63823 -1271
+ Partials 9696 8998 -698
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
| ReadTimeout: 30 * time.Second, | ||
| WriteTimeout: 2 * time.Minute, | ||
| IdleTimeout: 120 * time.Second, |
There was a problem hiding this comment.
Idle timeout strikes me as a bit long. What do you think @sei-will?
Also, do we have any data on how long standard requests take? Ideally we keep these tightly scoped to what we expect standard workloads to use. For instance, if the largest range query only take 10 seconds based on x years historical data, then we can tighten this to 15 seconds for example.
We will never get this exactly right so not looking for a perfect magic number, just curious if we have those inputs. My hunch is 2 minutes for a write is more lenient than we need to be
There was a problem hiding this comment.
Thanks for feedback. Reduced the idle timeout to 30s.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 2 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 9a4484d. Configure here.

Summary
PR #3558 added
ReadHeaderTimeoutto the gRPC-Webhttp.Server, protecting against slow-header attacks. The body-stall DoS vector remained: a client that sends valid headers and then stalls while the server waits indefinitely for the request body. This PR closes that gap and adds a connection cap to bound total resource usage.Timeout changes
ReadHeaderTimeoutReadTimeoutWriteTimeoutIdleTimeoutWriteTimeoutis set to 2 minutes rather than a shorter value because the longest legitimate call through this server isBroadcastTxCommit, which is bounded by Tendermint'sTimeoutBroadcastTxCommit(default 10s). Paginated query RPCs are already capped at the application layer (PLT-361). The 2-minute window gives a large margin above any real workload while still providing a backstop against response-side connection holds.MaxOpenConnections
Wraps the gRPC-Web listener with
netutil.LimitListenerto cap the number of simultaneously open TCP connections. New connections block at the OS accept queue once the limit is reached rather than being accepted and left waiting inside the server.grpc-web.max-open-connectionsinapp.toml; set to0to disable the capFiles changed:
sei-cosmos/server/grpc/grpc_web.go,sei-cosmos/server/config/config.goTests
TestStartGRPCWebTimeouts— starts a real gRPC-Web server on a free loopback port and asserts all four timeout fields on the returned*http.Server.Test plan
go test ./sei-cosmos/server/grpc/... -run TestStartGRPCWebTimeouts -vpassesgofmt -s -l .prints nothingmake buildsucceeds🤖 Generated with Claude Code