Skip to content

Commit

Permalink
Implement CheckMessages API (#11621)
Browse files Browse the repository at this point in the history
* Implement CheckMessages API

* Make AtLeastAsSafeAs a function of SafetyLevel

* op-supervisor: checkMessages bundle message identifier and payload-hash

---------

Co-authored-by: protolambda <proto@protolambda.com>
  • Loading branch information
axelKingsley and protolambda authored Aug 27, 2024
1 parent 0da4ba1 commit ebdae42
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 0 deletions.
18 changes: 18 additions & 0 deletions op-supervisor/supervisor/backend/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,24 @@ func (su *SupervisorBackend) CheckMessage(identifier types.Identifier, payloadHa
return safest, nil
}

func (su *SupervisorBackend) CheckMessages(
messages []types.Message,
minSafety types.SafetyLevel) error {
for _, msg := range messages {
safety, err := su.CheckMessage(msg.Identifier, msg.PayloadHash)
if err != nil {
return fmt.Errorf("failed to check message: %w", err)
}
if !safety.AtLeastAsSafe(minSafety) {
return fmt.Errorf("message %v (safety level: %v) does not meet the minimum safety %v",
msg.Identifier,
safety,
minSafety)
}
}
return nil
}

// CheckBlock checks if the block is safe according to the safety level
// The block is considered safe if all logs in the block are safe
// this is decided by finding the last log in the block and
Expand Down
4 changes: 4 additions & 0 deletions op-supervisor/supervisor/backend/mock.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ func (m *MockBackend) CheckMessage(identifier types.Identifier, payloadHash comm
return types.CrossUnsafe, nil
}

func (m *MockBackend) CheckMessages(messages []types.Message, minSafety types.SafetyLevel) error {
return nil
}

func (m *MockBackend) CheckBlock(chainID *hexutil.U256, blockHash common.Hash, blockNumber hexutil.Uint64) (types.SafetyLevel, error) {
return types.CrossUnsafe, nil
}
Expand Down
9 changes: 9 additions & 0 deletions op-supervisor/supervisor/frontend/frontend.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ type AdminBackend interface {

type QueryBackend interface {
CheckMessage(identifier types.Identifier, payloadHash common.Hash) (types.SafetyLevel, error)
CheckMessages(messages []types.Message, minSafety types.SafetyLevel) error
CheckBlock(chainID *hexutil.U256, blockHash common.Hash, blockNumber hexutil.Uint64) (types.SafetyLevel, error)
}

Expand All @@ -34,6 +35,14 @@ func (q *QueryFrontend) CheckMessage(identifier types.Identifier, payloadHash co
return q.Supervisor.CheckMessage(identifier, payloadHash)
}

// CheckMessage checks the safety-level of a collection of messages,
// and returns if the minimum safety-level is met for all messages.
func (q *QueryFrontend) CheckMessages(
messages []types.Message,
minSafety types.SafetyLevel) error {
return q.Supervisor.CheckMessages(messages, minSafety)
}

// CheckBlock checks the safety-level of an L2 block as a whole.
func (q *QueryFrontend) CheckBlock(chainID *hexutil.U256, blockHash common.Hash, blockNumber hexutil.Uint64) (types.SafetyLevel, error) {
return q.Supervisor.CheckBlock(chainID, blockHash, blockNumber)
Expand Down
21 changes: 21 additions & 0 deletions op-supervisor/supervisor/types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ import (
"github.com/ethereum/go-ethereum/common/hexutil"
)

type Message struct {
Identifier Identifier `json:"identifier"`
PayloadHash common.Hash `json:"payloadHash"`
}

type Identifier struct {
Origin common.Address
BlockNumber uint64
Expand Down Expand Up @@ -83,6 +88,22 @@ func (lvl *SafetyLevel) UnmarshalText(text []byte) error {
return nil
}

// AtLeastAsSafe returns true if the receiver is at least as safe as the other SafetyLevel.
func (lvl *SafetyLevel) AtLeastAsSafe(min SafetyLevel) bool {
switch min {
case Invalid:
return true
case Unsafe:
return *lvl != Invalid
case Safe:
return *lvl == Safe || *lvl == Finalized
case Finalized:
return *lvl == Finalized
default:
return false
}
}

const (
CrossFinalized SafetyLevel = "cross-finalized"
Finalized SafetyLevel = "finalized"
Expand Down

0 comments on commit ebdae42

Please sign in to comment.