github.com/ari-anchor/sei-tendermint@v0.0.0-20230519144642-dc826b7b56bb/light/store/db/db_test.go (about) 1 package db 2 3 import ( 4 "context" 5 "sync" 6 "testing" 7 "time" 8 9 "github.com/stretchr/testify/assert" 10 "github.com/stretchr/testify/require" 11 dbm "github.com/tendermint/tm-db" 12 13 "github.com/ari-anchor/sei-tendermint/crypto" 14 "github.com/ari-anchor/sei-tendermint/internal/test/factory" 15 tmrand "github.com/ari-anchor/sei-tendermint/libs/rand" 16 "github.com/ari-anchor/sei-tendermint/types" 17 "github.com/ari-anchor/sei-tendermint/version" 18 ) 19 20 func TestLast_FirstLightBlockHeight(t *testing.T) { 21 dbStore := New(dbm.NewMemDB()) 22 ctx, cancel := context.WithCancel(context.Background()) 23 defer cancel() 24 25 // Empty store 26 height, err := dbStore.LastLightBlockHeight() 27 require.NoError(t, err) 28 assert.EqualValues(t, -1, height) 29 30 height, err = dbStore.FirstLightBlockHeight() 31 require.NoError(t, err) 32 assert.EqualValues(t, -1, height) 33 34 // 1 key 35 err = dbStore.SaveLightBlock(randLightBlock(ctx, t, int64(1))) 36 require.NoError(t, err) 37 38 height, err = dbStore.LastLightBlockHeight() 39 require.NoError(t, err) 40 assert.EqualValues(t, 1, height) 41 42 height, err = dbStore.FirstLightBlockHeight() 43 require.NoError(t, err) 44 assert.EqualValues(t, 1, height) 45 } 46 47 func Test_SaveLightBlock(t *testing.T) { 48 dbStore := New(dbm.NewMemDB()) 49 ctx, cancel := context.WithCancel(context.Background()) 50 defer cancel() 51 52 // Empty store 53 h, err := dbStore.LightBlock(1) 54 require.Error(t, err) 55 assert.Nil(t, h) 56 57 // 1 key 58 err = dbStore.SaveLightBlock(randLightBlock(ctx, t, 1)) 59 require.NoError(t, err) 60 61 size := dbStore.Size() 62 assert.Equal(t, uint16(1), size) 63 t.Log(size) 64 65 h, err = dbStore.LightBlock(1) 66 require.NoError(t, err) 67 assert.NotNil(t, h) 68 69 // Empty store 70 err = dbStore.DeleteLightBlock(1) 71 require.NoError(t, err) 72 73 h, err = dbStore.LightBlock(1) 74 require.Error(t, err) 75 assert.Nil(t, h) 76 77 } 78 79 func Test_LightBlockBefore(t *testing.T) { 80 dbStore := New(dbm.NewMemDB()) 81 ctx, cancel := context.WithCancel(context.Background()) 82 defer cancel() 83 84 assert.Panics(t, func() { 85 _, _ = dbStore.LightBlockBefore(0) 86 _, _ = dbStore.LightBlockBefore(100) 87 }) 88 89 err := dbStore.SaveLightBlock(randLightBlock(ctx, t, int64(2))) 90 require.NoError(t, err) 91 92 h, err := dbStore.LightBlockBefore(3) 93 require.NoError(t, err) 94 if assert.NotNil(t, h) { 95 assert.EqualValues(t, 2, h.Height) 96 } 97 98 _, err = dbStore.LightBlockBefore(2) 99 require.Error(t, err) 100 } 101 102 func Test_Prune(t *testing.T) { 103 dbStore := New(dbm.NewMemDB()) 104 ctx, cancel := context.WithCancel(context.Background()) 105 defer cancel() 106 107 // Empty store 108 assert.EqualValues(t, 0, dbStore.Size()) 109 err := dbStore.Prune(0) 110 require.NoError(t, err) 111 112 // One header 113 err = dbStore.SaveLightBlock(randLightBlock(ctx, t, 2)) 114 require.NoError(t, err) 115 116 assert.EqualValues(t, 1, dbStore.Size()) 117 118 err = dbStore.Prune(1) 119 require.NoError(t, err) 120 assert.EqualValues(t, 1, dbStore.Size()) 121 122 err = dbStore.Prune(0) 123 require.NoError(t, err) 124 assert.EqualValues(t, 0, dbStore.Size()) 125 126 // Multiple headers 127 for i := 1; i <= 10; i++ { 128 err = dbStore.SaveLightBlock(randLightBlock(ctx, t, int64(i))) 129 require.NoError(t, err) 130 } 131 132 err = dbStore.Prune(11) 133 require.NoError(t, err) 134 assert.EqualValues(t, 10, dbStore.Size()) 135 136 err = dbStore.Prune(7) 137 require.NoError(t, err) 138 assert.EqualValues(t, 7, dbStore.Size()) 139 } 140 141 func Test_Concurrency(t *testing.T) { 142 dbStore := New(dbm.NewMemDB()) 143 144 ctx, cancel := context.WithCancel(context.Background()) 145 defer cancel() 146 147 var wg sync.WaitGroup 148 for i := 1; i <= 100; i++ { 149 wg.Add(1) 150 go func(i int64) { 151 defer wg.Done() 152 153 err := dbStore.SaveLightBlock(randLightBlock(ctx, t, i)) 154 require.NoError(t, err) 155 156 _, err = dbStore.LightBlock(i) 157 if err != nil { 158 t.Log(err) 159 } 160 161 if i > 2 { 162 _, err = dbStore.LightBlockBefore(i - 1) 163 if err != nil { 164 t.Log(err) 165 } 166 } 167 168 _, err = dbStore.LastLightBlockHeight() 169 if err != nil { 170 t.Log(err) 171 } 172 _, err = dbStore.FirstLightBlockHeight() 173 if err != nil { 174 t.Log(err) 175 } 176 177 err = dbStore.Prune(3) 178 if err != nil { 179 t.Log(err) 180 } 181 _ = dbStore.Size() 182 183 if i > 2 && i%2 == 0 { 184 err = dbStore.DeleteLightBlock(i - 1) 185 if err != nil { 186 t.Log(err) 187 } 188 } 189 190 }(int64(i)) 191 } 192 193 wg.Wait() 194 } 195 196 func randLightBlock(ctx context.Context, t *testing.T, height int64) *types.LightBlock { 197 t.Helper() 198 vals, _ := factory.ValidatorSet(ctx, t, 2, 1) 199 return &types.LightBlock{ 200 SignedHeader: &types.SignedHeader{ 201 Header: &types.Header{ 202 Version: version.Consensus{Block: version.BlockProtocol, App: 0}, 203 ChainID: tmrand.Str(12), 204 Height: height, 205 Time: time.Now(), 206 LastBlockID: types.BlockID{}, 207 LastCommitHash: crypto.CRandBytes(crypto.HashSize), 208 DataHash: crypto.CRandBytes(crypto.HashSize), 209 ValidatorsHash: crypto.CRandBytes(crypto.HashSize), 210 NextValidatorsHash: crypto.CRandBytes(crypto.HashSize), 211 ConsensusHash: crypto.CRandBytes(crypto.HashSize), 212 AppHash: crypto.CRandBytes(crypto.HashSize), 213 LastResultsHash: crypto.CRandBytes(crypto.HashSize), 214 EvidenceHash: crypto.CRandBytes(crypto.HashSize), 215 ProposerAddress: crypto.CRandBytes(crypto.AddressSize), 216 }, 217 Commit: &types.Commit{}, 218 }, 219 ValidatorSet: vals, 220 } 221 }