diff --git a/op-e2e/actions/dencun_fork_test.go b/op-e2e/actions/dencun_fork_test.go index 5e0f1706cb31..9b411e28f1e7 100644 --- a/op-e2e/actions/dencun_fork_test.go +++ b/op-e2e/actions/dencun_fork_test.go @@ -62,8 +62,7 @@ func TestDencunL1ForkAfterGenesis(gt *testing.T) { func TestDencunL1ForkAtGenesis(gt *testing.T) { t := NewDefaultTesting(gt) dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) - offset := hexutil.Uint64(0) - dp.DeployConfig.L1CancunTimeOffset = &offset + require.Zero(t, *dp.DeployConfig.L1CancunTimeOffset) sd := e2eutils.Setup(t, dp, defaultAlloc) log := testlog.Logger(t, log.LevelDebug) _, _, miner, sequencer, _, verifier, _, batcher := setupReorgTestActors(t, dp, sd, log) @@ -120,14 +119,13 @@ func verifyEcotoneBlock(gt *testing.T, header *types.Header) { func TestDencunL2ForkAfterGenesis(gt *testing.T) { t := NewDefaultTesting(gt) dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) - - cancunOffset := hexutil.Uint64(0) - dp.DeployConfig.L1CancunTimeOffset = &cancunOffset + require.Zero(t, *dp.DeployConfig.L1CancunTimeOffset) // This test wil fork on the second block offset := hexutil.Uint64(dp.DeployConfig.L2BlockTime * 2) - dp.DeployConfig.L2GenesisCanyonTimeOffset = &offset - dp.DeployConfig.L2GenesisDeltaTimeOffset = &offset dp.DeployConfig.L2GenesisEcotoneTimeOffset = &offset + dp.DeployConfig.L2GenesisFjordTimeOffset = nil + dp.DeployConfig.L2GenesisGraniteTimeOffset = nil + // New forks have to be added here, after changing the default deploy config! sd := e2eutils.Setup(t, dp, defaultAlloc) log := testlog.Logger(t, log.LevelDebug) @@ -159,12 +157,7 @@ func TestDencunL2ForkAfterGenesis(gt *testing.T) { func TestDencunL2ForkAtGenesis(gt *testing.T) { t := NewDefaultTesting(gt) dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) - offset := hexutil.Uint64(0) - dp.DeployConfig.L2GenesisRegolithTimeOffset = &offset - dp.DeployConfig.L1CancunTimeOffset = &offset - dp.DeployConfig.L2GenesisCanyonTimeOffset = &offset - dp.DeployConfig.L2GenesisDeltaTimeOffset = &offset - dp.DeployConfig.L2GenesisEcotoneTimeOffset = &offset + require.Zero(t, *dp.DeployConfig.L2GenesisEcotoneTimeOffset) sd := e2eutils.Setup(t, dp, defaultAlloc) log := testlog.Logger(t, log.LevelDebug) @@ -202,11 +195,6 @@ func newEngine(t Testing, sd *e2eutils.SetupData, log log.Logger) *L2Engine { func TestDencunBlobTxRPC(gt *testing.T) { t := NewDefaultTesting(gt) dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) - offset := hexutil.Uint64(0) - dp.DeployConfig.L2GenesisRegolithTimeOffset = &offset - dp.DeployConfig.L2GenesisCanyonTimeOffset = &offset - dp.DeployConfig.L2GenesisDeltaTimeOffset = &offset - dp.DeployConfig.L2GenesisEcotoneTimeOffset = &offset sd := e2eutils.Setup(t, dp, defaultAlloc) log := testlog.Logger(t, log.LevelDebug) @@ -221,11 +209,6 @@ func TestDencunBlobTxRPC(gt *testing.T) { func TestDencunBlobTxInTxPool(gt *testing.T) { t := NewDefaultTesting(gt) dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) - offset := hexutil.Uint64(0) - dp.DeployConfig.L2GenesisRegolithTimeOffset = &offset - dp.DeployConfig.L2GenesisCanyonTimeOffset = &offset - dp.DeployConfig.L2GenesisDeltaTimeOffset = &offset - dp.DeployConfig.L2GenesisEcotoneTimeOffset = &offset sd := e2eutils.Setup(t, dp, defaultAlloc) log := testlog.Logger(t, log.LevelDebug) @@ -239,11 +222,6 @@ func TestDencunBlobTxInTxPool(gt *testing.T) { func TestDencunBlobTxInclusion(gt *testing.T) { t := NewDefaultTesting(gt) dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) - offset := hexutil.Uint64(0) - dp.DeployConfig.L2GenesisRegolithTimeOffset = &offset - dp.DeployConfig.L2GenesisCanyonTimeOffset = &offset - dp.DeployConfig.L2GenesisDeltaTimeOffset = &offset - dp.DeployConfig.L2GenesisEcotoneTimeOffset = &offset sd := e2eutils.Setup(t, dp, defaultAlloc) log := testlog.Logger(t, log.LevelDebug) diff --git a/op-e2e/actions/ecotone_fork_test.go b/op-e2e/actions/ecotone_fork_test.go index 54802816322d..260a7960089a 100644 --- a/op-e2e/actions/ecotone_fork_test.go +++ b/op-e2e/actions/ecotone_fork_test.go @@ -42,18 +42,16 @@ func verifyCodeHashMatches(t Testing, client *ethclient.Client, address common.A func TestEcotoneNetworkUpgradeTransactions(gt *testing.T) { t := NewDefaultTesting(gt) dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) - genesisBlock := hexutil.Uint64(0) ecotoneOffset := hexutil.Uint64(4) log := testlog.Logger(t, log.LevelDebug) - dp.DeployConfig.L1CancunTimeOffset = &genesisBlock // can be removed once Cancun on L1 is the default - + require.Zero(t, *dp.DeployConfig.L1CancunTimeOffset) // Activate all forks at genesis, and schedule Ecotone the block after - dp.DeployConfig.L2GenesisRegolithTimeOffset = &genesisBlock - dp.DeployConfig.L2GenesisCanyonTimeOffset = &genesisBlock - dp.DeployConfig.L2GenesisDeltaTimeOffset = &genesisBlock dp.DeployConfig.L2GenesisEcotoneTimeOffset = &ecotoneOffset + dp.DeployConfig.L2GenesisFjordTimeOffset = nil + dp.DeployConfig.L2GenesisGraniteTimeOffset = nil + // New forks have to be added here... require.NoError(t, dp.DeployConfig.Check(log), "must have valid config") sd := e2eutils.Setup(t, dp, defaultAlloc) diff --git a/op-e2e/actions/l2_engine_test.go b/op-e2e/actions/l2_engine_test.go index 6a113e086940..5d7a537b5d03 100644 --- a/op-e2e/actions/l2_engine_test.go +++ b/op-e2e/actions/l2_engine_test.go @@ -1,26 +1,28 @@ package actions import ( + "encoding/binary" "errors" "math/big" "testing" - "github.com/ethereum-optimism/optimism/op-program/client/l2/engineapi" - "github.com/ethereum-optimism/optimism/op-program/client/l2/engineapi/test" + "github.com/stretchr/testify/require" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/consensus/beacon" "github.com/ethereum/go-ethereum/consensus/ethash" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/triedb" "github.com/ethereum/go-ethereum/triedb/hashdb" - "github.com/stretchr/testify/require" - - "github.com/ethereum/go-ethereum/log" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils" + "github.com/ethereum-optimism/optimism/op-program/client/l2/engineapi" + "github.com/ethereum-optimism/optimism/op-program/client/l2/engineapi/test" "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum-optimism/optimism/op-service/sources" "github.com/ethereum-optimism/optimism/op-service/testlog" @@ -44,50 +46,62 @@ func TestL2EngineAPI(gt *testing.T) { require.NoError(t, err) // build an empty block - chainA, _ := core.GenerateChain(sd.L2Cfg.Config, genesisBlock, consensus, db, 1, func(i int, gen *core.BlockGen) { + chainA, _ := core.GenerateChain(sd.L2Cfg.Config, genesisBlock, consensus, db, 1, func(n int, gen *core.BlockGen) { gen.SetCoinbase(common.Address{'A'}) + if sd.L2Cfg.Config.IsCancun(gen.Number(), gen.Timestamp()) { + root := crypto.Keccak256Hash([]byte("A"), binary.BigEndian.AppendUint64(nil, uint64(n))) + gen.SetParentBeaconRoot(root) + } }) - payloadA, err := eth.BlockAsPayload(chainA[0], sd.RollupCfg.CanyonTime) + + payloadA, err := eth.BlockAsPayloadEnv(chainA[0], sd.RollupCfg.CanyonTime) require.NoError(t, err) // apply the payload - status, err := l2Cl.NewPayload(t.Ctx(), payloadA, nil) + status, err := l2Cl.NewPayload(t.Ctx(), payloadA.ExecutionPayload, payloadA.ParentBeaconBlockRoot) require.NoError(t, err) - require.Equal(t, status.Status, eth.ExecutionValid) + require.Equal(t, eth.ExecutionValid, status.Status) require.Equal(t, genesisBlock.Hash(), engine.l2Chain.CurrentBlock().Hash(), "processed payloads are not immediately canonical") // recognize the payload as canonical fcRes, err := l2Cl.ForkchoiceUpdate(t.Ctx(), ð.ForkchoiceState{ - HeadBlockHash: payloadA.BlockHash, + HeadBlockHash: payloadA.ExecutionPayload.BlockHash, SafeBlockHash: genesisBlock.Hash(), FinalizedBlockHash: genesisBlock.Hash(), }, nil) require.NoError(t, err) + require.Equal(t, fcRes.PayloadStatus.Status, eth.ExecutionValid) - require.Equal(t, payloadA.BlockHash, engine.l2Chain.CurrentBlock().Hash(), "now payload A is canonical") + require.Equal(t, payloadA.ExecutionPayload.BlockHash, engine.l2Chain.CurrentBlock().Hash(), "now payload A is canonical") // build an alternative block - chainB, _ := core.GenerateChain(sd.L2Cfg.Config, genesisBlock, consensus, db, 1, func(i int, gen *core.BlockGen) { + chainB, _ := core.GenerateChain(sd.L2Cfg.Config, genesisBlock, consensus, db, 1, func(n int, gen *core.BlockGen) { gen.SetCoinbase(common.Address{'B'}) + if sd.L2Cfg.Config.IsCancun(gen.Number(), gen.Timestamp()) { + root := crypto.Keccak256Hash([]byte("A"), binary.BigEndian.AppendUint64(nil, uint64(n))) + gen.SetParentBeaconRoot(root) + } }) - payloadB, err := eth.BlockAsPayload(chainB[0], sd.RollupCfg.CanyonTime) + + payloadB, err := eth.BlockAsPayloadEnv(chainB[0], sd.RollupCfg.CanyonTime) require.NoError(t, err) // apply the payload - status, err = l2Cl.NewPayload(t.Ctx(), payloadB, nil) + status, err = l2Cl.NewPayload(t.Ctx(), payloadB.ExecutionPayload, payloadB.ParentBeaconBlockRoot) require.NoError(t, err) require.Equal(t, status.Status, eth.ExecutionValid) - require.Equal(t, payloadA.BlockHash, engine.l2Chain.CurrentBlock().Hash(), "processed payloads are not immediately canonical") + require.Equal(t, payloadA.ExecutionPayload.BlockHash, engine.l2Chain.CurrentBlock().Hash(), "processed payloads are not immediately canonical") // reorg block A in favor of block B fcRes, err = l2Cl.ForkchoiceUpdate(t.Ctx(), ð.ForkchoiceState{ - HeadBlockHash: payloadB.BlockHash, + HeadBlockHash: payloadB.ExecutionPayload.BlockHash, SafeBlockHash: genesisBlock.Hash(), FinalizedBlockHash: genesisBlock.Hash(), }, nil) require.NoError(t, err) require.Equal(t, fcRes.PayloadStatus.Status, eth.ExecutionValid) - require.Equal(t, payloadB.BlockHash, engine.l2Chain.CurrentBlock().Hash(), "now payload B is canonical") + require.Equal(t, payloadB.ExecutionPayload.BlockHash, engine.l2Chain.CurrentBlock().Hash(), "now payload B is canonical") + } func TestL2EngineAPIBlockBuilding(gt *testing.T) { @@ -133,6 +147,11 @@ func TestL2EngineAPIBlockBuilding(gt *testing.T) { w = &types.Withdrawals{} } + var parentBeaconBlockRoot *common.Hash + if sd.RollupCfg.IsEcotone(uint64(nextBlockTime)) { + parentBeaconBlockRoot = &common.Hash{} + } + // Now let's ask the engine to build a block fcRes, err := l2Cl.ForkchoiceUpdate(t.Ctx(), ð.ForkchoiceState{ HeadBlockHash: parent.Hash(), @@ -146,6 +165,7 @@ func TestL2EngineAPIBlockBuilding(gt *testing.T) { NoTxPool: false, GasLimit: (*eth.Uint64Quantity)(&sd.RollupCfg.Genesis.SystemConfig.GasLimit), Withdrawals: w, + ParentBeaconBlockRoot: parentBeaconBlockRoot, }) require.NoError(t, err) require.Equal(t, fcRes.PayloadStatus.Status, eth.ExecutionValid) @@ -161,7 +181,7 @@ func TestL2EngineAPIBlockBuilding(gt *testing.T) { require.Equal(t, parent.Hash(), payload.ParentHash, "block builds on parent block") // apply the payload - status, err := l2Cl.NewPayload(t.Ctx(), payload, nil) + status, err := l2Cl.NewPayload(t.Ctx(), payload, envelope.ParentBeaconBlockRoot) require.NoError(t, err) require.Equal(t, status.Status, eth.ExecutionValid) require.Equal(t, parent.Hash(), engine.l2Chain.CurrentBlock().Hash(), "processed payloads are not immediately canonical") diff --git a/op-e2e/actions/span_batch_test.go b/op-e2e/actions/span_batch_test.go index 85da7d5b3894..23f5963fa97a 100644 --- a/op-e2e/actions/span_batch_test.go +++ b/op-e2e/actions/span_batch_test.go @@ -132,6 +132,11 @@ func TestHardforkMiddleOfSpanBatch(gt *testing.T) { // Activate HF in the middle of the first epoch deltaOffset := hexutil.Uint64(6) applyDeltaTimeOffset(dp, &deltaOffset) + // Applies to HF that goes into Delta. Otherwise we end up with more upgrade txs and things during this case. + dp.DeployConfig.L2GenesisEcotoneTimeOffset = nil + dp.DeployConfig.L2GenesisFjordTimeOffset = nil + dp.DeployConfig.L2GenesisGraniteTimeOffset = nil + sd := e2eutils.Setup(t, dp, defaultAlloc) log := testlog.Logger(t, log.LevelError) miner, seqEngine, sequencer := setupSequencerTest(t, sd, log) diff --git a/op-e2e/actions/system_config_test.go b/op-e2e/actions/system_config_test.go index d6d97a3b1964..452d5dbc300b 100644 --- a/op-e2e/actions/system_config_test.go +++ b/op-e2e/actions/system_config_test.go @@ -228,6 +228,14 @@ func GPOParamsChange(gt *testing.T, deltaTimeOffset *hexutil.Uint64) { t := NewDefaultTesting(gt) dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) applyDeltaTimeOffset(dp, deltaTimeOffset) + + // activating Delta only, not Ecotone and further: + // the GPO change assertions here all apply only for the Delta transition. + // Separate tests cover Ecotone GPO changes. + dp.DeployConfig.L2GenesisEcotoneTimeOffset = nil + dp.DeployConfig.L2GenesisFjordTimeOffset = nil + dp.DeployConfig.L2GenesisGraniteTimeOffset = nil + sd := e2eutils.Setup(t, dp, defaultAlloc) log := testlog.Logger(t, log.LevelDebug) miner, seqEngine, sequencer := setupSequencerTest(t, sd, log) diff --git a/op-e2e/system_adminrpc_test.go b/op-e2e/system_adminrpc_test.go index e7c0af673b84..c0b9e60abd81 100644 --- a/op-e2e/system_adminrpc_test.go +++ b/op-e2e/system_adminrpc_test.go @@ -198,19 +198,19 @@ func TestPostUnsafePayload(t *testing.T) { blockNumberOne, err := l2Seq.BlockByNumber(ctx, big.NewInt(1)) require.NoError(t, err) - payload, err := eth.BlockAsPayload(blockNumberOne, sys.RollupConfig.CanyonTime) + payloadEnv, err := eth.BlockAsPayloadEnv(blockNumberOne, sys.RollupConfig.CanyonTime) require.NoError(t, err) - err = rollupClient.PostUnsafePayload(ctx, ð.ExecutionPayloadEnvelope{ExecutionPayload: payload}) + err = rollupClient.PostUnsafePayload(ctx, payloadEnv) require.NoError(t, err) require.NoError(t, wait.ForUnsafeBlock(ctx, rollupClient, 1), "Chain did not advance after posting payload") // Test validation blockNumberTwo, err := l2Seq.BlockByNumber(ctx, big.NewInt(2)) require.NoError(t, err) - payload, err = eth.BlockAsPayload(blockNumberTwo, sys.RollupConfig.CanyonTime) + payloadEnv, err = eth.BlockAsPayloadEnv(blockNumberTwo, sys.RollupConfig.CanyonTime) require.NoError(t, err) - payload.BlockHash = common.Hash{0xaa} - err = rollupClient.PostUnsafePayload(ctx, ð.ExecutionPayloadEnvelope{ExecutionPayload: payload}) + payloadEnv.ExecutionPayload.BlockHash = common.Hash{0xaa} + err = rollupClient.PostUnsafePayload(ctx, payloadEnv) require.ErrorContains(t, err, "payload has bad block hash") } diff --git a/op-e2e/system_tob_test.go b/op-e2e/system_tob_test.go index ce3ddf46c5f0..284c775a8ca7 100644 --- a/op-e2e/system_tob_test.go +++ b/op-e2e/system_tob_test.go @@ -5,6 +5,7 @@ import ( "context" "crypto/ecdsa" "fmt" + "math" "math/big" "math/rand" "testing" @@ -19,10 +20,10 @@ import ( "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait" "github.com/ethereum-optimism/optimism/op-node/bindings" bindingspreview "github.com/ethereum-optimism/optimism/op-node/bindings/preview" + "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum-optimism/optimism/op-service/predeploys" "github.com/ethereum-optimism/optimism/op-service/testutils/fuzzerutils" "github.com/ethereum/go-ethereum/accounts" - "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" @@ -41,17 +42,16 @@ func TestGasPriceOracleFeeUpdates(t *testing.T) { defer ctxCancel() InitParallel(t) - // Define our values to set in the GasPriceOracle (we set them high to see if it can lock L2 or stop bindings - // from updating the prices once again. - overheadValue := new(big.Int).Set(abi.MaxUint256) - // Ensure the most significant byte is 0x00 - scalarValue := new(big.Int).Rsh(new(big.Int).Set(abi.MaxUint256), 8) + maxScalars := eth.EcotoneScalars{ + BaseFeeScalar: math.MaxUint32, + BlobBaseFeeScalar: math.MaxUint32, + } var cancel context.CancelFunc // Create our system configuration for L1/L2 and start it cfg := DefaultSystemConfig(t) sys, err := cfg.Start(t) - require.Nil(t, err, "Error starting up system") + require.NoError(t, err, "Error starting up system") defer sys.Close() // Obtain our sequencer, verifier, and transactor keypair. @@ -62,66 +62,61 @@ func TestGasPriceOracleFeeUpdates(t *testing.T) { // Bind to the SystemConfig & GasPriceOracle contracts sysconfig, err := legacybindings.NewSystemConfig(cfg.L1Deployments.SystemConfigProxy, l1Client) - require.Nil(t, err) + require.NoError(t, err) gpoContract, err := legacybindings.NewGasPriceOracleCaller(predeploys.GasPriceOracleAddr, l2Seq) - require.Nil(t, err) + require.NoError(t, err) // Obtain our signer. opts, err := bind.NewKeyedTransactorWithChainID(ethPrivKey, cfg.L1ChainIDBig()) - require.Nil(t, err) + require.NoError(t, err) // Define our L1 transaction timeout duration. txTimeoutDuration := 10 * time.Duration(cfg.DeployConfig.L1BlockTime) * time.Second // Update the gas config, wait for it to show up on L2, & verify that it was set as intended opts.Context, cancel = context.WithTimeout(ctx, txTimeoutDuration) - tx, err := sysconfig.SetGasConfig(opts, overheadValue, scalarValue) + tx, err := sysconfig.SetGasConfigEcotone(opts, maxScalars.BaseFeeScalar, maxScalars.BlobBaseFeeScalar) cancel() - require.Nil(t, err, "sending overhead update tx") + require.NoError(t, err, "SetGasConfigEcotone update tx") receipt, err := wait.ForReceiptOK(ctx, l1Client, tx.Hash()) - require.Nil(t, err, "Waiting for sysconfig set gas config update tx") + require.NoError(t, err, "Waiting for sysconfig set gas config update tx") _, err = geth.WaitForL1OriginOnL2(sys.RollupConfig, receipt.BlockNumber.Uint64(), l2Seq, txTimeoutDuration) require.NoError(t, err, "waiting for L2 block to include the sysconfig update") - gpoOverhead, err := gpoContract.Overhead(&bind.CallOpts{}) - require.Nil(t, err, "reading gpo overhead") - gpoScalar, err := gpoContract.Scalar(&bind.CallOpts{}) - require.Nil(t, err, "reading gpo scalar") + baseFeeScalar, err := gpoContract.BaseFeeScalar(&bind.CallOpts{}) + require.NoError(t, err, "reading base fee scalar") + require.Equal(t, baseFeeScalar, maxScalars.BaseFeeScalar) - if gpoOverhead.Cmp(overheadValue) != 0 { - t.Errorf("overhead that was found (%v) is not what was set (%v)", gpoOverhead, overheadValue) - } - if gpoScalar.Cmp(scalarValue) != 0 { - t.Errorf("scalar that was found (%v) is not what was set (%v)", gpoScalar, scalarValue) - } + blobBaseFeeScalar, err := gpoContract.BlobBaseFeeScalar(&bind.CallOpts{}) + require.NoError(t, err, "reading blob base fee scalar") + require.Equal(t, blobBaseFeeScalar, maxScalars.BlobBaseFeeScalar) // Now modify the scalar value & ensure that the gas params can be modified - scalarValue = big.NewInt(params.Ether) + normalScalars := eth.EcotoneScalars{ + BaseFeeScalar: 1e6, + BlobBaseFeeScalar: 1e6, + } opts.Context, cancel = context.WithTimeout(context.Background(), txTimeoutDuration) - tx, err = sysconfig.SetGasConfig(opts, overheadValue, scalarValue) + tx, err = sysconfig.SetGasConfigEcotone(opts, normalScalars.BaseFeeScalar, normalScalars.BlobBaseFeeScalar) cancel() - require.Nil(t, err, "sending overhead update tx") + require.NoError(t, err, "SetGasConfigEcotone update tx") receipt, err = wait.ForReceiptOK(ctx, l1Client, tx.Hash()) - require.Nil(t, err, "Waiting for sysconfig set gas config update tx") + require.NoError(t, err, "Waiting for sysconfig set gas config update tx") _, err = geth.WaitForL1OriginOnL2(sys.RollupConfig, receipt.BlockNumber.Uint64(), l2Seq, txTimeoutDuration) require.NoError(t, err, "waiting for L2 block to include the sysconfig update") - gpoOverhead, err = gpoContract.Overhead(&bind.CallOpts{}) - require.Nil(t, err, "reading gpo overhead") - gpoScalar, err = gpoContract.Scalar(&bind.CallOpts{}) - require.Nil(t, err, "reading gpo scalar") + baseFeeScalar, err = gpoContract.BaseFeeScalar(&bind.CallOpts{}) + require.NoError(t, err, "reading base fee scalar") + require.Equal(t, baseFeeScalar, normalScalars.BaseFeeScalar) - if gpoOverhead.Cmp(overheadValue) != 0 { - t.Errorf("overhead that was found (%v) is not what was set (%v)", gpoOverhead, overheadValue) - } - if gpoScalar.Cmp(scalarValue) != 0 { - t.Errorf("scalar that was found (%v) is not what was set (%v)", gpoScalar, scalarValue) - } + blobBaseFeeScalar, err = gpoContract.BlobBaseFeeScalar(&bind.CallOpts{}) + require.NoError(t, err, "reading blob base fee scalar") + require.Equal(t, blobBaseFeeScalar, normalScalars.BlobBaseFeeScalar) } // TestL2SequencerRPCDepositTx checks that the L2 sequencer will not accept DepositTx type transactions. diff --git a/op-program/client/l2/engineapi/test/l2_engine_api_tests.go b/op-program/client/l2/engineapi/test/l2_engine_api_tests.go index 1d8a9ff61ff7..4a78e258e780 100644 --- a/op-program/client/l2/engineapi/test/l2_engine_api_tests.go +++ b/op-program/client/l2/engineapi/test/l2_engine_api_tests.go @@ -2,18 +2,21 @@ package test import ( "context" + "math/big" "testing" + "github.com/stretchr/testify/require" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/params" + "github.com/ethereum-optimism/optimism/op-node/rollup" "github.com/ethereum-optimism/optimism/op-node/rollup/derive" "github.com/ethereum-optimism/optimism/op-program/client/l2/engineapi" "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum-optimism/optimism/op-service/testlog" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/params" - "github.com/stretchr/testify/require" ) var gasLimit = eth.Uint64Quantity(30_000_000) @@ -109,7 +112,7 @@ func RunEngineAPITests(t *testing.T, createBackend func(t *testing.T) engineapi. payload := envelope.ExecutionPayload api.assert.Equal(genesis.Hash(), payload.ParentHash, "should have old block as parent") - api.newPayload(payload) + api.newPayload(envelope) api.forkChoiceUpdated(payload.BlockHash, genesis.Hash(), genesis.Hash()) api.assert.Equal(payload.BlockHash, api.headHash(), "should reorg to block built on old parent") }) @@ -138,13 +141,12 @@ func RunEngineAPITests(t *testing.T, createBackend func(t *testing.T) engineapi. // Build a valid block payloadID := api.startBlockBuilding(genesis, eth.Uint64Quantity(genesis.Time+2)) envelope := api.getPayload(payloadID) - newBlock := envelope.ExecutionPayload // But then make it invalid by changing the state root - newBlock.StateRoot = eth.Bytes32(genesis.TxHash) + envelope.ExecutionPayload.StateRoot = eth.Bytes32(genesis.TxHash) updateBlockHash(envelope) - r, err := api.engine.NewPayloadV2(api.ctx, newBlock) + r, err := api.callNewPayload(envelope) api.assert.NoError(err) api.assert.Equal(eth.ExecutionInvalid, r.Status) }) @@ -156,13 +158,12 @@ func RunEngineAPITests(t *testing.T, createBackend func(t *testing.T) engineapi. // Start with a valid time payloadID := api.startBlockBuilding(genesis, eth.Uint64Quantity(genesis.Time+1)) envelope := api.getPayload(payloadID) - newBlock := envelope.ExecutionPayload // Then make it invalid to check NewPayload rejects it - newBlock.Timestamp = eth.Uint64Quantity(genesis.Time) + envelope.ExecutionPayload.Timestamp = eth.Uint64Quantity(genesis.Time) updateBlockHash(envelope) - r, err := api.engine.NewPayloadV2(api.ctx, newBlock) + r, err := api.callNewPayload(envelope) api.assert.NoError(err) api.assert.Equal(eth.ExecutionInvalid, r.Status) }) @@ -174,13 +175,12 @@ func RunEngineAPITests(t *testing.T, createBackend func(t *testing.T) engineapi. // Start with a valid time payloadID := api.startBlockBuilding(genesis, eth.Uint64Quantity(genesis.Time+1)) envelope := api.getPayload(payloadID) - newBlock := envelope.ExecutionPayload // Then make it invalid to check NewPayload rejects it - newBlock.Timestamp = eth.Uint64Quantity(genesis.Time - 1) + envelope.ExecutionPayload.Timestamp = eth.Uint64Quantity(genesis.Time - 1) updateBlockHash(envelope) - r, err := api.engine.NewPayloadV2(api.ctx, newBlock) + r, err := api.callNewPayload(envelope) api.assert.NoError(err) api.assert.Equal(eth.ExecutionInvalid, r.Status) }) @@ -363,7 +363,7 @@ func (h *testHelper) addBlockWithParent(head *types.Header, timestamp eth.Uint64 h.assert.Equal(head.Hash(), block.ParentHash, "should have correct parent") h.assert.Len(block.Transactions, len(txs)) - h.newPayload(block) + h.newPayload(envelope) // Should not have changed the chain head yet h.assert.Equal(prevHead, h.backend.CurrentHeader()) @@ -395,25 +395,35 @@ func (h *testHelper) startBlockBuilding(head *types.Header, newBlockTimestamp et txData = append(txData, rlp) } - canyonTime := h.backend.Config().CanyonTime - var w *types.Withdrawals - if canyonTime != nil && *canyonTime <= uint64(newBlockTimestamp) { - w = &types.Withdrawals{} - } - - result, err := h.engine.ForkchoiceUpdatedV2(h.ctx, ð.ForkchoiceState{ - HeadBlockHash: head.Hash(), - SafeBlockHash: head.Hash(), - FinalizedBlockHash: head.Hash(), - }, ð.PayloadAttributes{ + attr := ð.PayloadAttributes{ Timestamp: newBlockTimestamp, PrevRandao: eth.Bytes32(head.MixDigest), SuggestedFeeRecipient: feeRecipient, Transactions: txData, NoTxPool: true, GasLimit: &gasLimit, - Withdrawals: w, - }) + } + n := new(big.Int).Add(head.Number, big.NewInt(1)) + if h.backend.Config().IsShanghai(n, uint64(newBlockTimestamp)) { + attr.Withdrawals = &types.Withdrawals{} + } + if h.backend.Config().IsCancun(n, uint64(newBlockTimestamp)) { + attr.ParentBeaconBlockRoot = &common.Hash{} + } + fcState := ð.ForkchoiceState{ + HeadBlockHash: head.Hash(), + SafeBlockHash: head.Hash(), + FinalizedBlockHash: head.Hash(), + } + var result *eth.ForkchoiceUpdatedResult + var err error + if h.backend.Config().IsCancun(n, uint64(newBlockTimestamp)) { + result, err = h.engine.ForkchoiceUpdatedV3(h.ctx, fcState, attr) + } else if h.backend.Config().IsShanghai(n, uint64(newBlockTimestamp)) { + result, err = h.engine.ForkchoiceUpdatedV2(h.ctx, fcState, attr) + } else { + result, err = h.engine.ForkchoiceUpdatedV1(h.ctx, fcState, attr) + } h.assert.NoError(err) h.assert.Equal(eth.ExecutionValid, result.PayloadStatus.Status) id := result.PayloadID @@ -423,16 +433,25 @@ func (h *testHelper) startBlockBuilding(head *types.Header, newBlockTimestamp et func (h *testHelper) getPayload(id *eth.PayloadID) *eth.ExecutionPayloadEnvelope { h.Log("getPayload", "id", id) - envelope, err := h.engine.GetPayloadV2(h.ctx, *id) + envelope, err := h.engine.GetPayloadV2(h.ctx, *id) // calls the same underlying function as V1 and V3 h.assert.NoError(err) h.assert.NotNil(envelope) h.assert.NotNil(envelope.ExecutionPayload) return envelope } -func (h *testHelper) newPayload(block *eth.ExecutionPayload) { - h.Log("newPayload", "hash", block.BlockHash) - r, err := h.engine.NewPayloadV2(h.ctx, block) +func (h *testHelper) callNewPayload(envelope *eth.ExecutionPayloadEnvelope) (*eth.PayloadStatusV1, error) { + n := new(big.Int).SetUint64(uint64(envelope.ExecutionPayload.BlockNumber)) + if h.backend.Config().IsCancun(n, uint64(envelope.ExecutionPayload.Timestamp)) { + return h.engine.NewPayloadV3(h.ctx, envelope.ExecutionPayload, []common.Hash{}, envelope.ParentBeaconBlockRoot) + } else { + return h.engine.NewPayloadV2(h.ctx, envelope.ExecutionPayload) + } +} + +func (h *testHelper) newPayload(envelope *eth.ExecutionPayloadEnvelope) { + h.Log("newPayload", "hash", envelope.ExecutionPayload.BlockHash) + r, err := h.callNewPayload(envelope) h.assert.NoError(err) h.assert.Equal(eth.ExecutionValid, r.Status) h.assert.Nil(r.ValidationError) diff --git a/ops-bedrock/beacon-data/config.yaml b/ops-bedrock/beacon-data/config.yaml index 0e2be808bbe5..0358aef31768 100644 --- a/ops-bedrock/beacon-data/config.yaml +++ b/ops-bedrock/beacon-data/config.yaml @@ -48,8 +48,7 @@ CAPELLA_FORK_VERSION: 0x03000001 CAPELLA_FORK_EPOCH: 0 # DENEB DENEB_FORK_VERSION: 0x04000001 -# TODO: activate Deneb at genesis -DENEB_FORK_EPOCH: 1 +DENEB_FORK_EPOCH: 0 # EIP6110 EIP6110_FORK_VERSION: 0x05000001 diff --git a/ops-bedrock/l1-generate-beacon-genesis.sh b/ops-bedrock/l1-generate-beacon-genesis.sh index 04ea8d111434..2fa3534659dd 100644 --- a/ops-bedrock/l1-generate-beacon-genesis.sh +++ b/ops-bedrock/l1-generate-beacon-genesis.sh @@ -4,7 +4,7 @@ set -eu echo "eth2-testnet-genesis path: $(which eth2-testnet-genesis)" -eth2-testnet-genesis capella \ +eth2-testnet-genesis deneb \ --config=./beacon-data/config.yaml \ --preset-phase0=minimal \ --preset-altair=minimal \ diff --git a/packages/contracts-bedrock/deploy-config/devnetL1-template.json b/packages/contracts-bedrock/deploy-config/devnetL1-template.json index 12694499cb46..c56fd92a3a3f 100644 --- a/packages/contracts-bedrock/deploy-config/devnetL1-template.json +++ b/packages/contracts-bedrock/deploy-config/devnetL1-template.json @@ -46,8 +46,9 @@ "l2GenesisRegolithTimeOffset": "0x0", "l2GenesisCanyonTimeOffset": "0x0", "l2GenesisDeltaTimeOffset": "0x0", - "l2GenesisEcotoneTimeOffset": "0x40", - "l1CancunTimeOffset": "0x30", + "l2GenesisEcotoneTimeOffset": "0x0", + "l2GenesisFjordTimeOffset": "0x0", + "l1CancunTimeOffset": "0x0", "systemConfigStartBlock": 0, "requiredProtocolVersion": "0x0000000000000000000000000000000000000000000000000000000000000000", "recommendedProtocolVersion": "0x0000000000000000000000000000000000000000000000000000000000000000",