Skip to content

Commit b6a99a3

Browse files
committed
sysgo: add Osaka activation test
1 parent 8417a3d commit b6a99a3

File tree

10 files changed

+110
-3
lines changed

10 files changed

+110
-3
lines changed

mise.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ svm-rs = "0.5.19"
1515

1616
# Go dependencies
1717
"go:github.com/ethereum/go-ethereum/cmd/abigen" = "1.15.10"
18+
"go:github.com/ethereum/go-ethereum/cmd/geth" = "ad55a3e07fe3854aa6582cca612f2fdf09915f67" # Commit contains Osaka functionality.
1819
"go:gotest.tools/gotestsum" = "1.12.1"
1920
"go:github.com/vektra/mockery/v2" = "2.46.0"
2021
"go:github.com/golangci/golangci-lint/cmd/golangci-lint" = "1.64.8"
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
package osaka
2+
3+
import (
4+
"bytes"
5+
"fmt"
6+
"os"
7+
"os/exec"
8+
"strings"
9+
"testing"
10+
"time"
11+
12+
"github.com/ethereum-optimism/optimism/op-batcher/batcher"
13+
"github.com/ethereum-optimism/optimism/op-batcher/flags"
14+
"github.com/ethereum-optimism/optimism/op-chain-ops/devkeys"
15+
"github.com/ethereum-optimism/optimism/op-devstack/devtest"
16+
"github.com/ethereum-optimism/optimism/op-devstack/presets"
17+
"github.com/ethereum-optimism/optimism/op-devstack/stack"
18+
"github.com/ethereum-optimism/optimism/op-devstack/sysgo"
19+
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/intentbuilder"
20+
"github.com/ethereum-optimism/optimism/op-service/eth"
21+
)
22+
23+
const osakaOffset = 30
24+
25+
func TestMain(m *testing.M) {
26+
// If the env var is unset, use geth (should be installed with mise).
27+
// Note that we always want a subprocess L1 EL for these tests because (as of right now) the
28+
// op-geth version we use in the monorepo does not include enough Osaka support.
29+
if _, ok := os.LookupEnv(sysgo.GethExecPathEnvVar); !ok {
30+
cmd := exec.Command("mise", "which", "geth")
31+
buf := bytes.NewBuffer([]byte{})
32+
cmd.Stdout = buf
33+
if err := cmd.Run(); err == nil {
34+
execPath := strings.TrimSpace(buf.String())
35+
fmt.Println("Found mise-installed geth:", execPath)
36+
_ = os.Setenv(sysgo.GethExecPathEnvVar, execPath)
37+
defer func() {
38+
_ = os.Setenv(sysgo.GethExecPathEnvVar, "")
39+
}()
40+
} else {
41+
fmt.Printf("Failed to find mise-installed geth: %v\n", err)
42+
}
43+
}
44+
45+
ids := sysgo.NewDefaultMinimalSystemIDs(sysgo.DefaultL1ID, sysgo.DefaultL2AID)
46+
opt := stack.Combine[*sysgo.Orchestrator]()
47+
opt.Add(sysgo.DefaultMinimalSystem(&ids))
48+
opt.Add(sysgo.WithDeployerOptions(
49+
func(_ devtest.P, _ devkeys.Keys, builder intentbuilder.Builder) {
50+
_, l1Config := builder.WithL1(ids.L1.ChainID())
51+
l1Config.WithOsakaOffset(osakaOffset)
52+
}))
53+
opt.Add(sysgo.WithBatcherOption(func(_ stack.L2BatcherID, cfg *batcher.CLIConfig) {
54+
cfg.DataAvailabilityType = flags.BlobsType
55+
}))
56+
presets.DoMain(m, stack.MakeCommon(opt))
57+
}
58+
59+
func TestOsakaActivation(gt *testing.T) {
60+
t := devtest.SerialT(gt)
61+
sys := presets.NewMinimal(t)
62+
osakaActivationTime := *sys.L1Network.Escape().ChainConfig().OsakaTime
63+
t.Log("Waiting for Osaka to activate...")
64+
for range time.Tick(sys.L1EL.EstimateBlockTime()) {
65+
ref := sys.L1EL.BlockRefByLabel(eth.Unsafe)
66+
if ref.Time >= osakaActivationTime {
67+
break
68+
}
69+
t.Logf("Waiting for Osaka activation currentBlock=%d remainingTime=%d", ref.Number, osakaActivationTime-ref.Time)
70+
}
71+
t.Log("Osaka activated")
72+
sys.L1EL.WaitForFinalization()
73+
}

