You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

354 lines
10 KiB

cleanup: Reduce and normalize import path aliasing. (#6975) The code in the Tendermint repository makes heavy use of import aliasing. This is made necessary by our extensive reuse of common base package names, and by repetition of similar names across different subdirectories. Unfortunately we have not been very consistent about which packages we alias in various circumstances, and the aliases we use vary. In the spirit of the advice in the style guide and https://github.com/golang/go/wiki/CodeReviewComments#imports, his change makes an effort to clean up and normalize import aliasing. This change makes no API or behavioral changes. It is a pure cleanup intended o help make the code more readable to developers (including myself) trying to understand what is being imported where. Only unexported names have been modified, and the changes were generated and applied mechanically with gofmt -r and comby, respecting the lexical and syntactic rules of Go. Even so, I did not fix every inconsistency. Where the changes would be too disruptive, I left it alone. The principles I followed in this cleanup are: - Remove aliases that restate the package name. - Remove aliases where the base package name is unambiguous. - Move overly-terse abbreviations from the import to the usage site. - Fix lexical issues (remove underscores, remove capitalization). - Fix import groupings to more closely match the style guide. - Group blank (side-effecting) imports and ensure they are commented. - Add aliases to multiple imports with the same base package name.
3 years ago
cleanup: Reduce and normalize import path aliasing. (#6975) The code in the Tendermint repository makes heavy use of import aliasing. This is made necessary by our extensive reuse of common base package names, and by repetition of similar names across different subdirectories. Unfortunately we have not been very consistent about which packages we alias in various circumstances, and the aliases we use vary. In the spirit of the advice in the style guide and https://github.com/golang/go/wiki/CodeReviewComments#imports, his change makes an effort to clean up and normalize import aliasing. This change makes no API or behavioral changes. It is a pure cleanup intended o help make the code more readable to developers (including myself) trying to understand what is being imported where. Only unexported names have been modified, and the changes were generated and applied mechanically with gofmt -r and comby, respecting the lexical and syntactic rules of Go. Even so, I did not fix every inconsistency. Where the changes would be too disruptive, I left it alone. The principles I followed in this cleanup are: - Remove aliases that restate the package name. - Remove aliases where the base package name is unambiguous. - Move overly-terse abbreviations from the import to the usage site. - Fix lexical issues (remove underscores, remove capitalization). - Fix import groupings to more closely match the style guide. - Group blank (side-effecting) imports and ensure they are commented. - Add aliases to multiple imports with the same base package name.
3 years ago
cleanup: Reduce and normalize import path aliasing. (#6975) The code in the Tendermint repository makes heavy use of import aliasing. This is made necessary by our extensive reuse of common base package names, and by repetition of similar names across different subdirectories. Unfortunately we have not been very consistent about which packages we alias in various circumstances, and the aliases we use vary. In the spirit of the advice in the style guide and https://github.com/golang/go/wiki/CodeReviewComments#imports, his change makes an effort to clean up and normalize import aliasing. This change makes no API or behavioral changes. It is a pure cleanup intended o help make the code more readable to developers (including myself) trying to understand what is being imported where. Only unexported names have been modified, and the changes were generated and applied mechanically with gofmt -r and comby, respecting the lexical and syntactic rules of Go. Even so, I did not fix every inconsistency. Where the changes would be too disruptive, I left it alone. The principles I followed in this cleanup are: - Remove aliases that restate the package name. - Remove aliases where the base package name is unambiguous. - Move overly-terse abbreviations from the import to the usage site. - Fix lexical issues (remove underscores, remove capitalization). - Fix import groupings to more closely match the style guide. - Group blank (side-effecting) imports and ensure they are commented. - Add aliases to multiple imports with the same base package name.
3 years ago
cleanup: Reduce and normalize import path aliasing. (#6975) The code in the Tendermint repository makes heavy use of import aliasing. This is made necessary by our extensive reuse of common base package names, and by repetition of similar names across different subdirectories. Unfortunately we have not been very consistent about which packages we alias in various circumstances, and the aliases we use vary. In the spirit of the advice in the style guide and https://github.com/golang/go/wiki/CodeReviewComments#imports, his change makes an effort to clean up and normalize import aliasing. This change makes no API or behavioral changes. It is a pure cleanup intended o help make the code more readable to developers (including myself) trying to understand what is being imported where. Only unexported names have been modified, and the changes were generated and applied mechanically with gofmt -r and comby, respecting the lexical and syntactic rules of Go. Even so, I did not fix every inconsistency. Where the changes would be too disruptive, I left it alone. The principles I followed in this cleanup are: - Remove aliases that restate the package name. - Remove aliases where the base package name is unambiguous. - Move overly-terse abbreviations from the import to the usage site. - Fix lexical issues (remove underscores, remove capitalization). - Fix import groupings to more closely match the style guide. - Group blank (side-effecting) imports and ensure they are commented. - Add aliases to multiple imports with the same base package name.
3 years ago
cleanup: Reduce and normalize import path aliasing. (#6975) The code in the Tendermint repository makes heavy use of import aliasing. This is made necessary by our extensive reuse of common base package names, and by repetition of similar names across different subdirectories. Unfortunately we have not been very consistent about which packages we alias in various circumstances, and the aliases we use vary. In the spirit of the advice in the style guide and https://github.com/golang/go/wiki/CodeReviewComments#imports, his change makes an effort to clean up and normalize import aliasing. This change makes no API or behavioral changes. It is a pure cleanup intended o help make the code more readable to developers (including myself) trying to understand what is being imported where. Only unexported names have been modified, and the changes were generated and applied mechanically with gofmt -r and comby, respecting the lexical and syntactic rules of Go. Even so, I did not fix every inconsistency. Where the changes would be too disruptive, I left it alone. The principles I followed in this cleanup are: - Remove aliases that restate the package name. - Remove aliases where the base package name is unambiguous. - Move overly-terse abbreviations from the import to the usage site. - Fix lexical issues (remove underscores, remove capitalization). - Fix import groupings to more closely match the style guide. - Group blank (side-effecting) imports and ensure they are commented. - Add aliases to multiple imports with the same base package name.
3 years ago
limit number of /subscribe clients and queries per client (#3269) * limit number of /subscribe clients and queries per client Add the following config variables (under [rpc] section): * max_subscription_clients * max_subscriptions_per_client * timeout_broadcast_tx_commit Fixes #2826 new HTTPClient interface for subscriptions finalize HTTPClient events interface remove EventSubscriber fix data race ``` WARNING: DATA RACE Read at 0x00c000a36060 by goroutine 129: github.com/tendermint/tendermint/rpc/client.(*Local).Subscribe.func1() /go/src/github.com/tendermint/tendermint/rpc/client/localclient.go:168 +0x1f0 Previous write at 0x00c000a36060 by goroutine 132: github.com/tendermint/tendermint/rpc/client.(*Local).Subscribe() /go/src/github.com/tendermint/tendermint/rpc/client/localclient.go:191 +0x4e0 github.com/tendermint/tendermint/rpc/client.WaitForOneEvent() /go/src/github.com/tendermint/tendermint/rpc/client/helpers.go:64 +0x178 github.com/tendermint/tendermint/rpc/client_test.TestTxEventsSentWithBroadcastTxSync.func1() /go/src/github.com/tendermint/tendermint/rpc/client/event_test.go:139 +0x298 testing.tRunner() /usr/local/go/src/testing/testing.go:827 +0x162 Goroutine 129 (running) created at: github.com/tendermint/tendermint/rpc/client.(*Local).Subscribe() /go/src/github.com/tendermint/tendermint/rpc/client/localclient.go:164 +0x4b7 github.com/tendermint/tendermint/rpc/client.WaitForOneEvent() /go/src/github.com/tendermint/tendermint/rpc/client/helpers.go:64 +0x178 github.com/tendermint/tendermint/rpc/client_test.TestTxEventsSentWithBroadcastTxSync.func1() /go/src/github.com/tendermint/tendermint/rpc/client/event_test.go:139 +0x298 testing.tRunner() /usr/local/go/src/testing/testing.go:827 +0x162 Goroutine 132 (running) created at: testing.(*T).Run() /usr/local/go/src/testing/testing.go:878 +0x659 github.com/tendermint/tendermint/rpc/client_test.TestTxEventsSentWithBroadcastTxSync() /go/src/github.com/tendermint/tendermint/rpc/client/event_test.go:119 +0x186 testing.tRunner() /usr/local/go/src/testing/testing.go:827 +0x162 ================== ``` lite client works (tested manually) godoc comments httpclient: do not close the out channel use TimeoutBroadcastTxCommit no timeout for unsubscribe but 1s Local (5s HTTP) timeout for resubscribe format code change Subscribe#out cap to 1 and replace config vars with RPCConfig TimeoutBroadcastTxCommit can't be greater than rpcserver.WriteTimeout rpc: Context as first parameter to all functions reformat code fixes after my own review fixes after Ethan's review add test stubs fix config.toml * fixes after manual testing - rpc: do not recommend to use BroadcastTxCommit because it's slow and wastes Tendermint resources (pubsub) - rpc: better error in Subscribe and BroadcastTxCommit - HTTPClient: do not resubscribe if err = ErrAlreadySubscribed * fixes after Ismail's review * Update rpc/grpc/grpc_test.go Co-Authored-By: melekes <anton.kalyaev@gmail.com>
6 years ago
cleanup: Reduce and normalize import path aliasing. (#6975) The code in the Tendermint repository makes heavy use of import aliasing. This is made necessary by our extensive reuse of common base package names, and by repetition of similar names across different subdirectories. Unfortunately we have not been very consistent about which packages we alias in various circumstances, and the aliases we use vary. In the spirit of the advice in the style guide and https://github.com/golang/go/wiki/CodeReviewComments#imports, his change makes an effort to clean up and normalize import aliasing. This change makes no API or behavioral changes. It is a pure cleanup intended o help make the code more readable to developers (including myself) trying to understand what is being imported where. Only unexported names have been modified, and the changes were generated and applied mechanically with gofmt -r and comby, respecting the lexical and syntactic rules of Go. Even so, I did not fix every inconsistency. Where the changes would be too disruptive, I left it alone. The principles I followed in this cleanup are: - Remove aliases that restate the package name. - Remove aliases where the base package name is unambiguous. - Move overly-terse abbreviations from the import to the usage site. - Fix lexical issues (remove underscores, remove capitalization). - Fix import groupings to more closely match the style guide. - Group blank (side-effecting) imports and ensure they are commented. - Add aliases to multiple imports with the same base package name.
3 years ago
cleanup: Reduce and normalize import path aliasing. (#6975) The code in the Tendermint repository makes heavy use of import aliasing. This is made necessary by our extensive reuse of common base package names, and by repetition of similar names across different subdirectories. Unfortunately we have not been very consistent about which packages we alias in various circumstances, and the aliases we use vary. In the spirit of the advice in the style guide and https://github.com/golang/go/wiki/CodeReviewComments#imports, his change makes an effort to clean up and normalize import aliasing. This change makes no API or behavioral changes. It is a pure cleanup intended o help make the code more readable to developers (including myself) trying to understand what is being imported where. Only unexported names have been modified, and the changes were generated and applied mechanically with gofmt -r and comby, respecting the lexical and syntactic rules of Go. Even so, I did not fix every inconsistency. Where the changes would be too disruptive, I left it alone. The principles I followed in this cleanup are: - Remove aliases that restate the package name. - Remove aliases where the base package name is unambiguous. - Move overly-terse abbreviations from the import to the usage site. - Fix lexical issues (remove underscores, remove capitalization). - Fix import groupings to more closely match the style guide. - Group blank (side-effecting) imports and ensure they are commented. - Add aliases to multiple imports with the same base package name.
3 years ago
cleanup: Reduce and normalize import path aliasing. (#6975) The code in the Tendermint repository makes heavy use of import aliasing. This is made necessary by our extensive reuse of common base package names, and by repetition of similar names across different subdirectories. Unfortunately we have not been very consistent about which packages we alias in various circumstances, and the aliases we use vary. In the spirit of the advice in the style guide and https://github.com/golang/go/wiki/CodeReviewComments#imports, his change makes an effort to clean up and normalize import aliasing. This change makes no API or behavioral changes. It is a pure cleanup intended o help make the code more readable to developers (including myself) trying to understand what is being imported where. Only unexported names have been modified, and the changes were generated and applied mechanically with gofmt -r and comby, respecting the lexical and syntactic rules of Go. Even so, I did not fix every inconsistency. Where the changes would be too disruptive, I left it alone. The principles I followed in this cleanup are: - Remove aliases that restate the package name. - Remove aliases where the base package name is unambiguous. - Move overly-terse abbreviations from the import to the usage site. - Fix lexical issues (remove underscores, remove capitalization). - Fix import groupings to more closely match the style guide. - Group blank (side-effecting) imports and ensure they are commented. - Add aliases to multiple imports with the same base package name.
3 years ago
cleanup: Reduce and normalize import path aliasing. (#6975) The code in the Tendermint repository makes heavy use of import aliasing. This is made necessary by our extensive reuse of common base package names, and by repetition of similar names across different subdirectories. Unfortunately we have not been very consistent about which packages we alias in various circumstances, and the aliases we use vary. In the spirit of the advice in the style guide and https://github.com/golang/go/wiki/CodeReviewComments#imports, his change makes an effort to clean up and normalize import aliasing. This change makes no API or behavioral changes. It is a pure cleanup intended o help make the code more readable to developers (including myself) trying to understand what is being imported where. Only unexported names have been modified, and the changes were generated and applied mechanically with gofmt -r and comby, respecting the lexical and syntactic rules of Go. Even so, I did not fix every inconsistency. Where the changes would be too disruptive, I left it alone. The principles I followed in this cleanup are: - Remove aliases that restate the package name. - Remove aliases where the base package name is unambiguous. - Move overly-terse abbreviations from the import to the usage site. - Fix lexical issues (remove underscores, remove capitalization). - Fix import groupings to more closely match the style guide. - Group blank (side-effecting) imports and ensure they are commented. - Add aliases to multiple imports with the same base package name.
3 years ago
cleanup: Reduce and normalize import path aliasing. (#6975) The code in the Tendermint repository makes heavy use of import aliasing. This is made necessary by our extensive reuse of common base package names, and by repetition of similar names across different subdirectories. Unfortunately we have not been very consistent about which packages we alias in various circumstances, and the aliases we use vary. In the spirit of the advice in the style guide and https://github.com/golang/go/wiki/CodeReviewComments#imports, his change makes an effort to clean up and normalize import aliasing. This change makes no API or behavioral changes. It is a pure cleanup intended o help make the code more readable to developers (including myself) trying to understand what is being imported where. Only unexported names have been modified, and the changes were generated and applied mechanically with gofmt -r and comby, respecting the lexical and syntactic rules of Go. Even so, I did not fix every inconsistency. Where the changes would be too disruptive, I left it alone. The principles I followed in this cleanup are: - Remove aliases that restate the package name. - Remove aliases where the base package name is unambiguous. - Move overly-terse abbreviations from the import to the usage site. - Fix lexical issues (remove underscores, remove capitalization). - Fix import groupings to more closely match the style guide. - Group blank (side-effecting) imports and ensure they are commented. - Add aliases to multiple imports with the same base package name.
3 years ago
  1. package core
  2. import (
  3. "context"
  4. "encoding/base64"
  5. "encoding/json"
  6. "fmt"
  7. "net"
  8. "net/http"
  9. "time"
  10. "github.com/rs/cors"
  11. "github.com/tendermint/tendermint/config"
  12. "github.com/tendermint/tendermint/crypto"
  13. "github.com/tendermint/tendermint/internal/blocksync"
  14. "github.com/tendermint/tendermint/internal/consensus"
  15. "github.com/tendermint/tendermint/internal/eventbus"
  16. "github.com/tendermint/tendermint/internal/eventlog"
  17. "github.com/tendermint/tendermint/internal/mempool"
  18. "github.com/tendermint/tendermint/internal/p2p"
  19. "github.com/tendermint/tendermint/internal/proxy"
  20. tmpubsub "github.com/tendermint/tendermint/internal/pubsub"
  21. "github.com/tendermint/tendermint/internal/pubsub/query"
  22. sm "github.com/tendermint/tendermint/internal/state"
  23. "github.com/tendermint/tendermint/internal/state/indexer"
  24. "github.com/tendermint/tendermint/internal/statesync"
  25. "github.com/tendermint/tendermint/libs/log"
  26. "github.com/tendermint/tendermint/libs/strings"
  27. "github.com/tendermint/tendermint/rpc/coretypes"
  28. rpcserver "github.com/tendermint/tendermint/rpc/jsonrpc/server"
  29. "github.com/tendermint/tendermint/types"
  30. )
  31. const (
  32. // see README
  33. defaultPerPage = 30
  34. maxPerPage = 100
  35. // SubscribeTimeout is the maximum time we wait to subscribe for an event.
  36. // must be less than the server's write timeout (see rpcserver.DefaultConfig)
  37. SubscribeTimeout = 5 * time.Second
  38. // genesisChunkSize is the maximum size, in bytes, of each
  39. // chunk in the genesis structure for the chunked API
  40. genesisChunkSize = 16 * 1024 * 1024 // 16
  41. )
  42. //----------------------------------------------
  43. // These interfaces are used by RPC and must be thread safe
  44. type consensusState interface {
  45. GetState() sm.State
  46. GetValidators() (int64, []*types.Validator)
  47. GetLastHeight() int64
  48. GetRoundStateJSON() ([]byte, error)
  49. GetRoundStateSimpleJSON() ([]byte, error)
  50. }
  51. type peerManager interface {
  52. Peers() []types.NodeID
  53. Addresses(types.NodeID) []p2p.NodeAddress
  54. }
  55. //----------------------------------------------
  56. // Environment contains objects and interfaces used by the RPC. It is expected
  57. // to be setup once during startup.
  58. type Environment struct {
  59. // external, thread safe interfaces
  60. ProxyAppQuery proxy.AppConnQuery
  61. ProxyAppMempool proxy.AppConnMempool
  62. // interfaces defined in types and above
  63. StateStore sm.Store
  64. BlockStore sm.BlockStore
  65. EvidencePool sm.EvidencePool
  66. ConsensusState consensusState
  67. ConsensusReactor *consensus.Reactor
  68. BlockSyncReactor *blocksync.Reactor
  69. IsListening bool
  70. Listeners []string
  71. NodeInfo types.NodeInfo
  72. // interfaces for new p2p interfaces
  73. PeerManager peerManager
  74. // objects
  75. PubKey crypto.PubKey
  76. GenDoc *types.GenesisDoc // cache the genesis structure
  77. EventSinks []indexer.EventSink
  78. EventBus *eventbus.EventBus // thread safe
  79. EventLog *eventlog.Log
  80. Mempool mempool.Mempool
  81. StateSyncMetricer statesync.Metricer
  82. Logger log.Logger
  83. Config config.RPCConfig
  84. // cache of chunked genesis data.
  85. genChunks []string
  86. }
  87. //----------------------------------------------
  88. func validatePage(pagePtr *int, perPage, totalCount int) (int, error) {
  89. // this can only happen if we haven't first run validatePerPage
  90. if perPage < 1 {
  91. panic(fmt.Errorf("%w (%d)", coretypes.ErrZeroOrNegativePerPage, perPage))
  92. }
  93. if pagePtr == nil { // no page parameter
  94. return 1, nil
  95. }
  96. pages := ((totalCount - 1) / perPage) + 1
  97. if pages == 0 {
  98. pages = 1 // one page (even if it's empty)
  99. }
  100. page := *pagePtr
  101. if page <= 0 || page > pages {
  102. return 1, fmt.Errorf("%w expected range: [1, %d], given %d", coretypes.ErrPageOutOfRange, pages, page)
  103. }
  104. return page, nil
  105. }
  106. func (env *Environment) validatePerPage(perPagePtr *int) int {
  107. if perPagePtr == nil { // no per_page parameter
  108. return defaultPerPage
  109. }
  110. perPage := *perPagePtr
  111. if perPage < 1 {
  112. return defaultPerPage
  113. // in unsafe mode there is no max on the page size but in safe mode
  114. // we cap it to maxPerPage
  115. } else if perPage > maxPerPage && !env.Config.Unsafe {
  116. return maxPerPage
  117. }
  118. return perPage
  119. }
  120. // InitGenesisChunks configures the environment and should be called on service
  121. // startup.
  122. func (env *Environment) InitGenesisChunks() error {
  123. if env.genChunks != nil {
  124. return nil
  125. }
  126. if env.GenDoc == nil {
  127. return nil
  128. }
  129. data, err := json.Marshal(env.GenDoc)
  130. if err != nil {
  131. return err
  132. }
  133. for i := 0; i < len(data); i += genesisChunkSize {
  134. end := i + genesisChunkSize
  135. if end > len(data) {
  136. end = len(data)
  137. }
  138. env.genChunks = append(env.genChunks, base64.StdEncoding.EncodeToString(data[i:end]))
  139. }
  140. return nil
  141. }
  142. func validateSkipCount(page, perPage int) int {
  143. skipCount := (page - 1) * perPage
  144. if skipCount < 0 {
  145. return 0
  146. }
  147. return skipCount
  148. }
  149. // latestHeight can be either latest committed or uncommitted (+1) height.
  150. func (env *Environment) getHeight(latestHeight int64, heightPtr *int64) (int64, error) {
  151. if heightPtr != nil {
  152. height := *heightPtr
  153. if height <= 0 {
  154. return 0, fmt.Errorf("%w (requested height: %d)", coretypes.ErrZeroOrNegativeHeight, height)
  155. }
  156. if height > latestHeight {
  157. return 0, fmt.Errorf("%w (requested height: %d, blockchain height: %d)",
  158. coretypes.ErrHeightExceedsChainHead, height, latestHeight)
  159. }
  160. base := env.BlockStore.Base()
  161. if height < base {
  162. return 0, fmt.Errorf("%w (requested height: %d, base height: %d)", coretypes.ErrHeightNotAvailable, height, base)
  163. }
  164. return height, nil
  165. }
  166. return latestHeight, nil
  167. }
  168. func (env *Environment) latestUncommittedHeight() int64 {
  169. if env.ConsensusReactor != nil {
  170. // consensus reactor can be nil in inspect mode.
  171. nodeIsSyncing := env.ConsensusReactor.WaitSync()
  172. if nodeIsSyncing {
  173. return env.BlockStore.Height()
  174. }
  175. }
  176. return env.BlockStore.Height() + 1
  177. }
  178. // StartService constructs and starts listeners for the RPC service
  179. // according to the config object, returning an error if the service
  180. // cannot be constructed or started. The listeners, which provide
  181. // access to the service, run until the context is canceled.
  182. func (env *Environment) StartService(ctx context.Context, conf *config.Config) ([]net.Listener, error) {
  183. if err := env.InitGenesisChunks(); err != nil {
  184. return nil, err
  185. }
  186. env.Listeners = []string{
  187. fmt.Sprintf("Listener(@%v)", conf.P2P.ExternalAddress),
  188. }
  189. listenAddrs := strings.SplitAndTrimEmpty(conf.RPC.ListenAddress, ",", " ")
  190. routes := NewRoutesMap(env, &RouteOptions{
  191. Unsafe: conf.RPC.Unsafe,
  192. })
  193. cfg := rpcserver.DefaultConfig()
  194. cfg.MaxBodyBytes = conf.RPC.MaxBodyBytes
  195. cfg.MaxHeaderBytes = conf.RPC.MaxHeaderBytes
  196. cfg.MaxOpenConnections = conf.RPC.MaxOpenConnections
  197. // If necessary adjust global WriteTimeout to ensure it's greater than
  198. // TimeoutBroadcastTxCommit.
  199. // See https://github.com/tendermint/tendermint/issues/3435
  200. if cfg.WriteTimeout <= conf.RPC.TimeoutBroadcastTxCommit {
  201. cfg.WriteTimeout = conf.RPC.TimeoutBroadcastTxCommit + 1*time.Second
  202. }
  203. // If the event log is enabled, subscribe to all events published to the
  204. // event bus, and forward them to the event log.
  205. if lg := env.EventLog; lg != nil {
  206. // TODO(creachadair): This is kind of a hack, ideally we'd share the
  207. // observer with the indexer, but it's tricky to plumb them together.
  208. // For now, use a "normal" subscription with a big buffer allowance.
  209. // The event log should always be able to keep up.
  210. const subscriberID = "event-log-subscriber"
  211. sub, err := env.EventBus.SubscribeWithArgs(ctx, tmpubsub.SubscribeArgs{
  212. ClientID: subscriberID,
  213. Query: query.All,
  214. Limit: 1 << 16, // essentially "no limit"
  215. })
  216. if err != nil {
  217. return nil, fmt.Errorf("event log subscribe: %w", err)
  218. }
  219. go func() {
  220. // N.B. Use background for unsubscribe, ctx is already terminated.
  221. defer env.EventBus.UnsubscribeAll(context.Background(), subscriberID) // nolint:errcheck
  222. for {
  223. msg, err := sub.Next(ctx)
  224. if err != nil {
  225. env.Logger.Error("Subscription terminated", "err", err)
  226. return
  227. }
  228. etype, ok := eventlog.FindType(msg.Events())
  229. if ok {
  230. _ = lg.Add(etype, msg.Data())
  231. }
  232. }
  233. }()
  234. env.Logger.Info("Event log subscription enabled")
  235. }
  236. // We may expose the RPC over both TCP and a Unix-domain socket.
  237. listeners := make([]net.Listener, len(listenAddrs))
  238. for i, listenAddr := range listenAddrs {
  239. mux := http.NewServeMux()
  240. rpcLogger := env.Logger.With("module", "rpc-server")
  241. rpcserver.RegisterRPCFuncs(mux, routes, rpcLogger)
  242. if conf.RPC.ExperimentalDisableWebsocket {
  243. rpcLogger.Info("Disabling websocket endpoints (experimental-disable-websocket=true)")
  244. } else {
  245. rpcLogger.Info("WARNING: Websocket RPC access is deprecated and will be removed " +
  246. "in Tendermint v0.37. See https://tinyurl.com/adr075 for more information.")
  247. wmLogger := rpcLogger.With("protocol", "websocket")
  248. wm := rpcserver.NewWebsocketManager(wmLogger, routes,
  249. rpcserver.OnDisconnect(func(remoteAddr string) {
  250. err := env.EventBus.UnsubscribeAll(context.Background(), remoteAddr)
  251. if err != nil && err != tmpubsub.ErrSubscriptionNotFound {
  252. wmLogger.Error("Failed to unsubscribe addr from events", "addr", remoteAddr, "err", err)
  253. }
  254. }),
  255. rpcserver.ReadLimit(cfg.MaxBodyBytes),
  256. )
  257. mux.HandleFunc("/websocket", wm.WebsocketHandler)
  258. }
  259. listener, err := rpcserver.Listen(
  260. listenAddr,
  261. cfg.MaxOpenConnections,
  262. )
  263. if err != nil {
  264. return nil, err
  265. }
  266. var rootHandler http.Handler = mux
  267. if conf.RPC.IsCorsEnabled() {
  268. corsMiddleware := cors.New(cors.Options{
  269. AllowedOrigins: conf.RPC.CORSAllowedOrigins,
  270. AllowedMethods: conf.RPC.CORSAllowedMethods,
  271. AllowedHeaders: conf.RPC.CORSAllowedHeaders,
  272. })
  273. rootHandler = corsMiddleware.Handler(mux)
  274. }
  275. if conf.RPC.IsTLSEnabled() {
  276. go func() {
  277. if err := rpcserver.ServeTLS(
  278. ctx,
  279. listener,
  280. rootHandler,
  281. conf.RPC.CertFile(),
  282. conf.RPC.KeyFile(),
  283. rpcLogger,
  284. cfg,
  285. ); err != nil {
  286. env.Logger.Error("error serving server with TLS", "err", err)
  287. }
  288. }()
  289. } else {
  290. go func() {
  291. if err := rpcserver.Serve(
  292. ctx,
  293. listener,
  294. rootHandler,
  295. rpcLogger,
  296. cfg,
  297. ); err != nil {
  298. env.Logger.Error("error serving server", "err", err)
  299. }
  300. }()
  301. }
  302. listeners[i] = listener
  303. }
  304. return listeners, nil
  305. }