diff --git a/README.md b/README.md index eb2c3d7c..1cb22ec8 100644 --- a/README.md +++ b/README.md @@ -441,17 +441,6 @@ optimism_package: # Interval between submitting L2 output proposals proposal_internal: 10m - # Default signer configuration - signer_params: - # The Docker image that should be used for the signer; leave blank to use the default image - image: us-docker.pkg.dev/oplabs-tools-artifacts/images/op-signer - - # The Docker tag that should be used for the signer; leave blank to use the default tag - tag: "" - - # A list of optional extra params that will be passed to the signer container for modifying its behaviour - extra_params: [] - # Default MEV configuration mev_params: # The Docker image that should be used for rollup boost; leave blank to use the default rollup-boost image diff --git a/justfile b/justfile index 7cb0e9a8..0d9eecae 100644 --- a/justfile +++ b/justfile @@ -20,6 +20,3 @@ lint: --checked-calls \ --local-imports \ main.star src/ test/ - -test: - mise exec -- kurtosis-test . diff --git a/main.star b/main.star index fc58c346..b74ace39 100644 --- a/main.star +++ b/main.star @@ -107,6 +107,7 @@ def run(plan, args={}): l2_launcher.launch_l2( plan, l2_num, + chain.network_params.name, chain, jwt_file, deployment_output, @@ -133,6 +134,30 @@ def run(plan, args={}): observability_helper, ) + # challenger must launch after supervisor because it depends on it for interop + for l2_num, l2 in enumerate(l2s): + chain = optimism_args.chains[l2_num] + op_challenger_image = ( + chain.challenger_params.image + if chain.challenger_params.image != "" + else input_parser.DEFAULT_CHALLENGER_IMAGES["op-challenger"] + ) + if chain.challenger_params.enabled: + op_challenger_launcher.launch( + plan, + l2_num, + "op-challenger-{0}".format(chain.network_params.name), + chain.challenger_params.image, + l2.participants[0].el_context, + l2.participants[0].cl_context, + l1_config_env_vars, + deployment_output, + chain.network_params, + chain.challenger_params, + interop_params, + observability_helper, + ) + observability.launch( plan, observability_helper, global_node_selectors, observability_params ) diff --git a/src/alt-da/da-server/da_server_launcher.star b/src/alt-da/da-server/da_server_launcher.star index f053c3c4..757437b9 100644 --- a/src/alt-da/da-server/da_server_launcher.star +++ b/src/alt-da/da-server/da_server_launcher.star @@ -25,14 +25,13 @@ def get_used_ports(): def launch_da_server( plan, + service_name, image, cmd, - network_params, ): - service_name = "da-server-{0}".format(network_params.name) - config = get_da_server_config( plan, + service_name, image, cmd, ) @@ -50,6 +49,7 @@ def launch_da_server( def get_da_server_config( plan, + service_name, image, cmd, ): diff --git a/src/batcher/op-batcher/op_batcher_launcher.star b/src/batcher/op-batcher/op_batcher_launcher.star index 0a1f021c..0ac6bab7 100644 --- a/src/batcher/op-batcher/op_batcher_launcher.star +++ b/src/batcher/op-batcher/op_batcher_launcher.star @@ -6,27 +6,25 @@ ethereum_package_constants = import_module( "github.com/ethpandaops/ethereum-package/src/package_io/constants.star" ) -input_parser = import_module("../../package_io/input_parser.star") constants = import_module("../../package_io/constants.star") util = import_module("../../util.star") observability = import_module("../../observability/observability.star") -op_signer_launcher = import_module("../../signer/op_signer_launcher.star") +prometheus = import_module("../../observability/prometheus/prometheus_launcher.star") # # ---------------------------------- Batcher client ------------------------------------- - -SERVICE_TYPE = "batcher" -SERVICE_NAME = util.make_op_service_name(SERVICE_TYPE) +# The Docker container runs as the "op-batcher" user so we can't write to root +BATCHER_DATA_DIRPATH_ON_SERVICE_CONTAINER = "/data/op-batcher/op-batcher-data" # Port nums -HTTP_PORT_NUM = 8548 +BATCHER_HTTP_PORT_NUM = 8548 def get_used_ports(): used_ports = { constants.HTTP_PORT_ID: ethereum_package_shared_utils.new_port_spec( - HTTP_PORT_NUM, + BATCHER_HTTP_PORT_NUM, ethereum_package_shared_utils.TCP_PROTOCOL, ethereum_package_shared_utils.HTTP_APPLICATION_PROTOCOL, ), @@ -39,46 +37,48 @@ ENTRYPOINT_ARGS = ["sh", "-c"] def launch( plan, + service_name, + image, el_context, cl_context, l1_config_env_vars, - signer_context, + gs_batcher_private_key, batcher_params, network_params, observability_helper, da_server_context, ): - service_instance_name = util.make_service_instance_name( - SERVICE_NAME, network_params + config = get_batcher_config( + plan, + image, + service_name, + el_context, + cl_context, + l1_config_env_vars, + gs_batcher_private_key, + batcher_params, + observability_helper, + da_server_context, ) - service = plan.add_service( - service_instance_name, - make_service_config( - plan, - el_context, - cl_context, - l1_config_env_vars, - signer_context, - batcher_params, - observability_helper, - da_server_context, - ), - ) + service = plan.add_service(service_name, config) + service_url = util.make_service_http_url(service) observability.register_op_service_metrics_job( observability_helper, service, network_params.network ) - return service + return service_url -def make_service_config( +def get_batcher_config( plan, + image, + service_name, el_context, cl_context, l1_config_env_vars, - signer_context, + gs_batcher_private_key, batcher_params, observability_helper, da_server_context, @@ -86,7 +86,7 @@ def make_service_config( ports = dict(get_used_ports()) cmd = [ - SERVICE_NAME, + "op-batcher", "--l2-eth-rpc=" + el_context.rpc_http_url, "--rollup-rpc=" + cl_context.beacon_http_url, "--poll-interval=1s", @@ -94,9 +94,12 @@ def make_service_config( "--num-confirmations=1", "--safe-abort-nonce-too-low-count=3", "--resubmission-timeout=30s", + "--rpc.addr=0.0.0.0", + "--rpc.port=" + str(BATCHER_HTTP_PORT_NUM), + "--rpc.enable-admin", "--max-channel-duration=1", "--l1-eth-rpc=" + l1_config_env_vars["L1_RPC_URL"], - "--private-key=" + signer_context.clients[SERVICE_TYPE].key, + "--private-key=" + gs_batcher_private_key, # da commitments currently have to be sent as calldata to the batcher inbox "--data-availability-type=" + ("calldata" if da_server_context.enabled else "blobs"), @@ -107,29 +110,16 @@ def make_service_config( "--altda.da-service", ] - files = {} - # apply customizations - util.configure_op_service_rpc(cmd, HTTP_PORT_NUM) - op_signer_launcher.configure_op_signer(cmd, files, signer_context, SERVICE_TYPE) - if observability_helper.enabled: observability.configure_op_service_metrics(cmd, ports) cmd += batcher_params.extra_params - # legacy default image logic - image = ( - batcher_params.image - if batcher_params.image != "" - else input_parser.DEFAULT_BATCHER_IMAGES[SERVICE_NAME] - ) - return ServiceConfig( image=image, ports=ports, cmd=cmd, - files=files, private_ip_address_placeholder=ethereum_package_constants.PRIVATE_IP_ADDRESS_PLACEHOLDER, ) diff --git a/src/blockscout/blockscout_launcher.star b/src/blockscout/blockscout_launcher.star index 5711269c..3b68eab0 100644 --- a/src/blockscout/blockscout_launcher.star +++ b/src/blockscout/blockscout_launcher.star @@ -44,6 +44,7 @@ VERIF_USED_PORTS = { def launch_blockscout( plan, + l2_services_suffix, l1_rpc_url, l2_el_context, l2_network_name, @@ -60,13 +61,17 @@ def launch_blockscout( postgres_output = postgres.run( plan, - service_name="{0}-postgres{1}".format(SERVICE_NAME_BLOCKSCOUT, l2_network_name), + 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 = "{0}-verif{1}".format(SERVICE_NAME_BLOCKSCOUT, l2_network_name) + 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://{}:{}".format( verif_service.hostname, verif_service.ports["http"].number @@ -88,7 +93,7 @@ def launch_blockscout( }, ) blockscout_service = plan.add_service( - "{0}{1}".format(SERVICE_NAME_BLOCKSCOUT, l2_network_name), config_backend + "{0}{1}".format(SERVICE_NAME_BLOCKSCOUT, l2_services_suffix), config_backend ) plan.print(blockscout_service) diff --git a/src/challenger/op-challenger/op_challenger_launcher.star b/src/challenger/op-challenger/op_challenger_launcher.star index d0d5f817..e42852c4 100644 --- a/src/challenger/op-challenger/op_challenger_launcher.star +++ b/src/challenger/op-challenger/op_challenger_launcher.star @@ -6,19 +6,15 @@ ethereum_package_constants = import_module( "github.com/ethpandaops/ethereum-package/src/package_io/constants.star" ) -input_parser = import_module("../../package_io/input_parser.star") observability = import_module("../../observability/observability.star") -op_signer_launcher = import_module("../../signer/op_signer_launcher.star") +prometheus = import_module("../../observability/prometheus/prometheus_launcher.star") interop_constants = import_module("../../interop/constants.star") util = import_module("../../util.star") # # ---------------------------------- Challenger client ------------------------------------- -SERVICE_TYPE = "challenger" -SERVICE_NAME = util.make_op_service_name(SERVICE_TYPE) - -DATA_DIRPATH_ON_SERVICE_CONTAINER = "/data/{0}/{0}-data".format(SERVICE_NAME) +CHALLENGER_DATA_DIRPATH_ON_SERVICE_CONTAINER = "/data/op-challenger/op-challenger-data" ENTRYPOINT_ARGS = ["sh", "-c"] @@ -29,61 +25,50 @@ def get_used_ports(): def launch( plan, + l2_num, + service_name, + image, el_context, cl_context, l1_config_env_vars, - signer_context, - game_factory_address, deployment_output, network_params, challenger_params, interop_params, observability_helper, ): - service_instance_name = util.make_service_instance_name( - SERVICE_NAME, network_params + config = get_challenger_config( + plan, + l2_num, + service_name, + image, + el_context, + cl_context, + l1_config_env_vars, + deployment_output, + network_params, + challenger_params, + interop_params, + observability_helper, ) - cannon_prestate_artifact = None - if challenger_params.cannon_prestate_path: - cannon_prestate_artifact = plan.upload_files( - src=challenger_params.cannon_prestate_path, - name="{}-prestates".format(service_instance_name), - ) - - service = plan.add_service( - service_instance_name, - make_service_config( - plan, - cannon_prestate_artifact, - el_context, - cl_context, - l1_config_env_vars, - signer_context, - game_factory_address, - deployment_output, - network_params, - challenger_params, - interop_params, - observability_helper, - ), - ) + service = plan.add_service(service_name, config) observability.register_op_service_metrics_job( observability_helper, service, network_params.network ) - return service + return "op_challenger" -def make_service_config( +def get_challenger_config( plan, - cannon_prestate_artifact, + l2_num, + service_name, + image, el_context, cl_context, l1_config_env_vars, - signer_context, - game_factory_address, deployment_output, network_params, challenger_params, @@ -92,8 +77,21 @@ def make_service_config( ): ports = dict(get_used_ports()) + game_factory_address = util.read_network_config_value( + plan, + deployment_output, + "state", + ".opChainDeployments[{0}].disputeGameFactoryProxyAddress".format(l2_num), + ) + challenger_key = util.read_network_config_value( + plan, + deployment_output, + "challenger-{0}".format(network_params.network_id), + ".privateKey", + ) + cmd = [ - SERVICE_NAME, + "op-challenger", "--cannon-l2-genesis=" + "{0}/genesis-{1}.json".format( ethereum_package_constants.GENESIS_DATA_MOUNTPOINT_ON_CLIENTS, @@ -105,11 +103,11 @@ def make_service_config( network_params.network_id, ), "--game-factory-address=" + game_factory_address, - "--datadir=" + DATA_DIRPATH_ON_SERVICE_CONTAINER, + "--datadir=" + CHALLENGER_DATA_DIRPATH_ON_SERVICE_CONTAINER, "--l1-beacon=" + l1_config_env_vars["CL_RPC_URL"], "--l1-eth-rpc=" + l1_config_env_vars["L1_RPC_URL"], "--l2-eth-rpc=" + el_context.rpc_http_url, - "--private-key=" + signer_context.clients[SERVICE_TYPE].key, + "--private-key=" + challenger_key, "--rollup-rpc=" + cl_context.beacon_http_url, "--trace-type=" + ",".join(challenger_params.cannon_trace_types), ] @@ -122,8 +120,6 @@ def make_service_config( # apply customizations - op_signer_launcher.configure_op_signer(cmd, files, signer_context, SERVICE_TYPE) - if observability_helper.enabled: observability.configure_op_service_metrics(cmd, ports) @@ -140,7 +136,11 @@ def make_service_config( and challenger_params.cannon_prestates_url ): fail("Only one of cannon_prestate_path and cannon_prestates_url can be set") - elif cannon_prestate_artifact != None: + elif challenger_params.cannon_prestate_path: + cannon_prestate_artifact = plan.upload_files( + src=challenger_params.cannon_prestate_path, + name="{}-prestates".format(service_name), + ) files["/prestates"] = cannon_prestate_artifact cmd.append("--cannon-prestate=/prestates/prestate-proof.json") elif challenger_params.cannon_prestates_url: @@ -149,18 +149,15 @@ def make_service_config( fail("One of cannon_prestate_path or cannon_prestates_url must be set") cmd += challenger_params.extra_params - - # legacy default image logic - image = ( - challenger_params.image - if challenger_params.image != "" - else input_parser.DEFAULT_CHALLENGER_IMAGES[SERVICE_NAME] + cmd = "mkdir -p {0} && {1}".format( + CHALLENGER_DATA_DIRPATH_ON_SERVICE_CONTAINER, " ".join(cmd) ) return ServiceConfig( image=image, ports=ports, - cmd=cmd, + entrypoint=ENTRYPOINT_ARGS, + cmd=[cmd], files=files, private_ip_address_placeholder=ethereum_package_constants.PRIVATE_IP_ADDRESS_PLACEHOLDER, ) diff --git a/src/cl/op-node/op_node_builder_launcher.star b/src/cl/op-node/op_node_builder_launcher.star index ddb43f84..d672339d 100644 --- a/src/cl/op-node/op_node_builder_launcher.star +++ b/src/cl/op-node/op_node_builder_launcher.star @@ -168,6 +168,9 @@ def get_beacon_config( ethereum_package_constants.GENESIS_DATA_MOUNTPOINT_ON_CLIENTS, launcher.network_params.network_id, ), + "--rpc.addr=0.0.0.0", + "--rpc.port={0}".format(BEACON_HTTP_PORT_NUM), + "--rpc.enable-admin", "--l1={0}".format(l1_config_env_vars["L1_RPC_URL"]), "--l1.rpckind={0}".format(l1_config_env_vars["L1_RPC_KIND"]), "--l1.beacon={0}".format(l1_config_env_vars["CL_RPC_URL"]), @@ -206,8 +209,6 @@ def get_beacon_config( # apply customizations - util.configure_op_service_rpc(cmd, BEACON_HTTP_PORT_NUM) - if observability_helper.enabled: observability.configure_op_service_metrics(cmd, ports) @@ -229,11 +230,11 @@ def get_beacon_config( ) if sequencer_enabled: - sequencer_private_key = util.read_service_private_key( + sequencer_private_key = util.read_network_config_value( plan, launcher.deployment_output, - "sequencer", - launcher.network_params, + "sequencer-{0}".format(launcher.network_params.network_id), + ".privateKey", ) cmd += [ diff --git a/src/cl/op-node/op_node_launcher.star b/src/cl/op-node/op_node_launcher.star index 8ef256b1..433f0472 100644 --- a/src/cl/op-node/op_node_launcher.star +++ b/src/cl/op-node/op_node_launcher.star @@ -168,6 +168,9 @@ def get_beacon_config( ethereum_package_constants.GENESIS_DATA_MOUNTPOINT_ON_CLIENTS, launcher.network_params.network_id, ), + "--rpc.addr=0.0.0.0", + "--rpc.port={0}".format(BEACON_HTTP_PORT_NUM), + "--rpc.enable-admin", "--l1={0}".format(l1_config_env_vars["L1_RPC_URL"]), "--l1.rpckind={0}".format(l1_config_env_vars["L1_RPC_KIND"]), "--l1.beacon={0}".format(l1_config_env_vars["CL_RPC_URL"]), @@ -206,10 +209,14 @@ def get_beacon_config( # apply customizations - util.configure_op_service_rpc(cmd, BEACON_HTTP_PORT_NUM) - if observability_helper.enabled: - observability.configure_op_service_metrics(cmd, ports) + cmd += [ + "--metrics.enabled=true", + "--metrics.addr=0.0.0.0", + "--metrics.port={0}".format(observability.METRICS_PORT_NUM), + ] + + observability.expose_metrics_port(ports) if interop_params.enabled: ports[ @@ -229,11 +236,11 @@ def get_beacon_config( ) if sequencer_enabled: - sequencer_private_key = util.read_service_private_key( + sequencer_private_key = util.read_network_config_value( plan, launcher.deployment_output, - "sequencer", - launcher.network_params, + "sequencer-{0}".format(launcher.network_params.network_id), + ".privateKey", ) cmd += [ diff --git a/src/contracts/contract_deployer.star b/src/contracts/contract_deployer.star index ae052e1b..2b5131de 100644 --- a/src/contracts/contract_deployer.star +++ b/src/contracts/contract_deployer.star @@ -6,7 +6,7 @@ FACTORY_DEPLOYER_CODE = "0xf8a58085174876e800830186a08080b853604580600e600039806 FUND_SCRIPT_FILEPATH = "../../static_files/scripts" -util = import_module("../util.star") +utils = import_module("../util.star") ethereum_package_genesis_constants = import_module( "github.com/ethpandaops/ethereum-package/src/prelaunch_data_generator/genesis_constants/genesis_constants.star" @@ -85,15 +85,15 @@ def deploy_contracts( env_vars=l1_config_env_vars, store=[ StoreSpec( - src=util.NETWORK_DATA_DIR, + src="/network-data", name="op-deployer-configs", ) ], - run=util.join_cmds( + run=" && ".join( [ - "mkdir -p {0}".format(util.NETWORK_DATA_DIR), - "op-deployer init --intent-config-type custom --l1-chain-id $L1_CHAIN_ID --l2-chain-ids {0} --workdir {1}".format( - l2_chain_ids, util.NETWORK_DATA_DIR + "mkdir -p /network-data", + "op-deployer init --intent-config-type custom --l1-chain-id $L1_CHAIN_ID --l2-chain-ids {0} --workdir /network-data".format( + l2_chain_ids ), ] ), @@ -118,7 +118,7 @@ def deploy_contracts( plan.run_sh( name="op-deployer-fund", description="Collect keys, and fund addresses", - image=util.DEPLOYMENT_UTILS_IMAGE, + image=utils.DEPLOYMENT_UTILS_IMAGE, env_vars={ "DEPLOYER_PRIVATE_KEY": priv_key, "FUND_PRIVATE_KEY": ethereum_package_genesis_constants.PRE_FUNDED_ACCOUNTS[ @@ -130,12 +130,12 @@ def deploy_contracts( | l1_config_env_vars, store=[ StoreSpec( - src=util.NETWORK_DATA_DIR, + src="/network-data", name="op-deployer-configs", ) ], files={ - util.NETWORK_DATA_DIR: op_deployer_init.files_artifacts[0], + "/network-data": op_deployer_init.files_artifacts[0], "/fund-script": fund_script_artifact, }, run='bash /fund-script/fund.sh "{0}"'.format(l2_chain_ids), @@ -245,63 +245,51 @@ def deploy_contracts( intent["chains"].append(intent_chain) intent_json = json.encode(intent) - intent_json_artifact = util.write_to_file(plan, intent_json, "/tmp", "intent.json") + intent_json_artifact = utils.write_to_file(plan, intent_json, "/tmp", "intent.json") op_deployer_configure = plan.run_sh( name="op-deployer-configure", description="Configure L2 contract deployments", - image=util.DEPLOYMENT_UTILS_IMAGE, + image=utils.DEPLOYMENT_UTILS_IMAGE, store=[ StoreSpec( - src=util.NETWORK_DATA_DIR, + src="/network-data", name="op-deployer-configs", ) ], files={ - util.NETWORK_DATA_DIR: op_deployer_init.files_artifacts[0], + "/network-data": op_deployer_init.files_artifacts[0], "/tmp": intent_json_artifact, }, - run=util.join_cmds( + run=" && ".join( [ # zhwrd: this mess is temporary until we implement json reading for op-deployer intent file # convert intent_json to yaml. this is necessary because its unreliable to evaluate command substitutions in json. - "cat /tmp/intent.json | dasel -r json -w yaml > {0}/intent.yaml".format( - util.NETWORK_DATA_DIR - ), + """cat /tmp/intent.json | dasel -r json -w yaml > /network-data/intent.yaml""", # evaluate the command substitutions - "eval \"echo '$(cat {0}/intent.yaml)'\" | dasel -r yaml -w json > {0}/intent-b.json".format( - util.NETWORK_DATA_DIR - ), + "eval \"echo '$(cat /network-data/intent.yaml)'\" | dasel -r yaml -w json > /network-data/intent-b.json", # convert op-deployer generated intent.toml to json - "dasel -r toml -w json -f {0}/intent.toml > {0}/intent-a.json".format( - util.NETWORK_DATA_DIR - ), + "dasel -r toml -w json -f /network-data/intent.toml > /network-data/intent-a.json", # merge the two intent.json files, ensuring that the chains array is merged correctly - "jq -s 'add + {{chains: map(.chains) | transpose | map(add)}}' {0}/intent-a.json {0}/intent-b.json > {0}/intent-merged.json".format( - util.NETWORK_DATA_DIR - ), + "jq -s 'add + {chains: map(.chains) | transpose | map(add)}' /network-data/intent-a.json /network-data/intent-b.json > /network-data/intent-merged.json", # convert the merged intent.json back to toml - "cat {0}/intent-merged.json | dasel -r json -w toml > {0}/intent.toml".format( - util.NETWORK_DATA_DIR - ), + "cat /network-data/intent-merged.json | dasel -r json -w toml > /network-data/intent.toml", ] ), ) apply_cmds = [ - "op-deployer apply --l1-rpc-url $L1_RPC_URL --private-key $PRIVATE_KEY --workdir {0}".format( - util.NETWORK_DATA_DIR - ), + "op-deployer apply --l1-rpc-url $L1_RPC_URL --private-key $PRIVATE_KEY --workdir /network-data", ] for chain in optimism_args.chains: network_id = chain.network_params.network_id apply_cmds.extend( [ - "op-deployer inspect genesis --workdir {0} --outfile {0}/genesis-{1}.json {1}".format( - util.NETWORK_DATA_DIR, network_id + "op-deployer inspect genesis --workdir /network-data --outfile /network-data/genesis-{0}.json {0}".format( + network_id ), - "op-deployer inspect rollup --workdir {0} --outfile {0}/rollup-{1}.json {1}".format( - util.NETWORK_DATA_DIR, network_id + "op-deployer inspect rollup --workdir /network-data --outfile /network-data/rollup-{0}.json {0}".format( + network_id ), ] ) @@ -317,37 +305,34 @@ def deploy_contracts( | l1_config_env_vars, store=[ StoreSpec( - src=util.NETWORK_DATA_DIR, + src="/network-data", name="op-deployer-configs", ) ], files={ - util.NETWORK_DATA_DIR: op_deployer_configure.files_artifacts[0], + "/network-data": op_deployer_configure.files_artifacts[0], } | contracts_extra_files, - run=util.join_cmds(apply_cmds), - wait=None, + run=" && ".join(apply_cmds), ) for chain in optimism_args.chains: plan.run_sh( name="op-deployer-generate-chainspec", description="Generate chainspec", - image=util.DEPLOYMENT_UTILS_IMAGE, + image=utils.DEPLOYMENT_UTILS_IMAGE, env_vars={"CHAIN_ID": str(chain.network_params.network_id)}, store=[ StoreSpec( - src=util.NETWORK_DATA_DIR, + src="/network-data", name="op-deployer-configs", ) ], files={ - util.NETWORK_DATA_DIR: op_deployer_output.files_artifacts[0], + "/network-data": op_deployer_output.files_artifacts[0], "/fund-script": fund_script_artifact, }, - run='jq --from-file /fund-script/gen2spec.jq < "{0}/genesis-{1}.json" > "{0}/chainspec-{1}.json"'.format( - util.NETWORK_DATA_DIR, chain.network_params.network_id - ), + run='jq --from-file /fund-script/gen2spec.jq < "/network-data/genesis-$CHAIN_ID.json" > "/network-data/chainspec-$CHAIN_ID.json"', ) return op_deployer_output.files_artifacts[0] @@ -358,6 +343,4 @@ def chain_key(index, key): def read_chain_cmd(filename, l2_chain_id): - return "`jq -r .address {0}/{1}-{2}.json`".format( - util.NETWORK_DATA_DIR, filename, l2_chain_id - ) + return "`jq -r .address /network-data/{0}-{1}.json`".format(filename, l2_chain_id) diff --git a/src/el/op-besu/op_besu_launcher.star b/src/el/op-besu/op_besu_launcher.star index 1908000e..5d1c74cb 100644 --- a/src/el/op-besu/op_besu_launcher.star +++ b/src/el/op-besu/op_besu_launcher.star @@ -214,7 +214,7 @@ def get_config( if observability_helper.enabled: cmd += [ - "--metrics-enabled", + "--metrics-enabled=true", "--metrics-host=0.0.0.0", "--metrics-port={0}".format(observability.METRICS_PORT_NUM), ] @@ -240,11 +240,12 @@ def get_config( ) cmd += participant.el_extra_params + cmd_str = " ".join(cmd) config_args = { "image": participant.el_image, "ports": ports, - "cmd": cmd, + "cmd": [cmd_str], "files": files, "entrypoint": ENTRYPOINT_ARGS, "private_ip_address_placeholder": ethereum_package_constants.PRIVATE_IP_ADDRESS_PLACEHOLDER, diff --git a/src/el_cl_launcher.star b/src/el_cl_launcher.star index 35b6e045..0bf2f9a1 100644 --- a/src/el_cl_launcher.star +++ b/src/el_cl_launcher.star @@ -30,21 +30,22 @@ op_node_builder = import_module("./cl/op-node/op_node_builder_launcher.star") def launch( plan, + jwt_file, network_params, mev_params, - interop_params, - jwt_file, deployment_output, participants, + num_participants, l1_config_env_vars, l2_services_suffix, - da_server_context, - additional_services, global_log_level, global_node_selectors, global_tolerations, persistent, + additional_services, observability_helper, + interop_params, + da_server_context, ): el_launchers = { "op-geth": { @@ -422,5 +423,5 @@ def launch( if sequencer_enabled: sequencer_enabled = False - plan.print("Successfully added {0} EL/CL participants".format(len(participants))) + plan.print("Successfully added {0} EL/CL participants".format(num_participants)) return all_el_contexts, all_cl_contexts diff --git a/src/l2.star b/src/l2.star index 8150d981..c5cd85a8 100644 --- a/src/l2.star +++ b/src/l2.star @@ -10,6 +10,7 @@ tx_fuzzer = import_module("./transaction_fuzzer/transaction_fuzzer.star") def launch_l2( plan, l2_num, + l2_services_suffix, l2_args, jwt_file, deployment_output, @@ -41,23 +42,31 @@ def launch_l2( plan.print("Launching da-server") da_server_context = da_server_launcher.launch_da_server( plan, + "da-server-{0}".format(l2_services_suffix), da_server_image, l2_args.da_server_params.cmd, - network_params, ) plan.print("Successfully launched da-server") l2 = participant_network.launch_participant_network( plan, - l2_args, + l2_args.participants, jwt_file, + network_params, + proxyd_params, + batcher_params, + challenger_params, + proposer_params, + mev_params, deployment_output, l1_config, l2_num, + l2_services_suffix, global_log_level, global_node_selectors, global_tolerations, persistent, + l2_args.additional_services, observability_helper, interop_params, da_server_context, @@ -79,32 +88,33 @@ def launch_l2( ), ) - if "blockscout" in l2_args.additional_services: - plan.print("Launching op-blockscout") - blockscout.launch_blockscout( - plan, - l1_rpc_url, - all_el_contexts[0], # first l2 EL url - network_params.name, - deployment_output, - network_params.network_id, - ) - plan.print("Successfully launched op-blockscout") - - if "tx_fuzzer" in l2_args.additional_services: - plan.print("Launching transaction spammer") - fuzz_target = "http://{0}:{1}".format( - all_el_contexts[0].ip_addr, - all_el_contexts[0].rpc_port_num, - ) - tx_fuzzer.launch( - plan, - "op-transaction-fuzzer-{0}".format(network_params.name), - fuzz_target, - tx_fuzzer_params, - global_node_selectors, - ) - plan.print("Successfully launched transaction spammer") + for additional_service in l2_args.additional_services: + if additional_service == "blockscout": + plan.print("Launching op-blockscout") + blockscout.launch_blockscout( + plan, + l2_services_suffix, + l1_rpc_url, + all_el_contexts[0], # first l2 EL url + network_params.name, + deployment_output, + network_params.network_id, + ) + plan.print("Successfully launched op-blockscout") + elif additional_service == "tx_fuzzer": + plan.print("Launching transaction spammer") + fuzz_target = "http://{0}:{1}".format( + all_el_contexts[0].ip_addr, + all_el_contexts[0].rpc_port_num, + ) + tx_fuzzer.launch( + plan, + "op-transaction-fuzzer-{0}".format(network_params.name), + fuzz_target, + tx_fuzzer_params, + global_node_selectors, + ) + plan.print("Successfully launched transaction spammer") plan.print(l2.participants) plan.print( diff --git a/src/package_io/input_parser.star b/src/package_io/input_parser.star index 7623e078..6b857ba5 100644 --- a/src/package_io/input_parser.star +++ b/src/package_io/input_parser.star @@ -245,11 +245,6 @@ def input_parser(plan, input_args): game_type=result["proposer_params"]["game_type"], proposal_interval=result["proposer_params"]["proposal_interval"], ), - signer_params=struct( - image=result["signer_params"]["image"], - tag=result["signer_params"]["tag"], - extra_params=result["signer_params"]["extra_params"], - ), mev_params=struct( rollup_boost_image=result["mev_params"]["rollup_boost_image"], builder_host=result["mev_params"]["builder_host"], @@ -354,12 +349,8 @@ def parse_network_params(plan, input_args): challenger_params = default_challenger_params() challenger_params.update(chain.get("challenger_params", {})) - signer_params = default_signer_params() - signer_params.update(chain.get("signer_params", {})) - mev_params = default_mev_params() mev_params.update(chain.get("mev_params", {})) - da_server_params = default_da_server_params() da_server_params.update(chain.get("da_server_params", {})) @@ -441,7 +432,6 @@ def parse_network_params(plan, input_args): "batcher_params": batcher_params, "challenger_params": challenger_params, "proposer_params": proposer_params, - "signer_params": signer_params, "mev_params": mev_params, "da_server_params": da_server_params, "additional_services": chain.get( @@ -569,7 +559,6 @@ def default_chains(): "batcher_params": default_batcher_params(), "proposer_params": default_proposer_params(), "challenger_params": default_challenger_params(), - "signer_params": default_signer_params(), "mev_params": default_mev_params(), "da_server_params": default_da_server_params(), "additional_services": DEFAULT_ADDITIONAL_SERVICES, @@ -628,14 +617,6 @@ def default_proposer_params(): } -def default_signer_params(): - return { - "image": "us-docker.pkg.dev/oplabs-tools-artifacts/images/op-signer", - "tag": "v1.5.0", - "extra_params": [], - } - - def default_participant(): return { "el_type": "op-geth", diff --git a/src/package_io/sanity_check.star b/src/package_io/sanity_check.star index cd2200de..ddbc60e0 100644 --- a/src/package_io/sanity_check.star +++ b/src/package_io/sanity_check.star @@ -155,7 +155,6 @@ SUBCATEGORY_PARAMS = { "cannon_prestates_url", "cannon_trace_types", ], - "signer_params": ["image", "tag", "extra_params"], "mev_params": ["rollup_boost_image", "builder_host", "builder_port"], "da_server_params": [ "enabled", diff --git a/src/participant_network.star b/src/participant_network.star index 4da87764..b9bc8f80 100644 --- a/src/participant_network.star +++ b/src/participant_network.star @@ -6,50 +6,53 @@ op_challenger_launcher = import_module( "./challenger/op-challenger/op_challenger_launcher.star" ) op_proposer_launcher = import_module("./proposer/op-proposer/op_proposer_launcher.star") -op_signer_launcher = import_module("./signer/op_signer_launcher.star") proxyd_launcher = import_module("./proxyd/proxyd_launcher.star") util = import_module("./util.star") def launch_participant_network( plan, - chain_args, + participants, jwt_file, + network_params, + proxyd_params, + batcher_params, + challenger_params, + proposer_params, + mev_params, deployment_output, l1_config_env_vars, l2_num, + l2_services_suffix, global_log_level, global_node_selectors, global_tolerations, persistent, + additional_services, observability_helper, interop_params, da_server_context, ): - participants = chain_args.participants - network_params = chain_args.network_params - batcher_params = chain_args.batcher_params - proposer_params = chain_args.proposer_params - challenger_params = chain_args.challenger_params - + num_participants = len(participants) # First EL and sequencer CL all_el_contexts, all_cl_contexts = el_cl_client_launcher.launch( plan, - network_params, - chain_args.mev_params, - interop_params, jwt_file, + network_params, + mev_params, deployment_output, participants, + num_participants, l1_config_env_vars, - network_params.name, - da_server_context, - chain_args.additional_services, + l2_services_suffix, global_log_level, global_node_selectors, global_tolerations, persistent, + additional_services, observability_helper, + interop_params, + da_server_context, ) all_participants = [] @@ -71,34 +74,31 @@ def launch_participant_network( proxyd_launcher.launch( plan, - chain_args.proxyd_params, + proxyd_params, network_params, all_el_contexts, observability_helper, ) - # signer needs to start before its clients - signer_context = op_signer_launcher.launch( + batcher_key = util.read_network_config_value( plan, - chain_args.signer_params, - network_params, deployment_output, - { - op_batcher_launcher.SERVICE_TYPE: op_batcher_launcher.SERVICE_NAME, - op_proposer_launcher.SERVICE_TYPE: op_proposer_launcher.SERVICE_NAME, - op_challenger_launcher.SERVICE_TYPE: op_challenger_launcher.SERVICE_NAME - if challenger_params.enabled - else None, - }, - observability_helper, + "batcher-{0}".format(network_params.network_id), + ".privateKey", ) - - batcher_service = op_batcher_launcher.launch( + op_batcher_image = ( + batcher_params.image + if batcher_params.image != "" + else input_parser.DEFAULT_BATCHER_IMAGES["op-batcher"] + ) + op_batcher_launcher.launch( plan, + "op-batcher-{0}".format(l2_services_suffix), + op_batcher_image, all_el_contexts[0], all_cl_contexts[0], l1_config_env_vars, - signer_context, + batcher_key, batcher_params, network_params, observability_helper, @@ -111,32 +111,30 @@ def launch_participant_network( "state", ".opChainDeployments[{0}].disputeGameFactoryProxyAddress".format(l2_num), ) - proposer_service = op_proposer_launcher.launch( + proposer_key = util.read_network_config_value( + plan, + deployment_output, + "proposer-{0}".format(network_params.network_id), + ".privateKey", + ) + op_proposer_image = ( + proposer_params.image + if proposer_params.image != "" + else input_parser.DEFAULT_PROPOSER_IMAGES["op-proposer"] + ) + op_proposer_launcher.launch( plan, + "op-proposer-{0}".format(l2_services_suffix), + op_proposer_image, all_cl_contexts[0], l1_config_env_vars, - signer_context, + proposer_key, game_factory_address, proposer_params, network_params, observability_helper, ) - if challenger_params.enabled: - op_challenger_launcher.launch( - plan, - all_el_contexts[0], - all_cl_contexts[0], - l1_config_env_vars, - signer_context, - game_factory_address, - deployment_output, - network_params, - challenger_params, - interop_params, - observability_helper, - ) - return struct( participants=all_participants, ) diff --git a/src/proposer/op-proposer/op_proposer_launcher.star b/src/proposer/op-proposer/op_proposer_launcher.star index f71d11be..3f394ae7 100644 --- a/src/proposer/op-proposer/op_proposer_launcher.star +++ b/src/proposer/op-proposer/op_proposer_launcher.star @@ -6,20 +6,16 @@ ethereum_package_constants = import_module( "github.com/ethpandaops/ethereum-package/src/package_io/constants.star" ) -input_parser = import_module("../../package_io/input_parser.star") constants = import_module("../../package_io/constants.star") util = import_module("../../util.star") observability = import_module("../../observability/observability.star") -op_signer_launcher = import_module("../../signer/op_signer_launcher.star") +prometheus = import_module("../../observability/prometheus/prometheus_launcher.star") # -# ---------------------------------- Proposer client ------------------------------------- -SERVICE_TYPE = "proposer" -SERVICE_NAME = util.make_op_service_name(SERVICE_TYPE) - +# ---------------------------------- Batcher client ------------------------------------- # The Docker container runs as the "op-proposer" user so we can't write to root -DATA_DIRPATH_ON_SERVICE_CONTAINER = "/data/{0}/{0}-data".format(SERVICE_NAME) +DATA_DIRPATH_ON_SERVICE_CONTAINER = "/data/op-proposer/op-proposer-data" # Port nums HTTP_PORT_NUM = 8560 @@ -41,43 +37,47 @@ ENTRYPOINT_ARGS = ["sh", "-c"] def launch( plan, + service_name, + image, cl_context, l1_config_env_vars, - signer_context, + gs_proposer_private_key, game_factory_address, proposer_params, network_params, observability_helper, ): - service_instance_name = util.make_service_instance_name( - SERVICE_NAME, network_params + proposer_service_name = "{0}".format(service_name) + + config = get_proposer_config( + plan, + image, + service_name, + cl_context, + l1_config_env_vars, + gs_proposer_private_key, + game_factory_address, + proposer_params, + observability_helper, ) - service = plan.add_service( - service_instance_name, - make_service_config( - plan, - cl_context, - l1_config_env_vars, - signer_context, - game_factory_address, - proposer_params, - observability_helper, - ), - ) + service = plan.add_service(service_name, config) + http_url = util.make_service_http_url(service) observability.register_op_service_metrics_job( observability_helper, service, network_params.network ) - return service + return http_url -def make_service_config( +def get_proposer_config( plan, + image, + service_name, cl_context, l1_config_env_vars, - signer_context, + gs_proposer_private_key, game_factory_address, proposer_params, observability_helper, @@ -85,12 +85,12 @@ def make_service_config( ports = dict(get_used_ports()) cmd = [ - SERVICE_NAME, + "op-proposer", "--poll-interval=12s", "--rpc.port=" + str(HTTP_PORT_NUM), "--rollup-rpc=" + cl_context.beacon_http_url, "--game-factory-address=" + str(game_factory_address), - "--private-key=" + signer_context.clients[SERVICE_TYPE].key, + "--private-key=" + gs_proposer_private_key, "--l1-eth-rpc=" + l1_config_env_vars["L1_RPC_URL"], "--allow-non-finalized=true", "--game-type={0}".format(proposer_params.game_type), @@ -98,28 +98,16 @@ def make_service_config( "--wait-node-sync=true", ] - files = {} - # apply customizations - op_signer_launcher.configure_op_signer(cmd, files, signer_context, SERVICE_TYPE) - if observability_helper.enabled: observability.configure_op_service_metrics(cmd, ports) cmd += proposer_params.extra_params - # legacy default image logic - image = ( - proposer_params.image - if proposer_params.image != "" - else input_parser.DEFAULT_PROPOSER_IMAGES[SERVICE_NAME] - ) - return ServiceConfig( image=image, ports=ports, cmd=cmd, - files=files, private_ip_address_placeholder=ethereum_package_constants.PRIVATE_IP_ADDRESS_PLACEHOLDER, ) diff --git a/src/signer/op_signer_launcher.star b/src/signer/op_signer_launcher.star deleted file mode 100644 index a13776b2..00000000 --- a/src/signer/op_signer_launcher.star +++ /dev/null @@ -1,410 +0,0 @@ -ethereum_package_shared_utils = import_module( - "github.com/ethpandaops/ethereum-package/src/shared_utils/shared_utils.star" -) - -ethereum_package_constants = import_module( - "github.com/ethpandaops/ethereum-package/src/package_io/constants.star" -) - -constants = import_module("../package_io/constants.star") -util = import_module("../util.star") - -observability = import_module("../observability/observability.star") - -SERVICE_TYPE = "signer" -SERVICE_NAME = util.make_op_service_name(SERVICE_TYPE) - -# Port nums -HTTP_PORT_NUM = 8545 - -TEMPLATES_FILEPATH = "./templates" - -CONFIG_FILE_NAME = "config.yaml" -CONFIG_TEMPLATE_FILEPATH = "{0}/{1}.tmpl".format(TEMPLATES_FILEPATH, CONFIG_FILE_NAME) - -TLS_DIR = "/tls" -TLS_CA_PATH = "{0}/ca.crt".format(TLS_DIR) -TLS_CERT_PATH = "{0}/tls.crt".format(TLS_DIR) -TLS_KEY_PATH = "{0}/tls.key".format(TLS_DIR) -CONFIG_DIRPATH_ON_SERVICE = "/config" -CLIENT_KEY_DIRPATH_ON_SERVICE = "/keys" - - -def get_used_ports(): - used_ports = { - constants.HTTP_PORT_ID: ethereum_package_shared_utils.new_port_spec( - HTTP_PORT_NUM, - ethereum_package_shared_utils.TCP_PROTOCOL, - ethereum_package_shared_utils.HTTP_APPLICATION_PROTOCOL, - ), - } - return used_ports - - -def launch( - plan, - signer_params, - network_params, - deployment_output, - clients, - observability_helper, -): - service_instance_name = util.make_service_instance_name( - SERVICE_NAME, network_params - ) - - signer_ca_artifact, signer_tls_artifact = create_tls_artifacts( - plan, - signer_params, - service_instance_name, - ) - - populated_clients = generate_client_creds( - plan, - network_params, - signer_params, - deployment_output, - signer_ca_artifact, - clients, - ) - - client_key_artifacts = create_key_artifacts( - plan, - service_instance_name, - populated_clients, - ) - - config_artifact_name = create_config_artifact( - plan, - service_instance_name, - client_key_artifacts, - observability_helper, - ) - - service = plan.add_service( - service_instance_name, - make_service_config( - plan, - signer_params, - signer_ca_artifact, - signer_tls_artifact, - config_artifact_name, - client_key_artifacts, - observability_helper, - ), - ) - - observability.register_op_service_metrics_job( - observability_helper, service, network_params.network - ) - - return struct( - service=service, - clients=populated_clients, - ca_artifact=signer_ca_artifact, - ) - - -def create_tls_artifacts( - plan, - signer_params, - service_instance_name, -): - signer_ca = generate_ca(plan, signer_params, service_instance_name) - - signer_tls = generate_client_tls( - plan, - signer_params, - signer_ca, - [service_instance_name], - )[0] - - return signer_ca, signer_tls - - -def create_key_artifacts( - plan, - service_instance_name, - clients, -): - client_key_artifacts = {} - - for client_name, client in clients.items(): - file_name = "{0}_key.pem".format(client_name) - der_file = "ec_key.der" - - cmds = [ - "mkdir {0}".format(CLIENT_KEY_DIRPATH_ON_SERVICE), - "cd {0}".format(CLIENT_KEY_DIRPATH_ON_SERVICE), - # convert raw hex private key to binary - "echo '{0}' | xxd -r -p > privkey.bin".format(client.key), - # add wrapper - "printf '\\x30\\x2e\\x02\\x01\\x01\\x04\\x20' > {0}".format(der_file), - "cat privkey.bin >> {0}".format(der_file), - "printf '\\xa0\\x07\\x06\\x05\\x2b\\x81\\x04\\x00\\x0a' >> {0}".format( - der_file - ), - # convert binary key to PEM - "openssl ec -inform DER -in {0} -out {1}".format(der_file, file_name), - "chmod 666 {0}".format(file_name), - ] - - run = plan.run_sh( - description="Convert ethereum private key to PEM", - image="alpine/openssl:3.3.3", - store=[ - StoreSpec( - src="{0}/{1}".format(CLIENT_KEY_DIRPATH_ON_SERVICE, file_name), - name="{0}-{1}-key".format(service_instance_name, client.name), - ), - ], - run=util.join_cmds(cmds), - ) - - client_key_artifacts[client.hostname] = struct( - filename=file_name, - artifact=run.files_artifacts[0], - ) - - return client_key_artifacts - - -def create_config_artifact( - plan, - service_instance_name, - client_key_artifacts, - observability_helper, -): - config_data = { - "Clients": client_key_artifacts, - "KeyDir": CLIENT_KEY_DIRPATH_ON_SERVICE, - } - - config_template_and_data = ethereum_package_shared_utils.new_template_and_data( - read_file(CONFIG_TEMPLATE_FILEPATH), config_data - ) - - config_artifact_name = plan.render_templates( - { - CONFIG_FILE_NAME: config_template_and_data, - }, - name="{0}-config".format(service_instance_name), - ) - - return config_artifact_name - - -def make_service_config( - plan, - signer_params, - ca_artifact, - tls_artifact, - config_artifact_name, - client_key_artifacts, - observability_helper, -): - ports = dict(get_used_ports()) - - cmd = [] - - files = { - CONFIG_DIRPATH_ON_SERVICE: config_artifact_name, - CLIENT_KEY_DIRPATH_ON_SERVICE: Directory( - artifact_names=[ - client_key_artifacts[client_hostname].artifact - for client_hostname in client_key_artifacts - ] - ), - } - - # apply customizations - - configure_tls_files(files, ca_artifact, tls_artifact) - - if observability_helper.enabled: - observability.configure_op_service_metrics(cmd, ports) - - cmd += signer_params.extra_params - - return ServiceConfig( - image=make_image(signer_params), - ports=ports, - cmd=cmd, - files=files, - env_vars={ - "OP_SIGNER_TLS_CA": TLS_CA_PATH, - "OP_SIGNER_TLS_CERT": TLS_CERT_PATH, - "OP_SIGNER_TLS_KEY": TLS_KEY_PATH, - "OP_SIGNER_RPC_PORT": str(HTTP_PORT_NUM), - "OP_SIGNER_SERVICE_CONFIG": "{0}/{1}".format( - CONFIG_DIRPATH_ON_SERVICE, CONFIG_FILE_NAME - ), - }, - private_ip_address_placeholder=ethereum_package_constants.PRIVATE_IP_ADDRESS_PLACEHOLDER, - ) - - -def make_image(signer_params): - return "{0}:{1}".format(signer_params.image, signer_params.tag) - - -def configure_op_signer(cmd, files, signer_context, client_type): - client = signer_context.clients[client_type] - - cmd.append("--signer.tls.ca=" + TLS_CA_PATH) - cmd.append("--signer.tls.cert=" + TLS_CERT_PATH) - cmd.append("--signer.tls.key=" + TLS_KEY_PATH) - cmd.append( - "--signer.endpoint=" + util.make_service_https_url(signer_context.service) - ) - cmd.append("--signer.address=" + client.address) - - configure_tls_files( - files, - signer_context.ca_artifact, - client.tls_artifact, - ) - - -def configure_tls_files(files, ca_artifact, tls_artifact): - files[TLS_DIR] = Directory( - artifact_names=[ - ca_artifact, - tls_artifact, - ] - ) - - -def make_client(client_type, client_name): - return struct( - name=client_type, - hostname=client_name, - ) - - -def make_populated_client(client, key, address, tls_artifact): - return struct( - name=client.name, - hostname=client.hostname, - key=key, - address=address, - tls_artifact=tls_artifact, - ) - - -def generate_credentials(plan, signer_params, args, store, files={}): - gen_script = "gen-local-creds.sh" - script_path = "/script/{0}".format(gen_script) - - # no way to avoid having to upload the script every time currently - - # script_artifact_name = "{0}-gen-creds".format(SERVICE_NAME) - - # script_artifact = plan.get_files_artifact(name=script_artifact_name) - # if script_artifact == None: - script_artifact = plan.upload_files( - src="github.com/ethereum-optimism/infra/op-signer/{0}@op-signer_{1}".format( - gen_script, signer_params.tag - ), - # name=script_artifact_name, - ) - - cmds = [ - "chmod +x {0}".format(script_path), - "{0} {1}".format(script_path, " ".join(args)), - "chmod -R 777 {0}/".format(TLS_DIR), - ] - - return plan.run_sh( - description="Generate signer credentials", - image="alpine/openssl:3.3.3", - files={ - "/script": script_artifact, - } - | files, - env_vars={ - "OP_SIGNER_GEN_TLS_DOCKER": "false", - "TLS_DIR": TLS_DIR, - }, - run=util.join_cmds(cmds), - store=store, - ).files_artifacts - - -def generate_ca(plan, signer_params, service_instance_name): - return generate_credentials( - plan, - signer_params, - ["ca"], - [ - StoreSpec( - src="{0}/*".format(TLS_DIR), - name="{0}-tls-ca".format(service_instance_name), - ) - ], - )[0] - - -def generate_client_tls(plan, signer_params, signer_ca_artifact, client_hostnames): - return generate_credentials( - plan, - signer_params, - ["client_tls"] + client_hostnames, - [ - StoreSpec( - src="{0}/{1}/*".format(TLS_DIR, client), - name="{0}-tls".format(client), - ) - for client in client_hostnames - ], - files={TLS_DIR: signer_ca_artifact}, - ) - - -def generate_client_creds( - plan, - network_params, - signer_params, - deployment_output, - signer_ca_artifact, - client_map, -): - clients = [] - for client_type, client_name in client_map.items(): - clients.append( - make_client( - client_type, - util.make_service_instance_name(client_name, network_params), - ) - ) - - client_tls_artifacts = generate_client_tls( - plan, - signer_params, - signer_ca_artifact, - [client.hostname for client in clients], - ) - - client_map = {} - - for client_num, client in enumerate(clients): - private_key = util.read_service_private_key( - plan, - deployment_output, - client.name, - network_params, - ) - - address = util.read_service_network_config_value( - plan, - deployment_output, - client.name, - network_params, - ".address", - ) - - client_map[client.name] = make_populated_client( - client, private_key, address, client_tls_artifacts[client_num] - ) - - return client_map diff --git a/src/signer/templates/config.yaml.tmpl b/src/signer/templates/config.yaml.tmpl deleted file mode 100644 index b50c5931..00000000 --- a/src/signer/templates/config.yaml.tmpl +++ /dev/null @@ -1,6 +0,0 @@ -provider: LOCAL -auth: - {{ range $client_name, $client_key := .Clients }} - - name: {{ $client_name }} - key: {{ $.KeyDir }}/{{ $client_key.filename }} - {{ end }} diff --git a/src/util.star b/src/util.star index 5ed98fc0..336cb6b5 100644 --- a/src/util.star +++ b/src/util.star @@ -2,30 +2,11 @@ constants = import_module("./package_io/constants.star") DEPLOYMENT_UTILS_IMAGE = "mslipper/deployment-utils:latest" -NETWORK_DATA_DIR = "/network-data" - def read_network_config_value(plan, network_config_file, json_file, json_path): - mounts = {NETWORK_DATA_DIR: network_config_file} + mounts = {"/network-data": network_config_file} return read_json_value( - plan, "{0}/{1}.json".format(NETWORK_DATA_DIR, json_file), json_path, mounts - ) - - -def read_service_network_config_value( - plan, network_config_file, service_type, network_params, json_path -): - return read_network_config_value( - plan, - network_config_file, - "{0}-{1}".format(service_type, network_params.network_id), - json_path, - ) - - -def read_service_private_key(plan, network_config_file, service_type, network_params): - return read_service_network_config_value( - plan, network_config_file, service_type, network_params, ".privateKey" + plan, "/network-data/{0}.json".format(json_file), json_path, mounts ) @@ -105,14 +86,6 @@ def join_cmds(commands): return " && ".join(commands) -def make_op_service_name(service_type): - return "op-{0}".format(service_type) - - -def make_service_instance_name(service_name, network_params): - return "{0}-{1}".format(service_name, network_params.network) - - def get_service_port_num(service, port_id): return service.ports[port_id].number @@ -133,10 +106,6 @@ def prefix_url_scheme_http(authority): return prefix_url_scheme("http", authority) -def prefix_url_scheme_https(authority): - return prefix_url_scheme("https", authority) - - def prefix_url_scheme_ws(authority): return prefix_url_scheme("ws", authority) @@ -150,17 +119,15 @@ def make_ws_url(host, port_num): def make_service_url_authority(service, port_id): - return make_url_authority(service.hostname, get_service_port_num(service, port_id)) + return make_url_authority( + service.ip_address, get_service_port_num(service, port_id) + ) def make_service_http_url(service, port_id=constants.HTTP_PORT_ID): return prefix_url_scheme_http(make_service_url_authority(service, port_id)) -def make_service_https_url(service, port_id=constants.HTTP_PORT_ID): - return prefix_url_scheme_https(make_service_url_authority(service, port_id)) - - def make_service_ws_url(service, port_id=constants.WS_PORT_ID): return prefix_url_scheme_ws(make_service_url_authority(service, port_id)) @@ -177,9 +144,3 @@ def make_execution_rpc_url(el_context): el_context.ip_addr, el_context.rpc_port_num, ) - - -def configure_op_service_rpc(cmd, port_num): - cmd.append("--rpc.addr=0.0.0.0") - cmd.append("--rpc.port={0}".format(port_num)) - cmd.append("--rpc.enable-admin") diff --git a/test/el_cl_launcher_test.star b/test/el_cl_launcher_test.star index 68260b1e..5a88c155 100644 --- a/test/el_cl_launcher_test.star +++ b/test/el_cl_launcher_test.star @@ -6,8 +6,6 @@ ethereum_package_constants = import_module( ) util = import_module("/src/util.star") -test_utils = import_module("/test/test_utils.star") - # # Default test inputs # @@ -53,27 +51,28 @@ def test_launch_with_defaults(plan): # We'll mock read_network_config_value since it returns a runtime value that we would not be able to retrieve sequencer_private_key_mock = "sequencer_private_key" - kurtosistest.mock(util, "read_service_private_key").mock_return_value( + kurtosistest.mock(util, "read_network_config_value").mock_return_value( sequencer_private_key_mock ) all_el_contexts, all_cl_contexts = el_cl_launcher.launch( plan=plan, + jwt_file=jwt_file, network_params=chain.network_params, mev_params=chain.mev_params, - interop_params=parsed_input_args.interop, - jwt_file=jwt_file, deployment_output=deployment_output, participants=chain.participants, + num_participants=len(chains), l1_config_env_vars=l1_config_env_vars, l2_services_suffix="", - da_server_context=da_server_context, - additional_services=[], global_log_level="info", global_node_selectors=[], global_tolerations=[], persistent=False, + additional_services=[], observability_helper=observability_helper, + interop_params=parsed_input_args.interop, + da_server_context=da_server_context, ) el_service_name = "op-el-1-op-reth-op-node-" @@ -84,8 +83,7 @@ def test_launch_with_defaults(plan): expect.ne(cl_service_config, None) expect.eq(cl_service_config.image, "op-node:latest") expect.eq(cl_service_config.env_vars, {}) - - test_utils.contains_all( + expect.eq( cl_service_config.cmd, [ "op-node", @@ -98,6 +96,9 @@ def test_launch_with_defaults(plan): "--rollup.config=/network-configs/rollup-{0}.json".format( chain.network_params.network_id ), + "--rpc.addr=0.0.0.0", + "--rpc.port=8547", + "--rpc.enable-admin", "--l1={0}".format(l1_config_env_vars["L1_RPC_URL"]), "--l1.rpckind={0}".format(l1_config_env_vars["L1_RPC_KIND"]), "--l1.beacon={0}".format(l1_config_env_vars["CL_RPC_URL"]), @@ -112,10 +113,7 @@ def test_launch_with_defaults(plan): "--safedb.path=/data/op-node/op-node-beacon-data", "--altda.enabled={0}".format(da_server_context.enabled), "--altda.da-server={0}".format(da_server_context.http_url), - "--rpc.addr=0.0.0.0", - "--rpc.port=8547", - "--rpc.enable-admin", - "--metrics.enabled", + "--metrics.enabled=true", "--metrics.addr=0.0.0.0", "--metrics.port=9001", "--p2p.sequencer.key={0}".format(sequencer_private_key_mock), @@ -127,8 +125,7 @@ def test_launch_with_defaults(plan): expect.ne(el_service_config, None) expect.eq(el_service_config.image, "op-reth:latest") expect.eq(el_service_config.env_vars, {}) - - test_utils.contains_all( + expect.eq( el_service_config.cmd, [ "node", @@ -184,27 +181,28 @@ def test_launch_with_el_op_besu(plan): # We'll mock read_network_config_value since it returns a runtime value that we would not be able to retrieve sequencer_private_key_mock = "sequencer_private_key" - kurtosistest.mock(util, "read_service_private_key").mock_return_value( + kurtosistest.mock(util, "read_network_config_value").mock_return_value( sequencer_private_key_mock ) all_el_contexts, all_cl_contexts = el_cl_launcher.launch( plan=plan, + jwt_file=jwt_file, network_params=chain.network_params, mev_params=chain.mev_params, - interop_params=parsed_input_args.interop, - jwt_file=jwt_file, deployment_output=deployment_output, participants=chain.participants, + num_participants=len(chains), l1_config_env_vars=l1_config_env_vars, l2_services_suffix="", - da_server_context=da_server_context, - additional_services=[], global_log_level="info", global_node_selectors=[], global_tolerations=[], persistent=False, + additional_services=[], observability_helper=observability_helper, + interop_params=parsed_input_args.interop, + da_server_context=da_server_context, ) el_service_name = "op-el-1-op-besu-op-node-" @@ -213,44 +211,49 @@ def test_launch_with_el_op_besu(plan): expect.ne(el_service_config, None) expect.eq(el_service_config.image, "op-besu:latest") expect.eq(el_service_config.env_vars, {}) - - test_utils.contains_all( + expect.eq( el_service_config.cmd, [ - "besu", - "--genesis-file=/network-configs/genesis-{0}.json".format( - chain.network_params.network_id - ), - "--network-id={0}".format(chain.network_params.network_id), - "--data-path=/data/besu/execution-data", - "--host-allowlist=*", - "--rpc-http-enabled=true", - "--rpc-http-host=0.0.0.0", - "--rpc-http-port=8545", - "--rpc-http-api=ADMIN,CLIQUE,ETH,NET,DEBUG,TXPOOL,ENGINE,TRACE,WEB3,MINER", - "--rpc-http-cors-origins=*", - "--rpc-http-max-active-connections=300", - "--rpc-ws-enabled=true", - "--rpc-ws-host=0.0.0.0", - "--rpc-ws-port=8546", - "--rpc-ws-api=ADMIN,CLIQUE,ETH,NET,DEBUG,TXPOOL,ENGINE,TRACE,WEB3,MINER", - "--p2p-enabled=true", - "--p2p-host={0}".format( - ethereum_package_constants.PRIVATE_IP_ADDRESS_PLACEHOLDER - ), - "--p2p-port=30303", - "--engine-rpc-enabled=true", - "--engine-jwt-secret={0}".format( - ethereum_package_constants.JWT_MOUNT_PATH_ON_CONTAINER - ), - "--engine-host-allowlist=*", - "--engine-rpc-port={0}".format(el_service.ports["engine-rpc"].number), - "--sync-mode=FULL", - "--bonsai-limit-trie-logs-enabled=false", - "--version-compatibility-protection=false", - "--metrics-enabled", - "--metrics-host=0.0.0.0", - "--metrics-port=9001", + " ".join( + [ + "besu", + "--genesis-file=/network-configs/genesis-{0}.json".format( + chain.network_params.network_id + ), + "--network-id={0}".format(chain.network_params.network_id), + "--data-path=/data/besu/execution-data", + "--host-allowlist=*", + "--rpc-http-enabled=true", + "--rpc-http-host=0.0.0.0", + "--rpc-http-port=8545", + "--rpc-http-api=ADMIN,CLIQUE,ETH,NET,DEBUG,TXPOOL,ENGINE,TRACE,WEB3,MINER", + "--rpc-http-cors-origins=*", + "--rpc-http-max-active-connections=300", + "--rpc-ws-enabled=true", + "--rpc-ws-host=0.0.0.0", + "--rpc-ws-port=8546", + "--rpc-ws-api=ADMIN,CLIQUE,ETH,NET,DEBUG,TXPOOL,ENGINE,TRACE,WEB3,MINER", + "--p2p-enabled=true", + "--p2p-host={0}".format( + ethereum_package_constants.PRIVATE_IP_ADDRESS_PLACEHOLDER + ), + "--p2p-port=30303", + "--engine-rpc-enabled=true", + "--engine-jwt-secret={0}".format( + ethereum_package_constants.JWT_MOUNT_PATH_ON_CONTAINER + ), + "--engine-host-allowlist=*", + "--engine-rpc-port={0}".format( + el_service.ports["engine-rpc"].number + ), + "--sync-mode=FULL", + "--bonsai-limit-trie-logs-enabled=false", + "--version-compatibility-protection=false", + "--metrics-enabled=true", + "--metrics-host=0.0.0.0", + "--metrics-port=9001", + ] + ) ], ) diff --git a/test/op_challenger_launcher_test.star b/test/op_challenger_launcher_test.star index e014706b..63662308 100644 --- a/test/op_challenger_launcher_test.star +++ b/test/op_challenger_launcher_test.star @@ -1,17 +1,13 @@ op_challenger_launcher = import_module( "/src/challenger/op-challenger/op_challenger_launcher.star" ) -op_signer_launcher = import_module("/src/signer/op_signer_launcher.star") input_parser = import_module("/src/package_io/input_parser.star") observability = import_module("/src/observability/observability.star") ethereum_package_constants = import_module( "github.com/ethpandaops/ethereum-package/src/package_io/constants.star" ) -constants = import_module("/src/package_io/constants.star") util = import_module("/src/util.star") -test_utils = import_module("/test/test_utils.star") - def test_launch_with_defaults(plan): parsed_input_args = input_parser.input_parser( @@ -19,9 +15,6 @@ def test_launch_with_defaults(plan): { "chains": [ { - "network_params": { - "network": "kurtosis-test", - }, "participants": [ { "el_type": "op-reth", @@ -50,12 +43,9 @@ def test_launch_with_defaults(plan): chains = parsed_input_args.chains chain = chains[0] - - service_type = op_challenger_launcher.SERVICE_TYPE - service_name = op_challenger_launcher.SERVICE_NAME - service_instance_name = util.make_service_instance_name( - service_name, chain.network_params - ) + l2_num = 0 + challenger_service_name = "op-challenger" + challenger_image = input_parser.DEFAULT_CHALLENGER_IMAGES["op-challenger"] deployment_output = "/path/to/deployment_output" l1_config_env_vars = { @@ -64,45 +54,24 @@ def test_launch_with_defaults(plan): "CL_RPC_URL": "CL_RPC_URL", } - challenger_private_key_mock = "challenger_private_key" - challenger_address_mock = "challenger_address" - - signer_client = op_signer_launcher.make_client( - service_type, - service_instance_name, + # We'll mock read_network_config_value since it returns a runtime value that we would not be able to retrieve + dispute_game_factory_mock = "dispute_game_factory" + kurtosistest.mock(util, "read_network_config_value").mock_return_value( + dispute_game_factory_mock ) - - signer_context = struct( - service=struct( - hostname=util.make_service_instance_name( - op_signer_launcher.SERVICE_NAME, chain.network_params - ), - ports={ - constants.HTTP_PORT_ID: struct( - number=op_signer_launcher.HTTP_PORT_NUM, - ), - }, - ), - ca_artifact="ca_artifact_mock", - clients={ - service_type: op_signer_launcher.make_populated_client( - client=signer_client, - key=challenger_private_key_mock, - address=challenger_address_mock, - tls_artifact="tls_artifact_mock", - ) - }, + challenger_private_key_mock = "challenger_private_key" + kurtosistest.mock(util, "read_network_config_value").mock_return_value( + challenger_private_key_mock ) - dispute_game_factory_address_mock = "dispute_game_factory_address" - op_challenger_launcher.launch( plan=plan, + l2_num=l2_num, + service_name=challenger_service_name, + image=challenger_image, el_context=el_context, cl_context=cl_context, l1_config_env_vars=l1_config_env_vars, - signer_context=signer_context, - game_factory_address=dispute_game_factory_address_mock, deployment_output=deployment_output, network_params=chain.network_params, challenger_params=chain.challenger_params, @@ -110,32 +79,19 @@ def test_launch_with_defaults(plan): observability_helper=observability_helper, ) - challenger_service_config = kurtosistest.get_service_config(service_instance_name) + challenger_service_config = kurtosistest.get_service_config( + service_name=challenger_service_name + ) expect.ne(challenger_service_config, None) + expect.eq(challenger_service_config.image, challenger_image) expect.eq(challenger_service_config.env_vars, {}) - - test_utils.contains_all( + expect.eq( + challenger_service_config.entrypoint, + ["sh", "-c"], + ) + expect.eq( challenger_service_config.cmd, [ - service_name, - "--cannon-l2-genesis=/network-configs/genesis-2151908.json", - "--cannon-rollup-config=/network-configs/rollup-2151908.json", - "--game-factory-address=dispute_game_factory_address", - "--datadir=/data/op-challenger/op-challenger-data", - "--l1-beacon=CL_RPC_URL", - "--l1-eth-rpc=L1_RPC_URL", - "--l2-eth-rpc=rpc_http_url", - "--private-key=challenger_private_key", - "--rollup-rpc=beacon_http_url", - "--trace-type=cannon,permissioned", - "--signer.tls.ca=/tls/ca.crt", - "--signer.tls.cert=/tls/tls.crt", - "--signer.tls.key=/tls/tls.key", - "--signer.endpoint=https://op-signer-kurtosis-test:8545", - "--signer.address=challenger_address", - "--metrics.enabled", - "--metrics.addr=0.0.0.0", - "--metrics.port=9001", - "--cannon-prestates-url=https://storage.googleapis.com/oplabs-network-data/proofs/op-program/cannon", + "mkdir -p /data/op-challenger/op-challenger-data && op-challenger --cannon-l2-genesis=/network-configs/genesis-2151908.json --cannon-rollup-config=/network-configs/rollup-2151908.json --game-factory-address=challenger_private_key --datadir=/data/op-challenger/op-challenger-data --l1-beacon=CL_RPC_URL --l1-eth-rpc=L1_RPC_URL --l2-eth-rpc=rpc_http_url --private-key=challenger_private_key --rollup-rpc=beacon_http_url --trace-type=cannon,permissioned --metrics.enabled --metrics.addr=0.0.0.0 --metrics.port=9001 --cannon-prestates-url=https://storage.googleapis.com/oplabs-network-data/proofs/op-program/cannon" ], ) diff --git a/test/test_utils.star b/test/test_utils.star deleted file mode 100644 index d0fd69d5..00000000 --- a/test/test_utils.star +++ /dev/null @@ -1,3 +0,0 @@ -def contains_all(actual, expected): - for e in expected: - expect.contains(actual, e)