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.

105 lines
1.9 KiB

  1. package main
  2. import (
  3. "encoding/binary"
  4. "encoding/hex"
  5. "fmt"
  6. "math/rand"
  7. "sync"
  8. "time"
  9. "github.com/pkg/errors"
  10. rpcclient "github.com/tendermint/go-rpc/client"
  11. rpctypes "github.com/tendermint/go-rpc/types"
  12. )
  13. type transacter struct {
  14. Target string
  15. Rate int
  16. Connections int
  17. conns []*rpcclient.WSClient
  18. wg sync.WaitGroup
  19. stopped bool
  20. }
  21. func newTransacter(target string, connections int, rate int) *transacter {
  22. conns := make([]*rpcclient.WSClient, connections)
  23. for i := 0; i < connections; i++ {
  24. conns[i] = rpcclient.NewWSClient(target, "/websocket")
  25. }
  26. return &transacter{
  27. Target: target,
  28. Rate: rate,
  29. Connections: connections,
  30. conns: conns,
  31. }
  32. }
  33. func (t *transacter) Start() error {
  34. t.stopped = false
  35. for _, c := range t.conns {
  36. if _, err := c.Start(); err != nil {
  37. return err
  38. }
  39. }
  40. for i := 0; i < t.Connections; i++ {
  41. t.wg.Add(1)
  42. go t.sendLoop(i)
  43. }
  44. return nil
  45. }
  46. func (t *transacter) Stop() {
  47. t.stopped = true
  48. t.wg.Wait()
  49. for _, c := range t.conns {
  50. c.Stop()
  51. }
  52. }
  53. func (t *transacter) sendLoop(connIndex int) {
  54. conn := t.conns[connIndex]
  55. var num = 0
  56. for {
  57. startTime := time.Now()
  58. for i := 0; i < t.Rate; i++ {
  59. if t.stopped {
  60. t.wg.Done()
  61. return
  62. }
  63. tx := generateTx(connIndex, num)
  64. err := conn.WriteJSON(rpctypes.RPCRequest{
  65. JSONRPC: "2.0",
  66. ID: "",
  67. Method: "broadcast_tx_async",
  68. Params: []interface{}{hex.EncodeToString(tx)},
  69. })
  70. if err != nil {
  71. panic(errors.Wrap(err, fmt.Sprintf("lost connection to %s", conn.Address)))
  72. }
  73. num++
  74. }
  75. timeToSend := time.Now().Sub(startTime)
  76. time.Sleep(time.Second - timeToSend)
  77. }
  78. }
  79. func generateTx(a int, b int) []byte {
  80. tx := make([]byte, 250)
  81. binary.PutUvarint(tx[:32], uint64(a))
  82. binary.PutUvarint(tx[32:64], uint64(b))
  83. if _, err := rand.Read(tx[234:]); err != nil {
  84. panic(errors.Wrap(err, "err reading from crypto/rand"))
  85. }
  86. return tx
  87. }