diff --git a/main.star b/main.star index 0d29bb7d8..5edea58b8 100644 --- a/main.star +++ b/main.star @@ -17,6 +17,7 @@ forkmon = import_module("./src/forkmon/forkmon_launcher.star") dora = import_module("./src/dora/dora_launcher.star") dugtrio = import_module("./src/dugtrio/dugtrio_launcher.star") blutgang = import_module("./src/blutgang/blutgang_launcher.star") +erpc = import_module("./src/erpc/erpc_launcher.star") blobscan = import_module("./src/blobscan/blobscan_launcher.star") forky = import_module("./src/forky/forky_launcher.star") tracoor = import_module("./src/tracoor/tracoor_launcher.star") @@ -598,6 +599,22 @@ def run(plan, args={}): args_with_right_defaults.docker_cache_params, ) plan.print("Successfully launched blutgang") + elif additional_service == "erpc": + plan.print("Launching erpc") + erpc_config_template = read_file(static_files.ERPC_CONFIG_TEMPLATE_FILEPATH) + erpc.launch_erpc( + plan, + erpc_config_template, + all_participants, + args_with_right_defaults.participants, + network_params, + global_node_selectors, + global_tolerations, + args_with_right_defaults.port_publisher, + index, + args_with_right_defaults.docker_cache_params, + ) + plan.print("Successfully launched erpc") elif additional_service == "blobscan": plan.print("Launching blobscan") blobscan.launch_blobscan( diff --git a/src/erpc/erpc_launcher.star b/src/erpc/erpc_launcher.star new file mode 100644 index 000000000..d0ce1b833 --- /dev/null +++ b/src/erpc/erpc_launcher.star @@ -0,0 +1,164 @@ +shared_utils = import_module("../shared_utils/shared_utils.star") +constants = import_module("../package_io/constants.star") +input_parser = import_module("../package_io/input_parser.star") +SERVICE_NAME = "erpc" + +HTTP_PORT_NUMBER = 4000 +METRICS_PORT_NUMBER = 4001 + +ERPC_CONFIG_FILENAME = "erpc.yaml" + +ERPC_CONFIG_MOUNT_DIRPATH_ON_SERVICE = "/root" + +IMAGE_NAME = "ghcr.io/erpc/erpc:latest" + +MIN_CPU = 100 +MAX_CPU = 1000 +MIN_MEMORY = 128 +MAX_MEMORY = 2048 + +USED_PORTS = { + constants.HTTP_PORT_ID: shared_utils.new_port_spec( + HTTP_PORT_NUMBER, + shared_utils.TCP_PROTOCOL, + shared_utils.HTTP_APPLICATION_PROTOCOL, + ), + constants.METRICS_PORT_ID: shared_utils.new_port_spec( + METRICS_PORT_NUMBER, + shared_utils.TCP_PROTOCOL, + shared_utils.HTTP_APPLICATION_PROTOCOL, + ), +} + + +def launch_erpc( + plan, + config_template, + participant_contexts, + participant_configs, + network_params, + global_node_selectors, + global_tolerations, + port_publisher, + additional_service_index, + docker_cache_params, +): + tolerations = shared_utils.get_tolerations(global_tolerations=global_tolerations) + + all_el_client_info = [] + for index, participant in enumerate(participant_contexts): + full_name, _, el_client, _ = shared_utils.get_client_names( + participant, index, participant_contexts, participant_configs + ) + all_el_client_info.append( + new_el_client_info( + el_client.ip_addr, + el_client.rpc_port_num, + el_client.ws_port_num, + full_name, + ) + ) + + template_data = new_config_template_data( + network_params.network, + network_params.network_id, + HTTP_PORT_NUMBER, + METRICS_PORT_NUMBER, + all_el_client_info, + ) + + template_and_data = shared_utils.new_template_and_data( + config_template, template_data + ) + template_and_data_by_rel_dest_filepath = {} + template_and_data_by_rel_dest_filepath[ERPC_CONFIG_FILENAME] = template_and_data + + config_files_artifact_name = plan.render_templates( + template_and_data_by_rel_dest_filepath, "erpc-config" + ) + + config = get_config( + config_files_artifact_name, + network_params, + global_node_selectors, + tolerations, + port_publisher, + additional_service_index, + docker_cache_params, + ) + + plan.add_service(SERVICE_NAME, config) + + +def get_config( + config_files_artifact_name, + network_params, + node_selectors, + tolerations, + port_publisher, + additional_service_index, + docker_cache_params, +): + config_file_path = shared_utils.path_join( + ERPC_CONFIG_MOUNT_DIRPATH_ON_SERVICE, + ERPC_CONFIG_FILENAME, + ) + + public_ports = {} + if port_publisher.additional_services_enabled: + public_ports_for_component = shared_utils.get_public_ports_for_component( + "additional_services", port_publisher, additional_service_index + ) + public_port_assignments = { + constants.HTTP_PORT_ID: public_ports_for_component[0], + constants.METRICS_PORT_ID: public_ports_for_component[1], + } + public_ports = shared_utils.get_port_specs(public_port_assignments) + + return ServiceConfig( + image=shared_utils.docker_cache_image_calc( + docker_cache_params, + IMAGE_NAME, + ), + ports=USED_PORTS, + public_ports=public_ports, + files={ + ERPC_CONFIG_MOUNT_DIRPATH_ON_SERVICE: config_files_artifact_name, + }, + min_cpu=MIN_CPU, + max_cpu=MAX_CPU, + min_memory=MIN_MEMORY, + max_memory=MAX_MEMORY, + node_selectors=node_selectors, + tolerations=tolerations, + ready_conditions=ReadyCondition( + recipe=GetHttpRequestRecipe( + port_id="http", + endpoint="/healthz", + ), + field="code", + assertion="==", + target_value=200, + ), + ) + + +def new_config_template_data( + network, network_id, http_port, metrics_port, el_client_info +): + return { + "Network": network, + "NetworkID": network_id, + "HTTPPort": http_port, + "MetricsPort": metrics_port, + "ELClientInfo": el_client_info, + } + + +def new_el_client_info(ip_addr, rpc_port_num, ws_port_num, full_name): + return { + "IP_Addr": ip_addr, + "RPC_PortNum": rpc_port_num, + "WS_PortNum": ws_port_num, + "FullName": full_name, + } diff --git a/src/package_io/sanity_check.star b/src/package_io/sanity_check.star index 3a98ebd33..2d5b12b41 100644 --- a/src/package_io/sanity_check.star +++ b/src/package_io/sanity_check.star @@ -382,6 +382,7 @@ ADDITIONAL_SERVICES_PARAMS = [ "blobscan", "dugtrio", "blutgang", + "erpc", "forky", "apache", "nginx", diff --git a/src/static_files/static_files.star b/src/static_files/static_files.star index 95d3e8944..caae93c72 100644 --- a/src/static_files/static_files.star +++ b/src/static_files/static_files.star @@ -37,6 +37,7 @@ DUGTRIO_CONFIG_TEMPLATE_FILEPATH = ( BLUTGANG_CONFIG_TEMPLATE_FILEPATH = ( STATIC_FILES_DIRPATH + "/blutgang-config/config.toml.tmpl" ) +ERPC_CONFIG_TEMPLATE_FILEPATH = STATIC_FILES_DIRPATH + "/erpc-config/erpc.yaml.tmpl" FORKY_CONFIG_TEMPLATE_FILEPATH = STATIC_FILES_DIRPATH + "/forky-config/config.yaml.tmpl" TRACOOR_CONFIG_TEMPLATE_FILEPATH = ( STATIC_FILES_DIRPATH + "/tracoor-config/config.yaml.tmpl" diff --git a/static_files/erpc-config/erpc.yaml.tmpl b/static_files/erpc-config/erpc.yaml.tmpl new file mode 100644 index 000000000..3fc98ad55 --- /dev/null +++ b/static_files/erpc-config/erpc.yaml.tmpl @@ -0,0 +1,65 @@ +logLevel: debug + +server: + httpHostV4: 0.0.0.0 + httpPortV4: {{ .HTTPPort }} + +metrics: + enabled: true + hostV4: 0.0.0.0 + port: {{ .MetricsPort }} + +healthCheck: + mode: networks + +database: + evmJsonRpcCache: + connectors: + - id: memory-cache + driver: memory + policies: + - network: "*" + method: "*" + finality: realtime + empty: allow + connector: memory-cache + ttl: 2s + - network: "*" + method: "*" + finality: unfinalized + empty: allow + connector: memory-cache + ttl: 10s + - network: "*" + method: "*" + finality: finalized + empty: allow + connector: memory-cache + ttl: 1h + +projects: + - id: main + upstreams: + {{- range $elClient := .ELClientInfo }} + - id: {{ $elClient.FullName }} + type: evm + endpoint: http://{{ $elClient.IP_Addr }}:{{ $elClient.RPC_PortNum }} + evm: + chainId: {{ $.NetworkID }} + {{- end }} + networks: + - architecture: evm + evm: + chainId: {{ .NetworkID }} + failsafe: + timeout: + duration: 30s + retry: + maxAttempts: 3 + delay: 500ms + backoffMaxDelay: 10s + backoffFactor: 1.2 + jitter: 500ms + hedge: + delay: 3000ms + maxCount: 2