Commit ee48beed authored by protolambda's avatar protolambda Committed by GitHub

op-e2e: improve compat with force-ecotone testing (#9075)

* op-e2e: update TestL1InfoContract to handle Ecotone

* op-e2e: fix some more delta tests to run with ecotone

* op-e2e: update system-fpp ecotone <> delta activation setup

* op-e2e: fix lint
parent 77a5c85f
......@@ -46,7 +46,7 @@ func TestBlockTimeBatchType(t *testing.T) {
func BatchInLastPossibleBlocks(gt *testing.T, deltaTimeOffset *hexutil.Uint64) {
t := NewDefaultTesting(gt)
dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams)
dp.DeployConfig.L2GenesisDeltaTimeOffset = deltaTimeOffset
applyDeltaTimeOffset(dp, deltaTimeOffset)
dp.DeployConfig.SequencerWindowSize = 4
dp.DeployConfig.L2BlockTime = 2
......@@ -161,7 +161,7 @@ func LargeL1Gaps(gt *testing.T, deltaTimeOffset *hexutil.Uint64) {
dp.DeployConfig.L2BlockTime = 2
dp.DeployConfig.SequencerWindowSize = 4
dp.DeployConfig.MaxSequencerDrift = 32
dp.DeployConfig.L2GenesisDeltaTimeOffset = deltaTimeOffset
applyDeltaTimeOffset(dp, deltaTimeOffset)
sd := e2eutils.Setup(t, dp, defaultAlloc)
log := testlog.Logger(t, log.LvlDebug)
......
......@@ -50,6 +50,27 @@ func TestL2BatcherBatchType(t *testing.T) {
}
}
// applyDeltaTimeOffset adjusts fork configuration to not conflict with the delta overrides
func applyDeltaTimeOffset(dp *e2eutils.DeployParams, deltaTimeOffset *hexutil.Uint64) {
dp.DeployConfig.L2GenesisDeltaTimeOffset = deltaTimeOffset
// configure Ecotone to not be before Delta accidentally
if dp.DeployConfig.L2GenesisEcotoneTimeOffset != nil {
if deltaTimeOffset == nil {
dp.DeployConfig.L2GenesisEcotoneTimeOffset = nil
} else if *dp.DeployConfig.L2GenesisEcotoneTimeOffset < *deltaTimeOffset {
dp.DeployConfig.L2GenesisEcotoneTimeOffset = deltaTimeOffset
}
}
// configure Fjord to not be before Delta accidentally
if dp.DeployConfig.L2GenesisFjordTimeOffset != nil {
if deltaTimeOffset == nil {
dp.DeployConfig.L2GenesisFjordTimeOffset = nil
} else if *dp.DeployConfig.L2GenesisFjordTimeOffset < *deltaTimeOffset {
dp.DeployConfig.L2GenesisFjordTimeOffset = deltaTimeOffset
}
}
}
func NormalBatcher(gt *testing.T, deltaTimeOffset *hexutil.Uint64) {
t := NewDefaultTesting(gt)
p := &e2eutils.TestParams{
......@@ -59,7 +80,7 @@ func NormalBatcher(gt *testing.T, deltaTimeOffset *hexutil.Uint64) {
L1BlockTime: 12,
}
dp := e2eutils.MakeDeployParams(t, p)
dp.DeployConfig.L2GenesisDeltaTimeOffset = deltaTimeOffset
applyDeltaTimeOffset(dp, deltaTimeOffset)
sd := e2eutils.Setup(t, dp, defaultAlloc)
log := testlog.Logger(t, log.LvlDebug)
miner, seqEngine, sequencer := setupSequencerTest(t, sd, log)
......@@ -131,7 +152,7 @@ func NormalBatcher(gt *testing.T, deltaTimeOffset *hexutil.Uint64) {
func L2Finalization(gt *testing.T, deltaTimeOffset *hexutil.Uint64) {
t := NewDefaultTesting(gt)
dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams)
dp.DeployConfig.L2GenesisDeltaTimeOffset = deltaTimeOffset
applyDeltaTimeOffset(dp, deltaTimeOffset)
sd := e2eutils.Setup(t, dp, defaultAlloc)
log := testlog.Logger(t, log.LvlDebug)
miner, engine, sequencer := setupSequencerTest(t, sd, log)
......@@ -238,7 +259,7 @@ func L2Finalization(gt *testing.T, deltaTimeOffset *hexutil.Uint64) {
func L2FinalizationWithSparseL1(gt *testing.T, deltaTimeOffset *hexutil.Uint64) {
t := NewDefaultTesting(gt)
dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams)
dp.DeployConfig.L2GenesisDeltaTimeOffset = deltaTimeOffset
applyDeltaTimeOffset(dp, deltaTimeOffset)
sd := e2eutils.Setup(t, dp, defaultAlloc)
log := testlog.Logger(t, log.LvlDebug)
miner, engine, sequencer := setupSequencerTest(t, sd, log)
......@@ -298,7 +319,7 @@ func GarbageBatch(gt *testing.T, deltaTimeOffset *hexutil.Uint64) {
t := NewDefaultTesting(gt)
p := defaultRollupTestParams
dp := e2eutils.MakeDeployParams(t, p)
dp.DeployConfig.L2GenesisDeltaTimeOffset = deltaTimeOffset
applyDeltaTimeOffset(dp, deltaTimeOffset)
for _, garbageKind := range GarbageKinds {
sd := e2eutils.Setup(t, dp, defaultAlloc)
log := testlog.Logger(t, log.LvlError)
......@@ -383,7 +404,7 @@ func ExtendedTimeWithoutL1Batches(gt *testing.T, deltaTimeOffset *hexutil.Uint64
L1BlockTime: 12,
}
dp := e2eutils.MakeDeployParams(t, p)
dp.DeployConfig.L2GenesisDeltaTimeOffset = deltaTimeOffset
applyDeltaTimeOffset(dp, deltaTimeOffset)
sd := e2eutils.Setup(t, dp, defaultAlloc)
log := testlog.Logger(t, log.LvlError)
miner, engine, sequencer := setupSequencerTest(t, sd, log)
......@@ -442,7 +463,7 @@ func BigL2Txs(gt *testing.T, deltaTimeOffset *hexutil.Uint64) {
L1BlockTime: 12,
}
dp := e2eutils.MakeDeployParams(t, p)
dp.DeployConfig.L2GenesisDeltaTimeOffset = deltaTimeOffset
applyDeltaTimeOffset(dp, deltaTimeOffset)
sd := e2eutils.Setup(t, dp, defaultAlloc)
log := testlog.Logger(t, log.LvlInfo)
miner, engine, sequencer := setupSequencerTest(t, sd, log)
......
......@@ -6,6 +6,7 @@ import (
"testing"
"time"
"github.com/ethereum-optimism/optimism/op-chain-ops/genesis"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/geth"
"github.com/ethereum-optimism/optimism/op-program/client/driver"
opp "github.com/ethereum-optimism/optimism/op-program/host"
......@@ -53,6 +54,26 @@ func TestVerifyL2OutputRootEmptyBlockDetachedSpanBatch(t *testing.T) {
testVerifyL2OutputRootEmptyBlock(t, true, true)
}
func applySpanBatchActivation(active bool, dp *genesis.DeployConfig) {
if active {
// Activate delta hard fork
minTs := hexutil.Uint64(0)
dp.L2GenesisDeltaTimeOffset = &minTs
// readjust other activations
if dp.L2GenesisEcotoneTimeOffset != nil {
dp.L2GenesisEcotoneTimeOffset = &minTs
}
if dp.L2GenesisFjordTimeOffset != nil {
dp.L2GenesisFjordTimeOffset = &minTs
}
} else {
// cancel delta and any later hardfork activations
dp.L2GenesisDeltaTimeOffset = nil
dp.L2GenesisEcotoneTimeOffset = nil
dp.L2GenesisFjordTimeOffset = nil
}
}
// TestVerifyL2OutputRootEmptyBlock asserts that the program can verify the output root of an empty block
// induced by missing batches.
// Setup is as follows:
......@@ -73,13 +94,7 @@ func testVerifyL2OutputRootEmptyBlock(t *testing.T, detached bool, spanBatchActi
// Use a small sequencer window size to avoid test timeout while waiting for empty blocks
// But not too small to ensure that our claim and subsequent state change is published
cfg.DeployConfig.SequencerWindowSize = 16
if spanBatchActivated {
// Activate delta hard fork
minTs := hexutil.Uint64(0)
cfg.DeployConfig.L2GenesisDeltaTimeOffset = &minTs
} else {
cfg.DeployConfig.L2GenesisDeltaTimeOffset = nil
}
applySpanBatchActivation(spanBatchActivated, cfg.DeployConfig)
sys, err := cfg.Start(t)
require.Nil(t, err, "Error starting up system")
......@@ -178,13 +193,7 @@ func testVerifyL2OutputRoot(t *testing.T, detached bool, spanBatchActivated bool
cfg := DefaultSystemConfig(t)
// We don't need a verifier - just the sequencer is enough
delete(cfg.Nodes, "verifier")
if spanBatchActivated {
// Activate delta hard fork
minTs := hexutil.Uint64(0)
cfg.DeployConfig.L2GenesisDeltaTimeOffset = &minTs
} else {
cfg.DeployConfig.L2GenesisDeltaTimeOffset = nil
}
applySpanBatchActivation(spanBatchActivated, cfg.DeployConfig)
sys, err := cfg.Start(t)
require.Nil(t, err, "Error starting up system")
......
......@@ -15,6 +15,7 @@ import (
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/consensus/misc/eip4844"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/eth/ethconfig"
......@@ -470,7 +471,7 @@ func TestMissingBatchE2E(t *testing.T) {
}
}
func L1InfoFromState(ctx context.Context, contract *bindings.L1Block, l2Number *big.Int) (*derive.L1BlockInfo, error) {
func L1InfoFromState(ctx context.Context, contract *bindings.L1Block, l2Number *big.Int, ecotone bool) (*derive.L1BlockInfo, error) {
var err error
var out = &derive.L1BlockInfo{}
opts := bind.CallOpts{
......@@ -504,17 +505,19 @@ func L1InfoFromState(ctx context.Context, contract *bindings.L1Block, l2Number *
return nil, fmt.Errorf("failed to get sequence number: %w", err)
}
overhead, err := contract.L1FeeOverhead(&opts)
if err != nil {
return nil, fmt.Errorf("failed to get l1 fee overhead: %w", err)
}
out.L1FeeOverhead = eth.Bytes32(common.BigToHash(overhead))
if !ecotone {
overhead, err := contract.L1FeeOverhead(&opts)
if err != nil {
return nil, fmt.Errorf("failed to get l1 fee overhead: %w", err)
}
out.L1FeeOverhead = eth.Bytes32(common.BigToHash(overhead))
scalar, err := contract.L1FeeScalar(&opts)
if err != nil {
return nil, fmt.Errorf("failed to get l1 fee scalar: %w", err)
scalar, err := contract.L1FeeScalar(&opts)
if err != nil {
return nil, fmt.Errorf("failed to get l1 fee scalar: %w", err)
}
out.L1FeeScalar = eth.Bytes32(common.BigToHash(scalar))
}
out.L1FeeScalar = eth.Bytes32(common.BigToHash(scalar))
batcherHash, err := contract.BatcherHash(&opts)
if err != nil {
......@@ -522,6 +525,26 @@ func L1InfoFromState(ctx context.Context, contract *bindings.L1Block, l2Number *
}
out.BatcherAddr = common.BytesToAddress(batcherHash[:])
if ecotone {
blobBaseFeeScalar, err := contract.BlobBaseFeeScalar(&opts)
if err != nil {
return nil, fmt.Errorf("failed to get blob basefee scalar: %w", err)
}
out.BlobBaseFeeScalar = blobBaseFeeScalar
baseFeeScalar, err := contract.BaseFeeScalar(&opts)
if err != nil {
return nil, fmt.Errorf("failed to get basefee scalar: %w", err)
}
out.BaseFeeScalar = baseFeeScalar
blobBaseFee, err := contract.BlobBaseFee(&opts)
if err != nil {
return nil, fmt.Errorf("failed to get blob basefee: %w", err)
}
out.BlobBaseFee = blobBaseFee
}
return out, nil
}
......@@ -880,7 +903,8 @@ func TestL1InfoContract(t *testing.T) {
require.NoError(t, err)
txList = append(txList, infoFromTx)
infoFromState, err := L1InfoFromState(ctx, contract, b.Number())
ecotone := sys.RollupConfig.IsEcotone(b.Time()) && !sys.RollupConfig.IsEcotoneActivationBlock(b.Time())
infoFromState, err := L1InfoFromState(ctx, contract, b.Number(), ecotone)
require.Nil(t, err)
stateList = append(stateList, infoFromState)
......@@ -909,8 +933,20 @@ func TestL1InfoContract(t *testing.T) {
BlockHash: h,
SequenceNumber: 0, // ignored, will be overwritten
BatcherAddr: sys.RollupConfig.Genesis.SystemConfig.BatcherAddr,
L1FeeOverhead: sys.RollupConfig.Genesis.SystemConfig.Overhead,
L1FeeScalar: sys.RollupConfig.Genesis.SystemConfig.Scalar,
}
if sys.RollupConfig.IsEcotone(b.Time()) && !sys.RollupConfig.IsEcotoneActivationBlock(b.Time()) {
blobBaseFeeScalar, baseFeeScalar, err := sys.RollupConfig.Genesis.SystemConfig.EcotoneScalars()
require.NoError(t, err)
l1blocks[h].BlobBaseFeeScalar = blobBaseFeeScalar
l1blocks[h].BaseFeeScalar = baseFeeScalar
if excess := b.ExcessBlobGas(); excess != nil {
l1blocks[h].BlobBaseFee = eip4844.CalcBlobFee(*excess)
} else {
l1blocks[h].BlobBaseFee = big.NewInt(1)
}
} else {
l1blocks[h].L1FeeOverhead = sys.RollupConfig.Genesis.SystemConfig.Overhead
l1blocks[h].L1FeeScalar = sys.RollupConfig.Genesis.SystemConfig.Scalar
}
h = b.ParentHash()
......
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