diff --git a/op-challenger/game/fault/preimages/split.go b/op-challenger/game/fault/preimages/split.go index 84541c7feb6e4..e49ffc41f8f08 100644 --- a/op-challenger/game/fault/preimages/split.go +++ b/op-challenger/game/fault/preimages/split.go @@ -4,6 +4,7 @@ import ( "context" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + preimage "github.com/ethereum-optimism/optimism/op-preimage" ) var _ PreimageUploader = (*SplitPreimageUploader)(nil) @@ -25,7 +26,9 @@ func (s *SplitPreimageUploader) UploadPreimage(ctx context.Context, parent uint6 return ErrNilPreimageData } // Always route local preimage uploads to the direct uploader. - if data.IsLocal || uint64(len(data.GetPreimageWithoutSize())) < s.largePreimageSizeThreshold { + // Large-preimage proposals are keccak-only on-chain, so non-keccak preimages must go through the direct path. + isKeccak := len(data.OracleKey) > 0 && preimage.KeyType(data.OracleKey[0]) == preimage.Keccak256KeyType + if data.IsLocal || !isKeccak || uint64(len(data.GetPreimageWithoutSize())) < s.largePreimageSizeThreshold { return s.directUploader.UploadPreimage(ctx, parent, data) } else { return s.largeUploader.UploadPreimage(ctx, parent, data) diff --git a/op-challenger/game/fault/preimages/split_test.go b/op-challenger/game/fault/preimages/split_test.go index fbecdc06467c5..506fa49e83e15 100644 --- a/op-challenger/game/fault/preimages/split_test.go +++ b/op-challenger/game/fault/preimages/split_test.go @@ -2,9 +2,12 @@ package preimages import ( "context" + "crypto/sha256" + "encoding/binary" "testing" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + preimage "github.com/ethereum-optimism/optimism/op-preimage" "github.com/stretchr/testify/require" ) @@ -43,6 +46,14 @@ func TestSplitPreimageUploader_UploadPreimage(t *testing.T) { require.Equal(t, 0, direct.updates) }) + t.Run("NonKeccakAlwaysUsesDirect", func(t *testing.T) { + oracle, direct, large := newTestSplitPreimageUploader(t, mockLargePreimageSizeThreshold) + err := oracle.UploadPreimage(context.Background(), 0, makeSha256PreimageData(make([]byte, mockLargePreimageSizeThreshold), 0)) + require.NoError(t, err) + require.Equal(t, 1, direct.updates) + require.Equal(t, 0, large.updates) + }) + t.Run("NilPreimageOracleData", func(t *testing.T) { oracle, _, _ := newTestSplitPreimageUploader(t, mockLargePreimageSizeThreshold) err := oracle.UploadPreimage(context.Background(), 0, nil) @@ -68,3 +79,13 @@ func newTestSplitPreimageUploader(t *testing.T, threshold uint64) (*SplitPreimag large := &mockPreimageUploader{} return NewSplitPreimageUploader(direct, large, threshold), direct, large } + +func makeSha256PreimageData(pre []byte, offset uint32) *types.PreimageOracleData { + sum := sha256.Sum256(pre) + key := preimage.Sha256Key(sum).PreimageKey() + // Add the length prefix to match how Cannon formats oracle data. + dataWithLength := make([]byte, 0, 8+len(pre)) + dataWithLength = binary.BigEndian.AppendUint64(dataWithLength, uint64(len(pre))) + dataWithLength = append(dataWithLength, pre...) + return types.NewPreimageOracleData(key[:], dataWithLength, offset) +}