Skip to content

Commit

Permalink
feat(op-supervisor): add op-supervisor component (#110)
Browse files Browse the repository at this point in the history
### 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:
ethereum-optimism/platforms-team#520
  • Loading branch information
edobry authored Jan 6, 2025
1 parent 6aba40a commit 99fe41d
Show file tree
Hide file tree
Showing 16 changed files with 333 additions and 42 deletions.
65 changes: 42 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
## Welcome to Optimism Package
# Welcome to Optimism Package

The default package for Optimism. The kurtosis package uses [op-deployer](https://github.com/ethereum-optimism/optimism/tree/develop/op-deployer) to manage
the L2 chains and all associated artifacts such as contract deployments.

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

## Quickstart
#### Run with your own configuration

### Run with your own configuration

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:

Expand All @@ -51,7 +53,7 @@ kurtosis clean -a

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

#### Run with changes to the optimism package
### Run with changes to the optimism package

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

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

# L2 Contract deployer
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.
## L2 Contract deployer

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)
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.

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)

## Configuration

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

```yaml
optimism_package:
# Interop configuration
interop:
# Whether or not to enable interop mode
enabled: false
# Default supervisor configuration
supervisor_params:
# The Docker image that should be used for the supervisor; leave blank to use the default op-supervisor image
image: ""

# A JSON string containing chain dependencies
dependency_set: ""

# A list of optional extra params that will be passed to the supervisor container for modifying its behaviour
extra_params: []
# An array of L2 networks to run
chains:
# Specification of the optimism-participants in the network
Expand Down Expand Up @@ -403,7 +419,7 @@ ethereum_package:

#### L1 customization

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:
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:

```yaml
optimism_package:
Expand Down Expand Up @@ -501,6 +517,7 @@ ethereum_package:
- dora
- blockscout
```

Note: if configuring multiple L2s, make sure that the `network_id` and `name` are set to differentiate networks.

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

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

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
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:

```
```bash
./livefuzzer spam --sk "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" --rpc http://127.0.0.1:<port> --slot-time 2
```

### Additional configurations

Please find examples of additional configurations in the [test folder](.github/tests/).

### Useful Kurtosis commands

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

* List information about running containers and open ports
- List information about running containers and open ports

```
```bash
kurtosis enclave ls
kurtosis enclave inspect <enclave-name>
```

* Inspect chain state.
- Inspect chain state.

```
```bash
kurtosis files inspect <enclave-name> op-deployer-configs
```

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

```
kurtosis enclave dump <enclave-name> -- dumps all files to a enclave-name prefixed directory under the current directory
```bash
# dumps all files to a enclave-name prefixed directory under the current directory
kurtosis enclave dump <enclave-name>
kurtosis files download <enclave-name> op-deployer-configs <where-to-download>
```

* Get logs for running services
- Get logs for running services

```
kurtosis service logs <enclave-name> <service-name> -f . (-f tails the log)
```bash
kurtosis service logs <enclave-name> <service-name> -f . # -f tails the log
```

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

```
```bash
kurtosis service stop <enclave-name> <service-name>
kurtosis service start <enclave-name> <service-name>
```
Expand All @@ -576,6 +595,6 @@ kurtosis service start <enclave-name> <service-name>

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

```
kurtosis lint --format .
```bash
kurtosis lint --format .
```
27 changes: 26 additions & 1 deletion main.star
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
ethereum_package = import_module("github.com/ethpandaops/ethereum-package/main.star")
contract_deployer = import_module("./src/contracts/contract_deployer.star")
l2_launcher = import_module("./src/l2.star")
op_supervisor_launcher = import_module(
"./src/interop/op-supervisor/op_supervisor_launcher.star"
)
wait_for_sync = import_module("./src/wait/wait_for_sync.star")
input_parser = import_module("./src/package_io/input_parser.star")
ethereum_package_static_files = import_module(
"github.com/ethpandaops/ethereum-package/src/static_files/static_files.star"
)


def run(plan, args):
Expand Down Expand Up @@ -34,6 +40,8 @@ def run(plan, args):
global_log_level = optimism_args_with_right_defaults.global_log_level
persistent = optimism_args_with_right_defaults.persistent

interop_params = optimism_args_with_right_defaults.interop

# Deploy the L1
l1_network = ""
if external_l1_args:
Expand Down Expand Up @@ -82,12 +90,19 @@ def run(plan, args):
l1_network,
)

jwt_file = plan.upload_files(
src=ethereum_package_static_files.JWT_PATH_FILEPATH,
name="op_jwt_file",
)

