Commit 34cf435f authored by refcell.eth's avatar refcell.eth Committed by GitHub

fix(op-challenger): update split preimage uploader to query the preimage...

fix(op-challenger): update split preimage uploader to query the preimage oracle contract for the min large preimage size (#9204)
parent 06d66f12
...@@ -29,6 +29,7 @@ const ( ...@@ -29,6 +29,7 @@ const (
methodProposalBlocksLen = "proposalBlocksLen" methodProposalBlocksLen = "proposalBlocksLen"
methodProposalBlocks = "proposalBlocks" methodProposalBlocks = "proposalBlocks"
methodPreimagePartOk = "preimagePartOk" methodPreimagePartOk = "preimagePartOk"
methodMinProposalSize = "minProposalSize"
) )
var ( var (
...@@ -134,6 +135,15 @@ func abiEncodeStateMatrix(stateMatrix *matrix.StateMatrix) bindings.LibKeccakSta ...@@ -134,6 +135,15 @@ func abiEncodeStateMatrix(stateMatrix *matrix.StateMatrix) bindings.LibKeccakSta
return bindings.LibKeccakStateMatrix{State: *stateSlice} return bindings.LibKeccakStateMatrix{State: *stateSlice}
} }
// MinLargePreimageSize returns the minimum size of a large preimage.
func (c *PreimageOracleContract) MinLargePreimageSize(ctx context.Context) (uint64, error) {
result, err := c.multiCaller.SingleCall(ctx, batching.BlockLatest, c.contract.Call(methodMinProposalSize))
if err != nil {
return 0, fmt.Errorf("failed to fetch min lpp size bytes: %w", err)
}
return result.GetBigInt(0).Uint64(), nil
}
func (c *PreimageOracleContract) GetActivePreimages(ctx context.Context, blockHash common.Hash) ([]keccakTypes.LargePreimageMetaData, error) { func (c *PreimageOracleContract) GetActivePreimages(ctx context.Context, blockHash common.Hash) ([]keccakTypes.LargePreimageMetaData, error) {
block := batching.BlockByHash(blockHash) block := batching.BlockByHash(blockHash)
results, err := batching.ReadArray(ctx, c.multiCaller, block, c.contract.Call(methodProposalCount), func(i *big.Int) *batching.ContractCall { results, err := batching.ReadArray(ctx, c.multiCaller, block, c.contract.Call(methodProposalCount), func(i *big.Int) *batching.ContractCall {
......
...@@ -88,9 +88,13 @@ func NewGamePlayer( ...@@ -88,9 +88,13 @@ func NewGamePlayer(
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to load oracle: %w", err) return nil, fmt.Errorf("failed to load oracle: %w", err)
} }
minLargePreimageSize, err := oracle.MinLargePreimageSize(ctx)
if err != nil {
return nil, fmt.Errorf("failed to load min large preimage size: %w", err)
}
direct := preimages.NewDirectPreimageUploader(logger, txMgr, loader) direct := preimages.NewDirectPreimageUploader(logger, txMgr, loader)
large := preimages.NewLargePreimageUploader(logger, txMgr, oracle) large := preimages.NewLargePreimageUploader(logger, txMgr, oracle)
uploader := preimages.NewSplitPreimageUploader(direct, large) uploader := preimages.NewSplitPreimageUploader(direct, large, minLargePreimageSize)
responder, err := responder.NewFaultResponder(logger, txMgr, loader, uploader, oracle) responder, err := responder.NewFaultResponder(logger, txMgr, loader, uploader, oracle)
if err != nil { if err != nil {
......
...@@ -8,31 +8,26 @@ import ( ...@@ -8,31 +8,26 @@ import (
var _ PreimageUploader = (*SplitPreimageUploader)(nil) var _ PreimageUploader = (*SplitPreimageUploader)(nil)
// PREIMAGE_SIZE_THRESHOLD is the size threshold for determining whether a preimage
// should be uploaded directly or through the large preimage uploader.
// TODO(client-pod#467): determine the correct size threshold to toggle between
//
// the direct and large preimage uploaders.
const PREIMAGE_SIZE_THRESHOLD = 136 * 128
// SplitPreimageUploader routes preimage uploads to the appropriate uploader // SplitPreimageUploader routes preimage uploads to the appropriate uploader
// based on the size of the preimage. // based on the size of the preimage.
type SplitPreimageUploader struct { type SplitPreimageUploader struct {
largePreimageSizeThreshold uint64
directUploader PreimageUploader directUploader PreimageUploader
largeUploader PreimageUploader largeUploader PreimageUploader
} }
func NewSplitPreimageUploader(directUploader PreimageUploader, largeUploader PreimageUploader) *SplitPreimageUploader { func NewSplitPreimageUploader(directUploader PreimageUploader, largeUploader PreimageUploader, minLargePreimageSize uint64) *SplitPreimageUploader {
return &SplitPreimageUploader{directUploader, largeUploader} return &SplitPreimageUploader{minLargePreimageSize, directUploader, largeUploader}
} }
func (s *SplitPreimageUploader) UploadPreimage(ctx context.Context, parent uint64, data *types.PreimageOracleData) error { func (s *SplitPreimageUploader) UploadPreimage(ctx context.Context, parent uint64, data *types.PreimageOracleData) error {
if data == nil { if data == nil {
return ErrNilPreimageData return ErrNilPreimageData
} }
if len(data.OracleData) > PREIMAGE_SIZE_THRESHOLD { // Always route local preimage uploads to the direct uploader.
return s.largeUploader.UploadPreimage(ctx, parent, data) if uint64(len(data.OracleData)) < s.largePreimageSizeThreshold || data.IsLocal {
} else {
return s.directUploader.UploadPreimage(ctx, parent, data) return s.directUploader.UploadPreimage(ctx, parent, data)
} else {
return s.largeUploader.UploadPreimage(ctx, parent, data)
} }
} }
...@@ -8,25 +8,43 @@ import ( ...@@ -8,25 +8,43 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
var mockLargePreimageSizeThreshold = uint64(100)
func TestSplitPreimageUploader_UploadPreimage(t *testing.T) { func TestSplitPreimageUploader_UploadPreimage(t *testing.T) {
t.Run("DirectUploadSucceeds", func(t *testing.T) { t.Run("DirectUploadSucceeds", func(t *testing.T) {
oracle, direct, large := newTestSplitPreimageUploader(t) oracle, direct, large := newTestSplitPreimageUploader(t, mockLargePreimageSizeThreshold)
err := oracle.UploadPreimage(context.Background(), 0, &types.PreimageOracleData{}) err := oracle.UploadPreimage(context.Background(), 0, &types.PreimageOracleData{})
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, 1, direct.updates) require.Equal(t, 1, direct.updates)
require.Equal(t, 0, large.updates) require.Equal(t, 0, large.updates)
}) })
t.Run("LocalDataUploadSucceeds", func(t *testing.T) {
oracle, direct, large := newTestSplitPreimageUploader(t, mockLargePreimageSizeThreshold)
err := oracle.UploadPreimage(context.Background(), 0, &types.PreimageOracleData{IsLocal: true})
require.NoError(t, err)
require.Equal(t, 1, direct.updates)
require.Equal(t, 0, large.updates)
})
t.Run("MaxSizeDirectUploadSucceeds", func(t *testing.T) {
oracle, direct, large := newTestSplitPreimageUploader(t, mockLargePreimageSizeThreshold)
err := oracle.UploadPreimage(context.Background(), 0, &types.PreimageOracleData{OracleData: make([]byte, mockLargePreimageSizeThreshold-1)})
require.NoError(t, err)
require.Equal(t, 1, direct.updates)
require.Equal(t, 0, large.updates)
})
t.Run("LargeUploadSucceeds", func(t *testing.T) { t.Run("LargeUploadSucceeds", func(t *testing.T) {
oracle, direct, large := newTestSplitPreimageUploader(t) oracle, direct, large := newTestSplitPreimageUploader(t, mockLargePreimageSizeThreshold)
err := oracle.UploadPreimage(context.Background(), 0, &types.PreimageOracleData{OracleData: make([]byte, PREIMAGE_SIZE_THRESHOLD+1)}) err := oracle.UploadPreimage(context.Background(), 0, &types.PreimageOracleData{OracleData: make([]byte, mockLargePreimageSizeThreshold)})
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, 1, large.updates) require.Equal(t, 1, large.updates)
require.Equal(t, 0, direct.updates) require.Equal(t, 0, direct.updates)
}) })
t.Run("NilPreimageOracleData", func(t *testing.T) { t.Run("NilPreimageOracleData", func(t *testing.T) {
oracle, _, _ := newTestSplitPreimageUploader(t) oracle, _, _ := newTestSplitPreimageUploader(t, mockLargePreimageSizeThreshold)
err := oracle.UploadPreimage(context.Background(), 0, nil) err := oracle.UploadPreimage(context.Background(), 0, nil)
require.ErrorIs(t, err, ErrNilPreimageData) require.ErrorIs(t, err, ErrNilPreimageData)
}) })
...@@ -45,8 +63,8 @@ func (s *mockPreimageUploader) UploadPreimage(ctx context.Context, parent uint64 ...@@ -45,8 +63,8 @@ func (s *mockPreimageUploader) UploadPreimage(ctx context.Context, parent uint64
return nil return nil
} }
func newTestSplitPreimageUploader(t *testing.T) (*SplitPreimageUploader, *mockPreimageUploader, *mockPreimageUploader) { func newTestSplitPreimageUploader(t *testing.T, threshold uint64) (*SplitPreimageUploader, *mockPreimageUploader, *mockPreimageUploader) {
direct := &mockPreimageUploader{} direct := &mockPreimageUploader{}
large := &mockPreimageUploader{} large := &mockPreimageUploader{}
return NewSplitPreimageUploader(direct, large), direct, large return NewSplitPreimageUploader(direct, large, threshold), direct, large
} }
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