Commit ac443ef0 authored by Adrian Sutton's avatar Adrian Sutton Committed by GitHub

op-e2e: Separate helpers for proofs action tests into a new package (#11920)

* op-e2e: Move action test helpers for proofs to a separate package.

* op-e2e: Use helpers package under proofs rather than a completely separate package tree for helpers.
parent 92ed64e1
...@@ -4,6 +4,7 @@ import ( ...@@ -4,6 +4,7 @@ import (
"testing" "testing"
"github.com/ethereum-optimism/optimism/op-e2e/actions" "github.com/ethereum-optimism/optimism/op-e2e/actions"
"github.com/ethereum-optimism/optimism/op-e2e/actions/proofs/helpers"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils"
"github.com/ethereum-optimism/optimism/op-program/client/claim" "github.com/ethereum-optimism/optimism/op-program/client/claim"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
...@@ -19,58 +20,58 @@ import ( ...@@ -19,58 +20,58 @@ import (
// 4. Submit the channel frame data across 2 transactions. // 4. Submit the channel frame data across 2 transactions.
// 5. Instruct the sequencer to derive the L2 chain. // 5. Instruct the sequencer to derive the L2 chain.
// 6. Run the FPP on the safe head. // 6. Run the FPP on the safe head.
func runChannelTimeoutTest(gt *testing.T, testCfg *TestCfg[any]) { func runChannelTimeoutTest(gt *testing.T, testCfg *helpers.TestCfg[any]) {
t := actions.NewDefaultTesting(gt) t := actions.NewDefaultTesting(gt)
tp := NewTestParams(func(tp *e2eutils.TestParams) { tp := helpers.NewTestParams(func(tp *e2eutils.TestParams) {
// Set the channel timeout to 10 blocks, 12x lower than the sequencing window. // Set the channel timeout to 10 blocks, 12x lower than the sequencing window.
tp.ChannelTimeout = 10 tp.ChannelTimeout = 10
}) })
env := NewL2FaultProofEnv(t, testCfg, tp, NewBatcherCfg()) env := helpers.NewL2FaultProofEnv(t, testCfg, tp, helpers.NewBatcherCfg())
const NumL2Blocks = 10 const NumL2Blocks = 10
// Build NumL2Blocks empty blocks on L2 // Build NumL2Blocks empty blocks on L2
for i := 0; i < NumL2Blocks; i++ { for i := 0; i < NumL2Blocks; i++ {
env.sequencer.ActL2StartBlock(t) env.Sequencer.ActL2StartBlock(t)
env.sequencer.ActL2EndBlock(t) env.Sequencer.ActL2EndBlock(t)
} }
// Buffer the first half of L2 blocks in the batcher, and submit it. // Buffer the first half of L2 blocks in the batcher, and submit it.
for i := 0; i < NumL2Blocks/2; i++ { for i := 0; i < NumL2Blocks/2; i++ {
env.batcher.ActL2BatchBuffer(t) env.Batcher.ActL2BatchBuffer(t)
} }
env.batcher.ActL2BatchSubmit(t) env.Batcher.ActL2BatchSubmit(t)
// Instruct the batcher to submit the first channel frame to L1, and include the transaction. // Instruct the batcher to submit the first channel frame to L1, and include the transaction.
env.miner.ActL1StartBlock(12)(t) env.Miner.ActL1StartBlock(12)(t)
env.miner.ActL1IncludeTxByHash(env.batcher.LastSubmitted.Hash())(t) env.Miner.ActL1IncludeTxByHash(env.Batcher.LastSubmitted.Hash())(t)
env.miner.ActL1EndBlock(t) env.Miner.ActL1EndBlock(t)
// Finalize the block with the first channel frame on L1. // Finalize the block with the first channel frame on L1.
env.miner.ActL1SafeNext(t) env.Miner.ActL1SafeNext(t)
env.miner.ActL1FinalizeNext(t) env.Miner.ActL1FinalizeNext(t)
// Instruct the sequencer to derive the L2 chain from the data on L1 that the batcher just posted. // Instruct the sequencer to derive the L2 chain from the data on L1 that the batcher just posted.
env.sequencer.ActL1HeadSignal(t) env.Sequencer.ActL1HeadSignal(t)
env.sequencer.ActL2PipelineFull(t) env.Sequencer.ActL2PipelineFull(t)
// Ensure that the safe head has not advanced - the channel is incomplete. // Ensure that the safe head has not advanced - the channel is incomplete.
l2SafeHead := env.engine.L2Chain().CurrentSafeBlock() l2SafeHead := env.Engine.L2Chain().CurrentSafeBlock()
require.Equal(t, uint64(0), l2SafeHead.Number.Uint64()) require.Equal(t, uint64(0), l2SafeHead.Number.Uint64())
// Time out the channel by mining `ChannelTimeout + 1` empty blocks on L1. // Time out the channel by mining `ChannelTimeout + 1` empty blocks on L1.
for i := uint64(0); i < tp.ChannelTimeout+1; i++ { for i := uint64(0); i < tp.ChannelTimeout+1; i++ {
env.miner.ActEmptyBlock(t) env.Miner.ActEmptyBlock(t)
env.miner.ActL1SafeNext(t) env.Miner.ActL1SafeNext(t)
env.miner.ActL1FinalizeNext(t) env.Miner.ActL1FinalizeNext(t)
} }
// Instruct the sequencer to derive the L2 chain - the channel should now be timed out. // Instruct the sequencer to derive the L2 chain - the channel should now be timed out.
env.sequencer.ActL1HeadSignal(t) env.Sequencer.ActL1HeadSignal(t)
env.sequencer.ActL2PipelineFull(t) env.Sequencer.ActL2PipelineFull(t)
// Ensure the safe head has still not advanced. // Ensure the safe head has still not advanced.
l2SafeHead = env.engine.L2Chain().CurrentSafeBlock() l2SafeHead = env.Engine.L2Chain().CurrentSafeBlock()
require.Equal(t, uint64(0), l2SafeHead.Number.Uint64()) require.Equal(t, uint64(0), l2SafeHead.Number.Uint64())
// Instruct the batcher to submit the blocks to L1 in a new channel, // Instruct the batcher to submit the blocks to L1 in a new channel,
...@@ -78,30 +79,30 @@ func runChannelTimeoutTest(gt *testing.T, testCfg *TestCfg[any]) { ...@@ -78,30 +79,30 @@ func runChannelTimeoutTest(gt *testing.T, testCfg *TestCfg[any]) {
for i := 0; i < 2; i++ { for i := 0; i < 2; i++ {
// Buffer half of the L2 chain's blocks. // Buffer half of the L2 chain's blocks.
for j := 0; j < NumL2Blocks/2; j++ { for j := 0; j < NumL2Blocks/2; j++ {
env.batcher.ActL2BatchBuffer(t) env.Batcher.ActL2BatchBuffer(t)
} }
// Close the channel on the second iteration. // Close the channel on the second iteration.
if i == 1 { if i == 1 {
env.batcher.ActL2ChannelClose(t) env.Batcher.ActL2ChannelClose(t)
} }
env.batcher.ActL2BatchSubmit(t) env.Batcher.ActL2BatchSubmit(t)
env.miner.ActL1StartBlock(12)(t) env.Miner.ActL1StartBlock(12)(t)
env.miner.ActL1IncludeTxByHash(env.batcher.LastSubmitted.Hash())(t) env.Miner.ActL1IncludeTxByHash(env.Batcher.LastSubmitted.Hash())(t)
env.miner.ActL1EndBlock(t) env.Miner.ActL1EndBlock(t)
// Finalize the block with the frame data on L1. // Finalize the block with the frame data on L1.
env.miner.ActL1SafeNext(t) env.Miner.ActL1SafeNext(t)
env.miner.ActL1FinalizeNext(t) env.Miner.ActL1FinalizeNext(t)
} }
// Instruct the sequencer to derive the L2 chain. // Instruct the sequencer to derive the L2 chain.
env.sequencer.ActL1HeadSignal(t) env.Sequencer.ActL1HeadSignal(t)
env.sequencer.ActL2PipelineFull(t) env.Sequencer.ActL2PipelineFull(t)
// Ensure the safe head has still advanced to L2 block # NumL2Blocks. // Ensure the safe head has still advanced to L2 block # NumL2Blocks.
l2SafeHead = env.engine.L2Chain().CurrentSafeBlock() l2SafeHead = env.Engine.L2Chain().CurrentSafeBlock()
require.EqualValues(t, NumL2Blocks, l2SafeHead.Number.Uint64()) require.EqualValues(t, NumL2Blocks, l2SafeHead.Number.Uint64())
// Run the FPP on L2 block # NumL2Blocks/2. // Run the FPP on L2 block # NumL2Blocks/2.
...@@ -109,22 +110,22 @@ func runChannelTimeoutTest(gt *testing.T, testCfg *TestCfg[any]) { ...@@ -109,22 +110,22 @@ func runChannelTimeoutTest(gt *testing.T, testCfg *TestCfg[any]) {
} }
func Test_ProgramAction_ChannelTimeout(gt *testing.T) { func Test_ProgramAction_ChannelTimeout(gt *testing.T) {
matrix := NewMatrix[any]() matrix := helpers.NewMatrix[any]()
defer matrix.Run(gt) defer matrix.Run(gt)
matrix.AddTestCase( matrix.AddTestCase(
"HonestClaim", "HonestClaim",
nil, nil,
LatestForkOnly, helpers.LatestForkOnly,
runChannelTimeoutTest, runChannelTimeoutTest,
ExpectNoError(), helpers.ExpectNoError(),
) )
matrix.AddTestCase( matrix.AddTestCase(
"JunkClaim", "JunkClaim",
nil, nil,
LatestForkOnly, helpers.LatestForkOnly,
runChannelTimeoutTest, runChannelTimeoutTest,
ExpectError(claim.ErrClaimNotValid), helpers.ExpectError(claim.ErrClaimNotValid),
WithL2Claim(common.HexToHash("0xdeadbeef")), helpers.WithL2Claim(common.HexToHash("0xdeadbeef")),
) )
} }
...@@ -5,6 +5,7 @@ import ( ...@@ -5,6 +5,7 @@ import (
"testing" "testing"
"github.com/ethereum-optimism/optimism/op-e2e/actions" "github.com/ethereum-optimism/optimism/op-e2e/actions"
"github.com/ethereum-optimism/optimism/op-e2e/actions/proofs/helpers"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils"
"github.com/ethereum-optimism/optimism/op-program/client/claim" "github.com/ethereum-optimism/optimism/op-program/client/claim"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
...@@ -25,73 +26,73 @@ var garbageKinds = []actions.GarbageKind{ ...@@ -25,73 +26,73 @@ var garbageKinds = []actions.GarbageKind{
// //
// channel format ([]Frame): // channel format ([]Frame):
// [f[0 - correct] f_x[1 - bad frame] f[1 - correct]] // [f[0 - correct] f_x[1 - bad frame] f[1 - correct]]
func runGarbageChannelTest(gt *testing.T, testCfg *TestCfg[actions.GarbageKind]) { func runGarbageChannelTest(gt *testing.T, testCfg *helpers.TestCfg[actions.GarbageKind]) {
t := actions.NewDefaultTesting(gt) t := actions.NewDefaultTesting(gt)
tp := NewTestParams(func(tp *e2eutils.TestParams) { tp := helpers.NewTestParams(func(tp *e2eutils.TestParams) {
// Set the channel timeout to 10 blocks, 12x lower than the sequencing window. // Set the channel timeout to 10 blocks, 12x lower than the sequencing window.
tp.ChannelTimeout = 10 tp.ChannelTimeout = 10
}) })
env := NewL2FaultProofEnv(t, testCfg, tp, NewBatcherCfg()) env := helpers.NewL2FaultProofEnv(t, testCfg, tp, helpers.NewBatcherCfg())
includeBatchTx := func(env *L2FaultProofEnv) { includeBatchTx := func(env *helpers.L2FaultProofEnv) {
// Instruct the batcher to submit the first channel frame to L1, and include the transaction. // Instruct the batcher to submit the first channel frame to L1, and include the transaction.
env.miner.ActL1StartBlock(12)(t) env.Miner.ActL1StartBlock(12)(t)
env.miner.ActL1IncludeTxByHash(env.batcher.LastSubmitted.Hash())(t) env.Miner.ActL1IncludeTxByHash(env.Batcher.LastSubmitted.Hash())(t)
env.miner.ActL1EndBlock(t) env.Miner.ActL1EndBlock(t)
// Finalize the block with the first channel frame on L1. // Finalize the block with the first channel frame on L1.
env.miner.ActL1SafeNext(t) env.Miner.ActL1SafeNext(t)
env.miner.ActL1FinalizeNext(t) env.Miner.ActL1FinalizeNext(t)
// Instruct the sequencer to derive the L2 chain from the data on L1 that the batcher just posted. // Instruct the sequencer to derive the L2 chain from the data on L1 that the batcher just posted.
env.sequencer.ActL1HeadSignal(t) env.Sequencer.ActL1HeadSignal(t)
env.sequencer.ActL2PipelineFull(t) env.Sequencer.ActL2PipelineFull(t)
} }
const NumL2Blocks = 10 const NumL2Blocks = 10
// Build NumL2Blocks empty blocks on L2 // Build NumL2Blocks empty blocks on L2
for i := 0; i < NumL2Blocks; i++ { for i := 0; i < NumL2Blocks; i++ {
env.sequencer.ActL2StartBlock(t) env.Sequencer.ActL2StartBlock(t)
env.sequencer.ActL2EndBlock(t) env.Sequencer.ActL2EndBlock(t)
} }
// Buffer the first half of L2 blocks in the batcher, and submit it. // Buffer the first half of L2 blocks in the batcher, and submit it.
for i := 0; i < NumL2Blocks/2; i++ { for i := 0; i < NumL2Blocks/2; i++ {
env.batcher.ActL2BatchBuffer(t) env.Batcher.ActL2BatchBuffer(t)
} }
env.batcher.ActL2BatchSubmit(t) env.Batcher.ActL2BatchSubmit(t)
// Include the batcher transaction. // Include the batcher transaction.
includeBatchTx(env) includeBatchTx(env)
// Ensure that the safe head has not advanced - the channel is incomplete. // Ensure that the safe head has not advanced - the channel is incomplete.
l2SafeHead := env.engine.L2Chain().CurrentSafeBlock() l2SafeHead := env.Engine.L2Chain().CurrentSafeBlock()
require.Equal(t, uint64(0), l2SafeHead.Number.Uint64()) require.Equal(t, uint64(0), l2SafeHead.Number.Uint64())
// Buffer the second half of L2 blocks in the batcher. // Buffer the second half of L2 blocks in the batcher.
for i := 0; i < NumL2Blocks/2; i++ { for i := 0; i < NumL2Blocks/2; i++ {
env.batcher.ActL2BatchBuffer(t) env.Batcher.ActL2BatchBuffer(t)
} }
env.batcher.ActL2ChannelClose(t) env.Batcher.ActL2ChannelClose(t)
expectedSecondFrame := env.batcher.ReadNextOutputFrame(t) expectedSecondFrame := env.Batcher.ReadNextOutputFrame(t)
// Submit a garbage frame, modified from the expected second frame. // Submit a garbage frame, modified from the expected second frame.
env.batcher.ActL2BatchSubmitGarbageRaw(t, expectedSecondFrame, testCfg.Custom) env.Batcher.ActL2BatchSubmitGarbageRaw(t, expectedSecondFrame, testCfg.Custom)
// Include the garbage second frame tx // Include the garbage second frame tx
includeBatchTx(env) includeBatchTx(env)
// Ensure that the safe head has not advanced - the channel is incomplete. // Ensure that the safe head has not advanced - the channel is incomplete.
l2SafeHead = env.engine.L2Chain().CurrentSafeBlock() l2SafeHead = env.Engine.L2Chain().CurrentSafeBlock()
require.Equal(t, uint64(0), l2SafeHead.Number.Uint64()) require.Equal(t, uint64(0), l2SafeHead.Number.Uint64())
// Submit the correct second frame. // Submit the correct second frame.
env.batcher.ActL2BatchSubmitRaw(t, expectedSecondFrame) env.Batcher.ActL2BatchSubmitRaw(t, expectedSecondFrame)
// Include the corract second frame tx. // Include the corract second frame tx.
includeBatchTx(env) includeBatchTx(env)
// Ensure that the safe head has advanced - the channel is complete. // Ensure that the safe head has advanced - the channel is complete.
l2SafeHead = env.engine.L2Chain().CurrentSafeBlock() l2SafeHead = env.Engine.L2Chain().CurrentSafeBlock()
require.Equal(t, uint64(NumL2Blocks), l2SafeHead.Number.Uint64()) require.Equal(t, uint64(NumL2Blocks), l2SafeHead.Number.Uint64())
// Run the FPP on L2 block # NumL2Blocks. // Run the FPP on L2 block # NumL2Blocks.
...@@ -99,24 +100,24 @@ func runGarbageChannelTest(gt *testing.T, testCfg *TestCfg[actions.GarbageKind]) ...@@ -99,24 +100,24 @@ func runGarbageChannelTest(gt *testing.T, testCfg *TestCfg[actions.GarbageKind])
} }
func Test_ProgramAction_GarbageChannel(gt *testing.T) { func Test_ProgramAction_GarbageChannel(gt *testing.T) {
matrix := NewMatrix[actions.GarbageKind]() matrix := helpers.NewMatrix[actions.GarbageKind]()
defer matrix.Run(gt) defer matrix.Run(gt)
for _, garbageKind := range garbageKinds { for _, garbageKind := range garbageKinds {
matrix.AddTestCase( matrix.AddTestCase(
fmt.Sprintf("HonestClaim-%s", garbageKind.String()), fmt.Sprintf("HonestClaim-%s", garbageKind.String()),
garbageKind, garbageKind,
LatestForkOnly, helpers.LatestForkOnly,
runGarbageChannelTest, runGarbageChannelTest,
ExpectNoError(), helpers.ExpectNoError(),
) )
matrix.AddTestCase( matrix.AddTestCase(
fmt.Sprintf("JunkClaim-%s", garbageKind.String()), fmt.Sprintf("JunkClaim-%s", garbageKind.String()),
garbageKind, garbageKind,
LatestForkOnly, helpers.LatestForkOnly,
runGarbageChannelTest, runGarbageChannelTest,
ExpectError(claim.ErrClaimNotValid), helpers.ExpectError(claim.ErrClaimNotValid),
WithL2Claim(common.HexToHash("0xdeadbeef")), helpers.WithL2Claim(common.HexToHash("0xdeadbeef")),
) )
} }
} }
package proofs package helpers
import ( import (
"context" "context"
...@@ -25,14 +25,14 @@ import ( ...@@ -25,14 +25,14 @@ import (
// L2FaultProofEnv is a test harness for a fault provable L2 chain. // L2FaultProofEnv is a test harness for a fault provable L2 chain.
type L2FaultProofEnv struct { type L2FaultProofEnv struct {
log log.Logger log log.Logger
batcher *actions.L2Batcher Batcher *actions.L2Batcher
sequencer *actions.L2Sequencer Sequencer *actions.L2Sequencer
engine *actions.L2Engine Engine *actions.L2Engine
engCl *sources.EngineClient engCl *sources.EngineClient
sd *e2eutils.SetupData sd *e2eutils.SetupData
dp *e2eutils.DeployParams dp *e2eutils.DeployParams
miner *actions.L1Miner Miner *actions.L1Miner
alice *actions.CrossLayerUser Alice *actions.CrossLayerUser
} }
func NewL2FaultProofEnv[c any](t actions.Testing, testCfg *TestCfg[c], tp *e2eutils.TestParams, batcherCfg *actions.BatcherCfg) *L2FaultProofEnv { func NewL2FaultProofEnv[c any](t actions.Testing, testCfg *TestCfg[c], tp *e2eutils.TestParams, batcherCfg *actions.BatcherCfg) *L2FaultProofEnv {
...@@ -102,14 +102,14 @@ func NewL2FaultProofEnv[c any](t actions.Testing, testCfg *TestCfg[c], tp *e2eut ...@@ -102,14 +102,14 @@ func NewL2FaultProofEnv[c any](t actions.Testing, testCfg *TestCfg[c], tp *e2eut
return &L2FaultProofEnv{ return &L2FaultProofEnv{
log: log, log: log,
batcher: batcher, Batcher: batcher,
sequencer: sequencer, Sequencer: sequencer,
engine: engine, Engine: engine,
engCl: engCl, engCl: engCl,
sd: sd, sd: sd,
dp: dp, dp: dp,
miner: miner, Miner: miner,
alice: alice, Alice: alice,
} }
} }
...@@ -137,11 +137,11 @@ func WithL2Claim(claim common.Hash) FixtureInputParam { ...@@ -137,11 +137,11 @@ func WithL2Claim(claim common.Hash) FixtureInputParam {
func (env *L2FaultProofEnv) RunFaultProofProgram(t actions.Testing, l2ClaimBlockNum uint64, checkResult CheckResult, fixtureInputParams ...FixtureInputParam) { func (env *L2FaultProofEnv) RunFaultProofProgram(t actions.Testing, l2ClaimBlockNum uint64, checkResult CheckResult, fixtureInputParams ...FixtureInputParam) {
// Fetch the pre and post output roots for the fault proof. // Fetch the pre and post output roots for the fault proof.
preRoot, err := env.sequencer.RollupClient().OutputAtBlock(t.Ctx(), l2ClaimBlockNum-1) preRoot, err := env.Sequencer.RollupClient().OutputAtBlock(t.Ctx(), l2ClaimBlockNum-1)
require.NoError(t, err) require.NoError(t, err)
claimRoot, err := env.sequencer.RollupClient().OutputAtBlock(t.Ctx(), l2ClaimBlockNum) claimRoot, err := env.Sequencer.RollupClient().OutputAtBlock(t.Ctx(), l2ClaimBlockNum)
require.NoError(t, err) require.NoError(t, err)
l1Head := env.miner.L1Chain().CurrentBlock() l1Head := env.Miner.L1Chain().CurrentBlock()
fixtureInputs := &FixtureInputs{ fixtureInputs := &FixtureInputs{
L2BlockNumber: l2ClaimBlockNum, L2BlockNumber: l2ClaimBlockNum,
...@@ -163,12 +163,12 @@ func (env *L2FaultProofEnv) RunFaultProofProgram(t actions.Testing, l2ClaimBlock ...@@ -163,12 +163,12 @@ func (env *L2FaultProofEnv) RunFaultProofProgram(t actions.Testing, l2ClaimBlock
) )
withInProcessPrefetcher := host.WithPrefetcher(func(ctx context.Context, logger log.Logger, kv kvstore.KV, cfg *config.Config) (host.Prefetcher, error) { withInProcessPrefetcher := host.WithPrefetcher(func(ctx context.Context, logger log.Logger, kv kvstore.KV, cfg *config.Config) (host.Prefetcher, error) {
// Set up in-process L1 sources // Set up in-process L1 sources
l1Cl := env.miner.L1Client(t, env.sd.RollupCfg) l1Cl := env.Miner.L1Client(t, env.sd.RollupCfg)
l1BlobFetcher := env.miner.BlobStore() l1BlobFetcher := env.Miner.BlobStore()
// Set up in-process L2 source // Set up in-process L2 source
l2ClCfg := sources.L2ClientDefaultConfig(env.sd.RollupCfg, true) l2ClCfg := sources.L2ClientDefaultConfig(env.sd.RollupCfg, true)
l2RPC := env.engine.RPCClient() l2RPC := env.Engine.RPCClient()
l2Client, err := host.NewL2Client(l2RPC, env.log, nil, &host.L2ClientConfig{L2ClientConfig: l2ClCfg, L2Head: cfg.L2Head}) l2Client, err := host.NewL2Client(l2RPC, env.log, nil, &host.L2ClientConfig{L2ClientConfig: l2ClCfg, L2Head: cfg.L2Head})
require.NoError(t, err, "failed to create L2 client") require.NoError(t, err, "failed to create L2 client")
l2DebugCl := &host.L2Source{L2Client: l2Client, DebugClient: sources.NewDebugClient(l2RPC.CallContext)} l2DebugCl := &host.L2Source{L2Client: l2Client, DebugClient: sources.NewDebugClient(l2RPC.CallContext)}
......
package proofs package helpers
import ( import (
"encoding/json" "encoding/json"
......
package proofs package helpers
import ( import (
"fmt" "fmt"
......
...@@ -4,42 +4,43 @@ import ( ...@@ -4,42 +4,43 @@ import (
"testing" "testing"
"github.com/ethereum-optimism/optimism/op-e2e/actions" "github.com/ethereum-optimism/optimism/op-e2e/actions"
"github.com/ethereum-optimism/optimism/op-e2e/actions/proofs/helpers"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
// Run a test that proves a deposit-only block generated due to sequence window expiry. // Run a test that proves a deposit-only block generated due to sequence window expiry.
func runSequenceWindowExpireTest(gt *testing.T, testCfg *TestCfg[any]) { func runSequenceWindowExpireTest(gt *testing.T, testCfg *helpers.TestCfg[any]) {
t := actions.NewDefaultTesting(gt) t := actions.NewDefaultTesting(gt)
tp := NewTestParams() tp := helpers.NewTestParams()
env := NewL2FaultProofEnv(t, testCfg, tp, NewBatcherCfg()) env := helpers.NewL2FaultProofEnv(t, testCfg, tp, helpers.NewBatcherCfg())
// Mine an empty block for gas estimation purposes. // Mine an empty block for gas estimation purposes.
env.miner.ActEmptyBlock(t) env.Miner.ActEmptyBlock(t)
// Expire the sequence window by building `SequenceWindow + 1` empty blocks on L1. // Expire the sequence window by building `SequenceWindow + 1` empty blocks on L1.
for i := 0; i < int(tp.SequencerWindowSize)+1; i++ { for i := 0; i < int(tp.SequencerWindowSize)+1; i++ {
env.alice.L1.ActResetTxOpts(t) env.Alice.L1.ActResetTxOpts(t)
env.alice.ActDeposit(t) env.Alice.ActDeposit(t)
env.miner.ActL1StartBlock(12)(t) env.Miner.ActL1StartBlock(12)(t)
env.miner.ActL1IncludeTx(env.alice.Address())(t) env.Miner.ActL1IncludeTx(env.Alice.Address())(t)
env.miner.ActL1EndBlock(t) env.Miner.ActL1EndBlock(t)
env.miner.ActL1SafeNext(t) env.Miner.ActL1SafeNext(t)
env.miner.ActL1FinalizeNext(t) env.Miner.ActL1FinalizeNext(t)
} }
// Ensure the safe head is still 0. // Ensure the safe head is still 0.
l2SafeHead := env.engine.L2Chain().CurrentSafeBlock() l2SafeHead := env.Engine.L2Chain().CurrentSafeBlock()
require.EqualValues(t, 0, l2SafeHead.Number.Uint64()) require.EqualValues(t, 0, l2SafeHead.Number.Uint64())
// Ask the sequencer to derive the deposit-only L2 chain. // Ask the sequencer to derive the deposit-only L2 chain.
env.sequencer.ActL1HeadSignal(t) env.Sequencer.ActL1HeadSignal(t)
env.sequencer.ActL2PipelineFull(t) env.Sequencer.ActL2PipelineFull(t)
// Ensure the safe head advanced forcefully. // Ensure the safe head advanced forcefully.
l2SafeHead = env.engine.L2Chain().CurrentSafeBlock() l2SafeHead = env.Engine.L2Chain().CurrentSafeBlock()
require.Greater(t, l2SafeHead.Number.Uint64(), uint64(0)) require.Greater(t, l2SafeHead.Number.Uint64(), uint64(0))
// Run the FPP on one of the auto-derived blocks. // Run the FPP on one of the auto-derived blocks.
...@@ -47,22 +48,22 @@ func runSequenceWindowExpireTest(gt *testing.T, testCfg *TestCfg[any]) { ...@@ -47,22 +48,22 @@ func runSequenceWindowExpireTest(gt *testing.T, testCfg *TestCfg[any]) {
} }
func Test_ProgramAction_SequenceWindowExpired(gt *testing.T) { func Test_ProgramAction_SequenceWindowExpired(gt *testing.T) {
matrix := NewMatrix[any]() matrix := helpers.NewMatrix[any]()
defer matrix.Run(gt) defer matrix.Run(gt)
matrix.AddTestCase( matrix.AddTestCase(
"HonestClaim", "HonestClaim",
nil, nil,
LatestForkOnly, helpers.LatestForkOnly,
runSequenceWindowExpireTest, runSequenceWindowExpireTest,
ExpectNoError(), helpers.ExpectNoError(),
) )
matrix.AddTestCase( matrix.AddTestCase(
"JunkClaim", "JunkClaim",
nil, nil,
LatestForkOnly, helpers.LatestForkOnly,
runSequenceWindowExpireTest, runSequenceWindowExpireTest,
ExpectNoError(), helpers.ExpectNoError(),
WithL2Claim(common.HexToHash("0xdeadbeef")), helpers.WithL2Claim(common.HexToHash("0xdeadbeef")),
) )
} }
...@@ -4,35 +4,36 @@ import ( ...@@ -4,35 +4,36 @@ import (
"testing" "testing"
"github.com/ethereum-optimism/optimism/op-e2e/actions" "github.com/ethereum-optimism/optimism/op-e2e/actions"
"github.com/ethereum-optimism/optimism/op-e2e/actions/proofs/helpers"
"github.com/ethereum-optimism/optimism/op-program/client/claim" "github.com/ethereum-optimism/optimism/op-program/client/claim"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
func runSimpleProgramTest(gt *testing.T, testCfg *TestCfg[any]) { func runSimpleProgramTest(gt *testing.T, testCfg *helpers.TestCfg[any]) {
t := actions.NewDefaultTesting(gt) t := actions.NewDefaultTesting(gt)
env := NewL2FaultProofEnv(t, testCfg, NewTestParams(), NewBatcherCfg()) env := helpers.NewL2FaultProofEnv(t, testCfg, helpers.NewTestParams(), helpers.NewBatcherCfg())
// Build an empty block on L2 // Build an empty block on L2
env.sequencer.ActL2StartBlock(t) env.Sequencer.ActL2StartBlock(t)
env.sequencer.ActL2EndBlock(t) env.Sequencer.ActL2EndBlock(t)
// Instruct the batcher to submit the block to L1, and include the transaction. // Instruct the batcher to submit the block to L1, and include the transaction.
env.batcher.ActSubmitAll(t) env.Batcher.ActSubmitAll(t)
env.miner.ActL1StartBlock(12)(t) env.Miner.ActL1StartBlock(12)(t)
env.miner.ActL1IncludeTxByHash(env.batcher.LastSubmitted.Hash())(t) env.Miner.ActL1IncludeTxByHash(env.Batcher.LastSubmitted.Hash())(t)
env.miner.ActL1EndBlock(t) env.Miner.ActL1EndBlock(t)
// Finalize the block with the batch on L1. // Finalize the block with the batch on L1.
env.miner.ActL1SafeNext(t) env.Miner.ActL1SafeNext(t)
env.miner.ActL1FinalizeNext(t) env.Miner.ActL1FinalizeNext(t)
// Instruct the sequencer to derive the L2 chain from the data on L1 that the batcher just posted. // Instruct the sequencer to derive the L2 chain from the data on L1 that the batcher just posted.
env.sequencer.ActL1HeadSignal(t) env.Sequencer.ActL1HeadSignal(t)
env.sequencer.ActL2PipelineFull(t) env.Sequencer.ActL2PipelineFull(t)
l1Head := env.miner.L1Chain().CurrentBlock() l1Head := env.Miner.L1Chain().CurrentBlock()
l2SafeHead := env.engine.L2Chain().CurrentSafeBlock() l2SafeHead := env.Engine.L2Chain().CurrentSafeBlock()
// Ensure there is only 1 block on L1. // Ensure there is only 1 block on L1.
require.Equal(t, uint64(1), l1Head.Number.Uint64()) require.Equal(t, uint64(1), l1Head.Number.Uint64())
...@@ -43,22 +44,22 @@ func runSimpleProgramTest(gt *testing.T, testCfg *TestCfg[any]) { ...@@ -43,22 +44,22 @@ func runSimpleProgramTest(gt *testing.T, testCfg *TestCfg[any]) {
} }
func Test_ProgramAction_SimpleEmptyChain(gt *testing.T) { func Test_ProgramAction_SimpleEmptyChain(gt *testing.T) {
matrix := NewMatrix[any]() matrix := helpers.NewMatrix[any]()
defer matrix.Run(gt) defer matrix.Run(gt)
matrix.AddTestCase( matrix.AddTestCase(
"HonestClaim", "HonestClaim",
nil, nil,
LatestForkOnly, helpers.LatestForkOnly,
runSimpleProgramTest, runSimpleProgramTest,
ExpectNoError(), helpers.ExpectNoError(),
) )
matrix.AddTestCase( matrix.AddTestCase(
"JunkClaim", "JunkClaim",
nil, nil,
LatestForkOnly, helpers.LatestForkOnly,
runSimpleProgramTest, runSimpleProgramTest,
ExpectError(claim.ErrClaimNotValid), helpers.ExpectError(claim.ErrClaimNotValid),
WithL2Claim(common.HexToHash("0xdeadbeef")), helpers.WithL2Claim(common.HexToHash("0xdeadbeef")),
) )
} }
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