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: add op-blockscout #11

Merged
merged 6 commits into from
Jun 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,12 @@ optimism_package:

# Seconds per slots
seconds_per_slot: 2

# Additional services to run alongside the network
# Defaults to []
# Available services:
# - blockscout
additional_services: []
```

### Additional configuration recommendations
Expand All @@ -74,6 +80,8 @@ optimism_package:
participants:
- el_type: op-geth
cl_type: op-node
additional_services:
- blockscout
ethereum_package:
participants:
- el_type: geth
Expand Down
29 changes: 27 additions & 2 deletions main.star
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ static_files = import_module(
"github.com/kurtosis-tech/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):
Expand Down Expand Up @@ -69,6 +70,8 @@ def run(plan, args={}):
el_cl_data,
gs_private_keys,
l2oo_address,
l1_bridge_address,
blockscout_env_variables,
) = contract_deployer.launch_contract_deployer(
plan,
l1_priv_key,
Expand All @@ -84,7 +87,7 @@ def run(plan, args={}):
name="op_jwt_file",
)

all_participants = participant_network.launch_participant_network(
all_l2_participants = participant_network.launch_participant_network(
plan,
args_with_right_defaults.participants,
jwt_file,
Expand All @@ -95,4 +98,26 @@ def run(plan, args={}):
l2oo_address,
)

plan.print(all_participants)
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)

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
)
)
4 changes: 2 additions & 2 deletions network_params.yaml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
optimism_package:
participants:
- el_type: op-geth
cl_type: op-node
count: 3
- el_type: op-reth
additional_services:
- blockscout
ethereum_package:
participants:
- el_type: geth
Expand Down
162 changes: 162 additions & 0 deletions src/blockscout/blockscout_launcher.star
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
shared_utils = import_module(
"github.com/kurtosis-tech/ethereum-package/src/shared_utils/shared_utils.star"
)
constants = import_module(
"github.com/kurtosis-tech/ethereum-package/src/package_io/constants.star"
)

postgres = import_module("github.com/kurtosis-tech/postgres-package/main.star")

IMAGE_NAME_BLOCKSCOUT = "blockscout/blockscout-optimism:6.6.0"
IMAGE_NAME_BLOCKSCOUT_VERIF = "ghcr.io/blockscout/smart-contract-verifier:v1.7.0"

SERVICE_NAME_BLOCKSCOUT = "op-blockscout"

HTTP_PORT_ID = "http"
HTTP_PORT_NUMBER = 4000
HTTP_PORT_NUMBER_VERIF = 8050

BLOCKSCOUT_MIN_CPU = 100
BLOCKSCOUT_MAX_CPU = 1000
BLOCKSCOUT_MIN_MEMORY = 1024
BLOCKSCOUT_MAX_MEMORY = 2048

BLOCKSCOUT_VERIF_MIN_CPU = 10
BLOCKSCOUT_VERIF_MAX_CPU = 1000
BLOCKSCOUT_VERIF_MIN_MEMORY = 10
BLOCKSCOUT_VERIF_MAX_MEMORY = 1024

USED_PORTS = {
HTTP_PORT_ID: shared_utils.new_port_spec(
HTTP_PORT_NUMBER,
shared_utils.TCP_PROTOCOL,
shared_utils.HTTP_APPLICATION_PROTOCOL,
)
}

VERIF_USED_PORTS = {
HTTP_PORT_ID: shared_utils.new_port_spec(
HTTP_PORT_NUMBER_VERIF,
shared_utils.TCP_PROTOCOL,
shared_utils.HTTP_APPLICATION_PROTOCOL,
)
}


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

config_verif = get_config_verif()
verif_service_name = "{}-verif".format(SERVICE_NAME_BLOCKSCOUT)
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,
verif_url,
l2oo_address,
additional_env_vars,
)
blockscout_service = plan.add_service(SERVICE_NAME_BLOCKSCOUT, config_backend)
plan.print(blockscout_service)

blockscout_url = "http://{}:{}".format(
blockscout_service.hostname, blockscout_service.ports["http"].number
)

return blockscout_url


def get_config_verif():
return ServiceConfig(
image=IMAGE_NAME_BLOCKSCOUT_VERIF,
ports=VERIF_USED_PORTS,
env_vars={
"SMART_CONTRACT_VERIFIER__SERVER__HTTP__ADDR": "0.0.0.0:{}".format(
HTTP_PORT_NUMBER_VERIF
)
},
min_cpu=BLOCKSCOUT_VERIF_MIN_CPU,
max_cpu=BLOCKSCOUT_VERIF_MAX_CPU,
min_memory=BLOCKSCOUT_VERIF_MIN_MEMORY,
max_memory=BLOCKSCOUT_VERIF_MAX_MEMORY,
)


def get_config_backend(
postgres_output, el_context, verif_url, l2oo_address, additional_env_vars
):
database_url = "{protocol}://{user}:{password}@{hostname}:{port}/{database}".format(
protocol="postgresql",
user=postgres_output.user,
password=postgres_output.password,
hostname=postgres_output.service.hostname,
port=postgres_output.port.number,
database=postgres_output.database,
)

optimism_env_vars = {
"CHAIN_TYPE": "optimism",
"INDEXER_OPTIMISM_L1_RPC": el_context.rpc_http_url,
# "INDEXER_OPTIMISM_L1_PORTAL_CONTRACT": "",
# "INDEXER_OPTIMISM_L1_BATCH_START_BLOCK": "",
"INDEXER_OPTIMISM_L1_BATCH_INBOX": "0xff00000000000000000000000000000000042069",
"INDEXER_OPTIMISM_L1_BATCH_SUBMITTER": "0x776463f498A63a42Ac1AFc7c64a4e5A9ccBB4d32",
"INDEXER_OPTIMISM_L1_BATCH_BLOCKSCOUT_BLOBS_API_URL": verif_url + "/blobs",
"INDEXER_OPTIMISM_L1_BATCH_BLOCKS_CHUNK_SIZE": "4",
"INDEXER_OPTIMISM_L2_BATCH_GENESIS_BLOCK_NUMBER": "0",
"INDEXER_OPTIMISM_L1_OUTPUT_ROOTS_START_BLOCK": "0",
# "INDEXER_OPTIMISM_L1_OUTPUT_ORACLE_CONTRACT": l2oo_address,
# "INDEXER_OPTIMISM_L1_DEPOSITS_START_BLOCK": l1_deposit_start_block,
"INDEXER_OPTIMISM_L1_DEPOSITS_BATCH_SIZE": "500",
# "INDEXER_OPTIMISM_L1_WITHDRAWALS_START_BLOCK": l1_deposit_start_block,
"INDEXER_OPTIMISM_L2_WITHDRAWALS_START_BLOCK": "1",
"INDEXER_OPTIMISM_L2_MESSAGE_PASSER_CONTRACT": "0xC0D3C0d3C0d3c0d3C0d3C0D3c0D3c0d3c0D30016",
} | additional_env_vars

return ServiceConfig(
image=IMAGE_NAME_BLOCKSCOUT,
ports=USED_PORTS,
cmd=[
"/bin/sh",
"-c",
'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,
"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",
"API_V2_ENABLED": "true",
"PORT": "{}".format(HTTP_PORT_NUMBER),
"SECRET_KEY_BASE": "56NtB48ear7+wMSf0IQuWDAAazhpb31qyc7GiyspBP2vh7t5zlCsF5QDv76chXeN",
}
| optimism_env_vars,
min_cpu=BLOCKSCOUT_MIN_CPU,
max_cpu=BLOCKSCOUT_MAX_CPU,
min_memory=BLOCKSCOUT_MIN_MEMORY,
max_memory=BLOCKSCOUT_MAX_MEMORY,
)
39 changes: 35 additions & 4 deletions src/contracts/contract_deployer.star
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,6 @@ def launch_contract_deployer(
"echo -n $GS_SEQUENCER_PRIVATE_KEY > /network-configs/GS_SEQUENCER_PRIVATE_KEY",
"echo -n $GS_BATCHER_PRIVATE_KEY > /network-configs/GS_BATCHER_PRIVATE_KEY",
"echo -n $GS_PROPOSER_PRIVATE_KEY > /network-configs/GS_PROPOSER_PRIVATE_KEY",
"cat /network-configs/kurtosis.json | jq -r .L2OutputOracleProxy > /network-configs/L2OutputOracleProxy.json",
"cat /network-configs/kurtosis.json | jq -r .L1StandardBridgeProxy > /network-configs/L1StandardBridgeProxy.json",
]
),
wait="2000s",
Expand All @@ -99,7 +97,26 @@ def launch_contract_deployer(

l2oo_address = plan.run_sh(
description="Getting the L2OutputOracleProxy address",
run="cat /network-configs/L2OutputOracleProxy.json | tr -d '\n'",
run="jq -r .L2OutputOracleProxy /network-configs/kurtosis.json | tr -d '\n'",
files={"/network-configs": op_genesis.files_artifacts[0]},
)

l1_bridge_address = plan.run_sh(
description="Getting the L1StandardBridgeProxy address",
run="jq -r .L1StandardBridgeProxy /network-configs/kurtosis.json | tr -d '\n'",
files={"/network-configs": op_genesis.files_artifacts[0]},
)

l1_deposit_start_block = plan.run_sh(
description="Getting the L1StandardBridgeProxy address",
image="badouralix/curl-jq",
run="jq -r .genesis.l1.number /network-configs/rollup.json | tr -d '\n'",
files={"/network-configs": op_genesis.files_artifacts[0]},
)

l1_portal_contract = plan.run_sh(
description="Getting the L1 portal contract",
run="jq -r .OptimismPortal /network-configs/kurtosis.json | tr -d '\n'",
files={"/network-configs": op_genesis.files_artifacts[0]},
)

Expand All @@ -109,4 +126,18 @@ def launch_contract_deployer(
"GS_PROPOSER_PRIVATE_KEY": gs_proposer_private_key.output,
}

return op_genesis.files_artifacts[0], private_keys, l2oo_address.output
blockscout_env_variables = {
"INDEXER_OPTIMISM_L1_PORTAL_CONTRACT": l1_portal_contract.output,
"INDEXER_OPTIMISM_L1_DEPOSITS_START_BLOCK": l1_deposit_start_block.output,
"INDEXER_OPTIMISM_L1_WITHDRAWALS_START_BLOCK": l1_deposit_start_block.output,
"INDEXER_OPTIMISM_L1_BATCH_START_BLOCK": l1_deposit_start_block.output,
"INDEXER_OPTIMISM_L1_OUTPUT_ORACLE_CONTRACT": l2oo_address.output,
}

return (
op_genesis.files_artifacts[0],
private_keys,
l2oo_address.output,
l1_bridge_address.output,
blockscout_env_variables,
)
6 changes: 6 additions & 0 deletions src/package_io/input_parser.star
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ ATTR_TO_BE_SKIPPED_AT_ROOT = (
)


DEFAULT_ADDITIONAL_SERVICES = []


def input_parser(plan, input_args):
result = parse_network_params(plan, input_args)

Expand All @@ -44,6 +47,9 @@ def input_parser(plan, input_args):
network_id=result["network_params"]["network_id"],
seconds_per_slot=result["network_params"]["seconds_per_slot"],
),
additional_services=result.get(
"additional_services", DEFAULT_ADDITIONAL_SERVICES
),
)


Expand Down