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 (
methodProposalBlocksLen = "proposalBlocksLen"
methodProposalBlocks = "proposalBlocks"
methodPreimagePartOk = "preimagePartOk"
methodMinProposalSize = "minProposalSize"
)
var (
......@@ -134,6 +135,15 @@ func abiEncodeStateMatrix(stateMatrix *matrix.StateMatrix) bindings.LibKeccakSta
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) {
block := batching.BlockByHash(blockHash)
results, err := batching.ReadArray(ctx, c.multiCaller, block, c.contract.Call(methodProposalCount), func(i *big.Int) *batching.ContractCall {
......
......@@ -88,9 +88,13 @@ func NewGamePlayer(
if err != nil {
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)
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)
if err != nil {
......
......@@ -8,31 +8,26 @@ import (
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
// based on the size of the preimage.
type SplitPreimageUploader struct {
directUploader PreimageUploader
largeUploader PreimageUploader
largePreimageSizeThreshold uint64
directUploader PreimageUploader
largeUploader PreimageUploader
}
func NewSplitPreimageUploader(directUploader PreimageUploader, largeUploader PreimageUploader) *SplitPreimageUploader {
return &SplitPreimageUploader{directUploader, largeUploader}
func NewSplitPreimageUploader(directUploader PreimageUploader, largeUploader PreimageUploader, minLargePreimageSize uint64) *SplitPreimageUploader {
return &SplitPreimageUploader{minLargePreimageSize, directUploader, largeUploader}
}
func (s *SplitPreimageUploader) UploadPreimage(ctx context.Context, parent uint64, data *types.PreimageOracleData) error {
if data == nil {
return ErrNilPreimageData
}
if len(data.OracleData) > PREIMAGE_SIZE_THRESHOLD {
return s.largeUploader.UploadPreimage(ctx, parent, data)
} else {
// Always route local preimage uploads to the direct uploader.
if uint64(len(data.OracleData)) < s.largePreimageSizeThreshold || data.IsLocal {
return s.directUploader.UploadPreimage(ctx, parent, data)
} else {
return s.largeUploader.UploadPreimage(ctx, parent, data)
}
}
......@@ -8,25 +8,43 @@ import (
"github.com/stretchr/testify/require"
)
var mockLargePreimageSizeThreshold = uint64(100)
func TestSplitPreimageUploader_UploadPreimage(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{})
require.NoError(t, err)
require.Equal(t, 1, direct.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) {
oracle, direct, large := newTestSplitPreimageUploader(t)
err := oracle.UploadPreimage(context.Background(), 0, &types.PreimageOracleData{OracleData: make([]byte, PREIMAGE_SIZE_THRESHOLD+1)})
oracle, direct, large := newTestSplitPreimageUploader(t, mockLargePreimageSizeThreshold)
err := oracle.UploadPreimage(context.Background(), 0, &types.PreimageOracleData{OracleData: make([]byte, mockLargePreimageSizeThreshold)})
require.NoError(t, err)
require.Equal(t, 1, large.updates)
require.Equal(t, 0, direct.updates)
})
t.Run("NilPreimageOracleData", func(t *testing.T) {
oracle, _, _ := newTestSplitPreimageUploader(t)
oracle, _, _ := newTestSplitPreimageUploader(t, mockLargePreimageSizeThreshold)
err := oracle.UploadPreimage(context.Background(), 0, nil)
require.ErrorIs(t, err, ErrNilPreimageData)
})
......@@ -45,8 +63,8 @@ func (s *mockPreimageUploader) UploadPreimage(ctx context.Context, parent uint64
return nil
}
func newTestSplitPreimageUploader(t *testing.T) (*SplitPreimageUploader, *mockPreimageUploader, *mockPreimageUploader) {
func newTestSplitPreimageUploader(t *testing.T, threshold uint64) (*SplitPreimageUploader, *mockPreimageUploader, *mockPreimageUploader) {
direct := &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