Commit cd863777 authored by Adrian Sutton's avatar Adrian Sutton

op-program: Add separate keystore for local keys

parent 131ae0a1
...@@ -84,6 +84,9 @@ func FaultProofProgram(logger log.Logger, cfg *config.Config) error { ...@@ -84,6 +84,9 @@ func FaultProofProgram(logger log.Logger, cfg *config.Config) error {
} }
} }
localPreimageSource := kvstore.NewLocalPreimageSource(cfg)
splitter := kvstore.NewPreimageSourceSplitter(localPreimageSource.Get, getPreimage)
// Setup pipe for preimage oracle interaction // Setup pipe for preimage oracle interaction
pClientRW, pHostRW := bidirectionalPipe() pClientRW, pHostRW := bidirectionalPipe()
oracleServer := preimage.NewOracleServer(pHostRW) oracleServer := preimage.NewOracleServer(pHostRW)
...@@ -93,7 +96,7 @@ func FaultProofProgram(logger log.Logger, cfg *config.Config) error { ...@@ -93,7 +96,7 @@ func FaultProofProgram(logger log.Logger, cfg *config.Config) error {
defer pHostRW.Close() defer pHostRW.Close()
defer hHostRW.Close() defer hHostRW.Close()
routeHints(logger, hHost, hinter) routeHints(logger, hHost, hinter)
launchOracleServer(logger, oracleServer, getPreimage) launchOracleServer(logger, oracleServer, splitter.Get)
return cl.ClientProgram( return cl.ClientProgram(
logger, logger,
......
package kvstore
import (
"encoding/binary"
"encoding/json"
"github.com/ethereum-optimism/optimism/op-program/host/config"
"github.com/ethereum-optimism/optimism/op-program/preimage"
"github.com/ethereum/go-ethereum/common"
)
type LocalPreimageSource struct {
config *config.Config
}
func NewLocalPreimageSource(config *config.Config) *LocalPreimageSource {
return &LocalPreimageSource{config}
}
func localKey(num int64) common.Hash {
return preimage.LocalIndexKey(num).PreimageKey()
}
var (
L1HeadKey = localKey(1)
L2HeadKey = localKey(2)
L2ClaimKey = localKey(3)
L2ClaimBlockNumberKey = localKey(4)
L2ChainConfigKey = localKey(5)
RollupKey = localKey(6)
)
func (s *LocalPreimageSource) Get(key common.Hash) ([]byte, error) {
switch key {
case L1HeadKey:
return s.config.L1Head.Bytes(), nil
case L2HeadKey:
return s.config.L2Head.Bytes(), nil
case L2ClaimKey:
return s.config.L2Claim.Bytes(), nil
case L2ClaimBlockNumberKey:
return binary.BigEndian.AppendUint64(nil, s.config.L2ClaimBlockNumber), nil
case L2ChainConfigKey:
return json.Marshal(s.config.L2ChainConfig)
case RollupKey:
return json.Marshal(s.config.Rollup)
default:
return nil, ErrNotFound
}
}
package kvstore
import (
"encoding/binary"
"encoding/json"
"testing"
"github.com/ethereum-optimism/optimism/op-node/chaincfg"
"github.com/ethereum-optimism/optimism/op-program/host/config"
"github.com/ethereum-optimism/optimism/op-program/preimage"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/params"
"github.com/stretchr/testify/require"
)
func TestLocalPreimageSource(t *testing.T) {
cfg := &config.Config{
Rollup: &chaincfg.Goerli,
L1Head: common.HexToHash("0x1111"),
L2Head: common.HexToHash("0x2222"),
L2Claim: common.HexToHash("0x3333"),
L2ClaimBlockNumber: 1234,
L2ChainConfig: params.GoerliChainConfig,
}
source := NewLocalPreimageSource(cfg)
tests := []struct {
name string
key common.Hash
expected []byte
}{
{"L1Head", L1HeadKey, cfg.L1Head.Bytes()},
{"L2Head", L2HeadKey, cfg.L2Head.Bytes()},
{"L2Claim", L2ClaimKey, cfg.L2Claim.Bytes()},
{"L2ClaimBlockNumber", L2ClaimBlockNumberKey, binary.BigEndian.AppendUint64(nil, cfg.L2ClaimBlockNumber)},
{"Rollup", RollupKey, asJson(t, cfg.Rollup)},
{"ChainConfig", L2ChainConfigKey, asJson(t, cfg.L2ChainConfig)},
{"Unknown", preimage.LocalIndexKey(1000).PreimageKey(), nil},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
result, err := source.Get(test.key)
if test.expected == nil {
require.ErrorIs(t, err, ErrNotFound)
} else {
require.NoError(t, err)
}
require.Equal(t, test.expected, result)
})
}
}
func asJson(t *testing.T, v any) []byte {
d, err := json.Marshal(v)
require.NoError(t, err)
return d
}
package kvstore
import (
"github.com/ethereum-optimism/optimism/op-program/preimage"
"github.com/ethereum/go-ethereum/common"
)
type PreimageSource func(key common.Hash) ([]byte, error)
type PreimageSourceSplitter struct {
local PreimageSource
global PreimageSource
}
func NewPreimageSourceSplitter(local PreimageSource, global PreimageSource) *PreimageSourceSplitter {
return &PreimageSourceSplitter{
local: local,
global: global,
}
}
func (s *PreimageSourceSplitter) Get(key common.Hash) ([]byte, error) {
if key[0] == byte(preimage.LocalKeyType) {
return s.local(key)
}
return s.global(key)
}
package kvstore
import (
"testing"
"github.com/ethereum-optimism/optimism/op-program/preimage"
"github.com/ethereum/go-ethereum/common"
"github.com/stretchr/testify/require"
)
func TestPreimageSourceSplitter(t *testing.T) {
localResult := []byte{1}
globalResult := []byte{2}
local := func(key common.Hash) ([]byte, error) { return localResult, nil }
global := func(key common.Hash) ([]byte, error) { return globalResult, nil }
splitter := NewPreimageSourceSplitter(local, global)
tests := []struct {
name string
keyPrefix byte
expected []byte
}{
{"Local", byte(preimage.LocalKeyType), localResult},
{"Keccak", byte(preimage.Keccak256KeyType), globalResult},
{"Generic", byte(3), globalResult},
{"Reserved", byte(4), globalResult},
{"Application", byte(255), globalResult},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
key := common.Hash{0xff}
key[0] = test.keyPrefix
res, err := splitter.Get(key)
require.NoError(t, err)
require.Equal(t, test.expected, res)
})
}
}
...@@ -33,8 +33,8 @@ const ( ...@@ -33,8 +33,8 @@ const (
_ KeyType = 0 _ KeyType = 0
// LocalKeyType is for input-type pre-images, specific to the local program instance. // LocalKeyType is for input-type pre-images, specific to the local program instance.
LocalKeyType KeyType = 1 LocalKeyType KeyType = 1
// Keccak25Key6Type is for keccak256 pre-images, for any global shared pre-images. // Keccak256KeyType is for keccak256 pre-images, for any global shared pre-images.
Keccak25Key6Type KeyType = 2 Keccak256KeyType KeyType = 2
) )
// LocalIndexKey is a key local to the program, indexing a special program input. // LocalIndexKey is a key local to the program, indexing a special program input.
...@@ -51,7 +51,7 @@ type Keccak256Key common.Hash ...@@ -51,7 +51,7 @@ type Keccak256Key common.Hash
func (k Keccak256Key) PreimageKey() (out common.Hash) { func (k Keccak256Key) PreimageKey() (out common.Hash) {
out = common.Hash(k) // copy the keccak hash out = common.Hash(k) // copy the keccak hash
out[0] = byte(Keccak25Key6Type) // apply prefix out[0] = byte(Keccak256KeyType) // apply prefix
return return
} }
......
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