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  }