Skip to content

Commit 99fe41d

Browse files
authored
feat(op-supervisor): add op-supervisor component (#110)
### Description This PR adds the [`op-supervisor`](https://github.com/ethereum-optimism/optimism/tree/develop/op-supervisor) component to the package, along with a new `interop` configuration section. It also wires `op-supervisor` up to `op-node` and `op-geth`. #### Example configuration The configuration options for the `interop` section can be set as follows: ```yaml optimism_package: interop: enabled: true supervisor_params: image: us-docker.pkg.dev/oplabs-tools-artifacts/images/op-supervisor:e0a34554c72d56808d3db52da3b87d36ab7ed2f0 dependency_set: | { "dependencies": { "2151908": { "chainIndex": "2151908", "activationTime": 0, "historyMinTime": 0 } } } extra_params: - --test-param # note that you must also set an interop_time_offset # on the chains participating in the interoperability set chains: - participants: - el_type: op-geth # ... network_params: network: "kurtosis" # ... interop_time_offset: 0 ``` #### Successful logs After executing `kurtosis run`, the `op-supervisor` service printed the following log messages, indicating a successful boot: ``` [op-supervisor] t=2024-12-19T16:16:39+0000 lvl=info msg="Initializing Supervisor" [op-supervisor] t=2024-12-19T16:16:39+0000 lvl=info msg="Metrics disabled" [op-supervisor] t=2024-12-19T16:16:39+0000 lvl=info msg="Opening entry database" path=/db/2151908/log.db [op-supervisor] t=2024-12-19T16:16:39+0000 lvl=info msg="Opening entry database" path=/db/2151908/local_safe.db [op-supervisor] t=2024-12-19T16:16:39+0000 lvl=info msg="Opening entry database" path=/db/2151908/cross_safe.db [op-supervisor] t=2024-12-19T16:16:39+0000 lvl=info msg="attaching RPC to chain processor" rpc=http://172.16.0.22:8545 [op-supervisor] t=2024-12-19T16:16:39+0000 lvl=info msg="Admin RPC enabled" [op-supervisor] t=2024-12-19T16:16:39+0000 lvl=info msg="Starting JSON-RPC server" [op-supervisor] t=2024-12-19T16:16:39+0000 lvl=info msg="Resuming, but found no DB contents" chain=2151908 [op-supervisor] t=2024-12-19T16:16:39+0000 lvl=info msg="JSON-RPC Server started" endpoint=[::]:8545 [op-supervisor] t=2024-12-19T16:16:44+0000 lvl=info msg="Updated local unsafe" chain=2151908 block=0x39cafdf728927312683427d088de806fc82f8726f7ec96defc25765da5521fb7:0 [op-supervisor] t=2024-12-19T16:16:44+0000 lvl=info msg="Indexed block events" chain=2151908 block=0x39cafdf728927312683427d088de806fc82f8726f7ec96defc25765da5521fb7:0 txs=0 [op-supervisor] t=2024-12-19T16:16:49+0000 lvl=info msg="Updated local unsafe" chain=2151908 block=0x0228dfb30ecc00f572e5b938c1c4f30d922e3669dfc9e0f93e2a9ebb46b9b1af:1 [op-supervisor] t=2024-12-19T16:16:49+0000 lvl=info msg="Indexed block events" chain=2151908 block=0x0228dfb30ecc00f572e5b938c1c4f30d922e3669dfc9e0f93e2a9ebb46b9b1af:1 txs=1 [op-supervisor] t=2024-12-19T16:16:54+0000 lvl=info msg="Updated local unsafe" chain=2151908 block=0xefe0bdc8d8d53472bcdae7a0a79a5cba0b1f98be0affd1705b3c43b3b27b492f:2 [op-supervisor] t=2024-12-19T16:16:54+0000 lvl=info msg="Indexed block events" chain=2151908 block=0xefe0bdc8d8d53472bcdae7a0a79a5cba0b1f98be0affd1705b3c43b3b27b492f:2 txs=1 [op-supervisor] t=2024-12-19T16:16:59+0000 lvl=info msg="Updated local unsafe" chain=2151908 block=0x77e4fe98ba86ffcbfa5df53154af56a6933ae688373c71543bba1d214eb40cec:3 [op-supervisor] t=2024-12-19T16:16:59+0000 lvl=info msg="Indexed block events" chain=2151908 block=0x77e4fe98ba86ffcbfa5df53154af56a6933ae688373c71543bba1d214eb40cec:3 txs=1 ``` ### Metadata This PR was created in support of: https://github.com/ethereum-optimism/platforms-team/issues/520
1 parent 6aba40a commit 99fe41d

16 files changed

Lines changed: 333 additions & 42 deletions

README.md

Lines changed: 42 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
## Welcome to Optimism Package
1+
# Welcome to Optimism Package
2+
23
The default package for Optimism. The kurtosis package uses [op-deployer](https://github.com/ethereum-optimism/optimism/tree/develop/op-deployer) to manage
34
the L2 chains and all associated artifacts such as contract deployments.
45

@@ -33,7 +34,8 @@ Please note, by default your network will be running a `minimal` preset Ethereum
3334
You can also completely remove `ethereum_package` from your configuration in which case it will default to a `minimal` preset Ethereum network.
3435

3536
## Quickstart
36-
#### Run with your own configuration
37+
38+
### Run with your own configuration
3739

3840
Kurtosis packages are parameterizable, meaning you can customize your network and its behavior to suit your needs by storing parameters in a file that you can pass in at runtime like so:
3941

@@ -51,7 +53,7 @@ kurtosis clean -a
5153

5254
This will stop and remove all running enclaves and **delete all data**.
5355

54-
#### Run with changes to the optimism package
56+
### Run with changes to the optimism package
5557

5658
If you are attempting to test any changes to the package code, you can point to the directory as the `run` argument
5759

@@ -60,11 +62,11 @@ cd ~/go/src/github.com/ethpandaops/optimism-package
6062
kurtosis run . --args-file ./network_params.yaml
6163
```
6264

63-
# L2 Contract deployer
64-
The enclave will automatically deploy an optimism L2 contract on the L1 network. The contract address will be printed in the logs. You can use this contract address to interact with the L2 network.
65+
## L2 Contract deployer
6566

66-
Please refer to this Dockerfile if you want to see how the contract deployer image is built: [Dockerfile](https://github.com/ethpandaops/eth-client-docker-image-builder/blob/master/op-contract-deployer/Dockerfile)
67+
The enclave will automatically deploy an optimism L2 contract on the L1 network. The contract address will be printed in the logs. You can use this contract address to interact with the L2 network.
6768

69+
Please refer to this Dockerfile if you want to see how the contract deployer image is built: [Dockerfile](https://github.com/ethereum-optimism/optimism/blob/develop/op-deployer/Dockerfile.default)
6870

6971
## Configuration
7072

@@ -73,6 +75,20 @@ The full YAML schema that can be passed in is as follows with the defaults provi
7375

7476
```yaml
7577
optimism_package:
78+
# Interop configuration
79+
interop:
80+
# Whether or not to enable interop mode
81+
enabled: false
82+
# Default supervisor configuration
83+
supervisor_params:
84+
# The Docker image that should be used for the supervisor; leave blank to use the default op-supervisor image
85+
image: ""
86+
87+
# A JSON string containing chain dependencies
88+
dependency_set: ""
89+
90+
# A list of optional extra params that will be passed to the supervisor container for modifying its behaviour
91+
extra_params: []
7692
# An array of L2 networks to run
7793
chains:
7894
# Specification of the optimism-participants in the network
@@ -403,7 +419,7 @@ ethereum_package:
403419

404420
#### L1 customization
405421

406-
It is required you to launch an L1 Ethereum node to interact with the L2 network. You can use the `ethereum_package` to launch an Ethereum node. The `ethereum_package` configuration is as follows:
422+
It is required for you to launch an L1 Ethereum node to interact with the L2 network. You can use the `ethereum_package` to launch an Ethereum node. The `ethereum_package` configuration is as follows:
407423

408424
```yaml
409425
optimism_package:
@@ -501,6 +517,7 @@ ethereum_package:
501517
- dora
502518
- blockscout
503519
```
520+
504521
Note: if configuring multiple L2s, make sure that the `network_id` and `name` are set to differentiate networks.
505522

506523
#### Rollup Boost for External Block Building
@@ -525,49 +542,51 @@ optimism_package:
525542

526543
#### Run tx-fuzz to send l2 transactions
527544

528-
Compile https://github.com/MariusVanDerWijden/tx-fuzz locally per instructions in the repo. Run tx-fuzz against the l2 EL client's RPC URL and using the pre-funded wallet
545+
Compile [tx-fuzz](https://github.com/MariusVanDerWijden/tx-fuzz) locally per instructions in the repo. Run tx-fuzz against the l2 EL client's RPC URL and using the pre-funded wallet:
529546

530-
```
547+
```bash
531548
./livefuzzer spam --sk "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" --rpc http://127.0.0.1:<port> --slot-time 2
532549
```
533550

534551
### Additional configurations
552+
535553
Please find examples of additional configurations in the [test folder](.github/tests/).
536554

537555
### Useful Kurtosis commands
538556

539557
#### Inspect enclave -- Container/Port information
540558

541-
* List information about running containers and open ports
559+
- List information about running containers and open ports
542560

543-
```
561+
```bash
544562
kurtosis enclave ls
545563
kurtosis enclave inspect <enclave-name>
546564
```
547565

548-
* Inspect chain state.
566+
- Inspect chain state.
549567

550-
```
568+
```bash
551569
kurtosis files inspect <enclave-name> op-deployer-configs
552570
```
553571

554-
* Dump all files generated by kurtosis to disk (for inspecting chain state/deploy configs/contract addresses etc.). A file that contains an exhaustive
572+
- Dump all files generated by kurtosis to disk (for inspecting chain state/deploy configs/contract addresses etc.). A file that contains an exhaustive
555573
set of information about the current deployment is `files/op-deployer-configs/state.json`. Deployed contract address, roles etc can all be found here.
556574

557-
```
558-
kurtosis enclave dump <enclave-name> -- dumps all files to a enclave-name prefixed directory under the current directory
575+
```bash
576+
# dumps all files to a enclave-name prefixed directory under the current directory
577+
kurtosis enclave dump <enclave-name>
559578
kurtosis files download <enclave-name> op-deployer-configs <where-to-download>
560579
```
561580

562-
* Get logs for running services
581+
- Get logs for running services
563582

564-
```
565-
kurtosis service logs <enclave-name> <service-name> -f . (-f tails the log)
583+
```bash
584+
kurtosis service logs <enclave-name> <service-name> -f . # -f tails the log
566585
```
567586

568-
* Stop/Start running service (restart sequencer/batcher/op-geth etc.)
587+
- Stop/Start running service (restart sequencer/batcher/op-geth etc.)
569588

570-
```
589+
```bash
571590
kurtosis service stop <enclave-name> <service-name>
572591
kurtosis service start <enclave-name> <service-name>
573592
```
@@ -576,6 +595,6 @@ kurtosis service start <enclave-name> <service-name>
576595

577596
If you have made changes and would like to submit a PR, test locally and make sure to run `lint` on your changes
578597

579-
```
580-
kurtosis lint --format .
598+
```bash
599+
kurtosis lint --format .
581600
```

main.star

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
11
ethereum_package = import_module("github.com/ethpandaops/ethereum-package/main.star")
22
contract_deployer = import_module("./src/contracts/contract_deployer.star")
33
l2_launcher = import_module("./src/l2.star")
4+
op_supervisor_launcher = import_module(
5+
"./src/interop/op-supervisor/op_supervisor_launcher.star"
6+
)
47
wait_for_sync = import_module("./src/wait/wait_for_sync.star")
58
input_parser = import_module("./src/package_io/input_parser.star")
9+
ethereum_package_static_files = import_module(
10+
"github.com/ethpandaops/ethereum-package/src/static_files/static_files.star"
11+
)
612

713

814
def run(plan, args):
@@ -34,6 +40,8 @@ def run(plan, args):
3440
global_log_level = optimism_args_with_right_defaults.global_log_level
3541
persistent = optimism_args_with_right_defaults.persistent
3642

43+
interop_params = optimism_args_with_right_defaults.interop
44+
3745
# Deploy the L1
3846
l1_network = ""
3947
if external_l1_args:
@@ -82,12 +90,19 @@ def run(plan, args):
8290
l1_network,
8391
)
8492

93+
jwt_file = plan.upload_files(
94+
src=ethereum_package_static_files.JWT_PATH_FILEPATH,
95+
name="op_jwt_file",
96+
)
97+
98+
all_participants = []
8599
for l2_num, chain in enumerate(optimism_args_with_right_defaults.chains):
86-
l2_launcher.launch_l2(
100+
all_participants += l2_launcher.launch_l2(
87101
plan,
88102
l2_num,
89103
chain.network_params.name,
90104
chain,
105+
jwt_file,
91106
deployment_output,
92107
l1_config_env_vars,
93108
l1_priv_key,
@@ -96,6 +111,16 @@ def run(plan, args):
96111
global_node_selectors,
97112
global_tolerations,
98113
persistent,
114+
interop_params,
115+
)
116+
117+
if interop_params.enabled:
118+
op_supervisor_launcher.launch(
119+
plan,
120+
l1_config_env_vars,
121+
all_participants,
122+
jwt_file,
123+
interop_params.supervisor_params,
99124
)
100125

101126

src/cl/op-node/op_node_launcher.star

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ ethereum_package_input_parser = import_module(
1717
constants = import_module("../../package_io/constants.star")
1818

1919
util = import_module("../../util.star")
20+
interop_constants = import_module("../../interop/constants.star")
2021

2122
# ---------------------------------- Beacon client -------------------------------------
2223

@@ -73,6 +74,7 @@ def launch(
7374
existing_cl_clients,
7475
l1_config_env_vars,
7576
sequencer_enabled,
77+
interop_params,
7678
):
7779
beacon_node_identity_recipe = PostHttpRequestRecipe(
7880
endpoint="/",
@@ -104,6 +106,7 @@ def launch(
104106
l1_config_env_vars,
105107
beacon_node_identity_recipe,
106108
sequencer_enabled,
109+
interop_params,
107110
)
108111

109112
beacon_service = plan.add_service(service_name, config)
@@ -148,6 +151,7 @@ def get_beacon_config(
148151
l1_config_env_vars,
149152
beacon_node_identity_recipe,
150153
sequencer_enabled,
154+
interop_params,
151155
):
152156
EXECUTION_ENGINE_ENDPOINT = "http://{0}:{1}".format(
153157
el_context.ip_addr,
@@ -223,10 +227,27 @@ def get_beacon_config(
223227
],
224228
)
225229

226-
ports = {}
227-
ports.update(used_ports)
230+
ports = dict(used_ports)
231+
232+
env_vars = dict(participant.cl_extra_env_vars)
233+
234+
if interop_params.enabled:
235+
ports[
236+
interop_constants.INTEROP_WS_PORT_ID
237+
] = ethereum_package_shared_utils.new_port_spec(
238+
interop_constants.INTEROP_WS_PORT_NUM,
239+
ethereum_package_shared_utils.TCP_PROTOCOL,
240+
)
241+
242+
env_vars.update(
243+
{
244+
"OP_NODE_INTEROP_SUPERVISOR": interop_constants.SUPERVISOR_ENDPOINT,
245+
"OP_NODE_INTEROP_RPC_ADDR": "0.0.0.0",
246+
"OP_NODE_INTEROP_RPC_PORT": str(interop_constants.INTEROP_WS_PORT_NUM),
247+
"OP_NODE_INTEROP_JWT_SECRET": ethereum_package_constants.JWT_MOUNT_PATH_ON_CONTAINER,
248+
}
249+
)
228250

229-
env_vars = participant.cl_extra_env_vars
230251
config_args = {
231252
"image": participant.cl_image,
232253
"ports": ports,
@@ -263,9 +284,10 @@ def get_beacon_config(
263284
return ServiceConfig(**config_args)
264285

265286

266-
def new_op_node_launcher(deployment_output, jwt_file, network_params):
287+
def new_op_node_launcher(deployment_output, jwt_file, network_params, interop_params):
267288
return struct(
268289
deployment_output=deployment_output,
269290
jwt_file=jwt_file,
270291
network_params=network_params,
292+
interop_params=interop_params,
271293
)

src/el/op-besu/op_besu_launcher.star

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ def launch(
105105
existing_el_clients,
106106
sequencer_enabled,
107107
sequencer_context,
108+
interop_params,
108109
):
109110
log_level = ethereum_package_input_parser.get_client_log_level_or_default(
110111
participant.el_log_level, global_log_level, VERBOSITY_LEVELS
@@ -275,10 +276,12 @@ def new_op_besu_launcher(
275276
jwt_file,
276277
network,
277278
network_id,
279+
interop_params,
278280
):
279281
return struct(
280282
deployment_output=deployment_output,
281283
jwt_file=jwt_file,
282284
network=network,
283285
network_id=network_id,
286+
interop_params=interop_params,
284287
)

src/el/op-erigon/op_erigon_launcher.star

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ def launch(
9797
existing_el_clients,
9898
sequencer_enabled,
9999
sequencer_context,
100+
interop_params,
100101
):
101102
log_level = ethereum_package_input_parser.get_client_log_level_or_default(
102103
participant.el_log_level, global_log_level, VERBOSITY_LEVELS
@@ -270,10 +271,12 @@ def new_op_erigon_launcher(
270271
jwt_file,
271272
network,
272273
network_id,
274+
interop_params,
273275
):
274276
return struct(
275277
deployment_output=deployment_output,
276278
jwt_file=jwt_file,
277279
network=network,
278280
network_id=network_id,
281+
interop_params=interop_params,
279282
)

src/el/op-geth/op_geth_launcher.star

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ ethereum_package_constants = import_module(
2222
)
2323

2424
constants = import_module("../../package_io/constants.star")
25+
interop_constants = import_module("../../interop/constants.star")
2526

2627
RPC_PORT_NUM = 8545
2728
WS_PORT_NUM = 8546
@@ -104,6 +105,7 @@ def launch(
104105
existing_el_clients,
105106
sequencer_enabled,
106107
sequencer_context,
108+
interop_params,
107109
):
108110
log_level = ethereum_package_input_parser.get_client_log_level_or_default(
109111
participant.el_log_level, global_log_level, VERBOSITY_LEVELS
@@ -124,6 +126,7 @@ def launch(
124126
cl_client_name,
125127
sequencer_enabled,
126128
sequencer_context,
129+
interop_params,
127130
)
128131

129132
service = plan.add_service(service_name, config)
@@ -166,6 +169,7 @@ def get_config(
166169
cl_client_name,
167170
sequencer_enabled,
168171
sequencer_context,
172+
interop_params,
169173
):
170174
init_datadir_cmd_str = "geth init --datadir={0} --state.scheme=hash {1}".format(
171175
EXECUTION_DATA_DIRPATH_ON_CLIENT_CONTAINER,
@@ -248,7 +252,12 @@ def get_config(
248252
constants.EL_TYPE.op_geth + "_volume_size"
249253
],
250254
)
251-
env_vars = participant.el_extra_env_vars
255+
256+
env_vars = dict(participant.cl_extra_env_vars)
257+
258+
if interop_params.enabled:
259+
env_vars["GETH_ROLLUP_INTEROPRPC"] = interop_constants.SUPERVISOR_ENDPOINT
260+
252261
config_args = {
253262
"image": participant.el_image,
254263
"ports": used_ports,
@@ -280,14 +289,12 @@ def get_config(
280289

281290

282291
def new_op_geth_launcher(
283-
deployment_output,
284-
jwt_file,
285-
network,
286-
network_id,
292+
deployment_output, jwt_file, network, network_id, interop_params
287293
):
288294
return struct(
289295
deployment_output=deployment_output,
290296
jwt_file=jwt_file,
291297
network=network,
292298
network_id=network_id,
299+
interop_params=interop_params,
293300
)

0 commit comments

Comments
 (0)