op-chain-ops/genesis/config.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,8 @@ type UpgradeScheduleDeployConfig struct {
377377
L1CancunTimeOffset *hexutil.Uint64 `json:"l1CancunTimeOffset,omitempty"`
378378
// When Prague activates. Relative to L1 genesis.
379379
L1PragueTimeOffset *hexutil.Uint64 `json:"l1PragueTimeOffset,omitempty"`
380+
// When Osaka activates. Relative to L1 genesis.
381+
L1OsakaTimeOffset *hexutil.Uint64 `json:"l1OsakaTimeOffset,omitempty"`
380382
}
381383

382384
var _ ConfigChecker = (*UpgradeScheduleDeployConfig)(nil)

op-chain-ops/genesis/genesis.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ func NewL1Genesis(config *DeployConfig) (*core.Genesis, error) {
139139
DevL1DeployConfig: config.DevL1DeployConfig,
140140
L1ChainID: eth.ChainIDFromUInt64(config.L1ChainID),
141141
L1PragueTimeOffset: (*uint64)(config.L1PragueTimeOffset),
142+
L1OsakaTimeOffset: (*uint64)(config.L1OsakaTimeOffset),
142143
})
143144
}
144145

@@ -148,6 +149,8 @@ type DevL1DeployConfigMinimal struct {
148149
L1ChainID eth.ChainID
149150
// When Prague activates. Relative to L1 genesis.
150151
L1PragueTimeOffset *uint64
152+
// When Osaka activates. Relative to L1 genesis.
153+
L1OsakaTimeOffset *uint64
151154
}
152155

