@@ -66,25 +66,83 @@ func (db *DB) ReplaceInvalidatedBlock(replacementDerived eth.BlockRef, invalidat
6666func (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
0 commit comments