github.com/prysmaticlabs/prysm@v1.4.4/beacon-chain/db/kv/utils_test.go (about) 1 package kv 2 3 import ( 4 "context" 5 "crypto/rand" 6 "testing" 7 8 "github.com/prysmaticlabs/prysm/shared/bytesutil" 9 "github.com/prysmaticlabs/prysm/shared/testutil/assert" 10 "github.com/prysmaticlabs/prysm/shared/testutil/require" 11 bolt "go.etcd.io/bbolt" 12 ) 13 14 func Test_deleteValueForIndices(t *testing.T) { 15 db := setupDB(t) 16 blocks := make([]byte, 128) 17 _, err := rand.Read(blocks) 18 require.NoError(t, err) 19 tests := []struct { 20 name string 21 inputIndices map[string][]byte 22 root []byte 23 outputIndices map[string][]byte 24 wantedErr string 25 }{ 26 { 27 name: "empty input, no root", 28 inputIndices: map[string][]byte{}, 29 root: []byte{}, 30 outputIndices: map[string][]byte{}, 31 }, 32 { 33 name: "empty input, root does not exist", 34 inputIndices: map[string][]byte{}, 35 root: bytesutil.PadTo([]byte("not found"), 32), 36 outputIndices: map[string][]byte{}, 37 }, 38 { 39 name: "non empty input, root does not exist", 40 inputIndices: map[string][]byte{ 41 "blocks": bytesutil.PadTo([]byte{0xde, 0xad, 0xbe, 0xef}, 64), 42 }, 43 root: bytesutil.PadTo([]byte("not found"), 32), 44 outputIndices: map[string][]byte{ 45 "blocks": bytesutil.PadTo([]byte{0xde, 0xad, 0xbe, 0xef}, 64), 46 }, 47 }, 48 { 49 name: "removes value for a single bucket", 50 inputIndices: map[string][]byte{ 51 "blocks": {0xde, 0xad, 0xbe, 0xef}, 52 }, 53 root: []byte{0xde}, 54 outputIndices: map[string][]byte{ 55 "blocks": {0xad, 0xbe, 0xef}, 56 }, 57 }, 58 { 59 name: "removes multi-byte value for a single bucket (non-aligned)", 60 inputIndices: map[string][]byte{ 61 "blocks": {0xde, 0xad, 0xbe, 0xef}, 62 }, 63 root: []byte{0xad, 0xbe}, 64 outputIndices: map[string][]byte{ 65 "blocks": {0xde, 0xad, 0xbe, 0xef}, 66 }, 67 }, 68 { 69 name: "removes multi-byte value for a single bucket (non-aligned)", 70 inputIndices: map[string][]byte{ 71 "blocks": {0xde, 0xad, 0xbe, 0xef, 0xff, 0x01}, 72 }, 73 root: []byte{0xbe, 0xef}, 74 outputIndices: map[string][]byte{ 75 "blocks": {0xde, 0xad, 0xff, 0x01}, 76 }, 77 }, 78 { 79 name: "removes value from multiple buckets", 80 inputIndices: map[string][]byte{ 81 "blocks": {0xff, 0x32, 0x45, 0x25, 0xde, 0xad, 0xbe, 0xef, 0x24}, 82 "state": {0x01, 0x02, 0x03, 0x04}, 83 "check-point": {0xde, 0xad, 0xbe, 0xef}, 84 "powchain": {0xba, 0xad, 0xb0, 0x00, 0xde, 0xad, 0xbe, 0xef, 0xff}, 85 }, 86 root: []byte{0xde, 0xad, 0xbe, 0xef}, 87 outputIndices: map[string][]byte{ 88 "blocks": {0xff, 0x32, 0x45, 0x25, 0x24}, 89 "state": {0x01, 0x02, 0x03, 0x04}, 90 "check-point": nil, 91 "powchain": {0xba, 0xad, 0xb0, 0x00, 0xff}, 92 }, 93 }, 94 { 95 name: "root as subsequence of two values (preserve)", 96 inputIndices: map[string][]byte{ 97 "blocks": blocks, 98 }, 99 outputIndices: map[string][]byte{ 100 "blocks": blocks, 101 }, 102 root: blocks[48:80], 103 }, 104 { 105 name: "root as subsequence of two values (remove)", 106 inputIndices: map[string][]byte{ 107 "blocks": blocks, 108 }, 109 outputIndices: map[string][]byte{ 110 "blocks": append(blocks[0:64], blocks[96:]...), 111 }, 112 root: blocks[64:96], 113 }, 114 } 115 116 for _, tt := range tests { 117 t.Run(tt.name, func(t *testing.T) { 118 err := db.db.Update(func(tx *bolt.Tx) error { 119 for k, idx := range tt.inputIndices { 120 bkt := tx.Bucket([]byte(k)) 121 require.NoError(t, bkt.Put(idx, tt.inputIndices[k])) 122 } 123 err := deleteValueForIndices(context.Background(), tt.inputIndices, tt.root, tx) 124 if tt.wantedErr != "" { 125 assert.ErrorContains(t, tt.wantedErr, err) 126 return nil 127 } 128 assert.NoError(t, err) 129 // Check updated indices. 130 for k, idx := range tt.inputIndices { 131 bkt := tx.Bucket([]byte(k)) 132 valuesAtIndex := bkt.Get(idx) 133 assert.DeepEqual(t, tt.outputIndices[k], valuesAtIndex) 134 } 135 return nil 136 }) 137 require.NoError(t, err) 138 }) 139 } 140 }