github.com/KYVENetwork/cometbft/v38@v38.0.3/mempool/cache_test.go (about) 1 package mempool 2 3 import ( 4 "crypto/rand" 5 "crypto/sha256" 6 "fmt" 7 "testing" 8 9 "github.com/KYVENetwork/cometbft/v38/abci/example/kvstore" 10 abci "github.com/KYVENetwork/cometbft/v38/abci/types" 11 "github.com/KYVENetwork/cometbft/v38/proxy" 12 "github.com/KYVENetwork/cometbft/v38/types" 13 "github.com/stretchr/testify/require" 14 ) 15 16 func TestCacheRemove(t *testing.T) { 17 cache := NewLRUTxCache(100) 18 numTxs := 10 19 20 txs := make([][]byte, numTxs) 21 for i := 0; i < numTxs; i++ { 22 // probability of collision is 2**-256 23 txBytes := make([]byte, 32) 24 _, err := rand.Read(txBytes) 25 require.NoError(t, err) 26 27 txs[i] = txBytes 28 cache.Push(txBytes) 29 30 // make sure its added to both the linked list and the map 31 require.Equal(t, i+1, len(cache.cacheMap)) 32 require.Equal(t, i+1, cache.list.Len()) 33 } 34 35 for i := 0; i < numTxs; i++ { 36 cache.Remove(txs[i]) 37 // make sure its removed from both the map and the linked list 38 require.Equal(t, numTxs-(i+1), len(cache.cacheMap)) 39 require.Equal(t, numTxs-(i+1), cache.list.Len()) 40 } 41 } 42 43 func TestCacheAfterUpdate(t *testing.T) { 44 app := kvstore.NewInMemoryApplication() 45 cc := proxy.NewLocalClientCreator(app) 46 mp, cleanup := newMempoolWithApp(cc) 47 defer cleanup() 48 49 // reAddIndices & txsInCache can have elements > numTxsToCreate 50 // also assumes max index is 255 for convenience 51 // txs in cache also checks order of elements 52 tests := []struct { 53 numTxsToCreate int 54 updateIndices []int 55 reAddIndices []int 56 txsInCache []int 57 }{ 58 {1, []int{}, []int{1}, []int{1, 0}}, // adding new txs works 59 {2, []int{1}, []int{}, []int{1, 0}}, // update doesn't remove tx from cache 60 {2, []int{2}, []int{}, []int{2, 1, 0}}, // update adds new tx to cache 61 {2, []int{1}, []int{1}, []int{1, 0}}, // re-adding after update doesn't make dupe 62 } 63 for tcIndex, tc := range tests { 64 for i := 0; i < tc.numTxsToCreate; i++ { 65 tx := kvstore.NewTx(fmt.Sprintf("%d", i), "value") 66 err := mp.CheckTx(tx, func(resp *abci.ResponseCheckTx) { 67 require.False(t, resp.IsErr()) 68 }, TxInfo{}) 69 require.NoError(t, err) 70 } 71 72 updateTxs := []types.Tx{} 73 for _, v := range tc.updateIndices { 74 tx := kvstore.NewTx(fmt.Sprintf("%d", v), "value") 75 updateTxs = append(updateTxs, tx) 76 } 77 err := mp.Update(int64(tcIndex), updateTxs, abciResponses(len(updateTxs), abci.CodeTypeOK), nil, nil) 78 require.NoError(t, err) 79 80 for _, v := range tc.reAddIndices { 81 tx := kvstore.NewTx(fmt.Sprintf("%d", v), "value") 82 _ = mp.CheckTx(tx, func(resp *abci.ResponseCheckTx) { 83 require.False(t, resp.IsErr()) 84 }, TxInfo{}) 85 } 86 87 cache := mp.cache.(*LRUTxCache) 88 node := cache.GetList().Front() 89 counter := 0 90 for node != nil { 91 require.NotEqual(t, len(tc.txsInCache), counter, 92 "cache larger than expected on testcase %d", tcIndex) 93 94 nodeVal := node.Value.(types.TxKey) 95 expTx := kvstore.NewTx(fmt.Sprintf("%d", tc.txsInCache[len(tc.txsInCache)-counter-1]), "value") 96 expectedBz := sha256.Sum256(expTx) 97 // Reference for reading the errors: 98 // >>> sha256('\x00').hexdigest() 99 // '6e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d' 100 // >>> sha256('\x01').hexdigest() 101 // '4bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459a' 102 // >>> sha256('\x02').hexdigest() 103 // 'dbc1b4c900ffe48d575b5da5c638040125f65db0fe3e24494b76ea986457d986' 104 105 require.EqualValues(t, expectedBz, nodeVal, "Equality failed on index %d, tc %d", counter, tcIndex) 106 counter++ 107 node = node.Next() 108 } 109 require.Equal(t, len(tc.txsInCache), counter, 110 "cache smaller than expected on testcase %d", tcIndex) 111 mp.Flush() 112 } 113 }