Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (

"github.com/ethereum-optimism/optimism/op-devstack/devtest"
"github.com/ethereum-optimism/optimism/op-devstack/dsl"
"github.com/ethereum-optimism/optimism/op-devstack/sysgo"
"github.com/ethereum-optimism/optimism/op-service/bigs"
"github.com/ethereum-optimism/optimism/op-service/eth"
"github.com/ethereum-optimism/optimism/op-service/txinclude"
Expand Down Expand Up @@ -83,8 +84,9 @@ func (ie *InvalidExecMsgSpammer) Spam(t devtest.T) error {
// executing messages are also spammed. The number of invalid messages spammed per slot is
// configurable via NAT_INVALID_MPS (default: 1_000).
func TestRelayWithInvalidMessagesSteady(gt *testing.T) {
gt.Skip("Skipping Interop Acceptance Test")
t, l2A, l2B := setupLoadTest(gt)
// TODO(#19411): remove skip once op-reth safe head mismatch is fixed
sysgo.SkipUnlessOpGeth(t, "panics due to safe head mismatch in EngineController")

// Emit a valid initiating message.
initTx, err := l2A.Include(t, planCall(t, &txintent.InitTrigger{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import (
func TestInteropHappyTx(gt *testing.T) {
gt.Skip("Skipping Interop Acceptance Test")
t := devtest.ParallelT(gt)
sys := presets.NewSimpleInterop(t)
sys := presets.NewTwoL2SupernodeInterop(t, 0)

// two EOAs for triggering the init and exec interop txs
alice := sys.FunderA.NewFundedEOA(eth.OneHundredthEther)
Expand All @@ -28,24 +28,24 @@ func TestInteropHappyTx(gt *testing.T) {
eventLoggerAddress := alice.DeployEventLogger()

// wait for chain B to catch up to chain A if necessary
sys.L2ChainB.CatchUpTo(sys.L2ChainA)
sys.L2B.CatchUpTo(sys.L2A)

// send initiating message on chain A
rng := rand.New(rand.NewSource(time.Now().UnixNano()))
initMsg := alice.SendInitMessage(interop.RandomInitTrigger(rng, eventLoggerAddress, rng.Intn(3), rng.Intn(10)))

// at least one block between the init tx on chain A and the exec tx on chain B
sys.L2ChainB.WaitForBlock()
sys.L2B.WaitForBlock()

// send executing message on chain B
execMsg := bob.SendExecMessage(initMsg)

// confirm that the cross-safe safety passed init and exec receipts and that blocks were not reorged
dsl.CheckAll(t,
sys.L2CLA.ReachedRefFn(stypes.CrossSafe, initMsg.BlockID(),
sys.L2ACL.ReachedRefFn(stypes.CrossSafe, initMsg.BlockID(),
// TODO(#16598): Make this relative to the block time
500),
sys.L2CLB.ReachedRefFn(stypes.CrossSafe, execMsg.BlockID(),
sys.L2BCL.ReachedRefFn(stypes.CrossSafe, execMsg.BlockID(),
// TODO(#16598): Make this relative to the block time
500),
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import (
func TestInteropMon(gt *testing.T) {
gt.Skip("Skipping Interop Acceptance Test")
t := devtest.ParallelT(gt)
sys := presets.NewSimpleInterop(t)
sys := presets.NewTwoL2SupernodeInterop(t, 0)

clients := map[eth.ChainID]*sources.EthClient{
sys.L2ELA.Escape().ChainID(): sys.L2ELA.Escape().EthClient().(*sources.EthClient),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,9 @@ func TestInteropFaultProofs_VariedBlockTimes_FasterChainB(gt *testing.T) {

func TestInteropFaultProofs_InvalidBlock(gt *testing.T) {
t := devtest.SerialT(gt)
// TODO(#19411): Unskip once supernode removes invalid transactions
t.Skip("Supernode does not yet remove invalid transactions from blocks")
sys := presets.NewSimpleInteropSupernodeProofs(t)
// TODO(#19411): Re-enable once the invalid-block supernode proof expectations match the
// native Kona FPP and challenger provider behavior again.
t.Skip("Temporarily skipped while investigating invalid-block supernode proof mismatches")
sys := presets.NewSimpleInteropSupernodeProofs(t, presets.WithChallengerCannonKonaEnabled())
sfp.RunInvalidBlockTest(t, sys)
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/ethereum-optimism/optimism/op-devstack/devtest"
"github.com/ethereum-optimism/optimism/op-devstack/dsl"
"github.com/ethereum-optimism/optimism/op-devstack/presets"
"github.com/ethereum-optimism/optimism/op-devstack/sysgo"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait"
"github.com/ethereum-optimism/optimism/op-service/bigs"
"github.com/ethereum-optimism/optimism/op-service/eth"
Expand All @@ -23,8 +24,9 @@ import (
)

func TestReorgInitExecMsg(gt *testing.T) {
gt.Skip("Skipping Interop Acceptance Test")
t := devtest.ParallelT(gt)
// TODO(#19411): remove skip once op-reth safe head mismatch is fixed
sysgo.SkipUnlessOpGeth(t, "panics due to safe head mismatch in EngineController")
ctx := t.Ctx()

sys := presets.NewSimpleInterop(t)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
"github.com/ethereum-optimism/optimism/op-core/predeploys"
"github.com/ethereum-optimism/optimism/op-devstack/devtest"
"github.com/ethereum-optimism/optimism/op-devstack/presets"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait"
"github.com/ethereum-optimism/optimism/op-devstack/sysgo"
"github.com/ethereum-optimism/optimism/op-service/eth"
"github.com/ethereum-optimism/optimism/op-service/txintent"
"github.com/ethereum-optimism/optimism/op-service/txintent/bindings"
Expand All @@ -23,10 +23,12 @@ import (
"github.com/stretchr/testify/require"
)

// TestReorgInvalidExecMsgs tests that the supervisor reorgs the chain when an invalid exec msg is included
// TestReorgInvalidExecMsgs tests that the supernode reorgs the chain when an invalid exec msg is included
// Each subtest runs a test with a different invalid message, by modifying the message in the txModifierFn
func TestReorgInvalidExecMsgs(gt *testing.T) {
gt.Skip("Skipping Interop Acceptance Test")
t := devtest.ParallelT(gt)
// TODO(#19411): remove skip once op-reth safe head mismatch is fixed
sysgo.SkipUnlessOpGeth(t, "panics due to safe head mismatch in EngineController")
gt.Run("invalid log index", func(gt *testing.T) {
testReorgInvalidExecMsg(gt, func(msg *suptypes.Message) {
msg.Identifier.LogIndex = 1024
Expand All @@ -50,18 +52,18 @@ func testReorgInvalidExecMsg(gt *testing.T, txModifierFn func(msg *suptypes.Mess
t := devtest.ParallelT(gt)
ctx := t.Ctx()

sys := presets.NewSimpleInterop(t)
sys := presets.NewTwoL2SupernodeInterop(t, 0)
l := sys.Log

ia := sys.TestSequencer.Escape().ControlAPI(sys.L2ChainA.ChainID())
ia := sys.TestSequencer.Escape().ControlAPI(sys.L2A.ChainID())

// three EOAs for triggering the init and exec interop txs, as well as a simple transfer tx
alice := sys.FunderA.NewFundedEOA(eth.OneHundredthEther)
bob := sys.FunderB.NewFundedEOA(eth.OneHundredthEther)
cathrine := sys.FunderA.NewFundedEOA(eth.OneHundredthEther)

sys.L1Network.WaitForBlock()
sys.L2ChainA.WaitForBlock()
sys.L2A.WaitForBlock()

// stop batcher on chain A
sys.L2BatcherA.Stop()
Expand Down Expand Up @@ -94,7 +96,7 @@ func testReorgInvalidExecMsg(gt *testing.T, txModifierFn func(msg *suptypes.Mess
}

// wait for chain B to catch up to chain A if necessary
sys.L2ChainB.CatchUpTo(sys.L2ChainA)
sys.L2B.CatchUpTo(sys.L2A)

var initTx *txintent.IntentTx[*txintent.InitTrigger, *txintent.InteropOutput]
var initReceipt *types.Receipt
Expand All @@ -106,14 +108,14 @@ func testReorgInvalidExecMsg(gt *testing.T, txModifierFn func(msg *suptypes.Mess
initReceipt, err = initTx.PlannedTx.Included.Eval(ctx)
require.NoError(t, err)

l.Info("initiating message included in chain B", "chain", sys.L2ChainB.ChainID(), "block_number", initReceipt.BlockNumber, "block_hash", initReceipt.BlockHash, "now", time.Now().Unix())
l.Info("initiating message included in chain B", "chain", sys.L2B.ChainID(), "block_number", initReceipt.BlockNumber, "block_hash", initReceipt.BlockHash, "now", time.Now().Unix())
}

// at least one block between the init tx on chain B and the exec tx on chain A
sys.L2ChainA.WaitForBlock()
sys.L2A.WaitForBlock()

// stop sequencer on chain A so that we later force include an invalid exec msg
latestUnsafe_A := sys.L2CLA.StopSequencer()
latestUnsafe_A := sys.L2ACL.StopSequencer()

var execTx *txintent.IntentTx[*txintent.ExecTrigger, *txintent.InteropOutput]
var execSignedTx *types.Transaction
Expand Down Expand Up @@ -151,7 +153,7 @@ func testReorgInvalidExecMsg(gt *testing.T, txModifierFn func(msg *suptypes.Mess

// sequence a new block with an invalid executing msg on chain A
{
l.Info("Building chain A with op-test-sequencer, and include invalid exec msg", "chain", sys.L2ChainA.ChainID(), "unsafeHead", latestUnsafe_A)
l.Info("Building chain A with op-test-sequencer, and include invalid exec msg", "chain", sys.L2A.ChainID(), "unsafeHead", latestUnsafe_A)

err := ia.New(ctx, seqtypes.BuildOpts{
Parent: latestUnsafe_A,
Expand All @@ -175,12 +177,12 @@ func testReorgInvalidExecMsg(gt *testing.T, txModifierFn func(msg *suptypes.Mess
{
currentUnsafeRef := sys.L2ELA.BlockRefByLabel(eth.Unsafe)

l.Info("Unsafe head after invalid exec msg has been included in chain A", "chain", sys.L2ChainA.ChainID(), "unsafeHead", currentUnsafeRef, "parent", currentUnsafeRef.ParentID())
l.Info("Unsafe head after invalid exec msg has been included in chain A", "chain", sys.L2A.ChainID(), "unsafeHead", currentUnsafeRef, "parent", currentUnsafeRef.ParentID())

divergenceBlockNumber_A = currentUnsafeRef.Number
originalHash_A = currentUnsafeRef.Hash
originalParentHash_A = currentUnsafeRef.ParentHash
l.Info("Continue building chain A with another block with op-test-sequencer", "chain", sys.L2ChainA.ChainID(), "unsafeHead", currentUnsafeRef, "parent", currentUnsafeRef.ParentID())
l.Info("Continue building chain A with another block with op-test-sequencer", "chain", sys.L2A.ChainID(), "unsafeHead", currentUnsafeRef, "parent", currentUnsafeRef.ParentID())
err := ia.New(ctx, seqtypes.BuildOpts{
Parent: currentUnsafeRef.Hash,
L1Origin: nil,
Expand All @@ -207,8 +209,8 @@ func testReorgInvalidExecMsg(gt *testing.T, txModifierFn func(msg *suptypes.Mess
time.Sleep(2 * time.Second)
}

// continue sequencing with op-node
sys.L2CLA.StartSequencer()
// continue sequencing with the supernode
sys.L2ACL.StartSequencer()

// start batcher on chain A
sys.L2BatcherA.Start()
Expand All @@ -220,25 +222,11 @@ func testReorgInvalidExecMsg(gt *testing.T, txModifierFn func(msg *suptypes.Mess
ParentHash: originalParentHash_A,
}, 30)

err := wait.For(ctx, 5*time.Second, func() (bool, error) {
safeL2Head_supervisor_A := sys.Supervisor.SafeBlockID(sys.L2ChainA.ChainID()).Hash
safeL2Head_sequencer_A := sys.L2CLA.SafeL2BlockRef()

if safeL2Head_sequencer_A.Number < divergenceBlockNumber_A {
l.Info("Safe ref number is still behind divergence block A number", "divergence", divergenceBlockNumber_A, "safe", safeL2Head_sequencer_A.Number)
return false, nil
}
// Wait for the supernode to validate the replacement block's timestamp.
divergenceTimestamp_A := sys.L2A.TimestampForBlockNum(divergenceBlockNumber_A)
sys.Supernode.AwaitValidatedTimestamp(divergenceTimestamp_A)

if safeL2Head_sequencer_A.Hash.Cmp(safeL2Head_supervisor_A) != 0 {
l.Info("Safe ref still not the same on supervisor and sequencer A", "supervisor", safeL2Head_supervisor_A, "sequencer", safeL2Head_sequencer_A.Hash)
return false, nil
}

l.Info("Safe ref the same across supervisor and sequencers",
"supervisor_A", safeL2Head_supervisor_A,
"sequencer_A", safeL2Head_sequencer_A.Hash)

return true, nil
})
require.NoError(t, err, "Expected to get same safe ref on both supervisor and sequencer eventually")
l.Info("supernode validated replacement block",
"divergence", divergenceBlockNumber_A,
"timestamp", divergenceTimestamp_A)
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import (
func TestL2CLResync(gt *testing.T) {
gt.Skip("Skipping Interop Acceptance Test")
t := devtest.ParallelT(gt)
sys := presets.NewSimpleInterop(t)
sys := presets.NewTwoL2SupernodeInterop(t, 0)
logger := sys.Log.With("Test", "TestL2CLResync")

logger.Info("Check unsafe chains are advancing")
Expand All @@ -26,8 +26,8 @@ func TestL2CLResync(gt *testing.T) {
)

logger.Info("Stop L2CL nodes")
sys.L2CLA.Stop()
sys.L2CLB.Stop()
sys.L2ACL.Stop()
sys.L2BCL.Stop()

logger.Info("Make sure L2ELs does not advance")
dsl.CheckAll(t,
Expand All @@ -36,8 +36,8 @@ func TestL2CLResync(gt *testing.T) {
)

logger.Info("Restart L2CL nodes")
sys.L2CLA.Start()
sys.L2CLB.Start()
sys.L2ACL.Start()
sys.L2BCL.Start()

// L2CL may advance a few blocks without supervisor connection, but eventually it will stop without the connection
// we must check that unsafe head is advancing due to reconnection
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ import (
// - The replacement block's timestamp eventually becomes verified
func TestSupernodeInteropInvalidMessageReplacement(gt *testing.T) {
t := devtest.SerialT(gt)
// TODO(ethereum-optimism/optimism#19411): remove skip once op-reth safe head mismatch is fixed
sysgo.SkipOnOpReth(t, "panics due to safe head mismatch in EngineController")
// TODO(#19411): remove skip once op-reth safe head mismatch is fixed
sysgo.SkipUnlessOpGeth(t, "panics due to safe head mismatch in EngineController")
sys := presets.NewTwoL2SupernodeInterop(t, 0)

ctx := t.Ctx()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ func TestSupernodeSameTimestampExecMessage(gt *testing.T) {
// TestSupernodeSameTimestampInvalidTransitive: Bad log index causes transitive invalidation
func TestSupernodeSameTimestampInvalidTransitive(gt *testing.T) {
t := devtest.SerialT(gt)
// TODO(ethereum-optimism/optimism#19411): remove skip once op-reth safe head mismatch is fixed
sysgo.SkipOnOpReth(t, "panics due to safe head mismatch in EngineController")
// TODO(#19411): remove skip once op-reth safe head mismatch is fixed
sysgo.SkipUnlessOpGeth(t, "panics due to safe head mismatch in EngineController")
sys := presets.NewTwoL2SupernodeInterop(t, 0).ForSameTimestampTesting(t)
rng := rand.New(rand.NewSource(77777))

Expand All @@ -46,8 +46,8 @@ func TestSupernodeSameTimestampInvalidTransitive(gt *testing.T) {
// TestSupernodeSameTimestampCycle: Mutual exec messages create cycle - both replaced
func TestSupernodeSameTimestampCycle(gt *testing.T) {
t := devtest.SerialT(gt)
// TODO(ethereum-optimism/optimism#19411): remove skip once op-reth safe head mismatch is fixed
sysgo.SkipOnOpReth(t, "panics due to safe head mismatch in EngineController")
// TODO(#19411): remove skip once op-reth safe head mismatch is fixed
sysgo.SkipUnlessOpGeth(t, "panics due to safe head mismatch in EngineController")
sys := presets.NewTwoL2SupernodeInterop(t, 0).ForSameTimestampTesting(t)
rng := rand.New(rand.NewSource(55555))

Expand Down
2 changes: 1 addition & 1 deletion op-devstack/dsl/l2_el.go
Original file line number Diff line number Diff line change
Expand Up @@ -464,7 +464,7 @@ func (el *L2ELNode) AssertTxNotInBlock(blockNumber uint64, txHash common.Hash) {
el.log.Info("confirmed transaction not in block", "blockNumber", blockNumber, "txHash", txHash)
}

// AssertTxNotInBlock asserts that a transaction with the given hash does not exist in the block at the given number.
// AssertTxInBlock asserts that a transaction with the given hash does not exist in the block at the given number.
func (el *L2ELNode) AssertTxInBlock(blockNumber uint64, txHash common.Hash) {
ctx, cancel := context.WithTimeout(el.ctx, DefaultTimeout)
defer cancel()
Expand Down
6 changes: 3 additions & 3 deletions op-devstack/sysgo/mixed_runtime.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,10 @@ const (
MixedL2ELOpReth MixedL2ELKind = "op-reth"
)

// SkipOnOpReth skips the test when the L2 execution layer is op-reth
// SkipUnlessOpGeth skips the test when the L2 execution layer is op-reth
// (i.e. DEVSTACK_L2EL_KIND is not "op-geth").
func SkipOnOpReth(t devtest.T, reason string) {
if MixedL2ELKind(os.Getenv(DevstackL2ELKindEnvVar)) == MixedL2ELOpReth {
func SkipUnlessOpGeth(t devtest.T, reason string) {
if MixedL2ELKind(os.Getenv(DevstackL2ELKindEnvVar)) != MixedL2ELOpGeth {
t.Skipf("skipping on op-reth: %s", reason)
}
}
Expand Down
Loading