Commit 665eda47 authored by refcell.eth's avatar refcell.eth Committed by GitHub

fix(op-challenger): Large Preimage Unique Identifier Construction (#9131)

* fix(op-challenger): construct unique uuid

* fix(op-challenger): remove nil check
parent e6ef3a90
...@@ -3,7 +3,7 @@ package preimages ...@@ -3,7 +3,7 @@ package preimages
import ( import (
"bytes" "bytes"
"context" "context"
"crypto/rand" "encoding/binary"
"errors" "errors"
"fmt" "fmt"
"io" "io"
...@@ -13,6 +13,7 @@ import ( ...@@ -13,6 +13,7 @@ import (
"github.com/ethereum-optimism/optimism/op-challenger/game/keccak/matrix" "github.com/ethereum-optimism/optimism/op-challenger/game/keccak/matrix"
"github.com/ethereum-optimism/optimism/op-service/txmgr" "github.com/ethereum-optimism/optimism/op-service/txmgr"
ethtypes "github.com/ethereum/go-ethereum/core/types" ethtypes "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
) )
...@@ -81,13 +82,8 @@ func (p *LargePreimageUploader) UploadPreimage(ctx context.Context, parent uint6 ...@@ -81,13 +82,8 @@ func (p *LargePreimageUploader) UploadPreimage(ctx context.Context, parent uint6
} }
} }
// TODO(client-pod#473): The UUID must be deterministic so the challenger can resume uploads. uuid := p.newUUID(data)
uuid, err := p.newUUID() err := p.initLargePreimage(ctx, uuid, data.OracleOffset, uint32(len(data.OracleData)))
if err != nil {
return fmt.Errorf("failed to generate UUID: %w", err)
}
err = p.initLargePreimage(ctx, uuid, data.OracleOffset, uint32(len(data.OracleData)))
if err != nil { if err != nil {
return fmt.Errorf("failed to initialize large preimage with uuid: %s: %w", uuid, err) return fmt.Errorf("failed to initialize large preimage with uuid: %s: %w", uuid, err)
} }
...@@ -103,10 +99,16 @@ func (p *LargePreimageUploader) UploadPreimage(ctx context.Context, parent uint6 ...@@ -103,10 +99,16 @@ func (p *LargePreimageUploader) UploadPreimage(ctx context.Context, parent uint6
return errNotSupported return errNotSupported
} }
func (p *LargePreimageUploader) newUUID() (*big.Int, error) { // newUUID generates a new unique identifier for the preimage by hashing the
max := new(big.Int) // concatenated preimage data, preimage offset, and sender address.
max.Exp(big.NewInt(2), big.NewInt(130), nil).Sub(max, big.NewInt(1)) func (p *LargePreimageUploader) newUUID(data *types.PreimageOracleData) *big.Int {
return rand.Int(rand.Reader, max) sender := p.txMgr.From()
offset := make([]byte, 4)
binary.LittleEndian.PutUint32(offset, data.OracleOffset)
concatenated := append(data.OracleData, offset...)
concatenated = append(concatenated, sender.Bytes()...)
hash := crypto.Keccak256Hash(concatenated)
return hash.Big()
} }
// initLargePreimage initializes the large preimage proposal. // initLargePreimage initializes the large preimage proposal.
......
...@@ -18,6 +18,52 @@ import ( ...@@ -18,6 +18,52 @@ import (
var mockAddLeavesError = errors.New("mock add leaves error") var mockAddLeavesError = errors.New("mock add leaves error")
func TestLargePreimageUploader_NewUUID(t *testing.T) {
tests := []struct {
name string
data *types.PreimageOracleData
expectedUUID *big.Int
}{
{
name: "EmptyOracleData",
data: &types.PreimageOracleData{},
expectedUUID: new(big.Int).SetBytes(common.Hex2Bytes("827b659bbda2a0bdecce2c91b8b68462545758f3eba2dbefef18e0daf84f5ccd")),
},
{
name: "OracleDataAndOffset_Control",
data: &types.PreimageOracleData{
OracleData: []byte{1, 2, 3},
OracleOffset: 0x010203,
},
expectedUUID: new(big.Int).SetBytes(common.Hex2Bytes("641e230bcf3ade8c71b7e591d210184cdb190e853f61ba59a1411c3b7aca9890")),
},
{
name: "OracleDataAndOffset_DifferentOffset",
data: &types.PreimageOracleData{
OracleData: []byte{1, 2, 3},
OracleOffset: 0x010204,
},
expectedUUID: new(big.Int).SetBytes(common.Hex2Bytes("aec56de44401325420e5793f72b777e3e547778de7d8344004b31be086a3136d")),
},
{
name: "OracleDataAndOffset_DifferentData",
data: &types.PreimageOracleData{
OracleData: []byte{1, 2, 3, 4},
OracleOffset: 0x010203,
},
expectedUUID: new(big.Int).SetBytes(common.Hex2Bytes("ca38aa17d56805cf26376a050c2c7b15b6be4e709bc422a1c679fe21aa6aa8c7")),
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
oracle, _, _ := newTestLargePreimageUploader(t)
uuid := oracle.newUUID(test.data)
require.Equal(t, test.expectedUUID, uuid)
})
}
}
func TestLargePreimageUploader_UploadPreimage(t *testing.T) { func TestLargePreimageUploader_UploadPreimage(t *testing.T) {
t.Run("InitFails", func(t *testing.T) { t.Run("InitFails", func(t *testing.T) {
oracle, _, contract := newTestLargePreimageUploader(t) oracle, _, contract := newTestLargePreimageUploader(t)
......
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