Commit ebdae429 authored by Axel Kingsley's avatar Axel Kingsley Committed by GitHub

Implement CheckMessages API (#11621)

* Implement CheckMessages API

* Make AtLeastAsSafeAs a function of SafetyLevel

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

---------
Co-authored-by: default avatarprotolambda <proto@protolambda.com>
parent 0da4ba1c
...@@ -159,6 +159,24 @@ func (su *SupervisorBackend) CheckMessage(identifier types.Identifier, payloadHa ...@@ -159,6 +159,24 @@ func (su *SupervisorBackend) CheckMessage(identifier types.Identifier, payloadHa
return safest, nil 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 // 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 // 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 // this is decided by finding the last log in the block and
......
...@@ -43,6 +43,10 @@ func (m *MockBackend) CheckMessage(identifier types.Identifier, payloadHash comm ...@@ -43,6 +43,10 @@ func (m *MockBackend) CheckMessage(identifier types.Identifier, payloadHash comm
return types.CrossUnsafe, nil 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) { func (m *MockBackend) CheckBlock(chainID *hexutil.U256, blockHash common.Hash, blockNumber hexutil.Uint64) (types.SafetyLevel, error) {
return types.CrossUnsafe, nil return types.CrossUnsafe, nil
} }
......
...@@ -16,6 +16,7 @@ type AdminBackend interface { ...@@ -16,6 +16,7 @@ type AdminBackend interface {
type QueryBackend interface { type QueryBackend interface {
CheckMessage(identifier types.Identifier, payloadHash common.Hash) (types.SafetyLevel, error) 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) CheckBlock(chainID *hexutil.U256, blockHash common.Hash, blockNumber hexutil.Uint64) (types.SafetyLevel, error)
} }
...@@ -34,6 +35,14 @@ func (q *QueryFrontend) CheckMessage(identifier types.Identifier, payloadHash co ...@@ -34,6 +35,14 @@ func (q *QueryFrontend) CheckMessage(identifier types.Identifier, payloadHash co
return q.Supervisor.CheckMessage(identifier, payloadHash) 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. // 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) { func (q *QueryFrontend) CheckBlock(chainID *hexutil.U256, blockHash common.Hash, blockNumber hexutil.Uint64) (types.SafetyLevel, error) {
return q.Supervisor.CheckBlock(chainID, blockHash, blockNumber) return q.Supervisor.CheckBlock(chainID, blockHash, blockNumber)
......
...@@ -13,6 +13,11 @@ import ( ...@@ -13,6 +13,11 @@ import (
"github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/common/hexutil"
) )
type Message struct {
Identifier Identifier `json:"identifier"`
PayloadHash common.Hash `json:"payloadHash"`
}
type Identifier struct { type Identifier struct {
Origin common.Address Origin common.Address
BlockNumber uint64 BlockNumber uint64
...@@ -83,6 +88,22 @@ func (lvl *SafetyLevel) UnmarshalText(text []byte) error { ...@@ -83,6 +88,22 @@ func (lvl *SafetyLevel) UnmarshalText(text []byte) error {
return nil 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 ( const (
CrossFinalized SafetyLevel = "cross-finalized" CrossFinalized SafetyLevel = "cross-finalized"
Finalized SafetyLevel = "finalized" Finalized SafetyLevel = "finalized"
......
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