github.com/ari-anchor/sei-tendermint@v0.0.0-20230519144642-dc826b7b56bb/light/client_benchmark_test.go (about)

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