Skip to content

Commit

Permalink
op-e2e: improve compat with force-ecotone testing (ethereum-optimism#…
Browse files Browse the repository at this point in the history
…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
  • Loading branch information
protolambda authored Jan 19, 2024
1 parent 77a5c85 commit ee48bee
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 35 deletions.
4 changes: 2 additions & 2 deletions op-e2e/actions/blocktime_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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)

Expand Down
33 changes: 27 additions & 6 deletions op-e2e/actions/l2_batcher_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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{
Expand All @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down
37 changes: 23 additions & 14 deletions op-e2e/system_fpp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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:
Expand All @@ -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")
Expand Down Expand Up @@ -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")
Expand Down
62 changes: 49 additions & 13 deletions op-e2e/system_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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{
Expand Down Expand Up @@ -504,24 +505,46 @@ 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 {
return nil, fmt.Errorf("failed to get batch sender: %w", err)
}
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
}

Expand Down Expand Up @@ -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)

Expand Down Expand Up @@ -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()
Expand Down

0 comments on commit ee48bee

Please sign in to comment.