Skip to content

Commit

Permalink
Add Routine to run Maintenence (#11552)
Browse files Browse the repository at this point in the history
  • Loading branch information
axelKingsley authored Aug 22, 2024
1 parent 5879300 commit 542f5ad
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 1 deletion.
3 changes: 3 additions & 0 deletions op-supervisor/supervisor/backend/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,11 +101,14 @@ func (su *SupervisorBackend) Start(ctx context.Context) error {
if !su.started.CompareAndSwap(false, true) {
return errors.New("already started")
}
// start chain monitors
for _, monitor := range su.chainMonitors {
if err := monitor.Start(); err != nil {
return fmt.Errorf("failed to start chain monitor: %w", err)
}
}
// start db maintenance loop
su.db.StartCrossHeadMaintenance(ctx)
return nil
}

Expand Down
34 changes: 33 additions & 1 deletion op-supervisor/supervisor/backend/db/db.go
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
package db

import (
"context"
"errors"
"fmt"
"io"
"time"

"github.com/ethereum-optimism/optimism/op-service/eth"
"github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db/entrydb"
"github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db/heads"
"github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db/logs"
backendTypes "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/types"
"github.com/ethereum-optimism/optimism/op-supervisor/supervisor/types"
"github.com/ethereum/go-ethereum/log"
)

var (
Expand Down Expand Up @@ -59,6 +62,35 @@ func (db *ChainsDB) Resume() error {
return nil
}

// StartCrossHeadMaintenance starts a background process that maintains the cross-heads of the chains
// for now it does not prevent multiple instances of this process from running
func (db *ChainsDB) StartCrossHeadMaintenance(ctx context.Context) {
go func() {
// create three safety checkers, one for each safety level
unsafeChecker := NewSafetyChecker(Unsafe, *db)
safeChecker := NewSafetyChecker(Safe, *db)
finalizedChecker := NewSafetyChecker(Finalized, *db)
// run the maintenance loop every 10 seconds for now
ticker := time.NewTicker(time.Second * 10)
for {
select {
case <-ctx.Done():
return
case <-ticker.C:
for _, checker := range []SafetyChecker{
unsafeChecker,
safeChecker,
finalizedChecker} {
if err := db.UpdateCrossHeads(checker); err != nil {
log.Error("failed to update cross-heads", "err", err, "safety", checker.Name())
// we should consider exiting if an error is encountered, as the path forward is unclear
}
}
}
}
}()
}

// UpdateCrossSafeHeads updates the cross-heads of all chains
// this is an example of how to use the SafetyChecker to update the cross-heads
func (db *ChainsDB) UpdateCrossSafeHeads() error {
Expand Down Expand Up @@ -117,7 +149,7 @@ func (db *ChainsDB) UpdateCrossHeadsForChain(chainID types.ChainID, checker Safe
return nil
}

// UpdateCrossSafeHeads updates the cross-heads of all chains
// UpdateCrossHeads updates the cross-heads of all chains
// based on the provided SafetyChecker. The SafetyChecker is used to determine
// the safety of each log entry in the database, and the cross-head associated with it.
func (db *ChainsDB) UpdateCrossHeads(checker SafetyChecker) error {
Expand Down
4 changes: 4 additions & 0 deletions op-supervisor/supervisor/backend/db/db_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,10 @@ func (s *stubChecker) LocalHeadForChain(chainID types.ChainID) entrydb.EntryIdx
return s.localHeadForChain
}

func (s *stubChecker) Name() string {
return "stubChecker"
}

func (s *stubChecker) CrossHeadForChain(chainID types.ChainID) entrydb.EntryIdx {
return s.crossHeadForChain
}
Expand Down
14 changes: 14 additions & 0 deletions op-supervisor/supervisor/backend/db/safety_checkers.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ type SafetyChecker interface {
CrossHeadForChain(chainID types.ChainID) entrydb.EntryIdx
Check(chain types.ChainID, blockNum uint64, logIdx uint32, logHash backendTypes.TruncatedHash) bool
Update(chain types.ChainID, index entrydb.EntryIdx) heads.OperationFn
Name() string
}

// unsafeChecker is a SafetyChecker that uses the unsafe head as the view into the database
Expand Down Expand Up @@ -57,6 +58,19 @@ func NewSafetyChecker(t string, chainsDB ChainsDB) SafetyChecker {
}
}

// Name returns the safety checker type, using the same strings as the constants used in construction
func (c *unsafeChecker) Name() string {
return Unsafe
}

func (c *safeChecker) Name() string {
return Safe
}

func (c *finalizedChecker) Name() string {
return Finalized
}

// LocalHeadForChain returns the local head for the given chain
// based on the type of SafetyChecker
func (c *unsafeChecker) LocalHeadForChain(chainID types.ChainID) entrydb.EntryIdx {
Expand Down

0 comments on commit 542f5ad

Please sign in to comment.