github.com/okex/exchain@v1.8.0/libs/tendermint/lite/provider_test.go (about)

     1  package lite
     2  
     3  import (
     4  	"errors"
     5  	"testing"
     6  
     7  	"github.com/stretchr/testify/assert"
     8  	"github.com/stretchr/testify/require"
     9  
    10  	dbm "github.com/okex/exchain/libs/tm-db"
    11  
    12  	log "github.com/okex/exchain/libs/tendermint/libs/log"
    13  	lerr "github.com/okex/exchain/libs/tendermint/lite/errors"
    14  	"github.com/okex/exchain/libs/tendermint/types"
    15  )
    16  
    17  // missingProvider doesn't store anything, always a miss.
    18  // Designed as a mock for testing.
    19  type missingProvider struct{}
    20  
    21  // NewMissingProvider returns a provider which does not store anything and always misses.
    22  func NewMissingProvider() PersistentProvider {
    23  	return missingProvider{}
    24  }
    25  
    26  func (missingProvider) SaveFullCommit(FullCommit) error { return nil }
    27  func (missingProvider) LatestFullCommit(chainID string, minHeight, maxHeight int64) (FullCommit, error) {
    28  	return FullCommit{}, lerr.ErrCommitNotFound()
    29  }
    30  func (missingProvider) ValidatorSet(chainID string, height int64) (*types.ValidatorSet, error) {
    31  	return nil, errors.New("missing validator set")
    32  }
    33  func (missingProvider) SetLogger(_ log.Logger) {}
    34  
    35  func TestMemProvider(t *testing.T) {
    36  	p := NewDBProvider("mem", dbm.NewMemDB())
    37  	checkProvider(t, p, "test-mem", "empty")
    38  }
    39  
    40  func TestMultiProvider(t *testing.T) {
    41  	p := NewMultiProvider(
    42  		NewMissingProvider(),
    43  		NewDBProvider("mem", dbm.NewMemDB()),
    44  		NewMissingProvider(),
    45  	)
    46  	checkProvider(t, p, "test-cache", "kjfhekfhkewhgit")
    47  }
    48  
    49  func checkProvider(t *testing.T, p PersistentProvider, chainID, app string) {
    50  	assert, require := assert.New(t), require.New(t)
    51  	appHash := []byte(app)
    52  	keys := genPrivKeys(5)
    53  	count := 10
    54  
    55  	// Make a bunch of full commits.
    56  	fcz := make([]FullCommit, count)
    57  	for i := 0; i < count; i++ {
    58  		vals := keys.ToValidators(10, int64(count/2))
    59  		h := int64(20 + 10*i)
    60  		fcz[i] = keys.GenFullCommit(chainID, h, nil, vals, vals, appHash, []byte("params"), []byte("results"), 0, 5)
    61  	}
    62  
    63  	// Check that provider is initially empty.
    64  	fc, err := p.LatestFullCommit(chainID, 1, 1<<63-1)
    65  	require.NotNil(err)
    66  	assert.True(lerr.IsErrCommitNotFound(err))
    67  
    68  	// Save all full commits to the provider.
    69  	for _, fc := range fcz {
    70  		err = p.SaveFullCommit(fc)
    71  		require.Nil(err)
    72  		// Make sure we can get it back.
    73  		fc2, err := p.LatestFullCommit(chainID, fc.Height(), fc.Height())
    74  		assert.Nil(err)
    75  		assert.Equal(fc.SignedHeader, fc2.SignedHeader)
    76  		assert.Equal(fc.Validators, fc2.Validators)
    77  		assert.Equal(fc.NextValidators, fc2.NextValidators)
    78  	}
    79  
    80  	// Make sure we get the last hash if we overstep.
    81  	fc, err = p.LatestFullCommit(chainID, 1, 5000)
    82  	if assert.Nil(err) {
    83  		assert.Equal(fcz[count-1].Height(), fc.Height())
    84  		assert.Equal(fcz[count-1], fc)
    85  	}
    86  
    87  	// ... and middle ones as well.
    88  	fc, err = p.LatestFullCommit(chainID, 1, 47)
    89  	if assert.Nil(err) {
    90  		// we only step by 10, so 40 must be the one below this
    91  		assert.EqualValues(40, fc.Height())
    92  	}
    93  
    94  }
    95  
    96  // This will make a get height, and if it is good, set the data as well.
    97  func checkLatestFullCommit(t *testing.T, p PersistentProvider, chainID string, ask, expect int64) {
    98  	fc, err := p.LatestFullCommit(chainID, 1, ask)
    99  	require.Nil(t, err)
   100  	if assert.Equal(t, expect, fc.Height()) {
   101  		err = p.SaveFullCommit(fc)
   102  		require.Nil(t, err)
   103  	}
   104  }
   105  
   106  func TestMultiLatestFullCommit(t *testing.T) {
   107  	require := require.New(t)
   108  
   109  	// We will write data to the second level of the cache (p2), and see what
   110  	// gets cached/stored in.
   111  	p := NewDBProvider("mem1", dbm.NewMemDB())
   112  	p2 := NewDBProvider("mem2", dbm.NewMemDB())
   113  	cp := NewMultiProvider(p, p2)
   114  
   115  	chainID := "cache-best-height"
   116  	appHash := []byte("01234567")
   117  	keys := genPrivKeys(5)
   118  	count := 10
   119  
   120  	// Set a bunch of full commits.
   121  	for i := 0; i < count; i++ {
   122  		vals := keys.ToValidators(10, int64(count/2))
   123  		h := int64(10 * (i + 1))
   124  		fc := keys.GenFullCommit(chainID, h, nil, vals, vals, appHash, []byte("params"), []byte("results"), 0, 5)
   125  		err := p2.SaveFullCommit(fc)
   126  		require.NoError(err)
   127  	}
   128  
   129  	// Get a few heights from the cache and set them proper.
   130  	checkLatestFullCommit(t, cp, chainID, 57, 50)
   131  	checkLatestFullCommit(t, cp, chainID, 33, 30)
   132  
   133  	// make sure they are set in p as well (but nothing else)
   134  	checkLatestFullCommit(t, p, chainID, 44, 30)
   135  	checkLatestFullCommit(t, p, chainID, 50, 50)
   136  	checkLatestFullCommit(t, p, chainID, 99, 50)
   137  
   138  	// now, query the cache for a higher value
   139  	checkLatestFullCommit(t, p2, chainID, 99, 90)
   140  	checkLatestFullCommit(t, cp, chainID, 99, 90)
   141  }