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