github.com/koko1123/flow-go-1@v0.29.6/storage/badger/dkg_state_test.go (about) 1 package badger_test 2 3 import ( 4 "errors" 5 "math/rand" 6 "testing" 7 "time" 8 9 "github.com/dgraph-io/badger/v3" 10 "github.com/stretchr/testify/assert" 11 "github.com/stretchr/testify/require" 12 13 "github.com/koko1123/flow-go-1/model/flow" 14 "github.com/koko1123/flow-go-1/module/metrics" 15 "github.com/koko1123/flow-go-1/storage" 16 bstorage "github.com/koko1123/flow-go-1/storage/badger" 17 "github.com/koko1123/flow-go-1/utils/unittest" 18 ) 19 20 func TestDKGState_DKGStarted(t *testing.T) { 21 unittest.RunWithTypedBadgerDB(t, bstorage.InitSecret, func(db *badger.DB) { 22 metrics := metrics.NewNoopCollector() 23 store, err := bstorage.NewDKGState(metrics, db) 24 require.NoError(t, err) 25 26 epochCounter := rand.Uint64() 27 28 // check dkg-started flag for non-existent epoch 29 t.Run("DKGStarted should default to false", func(t *testing.T) { 30 started, err := store.GetDKGStarted(rand.Uint64()) 31 assert.NoError(t, err) 32 assert.False(t, started) 33 }) 34 35 // store dkg-started flag for epoch 36 t.Run("should be able to set DKGStarted", func(t *testing.T) { 37 err = store.SetDKGStarted(epochCounter) 38 assert.NoError(t, err) 39 }) 40 41 // retrieve flag for epoch 42 t.Run("should be able to read DKGStarted", func(t *testing.T) { 43 started, err := store.GetDKGStarted(epochCounter) 44 assert.NoError(t, err) 45 assert.True(t, started) 46 }) 47 }) 48 } 49 50 func TestDKGState_BeaconKeys(t *testing.T) { 51 unittest.RunWithTypedBadgerDB(t, bstorage.InitSecret, func(db *badger.DB) { 52 metrics := metrics.NewNoopCollector() 53 store, err := bstorage.NewDKGState(metrics, db) 54 require.NoError(t, err) 55 56 rand.Seed(time.Now().UnixNano()) 57 epochCounter := rand.Uint64() 58 59 // attempt to get a non-existent key 60 t.Run("should error if retrieving non-existent key", func(t *testing.T) { 61 _, err = store.RetrieveMyBeaconPrivateKey(epochCounter) 62 assert.True(t, errors.Is(err, storage.ErrNotFound)) 63 }) 64 65 // attempt to store a nil key should fail (use DKGState.SetEndState(flow.DKGEndStateNoKey) 66 t.Run("should fail to store a nil key instead)", func(t *testing.T) { 67 err = store.InsertMyBeaconPrivateKey(epochCounter, nil) 68 assert.Error(t, err) 69 }) 70 71 // store a key in db 72 expected := unittest.RandomBeaconPriv() 73 t.Run("should be able to store and read a key", func(t *testing.T) { 74 err = store.InsertMyBeaconPrivateKey(epochCounter, expected) 75 require.NoError(t, err) 76 }) 77 78 // retrieve the key by epoch counter 79 t.Run("should be able to retrieve stored key", func(t *testing.T) { 80 actual, err := store.RetrieveMyBeaconPrivateKey(epochCounter) 81 require.NoError(t, err) 82 assert.Equal(t, expected, actual) 83 }) 84 85 // test storing same key 86 t.Run("should fail to store a key twice", func(t *testing.T) { 87 err = store.InsertMyBeaconPrivateKey(epochCounter, expected) 88 require.True(t, errors.Is(err, storage.ErrAlreadyExists)) 89 }) 90 }) 91 } 92 93 func TestDKGState_EndState(t *testing.T) { 94 unittest.RunWithTypedBadgerDB(t, bstorage.InitSecret, func(db *badger.DB) { 95 metrics := metrics.NewNoopCollector() 96 store, err := bstorage.NewDKGState(metrics, db) 97 require.NoError(t, err) 98 99 rand.Seed(time.Now().UnixNano()) 100 epochCounter := rand.Uint64() 101 endState := flow.DKGEndStateNoKey 102 103 t.Run("should be able to store an end state", func(t *testing.T) { 104 err = store.SetDKGEndState(epochCounter, endState) 105 require.NoError(t, err) 106 }) 107 108 t.Run("should be able to read an end state", func(t *testing.T) { 109 readEndState, err := store.GetDKGEndState(epochCounter) 110 require.NoError(t, err) 111 assert.Equal(t, endState, readEndState) 112 }) 113 }) 114 } 115 116 func TestSafeBeaconPrivateKeys(t *testing.T) { 117 unittest.RunWithTypedBadgerDB(t, bstorage.InitSecret, func(db *badger.DB) { 118 metrics := metrics.NewNoopCollector() 119 dkgState, err := bstorage.NewDKGState(metrics, db) 120 require.NoError(t, err) 121 safeKeys := bstorage.NewSafeBeaconPrivateKeys(dkgState) 122 123 t.Run("non-existent key - should error", func(t *testing.T) { 124 epochCounter := rand.Uint64() 125 key, safe, err := safeKeys.RetrieveMyBeaconPrivateKey(epochCounter) 126 assert.Nil(t, key) 127 assert.False(t, safe) 128 assert.Error(t, err) 129 }) 130 131 t.Run("existent key, non-existent dkg end state - should error", func(t *testing.T) { 132 epochCounter := rand.Uint64() 133 134 // store a key 135 expected := unittest.RandomBeaconPriv().PrivateKey 136 err := dkgState.InsertMyBeaconPrivateKey(epochCounter, expected) 137 assert.NoError(t, err) 138 139 key, safe, err := safeKeys.RetrieveMyBeaconPrivateKey(epochCounter) 140 assert.Nil(t, key) 141 assert.False(t, safe) 142 assert.Error(t, err) 143 }) 144 145 t.Run("existent key, unsuccessful dkg - not safe", func(t *testing.T) { 146 epochCounter := rand.Uint64() 147 148 // store a key 149 expected := unittest.RandomBeaconPriv().PrivateKey 150 err := dkgState.InsertMyBeaconPrivateKey(epochCounter, expected) 151 assert.NoError(t, err) 152 // mark dkg unsuccessful 153 err = dkgState.SetDKGEndState(epochCounter, flow.DKGEndStateInconsistentKey) 154 assert.NoError(t, err) 155 156 key, safe, err := safeKeys.RetrieveMyBeaconPrivateKey(epochCounter) 157 assert.Nil(t, key) 158 assert.False(t, safe) 159 assert.NoError(t, err) 160 }) 161 162 t.Run("existent key, successful dkg - safe", func(t *testing.T) { 163 epochCounter := rand.Uint64() 164 165 // store a key 166 expected := unittest.RandomBeaconPriv().PrivateKey 167 err := dkgState.InsertMyBeaconPrivateKey(epochCounter, expected) 168 assert.NoError(t, err) 169 // mark dkg successful 170 err = dkgState.SetDKGEndState(epochCounter, flow.DKGEndStateSuccess) 171 assert.NoError(t, err) 172 173 key, safe, err := safeKeys.RetrieveMyBeaconPrivateKey(epochCounter) 174 assert.NotNil(t, key) 175 assert.True(t, expected.Equals(key)) 176 assert.True(t, safe) 177 assert.NoError(t, err) 178 }) 179 }) 180 } 181 182 // TestSecretDBRequirement tests that the DKGState constructor will return an 183 // error if instantiated using a database not marked with the correct type. 184 func TestSecretDBRequirement(t *testing.T) { 185 unittest.RunWithBadgerDB(t, func(db *badger.DB) { 186 metrics := metrics.NewNoopCollector() 187 _, err := bstorage.NewDKGState(metrics, db) 188 require.Error(t, err) 189 }) 190 }