Commit 7ccb26bc authored by refcell.eth's avatar refcell.eth Committed by GitHub

feat(op-challenger): Split Preimage Uploader Wiring (#9023)

* feat(op-challenger): large preimage uploader

* feat(op-challenger): split preimage wiring
parent 247225b3
...@@ -4,6 +4,7 @@ import ( ...@@ -4,6 +4,7 @@ import (
"context" "context"
"fmt" "fmt"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/preimages"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/responder" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/responder"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types"
gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types" gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types"
...@@ -80,7 +81,11 @@ func NewGamePlayer( ...@@ -80,7 +81,11 @@ func NewGamePlayer(
return nil, fmt.Errorf("failed to create trace accessor: %w", err) return nil, fmt.Errorf("failed to create trace accessor: %w", err)
} }
responder, err := responder.NewFaultResponder(logger, txMgr, loader) direct := preimages.NewDirectPreimageUploader(logger, txMgr, loader)
large := preimages.NewLargePreimageUploader(logger, txMgr, loader)
uploader := preimages.NewSplitPreimageUploader(direct, large)
responder, err := responder.NewFaultResponder(logger, txMgr, loader, uploader)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to create the responder: %w", err) return nil, fmt.Errorf("failed to create the responder: %w", err)
} }
......
...@@ -37,12 +37,12 @@ type FaultResponder struct { ...@@ -37,12 +37,12 @@ type FaultResponder struct {
} }
// NewFaultResponder returns a new [FaultResponder]. // NewFaultResponder returns a new [FaultResponder].
func NewFaultResponder(logger log.Logger, txMgr txmgr.TxManager, contract GameContract) (*FaultResponder, error) { func NewFaultResponder(logger log.Logger, txMgr txmgr.TxManager, contract GameContract, uploader preimages.PreimageUploader) (*FaultResponder, error) {
return &FaultResponder{ return &FaultResponder{
log: logger, log: logger,
txMgr: txMgr, txMgr: txMgr,
contract: contract, contract: contract,
uploader: preimages.NewDirectPreimageUploader(logger, txMgr, contract), uploader: uploader,
}, nil }, nil
} }
......
...@@ -19,14 +19,15 @@ import ( ...@@ -19,14 +19,15 @@ import (
) )
var ( var (
mockSendError = errors.New("mock send error") mockPreimageUploadErr = errors.New("mock preimage upload error")
mockCallError = errors.New("mock call error") mockSendError = errors.New("mock send error")
mockCallError = errors.New("mock call error")
) )
// TestCallResolve tests the [Responder.CallResolve]. // TestCallResolve tests the [Responder.CallResolve].
func TestCallResolve(t *testing.T) { func TestCallResolve(t *testing.T) {
t.Run("SendFails", func(t *testing.T) { t.Run("SendFails", func(t *testing.T) {
responder, _, contract := newTestFaultResponder(t) responder, _, contract, _ := newTestFaultResponder(t)
contract.callFails = true contract.callFails = true
status, err := responder.CallResolve(context.Background()) status, err := responder.CallResolve(context.Background())
require.ErrorIs(t, err, mockCallError) require.ErrorIs(t, err, mockCallError)
...@@ -35,7 +36,7 @@ func TestCallResolve(t *testing.T) { ...@@ -35,7 +36,7 @@ func TestCallResolve(t *testing.T) {
}) })
t.Run("Success", func(t *testing.T) { t.Run("Success", func(t *testing.T) {
responder, _, contract := newTestFaultResponder(t) responder, _, contract, _ := newTestFaultResponder(t)
status, err := responder.CallResolve(context.Background()) status, err := responder.CallResolve(context.Background())
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, gameTypes.GameStatusInProgress, status) require.Equal(t, gameTypes.GameStatusInProgress, status)
...@@ -46,7 +47,7 @@ func TestCallResolve(t *testing.T) { ...@@ -46,7 +47,7 @@ func TestCallResolve(t *testing.T) {
// TestResolve tests the [Responder.Resolve] method. // TestResolve tests the [Responder.Resolve] method.
func TestResolve(t *testing.T) { func TestResolve(t *testing.T) {
t.Run("SendFails", func(t *testing.T) { t.Run("SendFails", func(t *testing.T) {
responder, mockTxMgr, _ := newTestFaultResponder(t) responder, mockTxMgr, _, _ := newTestFaultResponder(t)
mockTxMgr.sendFails = true mockTxMgr.sendFails = true
err := responder.Resolve(context.Background()) err := responder.Resolve(context.Background())
require.ErrorIs(t, err, mockSendError) require.ErrorIs(t, err, mockSendError)
...@@ -54,7 +55,7 @@ func TestResolve(t *testing.T) { ...@@ -54,7 +55,7 @@ func TestResolve(t *testing.T) {
}) })
t.Run("Success", func(t *testing.T) { t.Run("Success", func(t *testing.T) {
responder, mockTxMgr, _ := newTestFaultResponder(t) responder, mockTxMgr, _, _ := newTestFaultResponder(t)
err := responder.Resolve(context.Background()) err := responder.Resolve(context.Background())
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, 1, mockTxMgr.sends) require.Equal(t, 1, mockTxMgr.sends)
...@@ -63,7 +64,7 @@ func TestResolve(t *testing.T) { ...@@ -63,7 +64,7 @@ func TestResolve(t *testing.T) {
func TestCallResolveClaim(t *testing.T) { func TestCallResolveClaim(t *testing.T) {
t.Run("SendFails", func(t *testing.T) { t.Run("SendFails", func(t *testing.T) {
responder, _, contract := newTestFaultResponder(t) responder, _, contract, _ := newTestFaultResponder(t)
contract.callFails = true contract.callFails = true
err := responder.CallResolveClaim(context.Background(), 0) err := responder.CallResolveClaim(context.Background(), 0)
require.ErrorIs(t, err, mockCallError) require.ErrorIs(t, err, mockCallError)
...@@ -71,7 +72,7 @@ func TestCallResolveClaim(t *testing.T) { ...@@ -71,7 +72,7 @@ func TestCallResolveClaim(t *testing.T) {
}) })
t.Run("Success", func(t *testing.T) { t.Run("Success", func(t *testing.T) {
responder, _, contract := newTestFaultResponder(t) responder, _, contract, _ := newTestFaultResponder(t)
err := responder.CallResolveClaim(context.Background(), 0) err := responder.CallResolveClaim(context.Background(), 0)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, 1, contract.calls) require.Equal(t, 1, contract.calls)
...@@ -80,7 +81,7 @@ func TestCallResolveClaim(t *testing.T) { ...@@ -80,7 +81,7 @@ func TestCallResolveClaim(t *testing.T) {
func TestResolveClaim(t *testing.T) { func TestResolveClaim(t *testing.T) {
t.Run("SendFails", func(t *testing.T) { t.Run("SendFails", func(t *testing.T) {
responder, mockTxMgr, _ := newTestFaultResponder(t) responder, mockTxMgr, _, _ := newTestFaultResponder(t)
mockTxMgr.sendFails = true mockTxMgr.sendFails = true
err := responder.ResolveClaim(context.Background(), 0) err := responder.ResolveClaim(context.Background(), 0)
require.ErrorIs(t, err, mockSendError) require.ErrorIs(t, err, mockSendError)
...@@ -88,7 +89,7 @@ func TestResolveClaim(t *testing.T) { ...@@ -88,7 +89,7 @@ func TestResolveClaim(t *testing.T) {
}) })
t.Run("Success", func(t *testing.T) { t.Run("Success", func(t *testing.T) {
responder, mockTxMgr, _ := newTestFaultResponder(t) responder, mockTxMgr, _, _ := newTestFaultResponder(t)
err := responder.ResolveClaim(context.Background(), 0) err := responder.ResolveClaim(context.Background(), 0)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, 1, mockTxMgr.sends) require.Equal(t, 1, mockTxMgr.sends)
...@@ -98,7 +99,7 @@ func TestResolveClaim(t *testing.T) { ...@@ -98,7 +99,7 @@ func TestResolveClaim(t *testing.T) {
// TestRespond tests the [Responder.Respond] method. // TestRespond tests the [Responder.Respond] method.
func TestPerformAction(t *testing.T) { func TestPerformAction(t *testing.T) {
t.Run("send fails", func(t *testing.T) { t.Run("send fails", func(t *testing.T) {
responder, mockTxMgr, _ := newTestFaultResponder(t) responder, mockTxMgr, _, _ := newTestFaultResponder(t)
mockTxMgr.sendFails = true mockTxMgr.sendFails = true
err := responder.PerformAction(context.Background(), types.Action{ err := responder.PerformAction(context.Background(), types.Action{
Type: types.ActionTypeMove, Type: types.ActionTypeMove,
...@@ -111,7 +112,7 @@ func TestPerformAction(t *testing.T) { ...@@ -111,7 +112,7 @@ func TestPerformAction(t *testing.T) {
}) })
t.Run("sends response", func(t *testing.T) { t.Run("sends response", func(t *testing.T) {
responder, mockTxMgr, _ := newTestFaultResponder(t) responder, mockTxMgr, _, _ := newTestFaultResponder(t)
err := responder.PerformAction(context.Background(), types.Action{ err := responder.PerformAction(context.Background(), types.Action{
Type: types.ActionTypeMove, Type: types.ActionTypeMove,
ParentIdx: 123, ParentIdx: 123,
...@@ -123,7 +124,7 @@ func TestPerformAction(t *testing.T) { ...@@ -123,7 +124,7 @@ func TestPerformAction(t *testing.T) {
}) })
t.Run("attack", func(t *testing.T) { t.Run("attack", func(t *testing.T) {
responder, mockTxMgr, contract := newTestFaultResponder(t) responder, mockTxMgr, contract, _ := newTestFaultResponder(t)
action := types.Action{ action := types.Action{
Type: types.ActionTypeMove, Type: types.ActionTypeMove,
ParentIdx: 123, ParentIdx: 123,
...@@ -139,7 +140,7 @@ func TestPerformAction(t *testing.T) { ...@@ -139,7 +140,7 @@ func TestPerformAction(t *testing.T) {
}) })
t.Run("defend", func(t *testing.T) { t.Run("defend", func(t *testing.T) {
responder, mockTxMgr, contract := newTestFaultResponder(t) responder, mockTxMgr, contract, _ := newTestFaultResponder(t)
action := types.Action{ action := types.Action{
Type: types.ActionTypeMove, Type: types.ActionTypeMove,
ParentIdx: 123, ParentIdx: 123,
...@@ -155,7 +156,7 @@ func TestPerformAction(t *testing.T) { ...@@ -155,7 +156,7 @@ func TestPerformAction(t *testing.T) {
}) })
t.Run("step", func(t *testing.T) { t.Run("step", func(t *testing.T) {
responder, mockTxMgr, contract := newTestFaultResponder(t) responder, mockTxMgr, contract, _ := newTestFaultResponder(t)
action := types.Action{ action := types.Action{
Type: types.ActionTypeStep, Type: types.ActionTypeStep,
ParentIdx: 123, ParentIdx: 123,
...@@ -172,7 +173,7 @@ func TestPerformAction(t *testing.T) { ...@@ -172,7 +173,7 @@ func TestPerformAction(t *testing.T) {
}) })
t.Run("stepWithOracleData", func(t *testing.T) { t.Run("stepWithOracleData", func(t *testing.T) {
responder, mockTxMgr, contract := newTestFaultResponder(t) responder, mockTxMgr, contract, uploader := newTestFaultResponder(t)
action := types.Action{ action := types.Action{
Type: types.ActionTypeStep, Type: types.ActionTypeStep,
ParentIdx: 123, ParentIdx: 123,
...@@ -186,23 +187,54 @@ func TestPerformAction(t *testing.T) { ...@@ -186,23 +187,54 @@ func TestPerformAction(t *testing.T) {
err := responder.PerformAction(context.Background(), action) err := responder.PerformAction(context.Background(), action)
require.NoError(t, err) require.NoError(t, err)
require.Len(t, mockTxMgr.sent, 2) require.Len(t, mockTxMgr.sent, 1)
require.EqualValues(t, action.OracleData, contract.updateOracleArgs) require.Nil(t, contract.updateOracleArgs) // mock uploader returns nil
require.EqualValues(t, action.ParentIdx, contract.updateOracleClaimIdx) require.Equal(t, ([]byte)("step"), mockTxMgr.sent[0].TxData)
require.EqualValues(t, []interface{}{uint64(action.ParentIdx), action.IsAttack, action.PreState, action.ProofData}, contract.stepArgs) require.Equal(t, 1, uploader.updates)
// Important that the oracle is updated first })
require.Equal(t, ([]byte)("updateOracle"), mockTxMgr.sent[0].TxData)
require.Equal(t, ([]byte)("step"), mockTxMgr.sent[1].TxData) t.Run("stepWithOracleDataAndUploadFails", func(t *testing.T) {
responder, mockTxMgr, contract, uploader := newTestFaultResponder(t)
uploader.uploadFails = true
action := types.Action{
Type: types.ActionTypeStep,
ParentIdx: 123,
IsAttack: true,
PreState: []byte{1, 2, 3},
ProofData: []byte{4, 5, 6},
OracleData: &types.PreimageOracleData{
IsLocal: true,
},
}
err := responder.PerformAction(context.Background(), action)
require.ErrorIs(t, err, mockPreimageUploadErr)
require.Len(t, mockTxMgr.sent, 0)
require.Nil(t, contract.updateOracleArgs) // mock uploader returns nil
require.Equal(t, 1, uploader.updates)
}) })
} }
func newTestFaultResponder(t *testing.T) (*FaultResponder, *mockTxManager, *mockContract) { func newTestFaultResponder(t *testing.T) (*FaultResponder, *mockTxManager, *mockContract, *mockPreimageUploader) {
log := testlog.Logger(t, log.LvlError) log := testlog.Logger(t, log.LvlError)
mockTxMgr := &mockTxManager{} mockTxMgr := &mockTxManager{}
contract := &mockContract{} contract := &mockContract{}
responder, err := NewFaultResponder(log, mockTxMgr, contract) uploader := &mockPreimageUploader{}
responder, err := NewFaultResponder(log, mockTxMgr, contract, uploader)
require.NoError(t, err) require.NoError(t, err)
return responder, mockTxMgr, contract return responder, mockTxMgr, contract, uploader
}
type mockPreimageUploader struct {
updates int
uploadFails bool
}
func (m *mockPreimageUploader) UploadPreimage(ctx context.Context, parent uint64, data *types.PreimageOracleData) error {
m.updates++
if m.uploadFails {
return mockPreimageUploadErr
}
return nil
} }
type mockTxManager struct { type mockTxManager struct {
......
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