Skip to content

Commit

Permalink
Temp commit for action test
Browse files Browse the repository at this point in the history
  • Loading branch information
Vinod Damle committed Nov 13, 2024
1 parent c6b60f8 commit 6b3c027
Show file tree
Hide file tree
Showing 7 changed files with 201 additions and 13 deletions.
14 changes: 14 additions & 0 deletions op-e2e/actions/helpers/l2_sequencer.go
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,13 @@ func (s *L2Sequencer) ActBuildL2ToTime(t Testing, target uint64) {
}
}

func (s *L2Sequencer) ActBuildL2ToCanyon(t Testing) {
require.NotNil(t, s.RollupCfg.CanyonTime, "cannot activate CanyonTime when it is not scheduled")
for s.L2Unsafe().Time < *s.RollupCfg.CanyonTime {
s.ActL2EmptyBlock(t)
}
}

func (s *L2Sequencer) ActBuildL2ToEcotone(t Testing) {
require.NotNil(t, s.RollupCfg.EcotoneTime, "cannot activate Ecotone when it is not scheduled")
for s.L2Unsafe().Time < *s.RollupCfg.EcotoneTime {
Expand Down Expand Up @@ -233,3 +240,10 @@ func (s *L2Sequencer) ActBuildL2ToHolocene(t Testing) {
s.ActL2EmptyBlock(t)
}
}

func (s *L2Sequencer) ActBuildL2ToIsthmus(t Testing) {
require.NotNil(t, s.RollupCfg.IsthmusTime, "cannot activate IsthmusTime when it is not scheduled")
for s.L2Unsafe().Time < *s.RollupCfg.IsthmusTime {
s.ActL2EmptyBlock(t)
}
}
159 changes: 153 additions & 6 deletions op-e2e/actions/upgrades/isthmus_fork_test.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,26 @@
package upgrades

import (
"context"
"math/big"
"testing"
"time"

"github.com/ethereum-optimism/optimism/op-e2e/actions/helpers"
"github.com/ethereum-optimism/optimism/op-e2e/bindings"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/geth"
"github.com/ethereum-optimism/optimism/op-node/rollup"
"github.com/ethereum-optimism/optimism/op-service/client"
"github.com/ethereum-optimism/optimism/op-service/eth"
"github.com/ethereum-optimism/optimism/op-service/predeploys"
"github.com/ethereum-optimism/optimism/op-service/testlog"
"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/core/types"
"github.com/ethereum/go-ethereum/log"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

Expand All @@ -34,10 +45,13 @@ func TestIsthmusActivationAtGenesis(gt *testing.T) {
env.Seq.ActBuildToL1Head(t)

block := env.VerifEngine.L2Chain().CurrentBlock()
verifyIsthmusBlock(gt, block)
verifyIsthmusHeaderWithdrawalsRoot(gt, block, false)
}

func TestWithdrawlsRootPreCanyon(gt *testing.T) {
// There are 2 stages pre-Isthmus that we need to test:
// 1. Pre-Canyon: withdrawals root should be nil
// 2. Post-Canyon: withdrawals root should be EmptyWithdrawalsHash
func TestWithdrawlsRootPreIsthmus(gt *testing.T) {
t := helpers.NewDefaultTesting(gt)
dp := e2eutils.MakeDeployParams(t, helpers.DefaultRollupTestParams())
genesisBlock := hexutil.Uint64(0)
Expand All @@ -60,19 +74,152 @@ func TestWithdrawlsRootPreCanyon(gt *testing.T) {

sd := e2eutils.Setup(t, dp, helpers.DefaultAlloc)
_, _, _, sequencer, engine, verifier, _, _ := helpers.SetupReorgTestActors(t, dp, sd, log)
// ethCl := engine.EthClient()

// start op-nodes
sequencer.ActL2PipelineFull(t)
verifier.ActL2PipelineFull(t)

verifyPreIsthmusBlock(gt, engine.L2Chain().CurrentBlock())
verifyPreCanyonHeaderWithdrawalsRoot(gt, engine.L2Chain().CurrentBlock())

// build blocks until canyon activates
sequencer.ActBuildL2ToCanyon(t)

// Send withdrawal transaction
// Bind L2 Withdrawer Contract
ethCl := engine.EthClient()
l2withdrawer, err := bindings.NewL2ToL1MessagePasser(predeploys.L2ToL1MessagePasserAddr, ethCl)
require.Nil(t, err, "binding withdrawer on L2")

// Initiate Withdrawal
l2opts, err := bind.NewKeyedTransactorWithChainID(dp.Secrets.Alice, new(big.Int).SetUint64(dp.DeployConfig.L2ChainID))
require.Nil(t, err)
l2opts.Value = big.NewInt(500)

l2withdrawer.Receive(l2opts)

// mine blocks
sequencer.ActL2EmptyBlock(t)
sequencer.ActL2EmptyBlock(t)

verifyPreIsthmusHeaderWithdrawalsRoot(gt, engine.L2Chain().CurrentBlock())
}

func verifyPreIsthmusBlock(gt *testing.T, header *types.Header) {
func TestWithdrawlsRootAtIsthmus(gt *testing.T) {
t := helpers.NewDefaultTesting(gt)
dp := e2eutils.MakeDeployParams(t, helpers.DefaultRollupTestParams())
genesisBlock := hexutil.Uint64(0)
isthmusOffset := hexutil.Uint64(2)

log := testlog.Logger(t, log.LvlDebug)

// dp.DeployConfig.L1CancunTimeOffset = &genesisBlock

// Activate pre-canyon forks at genesis, and schedule Canyon the block after
// dummyAddr := common.Address{19: 0x01}
// dp.DeployConfig.OutputOracleDeployConfig = genesis.OutputOracleDeployConfig{
// L2OutputOracleSubmissionInterval: 1,
// L2OutputOracleStartingTimestamp: 1,
// L2OutputOracleStartingBlockNumber: 3,
// L2OutputOracleProposer: dummyAddr,
// L2OutputOracleChallenger: dummyAddr,
// }
dp.DeployConfig.L2GenesisRegolithTimeOffset = &genesisBlock
dp.DeployConfig.L2GenesisCanyonTimeOffset = &genesisBlock
dp.DeployConfig.L2GenesisIsthmusTimeOffset = &isthmusOffset
dp.DeployConfig.L2GenesisDeltaTimeOffset = &genesisBlock
dp.DeployConfig.L2GenesisEcotoneTimeOffset = &genesisBlock
dp.DeployConfig.L2GenesisFjordTimeOffset = &genesisBlock
dp.DeployConfig.L2GenesisGraniteTimeOffset = &genesisBlock
dp.DeployConfig.L2GenesisHoloceneTimeOffset = &genesisBlock
require.NoError(t, dp.DeployConfig.Check(log), "must have valid config")

sd := e2eutils.Setup(t, dp, helpers.DefaultAlloc)
_, _, _, sequencer, engine, verifier, _, _ := helpers.SetupReorgTestActors(t, dp, sd, log)

// start op-nodes
sequencer.ActL2PipelineFull(t)
verifier.ActL2PipelineFull(t)

verifyPreIsthmusHeaderWithdrawalsRoot(gt, engine.L2Chain().CurrentBlock())

getStorageRoot := func(rpcCl client.RPC, ctx context.Context, address common.Address, blockTag string) common.Hash {
var getProofResponse *eth.AccountResult
err := rpcCl.CallContext(ctx, &getProofResponse, "eth_getProof", address, []common.Hash{}, blockTag)
assert.Nil(t, err)
assert.NotNil(t, getProofResponse)
return getProofResponse.StorageHash
}

rpcCl := engine.RPCClient()
currentBlock := engine.L2Chain().CurrentBlock()
t.Log("Current block number: ", currentBlock.Number)
storageHash := getStorageRoot(rpcCl, context.Background(), predeploys.L2ToL1MessagePasserAddr, "latest")
t.Log("Storage hash: ", storageHash)
// require.Equal(t, *currentBlock.WithdrawalsHash, storageHash)

// Send withdrawal transaction
// Bind L2 Withdrawer Contract
ethCl := engine.EthClient()
l2withdrawer, err := bindings.NewL2ToL1MessagePasser(predeploys.L2ToL1MessagePasserAddr, ethCl)
require.Nil(t, err, "binding withdrawer on L2")

// Initiate Withdrawal
l2opts, err := bind.NewKeyedTransactorWithChainID(dp.Secrets.Alice, new(big.Int).SetUint64(dp.DeployConfig.L2ChainID))
require.Nil(t, err)
l2opts.Value = big.NewInt(500)

tx, err := l2withdrawer.Receive(l2opts)
require.Nil(t, err)

// build blocks until Isthmus activates
sequencer.ActL2StartBlock(t)
sequencer.ActL2EndBlock(t)
sequencer.ActL2StartBlock(t)
engine.ActL2IncludeTx(dp.Addresses.Alice)(t)
sequencer.ActL2EndBlock(t)

receipt, err := geth.WaitForTransaction(tx.Hash(), ethCl, 10*time.Duration(dp.DeployConfig.L2BlockTime)*time.Second)
require.Nil(t, err, "withdrawal initiated on L2 sequencer")
require.Equal(t, types.ReceiptStatusSuccessful, receipt.Status, "transaction had incorrect status")

sequencer.ActL2StartBlock(t)
sequencer.ActL2EndBlock(t)

currentBlock = engine.L2Chain().CurrentBlock()
t.Log("Current block number: ", currentBlock.Number)
storageHash = getStorageRoot(rpcCl, context.Background(), predeploys.L2ToL1MessagePasserAddr, "latest")
require.Equal(t, *currentBlock.WithdrawalsHash, storageHash)
// verifyIsthmusHeaderWithdrawalsRoot(gt, engine.L2Chain().CurrentBlock(), true)
}

// Pre-Canyon, the withdrawals root field in the header should be nil
func verifyPreCanyonHeaderWithdrawalsRoot(gt *testing.T, header *types.Header) {
require.Nil(gt, header.WithdrawalsHash)
}

func verifyIsthmusBlock(gt *testing.T, header *types.Header) {
// Post-Canyon, the withdrawals root field in the header should be EmptyWithdrawalsHash
func verifyPreIsthmusHeaderWithdrawalsRoot(gt *testing.T, header *types.Header) {
require.Equal(gt, types.EmptyWithdrawalsHash, *header.WithdrawalsHash)
}

func verifyIsthmusHeaderWithdrawalsRoot(gt *testing.T, header *types.Header, l2toL1MPPresent bool) {
if !l2toL1MPPresent {
require.Equal(gt, types.EmptyWithdrawalsHash, *header.WithdrawalsHash)
} else {
require.NotEqual(gt, types.EmptyWithdrawalsHash, *header.WithdrawalsHash)
}
}

// func getL2ToL1MP(t *testing.T, engine *e2eutils.Engine) *types.Transaction {
// // Get the L2 to L1 message passing tx
// l2ToL1MP, err := engine.L2Chain().CurrentBlock().GetL2ToL1MessagePassingTx()
// require.NoError(t, err)
// return l2ToL1MP
// }

// func getL2ToL1MPStorageRoot(t *testing.T, ethCl *ethclient.Client) string {
// proof, err := ethCl.GetProof(ctx, predeploys.L2ToL1MessagePasserAddr, []common.Hash{}, blockHash.String())
// rootValue, err := ethCl.StorageAt(context.Background(), predeploys.L2ToL1MessagePasserAddr, rootIdx, nil)
// require.NoError(t, err)
// require.Equal(t, expectedHash, common.BytesToHash(rootValue), msg)
// }
21 changes: 21 additions & 0 deletions op-e2e/opgeth/op_geth.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@ import (
"github.com/ethereum-optimism/optimism/op-node/rollup/derive"
"github.com/ethereum-optimism/optimism/op-service/client"
"github.com/ethereum-optimism/optimism/op-service/eth"
"github.com/ethereum-optimism/optimism/op-service/predeploys"
"github.com/ethereum-optimism/optimism/op-service/sources"
"github.com/ethereum-optimism/optimism/op-service/testlog"
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core/types"
Expand Down Expand Up @@ -150,6 +152,25 @@ func (d *OpGeth) AddL2Block(ctx context.Context, txs ...*types.Transaction) (*et
return nil, errors.New("required transactions were not included")
}

// if we are at Isthmus, set the withdrawalsRoot in the execution payload to the storage root of the message passer contract
if d.L2ChainConfig.IsIsthmus(uint64(payload.Timestamp)) {
var getProofResponse *eth.AccountResult
rpcClient := d.l2Engine.RPC
err := rpcClient.CallContext(ctx, &getProofResponse, "eth_getProof", predeploys.L2ToL1MessagePasserAddr, []common.Hash{}, payload.BlockHash.String())
if err != nil {
return nil, err
}
if getProofResponse == nil {
return nil, ethereum.NotFound
}
// output, err := d.l2Engine.OutputV0AtBlock(ctx, payload.BlockHash)
// if err != nil {
// return nil, fmt.Errorf("output at block: %w", err)
// }
storageHash := getProofResponse.StorageHash
payload.WithdrawalsRoot = &storageHash
}

status, err := d.l2Engine.NewPayload(ctx, payload, envelope.ParentBeaconBlockRoot)
if err != nil {
return nil, fmt.Errorf("new payload: %w", err)
Expand Down
8 changes: 4 additions & 4 deletions op-program/client/l2/engineapi/l2_engine_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ func (ea *L2EngineAPI) NewPayloadV1(ctx context.Context, payload *eth.ExecutionP
return &eth.PayloadStatusV1{Status: eth.ExecutionInvalid}, engine.InvalidParams.With(errors.New("withdrawals not supported in V1"))
}

return ea.newPayload(ctx, payload, nil, nil)
return ea.newPayload(ctx, payload, nil, nil, ea.backend.Config())
}

func (ea *L2EngineAPI) NewPayloadV2(ctx context.Context, payload *eth.ExecutionPayload) (*eth.PayloadStatusV1, error) {
Expand All @@ -313,7 +313,7 @@ func (ea *L2EngineAPI) NewPayloadV2(ctx context.Context, payload *eth.ExecutionP
return &eth.PayloadStatusV1{Status: eth.ExecutionInvalid}, engine.InvalidParams.With(errors.New("non-nil withdrawals pre-shanghai"))
}

return ea.newPayload(ctx, payload, nil, nil)
return ea.newPayload(ctx, payload, nil, nil, ea.backend.Config())
}

// Ported from: https://github.com/ethereum-optimism/op-geth/blob/c50337a60a1309a0f1dca3bf33ed1bb38c46cdd7/eth/catalyst/api.go#L486C1-L507
Expand Down Expand Up @@ -342,7 +342,7 @@ func (ea *L2EngineAPI) NewPayloadV3(ctx context.Context, params *eth.ExecutionPa
}
}

return ea.newPayload(ctx, params, versionedHashes, beaconRoot)
return ea.newPayload(ctx, params, versionedHashes, beaconRoot, ea.backend.Config())
}

func (ea *L2EngineAPI) getPayload(_ context.Context, payloadId eth.PayloadID) (*eth.ExecutionPayloadEnvelope, error) {
Expand Down Expand Up @@ -479,7 +479,7 @@ func toGethWithdrawals(payload *eth.ExecutionPayload) []*types.Withdrawal {
return result
}

func (ea *L2EngineAPI) newPayload(_ context.Context, payload *eth.ExecutionPayload, hashes []common.Hash, root *common.Hash) (*eth.PayloadStatusV1, error) {
func (ea *L2EngineAPI) newPayload(_ context.Context, payload *eth.ExecutionPayload, hashes []common.Hash, root *common.Hash, config *params.ChainConfig) (*eth.PayloadStatusV1, error) {
ea.log.Trace("L2Engine API request received", "method", "ExecutePayload", "number", payload.BlockNumber, "hash", payload.BlockHash)
txs := make([][]byte, len(payload.Transactions))
for i, tx := range payload.Transactions {
Expand Down
2 changes: 2 additions & 0 deletions op-service/eth/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,8 @@ type PayloadAttributes struct {
GasLimit *Uint64Quantity `json:"gasLimit,omitempty"`
// EIP-1559 parameters, to be specified only post-Holocene
EIP1559Params *Bytes8 `json:"eip1559Params,omitempty"`
// WithdrawalsRoot, to be specified post Isthmus as the storage root of the L2toL1MessagePasser contract
WithdrawalsRoot *common.Hash `json:"withdrawalsRoot,omitempty"`
}

// IsDepositsOnly returns whether all transactions of the PayloadAttributes are of Deposit
Expand Down
8 changes: 6 additions & 2 deletions ops/docker/ci-builder/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ COPY ./versions.json ./versions.json

RUN /bin/sh -c set -eux; \
apt-get update; \
apt-get install -y --no-install-recommends bash curl openssh-client git build-essential ca-certificates jq gnupg binutils-mips-linux-gnu python3 python3-pip python3-setuptools; \
apt-get install -y --no-install-recommends bash curl openssh-client git build-essential ca-certificates jq gnupg binutils-mips-linux-gnu python3 python3-pip python3-setuptools mercurial make binutils bison gcc bsdmainutils; \
mkdir -p /etc/apt/keyrings; \
curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg; \
chmod a+r /etc/apt/keyrings/docker.gpg; \
Expand All @@ -107,7 +107,11 @@ RUN /bin/sh -c set -eux; \
pip install capstone pyelftools; \
pip install semgrep==$(jq -r .semgrep < versions.json); \
curl -fLSs https://raw.githubusercontent.com/CircleCI-Public/circleci-cli/master/install.sh | bash; \
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.0/install.sh | bash; \
bash < <(curl -s -S -L https://raw.githubusercontent.com/moovweb/gvm/master/binscripts/gvm-installer); \
nvm install 18.12.1;

RUN apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \
rm -rf /var/lib/apt/lists/*; \
rm -rf /root/.cache/pip;

Expand Down
2 changes: 1 addition & 1 deletion versions.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@
"kontrol": "1.0.53",
"just": "1.34.0",
"binary_signer": "1.0.4",
"semgrep": "1.90.0"
"semgrep": "1.96.0"
}

0 comments on commit 6b3c027

Please sign in to comment.