all_participants = []
for l2_num, chain in enumerate(optimism_args_with_right_defaults.chains):
l2_launcher.launch_l2(
all_participants += l2_launcher.launch_l2(
plan,
l2_num,
chain.network_params.name,
chain,
jwt_file,
deployment_output,
l1_config_env_vars,
l1_priv_key,
Expand All @@ -96,6 +111,16 @@ def run(plan, args):
global_node_selectors,
global_tolerations,
persistent,
interop_params,
)

if interop_params.enabled:
op_supervisor_launcher.launch(
plan,
l1_config_env_vars,
all_participants,
jwt_file,
interop_params.supervisor_params,
)


Expand Down
30 changes: 26 additions & 4 deletions src/cl/op-node/op_node_launcher.star
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ ethereum_package_input_parser = import_module(
constants = import_module("../../package_io/constants.star")

util = import_module("../../util.star")
interop_constants = import_module("../../interop/constants.star")

# ---------------------------------- Beacon client -------------------------------------

Expand Down Expand Up @@ -73,6 +74,7 @@ def launch(
existing_cl_clients,
l1_config_env_vars,
sequencer_enabled,
interop_params,
):
beacon_node_identity_recipe = PostHttpRequestRecipe(
endpoint="/",
Expand Down Expand Up @@ -104,6 +106,7 @@ def launch(
l1_config_env_vars,
beacon_node_identity_recipe,
sequencer_enabled,
interop_params,
)

beacon_service = plan.add_service(service_name, config)
Expand Down Expand Up @@ -148,6 +151,7 @@ def get_beacon_config(
l1_config_env_vars,
beacon_node_identity_recipe,
sequencer_enabled,
interop_params,
):
EXECUTION_ENGINE_ENDPOINT = "http://{0}:{1}".format(
el_context.ip_addr,
Expand Down Expand Up @@ -223,10 +227,27 @@ def get_beacon_config(
],
)

ports = {}
ports.update(used_ports)
ports = dict(used_ports)

env_vars = dict(participant.cl_extra_env_vars)

if interop_params.enabled:
ports[
interop_constants.INTEROP_WS_PORT_ID
] = ethereum_package_shared_utils.new_port_spec(
interop_constants.INTEROP_WS_PORT_NUM,
ethereum_package_shared_utils.TCP_PROTOCOL,
)

env_vars.update(
{
"OP_NODE_INTEROP_SUPERVISOR": interop_constants.SUPERVISOR_ENDPOINT,
"OP_NODE_INTEROP_RPC_ADDR": "0.0.0.0",
"OP_NODE_INTEROP_RPC_PORT": str(interop_constants.INTEROP_WS_PORT_NUM),
"OP_NODE_INTEROP_JWT_SECRET": ethereum_package_constants.JWT_MOUNT_PATH_ON_CONTAINER,
}
)

env_vars = participant.cl_extra_env_vars
config_args = {
"image": participant.cl_image,
"ports": ports,
Expand Down Expand Up @@ -263,9 +284,10 @@ def get_beacon_config(
return ServiceConfig(**config_args)


def new_op_node_launcher(deployment_output, jwt_file, network_params):
def new_op_node_launcher(deployment_output, jwt_file, network_params, interop_params):
return struct(
deployment_output=deployment_output,
jwt_file=jwt_file,
network_params=network_params,
interop_params=interop_params,
)
3 changes: 3 additions & 0 deletions src/el/op-besu/op_besu_launcher.star
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ def launch(
existing_el_clients,
sequencer_enabled,
sequencer_context,
interop_params,
):
log_level = ethereum_package_input_parser.get_client_log_level_or_default(
participant.el_log_level, global_log_level, VERBOSITY_LEVELS
Expand Down Expand Up @@ -275,10 +276,12 @@ def new_op_besu_launcher(
jwt_file,
network,
network_id,
interop_params,
):
return struct(
deployment_output=deployment_output,
jwt_file=jwt_file,
network=network,
network_id=network_id,
interop_params=interop_params,
)
3 changes: 3 additions & 0 deletions src/el/op-erigon/op_erigon_launcher.star
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ def launch(
existing_el_clients,
sequencer_enabled,
sequencer_context,
interop_params,
):
log_level = ethereum_package_input_parser.get_client_log_level_or_default(
participant.el_log_level, global_log_level, VERBOSITY_LEVELS
Expand Down Expand Up @@ -270,10 +271,12 @@ def new_op_erigon_launcher(
jwt_file,
network,
network_id,
interop_params,
):
return struct(
deployment_output=deployment_output,
jwt_file=jwt_file,
network=network,
network_id=network_id,
interop_params=interop_params,
)
17 changes: 12 additions & 5 deletions src/el/op-geth/op_geth_launcher.star
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ ethereum_package_constants = import_module(
)

constants = import_module("../../package_io/constants.star")
interop_constants = import_module("../../interop/constants.star")

RPC_PORT_NUM = 8545
WS_PORT_NUM = 8546
Expand Down Expand Up @@ -104,6 +105,7 @@ def launch(
existing_el_clients,
sequencer_enabled,
sequencer_context,
interop_params,
):
log_level = ethereum_package_input_parser.get_client_log_level_or_default(
participant.el_log_level, global_log_level, VERBOSITY_LEVELS
Expand All @@ -124,6 +126,7 @@ def launch(
cl_client_name,
sequencer_enabled,
sequencer_context,
interop_params,
)

service = plan.add_service(service_name, config)
Expand Down Expand Up @@ -166,6 +169,7 @@ def get_config(
cl_client_name,
sequencer_enabled,
sequencer_context,
interop_params,
):
init_datadir_cmd_str = "geth init --datadir={0} --state.scheme=hash {1}".format(
EXECUTION_DATA_DIRPATH_ON_CLIENT_CONTAINER,
Expand Down Expand Up @@ -248,7 +252,12 @@ def get_config(
constants.EL_TYPE.op_geth + "_volume_size"
],
)
env_vars = participant.el_extra_env_vars

env_vars = dict(participant.cl_extra_env_vars)

if interop_params.enabled:
env_vars["GETH_ROLLUP_INTEROPRPC"] = interop_constants.SUPERVISOR_ENDPOINT

config_args = {
"image": participant.el_image,
"ports": used_ports,
Expand Down Expand Up @@ -280,14 +289,12 @@ def get_config(


def new_op_geth_launcher(
deployment_output,
jwt_file,
network,
network_id,
deployment_output, jwt_file, network, network_id, interop_params
):
return struct(
deployment_output=deployment_output,
jwt_file=jwt_file,
network=network,
network_id=network_id,
interop_params=interop_params,
)
Loading

0 comments on commit 99fe41d

Please sign in to comment.