Commit 78d2cdd0 authored by Adrian Sutton's avatar Adrian Sutton Committed by GitHub

op-challenger: Trigger verification of completed preimages (#9097)

parent 8c8fa159
...@@ -9,19 +9,25 @@ import ( ...@@ -9,19 +9,25 @@ import (
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
) )
type Verifier interface {
Verify(ctx context.Context, oracle types.LargePreimageOracle, preimage types.LargePreimageMetaData)
}
type LargePreimageScheduler struct { type LargePreimageScheduler struct {
log log.Logger log log.Logger
ch chan common.Hash ch chan common.Hash
oracles []types.LargePreimageOracle oracles []types.LargePreimageOracle
cancel func() verifier Verifier
wg sync.WaitGroup cancel func()
wg sync.WaitGroup
} }
func NewLargePreimageScheduler(logger log.Logger, oracles []types.LargePreimageOracle) *LargePreimageScheduler { func NewLargePreimageScheduler(logger log.Logger, oracles []types.LargePreimageOracle, verifier Verifier) *LargePreimageScheduler {
return &LargePreimageScheduler{ return &LargePreimageScheduler{
log: logger, log: logger,
ch: make(chan common.Hash, 1), ch: make(chan common.Hash, 1),
oracles: oracles, oracles: oracles,
verifier: verifier,
} }
} }
...@@ -71,6 +77,11 @@ func (s *LargePreimageScheduler) verifyPreimages(ctx context.Context, blockHash ...@@ -71,6 +77,11 @@ func (s *LargePreimageScheduler) verifyPreimages(ctx context.Context, blockHash
} }
func (s *LargePreimageScheduler) verifyOraclePreimages(ctx context.Context, oracle types.LargePreimageOracle, blockHash common.Hash) error { func (s *LargePreimageScheduler) verifyOraclePreimages(ctx context.Context, oracle types.LargePreimageOracle, blockHash common.Hash) error {
_, err := oracle.GetActivePreimages(ctx, blockHash) preimages, err := oracle.GetActivePreimages(ctx, blockHash)
for _, preimage := range preimages {
if preimage.ShouldVerify() {
s.verifier.Verify(ctx, oracle, preimage)
}
}
return err return err
} }
...@@ -2,6 +2,7 @@ package keccak ...@@ -2,6 +2,7 @@ package keccak
import ( import (
"context" "context"
"math/big"
"sync" "sync"
"testing" "testing"
"time" "time"
...@@ -16,8 +17,32 @@ import ( ...@@ -16,8 +17,32 @@ import (
func TestScheduleNextCheck(t *testing.T) { func TestScheduleNextCheck(t *testing.T) {
ctx := context.Background() ctx := context.Background()
logger := testlog.Logger(t, log.LvlInfo) logger := testlog.Logger(t, log.LvlInfo)
oracle := &stubOracle{} preimage1 := types.LargePreimageMetaData{ // Incomplete so won't be verified
scheduler := NewLargePreimageScheduler(logger, []types.LargePreimageOracle{oracle}) LargePreimageIdent: types.LargePreimageIdent{
Claimant: common.Address{0xab},
UUID: big.NewInt(111),
},
}
preimage2 := types.LargePreimageMetaData{ // Already countered so won't be verified
LargePreimageIdent: types.LargePreimageIdent{
Claimant: common.Address{0xab},
UUID: big.NewInt(222),
},
Timestamp: 1234,
Countered: true,
}
preimage3 := types.LargePreimageMetaData{
LargePreimageIdent: types.LargePreimageIdent{
Claimant: common.Address{0xdd},
UUID: big.NewInt(333),
},
Timestamp: 1234,
}
oracle := &stubOracle{
images: []types.LargePreimageMetaData{preimage1, preimage2, preimage3},
}
verifier := &stubVerifier{}
scheduler := NewLargePreimageScheduler(logger, []types.LargePreimageOracle{oracle}, verifier)
scheduler.Start(ctx) scheduler.Start(ctx)
defer scheduler.Close() defer scheduler.Close()
err := scheduler.Schedule(common.Hash{0xaa}, 3) err := scheduler.Schedule(common.Hash{0xaa}, 3)
...@@ -25,12 +50,18 @@ func TestScheduleNextCheck(t *testing.T) { ...@@ -25,12 +50,18 @@ func TestScheduleNextCheck(t *testing.T) {
require.Eventually(t, func() bool { require.Eventually(t, func() bool {
return oracle.GetPreimagesCount() == 1 return oracle.GetPreimagesCount() == 1
}, 10*time.Second, 10*time.Millisecond) }, 10*time.Second, 10*time.Millisecond)
require.Eventually(t, func() bool {
verified := verifier.Verified()
t.Logf("Verified preimages: %v", verified)
return len(verified) == 1 && verified[0] == preimage3
}, 10*time.Second, 10*time.Millisecond, "Did not verify preimage")
} }
type stubOracle struct { type stubOracle struct {
m sync.Mutex m sync.Mutex
addr common.Address addr common.Address
getPreimagesCount int getPreimagesCount int
images []types.LargePreimageMetaData
} }
func (s *stubOracle) Addr() common.Address { func (s *stubOracle) Addr() common.Address {
...@@ -41,7 +72,7 @@ func (s *stubOracle) GetActivePreimages(_ context.Context, _ common.Hash) ([]typ ...@@ -41,7 +72,7 @@ func (s *stubOracle) GetActivePreimages(_ context.Context, _ common.Hash) ([]typ
s.m.Lock() s.m.Lock()
defer s.m.Unlock() defer s.m.Unlock()
s.getPreimagesCount++ s.getPreimagesCount++
return nil, nil return s.images, nil
} }
func (s *stubOracle) GetPreimagesCount() int { func (s *stubOracle) GetPreimagesCount() int {
...@@ -49,3 +80,22 @@ func (s *stubOracle) GetPreimagesCount() int { ...@@ -49,3 +80,22 @@ func (s *stubOracle) GetPreimagesCount() int {
defer s.m.Unlock() defer s.m.Unlock()
return s.getPreimagesCount return s.getPreimagesCount
} }
type stubVerifier struct {
m sync.Mutex
verified []types.LargePreimageMetaData
}
func (s *stubVerifier) Verify(_ context.Context, _ types.LargePreimageOracle, image types.LargePreimageMetaData) {
s.m.Lock()
defer s.m.Unlock()
s.verified = append(s.verified, image)
}
func (s *stubVerifier) Verified() []types.LargePreimageMetaData {
s.m.Lock()
defer s.m.Unlock()
v := make([]types.LargePreimageMetaData, len(s.verified))
copy(v, s.verified)
return v
}
package keccak
import (
"context"
"github.com/ethereum-optimism/optimism/op-challenger/game/types"
"github.com/ethereum/go-ethereum/log"
)
type PreimageVerifier struct {
log log.Logger
}
func NewPreimageVerifier(logger log.Logger) *PreimageVerifier {
return &PreimageVerifier{
log: logger,
}
}
func (v *PreimageVerifier) Verify(ctx context.Context, oracle types.LargePreimageOracle, preimage types.LargePreimageMetaData) {
// No verification currently performed.
}
...@@ -225,7 +225,8 @@ func (s *Service) initScheduler(cfg *config.Config) error { ...@@ -225,7 +225,8 @@ func (s *Service) initScheduler(cfg *config.Config) error {
} }
func (s *Service) initLargePreimages() error { func (s *Service) initLargePreimages() error {
s.preimages = keccak.NewLargePreimageScheduler(s.logger, s.registry.Oracles()) verifier := keccak.NewPreimageVerifier(s.logger)
s.preimages = keccak.NewLargePreimageScheduler(s.logger, s.registry.Oracles(), verifier)
return nil return nil
} }
......
...@@ -62,6 +62,12 @@ type LargePreimageMetaData struct { ...@@ -62,6 +62,12 @@ type LargePreimageMetaData struct {
Countered bool Countered bool
} }
// ShouldVerify returns true if the preimage upload is complete and has not yet been countered.
// Note that the challenge period for the preimage may have expired but the image not yet been finalized.
func (m LargePreimageMetaData) ShouldVerify() bool {
return m.Timestamp > 0 && !m.Countered
}
type LargePreimageOracle interface { type LargePreimageOracle interface {
Addr() common.Address Addr() common.Address
GetActivePreimages(ctx context.Context, blockHash common.Hash) ([]LargePreimageMetaData, error) GetActivePreimages(ctx context.Context, blockHash common.Hash) ([]LargePreimageMetaData, error)
......
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