Skip to content

Commit 9580179

Browse files
authored
Refactor Derivation DB Reset Functions (#13874)
1 parent 57c7d16 commit 9580179

File tree

7 files changed

+104
-33
lines changed

7 files changed

+104
-33
lines changed

op-node/rollup/interop/managed/system.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,7 @@ const (
209209

210210
func (m *ManagedMode) Reset(ctx context.Context, unsafe, safe, finalized eth.BlockID) error {
211211
logger := m.log.New("unsafe", unsafe, "safe", safe, "finalized", finalized)
212+
logger.Debug("Received reset request", "unsafe", unsafe, "safe", safe, "finalized", finalized)
212213

213214
verify := func(ref eth.BlockID, name string) (eth.L2BlockRef, error) {
214215
result, err := m.l2.L2BlockRefByNumber(ctx, ref.Number)

op-supervisor/supervisor/backend/backend.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -567,3 +567,8 @@ func (su *SupervisorBackend) PullFinalizedL1() error {
567567
func (su *SupervisorBackend) SetConfDepthL1(depth uint64) {
568568
su.l1Accessor.SetConfDepth(depth)
569569
}
570+
571+
// Rewind rolls back the state of the supervisor for the given chain.
572+
func (su *SupervisorBackend) Rewind(chain eth.ChainID, block eth.BlockID) error {
573+
return su.chainDBs.Rewind(chain, block)
574+
}

op-supervisor/supervisor/backend/db/db.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ type LocalDerivedFromStorage interface {
6161
NextDerived(derived eth.BlockID) (next types.DerivedBlockSealPair, err error)
6262
PreviousDerivedFrom(derivedFrom eth.BlockID) (prevDerivedFrom types.BlockSeal, err error)
6363
PreviousDerived(derived eth.BlockID) (prevDerived types.BlockSeal, err error)
64+
RewindToL2(derived uint64) error
6465
}
6566

6667
var _ LocalDerivedFromStorage = (*fromda.DB)(nil)

op-supervisor/supervisor/backend/db/fromda/db.go

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -51,22 +51,6 @@ func NewFromEntryStore(logger log.Logger, m Metrics, store EntryStore) (*DB, err
5151
return db, nil
5252
}
5353

54-
// Rewind to the last entry that was derived from a L1 block with the given block number.
55-
func (db *DB) Rewind(derivedFrom uint64) error {
56-
db.rwLock.Lock()
57-
defer db.rwLock.Unlock()
58-
index, _, err := db.lastDerivedAt(derivedFrom)
59-
if err != nil {
60-
return fmt.Errorf("failed to find point to rewind to: %w", err)
61-
}
62-
err = db.store.Truncate(index)
63-
if err != nil {
64-
return err
65-
}
66-
db.m.RecordDBDerivedEntryCount(int64(index) + 1)
67-
return nil
68-
}
69-
7054
// First returns the first known values, alike to Latest.
7155
func (db *DB) First() (pair types.DerivedBlockSealPair, err error) {
7256
db.rwLock.RLock()

op-supervisor/supervisor/backend/db/fromda/db_test.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -679,17 +679,17 @@ func TestRewind(t *testing.T) {
679679
require.Equal(t, l2Block2, pair.Derived)
680680

681681
// Rewind to the future
682-
require.ErrorIs(t, db.Rewind(6), types.ErrFuture)
682+
require.ErrorIs(t, db.RewindToL1(6), types.ErrFuture)
683683

684684
// Rewind to the exact block we're at
685-
require.NoError(t, db.Rewind(l1Block5.Number))
685+
require.NoError(t, db.RewindToL1(l1Block5.Number))
686686
pair, err = db.Latest()
687687
require.NoError(t, err)
688688
require.Equal(t, l1Block5, pair.DerivedFrom)
689689
require.Equal(t, l2Block2, pair.Derived)
690690

691691
// Now rewind to L1 block 3 (inclusive).
692-
require.NoError(t, db.Rewind(l1Block3.Number))
692+
require.NoError(t, db.RewindToL1(l1Block3.Number))
693693

694694
// See if we find consistent data
695695
pair, err = db.Latest()
@@ -698,14 +698,14 @@ func TestRewind(t *testing.T) {
698698
require.Equal(t, l2Block1, pair.Derived)
699699

700700
// Rewind further to L1 block 1 (inclusive).
701-
require.NoError(t, db.Rewind(l1Block1.Number))
701+
require.NoError(t, db.RewindToL1(l1Block1.Number))
702702
pair, err = db.Latest()
703703
require.NoError(t, err)
704704
require.Equal(t, l1Block1, pair.DerivedFrom)
705705
require.Equal(t, l2Block1, pair.Derived)
706706

707707
// Rewind further to L1 block 0 (inclusive).
708-
require.NoError(t, db.Rewind(l1Block0.Number))
708+
require.NoError(t, db.RewindToL1(l1Block0.Number))
709709
pair, err = db.Latest()
710710
require.NoError(t, err)
711711
require.Equal(t, l1Block0, pair.DerivedFrom)

op-supervisor/supervisor/backend/db/fromda/update.go

Lines changed: 68 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -66,25 +66,83 @@ func (db *DB) ReplaceInvalidatedBlock(replacementDerived eth.BlockRef, invalidat
6666
func (db *DB) RewindAndInvalidate(invalidated types.DerivedBlockRefPair) error {
6767
db.rwLock.Lock()
6868
defer db.rwLock.Unlock()
69-
i, link, err := db.lookup(invalidated.DerivedFrom.Number, invalidated.Derived.Number)
69+
70+
invalidatedSeals := types.DerivedBlockSealPair{
71+
DerivedFrom: types.BlockSealFromRef(invalidated.DerivedFrom),
72+
Derived: types.BlockSealFromRef(invalidated.Derived),
73+
}
74+
if err := db.rewindLocked(invalidatedSeals, true); err != nil {
75+
return err
76+
}
77+
if err := db.addLink(invalidated.DerivedFrom, invalidated.Derived, invalidated.Derived.Hash); err != nil {
78+
return fmt.Errorf("failed to add invalidation entry %s: %w", invalidated, err)
79+
}
80+
return nil
81+
}
82+
83+
// Rewind rolls back the database to the target, including the target if the including flag is set.
84+
// it locks the DB and calls rewindLocked.
85+
func (db *DB) Rewind(target types.DerivedBlockSealPair, including bool) error {
86+
db.rwLock.Lock()
87+
defer db.rwLock.Unlock()
88+
return db.rewindLocked(target, including)
89+
}
90+
91+
// RewindToL2 rewinds to the first entry where the L2 block with the given number was derived.
92+
func (db *DB) RewindToL2(derived uint64) error {
93+
db.rwLock.Lock()
94+
defer db.rwLock.Unlock()
95+
_, link, err := db.firstDerivedFrom(derived)
96+
if err != nil {
97+
return fmt.Errorf("failed to find last derived-from %d: %w", derived, err)
98+
}
99+
return db.rewindLocked(types.DerivedBlockSealPair{
100+
DerivedFrom: link.derivedFrom,
101+
Derived: link.derived,
102+
}, false)
103+
}
104+
105+
// RewindToL1 rewinds to the last entry that was derived from a L1 block with the given block number.
106+
func (db *DB) RewindToL1(derivedFrom uint64) error {
107+
db.rwLock.Lock()
108+
defer db.rwLock.Unlock()
109+
_, link, err := db.lastDerivedAt(derivedFrom)
110+
if err != nil {
111+
return fmt.Errorf("failed to find last derived-from %d: %w", derivedFrom, err)
112+
}
113+
return db.rewindLocked(types.DerivedBlockSealPair{
114+
DerivedFrom: link.derivedFrom,
115+
Derived: link.derived,
116+
}, false)
117+
}
118+
119+
// rewindLocked performs the truncate operation to a specified block seal pair.
120+
// data beyond the specified block seal pair is truncated from the database.
121+
// if including is true, the block seal pair itself is removed as well.
122+
// Note: This function must be called with the rwLock held.
123+
// Callers are responsible for locking and unlocking the Database.
124+
func (db *DB) rewindLocked(t types.DerivedBlockSealPair, including bool) error {
125+
i, link, err := db.lookup(t.DerivedFrom.Number, t.Derived.Number)
70126
if err != nil {
71127
return err
72128
}
73-
if link.derivedFrom.Hash != invalidated.DerivedFrom.Hash {
129+
if link.derivedFrom.Hash != t.DerivedFrom.Hash {
74130
return fmt.Errorf("found derived-from %s, but expected %s: %w",
75-
link.derivedFrom, invalidated.DerivedFrom, types.ErrConflict)
131+
link.derivedFrom, t.DerivedFrom, types.ErrConflict)
76132
}
77-
if link.derived.Hash != invalidated.Derived.Hash {
133+
if link.derived.Hash != t.Derived.Hash {
78134
return fmt.Errorf("found derived %s, but expected %s: %w",
79-
link.derived, invalidated.Derived, types.ErrConflict)
135+
link.derived, t.Derived, types.ErrConflict)
80136
}
81-
if err := db.store.Truncate(i - 1); err != nil {
82-
return fmt.Errorf("failed to rewind upon block invalidation of %s: %w", invalidated, err)
137+
// adjust the target index to include the block seal pair itself if requested
138+
target := i
139+
if including {
140+
target = i - 1
83141
}
84-
db.m.RecordDBDerivedEntryCount(int64(i))
85-
if err := db.addLink(invalidated.DerivedFrom, invalidated.Derived, invalidated.Derived.Hash); err != nil {
86-
return fmt.Errorf("failed to add invalidation entry %s: %w", invalidated, err)
142+
if err := db.store.Truncate(target); err != nil {
143+
return fmt.Errorf("failed to rewind upon block invalidation of %s: %w", t, err)
87144
}
145+
db.m.RecordDBDerivedEntryCount(int64(target) + 1)
88146
return nil
89147
}
90148

op-supervisor/supervisor/backend/db/update.go

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,33 @@ func (db *ChainsDB) SealBlock(chain eth.ChainID, block eth.BlockRef) error {
4141
}
4242

4343
func (db *ChainsDB) Rewind(chain eth.ChainID, headBlock eth.BlockID) error {
44+
// Rewind the logDB
4445
logDB, ok := db.logDBs.Get(chain)
4546
if !ok {
4647
return fmt.Errorf("cannot Rewind: %w: %s", types.ErrUnknownChain, chain)
4748
}
48-
return logDB.Rewind(headBlock)
49+
if err := logDB.Rewind(headBlock); err != nil {
50+
return fmt.Errorf("failed to rewind to block %v: %w", headBlock, err)
51+
}
52+
53+
// Rewind the localDB
54+
localDB, ok := db.localDBs.Get(chain)
55+
if !ok {
56+
return fmt.Errorf("cannot Rewind (localDB not found): %w: %s", types.ErrUnknownChain, chain)
57+
}
58+
if err := localDB.RewindToL2(headBlock.Number); err != nil {
59+
return fmt.Errorf("failed to rewind localDB to block %v: %w", headBlock, err)
60+
}
61+
62+
// Rewind the crossDB
63+
crossDB, ok := db.crossDBs.Get(chain)
64+
if !ok {
65+
return fmt.Errorf("cannot Rewind (crossDB not found): %w: %s", types.ErrUnknownChain, chain)
66+
}
67+
if err := crossDB.RewindToL2(headBlock.Number); err != nil {
68+
return fmt.Errorf("failed to rewind crossDB to block %v: %w", headBlock, err)
69+
}
70+
return nil
4971
}
5072

5173
func (db *ChainsDB) UpdateLocalSafe(chain eth.ChainID, derivedFrom eth.BlockRef, lastDerived eth.BlockRef) {
@@ -57,7 +79,7 @@ func (db *ChainsDB) UpdateLocalSafe(chain eth.ChainID, derivedFrom eth.BlockRef,
5779
}
5880
logger.Debug("Updating local safe DB")
5981
if err := localDB.AddDerived(derivedFrom, lastDerived); err != nil {
60-
db.logger.Warn("Failed to update local safe")
82+
db.logger.Warn("Failed to update local safe", "err", err)
6183
db.emitter.Emit(superevents.LocalSafeOutOfSyncEvent{
6284
ChainID: chain,
6385
L1Ref: derivedFrom,

0 commit comments

Comments
 (0)