Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

op-e2e: Enable Fjord / RIP-7212 Test #10260

Merged
merged 2 commits into from
Apr 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ require (
rsc.io/tmplfunc v0.0.3 // indirect
)

replace github.com/ethereum/go-ethereum v1.13.11 => github.com/ethereum-optimism/op-geth v1.101311.0
replace github.com/ethereum/go-ethereum v1.13.11 => github.com/ethereum-optimism/op-geth v1.101311.1-rc.1

//replace github.com/ethereum/go-ethereum v1.13.9 => ../op-geth

Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -223,8 +223,8 @@ github.com/elastic/gosigar v0.14.2 h1:Dg80n8cr90OZ7x+bAax/QjoW/XqTI11RmA79ZwIm9/
github.com/elastic/gosigar v0.14.2/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs=
github.com/ethereum-optimism/go-ethereum-hdwallet v0.1.3 h1:RWHKLhCrQThMfch+QJ1Z8veEq5ZO3DfIhZ7xgRP9WTc=
github.com/ethereum-optimism/go-ethereum-hdwallet v0.1.3/go.mod h1:QziizLAiF0KqyLdNJYD7O5cpDlaFMNZzlxYNcWsJUxs=
github.com/ethereum-optimism/op-geth v1.101311.0 h1:n0e5WD9kEwuXb5prAO7b+2ctz/sLy6tlJ2qmbbPEi9Y=
github.com/ethereum-optimism/op-geth v1.101311.0/go.mod h1:K23yb9efVf9DdUOv/vl/Ux57Tng00rLaFqWYlFF45CA=
github.com/ethereum-optimism/op-geth v1.101311.1-rc.1 h1:oOLkib+1GGZAgOMc5cG0dcku928ml/L+1SsbBnXoGko=
github.com/ethereum-optimism/op-geth v1.101311.1-rc.1/go.mod h1:K23yb9efVf9DdUOv/vl/Ux57Tng00rLaFqWYlFF45CA=
github.com/ethereum-optimism/superchain-registry/superchain v0.0.0-20240418160534-4156733e7232 h1:jRdLJs4E3ilsDGK7+k39QPi3QKL/b1cLnyv8mfOCVo4=
github.com/ethereum-optimism/superchain-registry/superchain v0.0.0-20240418160534-4156733e7232/go.mod h1:7xh2awFQqsiZxFrHKTgEd+InVfDRrkKVUIuK8SAFHp0=
github.com/ethereum/c-kzg-4844 v0.4.0 h1:3MS1s4JtA868KpJxroZoepdV0ZKBp3u/O5HcZ7R3nlY=
Expand Down
1 change: 1 addition & 0 deletions op-chain-ops/genesis/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ func NewL2Genesis(config *DeployConfig, block *types.Block) (*core.Genesis, erro
ShanghaiTime: config.CanyonTime(block.Time()),
CancunTime: config.EcotoneTime(block.Time()),
EcotoneTime: config.EcotoneTime(block.Time()),
FjordTime: config.FjordTime(block.Time()),
InteropTime: config.InteropTime(block.Time()),
Optimism: &params.OptimismConfig{
EIP1559Denominator: eip1559Denom,
Expand Down
113 changes: 113 additions & 0 deletions op-e2e/op_geth_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,14 @@ import (
"github.com/stretchr/testify/require"
)

var (
rip7212Precompile = common.HexToAddress("0x0000000000000000000000000000000000000100")
invalid7212Data = []byte{0x00}
// This is a valid hash, r, s, x, y params for RIP-7212 taken from:
// https://gist.github.com/ulerdogan/8f1714895e23a54147fc529ea30517eb
valid7212Data = common.FromHex("4cee90eb86eaa050036147a12d49004b6b9c72bd725d39d4785011fe190f0b4da73bd4903f0ce3b639bbbf6e8e80d16931ff4bcf5993d58468e8fb19086e8cac36dbcd03009df8c59286b162af3bd7fcc0450c9aa81be5d10d312af6c66b1d604aebd3099c618202fcfe16ae7770b0c49ab5eadf74b754204a3bb6060e44eff37618b065f9832de4ca6ca971a7a1adc826d0f7c00181a5fb2ddf79ae00b4e10e")
)

// TestMissingGasLimit tests that op-geth cannot build a block without gas limit while optimism is active in the chain config.
func TestMissingGasLimit(t *testing.T) {
InitParallel(t)
Expand Down Expand Up @@ -1015,3 +1023,108 @@ func TestEcotone(t *testing.T) {
})
}
}

