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.

171 lines
4.1 KiB

  1. package light_test
  2. import (
  3. "context"
  4. "errors"
  5. "testing"
  6. "time"
  7. dbm "github.com/tendermint/tm-db"
  8. "github.com/tendermint/tendermint/libs/log"
  9. "github.com/tendermint/tendermint/light"
  10. "github.com/tendermint/tendermint/light/provider"
  11. dbs "github.com/tendermint/tendermint/light/store/db"
  12. "github.com/tendermint/tendermint/types"
  13. )
  14. // NOTE: block is produced every minute. Make sure the verification time
  15. // provided in the function call is correct for the size of the blockchain. The
  16. // benchmarking may take some time hence it can be more useful to set the time
  17. // or the amount of iterations use the flag -benchtime t -> i.e. -benchtime 5m
  18. // or -benchtime 100x.
  19. //
  20. // Remember that none of these benchmarks account for network latency.
  21. var ()
  22. type providerBenchmarkImpl struct {
  23. currentHeight int64
  24. blocks map[int64]*types.LightBlock
  25. }
  26. func newProviderBenchmarkImpl(headers map[int64]*types.SignedHeader,
  27. vals map[int64]*types.ValidatorSet) provider.Provider {
  28. impl := providerBenchmarkImpl{
  29. blocks: make(map[int64]*types.LightBlock, len(headers)),
  30. }
  31. for height, header := range headers {
  32. if height > impl.currentHeight {
  33. impl.currentHeight = height
  34. }
  35. impl.blocks[height] = &types.LightBlock{
  36. SignedHeader: header,
  37. ValidatorSet: vals[height],
  38. }
  39. }
  40. return &impl
  41. }
  42. func (impl *providerBenchmarkImpl) LightBlock(ctx context.Context, height int64) (*types.LightBlock, error) {
  43. if height == 0 {
  44. return impl.blocks[impl.currentHeight], nil
  45. }
  46. lb, ok := impl.blocks[height]
  47. if !ok {
  48. return nil, provider.ErrLightBlockNotFound
  49. }
  50. return lb, nil
  51. }
  52. func (impl *providerBenchmarkImpl) ReportEvidence(_ context.Context, _ types.Evidence) error {
  53. return errors.New("not implemented")
  54. }
  55. func BenchmarkSequence(b *testing.B) {
  56. ctx, cancel := context.WithCancel(context.Background())
  57. defer cancel()
  58. headers, vals, _ := genLightBlocksWithKeys(b, chainID, 1000, 100, 1, bTime)
  59. benchmarkFullNode := newProviderBenchmarkImpl(headers, vals)
  60. genesisBlock, _ := benchmarkFullNode.LightBlock(ctx, 1)
  61. logger := log.NewTestingLogger(b)
  62. c, err := light.NewClient(
  63. ctx,
  64. chainID,
  65. light.TrustOptions{
  66. Period: 24 * time.Hour,
  67. Height: 1,
  68. Hash: genesisBlock.Hash(),
  69. },
  70. benchmarkFullNode,
  71. []provider.Provider{benchmarkFullNode},
  72. dbs.New(dbm.NewMemDB()),
  73. light.Logger(logger),
  74. light.SequentialVerification(),
  75. )
  76. if err != nil {
  77. b.Fatal(err)
  78. }
  79. b.ResetTimer()
  80. for n := 0; n < b.N; n++ {
  81. _, err = c.VerifyLightBlockAtHeight(ctx, 1000, bTime.Add(1000*time.Minute))
  82. if err != nil {
  83. b.Fatal(err)
  84. }
  85. }
  86. }
  87. func BenchmarkBisection(b *testing.B) {
  88. ctx, cancel := context.WithCancel(context.Background())
  89. defer cancel()
  90. headers, vals, _ := genLightBlocksWithKeys(b, chainID, 1000, 100, 1, bTime)
  91. benchmarkFullNode := newProviderBenchmarkImpl(headers, vals)
  92. genesisBlock, _ := benchmarkFullNode.LightBlock(ctx, 1)
  93. logger := log.NewTestingLogger(b)
  94. c, err := light.NewClient(
  95. context.Background(),
  96. chainID,
  97. light.TrustOptions{
  98. Period: 24 * time.Hour,
  99. Height: 1,
  100. Hash: genesisBlock.Hash(),
  101. },
  102. benchmarkFullNode,
  103. []provider.Provider{benchmarkFullNode},
  104. dbs.New(dbm.NewMemDB()),
  105. light.Logger(logger),
  106. )
  107. if err != nil {
  108. b.Fatal(err)
  109. }
  110. b.ResetTimer()
  111. for n := 0; n < b.N; n++ {
  112. _, err = c.VerifyLightBlockAtHeight(ctx, 1000, bTime.Add(1000*time.Minute))
  113. if err != nil {
  114. b.Fatal(err)
  115. }
  116. }
  117. }
  118. func BenchmarkBackwards(b *testing.B) {
  119. ctx, cancel := context.WithCancel(context.Background())
  120. defer cancel()
  121. headers, vals, _ := genLightBlocksWithKeys(b, chainID, 1000, 100, 1, bTime)
  122. benchmarkFullNode := newProviderBenchmarkImpl(headers, vals)
  123. trustedBlock, _ := benchmarkFullNode.LightBlock(ctx, 0)
  124. logger := log.NewTestingLogger(b)
  125. c, err := light.NewClient(
  126. ctx,
  127. chainID,
  128. light.TrustOptions{
  129. Period: 24 * time.Hour,
  130. Height: trustedBlock.Height,
  131. Hash: trustedBlock.Hash(),
  132. },
  133. benchmarkFullNode,
  134. []provider.Provider{benchmarkFullNode},
  135. dbs.New(dbm.NewMemDB()),
  136. light.Logger(logger),
  137. )
  138. if err != nil {
  139. b.Fatal(err)
  140. }
  141. b.ResetTimer()
  142. for n := 0; n < b.N; n++ {
  143. _, err = c.VerifyLightBlockAtHeight(ctx, 1, bTime)
  144. if err != nil {
  145. b.Fatal(err)
  146. }
  147. }
  148. }