Commit 542f5ad9 authored by Axel Kingsley's avatar Axel Kingsley Committed by GitHub

Add Routine to run Maintenence (#11552)

parent 58793000
...@@ -101,11 +101,14 @@ func (su *SupervisorBackend) Start(ctx context.Context) error { ...@@ -101,11 +101,14 @@ func (su *SupervisorBackend) Start(ctx context.Context) error {
if !su.started.CompareAndSwap(false, true) { if !su.started.CompareAndSwap(false, true) {
return errors.New("already started") return errors.New("already started")
} }
// start chain monitors
for _, monitor := range su.chainMonitors { for _, monitor := range su.chainMonitors {
if err := monitor.Start(); err != nil { if err := monitor.Start(); err != nil {
return fmt.Errorf("failed to start chain monitor: %w", err) return fmt.Errorf("failed to start chain monitor: %w", err)
} }
} }
// start db maintenance loop
su.db.StartCrossHeadMaintenance(ctx)
return nil return nil
} }
......
package db package db
import ( import (
"context"
"errors" "errors"
"fmt" "fmt"
"io" "io"
"time"
"github.com/ethereum-optimism/optimism/op-service/eth" "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/entrydb"
...@@ -11,6 +13,7 @@ import ( ...@@ -11,6 +13,7 @@ import (
"github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db/logs" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/db/logs"
backendTypes "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/types" backendTypes "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/types"
"github.com/ethereum-optimism/optimism/op-supervisor/supervisor/types" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/types"
"github.com/ethereum/go-ethereum/log"
) )
var ( var (
...@@ -59,6 +62,35 @@ func (db *ChainsDB) Resume() error { ...@@ -59,6 +62,35 @@ func (db *ChainsDB) Resume() error {
return nil 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 // UpdateCrossSafeHeads updates the cross-heads of all chains
// this is an example of how to use the SafetyChecker to update the cross-heads // this is an example of how to use the SafetyChecker to update the cross-heads
func (db *ChainsDB) UpdateCrossSafeHeads() error { func (db *ChainsDB) UpdateCrossSafeHeads() error {
...@@ -117,7 +149,7 @@ func (db *ChainsDB) UpdateCrossHeadsForChain(chainID types.ChainID, checker Safe ...@@ -117,7 +149,7 @@ func (db *ChainsDB) UpdateCrossHeadsForChain(chainID types.ChainID, checker Safe
return nil 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 // 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. // the safety of each log entry in the database, and the cross-head associated with it.
func (db *ChainsDB) UpdateCrossHeads(checker SafetyChecker) error { func (db *ChainsDB) UpdateCrossHeads(checker SafetyChecker) error {
......
...@@ -213,6 +213,10 @@ func (s *stubChecker) LocalHeadForChain(chainID types.ChainID) entrydb.EntryIdx ...@@ -213,6 +213,10 @@ func (s *stubChecker) LocalHeadForChain(chainID types.ChainID) entrydb.EntryIdx
return s.localHeadForChain return s.localHeadForChain
} }
func (s *stubChecker) Name() string {
return "stubChecker"
}
func (s *stubChecker) CrossHeadForChain(chainID types.ChainID) entrydb.EntryIdx { func (s *stubChecker) CrossHeadForChain(chainID types.ChainID) entrydb.EntryIdx {
return s.crossHeadForChain return s.crossHeadForChain
} }
......
...@@ -20,6 +20,7 @@ type SafetyChecker interface { ...@@ -20,6 +20,7 @@ type SafetyChecker interface {
CrossHeadForChain(chainID types.ChainID) entrydb.EntryIdx CrossHeadForChain(chainID types.ChainID) entrydb.EntryIdx
Check(chain types.ChainID, blockNum uint64, logIdx uint32, logHash backendTypes.TruncatedHash) bool Check(chain types.ChainID, blockNum uint64, logIdx uint32, logHash backendTypes.TruncatedHash) bool
Update(chain types.ChainID, index entrydb.EntryIdx) heads.OperationFn 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 // unsafeChecker is a SafetyChecker that uses the unsafe head as the view into the database
...@@ -57,6 +58,19 @@ func NewSafetyChecker(t string, chainsDB ChainsDB) SafetyChecker { ...@@ -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 // LocalHeadForChain returns the local head for the given chain
// based on the type of SafetyChecker // based on the type of SafetyChecker
func (c *unsafeChecker) LocalHeadForChain(chainID types.ChainID) entrydb.EntryIdx { func (c *unsafeChecker) LocalHeadForChain(chainID types.ChainID) entrydb.EntryIdx {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment