Skip to content

Commit

Permalink
feat: add blobber
Browse files Browse the repository at this point in the history
  • Loading branch information
barnabasbusa committed Dec 12, 2023
1 parent 3c06194 commit 706915f
Show file tree
Hide file tree
Showing 14 changed files with 183 additions and 1 deletion.
19 changes: 19 additions & 0 deletions .github/tests/blobber.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
participants:
- el_client_type: geth
cl_client_type: teku
blobber_enabled: true
- el_client_type: nethermind
cl_client_type: prysm
blobber_enabled: true
- el_client_type: erigon
cl_client_type: nimbus
blobber_enabled: true
- el_client_type: besu
cl_client_type: lighthouse
blobber_enabled: true
- el_client_type: reth
cl_client_type: lodestar
blobber_enabled: true
- el_client_type: ethereumjs
cl_client_type: teku
blobber_enabled: true
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,14 @@ participants:
# Additional labels to be added. Default to empty
labels: {}
# Blobber can be enabled with the `blobber_enabled` flag per client or globally
# Defaults to false
blobber_enabled: false
# Blobber extra params can be passed in to the blobber container
# Defaults to empty
blobber_extra_params: []
# Default configuration parameters for the Eth network
network_params:
# The network ID of the network.
Expand Down
2 changes: 2 additions & 0 deletions network_params.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ participants:
prometheus_config:
scrape_interval: 15s
labels: {}
blobber_enabled: false
blobber_extra_params: []
network_params:
network_id: "3151908"
deposit_contract_address: "0x4242424242424242424242424242424242424242"
Expand Down
5 changes: 5 additions & 0 deletions src/blobber/blobber_context.star
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
def new_blobber_context(ip_addr, port_num):
return struct(
ip_addr=ip_addr,
port_num=port_num,
)
67 changes: 67 additions & 0 deletions src/blobber/blobber_launcher.star
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
shared_utils = import_module("../shared_utils/shared_utils.star")
input_parser = import_module("../package_io/input_parser.star")
cl_client_context = import_module("../cl/cl_client_context.star")

blobber_context = import_module("../blobber/blobber_context.star")

BLOBBER_BEACON_PORT_NUM = 9000
BLOBBER_BEACON_PORT_ID = "discovery"
BLOBBER_VALIDATOR_PROXY_PORT_NUM = 4000
BLOBBER_VALIDATOR_PROXY_PORT_ID = "http"

PRIVATE_IP_ADDRESS_PLACEHOLDER = "KURTOSIS_IP_ADDR_PLACEHOLDER"

DEFAULT_BLOBBER_IMAGE = "ethpandaops/blobber:1.0.5"

VALIDATOR_KEYS_MOUNTPOINT_ON_CLIENTS = "/validator-keys"

BLOBBER_USED_PORTS = {
BLOBBER_VALIDATOR_PROXY_PORT_ID: shared_utils.new_port_spec(
BLOBBER_VALIDATOR_PROXY_PORT_NUM, shared_utils.TCP_PROTOCOL, wait="5s"
),
BLOBBER_BEACON_PORT_ID: shared_utils.new_port_spec(
BLOBBER_BEACON_PORT_NUM, shared_utils.TCP_PROTOCOL, wait=None
),
}


def launch(plan, service_name, node_keystore_files, beacon_http_url, extra_params):
blobber_service_name = "{0}".format(service_name)

blobber_config = get_config(
service_name, node_keystore_files, beacon_http_url, extra_params
)

blobber_service = plan.add_service(blobber_service_name, blobber_config)
return blobber_context.new_blobber_context(
blobber_service.ip_address, BLOBBER_VALIDATOR_PROXY_PORT_NUM
)


def get_config(service_name, node_keystore_files, beacon_http_url, extra_params):

validator_root_dirpath = shared_utils.path_join(
VALIDATOR_KEYS_MOUNTPOINT_ON_CLIENTS,
node_keystore_files.raw_root_dirpath,
)
cmd = [
"--beacon-port-start={0}".format(BLOBBER_BEACON_PORT_NUM),
"--cl={0}".format(beacon_http_url),
"--validator-key-folder={0}".format(validator_root_dirpath),
"--enable-unsafe-mode",
"--external-ip={0}".format(PRIVATE_IP_ADDRESS_PLACEHOLDER),
"--validator-proxy-port-start={0}".format(BLOBBER_VALIDATOR_PROXY_PORT_NUM), # use the same port as the beacon http port
]

if len(extra_params) > 0:
cmd.extend([param for param in extra_params])

return ServiceConfig(
image=DEFAULT_BLOBBER_IMAGE,
ports=BLOBBER_USED_PORTS,
files={
VALIDATOR_KEYS_MOUNTPOINT_ON_CLIENTS: node_keystore_files.files_artifact_uuid
},
cmd=cmd,
private_ip_address_placeholder=PRIVATE_IP_ADDRESS_PLACEHOLDER,
)
21 changes: 21 additions & 0 deletions src/cl/lighthouse/lighthouse_launcher.star
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ cl_node_ready_conditions = import_module("../../cl/cl_node_ready_conditions.star

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

blobber_launcher = import_module("../../blobber/blobber_launcher.star")

LIGHTHOUSE_BINARY_COMMAND = "lighthouse"

VALIDATOR_KEYS_MOUNTPOINT_ON_CLIENTS = "/validator-keys"
Expand Down Expand Up @@ -113,6 +115,8 @@ def launch(
v_max_mem,
snooper_enabled,
snooper_engine_context,
blobber_enabled,
blobber_extra_params,
extra_beacon_params,
extra_validator_params,
extra_beacon_labels,
Expand Down Expand Up @@ -155,6 +159,23 @@ def launch(
beacon_service.ip_address, beacon_http_port.number
)

# Blobber config
if blobber_enabled:
blobber_service_name = "{0}-{1}".format("blobber", beacon_node_service_name)
blobber_config = blobber_launcher.get_config(
blobber_service_name,
node_keystore_files,
beacon_http_url,
blobber_extra_params,
)

blobber_service = plan.add_service(blobber_service_name, blobber_config)
blobber_http_port = blobber_service.ports[BEACON_HTTP_PORT_ID]
blobber_http_url = "http://{0}:{1}".format(
blobber_service.ip_address, beacon_http_port.number
)
beacon_http_url = blobber_http_url

# Launch validator node if we have a keystore
validator_service = None
if node_keystore_files != None:
Expand Down
19 changes: 19 additions & 0 deletions src/cl/lodestar/lodestar_launcher.star
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ def launch(
v_max_mem,
snooper_enabled,
snooper_engine_context,
blobber_enabled,
blobber_extra_params,
extra_beacon_params,
extra_validator_params,
extra_beacon_labels,
Expand Down Expand Up @@ -132,6 +134,23 @@ def launch(
beacon_service.ip_address, beacon_http_port.number
)

# Blobber config
if blobber_enabled:
blobber_service_name = "{0}-{1}".format("blobber", beacon_node_service_name)
blobber_config = blobber_launcher.get_config(
blobber_service_name,
node_keystore_files,
beacon_http_url,
blobber_extra_params,
)

blobber_service = plan.add_service(blobber_service_name, blobber_config)
blobber_http_port = blobber_service.ports[BEACON_HTTP_PORT_ID]
blobber_http_url = "http://{0}:{1}".format(
blobber_service.ip_address, beacon_http_port.number
)
beacon_http_url = blobber_http_url

# Launch validator node if we have a keystore
if node_keystore_files != None:
v_min_cpu = int(v_min_cpu) if int(v_min_cpu) > 0 else VALIDATOR_MIN_CPU
Expand Down
2 changes: 2 additions & 0 deletions src/cl/nimbus/nimbus_launcher.star
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ def launch(
v_max_mem,
snooper_enabled,
snooper_engine_context,
blobber_enabled,
blobber_extra_params,
extra_beacon_params,
extra_validator_params,
extra_beacon_labels,
Expand Down
19 changes: 19 additions & 0 deletions src/cl/prysm/prysm_launcher.star
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ def launch(
v_max_mem,
snooper_enabled,
snooper_engine_context,
blobber_enabled,
blobber_extra_params,
extra_beacon_params,
extra_validator_params,
extra_beacon_labels,
Expand Down Expand Up @@ -158,6 +160,23 @@ def launch(
beacon_http_endpoint = "{0}:{1}".format(beacon_service.ip_address, HTTP_PORT_NUM)
beacon_rpc_endpoint = "{0}:{1}".format(beacon_service.ip_address, RPC_PORT_NUM)

# Blobber config
if blobber_enabled:
blobber_service_name = "{0}-{1}".format("blobber", beacon_node_service_name)
blobber_config = blobber_launcher.get_config(
blobber_service_name,
node_keystore_files,
beacon_http_url,
blobber_extra_params,
)

blobber_service = plan.add_service(blobber_service_name, blobber_config)
blobber_http_port = blobber_service.ports[BEACON_HTTP_PORT_ID]
blobber_http_url = "http://{0}:{1}".format(
blobber_service.ip_address, beacon_http_port.number
)
beacon_http_url = blobber_http_url

# Launch validator node if we have a keystore file
validator_service = None
if node_keystore_files != None:
Expand Down
2 changes: 2 additions & 0 deletions src/cl/teku/teku_launcher.star
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ def launch(
v_max_mem,
snooper_enabled,
snooper_engine_context,
blobber_enabled,
blobber_extra_params,
extra_beacon_params,
extra_validator_params,
extra_beacon_labels,
Expand Down
11 changes: 11 additions & 0 deletions src/package_io/input_parser.star
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,8 @@ def input_parser(plan, input_args):
scrape_interval=participant["prometheus_config"]["scrape_interval"],
labels=participant["prometheus_config"]["labels"],
),
blobber_enabled=participant["blobber_enabled"],
blobber_extra_params=participant["blobber_params"],
)
for participant in result["participants"]
],
Expand Down Expand Up @@ -281,6 +283,13 @@ def parse_network_params(input_args):
ethereum_metrics_exporter_enabled = participant[
"ethereum_metrics_exporter_enabled"
]

blobber_enabled = participant["blobber_enabled"]
if blobber_enabled:
if participant["cl_client_type"] == ("teku" or "nimbus"):
# TODO: remove this once teku and nimbus support blobber
participant["blobber_enabled"] = False

if ethereum_metrics_exporter_enabled == False:
default_ethereum_metrics_exporter_enabled = result[
"ethereum_metrics_exporter_enabled"
Expand Down Expand Up @@ -433,6 +442,8 @@ def default_participant():
"scrape_interval": "15s",
"labels": None,
},
"blobber_enabled": False,
"blobber_params": [],
}


Expand Down
5 changes: 4 additions & 1 deletion src/participant_network.star
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,6 @@ def launch_participant_network(
snooper_engine_context
)
)

all_snooper_engine_contexts.append(snooper_engine_context)

if index == 0:
Expand All @@ -335,6 +334,8 @@ def launch_participant_network(
participant.v_max_mem,
participant.snooper_enabled,
snooper_engine_context,
participant.blobber_enabled,
participant.blobber_extra_params,
participant.beacon_extra_params,
participant.validator_extra_params,
participant.beacon_extra_labels,
Expand Down Expand Up @@ -362,6 +363,8 @@ def launch_participant_network(
participant.v_max_mem,
participant.snooper_enabled,
snooper_engine_context,
participant.blobber_enabled,
participant.blobber_extra_params,
participant.beacon_extra_params,
participant.validator_extra_params,
participant.beacon_extra_labels,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# One of these will be created per node we're trying to start
def new_keystore_files(
files_artifact_uuid,
raw_root_dirpath,
raw_keys_relative_dirpath,
raw_secrets_relative_dirpath,
nimbus_keys_relative_dirpath,
Expand All @@ -11,6 +12,7 @@ def new_keystore_files(
return struct(
files_artifact_uuid=files_artifact_uuid,
# ------------ All directories below are relative to the root of the files artifact ----------------
raw_root_dirpath=raw_root_dirpath,
raw_keys_relative_dirpath=raw_keys_relative_dirpath,
raw_secrets_relative_dirpath=raw_secrets_relative_dirpath,
nimbus_keys_relative_dirpath=nimbus_keys_relative_dirpath,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ def generate_validator_keystores(plan, mnemonic, participants):
base_dirname_in_artifact = shared_utils.path_base(output_dirpath)
to_add = keystore_files_module.new_keystore_files(
artifact_name,
shared_utils.path_join(base_dirname_in_artifact),
shared_utils.path_join(base_dirname_in_artifact, RAW_KEYS_DIRNAME),
shared_utils.path_join(base_dirname_in_artifact, RAW_SECRETS_DIRNAME),
shared_utils.path_join(base_dirname_in_artifact, NIMBUS_KEYS_DIRNAME),
Expand Down Expand Up @@ -283,6 +284,7 @@ def generate_valdiator_keystores_in_parallel(plan, mnemonic, participants):
base_dirname_in_artifact = shared_utils.path_base(output_dirpath)
to_add = keystore_files_module.new_keystore_files(
artifact_name,
shared_utils.path_join(base_dirname_in_artifact),
shared_utils.path_join(base_dirname_in_artifact, RAW_KEYS_DIRNAME),
shared_utils.path_join(base_dirname_in_artifact, RAW_SECRETS_DIRNAME),
shared_utils.path_join(base_dirname_in_artifact, NIMBUS_KEYS_DIRNAME),
Expand Down

0 comments on commit 706915f

Please sign in to comment.