github.com/prysmaticlabs/prysm@v1.4.4/beacon-chain/state/stategen/setter_test.go (about) 1 package stategen 2 3 import ( 4 "context" 5 "testing" 6 7 testDB "github.com/prysmaticlabs/prysm/beacon-chain/db/testing" 8 "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1/wrapper" 9 "github.com/prysmaticlabs/prysm/shared/params" 10 "github.com/prysmaticlabs/prysm/shared/testutil" 11 "github.com/prysmaticlabs/prysm/shared/testutil/assert" 12 "github.com/prysmaticlabs/prysm/shared/testutil/require" 13 logTest "github.com/sirupsen/logrus/hooks/test" 14 ) 15 16 func TestSaveState_HotStateCanBeSaved(t *testing.T) { 17 ctx := context.Background() 18 beaconDB := testDB.SetupDB(t) 19 20 service := New(beaconDB) 21 service.slotsPerArchivedPoint = 1 22 beaconState, _ := testutil.DeterministicGenesisState(t, 32) 23 // This goes to hot section, verify it can save on epoch boundary. 24 require.NoError(t, beaconState.SetSlot(params.BeaconConfig().SlotsPerEpoch)) 25 26 r := [32]byte{'a'} 27 require.NoError(t, service.SaveState(ctx, r, beaconState)) 28 29 // Should save both state and state summary. 30 _, ok, err := service.epochBoundaryStateCache.getByRoot(r) 31 require.NoError(t, err) 32 assert.Equal(t, true, ok, "Should have saved the state") 33 assert.Equal(t, true, service.beaconDB.HasStateSummary(ctx, r), "Should have saved the state summary") 34 } 35 36 func TestSaveState_HotStateCached(t *testing.T) { 37 hook := logTest.NewGlobal() 38 ctx := context.Background() 39 beaconDB := testDB.SetupDB(t) 40 41 service := New(beaconDB) 42 service.slotsPerArchivedPoint = 1 43 beaconState, _ := testutil.DeterministicGenesisState(t, 32) 44 require.NoError(t, beaconState.SetSlot(params.BeaconConfig().SlotsPerEpoch)) 45 46 // Cache the state prior. 47 r := [32]byte{'a'} 48 service.hotStateCache.put(r, beaconState) 49 require.NoError(t, service.SaveState(ctx, r, beaconState)) 50 51 // Should not save the state and state summary. 52 assert.Equal(t, false, service.beaconDB.HasState(ctx, r), "Should not have saved the state") 53 assert.Equal(t, false, service.beaconDB.HasStateSummary(ctx, r), "Should have saved the state summary") 54 require.LogsDoNotContain(t, hook, "Saved full state on epoch boundary") 55 } 56 57 func TestState_ForceCheckpoint_SavesStateToDatabase(t *testing.T) { 58 ctx := context.Background() 59 beaconDB := testDB.SetupDB(t) 60 61 svc := New(beaconDB) 62 beaconState, _ := testutil.DeterministicGenesisState(t, 32) 63 require.NoError(t, beaconState.SetSlot(params.BeaconConfig().SlotsPerEpoch)) 64 65 r := [32]byte{'a'} 66 svc.hotStateCache.put(r, beaconState) 67 68 require.Equal(t, false, beaconDB.HasState(ctx, r), "Database has state stored already") 69 assert.NoError(t, svc.ForceCheckpoint(ctx, r[:])) 70 assert.Equal(t, true, beaconDB.HasState(ctx, r), "Did not save checkpoint to database") 71 72 // Should not panic with genesis finalized root. 73 assert.NoError(t, svc.ForceCheckpoint(ctx, params.BeaconConfig().ZeroHash[:])) 74 } 75 76 func TestSaveState_Alreadyhas(t *testing.T) { 77 hook := logTest.NewGlobal() 78 ctx := context.Background() 79 beaconDB := testDB.SetupDB(t) 80 service := New(beaconDB) 81 82 beaconState, _ := testutil.DeterministicGenesisState(t, 32) 83 require.NoError(t, beaconState.SetSlot(params.BeaconConfig().SlotsPerEpoch)) 84 r := [32]byte{'A'} 85 86 // Pre cache the hot state. 87 service.hotStateCache.put(r, beaconState) 88 require.NoError(t, service.saveStateByRoot(ctx, r, beaconState)) 89 90 // Should not save the state and state summary. 91 assert.Equal(t, false, service.beaconDB.HasState(ctx, r), "Should not have saved the state") 92 assert.Equal(t, false, service.beaconDB.HasStateSummary(ctx, r), "Should have saved the state summary") 93 require.LogsDoNotContain(t, hook, "Saved full state on epoch boundary") 94 } 95 96 func TestSaveState_CanSaveOnEpochBoundary(t *testing.T) { 97 ctx := context.Background() 98 beaconDB := testDB.SetupDB(t) 99 service := New(beaconDB) 100 101 beaconState, _ := testutil.DeterministicGenesisState(t, 32) 102 require.NoError(t, beaconState.SetSlot(params.BeaconConfig().SlotsPerEpoch)) 103 r := [32]byte{'A'} 104 105 require.NoError(t, service.saveStateByRoot(ctx, r, beaconState)) 106 107 // Should save both state and state summary. 108 _, ok, err := service.epochBoundaryStateCache.getByRoot(r) 109 require.NoError(t, err) 110 require.Equal(t, true, ok, "Did not save epoch boundary state") 111 assert.Equal(t, true, service.beaconDB.HasStateSummary(ctx, r), "Should have saved the state summary") 112 // Should have not been saved in DB. 113 require.Equal(t, false, beaconDB.HasState(ctx, r)) 114 } 115 116 func TestSaveState_NoSaveNotEpochBoundary(t *testing.T) { 117 hook := logTest.NewGlobal() 118 ctx := context.Background() 119 beaconDB := testDB.SetupDB(t) 120 service := New(beaconDB) 121 122 beaconState, _ := testutil.DeterministicGenesisState(t, 32) 123 require.NoError(t, beaconState.SetSlot(params.BeaconConfig().SlotsPerEpoch-1)) 124 r := [32]byte{'A'} 125 b := testutil.NewBeaconBlock() 126 require.NoError(t, beaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(b))) 127 gRoot, err := b.Block.HashTreeRoot() 128 require.NoError(t, err) 129 require.NoError(t, beaconDB.SaveGenesisBlockRoot(ctx, gRoot)) 130 require.NoError(t, service.SaveState(ctx, r, beaconState)) 131 132 // Should only save state summary. 133 assert.Equal(t, false, service.beaconDB.HasState(ctx, r), "Should not have saved the state") 134 assert.Equal(t, true, service.beaconDB.HasStateSummary(ctx, r), "Should have saved the state summary") 135 require.LogsDoNotContain(t, hook, "Saved full state on epoch boundary") 136 // Should have not been saved in DB. 137 require.Equal(t, false, beaconDB.HasState(ctx, r)) 138 } 139 140 func TestSaveState_CanSaveHotStateToDB(t *testing.T) { 141 hook := logTest.NewGlobal() 142 ctx := context.Background() 143 beaconDB := testDB.SetupDB(t) 144 service := New(beaconDB) 145 service.EnableSaveHotStateToDB(ctx) 146 beaconState, _ := testutil.DeterministicGenesisState(t, 32) 147 require.NoError(t, beaconState.SetSlot(defaultHotStateDBInterval)) 148 149 r := [32]byte{'A'} 150 require.NoError(t, service.saveStateByRoot(ctx, r, beaconState)) 151 152 require.LogsContain(t, hook, "Saving hot state to DB") 153 // Should have saved in DB. 154 require.Equal(t, true, beaconDB.HasState(ctx, r)) 155 } 156 157 func TestEnableSaveHotStateToDB_Enabled(t *testing.T) { 158 hook := logTest.NewGlobal() 159 ctx := context.Background() 160 beaconDB := testDB.SetupDB(t) 161 service := New(beaconDB) 162 163 service.EnableSaveHotStateToDB(ctx) 164 require.LogsContain(t, hook, "Entering mode to save hot states in DB") 165 require.Equal(t, true, service.saveHotStateDB.enabled) 166 } 167 168 func TestEnableSaveHotStateToDB_AlreadyEnabled(t *testing.T) { 169 hook := logTest.NewGlobal() 170 ctx := context.Background() 171 beaconDB := testDB.SetupDB(t) 172 service := New(beaconDB) 173 service.saveHotStateDB.enabled = true 174 service.EnableSaveHotStateToDB(ctx) 175 require.LogsDoNotContain(t, hook, "Entering mode to save hot states in DB") 176 require.Equal(t, true, service.saveHotStateDB.enabled) 177 } 178 179 func TestEnableSaveHotStateToDB_Disabled(t *testing.T) { 180 hook := logTest.NewGlobal() 181 ctx := context.Background() 182 beaconDB := testDB.SetupDB(t) 183 service := New(beaconDB) 184 service.saveHotStateDB.enabled = true 185 b := testutil.NewBeaconBlock() 186 require.NoError(t, beaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(b))) 187 r, err := b.Block.HashTreeRoot() 188 require.NoError(t, err) 189 service.saveHotStateDB.savedStateRoots = [][32]byte{r} 190 require.NoError(t, service.DisableSaveHotStateToDB(ctx)) 191 require.LogsContain(t, hook, "Exiting mode to save hot states in DB") 192 require.Equal(t, false, service.saveHotStateDB.enabled) 193 require.Equal(t, 0, len(service.saveHotStateDB.savedStateRoots)) 194 } 195 196 func TestEnableSaveHotStateToDB_AlreadyDisabled(t *testing.T) { 197 hook := logTest.NewGlobal() 198 ctx := context.Background() 199 beaconDB := testDB.SetupDB(t) 200 service := New(beaconDB) 201 require.NoError(t, service.DisableSaveHotStateToDB(ctx)) 202 require.LogsDoNotContain(t, hook, "Exiting mode to save hot states in DB") 203 require.Equal(t, false, service.saveHotStateDB.enabled) 204 }