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.

128 lines
3.4 KiB

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
7 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
  1. package core
  2. import (
  3. "fmt"
  4. "sort"
  5. "github.com/pkg/errors"
  6. tmmath "github.com/tendermint/tendermint/libs/math"
  7. tmquery "github.com/tendermint/tendermint/libs/pubsub/query"
  8. ctypes "github.com/tendermint/tendermint/rpc/core/types"
  9. rpctypes "github.com/tendermint/tendermint/rpc/lib/types"
  10. "github.com/tendermint/tendermint/state/txindex/null"
  11. "github.com/tendermint/tendermint/types"
  12. )
  13. // Tx allows you to query the transaction results. `nil` could mean the
  14. // transaction is in the mempool, invalidated, or was not sent in the first
  15. // place.
  16. // More: https://docs.tendermint.com/master/rpc/#/Info/tx
  17. func Tx(ctx *rpctypes.Context, hash []byte, prove bool) (*ctypes.ResultTx, error) {
  18. // if index is disabled, return error
  19. if _, ok := txIndexer.(*null.TxIndex); ok {
  20. return nil, fmt.Errorf("transaction indexing is disabled")
  21. }
  22. r, err := txIndexer.Get(hash)
  23. if err != nil {
  24. return nil, err
  25. }
  26. if r == nil {
  27. return nil, fmt.Errorf("tx (%X) not found", hash)
  28. }
  29. height := r.Height
  30. index := r.Index
  31. var proof types.TxProof
  32. if prove {
  33. block := blockStore.LoadBlock(height)
  34. proof = block.Data.Txs.Proof(int(index)) // XXX: overflow on 32-bit machines
  35. }
  36. return &ctypes.ResultTx{
  37. Hash: hash,
  38. Height: height,
  39. Index: index,
  40. TxResult: r.Result,
  41. Tx: r.Tx,
  42. Proof: proof,
  43. }, nil
  44. }
  45. // TxSearch allows you to query for multiple transactions results. It returns a
  46. // list of transactions (maximum ?per_page entries) and the total count.
  47. // More: https://docs.tendermint.com/master/rpc/#/Info/tx_search
  48. func TxSearch(ctx *rpctypes.Context, query string, prove bool, page, perPage int, orderBy string) (
  49. *ctypes.ResultTxSearch, error) {
  50. // if index is disabled, return error
  51. if _, ok := txIndexer.(*null.TxIndex); ok {
  52. return nil, errors.New("transaction indexing is disabled")
  53. }
  54. q, err := tmquery.New(query)
  55. if err != nil {
  56. return nil, err
  57. }
  58. results, err := txIndexer.Search(q)
  59. if err != nil {
  60. return nil, err
  61. }
  62. totalCount := len(results)
  63. perPage = validatePerPage(perPage)
  64. page, err = validatePage(page, perPage, totalCount)
  65. if err != nil {
  66. return nil, err
  67. }
  68. skipCount := validateSkipCount(page, perPage)
  69. apiResults := make([]*ctypes.ResultTx, tmmath.MinInt(perPage, totalCount-skipCount))
  70. var proof types.TxProof
  71. // if there's no tx in the results array, we don't need to loop through the apiResults array
  72. for i := 0; i < len(apiResults); i++ {
  73. r := results[skipCount+i]
  74. height := r.Height
  75. index := r.Index
  76. if prove {
  77. block := blockStore.LoadBlock(height)
  78. proof = block.Data.Txs.Proof(int(index)) // XXX: overflow on 32-bit machines
  79. }
  80. apiResults[i] = &ctypes.ResultTx{
  81. Hash: r.Tx.Hash(),
  82. Height: height,
  83. Index: index,
  84. TxResult: r.Result,
  85. Tx: r.Tx,
  86. Proof: proof,
  87. }
  88. }
  89. if len(apiResults) > 1 {
  90. switch orderBy {
  91. case "desc":
  92. sort.Slice(apiResults, func(i, j int) bool {
  93. if apiResults[i].Height == apiResults[j].Height {
  94. return apiResults[i].Index > apiResults[j].Index
  95. }
  96. return apiResults[i].Height > apiResults[j].Height
  97. })
  98. case "asc", "":
  99. sort.Slice(apiResults, func(i, j int) bool {
  100. if apiResults[i].Height == apiResults[j].Height {
  101. return apiResults[i].Index < apiResults[j].Index
  102. }
  103. return apiResults[i].Height < apiResults[j].Height
  104. })
  105. default:
  106. return nil, errors.New("expected order_by to be either `asc` or `desc` or empty")
  107. }
  108. }
  109. return &ctypes.ResultTxSearch{Txs: apiResults, TotalCount: totalCount}, nil
  110. }