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

feat: deploy multiple op l2s #20

Merged
merged 43 commits into from
Jun 18, 2024
Merged
Show file tree
Hide file tree
Changes from 36 commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
e3364b0
deploy multiple l2s
tedim52 Jun 11, 2024
cd5c11c
separate deploying factory contract and l2 contracts
tedim52 Jun 11, 2024
d1903b8
adjust network params
tedim52 Jun 11, 2024
ead655a
Merge pull request #1 from tedim52/tedi/multil2
tedim52 Jun 11, 2024
023bc7b
adjust locator
tedim52 Jun 11, 2024
bba66fe
remove redundant steps
tedim52 Jun 11, 2024
db87257
add package icon
tedim52 Jun 11, 2024
0aae947
remove priv key
tedim52 Jun 11, 2024
d3025c1
add back funding
tedim52 Jun 11, 2024
05b4a80
remove unused vars
tedim52 Jun 11, 2024
1aafeef
Apply suggestions from code review
tedim52 Jun 12, 2024
a0272aa
only add service suffix if > 1 l2s
tedim52 Jun 12, 2024
38a7a40
elaborate on deploy contract timing
tedim52 Jun 12, 2024
1bb1ca0
clarify comments
tedim52 Jun 12, 2024
4249230
redirect ethereum package
tedim52 Jun 13, 2024
6987bbf
prefund l2 accounts
tedim52 Jun 13, 2024
f88243f
switch to ethpandaops
tedim52 Jun 13, 2024
3fee4f2
fix json
tedim52 Jun 13, 2024
269be6b
create separate op genesis files artifacts for each roll up
tedim52 Jun 14, 2024
9900c98
Merge branch 'tedi/multil2'
tedim52 Jun 14, 2024
d9a0851
fix typo
tedim52 Jun 14, 2024
18d18b9
update locator
tedim52 Jun 14, 2024
3044b6f
use l2 rpc url
tedim52 Jun 17, 2024
682a970
address pr comments
tedim52 Jun 17, 2024
581bcb0
fix nested if else
tedim52 Jun 17, 2024
7c3925f
get private keys once
tedim52 Jun 17, 2024
ca3407d
add name
tedim52 Jun 17, 2024
75753d0
Merge branch 'main' into tedi/multil2
tedim52 Jun 17, 2024
47b4518
remove edit script
tedim52 Jun 17, 2024
4585858
add multi l2 config to readme
tedim52 Jun 17, 2024
3e0fc36
re order config
tedim52 Jun 17, 2024
87c27ba
rename locator
tedim52 Jun 17, 2024
8e88b7f
update readme
tedim52 Jun 17, 2024
bf13744
rm num from prefix
tedim52 Jun 17, 2024
ccfcaf6
add multi roll up yaml
tedim52 Jun 17, 2024
08bbfa0
- -> _
tedim52 Jun 17, 2024
d72c769
fix typo
tedim52 Jun 17, 2024
e8010a8
adjust docstring
tedim52 Jun 17, 2024
e88592f
rm commented sections
tedim52 Jun 17, 2024
e61f875
suffix only if multiple l2s
tedim52 Jun 18, 2024
3dd1ca2
add sanity check
barnabasbusa Jun 18, 2024
71489ac
add some tests
barnabasbusa Jun 18, 2024
332020b
add some tests
barnabasbusa Jun 18, 2024
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
31 changes: 31 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,3 +92,34 @@ ethereum_package:
- dora
- blockscout
```

Additionally, you can spin up multipl L2 networks by providing a list of L2 configuration parameters like so:

```yaml
optimism_package:
- participants:
- el_type: op-geth
network_params:
name: op_rollup_one
network_id: "3151909"
preset: minimal
additional_services:
- blockscout
- participants:
- el_type: op-geth
network_params:
name: op_rollup_two
network_id: "3151910"
additional_services:
- blockscout
ethereum_package:
participants:
- el_type: geth
- el_type: reth
network_params:
preset: minimal
additional_services:
- dora
- blockscout
```
Note: if configuring multiple L2s, make sure that the `network_id` and `name` are set to differentiate networks.
Binary file added kurtosis-package-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
138 changes: 40 additions & 98 deletions main.star
Original file line number Diff line number Diff line change
@@ -1,123 +1,65 @@
input_parser = import_module("./src/package_io/input_parser.star")
ethereum_package = import_module("github.com/ethpandaops/ethereum-package/main.star")
contract_deployer = import_module("./src/contracts/contract_deployer.star")
static_files = import_module(
"github.com/ethpandaops/ethereum-package/src/static_files/static_files.star"
)
participant_network = import_module("./src/participant_network.star")
blockscout = import_module("./src/blockscout/blockscout_launcher.star")


def get_l1_stuff(all_l1_participants, l1_network_params):
env_vars = {}
env_vars["L1_RPC_KIND"] = "any"
env_vars["WEB3_RPC_URL"] = str(all_l1_participants[0].el_context.rpc_http_url)
env_vars["L1_RPC_URL"] = str(all_l1_participants[0].el_context.rpc_http_url)
env_vars["CL_RPC_URL"] = str(all_l1_participants[0].cl_context.beacon_http_url)
env_vars["L1_CHAIN_ID"] = str(l1_network_params.network_id)
env_vars["L1_BLOCK_TIME"] = str(l1_network_params.seconds_per_slot)
env_vars["DEPLOYMENT_OUTFILE"] = (
"/workspace/optimism/packages/contracts-bedrock/deployments/"
+ str(l1_network_params.network_id)
+ "/kurtosis.json"
)
env_vars["STATE_DUMP_PATH"] = (
"/workspace/optimism/packages/contracts-bedrock/deployments/"
+ str(l1_network_params.network_id)
+ "/state-dump.json"
)

return env_vars
static_files = import_module("github.com/ethpandaops/ethereum-package/src/static_files/static_files.star")
l2_launcher = import_module("./src/l2.star")
input_parser = import_module("./src/package_io/input_parser.star")


def run(plan, args={}):
"""Deploy a Optimism L2 with a local L1.
def run(plan, args):
"""Deploy Optimism L2s on an Ethereum L1.

Args:
args(yaml): Configures other aspects of the environment.
args(json): Configures other aspects of the environment.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

currently, our package indexer only picks up json (you can still pass it in as yaml but starlark converts it to json) so in order for the package to show up in package catalog, has to be set to json instead of yaml. I can update package indexer to support yaml type as well

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

which package indexer?

Returns:
A full deployment of Optimism L2
Full Optimism L2s.
"""

# Parse the values for the args
plan.print("Parsing the L1 input args")

ethereum_args = args["ethereum_package"]

# Deploy the L1
plan.print("Deploying a local L1")
l1 = ethereum_package.run(plan, ethereum_args)

# Get L1 info
all_l1_participants = l1.all_participants
l1_network_params = l1.network_params
l1_priv_key = l1.pre_funded_accounts[
12
].private_key # reserved for L2 contract deployer
# Deploy L2 smart contracts
# Parse the values for the args
plan.print("Parsing the L2 input args")
optimism_args = args["optimism_package"]

l1_config_env_vars = get_l1_stuff(all_l1_participants, l1_network_params)
l1_priv_key = l1.pre_funded_accounts[12].private_key # reserved for L2 contract deployers
l1_config_env_vars = get_l1_config(all_l1_participants, l1_network_params)

args_with_right_defaults = input_parser.input_parser(plan, optimism_args)
network_params = args_with_right_defaults.network_params
# Deploy Create2 Factory contract (only need to do this once for multiple l2s)
l2_private_keys = contract_deployer.deploy_factory_contract(plan, l1_priv_key, l1_config_env_vars)

l2_config_env_vars = {}
l2_config_env_vars["L2_CHAIN_ID"] = str(network_params.network_id)
l2_config_env_vars["L2_BLOCK_TIME"] = str(network_params.seconds_per_slot)
# Deploy L2s
if type(args["optimism_package"]) == "dict":
l2_services_suffix = "" # no suffix if one l2
l2_launcher.launch_l2(plan, l2_services_suffix, args["optimism_package"], l1_config_env_vars, l1_priv_key, all_l1_participants[0].el_context, l2_private_keys)
elif type(args["optimism_package"]) == "list":
for l2_num, l2_args in enumerate(args["optimism-package"]):
l2_services_suffix = "-{0}".format(l2_args["network_params"]["name"]) # suffix with rollup name, and enforce a name is provided to distinguish them
l2_launcher.launch_l2(plan, l2_num, l2_services_suffix, l1_config_env_vars, l1_priv_key, all_l1_participants[0].el_context, l2_private_keys)
else:
fail("invalid type provided for param: `optimism-package`")

(
el_cl_data,
gs_private_keys,
l2oo_address,
l1_bridge_address,
blockscout_env_variables,
) = contract_deployer.launch_contract_deployer(
plan,
l1_priv_key,
l1_config_env_vars,
l2_config_env_vars,
)

# Deploy the L2
plan.print("Deploying a local L2")

jwt_file = plan.upload_files(
src=static_files.JWT_PATH_FILEPATH,
name="op_jwt_file",
def get_l1_config(all_l1_participants, l1_network_params):
env_vars = {}
env_vars["L1_RPC_KIND"] = "any"
env_vars["WEB3_RPC_URL"] = str(all_l1_participants[0].el_context.rpc_http_url)
env_vars["L1_RPC_URL"] = str(all_l1_participants[0].el_context.rpc_http_url)
env_vars["CL_RPC_URL"] = str(all_l1_participants[0].cl_context.beacon_http_url)
env_vars["L1_CHAIN_ID"] = str(l1_network_params.network_id)
env_vars["L1_BLOCK_TIME"] = str(l1_network_params.seconds_per_slot)
env_vars["DEPLOYMENT_OUTFILE"] = (
"/workspace/optimism/packages/contracts-bedrock/deployments/"
+ str(l1_network_params.network_id)
+ "/kurtosis.json"
)

all_l2_participants = participant_network.launch_participant_network(
plan,
args_with_right_defaults.participants,
jwt_file,
network_params,
el_cl_data,
gs_private_keys,
l1_config_env_vars,
l2oo_address,
env_vars["STATE_DUMP_PATH"] = (
"/workspace/optimism/packages/contracts-bedrock/deployments/"
+ str(l1_network_params.network_id)
+ "/state-dump.json"
)

all_el_contexts = []
all_cl_contexts = []
for participant in all_l2_participants:
all_el_contexts.append(participant.el_context)
all_cl_contexts.append(participant.cl_context)
return env_vars

for additional_service in args_with_right_defaults.additional_services:
if additional_service == "blockscout":
plan.print("Launching op-blockscout")
blockscout_launcher = blockscout.launch_blockscout(
plan,
all_l1_participants[0].el_context, # first L1 EL url,
l2oo_address,
blockscout_env_variables,
)
plan.print("Successfully launched op-blockscout")

plan.print(all_l2_participants)
plan.print(
"Begin your L2 adventures by depositing some L1 Kurtosis ETH to: {0}".format(
l1_bridge_address
)
)
3 changes: 1 addition & 2 deletions network_params.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,4 @@ ethereum_package:
preset: minimal
additional_services:
- dora
- blockscout

- blockscout
21 changes: 21 additions & 0 deletions network_params_two_rollups.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
ethereum_package:
participants:
- el_type: geth
- el_type: reth
network_params:
preset: minimal
optimism_package:
- participants:
- el_type: op-geth
additional_services:
- blockscout
network_params:
name: op-rollup-one
network_id: "3151909"
- participants:
- el_type: op-geth
network_params:
name: op-rollup-two
network_id: "3151910"
additional_services:
- blockscout
40 changes: 26 additions & 14 deletions src/blockscout/blockscout_launcher.star
Original file line number Diff line number Diff line change
Expand Up @@ -45,32 +45,43 @@ VERIF_USED_PORTS = {

def launch_blockscout(
plan,
el_context,
l2_services_suffix,
l1_el_context,
l2_el_context,
l2oo_address,
l2_network_name,
additional_env_vars,
):
postgres_output = postgres.run(
plan,
service_name="{0}-postgres".format(SERVICE_NAME_BLOCKSCOUT),
service_name="{0}-postgres{1}".format(
SERVICE_NAME_BLOCKSCOUT, l2_services_suffix
),
database="blockscout",
extra_configs=["max_connections=1000"],
)

config_verif = get_config_verif()
verif_service_name = "{}-verif".format(SERVICE_NAME_BLOCKSCOUT)
verif_service_name = "{0}-verif{1}".format(
SERVICE_NAME_BLOCKSCOUT, l2_services_suffix
)
verif_service = plan.add_service(verif_service_name, config_verif)
verif_url = "http://{}:{}/api".format(
verif_service.hostname, verif_service.ports["http"].number
)

config_backend = get_config_backend(
postgres_output,
el_context,
l1_el_context,
l2_el_context,
verif_url,
l2oo_address,
l2_network_name,
additional_env_vars,
)
blockscout_service = plan.add_service(SERVICE_NAME_BLOCKSCOUT, config_backend)
blockscout_service = plan.add_service(
"{0}{1}".format(SERVICE_NAME_BLOCKSCOUT, l2_services_suffix), config_backend
)
plan.print(blockscout_service)

blockscout_url = "http://{}:{}".format(
Expand All @@ -97,7 +108,7 @@ def get_config_verif():


def get_config_backend(
postgres_output, el_context, verif_url, l2oo_address, additional_env_vars
postgres_output, l1_el_context, l2_el_context, verif_url, l2oo_address, l2_network_name, additional_env_vars
):
database_url = "{protocol}://{user}:{password}@{hostname}:{port}/{database}".format(
protocol="postgresql",
Expand All @@ -110,7 +121,7 @@ def get_config_backend(

optimism_env_vars = {
"CHAIN_TYPE": "optimism",
"INDEXER_OPTIMISM_L1_RPC": el_context.rpc_http_url,
"INDEXER_OPTIMISM_L1_RPC": l1_el_context.rpc_http_url,
# "INDEXER_OPTIMISM_L1_PORTAL_CONTRACT": "",
# "INDEXER_OPTIMISM_L1_BATCH_START_BLOCK": "",
"INDEXER_OPTIMISM_L1_BATCH_INBOX": "0xff00000000000000000000000000000000042069",
Expand All @@ -136,20 +147,21 @@ def get_config_backend(
'bin/blockscout eval "Elixir.Explorer.ReleaseTasks.create_and_migrate()" && bin/blockscout start',
],
env_vars={
"ETHEREUM_JSONRPC_VARIANT": "erigon"
if el_context.client_name == "erigon" or el_context.client_name == "reth"
else el_context.client_name,
"ETHEREUM_JSONRPC_HTTP_URL": el_context.rpc_http_url,
"ETHEREUM_JSONRPC_TRACE_URL": el_context.rpc_http_url,
# "ETHEREUM_JSONRPC_VARIANT": "erigon"
# if l2_el_context.client_name == "erigon" or l2_el_context.client_name == "reth"
# else l2_el_context.client_name,
"ETHEREUM_JSONRPC_VARIANT": "geth",
"ETHEREUM_JSONRPC_HTTP_URL": l2_el_context.rpc_http_url,
"ETHEREUM_JSONRPC_TRACE_URL": l2_el_context.rpc_http_url,
"DATABASE_URL": database_url,
"COIN": "opETH",
"MICROSERVICE_SC_VERIFIER_ENABLED": "true",
"MICROSERVICE_SC_VERIFIER_URL": verif_url,
"MICROSERVICE_SC_VERIFIER_TYPE": "sc_verifier",
"INDEXER_DISABLE_PENDING_TRANSACTIONS_FETCHER": "true",
"ECTO_USE_SSL": "false",
"NETWORK": "Kurtosis",
"SUBNETWORK": "Kurtosis",
"NETWORK": l2_network_name,
"SUBNETWORK": l2_network_name,
"API_V2_ENABLED": "true",
"PORT": "{}".format(HTTP_PORT_NUMBER),
"SECRET_KEY_BASE": "56NtB48ear7+wMSf0IQuWDAAazhpb31qyc7GiyspBP2vh7t5zlCsF5QDv76chXeN",
Expand Down
Loading