func TestPreFjord(t *testing.T) {
futureTimestamp := hexutil.Uint64(4)

tests := []struct {
name string
fjordTime *hexutil.Uint64
}{
{name: "FjordNotScheduled"},
{name: "FjordNotYetActive", fjordTime: &futureTimestamp},
}
for _, test := range tests {
test := test

t.Run(fmt.Sprintf("RIP7212_%s", test.name), func(t *testing.T) {
InitParallel(t)
cfg := DefaultSystemConfig(t)
s := hexutil.Uint64(0)
cfg.DeployConfig.L2GenesisCanyonTimeOffset = &s
cfg.DeployConfig.L2GenesisDeltaTimeOffset = &s
cfg.DeployConfig.L2GenesisEcotoneTimeOffset = &s
cfg.DeployConfig.L2GenesisFjordTimeOffset = test.fjordTime

ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
defer cancel()

opGeth, err := NewOpGeth(t, ctx, &cfg)
require.NoError(t, err)
defer opGeth.Close()

// valid request pre-fjord returns empty response
response, err := opGeth.L2Client.CallContract(ctx, ethereum.CallMsg{
To: &rip7212Precompile,
Data: valid7212Data,
}, nil)

require.NoError(t, err)
require.Equal(t, []byte{}, response, "should return empty response pre-fjord for valid signature")

// invalid request returns returns empty response
response, err = opGeth.L2Client.CallContract(ctx, ethereum.CallMsg{
To: &rip7212Precompile,
Data: invalid7212Data,
}, nil)

require.NoError(t, err)
require.Equal(t, []byte{}, response, "should return empty response for invalid signature")
})
}
}

func TestFjord(t *testing.T) {
tests := []struct {
name string
fjordTime hexutil.Uint64
activateFjord func(ctx context.Context, opGeth *OpGeth)
}{
{name: "ActivateAtGenesis", fjordTime: 0, activateFjord: func(ctx context.Context, opGeth *OpGeth) {}},
{name: "ActivateAfterGenesis", fjordTime: 2, activateFjord: func(ctx context.Context, opGeth *OpGeth) {
// Adding this block advances us to the fork time.
_, err := opGeth.AddL2Block(ctx)
require.NoError(t, err)
}},
}

for _, test := range tests {
test := test
t.Run(fmt.Sprintf("RIP7212_%s", test.name), func(t *testing.T) {
InitParallel(t)
cfg := DefaultSystemConfig(t)
s := hexutil.Uint64(0)
cfg.DeployConfig.L2GenesisCanyonTimeOffset = &s
cfg.DeployConfig.L2GenesisDeltaTimeOffset = &s
cfg.DeployConfig.L2GenesisEcotoneTimeOffset = &s
cfg.DeployConfig.L2GenesisFjordTimeOffset = &test.fjordTime

ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
defer cancel()

opGeth, err := NewOpGeth(t, ctx, &cfg)
require.NoError(t, err)
defer opGeth.Close()

test.activateFjord(ctx, opGeth)

// valid request returns one
response, err := opGeth.L2Client.CallContract(ctx, ethereum.CallMsg{
To: &rip7212Precompile,
Data: valid7212Data,
}, nil)

require.NoError(t, err)
require.Equal(t, common.LeftPadBytes([]byte{1}, 32), response, "should return 1 for valid signature")

// invalid request returns empty response, this is how the spec denotes an error.
response, err = opGeth.L2Client.CallContract(ctx, ethereum.CallMsg{
To: &rip7212Precompile,
Data: invalid7212Data,
}, nil)

require.NoError(t, err)
require.Equal(t, []byte{}, response, "should return empty response for invalid signature")
})
}
}