153156
// NewL1GenesisMinimal creates a L1 dev genesis template.
@@ -203,6 +206,10 @@ func NewL1GenesisMinimal(config *DevL1DeployConfigMinimal) (*core.Genesis, error
203206
pragueTime := uint64(timestamp) + uint64(*config.L1PragueTimeOffset)
204207
chainConfig.PragueTime = &pragueTime
205208
}
209+
if config.L1OsakaTimeOffset != nil {
210+
osakaTime := uint64(timestamp) + uint64(*config.L1OsakaTimeOffset)
211+
chainConfig.OsakaTime = &osakaTime
212+
}
206213
// Note: excess-blob-gas, blob-gas-used, withdrawals-hash, requests-hash are set to reasonable defaults for L1 by the ToBlock() function
207214
return &core.Genesis{
208215
Config: &chainConfig,

op-deployer/pkg/deployer/pipeline/seal_l1_dev_genesis.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ func SealL1DevGenesis(env *Env, intent *state.Intent, st *state.State) error {
4848
},
4949
L1ChainID: eth.ChainIDFromUInt64(intent.L1ChainID),
5050
L1PragueTimeOffset: l1DevParams.PragueTimeOffset,
51+
L1OsakaTimeOffset: l1DevParams.OsakaTimeOffset,
5152
})
5253
if err != nil {
5354
return fmt.Errorf("failed to create dev L1 genesis template: %w", err)

op-deployer/pkg/deployer/state/intent.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@ type L1DevGenesisParams struct {
5555
// PragueTimeOffset configures Prague (aka Pectra) to be activated at the given time after L1 dev genesis time.
5656
PragueTimeOffset *uint64 `json:"pragueTimeOffset" toml:"pragueTimeOffset"`
5757

58+
// OsakaTimeOffset configures Osaka (the EL changes in the Fusaka Ethereum fork) to be
59+
// activated at the given time after L1 dev genesis time.
60+
OsakaTimeOffset *uint64 `json:"osakaTimeOffset" toml:"osakaTimeOffset"`
61+
5862
// Prefund is a map of addresses to balances (in wei), to prefund in the L1 dev genesis state.
5963
// This is independent of the "Prefund" functionality that may fund a default 20 test accounts.
6064
Prefund map[common.Address]*hexutil.U256 `json:"prefund" toml:"prefund"`

op-devstack/sysgo/engine_client.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,10 @@ func (e *engineClient) GetPayloadV4(id engine.PayloadID) (*engine.ExecutionPaylo
6464
return e.getPayload(id, "engine_getPayloadV4")
6565
}
6666

67+
func (e *engineClient) GetPayloadV5(id engine.PayloadID) (*engine.ExecutionPayloadEnvelope, error) {
68+
return e.getPayload(id, "engine_getPayloadV5")
69+
}
70+
6771
func (e *engineClient) NewPayloadV2(data engine.ExecutableData) (engine.PayloadStatusV1, error) {
6872
var result engine.PayloadStatusV1
6973
if err := e.inner.CallContext(context.Background(), &result, "engine_newPayloadV2", data); err != nil {

op-e2e/e2eutils/geth/fakepos.go

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ type EngineAPI interface {
5959
ForkchoiceUpdatedV3(engine.ForkchoiceStateV1, *engine.PayloadAttributes) (engine.ForkChoiceResponse, error)
6060
ForkchoiceUpdatedV2(engine.ForkchoiceStateV1, *engine.PayloadAttributes) (engine.ForkChoiceResponse, error)
6161

62+
GetPayloadV5(engine.PayloadID) (*engine.ExecutionPayloadEnvelope, error)
6263
GetPayloadV4(engine.PayloadID) (*engine.ExecutionPayloadEnvelope, error)
6364
GetPayloadV3(engine.PayloadID) (*engine.ExecutionPayloadEnvelope, error)
6465
GetPayloadV2(engine.PayloadID) (*engine.ExecutionPayloadEnvelope, error)
@@ -157,8 +158,10 @@ func (f *FakePoS) Start() error {
157158
Withdrawals: withdrawals,
158159
}
159160
parentBeaconBlockRoot := f.FakeBeaconBlockRoot(head.Time) // parent beacon block root
160-
isCancun := f.config.IsCancun(new(big.Int).SetUint64(head.Number.Uint64()+1), newBlockTime)
161-
isPrague := f.config.IsPrague(new(big.Int).SetUint64(head.Number.Uint64()+1), newBlockTime)
161+
nextHeight := new(big.Int).SetUint64(head.Number.Uint64() + 1)
162+
isCancun := f.config.IsCancun(nextHeight, newBlockTime)
163+
isPrague := f.config.IsPrague(nextHeight, newBlockTime)
164+
isOsaka := f.config.IsOsaka(nextHeight, newBlockTime)
162165
if isCancun {
163166
attrs.BeaconRoot = &parentBeaconBlockRoot
164167
}
@@ -192,7 +195,9 @@ func (f *FakePoS) Start() error {
192195
return nil
193196
}
194197
var envelope *engine.ExecutionPayloadEnvelope
195-
if isPrague {
198+
if isOsaka {
199+
envelope, err = f.engineAPI.GetPayloadV5(*res.PayloadID)
200+
} else if isPrague {
196201
envelope, err = f.engineAPI.GetPayloadV4(*res.PayloadID)
197202
} else if isCancun {
198203
envelope, err = f.engineAPI.GetPayloadV3(*res.PayloadID)

op-e2e/e2eutils/intentbuilder/builder.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ type L1Configurator interface {
2828
WithGasLimit(v uint64) L1Configurator
2929
WithExcessBlobGas(v uint64) L1Configurator
3030
WithPragueOffset(v uint64) L1Configurator
31+
WithOsakaOffset(v uint64) L1Configurator
3132
WithPrefundedAccount(addr common.Address, amount uint256.Int) L1Configurator
3233
}
3334

@@ -303,6 +304,12 @@ func (c *l1Configurator) WithPragueOffset(v uint64) L1Configurator {
303304
return c
304305
}
305306

307+
func (c *l1Configurator) WithOsakaOffset(v uint64) L1Configurator {
308+
c.initL1DevGenesisParams()
309+
c.builder.intent.L1DevGenesisParams.OsakaTimeOffset = &v
310+
return c
311+
}
312+
306313
func (c *l1Configurator) WithPrefundedAccount(addr common.Address, amount uint256.Int) L1Configurator {
307314
c.initL1DevGenesisParams()
308315
c.builder.intent.L1DevGenesisParams.Prefund[addr] = (*hexutil.U256)(&amount)

op-e2e/e2eutils/intentbuilder/builder_test.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ func TestBuilder(t *testing.T) {
3636

3737
// Configure L1
3838
pragueOffset := uint64(100)
39+
osakaOffset := uint64(200)
3940
alice := common.HexToAddress("0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
4041
aliceFunds := uint256.NewInt(10000)
4142
l1Params := state.L1DevGenesisParams{
@@ -45,6 +46,7 @@ func TestBuilder(t *testing.T) {
4546
ExcessBlobGas: 123,
4647
},
4748
PragueTimeOffset: &pragueOffset,
49+
OsakaTimeOffset: &osakaOffset,
4850
Prefund: map[common.Address]*hexutil.U256{
4951
alice: (*hexutil.U256)(aliceFunds),
5052
},
@@ -55,6 +57,7 @@ func TestBuilder(t *testing.T) {
5557
l1Config.WithGasLimit(l1Params.BlockParams.GasLimit)
5658
l1Config.WithExcessBlobGas(l1Params.BlockParams.ExcessBlobGas)
5759
l1Config.WithPragueOffset(*l1Params.PragueTimeOffset)
60+
l1Config.WithOsakaOffset(*l1Params.OsakaTimeOffset)
5861
l1Config.WithPrefundedAccount(alice, *aliceFunds)
5962

6063
// Configure L2

0 commit comments

Comments
 (0)