Skip to content

Commit e9ba141

Browse files
authored
fix: data race issues with api.Server (backport #11724) (#11748)
1 parent 3911f52 commit e9ba141

File tree

2 files changed

+19
-2
lines changed

2 files changed

+19
-2
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ Ref: https://keepachangelog.com/en/1.0.0/
3737

3838
## [Unreleased]
3939

40+
### Bug Fixes
41+
42+
* [\#11724](https://github.com/cosmos/cosmos-sdk/pull/11724) Fix data race issues with `api.Server`.
43+
4044
### Improvements
4145

4246
* [\#11693](https://github.com/cosmos/cosmos-sdk/pull/11693) Add validation for gentx cmd.

server/api/server.go

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"net"
66
"net/http"
77
"strings"
8+
"sync"
89
"time"
910

1011
"github.com/gogo/gateway"
@@ -30,8 +31,13 @@ type Server struct {
3031
GRPCGatewayRouter *runtime.ServeMux
3132
ClientCtx client.Context
3233

33-
logger log.Logger
34-
metrics *telemetry.Metrics
34+
logger log.Logger
35+
metrics *telemetry.Metrics
36+
// Start() is blocking and generally called from a separate goroutine.
37+
// Close() can be called asynchronously and access shared memory
38+
// via the listener. Therefore, we sync access to Start and Close with
39+
// this mutex to avoid data races.
40+
mtx sync.Mutex
3541
listener net.Listener
3642
}
3743

@@ -83,9 +89,11 @@ func New(clientCtx client.Context, logger log.Logger) *Server {
8389
// and are delegated to the Tendermint JSON RPC server. The process is
8490
// non-blocking, so an external signal handler must be used.
8591
func (s *Server) Start(cfg config.Config) error {
92+
s.mtx.Lock()
8693
if cfg.Telemetry.Enabled {
8794
m, err := telemetry.New(cfg.Telemetry)
8895
if err != nil {
96+
s.mtx.Unlock()
8997
return err
9098
}
9199

@@ -101,6 +109,7 @@ func (s *Server) Start(cfg config.Config) error {
101109

102110
listener, err := tmrpcserver.Listen(cfg.API.Address, tmCfg)
103111
if err != nil {
112+
s.mtx.Unlock()
104113
return err
105114
}
106115

@@ -111,15 +120,19 @@ func (s *Server) Start(cfg config.Config) error {
111120

112121
if cfg.API.EnableUnsafeCORS {
113122
allowAllCORS := handlers.CORS(handlers.AllowedHeaders([]string{"Content-Type"}))
123+
s.mtx.Unlock()
114124
return tmrpcserver.Serve(s.listener, allowAllCORS(h), s.logger, tmCfg)
115125
}
116126

117127
s.logger.Info("starting API server...")
128+
s.mtx.Unlock()
118129
return tmrpcserver.Serve(s.listener, s.Router, s.logger, tmCfg)
119130
}
120131

121132
// Close closes the API server.
122133
func (s *Server) Close() error {
134+
s.mtx.Lock()
135+
defer s.mtx.Unlock()
123136
return s.listener.Close()
124137
}
125138

0 commit comments

Comments
 (0)