Skip to content

Commit 976f872

Browse files
authored
feat(devstack): add minimal preset (#15842)
This adds a lightweight preset for sanity checks. This will be used by basic acceptance tests.
1 parent 78cf366 commit 976f872

File tree

8 files changed

+205
-8
lines changed

8 files changed

+205
-8
lines changed

mise.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ anvil = "1.1.0"
3838
codecov-uploader = "0.8.0"
3939
goreleaser-pro = "2.3.2-pro"
4040
kurtosis = "1.6.0"
41-
op-acceptor = "op-acceptor/v0.2.0"
41+
op-acceptor = "op-acceptor/v0.2.1"
4242

4343
# Fake dependencies
4444
# Put things here if you need to track versions of tools or projects that can't

op-acceptance-tests/acceptance-tests.yaml

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,7 @@ gates:
88
- id: base
99
description: "Sanity/smoke acceptance tests for all networks."
1010
tests:
11-
- name: TestRPCConnectivity
12-
package: github.com/ethereum-optimism/optimism/op-acceptance-tests/tests/base
13-
- name: TestChainFork
14-
package: github.com/ethereum-optimism/optimism/op-acceptance-tests/tests/base
11+
- package: github.com/ethereum-optimism/optimism/op-acceptance-tests/tests/base
1512

1613
- id: holocene
1714
inherits:
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package base
2+
3+
import (
4+
"testing"
5+
"time"
6+
7+
"github.com/ethereum-optimism/optimism/op-devstack/devtest"
8+
"github.com/ethereum-optimism/optimism/op-devstack/presets"
9+
"github.com/stretchr/testify/require"
10+
)
11+
12+
func TestCLAdvance(gt *testing.T) {
13+
t := devtest.ParallelT(gt)
14+
sys := presets.NewMinimal(t)
15+
tracer := t.Tracer()
16+
ctx := t.Ctx()
17+
18+
blockTime := sys.L2Chain.Escape().RollupConfig().BlockTime
19+
waitTime := time.Duration(blockTime+1) * time.Second
20+
21+
num := sys.L2CL.SafeL2BlockRef().Number
22+
new_num := num
23+
require.Eventually(t, func() bool {
24+
ctx, span := tracer.Start(ctx, "check head")
25+
defer span.End()
26+
27+
new_num, num = sys.L2CL.SafeL2BlockRef().Number, new_num
28+
t.Logger().WithContext(ctx).Info("safe head", "number", new_num)
29+
return new_num > num
30+
}, 30*time.Second, waitTime)
31+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package base
2+
3+
import (
4+
"testing"
5+
6+
"github.com/ethereum-optimism/optimism/op-devstack/devtest"
7+
"github.com/ethereum-optimism/optimism/op-devstack/presets"
8+
"github.com/ethereum-optimism/optimism/op-service/eth"
9+
)
10+
11+
func TestFaucetFund(gt *testing.T) {
12+
t := devtest.ParallelT(gt)
13+
sys := presets.NewMinimal(t)
14+
tracer := t.Tracer()
15+
ctx := t.Ctx()
16+
17+
ctx, span := tracer.Start(ctx, "acquire wallets")
18+
funded := sys.Funder.NewFundedEOA(eth.Ether(2))
19+
unfunded := sys.Wallet.NewEOA(sys.L2EL)
20+
span.End()
21+
22+
_, span = tracer.Start(ctx, "transfer funds")
23+
amount := eth.OneEther
24+
funded.Transfer(unfunded.Address(), amount)
25+
t.Logger().WithContext(ctx).Info("funds transferred", "amount", amount)
26+
span.End()
27+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package base
2+
3+
import (
4+
"testing"
5+
6+
"github.com/ethereum-optimism/optimism/op-devstack/presets"
7+
)
8+
9+
// TestMain creates the test-setups against the shared backend
10+
func TestMain(m *testing.M) {
11+
presets.DoMain(m, presets.WithMinimal())
12+
13+
}

op-devstack/presets/minimal.go

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package presets
2+
3+
import (
4+
"github.com/ethereum/go-ethereum/log"
5+
6+
"github.com/ethereum-optimism/optimism/op-chain-ops/devkeys"
7+
"github.com/ethereum-optimism/optimism/op-devstack/devtest"
8+
"github.com/ethereum-optimism/optimism/op-devstack/dsl"
9+
"github.com/ethereum-optimism/optimism/op-devstack/shim"
10+
"github.com/ethereum-optimism/optimism/op-devstack/stack"
11+
"github.com/ethereum-optimism/optimism/op-devstack/stack/match"
12+
"github.com/ethereum-optimism/optimism/op-devstack/sysgo"
13+
)
14+
15+
type Minimal struct {
16+
Log log.Logger
17+
T devtest.T
18+
ControlPlane stack.ControlPlane
19+
20+
L1Network *dsl.L1Network
21+
22+
L2Chain *dsl.L2Network
23+
L2Batcher *dsl.L2Batcher
24+
L2EL *dsl.L2ELNode
25+
L2CL *dsl.L2CLNode
26+
27+
Wallet *dsl.HDWallet
28+
29+
Faucet *dsl.Faucet
30+
Funder *dsl.Funder
31+
}
32+
33+
func (m *Minimal) L2Networks() []*dsl.L2Network {
34+
return []*dsl.L2Network{
35+
m.L2Chain,
36+
}
37+
}
38+
39+
func WithMinimal() stack.CommonOption {
40+
return stack.MakeCommon(sysgo.DefaultMinimalSystem(&sysgo.DefaultMinimalSystemIDs{}))
41+
}
42+
43+
func NewMinimal(t devtest.T) *Minimal {
44+
system := shim.NewSystem(t)
45+
orch := Orchestrator()
46+
orch.Hydrate(system)
47+
48+
l2 := system.L2Network(match.Assume(t, match.L2ChainA))
49+
out := &Minimal{
50+
Log: t.Logger(),
51+
T: t,
52+
ControlPlane: orch.ControlPlane(),
53+
L1Network: dsl.NewL1Network(system.L1Network(match.FirstL1Network)),
54+
L2Chain: dsl.NewL2Network(l2),
55+
L2Batcher: dsl.NewL2Batcher(l2.L2Batcher(match.Assume(t, match.FirstL2Batcher))),
56+
L2EL: dsl.NewL2ELNode(l2.L2ELNode(match.Assume(t, match.FirstL2EL))),
57+
L2CL: dsl.NewL2CLNode(l2.L2CLNode(match.Assume(t, match.FirstL2CL)), orch.ControlPlane(), l2.ChainID()),
58+
Wallet: dsl.NewHDWallet(t, devkeys.TestMnemonic, 30),
59+
Faucet: dsl.NewFaucet(l2.Faucet(match.Assume(t, match.FirstFaucet))),
60+
}
61+
out.Funder = dsl.NewFunder(out.Wallet, out.Faucet, out.L2EL)
62+
return out
63+
}

op-devstack/sysgo/l2_cl.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,12 +71,14 @@ func (n *L2CLNode) hydrate(system stack.ExtensibleSystem) {
7171
func (n *L2CLNode) rememberPort() {
7272
userRPCPort, err := n.opNode.UserRPCPort()
7373
n.p.Require().NoError(err)
74-
interopRPCPort, err := n.opNode.InteropRPCPort()
75-
n.p.Require().NoError(err)
7674
n.cfg.RPC.ListenPort = userRPCPort
75+
7776
cfg, ok := n.cfg.InteropConfig.(*interop.Config)
7877
n.p.Require().True(ok)
79-
cfg.RPCPort = interopRPCPort
78+
79+
if interopRPCPort, err := n.opNode.InteropRPCPort(); err == nil {
80+
cfg.RPCPort = interopRPCPort
81+
}
8082
n.cfg.InteropConfig = cfg
8183
}
8284

op-devstack/sysgo/system.go

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,70 @@ import (
66
"github.com/ethereum-optimism/optimism/op-service/eth"
77
)
88

9+
type DefaultMinimalSystemIDs struct {
10+
L1 stack.L1NetworkID
11+
L1EL stack.L1ELNodeID
12+
L1CL stack.L1CLNodeID
13+
14+
L2 stack.L2NetworkID
15+
L2CL stack.L2CLNodeID
16+
L2EL stack.L2ELNodeID
17+
18+
L2Batcher stack.L2BatcherID
19+
L2Proposer stack.L2ProposerID
20+
}
21+
22+
func NewDefaultMinimalSystemIDs(l1ID, l2ID eth.ChainID) DefaultMinimalSystemIDs {
23+
ids := DefaultMinimalSystemIDs{
24+
L1: stack.L1NetworkID(l1ID),
25+
L1EL: stack.L1ELNodeID{Key: "l1", ChainID: l1ID},
26+
L1CL: stack.L1CLNodeID{Key: "l1", ChainID: l1ID},
27+
L2: stack.L2NetworkID(l2ID),
28+
L2CL: stack.L2CLNodeID{Key: "sequencer", ChainID: l2ID},
29+
L2EL: stack.L2ELNodeID{Key: "sequencer", ChainID: l2ID},
30+
L2Batcher: stack.L2BatcherID{Key: "main", ChainID: l2ID},
31+
L2Proposer: stack.L2ProposerID{Key: "main", ChainID: l2ID},
32+
}
33+
return ids
34+
}
35+
36+
func DefaultMinimalSystem(dest *DefaultMinimalSystemIDs) stack.Option[*Orchestrator] {
37+
l1ID := eth.ChainIDFromUInt64(900)
38+
l2ID := eth.ChainIDFromUInt64(901)
39+
ids := NewDefaultMinimalSystemIDs(l1ID, l2ID)
40+
41+
opt := stack.Combine[*Orchestrator]()
42+
opt.Add(stack.BeforeDeploy(func(o *Orchestrator) {
43+
o.P().Logger().Info("Setting up")
44+
}))
45+
46+
opt.Add(WithMnemonicKeys(devkeys.TestMnemonic))
47+
48+
opt.Add(WithDeployer(),
49+
WithDeployerOptions(
50+
WithLocalContractSources(),
51+
WithCommons(ids.L1.ChainID()),
52+
WithPrefundedL2(ids.L2.ChainID()),
53+
),
54+
)
55+
56+
opt.Add(WithL1Nodes(ids.L1EL, ids.L1CL))
57+
58+
opt.Add(WithL2ELNode(ids.L2EL, nil))
59+
opt.Add(WithL2CLNode(ids.L2CL, true, ids.L1CL, ids.L1EL, ids.L2EL))
60+
61+
opt.Add(WithBatcher(ids.L2Batcher, ids.L1EL, ids.L2CL, ids.L2EL))
62+
opt.Add(WithProposer(ids.L2Proposer, ids.L1EL, &ids.L2CL, nil))
63+
64+
opt.Add(WithFaucets([]stack.L1ELNodeID{ids.L1EL}, []stack.L2ELNodeID{ids.L2EL}))
65+
66+
opt.Add(stack.Finally(func(orch *Orchestrator) {
67+
*dest = ids
68+
}))
69+
70+
return opt
71+
}
72+
973
// struct of the services, so we can access them later and do not have to guess their IDs.
1074
type DefaultInteropSystemIDs struct {
1175
L1 stack.L1NetworkID

0 commit comments

Comments
 (0)