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.

176 lines
4.3 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. // provierBenchmarkImpl does not have an ID iteself.
  56. // Thus we return a sample string
  57. func (impl *providerBenchmarkImpl) ID() string { return "ip-not-defined.com" }
  58. func BenchmarkSequence(b *testing.B) {
  59. ctx, cancel := context.WithCancel(context.Background())
  60. defer cancel()
  61. headers, vals, _ := genLightBlocksWithKeys(b, chainID, 1000, 100, 1, bTime)
  62. benchmarkFullNode := newProviderBenchmarkImpl(headers, vals)
  63. genesisBlock, _ := benchmarkFullNode.LightBlock(ctx, 1)
  64. logger := log.NewTestingLogger(b)
  65. c, err := light.NewClient(
  66. ctx,
  67. chainID,
  68. light.TrustOptions{
  69. Period: 24 * time.Hour,
  70. Height: 1,
  71. Hash: genesisBlock.Hash(),
  72. },
  73. benchmarkFullNode,
  74. []provider.Provider{benchmarkFullNode},
  75. dbs.New(dbm.NewMemDB()),
  76. light.Logger(logger),
  77. light.SequentialVerification(),
  78. )
  79. if err != nil {
  80. b.Fatal(err)
  81. }
  82. b.ResetTimer()
  83. for n := 0; n < b.N; n++ {
  84. _, err = c.VerifyLightBlockAtHeight(ctx, 1000, bTime.Add(1000*time.Minute))
  85. if err != nil {
  86. b.Fatal(err)
  87. }
  88. }
  89. }
  90. func BenchmarkBisection(b *testing.B) {
  91. ctx, cancel := context.WithCancel(context.Background())
  92. defer cancel()
  93. headers, vals, _ := genLightBlocksWithKeys(b, chainID, 1000, 100, 1, bTime)
  94. benchmarkFullNode := newProviderBenchmarkImpl(headers, vals)
  95. genesisBlock, _ := benchmarkFullNode.LightBlock(ctx, 1)
  96. logger := log.NewTestingLogger(b)
  97. c, err := light.NewClient(
  98. context.Background(),
  99. chainID,
  100. light.TrustOptions{
  101. Period: 24 * time.Hour,
  102. Height: 1,
  103. Hash: genesisBlock.Hash(),
  104. },
  105. benchmarkFullNode,
  106. []provider.Provider{benchmarkFullNode},
  107. dbs.New(dbm.NewMemDB()),
  108. light.Logger(logger),
  109. )
  110. if err != nil {
  111. b.Fatal(err)
  112. }
  113. b.ResetTimer()
  114. for n := 0; n < b.N; n++ {
  115. _, err = c.VerifyLightBlockAtHeight(ctx, 1000, bTime.Add(1000*time.Minute))
  116. if err != nil {
  117. b.Fatal(err)
  118. }
  119. }
  120. }
  121. func BenchmarkBackwards(b *testing.B) {
  122. ctx, cancel := context.WithCancel(context.Background())
  123. defer cancel()
  124. headers, vals, _ := genLightBlocksWithKeys(b, chainID, 1000, 100, 1, bTime)
  125. benchmarkFullNode := newProviderBenchmarkImpl(headers, vals)
  126. trustedBlock, _ := benchmarkFullNode.LightBlock(ctx, 0)
  127. logger := log.NewTestingLogger(b)
  128. c, err := light.NewClient(
  129. ctx,
  130. chainID,
  131. light.TrustOptions{
  132. Period: 24 * time.Hour,
  133. Height: trustedBlock.Height,
  134. Hash: trustedBlock.Hash(),
  135. },
  136. benchmarkFullNode,
  137. []provider.Provider{benchmarkFullNode},
  138. dbs.New(dbm.NewMemDB()),
  139. light.Logger(logger),
  140. )
  141. if err != nil {
  142. b.Fatal(err)
  143. }
  144. b.ResetTimer()
  145. for n := 0; n < b.N; n++ {
  146. _, err = c.VerifyLightBlockAtHeight(ctx, 1, bTime)
  147. if err != nil {
  148. b.Fatal(err)
  149. }
  150. }
  151. }