Commit 316ed4b4 authored by Adrian Sutton's avatar Adrian Sutton Committed by GitHub

op-challenger: Move Proposal out of contracts (#13795)

Its only used by split adapter and isn't related to the contracts.
parent 5d52bea9
......@@ -67,11 +67,6 @@ type FaultDisputeGameContractLatest struct {
contract *batching.BoundContract
}
type Proposal struct {
L2BlockNumber *big.Int
OutputRoot common.Hash
}
// outputRootProof is designed to match the solidity OutputRootProof struct.
type outputRootProof struct {
Version [32]byte
......
......@@ -3,7 +3,6 @@ package outputs
import (
"context"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/alphabet"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/split"
......@@ -27,7 +26,7 @@ func NewOutputAlphabetTraceAccessor(
poststateBlock uint64,
) (*trace.Accessor, error) {
outputProvider := NewTraceProvider(logger, prestateProvider, rollupClient, l2Client, l1Head, splitDepth, prestateBlock, poststateBlock)
alphabetCreator := func(ctx context.Context, localContext common.Hash, depth types.Depth, agreed contracts.Proposal, claimed contracts.Proposal) (types.TraceProvider, error) {
alphabetCreator := func(ctx context.Context, localContext common.Hash, depth types.Depth, agreed utils.Proposal, claimed utils.Proposal) (types.TraceProvider, error) {
provider := alphabet.NewTraceProvider(agreed.L2BlockNumber, depth)
return provider, nil
}
......
......@@ -8,7 +8,6 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/asterisc"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/split"
......@@ -35,7 +34,7 @@ func NewOutputAsteriscTraceAccessor(
poststateBlock uint64,
) (*trace.Accessor, error) {
outputProvider := NewTraceProvider(logger, prestateProvider, rollupClient, l2Client, l1Head, splitDepth, prestateBlock, poststateBlock)
asteriscCreator := func(ctx context.Context, localContext common.Hash, depth types.Depth, agreed contracts.Proposal, claimed contracts.Proposal) (types.TraceProvider, error) {
asteriscCreator := func(ctx context.Context, localContext common.Hash, depth types.Depth, agreed utils.Proposal, claimed utils.Proposal) (types.TraceProvider, error) {
logger := logger.New("pre", agreed.OutputRoot, "post", claimed.OutputRoot, "localContext", localContext)
subdir := filepath.Join(dir, localContext.Hex())
localInputs, err := utils.FetchLocalInputsFromProposals(ctx, l1Head.Hash, l2Client, agreed, claimed)
......
......@@ -8,7 +8,6 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/cannon"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/split"
......@@ -35,7 +34,7 @@ func NewOutputCannonTraceAccessor(
poststateBlock uint64,
) (*trace.Accessor, error) {
outputProvider := NewTraceProvider(logger, prestateProvider, rollupClient, l2Client, l1Head, splitDepth, prestateBlock, poststateBlock)
cannonCreator := func(ctx context.Context, localContext common.Hash, depth types.Depth, agreed contracts.Proposal, claimed contracts.Proposal) (types.TraceProvider, error) {
cannonCreator := func(ctx context.Context, localContext common.Hash, depth types.Depth, agreed utils.Proposal, claimed utils.Proposal) (types.TraceProvider, error) {
logger := logger.New("pre", agreed.OutputRoot, "post", claimed.OutputRoot, "localContext", localContext)
subdir := filepath.Join(dir, localContext.Hex())
localInputs, err := utils.FetchLocalInputsFromProposals(ctx, l1Head.Hash, l2Client, agreed, claimed)
......
......@@ -3,7 +3,7 @@ package outputs
import (
"context"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/utils"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/types"
"github.com/ethereum-optimism/optimism/op-service/sources/caching"
"github.com/ethereum/go-ethereum/common"
......@@ -14,7 +14,7 @@ type ProviderCache struct {
creator ProposalTraceProviderCreator
}
func (c *ProviderCache) GetOrCreate(ctx context.Context, localContext common.Hash, depth types.Depth, agreed contracts.Proposal, claimed contracts.Proposal) (types.TraceProvider, error) {
func (c *ProviderCache) GetOrCreate(ctx context.Context, localContext common.Hash, depth types.Depth, agreed utils.Proposal, claimed utils.Proposal) (types.TraceProvider, error) {
provider, ok := c.cache.Get(localContext)
if ok {
return provider, nil
......
......@@ -6,8 +6,8 @@ import (
"math/big"
"testing"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/alphabet"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/utils"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/types"
"github.com/ethereum-optimism/optimism/op-challenger/metrics"
"github.com/ethereum/go-ethereum/common"
......@@ -15,17 +15,17 @@ import (
)
func TestProviderCache(t *testing.T) {
agreed := contracts.Proposal{
agreed := utils.Proposal{
L2BlockNumber: big.NewInt(34),
OutputRoot: common.Hash{0xaa},
}
claimed := contracts.Proposal{
claimed := utils.Proposal{
L2BlockNumber: big.NewInt(35),
OutputRoot: common.Hash{0xcc},
}
depth := types.Depth(6)
var createdProvider types.TraceProvider
creator := func(ctx context.Context, localContext common.Hash, depth types.Depth, agreed contracts.Proposal, claimed contracts.Proposal) (types.TraceProvider, error) {
creator := func(ctx context.Context, localContext common.Hash, depth types.Depth, agreed utils.Proposal, claimed utils.Proposal) (types.TraceProvider, error) {
createdProvider = alphabet.NewTraceProvider(big.NewInt(0), depth)
return createdProvider, nil
}
......@@ -57,20 +57,20 @@ func TestProviderCache(t *testing.T) {
func TestProviderCache_DoNotCacheErrors(t *testing.T) {
callCount := 0
providerErr := errors.New("boom")
creator := func(ctx context.Context, localContext common.Hash, depth types.Depth, agreed contracts.Proposal, claimed contracts.Proposal) (types.TraceProvider, error) {
creator := func(ctx context.Context, localContext common.Hash, depth types.Depth, agreed utils.Proposal, claimed utils.Proposal) (types.TraceProvider, error) {
callCount++
return nil, providerErr
}
localContext1 := common.Hash{0xdd}
cache := NewProviderCache(metrics.NoopMetrics, "test", creator)
provider, err := cache.GetOrCreate(context.Background(), localContext1, 6, contracts.Proposal{}, contracts.Proposal{})
provider, err := cache.GetOrCreate(context.Background(), localContext1, 6, utils.Proposal{}, utils.Proposal{})
require.Nil(t, provider)
require.ErrorIs(t, err, providerErr)
require.Equal(t, 1, callCount)
// Should call the creator again on the second attempt
provider, err = cache.GetOrCreate(context.Background(), localContext1, 6, contracts.Proposal{}, contracts.Proposal{})
provider, err = cache.GetOrCreate(context.Background(), localContext1, 6, utils.Proposal{}, utils.Proposal{})
require.Nil(t, provider)
require.ErrorIs(t, err, providerErr)
require.Equal(t, 2, callCount)
......
......@@ -5,18 +5,17 @@ import (
"fmt"
"math/big"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/split"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/utils"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/types"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
)
type ProposalTraceProviderCreator func(ctx context.Context, localContext common.Hash, depth types.Depth, agreed contracts.Proposal, claimed contracts.Proposal) (types.TraceProvider, error)
type ProposalTraceProviderCreator func(ctx context.Context, localContext common.Hash, depth types.Depth, agreed utils.Proposal, claimed utils.Proposal) (types.TraceProvider, error)
func OutputRootSplitAdapter(topProvider *OutputTraceProvider, creator ProposalTraceProviderCreator) split.ProviderCreator {
return func(ctx context.Context, depth types.Depth, pre types.Claim, post types.Claim) (types.TraceProvider, error) {
localContext := CreateLocalContext(pre, post)
localContext := split.CreateLocalContext(pre, post)
agreed, disputed, err := FetchProposals(ctx, topProvider, pre, post)
if err != nil {
return nil, err
......@@ -25,54 +24,35 @@ func OutputRootSplitAdapter(topProvider *OutputTraceProvider, creator ProposalTr
}
}
func FetchProposals(ctx context.Context, topProvider *OutputTraceProvider, pre types.Claim, post types.Claim) (contracts.Proposal, contracts.Proposal, error) {
func FetchProposals(ctx context.Context, topProvider *OutputTraceProvider, pre types.Claim, post types.Claim) (utils.Proposal, utils.Proposal, error) {
usePrestateBlock := pre == (types.Claim{})
var agreed contracts.Proposal
var agreed utils.Proposal
if usePrestateBlock {
prestateRoot, err := topProvider.AbsolutePreStateCommitment(ctx)
if err != nil {
return contracts.Proposal{}, contracts.Proposal{}, fmt.Errorf("failed to retrieve absolute prestate output root: %w", err)
return utils.Proposal{}, utils.Proposal{}, fmt.Errorf("failed to retrieve absolute prestate output root: %w", err)
}
agreed = contracts.Proposal{
agreed = utils.Proposal{
L2BlockNumber: new(big.Int).SetUint64(topProvider.prestateBlock),
OutputRoot: prestateRoot,
}
} else {
preBlockNum, err := topProvider.HonestBlockNumber(ctx, pre.Position)
if err != nil {
return contracts.Proposal{}, contracts.Proposal{}, fmt.Errorf("unable to calculate pre-claim block number: %w", err)
return utils.Proposal{}, utils.Proposal{}, fmt.Errorf("unable to calculate pre-claim block number: %w", err)
}
agreed = contracts.Proposal{
agreed = utils.Proposal{
L2BlockNumber: new(big.Int).SetUint64(preBlockNum),
OutputRoot: pre.Value,
}
}
postBlockNum, err := topProvider.ClaimedBlockNumber(post.Position)
if err != nil {
return contracts.Proposal{}, contracts.Proposal{}, fmt.Errorf("unable to calculate post-claim block number: %w", err)
return utils.Proposal{}, utils.Proposal{}, fmt.Errorf("unable to calculate post-claim block number: %w", err)
}
claimed := contracts.Proposal{
claimed := utils.Proposal{
L2BlockNumber: new(big.Int).SetUint64(postBlockNum),
OutputRoot: post.Value,
}
return agreed, claimed, nil
}
func CreateLocalContext(pre types.Claim, post types.Claim) common.Hash {
return crypto.Keccak256Hash(localContextPreimage(pre, post))
}
func localContextPreimage(pre types.Claim, post types.Claim) []byte {
encodeClaim := func(c types.Claim) []byte {
data := make([]byte, 64)
copy(data[0:32], c.Value.Bytes())
c.Position.ToGIndex().FillBytes(data[32:])
return data
}
var data []byte
if pre != (types.Claim{}) {
data = encodeClaim(pre)
}
data = append(data, encodeClaim(post)...)
return data
}
......@@ -7,8 +7,8 @@ import (
"math/big"
"testing"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/split"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/utils"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/types"
"github.com/ethereum-optimism/optimism/op-service/eth"
"github.com/ethereum-optimism/optimism/op-service/testlog"
......@@ -73,18 +73,18 @@ func TestOutputRootSplitAdapter(t *testing.T) {
ParentContractIndex: 1,
}
expectedAgreed := contracts.Proposal{
expectedAgreed := utils.Proposal{
L2BlockNumber: big.NewInt(test.expectedAgreedBlockNum),
OutputRoot: preClaim.Value,
}
expectedClaimed := contracts.Proposal{
expectedClaimed := utils.Proposal{
L2BlockNumber: big.NewInt(test.expectedClaimedBlockNum),
OutputRoot: postClaim.Value,
}
_, err := adapter(context.Background(), 5, preClaim, postClaim)
require.ErrorIs(t, err, creatorError)
require.Equal(t, CreateLocalContext(preClaim, postClaim), creator.localContext)
require.Equal(t, split.CreateLocalContext(preClaim, postClaim), creator.localContext)
require.Equal(t, expectedAgreed, creator.agreed)
require.Equal(t, expectedClaimed, creator.claimed)
})
......@@ -104,18 +104,18 @@ func TestOutputRootSplitAdapter_FromAbsolutePrestate(t *testing.T) {
ParentContractIndex: 1,
}
expectedAgreed := contracts.Proposal{
expectedAgreed := utils.Proposal{
L2BlockNumber: big.NewInt(20),
OutputRoot: prestateOutputRoot, // Absolute prestate output root
}
expectedClaimed := contracts.Proposal{
expectedClaimed := utils.Proposal{
L2BlockNumber: big.NewInt(21),
OutputRoot: postClaim.Value,
}
_, err := adapter(context.Background(), 5, types.Claim{}, postClaim)
require.ErrorIs(t, err, creatorError)
require.Equal(t, CreateLocalContext(types.Claim{}, postClaim), creator.localContext)
require.Equal(t, split.CreateLocalContext(types.Claim{}, postClaim), creator.localContext)
require.Equal(t, expectedAgreed, creator.agreed)
require.Equal(t, expectedClaimed, creator.claimed)
}
......@@ -146,11 +146,11 @@ func setupAdapterTest(t *testing.T, topDepth types.Depth) (split.ProviderCreator
type capturingCreator struct {
localContext common.Hash
agreed contracts.Proposal
claimed contracts.Proposal
agreed utils.Proposal
claimed utils.Proposal
}
func (c *capturingCreator) Create(_ context.Context, localContext common.Hash, _ types.Depth, agreed contracts.Proposal, claimed contracts.Proposal) (types.TraceProvider, error) {
func (c *capturingCreator) Create(_ context.Context, localContext common.Hash, _ types.Depth, agreed utils.Proposal, claimed utils.Proposal) (types.TraceProvider, error) {
c.localContext = localContext
c.agreed = agreed
c.claimed = claimed
......@@ -207,9 +207,9 @@ func TestCreateLocalContext(t *testing.T) {
Position: test.postPosition,
},
}
actualPreimage := localContextPreimage(pre, post)
actualPreimage := split.LocalContextPreimage(pre, post)
require.Equal(t, test.expected, actualPreimage)
localContext := CreateLocalContext(pre, post)
localContext := split.CreateLocalContext(pre, post)
require.Equal(t, crypto.Keccak256Hash(test.expected), localContext)
})
}
......
package split
import (
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/types"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
)
func CreateLocalContext(pre types.Claim, post types.Claim) common.Hash {
return crypto.Keccak256Hash(LocalContextPreimage(pre, post))
}
func LocalContextPreimage(pre types.Claim, post types.Claim) []byte {
encodeClaim := func(c types.Claim) []byte {
data := make([]byte, 64)
copy(data[0:32], c.Value.Bytes())
c.Position.ToGIndex().FillBytes(data[32:])
return data
}
var data []byte
if pre != (types.Claim{}) {
data = encodeClaim(pre)
}
data = append(data, encodeClaim(post)...)
return data
}
......@@ -5,7 +5,6 @@ import (
"fmt"
"math/big"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts"
"github.com/ethereum/go-ethereum/common"
ethtypes "github.com/ethereum/go-ethereum/core/types"
)
......@@ -28,7 +27,12 @@ type L1HeadSource interface {
type GameInputsSource interface {
L1HeadSource
GetProposals(ctx context.Context) (agreed contracts.Proposal, disputed contracts.Proposal, err error)
GetProposals(ctx context.Context) (agreed Proposal, disputed Proposal, err error)
}
type Proposal struct {
L2BlockNumber *big.Int
OutputRoot common.Hash
}
func FetchLocalInputs(ctx context.Context, caller GameInputsSource, l2Client L2HeaderSource) (LocalGameInputs, error) {
......@@ -44,7 +48,7 @@ func FetchLocalInputs(ctx context.Context, caller GameInputsSource, l2Client L2H
return FetchLocalInputsFromProposals(ctx, l1Head, l2Client, agreedOutput, claimedOutput)
}
func FetchLocalInputsFromProposals(ctx context.Context, l1Head common.Hash, l2Client L2HeaderSource, agreedOutput contracts.Proposal, claimedOutput contracts.Proposal) (LocalGameInputs, error) {
func FetchLocalInputsFromProposals(ctx context.Context, l1Head common.Hash, l2Client L2HeaderSource, agreedOutput Proposal, claimedOutput Proposal) (LocalGameInputs, error) {
agreedHeader, err := l2Client.HeaderByNumber(ctx, agreedOutput.L2BlockNumber)
if err != nil {
return LocalGameInputs{}, fmt.Errorf("fetch L2 block header %v: %w", agreedOutput.L2BlockNumber, err)
......
......@@ -5,7 +5,6 @@ import (
"math/big"
"testing"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts"
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/common"
ethtypes "github.com/ethereum/go-ethereum/core/types"
......@@ -16,11 +15,11 @@ func TestFetchLocalInputs(t *testing.T) {
ctx := context.Background()
contract := &mockGameInputsSource{
l1Head: common.Hash{0xcc},
starting: contracts.Proposal{
starting: Proposal{
L2BlockNumber: big.NewInt(2222),
OutputRoot: common.Hash{0xdd},
},
disputed: contracts.Proposal{
disputed: Proposal{
L2BlockNumber: big.NewInt(3333),
OutputRoot: common.Hash{0xee},
},
......@@ -44,11 +43,11 @@ func TestFetchLocalInputs(t *testing.T) {
func TestFetchLocalInputsFromProposals(t *testing.T) {
ctx := context.Background()
agreed := contracts.Proposal{
agreed := Proposal{
L2BlockNumber: big.NewInt(2222),
OutputRoot: common.Hash{0xdd},
}
claimed := contracts.Proposal{
claimed := Proposal{
L2BlockNumber: big.NewInt(3333),
OutputRoot: common.Hash{0xee},
}
......@@ -72,15 +71,15 @@ func TestFetchLocalInputsFromProposals(t *testing.T) {
type mockGameInputsSource struct {
l1Head common.Hash
starting contracts.Proposal
disputed contracts.Proposal
starting Proposal
disputed Proposal
}
func (s *mockGameInputsSource) GetL1Head(_ context.Context) (common.Hash, error) {
return s.l1Head, nil
}
func (s *mockGameInputsSource) GetProposals(_ context.Context) (contracts.Proposal, contracts.Proposal, error) {
func (s *mockGameInputsSource) GetProposals(_ context.Context) (Proposal, Proposal, error) {
return s.starting, s.disputed, nil
}
......
......@@ -314,7 +314,7 @@ func (g *OutputCannonGameHelper) createCannonTraceProvider(ctx context.Context,
g.T.Logf("Using trace between blocks %v and %v\n", agreed.L2BlockNumber, disputed.L2BlockNumber)
localInputs, err := utils.FetchLocalInputsFromProposals(ctx, l1Head.Hash, l2Client, agreed, disputed)
g.Require.NoError(err, "Failed to fetch local inputs")
localContext = outputs.CreateLocalContext(pre, post)
localContext = split.CreateLocalContext(pre, post)
dir := filepath.Join(cfg.Datadir, "cannon-trace")
subdir := filepath.Join(dir, localContext.Hex())
return cannon.NewTraceProviderForTest(logger, metrics.NoopMetrics.ToTypedVmMetrics(types.TraceTypeCannon.String()), cfg, localInputs, subdir, g.MaxDepth(ctx)-splitDepth-1), nil
......
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