Skip to content

Commit ca583f7

Browse files
ajsuttonInphi
andauthored
op-program: Add chain ID to hints when using interop (#13735)
* op-program: Add L2 chain ID to hints when using interop * op-program: Add L2 chain ID to OutputRoot hints when using interop * Fix label in error message. Co-authored-by: Inphi <[email protected]> --------- Co-authored-by: Inphi <[email protected]>
1 parent 66a67e0 commit ca583f7

File tree

20 files changed

+547
-176
lines changed

20 files changed

+547
-176
lines changed

op-e2e/actions/interop/interop_test.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,6 @@ func TestInteropFaultProofs(gt *testing.T) {
319319
agreedClaim: step1Expected,
320320
disputedClaim: step2Expected,
321321
expectValid: true,
322-
skip: true,
323322
},
324323
{
325324
name: "PaddingStep",

op-program/client/l2/cache.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -39,42 +39,42 @@ func NewCachingOracle(oracle Oracle) *CachingOracle {
3939
}
4040
}
4141

42-
func (o *CachingOracle) NodeByHash(nodeHash common.Hash) []byte {
42+
func (o *CachingOracle) NodeByHash(nodeHash common.Hash, chainID uint64) []byte {
4343
node, ok := o.nodes.Get(nodeHash)
4444
if ok {
4545
return node
4646
}
47-
node = o.oracle.NodeByHash(nodeHash)
47+
node = o.oracle.NodeByHash(nodeHash, chainID)
4848
o.nodes.Add(nodeHash, node)
4949
return node
5050
}
5151

52-
func (o *CachingOracle) CodeByHash(codeHash common.Hash) []byte {
52+
func (o *CachingOracle) CodeByHash(codeHash common.Hash, chainID uint64) []byte {
5353
code, ok := o.codes.Get(codeHash)
5454
if ok {
5555
return code
5656
}
57-
code = o.oracle.CodeByHash(codeHash)
57+
code = o.oracle.CodeByHash(codeHash, chainID)
5858
o.codes.Add(codeHash, code)
5959
return code
6060
}
6161

62-
func (o *CachingOracle) BlockByHash(blockHash common.Hash) *types.Block {
62+
func (o *CachingOracle) BlockByHash(blockHash common.Hash, chainID uint64) *types.Block {
6363
block, ok := o.blocks.Get(blockHash)
6464
if ok {
6565
return block
6666
}
67-
block = o.oracle.BlockByHash(blockHash)
67+
block = o.oracle.BlockByHash(blockHash, chainID)
6868
o.blocks.Add(blockHash, block)
6969
return block
7070
}
7171

72-
func (o *CachingOracle) OutputByRoot(root common.Hash) eth.Output {
72+
func (o *CachingOracle) OutputByRoot(root common.Hash, chainID uint64) eth.Output {
7373
output, ok := o.outputs.Get(root)
7474
if ok {
7575
return output
7676
}
77-
output = o.oracle.OutputByRoot(root)
77+
output = o.oracle.OutputByRoot(root, chainID)
7878
o.outputs.Add(root, output)
7979
return output
8080
}

op-program/client/l2/cache_test.go

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import (
1515
var _ Oracle = (*CachingOracle)(nil)
1616

1717
func TestBlockByHash(t *testing.T) {
18+
chainID := uint64(48294)
1819
stub, _ := test.NewStubOracle(t)
1920
oracle := NewCachingOracle(stub)
2021

@@ -23,12 +24,12 @@ func TestBlockByHash(t *testing.T) {
2324

2425
// Initial call retrieves from the stub
2526
stub.Blocks[block.Hash()] = block
26-
actual := oracle.BlockByHash(block.Hash())
27+
actual := oracle.BlockByHash(block.Hash(), chainID)
2728
require.Equal(t, block, actual)
2829

29-
// Later calls should retrieve from cache
30+
// Later calls should retrieve from cache (even if chain ID is different)
3031
delete(stub.Blocks, block.Hash())
31-
actual = oracle.BlockByHash(block.Hash())
32+
actual = oracle.BlockByHash(block.Hash(), 9982)
3233
require.Equal(t, block, actual)
3334
}
3435

@@ -41,12 +42,12 @@ func TestNodeByHash(t *testing.T) {
4142

4243
// Initial call retrieves from the stub
4344
stateStub.Data[hash] = node
44-
actual := oracle.NodeByHash(hash)
45+
actual := oracle.NodeByHash(hash, 1234)
4546
require.Equal(t, node, actual)
4647

47-
// Later calls should retrieve from cache
48+
// Later calls should retrieve from cache (even if chain ID is different)
4849
delete(stateStub.Data, hash)
49-
actual = oracle.NodeByHash(hash)
50+
actual = oracle.NodeByHash(hash, 997845)
5051
require.Equal(t, node, actual)
5152
}
5253

@@ -59,12 +60,12 @@ func TestCodeByHash(t *testing.T) {
5960

6061
// Initial call retrieves from the stub
6162
stateStub.Code[hash] = node
62-
actual := oracle.CodeByHash(hash)
63+
actual := oracle.CodeByHash(hash, 342)
6364
require.Equal(t, node, actual)
6465

65-
// Later calls should retrieve from cache
66+
// Later calls should retrieve from cache (even if the chain ID is different)
6667
delete(stateStub.Code, hash)
67-
actual = oracle.CodeByHash(hash)
68+
actual = oracle.CodeByHash(hash, 986776)
6869
require.Equal(t, node, actual)
6970
}
7071

@@ -78,11 +79,11 @@ func TestOutputByRoot(t *testing.T) {
7879
// Initial call retrieves from the stub
7980
root := common.Hash(eth.OutputRoot(output))
8081
stub.Outputs[root] = output
81-
actual := oracle.OutputByRoot(root)
82+
actual := oracle.OutputByRoot(root, 59284)
8283
require.Equal(t, output, actual)
8384

84-
// Later calls should retrieve from cache
85+
// Later calls should retrieve from cache (even if the chain ID is different)
8586
delete(stub.Outputs, root)
86-
actual = oracle.OutputByRoot(root)
87+
actual = oracle.OutputByRoot(root, 9193)
8788
require.Equal(t, output, actual)
8889
}

op-program/client/l2/db.go

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,16 @@ var codePrefixedKeyLength = common.HashLength + len(rawdb.CodePrefix)
1616
var ErrInvalidKeyLength = errors.New("pre-images must be identified by 32-byte hash keys")
1717

1818
type OracleKeyValueStore struct {
19-
db ethdb.KeyValueStore
20-
oracle StateOracle
19+
db ethdb.KeyValueStore
20+
oracle StateOracle
21+
chainID uint64
2122
}
2223

23-
func NewOracleBackedDB(oracle StateOracle) *OracleKeyValueStore {
24+
func NewOracleBackedDB(oracle StateOracle, chainID uint64) *OracleKeyValueStore {
2425
return &OracleKeyValueStore{
25-
db: memorydb.New(),
26-
oracle: oracle,
26+
db: memorydb.New(),
27+
oracle: oracle,
28+
chainID: chainID,
2729
}
2830
}
2931

@@ -38,12 +40,12 @@ func (o *OracleKeyValueStore) Get(key []byte) ([]byte, error) {
3840

3941
if len(key) == codePrefixedKeyLength && bytes.HasPrefix(key, rawdb.CodePrefix) {
4042
key = key[len(rawdb.CodePrefix):]
41-
return o.oracle.CodeByHash(*(*[common.HashLength]byte)(key)), nil
43+
return o.oracle.CodeByHash(*(*[common.HashLength]byte)(key), o.chainID), nil
4244
}
4345
if len(key) != common.HashLength {
4446
return nil, ErrInvalidKeyLength
4547
}
46-
return o.oracle.NodeByHash(*(*[common.HashLength]byte)(key)), nil
48+
return o.oracle.NodeByHash(*(*[common.HashLength]byte)(key), o.chainID), nil
4749
}
4850

4951
func (o *OracleKeyValueStore) NewBatch() ethdb.Batch {

op-program/client/l2/db_test.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,15 +34,15 @@ var _ ethdb.KeyValueStore = (*OracleKeyValueStore)(nil)
3434
func TestGet(t *testing.T) {
3535
t.Run("IncorrectLengthKey", func(t *testing.T) {
3636
oracle := test.NewStubStateOracle(t)
37-
db := NewOracleBackedDB(oracle)
37+
db := NewOracleBackedDB(oracle, 1234)
3838
val, err := db.Get([]byte{1, 2, 3})
3939
require.ErrorIs(t, err, ErrInvalidKeyLength)
4040
require.Nil(t, val)
4141
})
4242

4343
t.Run("KeyWithCodePrefix", func(t *testing.T) {
4444
oracle := test.NewStubStateOracle(t)
45-
db := NewOracleBackedDB(oracle)
45+
db := NewOracleBackedDB(oracle, 1234)
4646
key := common.HexToHash("0x12345678")
4747
prefixedKey := append(rawdb.CodePrefix, key.Bytes()...)
4848

@@ -56,7 +56,7 @@ func TestGet(t *testing.T) {
5656

5757
t.Run("NormalKeyThatHappensToStartWithCodePrefix", func(t *testing.T) {
5858
oracle := test.NewStubStateOracle(t)
59-
db := NewOracleBackedDB(oracle)
59+
db := NewOracleBackedDB(oracle, 1234)
6060
key := make([]byte, common.HashLength)
6161
copy(rawdb.CodePrefix, key)
6262
fmt.Println(key[0])
@@ -73,7 +73,7 @@ func TestGet(t *testing.T) {
7373
expected := []byte{2, 6, 3, 8}
7474
oracle := test.NewStubStateOracle(t)
7575
oracle.Data[key] = expected
76-
db := NewOracleBackedDB(oracle)
76+
db := NewOracleBackedDB(oracle, 1234)
7777
val, err := db.Get(key.Bytes())
7878
require.NoError(t, err)
7979
require.Equal(t, expected, val)
@@ -83,7 +83,7 @@ func TestGet(t *testing.T) {
8383
func TestPut(t *testing.T) {
8484
t.Run("NewKey", func(t *testing.T) {
8585
oracle := test.NewStubStateOracle(t)
86-
db := NewOracleBackedDB(oracle)
86+
db := NewOracleBackedDB(oracle, 1234)
8787
key := common.HexToHash("0xAA4488")
8888
value := []byte{2, 6, 3, 8}
8989
err := db.Put(key.Bytes(), value)
@@ -95,7 +95,7 @@ func TestPut(t *testing.T) {
9595
})
9696
t.Run("ReplaceKey", func(t *testing.T) {
9797
oracle := test.NewStubStateOracle(t)
98-
db := NewOracleBackedDB(oracle)
98+
db := NewOracleBackedDB(oracle, 1234)
9999
key := common.HexToHash("0xAA4488")
100100
value1 := []byte{2, 6, 3, 8}
101101
value2 := []byte{1, 2, 3}
@@ -117,13 +117,13 @@ func TestSupportsStateDBOperations(t *testing.T) {
117117
genesisBlock := l2Genesis.MustCommit(realDb, trieDB)
118118

119119
loader := test.NewKvStateOracle(t, realDb)
120-
assertStateDataAvailable(t, NewOracleBackedDB(loader), l2Genesis, genesisBlock)
120+
assertStateDataAvailable(t, NewOracleBackedDB(loader, 1234), l2Genesis, genesisBlock)
121121
}
122122

123123
func TestUpdateState(t *testing.T) {
124124
l2Genesis := createGenesis()
125125
oracle := test.NewStubStateOracle(t)
126-
db := rawdb.NewDatabase(NewOracleBackedDB(oracle))
126+
db := rawdb.NewDatabase(NewOracleBackedDB(oracle, 1234))
127127

128128
trieDB := triedb.NewDatabase(db, &triedb.Config{HashDB: hashdb.Defaults})
129129
genesisBlock := l2Genesis.MustCommit(db, trieDB)

op-program/client/l2/engine_backend.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,13 @@ type OracleBackedL2Chain struct {
4545
var _ engineapi.CachingEngineBackend = (*OracleBackedL2Chain)(nil)
4646

4747
func NewOracleBackedL2Chain(logger log.Logger, oracle Oracle, precompileOracle engineapi.PrecompileOracle, chainCfg *params.ChainConfig, l2OutputRoot common.Hash) (*OracleBackedL2Chain, error) {
48-
output := oracle.OutputByRoot(l2OutputRoot)
48+
chainID := chainCfg.ChainID.Uint64()
49+
output := oracle.OutputByRoot(l2OutputRoot, chainID)
4950
outputV0, ok := output.(*eth.OutputV0)
5051
if !ok {
5152
return nil, fmt.Errorf("unsupported L2 output version: %d", output.Version())
5253
}
53-
head := oracle.BlockByHash(outputV0.BlockHash)
54+
head := oracle.BlockByHash(outputV0.BlockHash, chainID)
5455
logger.Info("Loaded L2 head", "hash", head.Hash(), "number", head.Number())
5556
return &OracleBackedL2Chain{
5657
log: logger,
@@ -69,7 +70,7 @@ func NewOracleBackedL2Chain(logger log.Logger, oracle Oracle, precompileOracle e
6970
finalized: head.Header(),
7071
oracleHead: head.Header(),
7172
blocks: make(map[common.Hash]*types.Block),
72-
db: NewOracleBackedDB(oracle),
73+
db: NewOracleBackedDB(oracle, chainID),
7374
vmCfg: vm.Config{
7475
PrecompileOverrides: engineapi.CreatePrecompileOverrides(precompileOracle),
7576
},
@@ -122,7 +123,7 @@ func (o *OracleBackedL2Chain) GetBlockByHash(hash common.Hash) *types.Block {
122123
return block
123124
}
124125
// Retrieve from the oracle
125-
return o.oracle.BlockByHash(hash)
126+
return o.oracle.BlockByHash(hash, o.chainCfg.ChainID.Uint64())
126127
}
127128

128129
func (o *OracleBackedL2Chain) GetBlock(hash common.Hash, number uint64) *types.Block {

op-program/client/l2/engine_backend_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -378,7 +378,7 @@ func createBlock(t *testing.T, chain *OracleBackedL2Chain, opts ...blockCreateOp
378378
require.NoError(t, err)
379379
nonce := parentDB.GetNonce(fundedAddress)
380380
config := chain.Config()
381-
db := rawdb.NewDatabase(NewOracleBackedDB(chain.oracle))
381+
db := rawdb.NewDatabase(NewOracleBackedDB(chain.oracle, config.ChainID.Uint64()))
382382
blocks, _ := core.GenerateChain(config, parent, chain.Engine(), db, 1, func(i int, gen *core.BlockGen) {
383383
rawTx := &types.DynamicFeeTx{
384384
ChainID: config.ChainID,

op-program/client/l2/hints.go

Lines changed: 60 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"fmt"
66

77
"github.com/ethereum/go-ethereum/common"
8+
"github.com/ethereum/go-ethereum/common/hexutil"
89

910
preimage "github.com/ethereum-optimism/optimism/op-preimage"
1011
)
@@ -19,43 +20,95 @@ const (
1920
HintAgreedPrestate = "agreed-pre-state"
2021
)
2122

22-
type BlockHeaderHint common.Hash
23+
type LegacyBlockHeaderHint common.Hash
24+
25+
var _ preimage.Hint = LegacyBlockHeaderHint{}
26+
27+
func (l LegacyBlockHeaderHint) Hint() string {
28+
return HintL2BlockHeader + " " + (common.Hash)(l).String()
29+
}
30+
31+
type HashAndChainID struct {
32+
Hash common.Hash
33+
ChainID uint64
34+
}
35+
36+
func (h HashAndChainID) Marshal() []byte {
37+
d := make([]byte, 32+8)
38+
copy(d[:32], h.Hash[:])
39+
binary.BigEndian.PutUint64(d[32:], h.ChainID)
40+
return d
41+
}
42+
43+
type BlockHeaderHint HashAndChainID
2344

2445
var _ preimage.Hint = BlockHeaderHint{}
2546

2647
func (l BlockHeaderHint) Hint() string {
27-
return HintL2BlockHeader + " " + (common.Hash)(l).String()
48+
return HintL2BlockHeader + " " + hexutil.Encode(HashAndChainID(l).Marshal())
49+
}
50+
51+
type LegacyTransactionsHint common.Hash
52+
53+
var _ preimage.Hint = LegacyTransactionsHint{}
54+
55+
func (l LegacyTransactionsHint) Hint() string {
56+
return HintL2Transactions + " " + (common.Hash)(l).String()
2857
}
2958

30-
type TransactionsHint common.Hash
59+
type TransactionsHint HashAndChainID
3160

3261
var _ preimage.Hint = TransactionsHint{}
3362

3463
func (l TransactionsHint) Hint() string {
35-
return HintL2Transactions + " " + (common.Hash)(l).String()
64+
return HintL2Transactions + " " + hexutil.Encode(HashAndChainID(l).Marshal())
3665
}
3766

38-
type CodeHint common.Hash
67+
type CodeHint HashAndChainID
3968

4069
var _ preimage.Hint = CodeHint{}
4170

4271
func (l CodeHint) Hint() string {
72+
return HintL2Code + " " + hexutil.Encode(HashAndChainID(l).Marshal())
73+
}
74+
75+
type LegacyCodeHint common.Hash
76+
77+
var _ preimage.Hint = LegacyCodeHint{}
78+
79+
func (l LegacyCodeHint) Hint() string {
4380
return HintL2Code + " " + (common.Hash)(l).String()
4481
}
4582

46-
type StateNodeHint common.Hash
83+
type StateNodeHint HashAndChainID
4784

4885
var _ preimage.Hint = StateNodeHint{}
4986

5087
func (l StateNodeHint) Hint() string {
88+
return HintL2StateNode + " " + hexutil.Encode(HashAndChainID(l).Marshal())
89+
}
90+
91+
type LegacyStateNodeHint common.Hash
92+
93+
var _ preimage.Hint = LegacyStateNodeHint{}
94+
95+
func (l LegacyStateNodeHint) Hint() string {
5196
return HintL2StateNode + " " + (common.Hash)(l).String()
5297
}
5398

54-
type L2OutputHint common.Hash
99+
type L2OutputHint HashAndChainID
55100

56101
var _ preimage.Hint = L2OutputHint{}
57102

58103
func (l L2OutputHint) Hint() string {
104+
return HintL2Output + " " + hexutil.Encode(HashAndChainID(l).Marshal())
105+
}
106+
107+
type LegacyL2OutputHint common.Hash
108+
109+
var _ preimage.Hint = LegacyL2OutputHint{}
110+
111+
func (l LegacyL2OutputHint) Hint() string {
59112
return HintL2Output + " " + (common.Hash)(l).String()
60113
}
61114

0 commit comments

Comments
 (0)