Commit 78e3cbb8 authored by protolambda's avatar protolambda Committed by GitHub

op-node: fix Ecotone beacon-block-root contract deployment (#9216)

* op-node: fix Ecotone beacon-block-root contract deployment

* op-e2e: update time chekc in op-e2e/actions/ecotone_fork_test.go
Co-authored-by: default avatarSebastian Stammler <seb@oplabs.co>

* op-e2e: deduplicate code-hash checking

* op-e2e: ecotone-test update: require instead of assert

* op-e2e: ecotone test L1 fee check comments clarification

---------
Co-authored-by: default avatarSebastian Stammler <seb@oplabs.co>
parent 0930dd04
...@@ -11,5 +11,6 @@ import "github.com/ethereum/go-ethereum/common" ...@@ -11,5 +11,6 @@ import "github.com/ethereum/go-ethereum/common"
// And https://eips.ethereum.org/EIPS/eip-4788 // And https://eips.ethereum.org/EIPS/eip-4788
var ( var (
EIP4788ContractAddr = common.HexToAddress("0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02") EIP4788ContractAddr = common.HexToAddress("0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02")
EIP4788ContractCode = common.Hex2Bytes("0x3373fffffffffffffffffffffffffffffffffffffffe14604d57602036146024575f5ffd5b5f35801560495762001fff810690815414603c575f5ffd5b62001fff01545f5260205ff35b5f5ffd5b62001fff42064281555f359062001fff015500") EIP4788ContractCode = common.FromHex("0x3373fffffffffffffffffffffffffffffffffffffffe14604d57602036146024575f5ffd5b5f35801560495762001fff810690815414603c575f5ffd5b62001fff01545f5260205ff35b5f5ffd5b62001fff42064281555f359062001fff015500")
EIP4788ContractCodeHash = common.HexToHash("0xf57acd40259872606d76197ef052f3d35588dadf919ee1f0e3cb9b62d3f4b02c")
) )
...@@ -5,7 +5,6 @@ import ( ...@@ -5,7 +5,6 @@ import (
"math/big" "math/big"
"testing" "testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
...@@ -24,15 +23,20 @@ import ( ...@@ -24,15 +23,20 @@ import (
) )
var ( var (
l1BlockCodeHash = common.FromHex("0xc88a313aa75dc4fbf0b6850d9f9ae41e04243b7008cf3eadb29256d4a71c1dfd") l1BlockCodeHash = common.HexToHash("0xc88a313aa75dc4fbf0b6850d9f9ae41e04243b7008cf3eadb29256d4a71c1dfd")
gasPriceOracleCodeHash = common.FromHex("0x8b71360ea773b4cfaf1ae6d2bd15464a4e1e2e360f786e475f63aeaed8da0ae5") gasPriceOracleCodeHash = common.HexToHash("0x8b71360ea773b4cfaf1ae6d2bd15464a4e1e2e360f786e475f63aeaed8da0ae5")
) )
func verifyCodeHashMatches(t *testing.T, client *ethclient.Client, address common.Address, expectedCodeHash []byte) { // verifyCodeHashMatches checks that the has of the code at the given address matches the expected code-hash.
// It also sanity-checks that the code is not empty: we should never deploy empty contract codes.
// Returns the contract code
func verifyCodeHashMatches(t Testing, client *ethclient.Client, address common.Address, expectedCodeHash common.Hash) []byte {
code, err := client.CodeAt(context.Background(), address, nil) code, err := client.CodeAt(context.Background(), address, nil)
require.NoError(t, err) require.NoError(t, err)
require.NotEmpty(t, code)
codeHash := crypto.Keccak256Hash(code) codeHash := crypto.Keccak256Hash(code)
require.Equal(t, expectedCodeHash, codeHash.Bytes()) require.Equal(t, expectedCodeHash, codeHash)
return code
} }
func TestEcotoneNetworkUpgradeTransactions(gt *testing.T) { func TestEcotoneNetworkUpgradeTransactions(gt *testing.T) {
...@@ -53,13 +57,14 @@ func TestEcotoneNetworkUpgradeTransactions(gt *testing.T) { ...@@ -53,13 +57,14 @@ func TestEcotoneNetworkUpgradeTransactions(gt *testing.T) {
sd := e2eutils.Setup(t, dp, defaultAlloc) sd := e2eutils.Setup(t, dp, defaultAlloc)
log := testlog.Logger(t, log.LvlDebug) log := testlog.Logger(t, log.LvlDebug)
_, _, miner, sequencer, engine, verifier, _, _ := setupReorgTestActors(t, dp, sd, log) _, _, miner, sequencer, engine, verifier, _, _ := setupReorgTestActors(t, dp, sd, log)
ethCl := engine.EthClient()
// start op-nodes // start op-nodes
sequencer.ActL2PipelineFull(t) sequencer.ActL2PipelineFull(t)
verifier.ActL2PipelineFull(t) verifier.ActL2PipelineFull(t)
// Get gas price from oracle // Get gas price from oracle
gasPriceOracle, err := bindings.NewGasPriceOracleCaller(predeploys.GasPriceOracleAddr, engine.EthClient()) gasPriceOracle, err := bindings.NewGasPriceOracleCaller(predeploys.GasPriceOracleAddr, ethCl)
require.NoError(t, err) require.NoError(t, err)
scalar, err := gasPriceOracle.Scalar(nil) scalar, err := gasPriceOracle.Scalar(nil)
...@@ -68,16 +73,16 @@ func TestEcotoneNetworkUpgradeTransactions(gt *testing.T) { ...@@ -68,16 +73,16 @@ func TestEcotoneNetworkUpgradeTransactions(gt *testing.T) {
require.True(t, scalar.Cmp(new(big.Int).SetUint64(dp.DeployConfig.GasPriceOracleScalar)) == 0, "must match deploy config") require.True(t, scalar.Cmp(new(big.Int).SetUint64(dp.DeployConfig.GasPriceOracleScalar)) == 0, "must match deploy config")
// Get current implementations addresses (by slot) for L1Block + GasPriceOracle // Get current implementations addresses (by slot) for L1Block + GasPriceOracle
initialGasPriceOracleAddress, err := engine.EthClient().StorageAt(context.Background(), predeploys.GasPriceOracleAddr, genesis.ImplementationSlot, nil) initialGasPriceOracleAddress, err := ethCl.StorageAt(context.Background(), predeploys.GasPriceOracleAddr, genesis.ImplementationSlot, nil)
require.NoError(t, err) require.NoError(t, err)
initialL1BlockAddress, err := engine.EthClient().StorageAt(context.Background(), predeploys.L1BlockAddr, genesis.ImplementationSlot, nil) initialL1BlockAddress, err := ethCl.StorageAt(context.Background(), predeploys.L1BlockAddr, genesis.ImplementationSlot, nil)
require.NoError(t, err) require.NoError(t, err)
// Build to the ecotone block // Build to the ecotone block
sequencer.ActBuildL2ToEcotone(t) sequencer.ActBuildL2ToEcotone(t)
// get latest block // get latest block
latestBlock, err := engine.EthClient().BlockByNumber(context.Background(), nil) latestBlock, err := ethCl.BlockByNumber(context.Background(), nil)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, sequencer.L2Unsafe().Number, latestBlock.Number().Uint64()) require.Equal(t, sequencer.L2Unsafe().Number, latestBlock.Number().Uint64())
...@@ -94,35 +99,37 @@ func TestEcotoneNetworkUpgradeTransactions(gt *testing.T) { ...@@ -94,35 +99,37 @@ func TestEcotoneNetworkUpgradeTransactions(gt *testing.T) {
// All transactions are successful // All transactions are successful
for i := 1; i < 7; i++ { for i := 1; i < 7; i++ {
txn := transactions[i] txn := transactions[i]
receipt, err := engine.EthClient().TransactionReceipt(context.Background(), txn.Hash()) receipt, err := ethCl.TransactionReceipt(context.Background(), txn.Hash())
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, types.ReceiptStatusSuccessful, receipt.Status) require.Equal(t, types.ReceiptStatusSuccessful, receipt.Status)
require.NotEmpty(t, txn.Data(), "upgrade tx must provide input data")
} }
expectedL1BlockAddress := crypto.CreateAddress(derive.L1BlockDeployerAddress, 0) expectedL1BlockAddress := crypto.CreateAddress(derive.L1BlockDeployerAddress, 0)
expectedGasPriceOracleAddress := crypto.CreateAddress(derive.GasPriceOracleDeployerAddress, 0) expectedGasPriceOracleAddress := crypto.CreateAddress(derive.GasPriceOracleDeployerAddress, 0)
// Gas Price Oracle Proxy is updated // Gas Price Oracle Proxy is updated
updatedGasPriceOracleAddress, err := engine.EthClient().StorageAt(context.Background(), predeploys.GasPriceOracleAddr, genesis.ImplementationSlot, latestBlock.Number()) updatedGasPriceOracleAddress, err := ethCl.StorageAt(context.Background(), predeploys.GasPriceOracleAddr, genesis.ImplementationSlot, latestBlock.Number())
require.NoError(t, err) require.NoError(t, err)
assert.Equal(t, expectedGasPriceOracleAddress, common.BytesToAddress(updatedGasPriceOracleAddress)) require.Equal(t, expectedGasPriceOracleAddress, common.BytesToAddress(updatedGasPriceOracleAddress))
assert.NotEqualf(t, initialGasPriceOracleAddress, updatedGasPriceOracleAddress, "Gas Price Oracle Proxy address should have changed") require.NotEqualf(t, initialGasPriceOracleAddress, updatedGasPriceOracleAddress, "Gas Price Oracle Proxy address should have changed")
verifyCodeHashMatches(gt, engine.EthClient(), expectedGasPriceOracleAddress, gasPriceOracleCodeHash) verifyCodeHashMatches(t, ethCl, expectedGasPriceOracleAddress, gasPriceOracleCodeHash)
// L1Block Proxy is updated // L1Block Proxy is updated
updatedL1BlockAddress, err := engine.EthClient().StorageAt(context.Background(), predeploys.L1BlockAddr, genesis.ImplementationSlot, latestBlock.Number()) updatedL1BlockAddress, err := ethCl.StorageAt(context.Background(), predeploys.L1BlockAddr, genesis.ImplementationSlot, latestBlock.Number())
require.NoError(t, err) require.NoError(t, err)
assert.Equal(t, expectedL1BlockAddress, common.BytesToAddress(updatedL1BlockAddress)) require.Equal(t, expectedL1BlockAddress, common.BytesToAddress(updatedL1BlockAddress))
assert.NotEqualf(t, initialL1BlockAddress, updatedL1BlockAddress, "L1Block Proxy address should have changed") require.NotEqualf(t, initialL1BlockAddress, updatedL1BlockAddress, "L1Block Proxy address should have changed")
verifyCodeHashMatches(gt, engine.EthClient(), expectedL1BlockAddress, l1BlockCodeHash) verifyCodeHashMatches(t, ethCl, expectedL1BlockAddress, l1BlockCodeHash)
_, err = gasPriceOracle.Scalar(nil) _, err = gasPriceOracle.Scalar(nil)
require.ErrorContains(t, err, "scalar() is deprecated") require.ErrorContains(t, err, "scalar() is deprecated")
cost, err := gasPriceOracle.GetL1Fee(nil, []byte{0, 1, 2, 3, 4}) cost, err := gasPriceOracle.GetL1Fee(nil, []byte{0, 1, 2, 3, 4})
require.NoError(t, err) require.NoError(t, err)
// Pre-ecotone the GPO getL1Fee contract erroneously returned the pre-regolith L1 fee. // The L1 info tx does not get included until after the Ecotone upgrade.
// Thus we do not assert the exact value here. // The scalars are thus empty during activation, and only deposits are included, so the L1 fee is unused.
require.True(t, cost.IsUint64())
require.Equal(t, cost.Uint64(), uint64(0), "expecting zero scalars within activation block") require.Equal(t, cost.Uint64(), uint64(0), "expecting zero scalars within activation block")
// Check that Ecotone was activated // Check that Ecotone was activated
...@@ -132,15 +139,47 @@ func TestEcotoneNetworkUpgradeTransactions(gt *testing.T) { ...@@ -132,15 +139,47 @@ func TestEcotoneNetworkUpgradeTransactions(gt *testing.T) {
// 4788 contract is deployed // 4788 contract is deployed
expected4788Address := crypto.CreateAddress(derive.EIP4788From, 0) expected4788Address := crypto.CreateAddress(derive.EIP4788From, 0)
code, err := engine.EthClient().CodeAt(context.Background(), expected4788Address, latestBlock.Number()) require.Equal(t, predeploys.EIP4788ContractAddr, expected4788Address)
code := verifyCodeHashMatches(t, ethCl, predeploys.EIP4788ContractAddr, predeploys.EIP4788ContractCodeHash)
require.Equal(t, predeploys.EIP4788ContractCode, code)
// Test that the beacon-block-root has been set
checkBeaconBlockRoot := func(timestamp uint64, expectedHash common.Hash, expectedTime uint64, msg string) {
historyBufferLength := uint64(8191)
rootIdx := common.BigToHash(new(big.Int).SetUint64((timestamp % historyBufferLength) + historyBufferLength))
timeIdx := common.BigToHash(new(big.Int).SetUint64(timestamp % historyBufferLength))
rootValue, err := ethCl.StorageAt(context.Background(), predeploys.EIP4788ContractAddr, rootIdx, nil)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, code, predeploys.EIP4788ContractCode) require.Equal(t, expectedHash, common.BytesToHash(rootValue), msg)
timeValue, err := ethCl.StorageAt(context.Background(), predeploys.EIP4788ContractAddr, timeIdx, nil)
require.NoError(t, err)
timeBig := new(big.Int).SetBytes(timeValue)
require.True(t, timeBig.IsUint64())
require.Equal(t, expectedTime, timeBig.Uint64(), msg)
}
// The header will always have the beacon-block-root, at the very start.
require.NotNil(t, latestBlock.BeaconRoot())
require.Equal(t, *latestBlock.BeaconRoot(), common.Hash{},
"L1 genesis block has zeroed parent-beacon-block-root, since it has no parent block, and that propagates into L2")
// The first block is an exception in upgrade-networks,
// since the beacon-block root contract isn't there at Ecotone activation,
// and the beacon-block-root insertion is processed at the start of the block before deposit txs.
// If the contract was permissionlessly deployed before, the contract storage will be updated however.
checkBeaconBlockRoot(latestBlock.Time(), common.Hash{}, 0, "ecotone activation block has no data yet (since contract wasn't there)")
// Build empty L2 block, to pass ecotone activation // Build empty L2 block, to pass ecotone activation
sequencer.ActL2StartBlock(t) sequencer.ActL2StartBlock(t)
sequencer.ActL2EndBlock(t) sequencer.ActL2EndBlock(t)
// assert again, now that we are past activation // Test the L2 block after activation: it should have data in the contract storage now
latestBlock, err = ethCl.BlockByNumber(context.Background(), nil)
require.NoError(t, err)
require.NotNil(t, latestBlock.BeaconRoot())
firstBeaconBlockRoot := *latestBlock.BeaconRoot()
checkBeaconBlockRoot(latestBlock.Time(), *latestBlock.BeaconRoot(), latestBlock.Time(), "post-activation")
// require.again, now that we are past activation
_, err = gasPriceOracle.Scalar(nil) _, err = gasPriceOracle.Scalar(nil)
require.ErrorContains(t, err, "scalar() is deprecated") require.ErrorContains(t, err, "scalar() is deprecated")
...@@ -151,14 +190,16 @@ func TestEcotoneNetworkUpgradeTransactions(gt *testing.T) { ...@@ -151,14 +190,16 @@ func TestEcotoneNetworkUpgradeTransactions(gt *testing.T) {
cost, err = gasPriceOracle.GetL1Fee(nil, []byte{0, 1, 2, 3, 4}) cost, err = gasPriceOracle.GetL1Fee(nil, []byte{0, 1, 2, 3, 4})
require.NoError(t, err) require.NoError(t, err)
// The GPO getL1Fee contract returns the L1 fee with approximate signature overhead pre-included,
// like the pre-regolith L1 fee. We do the full fee check below. Just sanity check it is not zero anymore first.
require.Greater(t, cost.Uint64(), uint64(0), "expecting non-zero scalars after activation block") require.Greater(t, cost.Uint64(), uint64(0), "expecting non-zero scalars after activation block")
// Get L1Block info // Get L1Block info
l1Block, err := bindings.NewL1BlockCaller(predeploys.L1BlockAddr, engine.EthClient()) l1Block, err := bindings.NewL1BlockCaller(predeploys.L1BlockAddr, ethCl)
require.NoError(t, err) require.NoError(t, err)
l1BlockInfo, err := l1Block.Timestamp(nil) l1BlockInfo, err := l1Block.Timestamp(nil)
require.NoError(t, err) require.NoError(t, err)
assert.Greater(t, l1BlockInfo, uint64(0)) require.Greater(t, l1BlockInfo, uint64(0))
l1OriginBlock, err := miner.EthClient().BlockByHash(context.Background(), sequencer.L2Unsafe().L1Origin.Hash) l1OriginBlock, err := miner.EthClient().BlockByHash(context.Background(), sequencer.L2Unsafe().L1Origin.Hash)
require.NoError(t, err) require.NoError(t, err)
...@@ -174,6 +215,18 @@ func TestEcotoneNetworkUpgradeTransactions(gt *testing.T) { ...@@ -174,6 +215,18 @@ func TestEcotoneNetworkUpgradeTransactions(gt *testing.T) {
expectedL1Fee = expectedL1Fee.Mul(expectedL1Fee, new(big.Int).SetUint64(uint64(basefeeScalar))) expectedL1Fee = expectedL1Fee.Mul(expectedL1Fee, new(big.Int).SetUint64(uint64(basefeeScalar)))
expectedL1Fee = expectedL1Fee.Div(expectedL1Fee, big.NewInt(16e6)) expectedL1Fee = expectedL1Fee.Div(expectedL1Fee, big.NewInt(16e6))
require.Equal(t, expectedL1Fee, cost, "expecting cost based on regular base fee scalar alone") require.Equal(t, expectedL1Fee, cost, "expecting cost based on regular base fee scalar alone")
// build forward, incorporate new L1 data
miner.ActEmptyBlock(t)
sequencer.ActL1HeadSignal(t)
sequencer.ActBuildToL1Head(t)
// Contract storage should be updated now, different than before
latestBlock, err = ethCl.BlockByNumber(context.Background(), nil)
require.NoError(t, err)
require.NotNil(t, latestBlock.BeaconRoot())
require.NotEqual(t, firstBeaconBlockRoot, *latestBlock.BeaconRoot())
checkBeaconBlockRoot(latestBlock.Time(), *latestBlock.BeaconRoot(), latestBlock.Time(), "updates on new L1 data")
} }
// TestEcotoneBeforeL1 tests that the L2 Ecotone fork can activate before L1 Dencun does // TestEcotoneBeforeL1 tests that the L2 Ecotone fork can activate before L1 Dencun does
......
...@@ -11,6 +11,7 @@ import ( ...@@ -11,6 +11,7 @@ import (
"github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/trie" "github.com/ethereum/go-ethereum/trie"
...@@ -94,7 +95,8 @@ func (s *L1Miner) ActL1StartBlock(timeDelta uint64) Action { ...@@ -94,7 +95,8 @@ func (s *L1Miner) ActL1StartBlock(timeDelta uint64) Action {
if s.l1Cfg.Config.IsCancun(header.Number, header.Time) { if s.l1Cfg.Config.IsCancun(header.Number, header.Time) {
header.BlobGasUsed = new(uint64) header.BlobGasUsed = new(uint64)
header.ExcessBlobGas = new(uint64) header.ExcessBlobGas = new(uint64)
header.ParentBeaconRoot = new(common.Hash) root := crypto.Keccak256Hash([]byte("fake-beacon-block-root"), header.Number.Bytes())
header.ParentBeaconRoot = &root
} }
s.l1Building = true s.l1Building = true
......
...@@ -34,7 +34,7 @@ var ( ...@@ -34,7 +34,7 @@ var (
enableEcotoneInput = crypto.Keccak256([]byte("setEcotone()"))[:4] enableEcotoneInput = crypto.Keccak256([]byte("setEcotone()"))[:4]
EIP4788From = common.HexToAddress("0x0B799C86a49DEeb90402691F1041aa3AF2d3C875") EIP4788From = common.HexToAddress("0x0B799C86a49DEeb90402691F1041aa3AF2d3C875")
eip4788CreationData = common.Hex2Bytes("0x60618060095f395ff33373fffffffffffffffffffffffffffffffffffffffe14604d57602036146024575f5ffd5b5f35801560495762001fff810690815414603c575f5ffd5b62001fff01545f5260205ff35b5f5ffd5b62001fff42064281555f359062001fff015500") eip4788CreationData = common.FromHex("0x60618060095f395ff33373fffffffffffffffffffffffffffffffffffffffe14604d57602036146024575f5ffd5b5f35801560495762001fff810690815414603c575f5ffd5b62001fff01545f5260205ff35b5f5ffd5b62001fff42064281555f359062001fff015500")
UpgradeToFuncBytes4 = crypto.Keccak256([]byte(UpgradeToFuncSignature))[:4] UpgradeToFuncBytes4 = crypto.Keccak256([]byte(UpgradeToFuncSignature))[:4]
l1BlockDeploymentBytecode = common.FromHex("0x608060405234801561001057600080fd5b5061053e806100206000396000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c80638381f58a11610097578063c598591811610066578063c598591814610229578063e591b28214610249578063e81b2c6d14610289578063f82061401461029257600080fd5b80638381f58a146101e35780638b239f73146101f75780639e8c496614610200578063b80777ea1461020957600080fd5b806354fd4d50116100d357806354fd4d50146101335780635cf249691461017c57806364ca23ef1461018557806368d5dca6146101b257600080fd5b8063015d8eb9146100fa57806309bd5a601461010f578063440a5e201461012b575b600080fd5b61010d61010836600461044c565b61029b565b005b61011860025481565b6040519081526020015b60405180910390f35b61010d6103da565b61016f6040518060400160405280600581526020017f312e322e3000000000000000000000000000000000000000000000000000000081525081565b60405161012291906104be565b61011860015481565b6003546101999067ffffffffffffffff1681565b60405167ffffffffffffffff9091168152602001610122565b6003546101ce9068010000000000000000900463ffffffff1681565b60405163ffffffff9091168152602001610122565b6000546101999067ffffffffffffffff1681565b61011860055481565b61011860065481565b6000546101999068010000000000000000900467ffffffffffffffff1681565b6003546101ce906c01000000000000000000000000900463ffffffff1681565b61026473deaddeaddeaddeaddeaddeaddeaddeaddead000181565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610122565b61011860045481565b61011860075481565b3373deaddeaddeaddeaddeaddeaddeaddeaddead000114610342576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603b60248201527f4c31426c6f636b3a206f6e6c7920746865206465706f7369746f72206163636f60448201527f756e742063616e20736574204c3120626c6f636b2076616c7565730000000000606482015260840160405180910390fd5b6000805467ffffffffffffffff98891668010000000000000000027fffffffffffffffffffffffffffffffff00000000000000000000000000000000909116998916999099179890981790975560019490945560029290925560038054919094167fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000009190911617909255600491909155600555600655565b3373deaddeaddeaddeaddeaddeaddeaddeaddead00011461040357633cc50b456000526004601cfd5b60043560801c60035560143560801c600055602435600155604435600755606435600255608435600455565b803567ffffffffffffffff8116811461044757600080fd5b919050565b600080600080600080600080610100898b03121561046957600080fd5b6104728961042f565b975061048060208a0161042f565b9650604089013595506060890135945061049c60808a0161042f565b979a969950949793969560a0850135955060c08501359460e001359350915050565b600060208083528351808285015260005b818110156104eb578581018301518582016040015282016104cf565b818111156104fd576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01692909201604001939250505056fea164736f6c634300080f000a") l1BlockDeploymentBytecode = common.FromHex("0x608060405234801561001057600080fd5b5061053e806100206000396000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c80638381f58a11610097578063c598591811610066578063c598591814610229578063e591b28214610249578063e81b2c6d14610289578063f82061401461029257600080fd5b80638381f58a146101e35780638b239f73146101f75780639e8c496614610200578063b80777ea1461020957600080fd5b806354fd4d50116100d357806354fd4d50146101335780635cf249691461017c57806364ca23ef1461018557806368d5dca6146101b257600080fd5b8063015d8eb9146100fa57806309bd5a601461010f578063440a5e201461012b575b600080fd5b61010d61010836600461044c565b61029b565b005b61011860025481565b6040519081526020015b60405180910390f35b61010d6103da565b61016f6040518060400160405280600581526020017f312e322e3000000000000000000000000000000000000000000000000000000081525081565b60405161012291906104be565b61011860015481565b6003546101999067ffffffffffffffff1681565b60405167ffffffffffffffff9091168152602001610122565b6003546101ce9068010000000000000000900463ffffffff1681565b60405163ffffffff9091168152602001610122565b6000546101999067ffffffffffffffff1681565b61011860055481565b61011860065481565b6000546101999068010000000000000000900467ffffffffffffffff1681565b6003546101ce906c01000000000000000000000000900463ffffffff1681565b61026473deaddeaddeaddeaddeaddeaddeaddeaddead000181565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610122565b61011860045481565b61011860075481565b3373deaddeaddeaddeaddeaddeaddeaddeaddead000114610342576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603b60248201527f4c31426c6f636b3a206f6e6c7920746865206465706f7369746f72206163636f60448201527f756e742063616e20736574204c3120626c6f636b2076616c7565730000000000606482015260840160405180910390fd5b6000805467ffffffffffffffff98891668010000000000000000027fffffffffffffffffffffffffffffffff00000000000000000000000000000000909116998916999099179890981790975560019490945560029290925560038054919094167fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000009190911617909255600491909155600555600655565b3373deaddeaddeaddeaddeaddeaddeaddeaddead00011461040357633cc50b456000526004601cfd5b60043560801c60035560143560801c600055602435600155604435600755606435600255608435600455565b803567ffffffffffffffff8116811461044757600080fd5b919050565b600080600080600080600080610100898b03121561046957600080fd5b6104728961042f565b975061048060208a0161042f565b9650604089013595506060890135945061049c60808a0161042f565b979a969950949793969560a0850135955060c08501359460e001359350915050565b600060208083528351808285015260005b818110156104eb578581018301518582016040015282016104cf565b818111156104fd576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01692909201604001939250505056fea164736f6c634300080f000a")
......
...@@ -110,9 +110,11 @@ func TestEcotoneNetworkTransactions(t *testing.T) { ...@@ -110,9 +110,11 @@ func TestEcotoneNetworkTransactions(t *testing.T) {
require.Nil(t, beaconRoots.To()) require.Nil(t, beaconRoots.To())
require.Equal(t, uint64(250_000), beaconRoots.Gas()) require.Equal(t, uint64(250_000), beaconRoots.Gas())
require.Equal(t, eip4788CreationData, beaconRoots.Data()) require.Equal(t, eip4788CreationData, beaconRoots.Data())
require.NotEmpty(t, beaconRoots.Data())
} }
func TestEip4788Params(t *testing.T) { func TestEip4788Params(t *testing.T) {
require.Equal(t, EIP4788From, common.HexToAddress("0x0B799C86a49DEeb90402691F1041aa3AF2d3C875")) require.Equal(t, EIP4788From, common.HexToAddress("0x0B799C86a49DEeb90402691F1041aa3AF2d3C875"))
require.Equal(t, eip4788CreationData, common.Hex2Bytes("0x60618060095f395ff33373fffffffffffffffffffffffffffffffffffffffe14604d57602036146024575f5ffd5b5f35801560495762001fff810690815414603c575f5ffd5b62001fff01545f5260205ff35b5f5ffd5b62001fff42064281555f359062001fff015500")) require.Equal(t, eip4788CreationData, common.FromHex("0x60618060095f395ff33373fffffffffffffffffffffffffffffffffffffffe14604d57602036146024575f5ffd5b5f35801560495762001fff810690815414603c575f5ffd5b62001fff01545f5260205ff35b5f5ffd5b62001fff42064281555f359062001fff015500"))
require.NotEmpty(t, eip4788CreationData)
} }
...@@ -80,6 +80,13 @@ func NewBlockProcessorFromHeader(provider BlockDataProvider, h *types.Header) (* ...@@ -80,6 +80,13 @@ func NewBlockProcessorFromHeader(provider BlockDataProvider, h *types.Header) (*
header.BaseFee = eip1559.CalcBaseFee(provider.Config(), parentHeader, header.Time) header.BaseFee = eip1559.CalcBaseFee(provider.Config(), parentHeader, header.Time)
header.GasUsed = 0 header.GasUsed = 0
gasPool := new(core.GasPool).AddGas(header.GasLimit) gasPool := new(core.GasPool).AddGas(header.GasLimit)
if h.ParentBeaconRoot != nil {
// Unfortunately this is not part of any Geth environment setup,
// we just have to apply it, like how the Geth block-builder worker does.
context := core.NewEVMBlockContext(header, provider, nil, provider.Config(), statedb)
vmenv := vm.NewEVM(context, vm.TxContext{}, statedb, provider.Config(), vm.Config{})
core.ProcessBeaconBlockRoot(*header.ParentBeaconRoot, vmenv, statedb)
}
return &BlockProcessor{ return &BlockProcessor{
header: header, header: header,
state: statedb, state: statedb,
......
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