diff --git a/beacon-chain/db/kv/state_diff_helpers.go b/beacon-chain/db/kv/state_diff_helpers.go index 71b58b54aa..5af47e71de 100644 --- a/beacon-chain/db/kv/state_diff_helpers.go +++ b/beacon-chain/db/kv/state_diff_helpers.go @@ -221,13 +221,15 @@ func (s *Store) getBaseAndDiffChain(offset uint64, slot primitives.Slot) (state. } var diffChainItems []diffItem + lastSeenAnchorSlot := baseAnchorSlot for i, exp := range exponents[1 : lvl+1] { span := math.PowerOf2(uint64(exp)) diffSlot := rel / span * span - if diffSlot == baseAnchorSlot { + if diffSlot == lastSeenAnchorSlot { continue } diffChainItems = append(diffChainItems, diffItem{level: i + 1, slot: diffSlot + offset}) + lastSeenAnchorSlot = diffSlot } baseSnapshot, err := s.getFullSnapshot(baseAnchorSlot) diff --git a/beacon-chain/db/kv/state_diff_test.go b/beacon-chain/db/kv/state_diff_test.go index 93ade0bb30..06d1ae5022 100644 --- a/beacon-chain/db/kv/state_diff_test.go +++ b/beacon-chain/db/kv/state_diff_test.go @@ -278,6 +278,46 @@ func TestStateDiff_SaveAndReadDiff(t *testing.T) { } } +func TestStateDiff_SaveAndReadDiff_WithRepetitiveAnchorSlots(t *testing.T) { + globalFlags := flags.GlobalFlags{ + StateDiffExponents: []int{20, 14, 10, 7, 5}, + } + flags.Init(&globalFlags) + + for v := range version.All() { + t.Run(version.String(v), func(t *testing.T) { + db := setupDB(t) + + err := setOffsetInDB(db, 0) + + st, _ := createState(t, 0, v) + require.NoError(t, err) + err = db.saveStateByDiff(context.Background(), st) + require.NoError(t, err) + + slot := primitives.Slot(math.PowerOf2(11)) + st, _ = createState(t, slot, v) + err = db.saveStateByDiff(context.Background(), st) + require.NoError(t, err) + + slot = primitives.Slot(math.PowerOf2(11) + math.PowerOf2(5)) + st, _ = createState(t, slot, v) + err = db.saveStateByDiff(context.Background(), st) + require.NoError(t, err) + + readSt, err := db.stateByDiff(context.Background(), slot) + require.NoError(t, err) + require.NotNil(t, readSt) + + stSSZ, err := st.MarshalSSZ() + require.NoError(t, err) + readStSSZ, err := readSt.MarshalSSZ() + require.NoError(t, err) + require.DeepSSZEqual(t, stSSZ, readStSSZ) + }) + } +} + func TestStateDiff_SaveAndReadDiff_MultipleLevels(t *testing.T) { setDefaultExponents() diff --git a/changelog/bastin_state-diff-anchor-slot-bug.md b/changelog/bastin_state-diff-anchor-slot-bug.md new file mode 100644 index 0000000000..87fad46eea --- /dev/null +++ b/changelog/bastin_state-diff-anchor-slot-bug.md @@ -0,0 +1,3 @@ +### Fixed + +- Fix state diff repetitive anchor slot bug. \ No newline at end of file