github.com/badrootd/nibiru-cometbft@v0.37.5-0.20240307173500-2a75559eee9b/light/store/db/db_test.go (about)

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