Commit 743ba44d authored by Barnabas Busa's avatar Barnabas Busa Committed by GitHub

feat!: merged genesis generation (#288)

Co-authored-by: default avatarGyanendra Mishra <anomaly.the@gmail.com>
parent 18b141ed
......@@ -11,7 +11,7 @@ executors:
parameters:
should-enable-check-latest-version-workflow:
type: boolean
default: false
default: true
# To enable/disabled the check_code workflow execution which will be triggered by the PR's checkers
should-enable-build-workflow:
type: boolean
......
......@@ -25,8 +25,5 @@
"cl_client_type": "lodestar"
}
],
"network_params": {
"capella_fork_epoch": 1
},
"launch_additional_services": false
}
{
"participants": [
{
"el_client_type": "geth",
"cl_client_type": "teku"
},
{
"el_client_type": "erigon",
"cl_client_type": "teku"
......@@ -25,8 +21,5 @@
"cl_client_type": "lodestar"
}
],
"network_params": {
"capella_fork_epoch": 1
},
"launch_additional_services": false
}
......@@ -21,8 +21,5 @@
"cl_client_type": "lodestar"
}
],
"network_params": {
"capella_fork_epoch": 1
},
"launch_additional_services": false
}
......@@ -21,8 +21,5 @@
"cl_client_type": "lodestar"
}
],
"network_params": {
"capella_fork_epoch": 1
},
"launch_additional_services": false
}
......@@ -25,8 +25,5 @@
"cl_client_type": "lighthouse"
}
],
"network_params": {
"capella_fork_epoch": 1
},
"launch_additional_services": false
}
......@@ -25,8 +25,5 @@
"cl_client_type": "lodestar"
}
],
"network_params": {
"capella_fork_epoch": 1
},
"launch_additional_services": false
}
......@@ -10,10 +10,10 @@
"prometheus_grafana"
],
"mev_params": {
"mev_relay_image": "flashbots/mev-boost-relay:0.27"
"launch_custom_flood": true,
"mev_relay_image": "flashbots/mev-boost-relay:0.28.0a2"
},
"network_params": {
"seconds_per_slot": 3,
"capella_fork_epoch": 1
"seconds_per_slot": 3
}
}
\ No newline at end of file
}
{
"participants": [
{
"el_client_type": "geth",
"cl_client_type": "teku"
},
{
"el_client_type": "nethermind",
"cl_client_type": "prysm"
},
{
"el_client_type": "erigon",
"cl_client_type": "nimbus"
},
{
"el_client_type": "besu",
"cl_client_type": "lighthouse"
},
{
"el_client_type": "reth",
"cl_client_type": "lodestar"
},
{
"el_client_type": "ethereumjs",
"cl_client_type": "teku"
}
],
"network_params": {
"capella_fork_epoch": 1
},
"launch_additional_services": false
}
......@@ -25,8 +25,5 @@
"cl_client_type": "teku"
}
],
"network_params": {
"capella_fork_epoch": 1
},
"launch_additional_services": false
}
......@@ -21,8 +21,5 @@
"cl_client_type": "lodestar"
}
],
"network_params": {
"capella_fork_epoch": 1
},
"launch_additional_services": false
}
......@@ -25,8 +25,5 @@
"cl_client_type": "nimbus"
}
],
"network_params": {
"capella_fork_epoch": 1
},
"launch_additional_services": false
}
......@@ -3,14 +3,5 @@
"el_client_type": "geth",
"cl_client_type": "nimbus"
}],
"network_params": {
"network_id": "3151908",
"deposit_contract_address": "0x4242424242424242424242424242424242424242",
"seconds_per_slot": 12,
"num_validator_keys_per_node": 64,
"preregistered_validator_keys_mnemonic": "giant issue aisle success illegal bike spike question tent bar rely arctic volcano long crawl hungry vocal artwork sniff fantasy very lucky have athlete",
"capella_fork_epoch": 1
},
"global_client_log_level": "info",
"mev_type": "full"
}
......@@ -25,8 +25,5 @@
"cl_client_type": "prysm"
}
],
"network_params": {
"capella_fork_epoch": 1
},
"launch_additional_services": false
}
{
"participants": [
{
"el_client_type": "geth",
"cl_client_type": "teku"
},
{
"el_client_type": "reth",
"cl_client_type": "teku"
......@@ -25,8 +21,5 @@
"cl_client_type": "lodestar"
}
],
"network_params": {
"capella_fork_epoch": 1
},
"launch_additional_services": false
}
......@@ -25,8 +25,5 @@
"cl_client_type": "teku"
}
],
"network_params": {
"capella_fork_epoch": 1
},
"launch_additional_services": false
}
......@@ -189,7 +189,11 @@ To configure the package behaviour, you can modify your `network_params.json` fi
// Count of nodes to spin up for this participant
// Default to 1
"count": 1
"count": 1,
// Count of the number of validators you want to run for a given participant
// Default to null, which means that the number of validators will be using the network parameter num_validator_keys_per_node
"validator_count": null
}
],
......@@ -213,6 +217,16 @@ To configure the package behaviour, you can modify your `network_params.json` fi
// How long you want the network to wait before starting up
"genesis_delay": 120,
// Max churn rate for the network introduced by
// EIP-7514 https://eips.ethereum.org/EIPS/eip-7514
// Defaults to 8
"max_churn": 8,
// Ejection balance
// Defaults to 16ETH
// 16000000000 gwei
"ejection_balance": 16000000000,
// The epoch at which the capella and deneb forks are set to occur.
"capella_fork_epoch": 0,
"deneb_fork_epoch": 4,
......@@ -245,7 +259,7 @@ To configure the package behaviour, you can modify your `network_params.json` fi
// - A light beacon chain explorer will be launched
// - Default: ["tx_spammer", "blob_spammer", "el_forkmon", "beacon_metrics_gazer", "dora"," "prometheus_grafana"]
"additional_services": [
"tx_spammer",
"tx_spammer",
"blob_spammer",
"custom_flood",
"goomy_blob",
......@@ -256,12 +270,6 @@ To configure the package behaviour, you can modify your `network_params.json` fi
"prometheus_grafana"
],
// Which blockchain explorer should be used
// "dora" will use the dora explorer developped by pk910
// "full" will use the explorer developped by the beaconcha.in team
// defaults to "light"
"explorer_version": "dora",
// If set, the package will block until a finalized epoch has occurred.
"wait_for_finalization": false,
......@@ -270,7 +278,8 @@ To configure the package behaviour, you can modify your `network_params.json` fi
// This value will be overridden by participant-specific values
"global_client_log_level": "info",
// EngineAPI Snooper
// EngineAPI Snooper global flags for all participants
// Default to false
"snooper_enabled": false,
// Parallelizes keystore generation so that each node has keystores being generated in their own container
......@@ -509,14 +518,14 @@ This package comes with [seven prefunded keys for testing](https://github.com/ku
Here's a table of where the keys are used
| Account Index | Component Used In | Private Key Used | Public Key Used | Comment |
|---------------|---------------------|------------------|-----------------|----------------------------|
| Account Index | Component Used In | Private Key Used | Public Key Used | Comment |
|---------------|---------------------|------------------|-----------------|-----------------------------|
| 0 | mev_flood | ✅ | | As the admin_key |
| 0 | mev_custom_flood | | ✅ | As the receiver of balance |
| 0 | mev_custom_flood | | ✅ | As the receiver of balance |
| 1 | blob_spammer | ✅ | | As the sender of blobs |
| 2 | mev_flood | ✅ | | As the user_key |
| 3 | transaction_spammer | ✅ | | To spam transactions with |
| 4 | goomy_blob | ✅ | | As the sender of blobs |
| 4 | goomy_blob | ✅ | | As the sender of blobs |
| 5 | eip4788_deployment | ✅ | | As contract deployer |
| 6 | mev_custom_flood | ✅ | | As the sender of balance |
......
......@@ -53,22 +53,18 @@ The participant network is the beating heart at the center of the package. The p
We'll explain these phases one by one.
### Generating EL client data
### Generating EL and CL client data
All EL clients require both a genesis file and a JWT secret. The exact format of the genesis file differs per client, so we first leverage [a Docker image containing tools for generating this genesis data][ethereum-genesis-generator] to create the actual files that the EL clients-to-be will need. This is accomplished by filling in several genesis generation config files found in [the `static_files` directory][static-files].
All EL clients require both a genesis file and a JWT secret. The exact format of the genesis file differs per client, so we first leverage [a Docker image containing tools for generating this genesis data][ethereum-genesis-generator] to create the actual files that the EL clients-to-be will need. This is accomplished by filling in a single genesis generation environment config files found in [`static_files`](../static_files/genesis-generation-config/el-cl/values.env.tmpl).
The generated output files then get stored in the Kurtosis enclave, ready for use when we start the EL clients. The information about these stored files is tracked in [the `el_genesis_data` struct](https://github.com/kurtosis-tech/ethereum-package/blob/main/src/participant_network/prelaunch_data_generator/el_genesis/el_genesis_data.star).
CL clients, like EL clients also have a genesis and config files that they need. This is created at the same time as the EL genesis files.
Then the validator keys are generated. A tool called [eth2-val-tools](https://github.com/protolambda/eth2-val-tools) is used to generate the keys. The keys are then stored as a file artifact.
### Starting EL clients
Next, we plug the generated genesis data [into EL client "launchers"](https://github.com/kurtosis-tech/ethereum-package/tree/main/src/participant_network/el) to start a mining network of EL nodes. The launchers come with a `launch` function that consumes EL genesis data and produces information about the running EL client node. Running EL node information is represented by [an `el_client_context` struct](https://github.com/kurtosis-tech/ethereum-package/blob/main/src/participant_network/el/el_client_context.star). Each EL client type has its own launcher (e.g. [Geth](https://github.com/kurtosis-tech/ethereum-package/tree/main/src/participant_network/el/geth), [Besu](https://github.com/kurtosis-tech/ethereum-package/tree/main/src/participant_network/el/besu)) because each EL client will require different environment variables and flags to be set when launching the client's container.
### Generating CL client data
CL clients, like EL clients, also have genesis and config files that they need. We use [the same Docker image with tools for generating genesis data][ethereum-genesis-generator] to create the necessary CL files, we provide the genesis generation config using templates in [the `static_files` directory][static-files], and we store the generated output files in the Kurtosis enclave in the same way as the EL client genesis files. Like with EL nodes, CL genesis data information is tracked in [the `cl_client_context` struct](https://github.com/kurtosis-tech/ethereum-package/blob/main/src/participant_network/el/el_client_context.star).
The major difference with CL clients is that CL clients have validator keys, so we need to generate keys for the CL clients to use during validation. The generation happens using [the same genesis-generating Docker image][ethereum-genesis-generator], but via a call to [a different tool bundled inside the Docker image](https://github.com/protolambda/eth2-val-tools).
### Starting CL clients
Once CL genesis data and keys have been created, the CL client nodes are started via [the CL client launchers](https://github.com/kurtosis-tech/ethereum-package/tree/main/src/participant_network/cl). Just as with EL clients:
......
......@@ -75,6 +75,7 @@ def run(plan, args={}):
all_participants,
final_genesis_timestamp,
genesis_validators_root,
el_cl_data_files_artifact_uuid,
) = participant_network.launch_participant_network(
plan,
args_with_right_defaults.participants,
......@@ -290,7 +291,12 @@ def run(plan, args={}):
elif additional_service == "dora":
plan.print("Launching dora")
dora_config_template = read_file(static_files.DORA_CONFIG_TEMPLATE_FILEPATH)
dora.launch_dora(plan, dora_config_template, all_cl_client_contexts)
dora.launch_dora(
plan,
dora_config_template,
all_cl_client_contexts,
el_cl_data_files_artifact_uuid,
)
plan.print("Succesfully launched dora")
elif additional_service == "full_beaconchain_explorer":
plan.print("Launching full-beaconchain-explorer")
......
......@@ -11,7 +11,8 @@
"beacon_extra_params": [],
"validator_extra_params": [],
"builder_network_params": null,
"count": 1
"validator_count": null,
"count": 2
}
],
"network_params": {
......@@ -22,7 +23,7 @@
"preregistered_validator_keys_mnemonic": "giant issue aisle success illegal bike spike question tent bar rely arctic volcano long crawl hungry vocal artwork sniff fantasy very lucky have athlete",
"genesis_delay": 120,
"capella_fork_epoch": 0,
"deneb_fork_epoch": 500,
"deneb_fork_epoch": 4,
"electra_fork_epoch": null
},
"launch_additional_services": true,
......
......@@ -7,8 +7,6 @@ package_io = import_module("../../package_io/constants.star")
LIGHTHOUSE_BINARY_COMMAND = "lighthouse"
GENESIS_DATA_MOUNTPOINT_ON_CLIENTS = "/genesis"
VALIDATOR_KEYS_MOUNTPOINT_ON_CLIENTS = "/validator-keys"
RUST_BACKTRACE_ENVVAR_NAME = "RUST_BACKTRACE"
......@@ -133,7 +131,7 @@ def launch(
# Launch Beacon node
beacon_config = get_beacon_config(
launcher.genesis_data,
launcher.el_cl_genesis_data,
image,
bootnode_contexts,
el_client_context,
......@@ -162,7 +160,7 @@ def launch(
v_max_mem = int(v_max_mem) if int(v_max_mem) > 0 else VALIDATOR_MAX_MEMORY
validator_config = get_validator_config(
launcher.genesis_data,
launcher.el_cl_genesis_data,
image,
log_level,
beacon_http_url,
......@@ -230,7 +228,7 @@ def launch(
def get_beacon_config(
genesis_data,
el_cl_genesis_data,
image,
boot_cl_client_ctxs,
el_client_context,
......@@ -255,15 +253,6 @@ def get_beacon_config(
el_client_context.engine_rpc_port_num,
)
# For some reason, Lighthouse takes in the parent directory of the config file (rather than the path to the config file itself)
genesis_config_parent_dirpath_on_client = shared_utils.path_join(
GENESIS_DATA_MOUNTPOINT_ON_CLIENTS,
shared_utils.path_dir(genesis_data.config_yml_rel_filepath),
)
jwt_secret_filepath = shared_utils.path_join(
GENESIS_DATA_MOUNTPOINT_ON_CLIENTS, genesis_data.jwt_secret_rel_filepath
)
# NOTE: If connecting to the merge devnet remotely we DON'T want the following flags; when they're not set, the node's external IP address is auto-detected
# from the peers it communicates with but when they're set they basically say "override the autodetection and
# use what I specify instead." This requires having a know external IP address and port, which we definitely won't
......@@ -277,7 +266,7 @@ def get_beacon_config(
"beacon_node",
"--debug-level=" + log_level,
"--datadir=" + CONSENSUS_DATA_DIRPATH_ON_BEACON_SERVICE_CONTAINER,
"--testnet-dir=" + genesis_config_parent_dirpath_on_client,
"--testnet-dir=" + package_io.GENESIS_CONFIG_MOUNT_PATH_ON_CONTAINER,
# vvvvvvvvvvvvvvvvvvv REMOVE THESE WHEN CONNECTING TO EXTERNAL NET vvvvvvvvvvvvvvvvvvvvv
"--disable-enr-auto-update",
"--enr-address=" + PRIVATE_IP_ADDRESS_PLACEHOLDER,
......@@ -298,7 +287,7 @@ def get_beacon_config(
# and the option says it's "useful for testing in smaller networks" (unclear what happens in larger networks)
"--disable-packet-filter",
"--execution-endpoints=" + EXECUTION_ENGINE_ENDPOINT,
"--jwt-secrets=" + jwt_secret_filepath,
"--jwt-secrets=" + package_io.JWT_AUTH_PATH,
"--suggested-fee-recipient=" + package_io.VALIDATING_REWARDS_ACCOUNT,
# Set per Paris' recommendation to reduce noise in the logs
"--subscribe-all-subnets",
......@@ -347,7 +336,9 @@ def get_beacon_config(
image=image,
ports=BEACON_USED_PORTS,
cmd=cmd,
files={GENESIS_DATA_MOUNTPOINT_ON_CLIENTS: genesis_data.files_artifact_uuid},
files={
package_io.GENESIS_DATA_MOUNTPOINT_ON_CLIENTS: el_cl_genesis_data.files_artifact_uuid
},
env_vars={RUST_BACKTRACE_ENVVAR_NAME: RUST_FULL_BACKTRACE_KEYWORD},
private_ip_address_placeholder=PRIVATE_IP_ADDRESS_PLACEHOLDER,
ready_conditions=ready_conditions,
......@@ -359,7 +350,7 @@ def get_beacon_config(
def get_validator_config(
genesis_data,
el_cl_genesis_data,
image,
log_level,
beacon_client_http_url,
......@@ -370,12 +361,6 @@ def get_validator_config(
v_max_mem,
extra_params,
):
# For some reason, Lighthouse takes in the parent directory of the config file (rather than the path to the config file itself)
genesis_config_parent_dirpath_on_client = shared_utils.path_join(
GENESIS_DATA_MOUNTPOINT_ON_CLIENTS,
shared_utils.path_dir(genesis_data.config_yml_rel_filepath),
)
validator_keys_dirpath = shared_utils.path_join(
VALIDATOR_KEYS_MOUNTPOINT_ON_CLIENTS,
node_keystore_files.raw_keys_relative_dirpath,
......@@ -389,7 +374,7 @@ def get_validator_config(
"lighthouse",
"validator_client",
"--debug-level=" + log_level,
"--testnet-dir=" + genesis_config_parent_dirpath_on_client,
"--testnet-dir=" + package_io.GENESIS_CONFIG_MOUNT_PATH_ON_CONTAINER,
"--validators-dir=" + validator_keys_dirpath,
# NOTE: When secrets-dir is specified, we can't add the --data-dir flag
"--secrets-dir=" + validator_secrets_dirpath,
......@@ -419,7 +404,7 @@ def get_validator_config(
ports=VALIDATOR_USED_PORTS,
cmd=cmd,
files={
GENESIS_DATA_MOUNTPOINT_ON_CLIENTS: genesis_data.files_artifact_uuid,
package_io.GENESIS_DATA_MOUNTPOINT_ON_CLIENTS: el_cl_genesis_data.files_artifact_uuid,
VALIDATOR_KEYS_MOUNTPOINT_ON_CLIENTS: node_keystore_files.files_artifact_uuid,
},
env_vars={RUST_BACKTRACE_ENVVAR_NAME: RUST_FULL_BACKTRACE_KEYWORD},
......@@ -430,7 +415,7 @@ def get_validator_config(
)
def new_lighthouse_launcher(cl_genesis_data):
def new_lighthouse_launcher(el_cl_genesis_data):
return struct(
genesis_data=cl_genesis_data,
el_cl_genesis_data=el_cl_genesis_data,
)
......@@ -6,7 +6,6 @@ cl_node_ready_conditions = import_module("../../cl/cl_node_ready_conditions.star
package_io = import_module("../../package_io/constants.star")
GENESIS_DATA_MOUNT_DIRPATH_ON_SERVICE_CONTAINER = "/genesis"
# ---------------------------------- Beacon client -------------------------------------
CONSENSUS_DATA_DIRPATH_ON_SERVICE_CONTAINER = "/consensus-data"
# Port IDs
......@@ -108,7 +107,7 @@ def launch(
# Launch Beacon node
beacon_config = get_beacon_config(
launcher.cl_genesis_data,
launcher.el_cl_genesis_data,
image,
bootnode_contexts,
el_client_context,
......@@ -138,7 +137,7 @@ def launch(
v_max_mem = int(v_max_mem) if int(v_max_mem) > 0 else VALIDATOR_MAX_MEMORY
validator_config = get_validator_config(
validator_node_service_name,
launcher.cl_genesis_data,
launcher.el_cl_genesis_data,
image,
log_level,
beacon_http_url,
......@@ -196,7 +195,7 @@ def launch(
def get_beacon_config(
genesis_data,
el_cl_genesis_data,
image,
bootnode_contexts,
el_client_context,
......@@ -226,26 +225,18 @@ def get_beacon_config(
el_client_context.engine_rpc_port_num,
)
genesis_config_filepath = shared_utils.path_join(
GENESIS_DATA_MOUNT_DIRPATH_ON_SERVICE_CONTAINER,
genesis_data.config_yml_rel_filepath,
)
genesis_ssz_filepath = shared_utils.path_join(
GENESIS_DATA_MOUNT_DIRPATH_ON_SERVICE_CONTAINER,
genesis_data.genesis_ssz_rel_filepath,
)
jwt_secret_filepath = shared_utils.path_join(
GENESIS_DATA_MOUNT_DIRPATH_ON_SERVICE_CONTAINER,
genesis_data.jwt_secret_rel_filepath,
)
cmd = [
"beacon",
"--logLevel=" + log_level,
"--port={0}".format(DISCOVERY_PORT_NUM),
"--discoveryPort={0}".format(DISCOVERY_PORT_NUM),
"--dataDir=" + CONSENSUS_DATA_DIRPATH_ON_SERVICE_CONTAINER,
"--paramsFile=" + genesis_config_filepath,
"--genesisStateFile=" + genesis_ssz_filepath,
"--paramsFile="
+ package_io.GENESIS_CONFIG_MOUNT_PATH_ON_CONTAINER
+ "/config.yaml",
"--genesisStateFile="
+ package_io.GENESIS_CONFIG_MOUNT_PATH_ON_CONTAINER
+ "/genesis.ssz",
"--eth1.depositContractDeployBlock=0",
"--network.connectToDiscv5Bootnodes=true",
"--discv5=true",
......@@ -262,7 +253,7 @@ def get_beacon_config(
"--enr.udp={0}".format(DISCOVERY_PORT_NUM),
# Set per Pari's recommendation to reduce noise in the logs
"--subscribeAllSubnets=true",
"--jwt-secret={0}".format(jwt_secret_filepath),
"--jwt-secret=" + package_io.JWT_AUTH_PATH,
# vvvvvvvvvvvvvvvvvvv METRICS CONFIG vvvvvvvvvvvvvvvvvvvvv
"--metrics",
"--metrics.address=0.0.0.0",
......@@ -287,7 +278,7 @@ def get_beacon_config(
ports=BEACON_USED_PORTS,
cmd=cmd,
files={
GENESIS_DATA_MOUNT_DIRPATH_ON_SERVICE_CONTAINER: genesis_data.files_artifact_uuid
package_io.GENESIS_DATA_MOUNTPOINT_ON_CLIENTS: el_cl_genesis_data.files_artifact_uuid
},
private_ip_address_placeholder=PRIVATE_IP_ADDRESS_PLACEHOLDER,
ready_conditions=cl_node_ready_conditions.get_ready_conditions(HTTP_PORT_ID),
......@@ -300,7 +291,7 @@ def get_beacon_config(
def get_validator_config(
service_name,
genesis_data,
el_cl_genesis_data,
image,
log_level,
beacon_client_http_url,
......@@ -315,15 +306,11 @@ def get_validator_config(
CONSENSUS_DATA_DIRPATH_ON_SERVICE_CONTAINER, service_name
)
genesis_config_filepath = shared_utils.path_join(
GENESIS_DATA_MOUNT_DIRPATH_ON_SERVICE_CONTAINER,
genesis_data.config_yml_rel_filepath,
)
validator_keys_dirpath = shared_utils.path_join(
VALIDATOR_KEYS_MOUNT_DIRPATH_ON_SERVICE_CONTAINER,
node_keystore_files.raw_keys_relative_dirpath,
)
validator_secrets_dirpath = shared_utils.path_join(
VALIDATOR_KEYS_MOUNT_DIRPATH_ON_SERVICE_CONTAINER,
node_keystore_files.raw_secrets_relative_dirpath,
......@@ -333,7 +320,9 @@ def get_validator_config(
"validator",
"--logLevel=" + log_level,
"--dataDir=" + root_dirpath,
"--paramsFile=" + genesis_config_filepath,
"--paramsFile="
+ package_io.GENESIS_CONFIG_MOUNT_PATH_ON_CONTAINER
+ "/config.yaml",
"--beaconNodes=" + beacon_client_http_url,
"--keystoresDir=" + validator_keys_dirpath,
"--secretsDir=" + validator_secrets_dirpath,
......@@ -354,7 +343,7 @@ def get_validator_config(
ports=VALIDATOR_USED_PORTS,
cmd=cmd,
files={
GENESIS_DATA_MOUNT_DIRPATH_ON_SERVICE_CONTAINER: genesis_data.files_artifact_uuid,
package_io.GENESIS_DATA_MOUNTPOINT_ON_CLIENTS: el_cl_genesis_data.files_artifact_uuid,
VALIDATOR_KEYS_MOUNT_DIRPATH_ON_SERVICE_CONTAINER: node_keystore_files.files_artifact_uuid,
},
private_ip_address_placeholder=PRIVATE_IP_ADDRESS_PLACEHOLDER,
......@@ -365,7 +354,7 @@ def get_validator_config(
)
def new_lodestar_launcher(cl_genesis_data):
def new_lodestar_launcher(el_cl_genesis_data):
return struct(
cl_genesis_data=cl_genesis_data,
el_cl_genesis_data=el_cl_genesis_data,
)
......@@ -6,8 +6,6 @@ cl_node_ready_conditions = import_module("../../cl/cl_node_ready_conditions.star
package_io = import_module("../../package_io/constants.star")
GENESIS_DATA_MOUNTPOINT_ON_CLIENT = "/genesis-data"
VALIDATOR_KEYS_MOUNTPOINT_ON_CLIENT = "/validator-keys"
# Port IDs
......@@ -116,7 +114,7 @@ def launch(
bn_max_mem = int(v_max_mem) if (int(v_max_mem) > bn_max_mem) else bn_max_mem
config = get_config(
launcher.cl_genesis_data,
launcher.el_cl_genesis_data,
image,
bootnode_contexts,
el_client_context,
......@@ -170,7 +168,7 @@ def launch(
def get_config(
genesis_data,
el_cl_genesis_data,
image,
bootnode_contexts,
el_client_context,
......@@ -196,15 +194,6 @@ def get_config(
el_client_context.engine_rpc_port_num,
)
# For some reason, Nimbus takes in the parent directory of the config file (rather than the path to the config file itself)
genesis_config_parent_dirpath_on_client = shared_utils.path_join(
GENESIS_DATA_MOUNTPOINT_ON_CLIENT,
shared_utils.path_dir(genesis_data.config_yml_rel_filepath),
)
jwt_secret_filepath = shared_utils.path_join(
GENESIS_DATA_MOUNTPOINT_ON_CLIENT, genesis_data.jwt_secret_rel_filepath
)
validator_keys_dirpath = ""
validator_secrets_dirpath = ""
if node_keystore_files != None:
......@@ -259,7 +248,7 @@ def get_config(
"--log-level=" + log_level,
"--udp-port={0}".format(DISCOVERY_PORT_NUM),
"--tcp-port={0}".format(DISCOVERY_PORT_NUM),
"--network=" + genesis_config_parent_dirpath_on_client,
"--network=" + package_io.GENESIS_CONFIG_MOUNT_PATH_ON_CONTAINER,
"--data-dir=" + CONSENSUS_DATA_DIRPATH_IN_SERVICE_CONTAINER,
"--web3-url=" + EXECUTION_ENGINE_ENDPOINT,
"--nat=extip:" + PRIVATE_IP_ADDRESS_PLACEHOLDER,
......@@ -277,7 +266,7 @@ def get_config(
"--subscribe-all-subnets=true",
# Nimbus can handle a max of 256 threads, if the host has more then nimbus crashes. Setting it to 4 so it doesn't crash on build servers
"--num-threads=4",
"--jwt-secret={0}".format(jwt_secret_filepath),
"--jwt-secret=" + package_io.JWT_AUTH_PATH,
# vvvvvvvvvvvvvvvvvvv METRICS CONFIG vvvvvvvvvvvvvvvvvvvvv
"--metrics",
"--metrics-address=0.0.0.0",
......@@ -307,7 +296,7 @@ def get_config(
cmd.extend([param for param in extra_params])
files = {
GENESIS_DATA_MOUNTPOINT_ON_CLIENT: genesis_data.files_artifact_uuid,
package_io.GENESIS_DATA_MOUNTPOINT_ON_CLIENTS: el_cl_genesis_data.files_artifact_uuid,
}
if node_keystore_files:
files[
......@@ -329,7 +318,7 @@ def get_config(
)
def new_nimbus_launcher(cl_genesis_data):
def new_nimbus_launcher(el_cl_genesis_data):
return struct(
cl_genesis_data=cl_genesis_data,
el_cl_genesis_data=el_cl_genesis_data,
)
......@@ -7,10 +7,9 @@ package_io = import_module("../../package_io/constants.star")
IMAGE_SEPARATOR_DELIMITER = ","
EXPECTED_NUM_IMAGES = 2
# ---------------------------------- Beacon client -------------------------------------
CONSENSUS_DATA_DIRPATH_ON_SERVICE_CONTAINER = "/consensus-data"
GENESIS_DATA_MOUNT_DIRPATH_ON_SERVICE_CONTAINER = "/genesis"
# Port IDs
TCP_DISCOVERY_PORT_ID = "tcp-discovery"
......@@ -135,7 +134,7 @@ def launch(
bn_max_mem = int(bn_max_mem) if int(bn_max_mem) > 0 else BEACON_MAX_MEMORY
beacon_config = get_beacon_config(
launcher.genesis_data,
launcher.el_cl_genesis_data,
beacon_image,
bootnode_contexts,
el_client_context,
......@@ -164,7 +163,7 @@ def launch(
v_min_mem = int(v_min_mem) if int(v_min_mem) > 0 else VALIDATOR_MIN_MEMORY
v_max_mem = int(v_max_mem) if int(v_max_mem) > 0 else VALIDATOR_MAX_MEMORY
validator_config = get_validator_config(
launcher.genesis_data,
launcher.el_cl_genesis_data,
validator_image,
validator_node_service_name,
log_level,
......@@ -236,7 +235,7 @@ def launch(
def get_beacon_config(
genesis_data,
el_cl_genesis_data,
beacon_image,
bootnode_contexts,
el_client_context,
......@@ -261,24 +260,15 @@ def get_beacon_config(
el_client_context.engine_rpc_port_num,
)
genesis_config_filepath = shared_utils.path_join(
GENESIS_DATA_MOUNT_DIRPATH_ON_SERVICE_CONTAINER,
genesis_data.config_yml_rel_filepath,
)
genesis_ssz_filepath = shared_utils.path_join(
GENESIS_DATA_MOUNT_DIRPATH_ON_SERVICE_CONTAINER,
genesis_data.genesis_ssz_rel_filepath,
)
jwt_secret_filepath = shared_utils.path_join(
GENESIS_DATA_MOUNT_DIRPATH_ON_SERVICE_CONTAINER,
genesis_data.jwt_secret_rel_filepath,
)
cmd = [
"--accept-terms-of-use=true", # it's mandatory in order to run the node
"--datadir=" + CONSENSUS_DATA_DIRPATH_ON_SERVICE_CONTAINER,
"--chain-config-file=" + genesis_config_filepath,
"--genesis-state=" + genesis_ssz_filepath,
"--chain-config-file="
+ package_io.GENESIS_CONFIG_MOUNT_PATH_ON_CONTAINER
+ "/config.yaml",
"--genesis-state="
+ package_io.GENESIS_CONFIG_MOUNT_PATH_ON_CONTAINER
+ "/genesis.ssz",
"--execution-endpoint=" + EXECUTION_ENGINE_ENDPOINT,
"--rpc-host=0.0.0.0",
"--rpc-port={0}".format(RPC_PORT_NUM),
......@@ -294,7 +284,7 @@ def get_beacon_config(
"--suggested-fee-recipient=" + package_io.VALIDATING_REWARDS_ACCOUNT,
# Set per Pari's recommendation to reduce noise
"--subscribe-all-subnets=true",
"--jwt-secret={0}".format(jwt_secret_filepath),
"--jwt-secret=" + package_io.JWT_AUTH_PATH,
# vvvvvvvvv METRICS CONFIG vvvvvvvvvvvvvvvvvvvvv
"--disable-monitoring=false",
"--monitoring-host=0.0.0.0",
......@@ -317,7 +307,7 @@ def get_beacon_config(
ports=BEACON_NODE_USED_PORTS,
cmd=cmd,
files={
GENESIS_DATA_MOUNT_DIRPATH_ON_SERVICE_CONTAINER: genesis_data.files_artifact_uuid,
package_io.GENESIS_DATA_MOUNTPOINT_ON_CLIENTS: el_cl_genesis_data.files_artifact_uuid,
},
private_ip_address_placeholder=PRIVATE_IP_ADDRESS_PLACEHOLDER,
ready_conditions=cl_node_ready_conditions.get_ready_conditions(HTTP_PORT_ID),
......@@ -329,7 +319,7 @@ def get_beacon_config(
def get_validator_config(
genesis_data,
el_cl_genesis_data,
validator_image,
service_name,
log_level,
......@@ -344,14 +334,6 @@ def get_validator_config(
prysm_password_relative_filepath,
prysm_password_artifact_uuid,
):
consensus_data_dirpath = shared_utils.path_join(
CONSENSUS_DATA_DIRPATH_ON_SERVICE_CONTAINER, service_name
)
genesis_config_filepath = shared_utils.path_join(
GENESIS_DATA_MOUNT_DIRPATH_ON_SERVICE_CONTAINER,
genesis_data.config_yml_rel_filepath,
)
validator_keys_dirpath = shared_utils.path_join(
VALIDATOR_KEYS_MOUNT_DIRPATH_ON_SERVICE_CONTAINER,
node_keystore_files.prysm_relative_dirpath,
......@@ -363,12 +345,14 @@ def get_validator_config(
cmd = [
"--accept-terms-of-use=true", # it's mandatory in order to run the node
"--chain-config-file=" + genesis_config_filepath,
"--chain-config-file="
+ package_io.GENESIS_CONFIG_MOUNT_PATH_ON_CONTAINER
+ "/config.yaml",
"--beacon-rpc-gateway-provider=" + beacon_http_endpoint,
"--beacon-rpc-provider=" + beacon_rpc_endpoint,
"--wallet-dir=" + validator_keys_dirpath,
"--wallet-password-file=" + validator_secrets_dirpath,
"--datadir=" + consensus_data_dirpath,
"--datadir=" + CONSENSUS_DATA_DIRPATH_ON_SERVICE_CONTAINER,
"--monitoring-port={0}".format(VALIDATOR_MONITORING_PORT_NUM),
"--verbosity=" + log_level,
"--suggested-fee-recipient=" + package_io.VALIDATING_REWARDS_ACCOUNT,
......@@ -389,7 +373,7 @@ def get_validator_config(
ports=VALIDATOR_NODE_USED_PORTS,
cmd=cmd,
files={
GENESIS_DATA_MOUNT_DIRPATH_ON_SERVICE_CONTAINER: genesis_data.files_artifact_uuid,
package_io.GENESIS_DATA_MOUNTPOINT_ON_CLIENTS: el_cl_genesis_data.files_artifact_uuid,
VALIDATOR_KEYS_MOUNT_DIRPATH_ON_SERVICE_CONTAINER: node_keystore_files.files_artifact_uuid,
PRYSM_PASSWORD_MOUNT_DIRPATH_ON_SERVICE_CONTAINER: prysm_password_artifact_uuid,
},
......@@ -402,10 +386,10 @@ def get_validator_config(
def new_prysm_launcher(
genesis_data, prysm_password_relative_filepath, prysm_password_artifact_uuid
el_cl_genesis_data, prysm_password_relative_filepath, prysm_password_artifact_uuid
):
return struct(
genesis_data=genesis_data,
el_cl_genesis_data=el_cl_genesis_data,
prysm_password_artifact_uuid=prysm_password_artifact_uuid,
prysm_password_relative_filepath=prysm_password_relative_filepath,
)
......@@ -8,8 +8,6 @@ package_io = import_module("../../package_io/constants.star")
TEKU_BINARY_FILEPATH_IN_IMAGE = "/opt/teku/bin/teku"
GENESIS_DATA_MOUNT_DIRPATH_ON_SERVICE_CONTAINER = "/genesis"
# The Docker container runs as the "teku" user so we can't write to root
CONSENSUS_DATA_DIRPATH_ON_SERVICE_CONTAINER = "/opt/teku/consensus-data"
......@@ -118,7 +116,7 @@ def launch(
bn_max_mem = int(v_max_mem) if (int(v_max_mem) > bn_max_mem) else bn_max_mem
config = get_config(
launcher.cl_genesis_data,
launcher.el_cl_genesis_data,
image,
bootnode_context,
el_client_context,
......@@ -174,7 +172,7 @@ def launch(
def get_config(
genesis_data,
el_cl_genesis_data,
image,
bootnode_contexts,
el_client_context,
......@@ -200,19 +198,6 @@ def get_config(
el_client_context.engine_rpc_port_num,
)
genesis_config_filepath = shared_utils.path_join(
GENESIS_DATA_MOUNT_DIRPATH_ON_SERVICE_CONTAINER,
genesis_data.config_yml_rel_filepath,
)
genesis_ssz_filepath = shared_utils.path_join(
GENESIS_DATA_MOUNT_DIRPATH_ON_SERVICE_CONTAINER,
genesis_data.genesis_ssz_rel_filepath,
)
jwt_secret_filepath = shared_utils.path_join(
GENESIS_DATA_MOUNT_DIRPATH_ON_SERVICE_CONTAINER,
genesis_data.jwt_secret_rel_filepath,
)
validator_keys_dirpath = ""
validator_secrets_dirpath = ""
if node_keystore_files:
......@@ -251,8 +236,12 @@ def get_config(
TEKU_BINARY_FILEPATH_IN_IMAGE,
"--logging=" + log_level,
"--log-destination=CONSOLE",
"--network=" + genesis_config_filepath,
"--initial-state=" + genesis_ssz_filepath,
"--network="
+ package_io.GENESIS_CONFIG_MOUNT_PATH_ON_CONTAINER
+ "/config.yaml",
"--initial-state="
+ package_io.GENESIS_CONFIG_MOUNT_PATH_ON_CONTAINER
+ "/genesis.ssz",
"--data-path=" + CONSENSUS_DATA_DIRPATH_ON_SERVICE_CONTAINER,
"--data-storage-mode={0}".format(
"ARCHIVE" if package_io.ARCHIVE_MODE else "PRUNE"
......@@ -269,7 +258,7 @@ def get_config(
"--rest-api-port={0}".format(HTTP_PORT_NUM),
"--rest-api-host-allowlist=*",
"--data-storage-non-canonical-blocks-enabled=true",
"--ee-jwt-secret-file={0}".format(jwt_secret_filepath),
"--ee-jwt-secret-file=" + package_io.JWT_AUTH_PATH,
"--ee-endpoint=" + EXECUTION_ENGINE_ENDPOINT,
# vvvvvvvvvvvvvvvvvvv METRICS CONFIG vvvvvvvvvvvvvvvvvvvvv
"--metrics-enabled",
......@@ -311,7 +300,7 @@ def get_config(
cmd.extend([param for param in extra_params])
files = {
GENESIS_DATA_MOUNT_DIRPATH_ON_SERVICE_CONTAINER: genesis_data.files_artifact_uuid,
package_io.GENESIS_DATA_MOUNTPOINT_ON_CLIENTS: el_cl_genesis_data.files_artifact_uuid,
}
if node_keystore_files:
files[
......@@ -333,5 +322,5 @@ def get_config(
)
def new_teku_launcher(cl_genesis_data):
return struct(cl_genesis_data=cl_genesis_data)
def new_teku_launcher(el_cl_genesis_data):
return struct(el_cl_genesis_data=el_cl_genesis_data)
shared_utils = import_module("../shared_utils/shared_utils.star")
package_io = import_module("../package_io/constants.star")
SERVICE_NAME = "dora"
IMAGE_NAME = "ethpandaops/dora:master"
......@@ -14,9 +13,6 @@ DORA_CONFIG_MOUNT_DIRPATH_ON_SERVICE = "/config"
VALIDATOR_RANGES_MOUNT_DIRPATH_ON_SERVICE = "/validator-ranges"
VALIDATOR_RANGES_ARTIFACT_NAME = "validator-ranges"
CL_CONFIG_MOUNT_DIRPATH_ON_SERVICE = "/cl-genesis-data"
CL_CONFIG_ARTIFACT_NAME = "cl-genesis-data"
USED_PORTS = {
HTTP_PORT_ID: shared_utils.new_port_spec(
......@@ -28,9 +24,7 @@ USED_PORTS = {
def launch_dora(
plan,
config_template,
cl_client_contexts,
plan, config_template, cl_client_contexts, el_cl_data_files_artifact_uuid
):
all_cl_client_info = []
for index, client in enumerate(cl_client_contexts):
......@@ -51,13 +45,16 @@ def launch_dora(
config_files_artifact_name = plan.render_templates(
template_and_data_by_rel_dest_filepath, "dora-config"
)
config = get_config(config_files_artifact_name)
el_cl_data_files_artifact_uuid = el_cl_data_files_artifact_uuid
config = get_config(
config_files_artifact_name,
el_cl_data_files_artifact_uuid,
)
plan.add_service(SERVICE_NAME, config)
def get_config(config_files_artifact_name):
def get_config(config_files_artifact_name, el_cl_data_files_artifact_uuid):
config_file_path = shared_utils.path_join(
DORA_CONFIG_MOUNT_DIRPATH_ON_SERVICE,
DORA_CONFIG_FILENAME,
......@@ -68,7 +65,7 @@ def get_config(config_files_artifact_name):
files={
DORA_CONFIG_MOUNT_DIRPATH_ON_SERVICE: config_files_artifact_name,
VALIDATOR_RANGES_MOUNT_DIRPATH_ON_SERVICE: VALIDATOR_RANGES_ARTIFACT_NAME,
CL_CONFIG_MOUNT_DIRPATH_ON_SERVICE: CL_CONFIG_ARTIFACT_NAME,
package_io.GENESIS_DATA_MOUNTPOINT_ON_CLIENTS: el_cl_data_files_artifact_uuid,
},
cmd=["-config", config_file_path],
)
......
......@@ -7,9 +7,6 @@ package_io = import_module("../../package_io/constants.star")
# The dirpath of the execution data directory on the client container
EXECUTION_DATA_DIRPATH_ON_CLIENT_CONTAINER = "/opt/besu/execution-data"
KZG_DATA_DIRPATH_ON_CLIENT_CONTAINER = "/opt/besu/genesis/output/trusted_setup.txt"
GENESIS_DATA_DIRPATH_ON_CLIENT_CONTAINER = "/opt/besu/genesis"
METRICS_PATH = "/metrics"
......@@ -87,9 +84,9 @@ def launch(
el_min_mem = int(el_min_mem) if int(el_min_mem) > 0 else EXECUTION_MIN_MEMORY
el_max_mem = int(el_max_mem) if int(el_max_mem) > 0 else EXECUTION_MAX_MEMORY
config, jwt_secret_json_filepath_on_client = get_config(
config = get_config(
launcher.network_id,
launcher.el_genesis_data,
launcher.el_cl_genesis_data,
image,
existing_el_clients,
log_level,
......@@ -105,10 +102,6 @@ def launch(
enode = el_admin_node_info.get_enode_for_node(plan, service_name, RPC_PORT_ID)
jwt_secret = shared_utils.read_file_from_service(
plan, service_name, jwt_secret_json_filepath_on_client
)
metrics_url = "{0}:{1}".format(service.ip_address, METRICS_PORT_NUM)
besu_metrics_info = node_metrics.new_node_metrics_info(
service_name, METRICS_PATH, metrics_url
......@@ -122,7 +115,6 @@ def launch(
RPC_PORT_NUM,
WS_PORT_NUM,
ENGINE_HTTP_RPC_PORT_NUM,
jwt_secret,
service_name,
[besu_metrics_info],
)
......@@ -130,7 +122,7 @@ def launch(
def get_config(
network_id,
genesis_data,
el_cl_genesis_data,
image,
existing_el_clients,
log_level,
......@@ -141,20 +133,13 @@ def get_config(
extra_params,
extra_env_vars,
):
genesis_json_filepath_on_client = shared_utils.path_join(
GENESIS_DATA_DIRPATH_ON_CLIENT_CONTAINER,
genesis_data.besu_genesis_json_relative_filepath,
)
jwt_secret_json_filepath_on_client = shared_utils.path_join(
GENESIS_DATA_DIRPATH_ON_CLIENT_CONTAINER,
genesis_data.jwt_secret_relative_filepath,
)
cmd = [
"besu",
"--logging=" + log_level,
"--data-path=" + EXECUTION_DATA_DIRPATH_ON_CLIENT_CONTAINER,
"--genesis-file=" + genesis_json_filepath_on_client,
"--genesis-file="
+ package_io.GENESIS_CONFIG_MOUNT_PATH_ON_CONTAINER
+ "/besu.json",
"--network-id=" + network_id,
"--host-allowlist=*",
"--rpc-http-enabled=true",
......@@ -170,12 +155,12 @@ def get_config(
"--p2p-host=" + PRIVATE_IP_ADDRESS_PLACEHOLDER,
"--p2p-port={0}".format(DISCOVERY_PORT_NUM),
"--engine-rpc-enabled=true",
"--engine-jwt-secret={0}".format(jwt_secret_json_filepath_on_client),
"--engine-jwt-secret=" + package_io.JWT_AUTH_PATH,
"--engine-host-allowlist=*",
"--engine-rpc-port={0}".format(ENGINE_HTTP_RPC_PORT_NUM),
"--sync-mode=FULL",
"--data-storage-format=BONSAI",
"--kzg-trusted-setup=" + KZG_DATA_DIRPATH_ON_CLIENT_CONTAINER,
"--kzg-trusted-setup=" + package_io.KZG_DATA_DIRPATH_ON_CLIENT_CONTAINER,
"--metrics-enabled=true",
"--metrics-host=0.0.0.0",
"--metrics-port={0}".format(METRICS_PORT_NUM),
......@@ -198,25 +183,22 @@ def get_config(
cmd_str = " ".join(cmd)
return (
ServiceConfig(
image=image,
ports=USED_PORTS,
cmd=[cmd_str],
files={
GENESIS_DATA_DIRPATH_ON_CLIENT_CONTAINER: genesis_data.files_artifact_uuid
},
entrypoint=ENTRYPOINT_ARGS,
private_ip_address_placeholder=PRIVATE_IP_ADDRESS_PLACEHOLDER,
min_cpu=el_min_cpu,
max_cpu=el_max_cpu,
min_memory=el_min_mem,
max_memory=el_max_mem,
env_vars=extra_env_vars,
),
jwt_secret_json_filepath_on_client,
return ServiceConfig(
image=image,
ports=USED_PORTS,
cmd=[cmd_str],
files={
package_io.GENESIS_DATA_MOUNTPOINT_ON_CLIENTS: el_cl_genesis_data.files_artifact_uuid,
},
entrypoint=ENTRYPOINT_ARGS,
private_ip_address_placeholder=PRIVATE_IP_ADDRESS_PLACEHOLDER,
min_cpu=el_min_cpu,
max_cpu=el_max_cpu,
min_memory=el_min_mem,
max_memory=el_max_mem,
env_vars=extra_env_vars,
)
def new_besu_launcher(network_id, el_genesis_data):
return struct(network_id=network_id, el_genesis_data=el_genesis_data)
def new_besu_launcher(network_id, el_cl_genesis_data):
return struct(network_id=network_id, el_cl_genesis_data=el_cl_genesis_data)
......@@ -6,7 +6,6 @@ def new_el_client_context(
rpc_port_num,
ws_port_num,
engine_rpc_port_num,
jwt_secret,
service_name="",
el_metrics_info=None,
):
......@@ -19,6 +18,5 @@ def new_el_client_context(
rpc_port_num=rpc_port_num,
ws_port_num=ws_port_num,
engine_rpc_port_num=engine_rpc_port_num,
jwt_secret=jwt_secret,
el_metrics_info=el_metrics_info,
)
......@@ -9,8 +9,6 @@ package_io = import_module("../../package_io/constants.star")
# The dirpath of the execution data directory on the client container
EXECUTION_DATA_DIRPATH_ON_CLIENT_CONTAINER = "/home/erigon/execution-data"
GENESIS_DATA_MOUNT_DIRPATH = "/genesis"
METRICS_PATH = "/metrics"
WS_RPC_PORT_NUM = 8545
......@@ -87,9 +85,9 @@ def launch(
el_min_mem = el_min_mem if int(el_min_mem) > 0 else EXECUTION_MIN_MEMORY
el_max_mem = el_max_mem if int(el_max_mem) > 0 else EXECUTION_MAX_MEMORY
config, jwt_secret_json_filepath_on_client = get_config(
config = get_config(
launcher.network_id,
launcher.el_genesis_data,
launcher.el_cl_genesis_data,
image,
existing_el_clients,
log_level,
......@@ -107,10 +105,6 @@ def launch(
plan, service_name, WS_RPC_PORT_ID
)
jwt_secret = shared_utils.read_file_from_service(
plan, service_name, jwt_secret_json_filepath_on_client
)
metrics_url = "{0}:{1}".format(service.ip_address, METRICS_PORT_NUM)
erigon_metrics_info = node_metrics.new_node_metrics_info(
service_name, METRICS_PATH, metrics_url
......@@ -124,7 +118,6 @@ def launch(
WS_RPC_PORT_NUM,
WS_RPC_PORT_NUM,
ENGINE_RPC_PORT_NUM,
jwt_secret,
service_name,
[erigon_metrics_info],
)
......@@ -132,7 +125,7 @@ def launch(
def get_config(
network_id,
genesis_data,
el_cl_genesis_data,
image,
existing_el_clients,
verbosity_level,
......@@ -145,24 +138,11 @@ def get_config(
):
network_id = network_id
genesis_json_filepath_on_client = shared_utils.path_join(
GENESIS_DATA_MOUNT_DIRPATH, genesis_data.erigon_genesis_json_relative_filepath
)
jwt_secret_json_filepath_on_client = shared_utils.path_join(
GENESIS_DATA_MOUNT_DIRPATH, genesis_data.jwt_secret_relative_filepath
)
init_datadir_cmd_str = "erigon init --datadir={0} {1}".format(
EXECUTION_DATA_DIRPATH_ON_CLIENT_CONTAINER,
genesis_json_filepath_on_client,
package_io.GENESIS_CONFIG_MOUNT_PATH_ON_CONTAINER + "/genesis.json",
)
# TODO remove this based on https://github.com/kurtosis-tech/eth2-merge-kurtosis-module/issues/152
if len(existing_el_clients) == 0:
fail("Erigon needs at least one node to exist, which it treats as the bootnode")
boot_node_1 = existing_el_clients[0]
cmd = [
"erigon",
"--log.console.verbosity=" + verbosity_level,
......@@ -178,7 +158,7 @@ def get_config(
"--http.addr=0.0.0.0",
"--http.corsdomain=*",
"--http.port={0}".format(WS_RPC_PORT_NUM),
"--authrpc.jwtsecret={0}".format(jwt_secret_json_filepath_on_client),
"--authrpc.jwtsecret=" + package_io.JWT_AUTH_PATH,
"--authrpc.addr=0.0.0.0",
"--authrpc.port={0}".format(ENGINE_RPC_PORT_NUM),
"--authrpc.vhosts=*",
......@@ -215,26 +195,25 @@ def get_config(
command_arg_str = " && ".join(command_arg)
return (
ServiceConfig(
image=image,
ports=USED_PORTS,
cmd=[command_arg_str],
files={GENESIS_DATA_MOUNT_DIRPATH: genesis_data.files_artifact_uuid},
entrypoint=ENTRYPOINT_ARGS,
private_ip_address_placeholder=PRIVATE_IP_ADDRESS_PLACEHOLDER,
min_cpu=el_min_cpu,
max_cpu=el_max_cpu,
min_memory=el_min_mem,
max_memory=el_max_mem,
env_vars=extra_env_vars,
),
jwt_secret_json_filepath_on_client,
return ServiceConfig(
image=image,
ports=USED_PORTS,
cmd=[command_arg_str],
files={
package_io.GENESIS_DATA_MOUNTPOINT_ON_CLIENTS: el_cl_genesis_data.files_artifact_uuid,
},
entrypoint=ENTRYPOINT_ARGS,
private_ip_address_placeholder=PRIVATE_IP_ADDRESS_PLACEHOLDER,
min_cpu=el_min_cpu,
max_cpu=el_max_cpu,
min_memory=el_min_mem,
max_memory=el_max_mem,
env_vars=extra_env_vars,
)
def new_erigon_launcher(network_id, el_genesis_data):
def new_erigon_launcher(network_id, el_cl_genesis_data):
return struct(
network_id=network_id,
el_genesis_data=el_genesis_data,
el_cl_genesis_data=el_cl_genesis_data,
)
......@@ -28,11 +28,6 @@ UDP_DISCOVERY_PORT_ID = "udp-discovery"
ENGINE_RPC_PORT_ID = "engine-rpc"
WS_PORT_ENGINE_ID = "ws-engine"
METRICS_PORT_ID = "metrics"
GENESIS_DATA_MOUNT_DIRPATH = "/genesis"
PREFUNDED_KEYS_MOUNT_DIRPATH = "/prefunded-keys"
METRICS_PATH = "/metrics"
# The dirpath of the execution data directory on the client container
......@@ -94,8 +89,8 @@ def launch(
el_min_mem = el_min_mem if int(el_min_mem) > 0 else EXECUTION_MIN_MEMORY
el_max_mem = el_max_mem if int(el_max_mem) > 0 else EXECUTION_MAX_MEMORY
config, jwt_secret_json_filepath_on_client = get_config(
launcher.el_genesis_data,
config = get_config(
launcher.el_cl_genesis_data,
image,
existing_el_clients,
log_level,
......@@ -111,10 +106,6 @@ def launch(
enode = el_admin_node_info.get_enode_for_node(plan, service_name, RPC_PORT_ID)
jwt_secret = shared_utils.read_file_from_service(
plan, service_name, jwt_secret_json_filepath_on_client
)
# TODO: Passing empty string for metrics_url for now https://github.com/kurtosis-tech/ethereum-package/issues/127
# metrics_url = "http://{0}:{1}".format(service.ip_address, METRICS_PORT_NUM)
ethjs_metrics_info = None
......@@ -127,14 +118,13 @@ def launch(
RPC_PORT_NUM,
WS_PORT_NUM,
ENGINE_RPC_PORT_NUM,
jwt_secret,
service_name,
[ethjs_metrics_info],
)
def get_config(
genesis_data,
el_cl_genesis_data,
image,
existing_el_clients,
verbosity_level,
......@@ -145,15 +135,10 @@ def get_config(
extra_params,
extra_env_vars,
):
genesis_json_filepath_on_client = shared_utils.path_join(
GENESIS_DATA_MOUNT_DIRPATH, genesis_data.geth_genesis_json_relative_filepath
)
jwt_secret_json_filepath_on_client = shared_utils.path_join(
GENESIS_DATA_MOUNT_DIRPATH, genesis_data.jwt_secret_relative_filepath
)
cmd = [
"--gethGenesis=" + genesis_json_filepath_on_client,
"--gethGenesis="
+ package_io.GENESIS_CONFIG_MOUNT_PATH_ON_CONTAINER
+ "/genesis.json",
"--dataDir=" + EXECUTION_DATA_DIRPATH_ON_CLIENT_CONTAINER,
"--port={0}".format(DISCOVERY_PORT_NUM),
"--rpc",
......@@ -168,7 +153,7 @@ def get_config(
"--wsPort={0}".format(WS_PORT_NUM),
"--wsEnginePort={0}".format(WS_PORT_ENGINE_NUM),
"--wsEngineAddr=0.0.0.0",
"--jwt-secret={0}".format(jwt_secret_json_filepath_on_client),
"--jwt-secret=" + package_io.JWT_AUTH_PATH,
"--extIP={0}".format(PRIVATE_IP_ADDRESS_PLACEHOLDER),
"--sync=full",
"--isSingleNode=true",
......@@ -190,27 +175,24 @@ def get_config(
# this is a repeated<proto type>, we convert it into Starlark
cmd.extend([param for param in extra_params])
return (
ServiceConfig(
image=image,
ports=USED_PORTS,
cmd=cmd,
files={
GENESIS_DATA_MOUNT_DIRPATH: genesis_data.files_artifact_uuid,
},
entrypoint=ENTRYPOINT_ARGS,
private_ip_address_placeholder=PRIVATE_IP_ADDRESS_PLACEHOLDER,
min_cpu=el_min_cpu,
max_cpu=el_max_cpu,
min_memory=el_min_mem,
max_memory=el_max_mem,
env_vars=extra_env_vars,
),
jwt_secret_json_filepath_on_client,
return ServiceConfig(
image=image,
ports=USED_PORTS,
cmd=cmd,
files={
package_io.GENESIS_DATA_MOUNTPOINT_ON_CLIENTS: el_cl_genesis_data.files_artifact_uuid,
},
entrypoint=ENTRYPOINT_ARGS,
private_ip_address_placeholder=PRIVATE_IP_ADDRESS_PLACEHOLDER,
min_cpu=el_min_cpu,
max_cpu=el_max_cpu,
min_memory=el_min_mem,
max_memory=el_max_mem,
env_vars=extra_env_vars,
)
def new_ethereumjs_launcher(el_genesis_data):
def new_ethereumjs_launcher(el_cl_genesis_data):
return struct(
el_genesis_data=el_genesis_data,
el_cl_genesis_data=el_cl_genesis_data,
)
......@@ -9,7 +9,6 @@ genesis_constants = import_module(
node_metrics = import_module("../../node_metrics_info.star")
package_io = import_module("../../package_io/constants.star")
RPC_PORT_NUM = 8545
WS_PORT_NUM = 8546
DISCOVERY_PORT_NUM = 30303
......@@ -34,28 +33,16 @@ METRICS_PORT_ID = "metrics"
# TODO(old) Scale this dynamically based on CPUs available and Geth nodes mining
NUM_MINING_THREADS = 1
GENESIS_DATA_MOUNT_DIRPATH = "/genesis"
PREFUNDED_KEYS_MOUNT_DIRPATH = "/prefunded-keys"
METRICS_PATH = "/debug/metrics/prometheus"
# The dirpath of the execution data directory on the client container
EXECUTION_DATA_DIRPATH_ON_CLIENT_CONTAINER = "/execution-data"
KEYSTORE_DIRPATH_ON_CLIENT_CONTAINER = (
EXECUTION_DATA_DIRPATH_ON_CLIENT_CONTAINER + "/keystore"
)
GETH_ACCOUNT_PASSWORD = (
"password" # Password that the Geth accounts will be locked with
)
GETH_ACCOUNT_PASSWORDS_FILE = "/tmp/password.txt" # Importing an account to
PRIVATE_IP_ADDRESS_PLACEHOLDER = "KURTOSIS_IP_ADDR_PLACEHOLDER"
USED_PORTS = {
RPC_PORT_ID: shared_utils.new_port_spec(RPC_PORT_NUM, shared_utils.TCP_PROTOCOL),
WS_PORT_ID: shared_utils.new_port_spec(WS_PORT_NUM, shared_utils.TCP_PROTOCOL),
# WS_PORT_ID: shared_utils.new_port_spec(WS_PORT_NUM, shared_utils.TCP_PROTOCOL),
TCP_DISCOVERY_PORT_ID: shared_utils.new_port_spec(
DISCOVERY_PORT_NUM, shared_utils.TCP_PROTOCOL
),
......@@ -107,12 +94,9 @@ def launch(
el_min_mem = el_min_mem if int(el_min_mem) > 0 else EXECUTION_MIN_MEMORY
el_max_mem = el_max_mem if int(el_max_mem) > 0 else EXECUTION_MAX_MEMORY
config, jwt_secret_json_filepath_on_client = get_config(
config = get_config(
launcher.network_id,
launcher.el_genesis_data,
launcher.prefunded_geth_keys_artifact_uuid,
launcher.prefunded_account_info,
launcher.genesis_validators_root,
launcher.el_cl_genesis_data,
image,
existing_el_clients,
log_level,
......@@ -131,10 +115,6 @@ def launch(
plan, service_name, RPC_PORT_ID
)
jwt_secret = shared_utils.read_file_from_service(
plan, service_name, jwt_secret_json_filepath_on_client
)
metrics_url = "{0}:{1}".format(service.ip_address, METRICS_PORT_NUM)
geth_metrics_info = node_metrics.new_node_metrics_info(
service_name, METRICS_PATH, metrics_url
......@@ -148,7 +128,6 @@ def launch(
RPC_PORT_NUM,
WS_PORT_NUM,
ENGINE_RPC_PORT_NUM,
jwt_secret,
service_name,
[geth_metrics_info],
)
......@@ -156,10 +135,7 @@ def launch(
def get_config(
network_id,
genesis_data,
prefunded_geth_keys_artifact_uuid,
prefunded_account_info,
genesis_validators_root,
el_cl_genesis_data,
image,
existing_el_clients,
verbosity_level,
......@@ -171,52 +147,16 @@ def get_config(
extra_env_vars,
electra_fork_epoch,
):
genesis_json_filepath_on_client = shared_utils.path_join(
GENESIS_DATA_MOUNT_DIRPATH, genesis_data.geth_genesis_json_relative_filepath
)
jwt_secret_json_filepath_on_client = shared_utils.path_join(
GENESIS_DATA_MOUNT_DIRPATH, genesis_data.jwt_secret_relative_filepath
)
account_addresses_to_unlock = []
for prefunded_account in prefunded_account_info:
account_addresses_to_unlock.append(prefunded_account.address)
for index, extra_param in enumerate(extra_params):
if package_io.GENESIS_VALIDATORS_ROOT_PLACEHOLDER in extra_param:
extra_params[index] = extra_param.replace(
package_io.GENESIS_VALIDATORS_ROOT_PLACEHOLDER, genesis_validators_root
)
accounts_to_unlock_str = ",".join(account_addresses_to_unlock)
init_datadir_cmd_str = "geth init {0} --datadir={1} {2}".format(
init_datadir_cmd_str = "geth init {0} --state.scheme=path --datadir={1} {2}".format(
"--cache.preimages" if electra_fork_epoch != None else "",
EXECUTION_DATA_DIRPATH_ON_CLIENT_CONTAINER,
genesis_json_filepath_on_client,
)
# We need to put the keys into the right spot
copy_keys_into_keystore_cmd_str = "cp -r {0}/* {1}/".format(
PREFUNDED_KEYS_MOUNT_DIRPATH,
KEYSTORE_DIRPATH_ON_CLIENT_CONTAINER,
)
create_passwords_file_cmd_str = (
"{"
+ ' for i in $(seq 1 {0}); do echo "{1}" >> {2}; done; '.format(
len(prefunded_account_info),
GETH_ACCOUNT_PASSWORD,
GETH_ACCOUNT_PASSWORDS_FILE,
)
+ "}"
package_io.GENESIS_CONFIG_MOUNT_PATH_ON_CONTAINER + "/genesis.json",
)
cmd = [
"geth",
"--state.scheme=path",
"--verbosity=" + verbosity_level,
"--unlock=" + accounts_to_unlock_str,
"--password=" + GETH_ACCOUNT_PASSWORDS_FILE,
"--datadir=" + EXECUTION_DATA_DIRPATH_ON_CLIENT_CONTAINER,
"--networkid=" + network_id,
"--http",
......@@ -237,7 +177,7 @@ def get_config(
"--authrpc.port={0}".format(ENGINE_RPC_PORT_NUM),
"--authrpc.addr=0.0.0.0",
"--authrpc.vhosts=*",
"--authrpc.jwtsecret={0}".format(jwt_secret_json_filepath_on_client),
"--authrpc.jwtsecret=" + package_io.JWT_AUTH_PATH,
"--syncmode=full",
"--rpc.allow-unprotected-txs",
"--metrics",
......@@ -268,46 +208,34 @@ def get_config(
subcommand_strs = [
init_datadir_cmd_str,
copy_keys_into_keystore_cmd_str,
create_passwords_file_cmd_str,
cmd_str,
]
command_str = " && ".join(subcommand_strs)
return (
ServiceConfig(
image=image,
ports=USED_PORTS,
cmd=[command_str],
files={
GENESIS_DATA_MOUNT_DIRPATH: genesis_data.files_artifact_uuid,
PREFUNDED_KEYS_MOUNT_DIRPATH: prefunded_geth_keys_artifact_uuid,
},
entrypoint=ENTRYPOINT_ARGS,
private_ip_address_placeholder=PRIVATE_IP_ADDRESS_PLACEHOLDER,
min_cpu=el_min_cpu,
max_cpu=el_max_cpu,
min_memory=el_min_mem,
max_memory=el_max_mem,
env_vars=extra_env_vars,
),
jwt_secret_json_filepath_on_client,
return ServiceConfig(
image=image,
ports=USED_PORTS,
cmd=[command_str],
files={
package_io.GENESIS_DATA_MOUNTPOINT_ON_CLIENTS: el_cl_genesis_data.files_artifact_uuid
},
entrypoint=ENTRYPOINT_ARGS,
private_ip_address_placeholder=PRIVATE_IP_ADDRESS_PLACEHOLDER,
min_cpu=el_min_cpu,
max_cpu=el_max_cpu,
min_memory=el_min_mem,
max_memory=el_max_mem,
env_vars=extra_env_vars,
)
def new_geth_launcher(
network_id,
el_genesis_data,
prefunded_geth_keys_artifact_uuid,
prefunded_account_info,
genesis_validators_root="",
el_cl_genesis_data,
electra_fork_epoch=None,
):
return struct(
network_id=network_id,
el_genesis_data=el_genesis_data,
prefunded_account_info=prefunded_account_info,
prefunded_geth_keys_artifact_uuid=prefunded_geth_keys_artifact_uuid,
genesis_validators_root=genesis_validators_root,
el_cl_genesis_data=el_cl_genesis_data,
electra_fork_epoch=electra_fork_epoch,
)
......@@ -8,8 +8,6 @@ package_io = import_module("../../package_io/constants.star")
# The dirpath of the execution data directory on the client container
EXECUTION_DATA_DIRPATH_ON_CLIENT_CONTAINER = "/execution-data"
KZG_DATA_DIRPATH_ON_CLIENT_CONTAINER = "/genesis/output/trusted_setup.txt"
GENESIS_DATA_MOUNT_DIRPATH = "/genesis"
METRICS_PATH = "/metrics"
......@@ -85,8 +83,8 @@ def launch(
el_min_mem = el_min_mem if int(el_min_mem) > 0 else EXECUTION_MIN_MEMORY
el_max_mem = el_max_mem if int(el_max_mem) > 0 else EXECUTION_MAX_MEMORY
config, jwt_secret_json_filepath_on_client = get_config(
launcher.el_genesis_data,
config = get_config(
launcher.el_cl_genesis_data,
image,
existing_el_clients,
log_level,
......@@ -102,10 +100,6 @@ def launch(
enode = el_admin_node_info.get_enode_for_node(plan, service_name, RPC_PORT_ID)
jwt_secret = shared_utils.read_file_from_service(
plan, service_name, jwt_secret_json_filepath_on_client
)
metrics_url = "{0}:{1}".format(service.ip_address, METRICS_PORT_NUM)
nethermind_metrics_info = node_metrics.new_node_metrics_info(
service_name, METRICS_PATH, metrics_url
......@@ -120,14 +114,13 @@ def launch(
RPC_PORT_NUM,
WS_PORT_NUM,
ENGINE_RPC_PORT_NUM,
jwt_secret,
service_name,
[nethermind_metrics_info],
)
def get_config(
genesis_data,
el_cl_genesis_data,
image,
existing_el_clients,
log_level,
......@@ -138,20 +131,14 @@ def get_config(
extra_params,
extra_env_vars,
):
genesis_json_filepath_on_client = shared_utils.path_join(
GENESIS_DATA_MOUNT_DIRPATH,
genesis_data.nethermind_genesis_json_relative_filepath,
)
jwt_secret_json_filepath_on_client = shared_utils.path_join(
GENESIS_DATA_MOUNT_DIRPATH, genesis_data.jwt_secret_relative_filepath
)
cmd = [
"--log=" + log_level,
"--datadir=" + EXECUTION_DATA_DIRPATH_ON_CLIENT_CONTAINER,
"--Init.ChainSpecPath=" + genesis_json_filepath_on_client,
"--Init.ChainSpecPath="
+ package_io.GENESIS_CONFIG_MOUNT_PATH_ON_CONTAINER
+ "/chainspec.json",
"--Init.WebSocketsEnabled=true",
"--Init.KzgSetupPath=" + KZG_DATA_DIRPATH_ON_CLIENT_CONTAINER,
"--Init.KzgSetupPath=" + package_io.KZG_DATA_DIRPATH_ON_CLIENT_CONTAINER,
"--config=none.cfg",
"--JsonRpc.Enabled=true",
"--JsonRpc.EnabledModules=net,eth,consensus,subscribe,web3,admin",
......@@ -163,7 +150,7 @@ def get_config(
"--Network.ExternalIp={0}".format(PRIVATE_IP_ADDRESS_PLACEHOLDER),
"--Network.DiscoveryPort={0}".format(DISCOVERY_PORT_NUM),
"--Network.P2PPort={0}".format(DISCOVERY_PORT_NUM),
"--JsonRpc.JwtSecretFile={0}".format(jwt_secret_json_filepath_on_client),
"--JsonRpc.JwtSecretFile=" + package_io.JWT_AUTH_PATH,
"--Network.OnlyStaticPeers=true",
"--Metrics.Enabled=true",
"--Metrics.ExposePort={0}".format(METRICS_PORT_NUM),
......@@ -184,24 +171,21 @@ def get_config(
# this is a repeated<proto type>, we convert it into Starlark
cmd.extend([param for param in extra_params])
return (
ServiceConfig(
image=image,
ports=USED_PORTS,
cmd=cmd,
files={
GENESIS_DATA_MOUNT_DIRPATH: genesis_data.files_artifact_uuid,
},
private_ip_address_placeholder=PRIVATE_IP_ADDRESS_PLACEHOLDER,
min_cpu=el_min_cpu,
max_cpu=el_max_cpu,
min_memory=el_min_mem,
max_memory=el_max_mem,
env_vars=extra_env_vars,
),
jwt_secret_json_filepath_on_client,
return ServiceConfig(
image=image,
ports=USED_PORTS,
cmd=cmd,
files={
package_io.GENESIS_DATA_MOUNTPOINT_ON_CLIENTS: el_cl_genesis_data.files_artifact_uuid,
},
private_ip_address_placeholder=PRIVATE_IP_ADDRESS_PLACEHOLDER,
min_cpu=el_min_cpu,
max_cpu=el_max_cpu,
min_memory=el_min_mem,
max_memory=el_max_mem,
env_vars=extra_env_vars,
)
def new_nethermind_launcher(el_genesis_data):
return struct(el_genesis_data=el_genesis_data)
def new_nethermind_launcher(el_cl_genesis_data):
return struct(el_cl_genesis_data=el_cl_genesis_data)
......@@ -28,8 +28,6 @@ METRICS_PORT_ID = "metrics"
# Paths
METRICS_PATH = "/metrics"
GENESIS_DATA_MOUNT_DIRPATH = "/genesis"
PREFUNDED_KEYS_MOUNT_DIRPATH = "/prefunded-keys"
# The dirpath of the execution data directory on the client container
EXECUTION_DATA_DIRPATH_ON_CLIENT_CONTAINER = "/execution-data"
......@@ -89,8 +87,8 @@ def launch(
el_min_mem = el_min_mem if int(el_min_mem) > 0 else EXECUTION_MIN_MEMORY
el_max_mem = el_max_mem if int(el_max_mem) > 0 else EXECUTION_MAX_MEMORY
config, jwt_secret_json_filepath_on_client = get_config(
launcher.el_genesis_data,
config = get_config(
launcher.el_cl_genesis_data,
image,
existing_el_clients,
log_level,
......@@ -106,10 +104,6 @@ def launch(
enode = el_admin_node_info.get_enode_for_node(plan, service_name, RPC_PORT_ID)
jwt_secret = shared_utils.read_file_from_service(
plan, service_name, jwt_secret_json_filepath_on_client
)
metric_url = "{0}:{1}".format(service.ip_address, METRICS_PORT_NUM)
reth_metrics_info = node_metrics.new_node_metrics_info(
service_name, METRICS_PATH, metric_url
......@@ -123,14 +117,13 @@ def launch(
RPC_PORT_NUM,
WS_PORT_NUM,
ENGINE_RPC_PORT_NUM,
jwt_secret,
service_name,
[reth_metrics_info],
)
def get_config(
genesis_data,
el_cl_genesis_data,
image,
existing_el_clients,
verbosity_level,
......@@ -141,16 +134,9 @@ def get_config(
extra_params,
extra_env_vars,
):
genesis_json_filepath_on_client = shared_utils.path_join(
GENESIS_DATA_MOUNT_DIRPATH, genesis_data.geth_genesis_json_relative_filepath
)
jwt_secret_json_filepath_on_client = shared_utils.path_join(
GENESIS_DATA_MOUNT_DIRPATH, genesis_data.jwt_secret_relative_filepath
)
init_datadir_cmd_str = "reth init --datadir={0} --chain={1}".format(
EXECUTION_DATA_DIRPATH_ON_CLIENT_CONTAINER,
genesis_json_filepath_on_client,
package_io.GENESIS_CONFIG_MOUNT_PATH_ON_CONTAINER + "/genesis.json",
)
cmd = [
......@@ -158,7 +144,9 @@ def get_config(
"node",
"-{0}".format(verbosity_level),
"--datadir=" + EXECUTION_DATA_DIRPATH_ON_CLIENT_CONTAINER,
"--chain=" + genesis_json_filepath_on_client,
"--chain="
+ package_io.GENESIS_CONFIG_MOUNT_PATH_ON_CONTAINER
+ "/genesis.json",
"--http",
"--http.port={0}".format(RPC_PORT_NUM),
"--http.addr=0.0.0.0",
......@@ -173,7 +161,7 @@ def get_config(
"--ws.origins=*",
"--nat=extip:" + PRIVATE_IP_ADDRESS_PLACEHOLDER,
"--authrpc.port={0}".format(ENGINE_RPC_PORT_NUM),
"--authrpc.jwtsecret={0}".format(jwt_secret_json_filepath_on_client),
"--authrpc.jwtsecret=" + package_io.JWT_AUTH_PATH,
"--authrpc.addr=0.0.0.0",
"--metrics=0.0.0.0:{0}".format(METRICS_PORT_NUM),
]
......@@ -201,27 +189,24 @@ def get_config(
]
command_str = " && ".join(subcommand_strs)
return (
ServiceConfig(
image=image,
ports=USED_PORTS,
cmd=[command_str],
files={
GENESIS_DATA_MOUNT_DIRPATH: genesis_data.files_artifact_uuid,
},
entrypoint=ENTRYPOINT_ARGS,
private_ip_address_placeholder=PRIVATE_IP_ADDRESS_PLACEHOLDER,
min_cpu=el_min_cpu,
max_cpu=el_max_cpu,
min_memory=el_min_mem,
max_memory=el_max_mem,
env_vars=extra_env_vars,
),
jwt_secret_json_filepath_on_client,
return ServiceConfig(
image=image,
ports=USED_PORTS,
cmd=[command_str],
files={
package_io.GENESIS_DATA_MOUNTPOINT_ON_CLIENTS: el_cl_genesis_data.files_artifact_uuid,
},
entrypoint=ENTRYPOINT_ARGS,
private_ip_address_placeholder=PRIVATE_IP_ADDRESS_PLACEHOLDER,
min_cpu=el_min_cpu,
max_cpu=el_max_cpu,
min_memory=el_min_mem,
max_memory=el_max_mem,
env_vars=extra_env_vars,
)
def new_reth_launcher(el_genesis_data):
def new_reth_launcher(el_cl_genesis_data):
return struct(
el_genesis_data=el_genesis_data,
el_cl_genesis_data=el_cl_genesis_data,
)
......@@ -32,3 +32,13 @@ GENESIS_VALIDATORS_ROOT_PLACEHOLDER = "GENESIS_VALIDATORS_ROOT_PLACEHOLDER"
DEFAULT_SNOOPER_IMAGE = "parithoshj/json_rpc_snoop:v1.0.0-x86"
ARCHIVE_MODE = True
JWT_AUTH_PATH = "/data/data/jwt/jwtsecret"
GENESIS_DATA_MOUNTPOINT_ON_CLIENTS = "/data"
GENESIS_CONFIG_MOUNT_PATH_ON_CONTAINER = (
GENESIS_DATA_MOUNTPOINT_ON_CLIENTS + "/data/custom_config_data"
)
KZG_DATA_DIRPATH_ON_CLIENT_CONTAINER = (
GENESIS_CONFIG_MOUNT_PATH_ON_CONTAINER + "/trusted_setup.txt"
)
......@@ -16,6 +16,7 @@ DEFAULT_CL_IMAGES = {
}
MEV_BOOST_RELAY_DEFAULT_IMAGE = "flashbots/mev-boost-relay:0.27"
MEV_BOOST_RELAY_IMAGE_NON_ZERO_CAPELLA = "flashbots/mev-boost-relay:0.26"
NETHERMIND_NODE_NAME = "nethermind"
......@@ -154,6 +155,8 @@ def parse_input(plan, input_args):
],
seconds_per_slot=result["network_params"]["seconds_per_slot"],
genesis_delay=result["network_params"]["genesis_delay"],
max_churn=result["network_params"]["max_churn"],
ejection_balance=result["network_params"]["ejection_balance"],
capella_fork_epoch=result["network_params"]["capella_fork_epoch"],
deneb_fork_epoch=result["network_params"]["deneb_fork_epoch"],
electra_fork_epoch=result["network_params"]["electra_fork_epoch"],
......@@ -161,6 +164,7 @@ def parse_input(plan, input_args):
mev_params=struct(
mev_relay_image=result["mev_params"]["mev_relay_image"],
mev_builder_image=result["mev_params"]["mev_builder_image"],
mev_builder_cl_image=result["mev_params"]["mev_builder_cl_image"],
mev_boost_image=result["mev_params"]["mev_boost_image"],
mev_relay_api_extra_args=result["mev_params"]["mev_relay_api_extra_args"],
mev_relay_housekeeper_extra_args=result["mev_params"][
......@@ -360,8 +364,10 @@ def default_network_params():
"deposit_contract_address": "0x4242424242424242424242424242424242424242",
"seconds_per_slot": 12,
"genesis_delay": 120,
"max_churn": 8,
"ejection_balance": 16000000000,
"capella_fork_epoch": 0,
"deneb_fork_epoch": 500,
"deneb_fork_epoch": 4,
"electra_fork_epoch": None,
}
......@@ -401,7 +407,8 @@ def get_default_mev_params():
return {
"mev_relay_image": MEV_BOOST_RELAY_DEFAULT_IMAGE,
# TODO replace with flashbots/builder when they publish an arm64 image as mentioned in flashbots/builder#105
"mev_builder_image": "ethpandaops/flashbots-builder:main",
"mev_builder_image": "flashbots/builder:latest",
"mev_builder_cl_image": "sigp/lighthouse:latest",
"mev_boost_image": "flashbots/mev-boost",
"mev_relay_api_extra_args": [],
"mev_relay_housekeeper_extra_args": [],
......@@ -468,7 +475,9 @@ def enrich_mev_extra_params(parsed_arguments_dict, mev_prefix, mev_port, mev_typ
"el_client_image": parsed_arguments_dict["mev_params"][
"mev_builder_image"
],
"cl_client_image": "sigp/lighthouse",
"cl_client_image": parsed_arguments_dict["mev_params"][
"mev_builder_cl_image"
],
"beacon_extra_params": [
"--always-prepare-payload",
"--prepare-payload-lookahead",
......
cl_validator_keystores = import_module(
"./prelaunch_data_generator/cl_validator_keystores/cl_validator_keystore_generator.star"
)
el_genesis_data_generator = import_module(
"./prelaunch_data_generator/el_genesis/el_genesis_data_generator.star"
)
cl_genesis_data_generator = import_module(
"./prelaunch_data_generator/cl_genesis/cl_genesis_data_generator.star"
el_cl_genesis_data_generator = import_module(
"./prelaunch_data_generator/el_cl_genesis/el_cl_genesis_generator.star"
)
static_files = import_module("../static_files/static_files.star")
static_files = import_module("./static_files/static_files.star")
geth = import_module("./el/geth/geth_launcher.star")
besu = import_module("./el/besu/besu_launcher.star")
......@@ -80,49 +78,46 @@ def launch_participant_network(
final_genesis_timestamp = get_final_genesis_timestamp(
plan, CL_GENESIS_DATA_GENERATION_TIME + num_participants * CL_NODE_STARTUP_TIME
)
plan.print("Generating EL data")
el_genesis_generation_config_template = read_file(
static_files.EL_GENESIS_GENERATION_CONFIG_TEMPLATE_FILEPATH
)
el_genesis_data = el_genesis_data_generator.generate_el_genesis_data(
plan,
el_genesis_generation_config_template,
final_genesis_timestamp,
network_params.network_id,
network_params.deposit_contract_address,
network_params.genesis_delay,
network_params.seconds_per_slot,
network_params.capella_fork_epoch,
network_params.deneb_fork_epoch,
network_params.electra_fork_epoch,
)
plan.print(json.indent(json.encode(el_genesis_data)))
total_number_of_validator_keys = 0
for participant in participants:
total_number_of_validator_keys += participant.validator_count
plan.print("Uploading GETH prefunded keys")
plan.print("Generating EL CL data")
# we are running bellatrix genesis (deprecated) - will be removed in the future
if (
network_params.capella_fork_epoch > 0
and network_params.electra_fork_epoch == None
):
ethereum_genesis_generator_image = (
"ethpandaops/ethereum-genesis-generator:1.3.14"
)
# we are running capella genesis - default behavior
elif (
network_params.capella_fork_epoch == 0
and network_params.electra_fork_epoch == None
):
ethereum_genesis_generator_image = (
"ethpandaops/ethereum-genesis-generator:2.0.4"
)
# we are running electra - experimental
elif network_params.electra_fork_epoch != None:
ethereum_genesis_generator_image = (
"ethpandaops/ethereum-genesis-generator:3.0.0-rc.10"
)
else:
fail(
"Unsupported fork epoch configuration, need to define either capella_fork_epoch, deneb_fork_epoch or electra_fork_epoch"
)
geth_prefunded_keys_artifact_name = plan.upload_files(
static_files.GETH_PREFUNDED_KEYS_DIRPATH, name="geth-prefunded-keys"
el_cl_genesis_config_template = read_file(
static_files.EL_CL_GENESIS_GENERATION_CONFIG_TEMPLATE_FILEPATH
)
plan.print("Uploaded GETH files succesfully")
plan.print("Generating CL data")
genesis_generation_config_yml_template = read_file(
static_files.CL_GENESIS_GENERATION_CONFIG_TEMPLATE_FILEPATH
)
genesis_generation_mnemonics_yml_template = read_file(
static_files.CL_GENESIS_GENERATION_MNEMONICS_TEMPLATE_FILEPATH
)
total_number_of_validator_keys = 0
for participant in participants:
total_number_of_validator_keys += participant.validator_count
cl_genesis_data = cl_genesis_data_generator.generate_cl_genesis_data(
el_cl_data = el_cl_genesis_data_generator.generate_el_cl_genesis_data(
plan,
genesis_generation_config_yml_template,
genesis_generation_mnemonics_yml_template,
el_genesis_data,
ethereum_genesis_generator_image,
el_cl_genesis_config_template,
final_genesis_timestamp,
network_params.network_id,
network_params.deposit_contract_address,
......@@ -130,50 +125,42 @@ def launch_participant_network(
network_params.preregistered_validator_keys_mnemonic,
total_number_of_validator_keys,
network_params.genesis_delay,
network_params.max_churn,
network_params.ejection_balance,
network_params.capella_fork_epoch,
network_params.deneb_fork_epoch,
network_params.electra_fork_epoch,
)
plan.print(json.indent(json.encode(cl_genesis_data)))
plan.print("Generated CL genesis data succesfully, launching EL & CL Participants")
genesis_validators_root = cl_genesis_data.genesis_validators_root
el_launchers = {
package_io.EL_CLIENT_TYPE.geth: {
"launcher": geth.new_geth_launcher(
network_params.network_id,
el_genesis_data,
geth_prefunded_keys_artifact_name,
genesis_constants.PRE_FUNDED_ACCOUNTS,
genesis_validators_root,
el_cl_data,
network_params.electra_fork_epoch,
),
"launch_method": geth.launch,
},
package_io.EL_CLIENT_TYPE.besu: {
"launcher": besu.new_besu_launcher(
network_params.network_id, el_genesis_data
),
"launcher": besu.new_besu_launcher(network_params.network_id, el_cl_data),
"launch_method": besu.launch,
},
package_io.EL_CLIENT_TYPE.erigon: {
"launcher": erigon.new_erigon_launcher(
network_params.network_id, el_genesis_data
network_params.network_id, el_cl_data
),
"launch_method": erigon.launch,
},
package_io.EL_CLIENT_TYPE.nethermind: {
"launcher": nethermind.new_nethermind_launcher(el_genesis_data),
"launcher": nethermind.new_nethermind_launcher(el_cl_data),
"launch_method": nethermind.launch,
},
package_io.EL_CLIENT_TYPE.reth: {
"launcher": reth.new_reth_launcher(el_genesis_data),
"launcher": reth.new_reth_launcher(el_cl_data),
"launch_method": reth.launch,
},
package_io.EL_CLIENT_TYPE.ethereumjs: {
"launcher": ethereumjs.new_ethereumjs_launcher(el_genesis_data),
"launcher": ethereumjs.new_ethereumjs_launcher(el_cl_data),
"launch_method": ethereumjs.launch,
},
}
......@@ -227,27 +214,27 @@ def launch_participant_network(
cl_launchers = {
package_io.CL_CLIENT_TYPE.lighthouse: {
"launcher": lighthouse.new_lighthouse_launcher(cl_genesis_data),
"launcher": lighthouse.new_lighthouse_launcher(el_cl_data),
"launch_method": lighthouse.launch,
},
package_io.CL_CLIENT_TYPE.lodestar: {
"launcher": lodestar.new_lodestar_launcher(cl_genesis_data),
"launcher": lodestar.new_lodestar_launcher(el_cl_data),
"launch_method": lodestar.launch,
},
package_io.CL_CLIENT_TYPE.nimbus: {
"launcher": nimbus.new_nimbus_launcher(cl_genesis_data),
"launcher": nimbus.new_nimbus_launcher(el_cl_data),
"launch_method": nimbus.launch,
},
package_io.CL_CLIENT_TYPE.prysm: {
"launcher": prysm.new_prysm_launcher(
cl_genesis_data,
el_cl_data,
cl_validator_data.prysm_password_relative_filepath,
cl_validator_data.prysm_password_artifact_uuid,
),
"launch_method": prysm.launch,
},
package_io.CL_CLIENT_TYPE.teku: {
"launcher": teku.new_teku_launcher(cl_genesis_data),
"launcher": teku.new_teku_launcher(el_cl_data),
"launch_method": teku.launch,
},
}
......@@ -381,7 +368,12 @@ def launch_participant_network(
all_participants.append(participant_entry)
return all_participants, final_genesis_timestamp, genesis_validators_root
return (
all_participants,
final_genesis_timestamp,
el_cl_data.genesis_validators_root,
el_cl_data.files_artifact_uuid,
)
def zfill_calculator(participants):
......
def new_cl_genesis_data(
def new_el_cl_genesis_data(
files_artifact_uuid,
jwt_secret_rel_filepath,
config_yml_rel_filepath,
genesis_ssz_rel_filepath,
genesis_validators_root="",
genesis_validators_root,
):
return struct(
files_artifact_uuid=files_artifact_uuid,
jwt_secret_rel_filepath=jwt_secret_rel_filepath,
config_yml_rel_filepath=config_yml_rel_filepath,
genesis_ssz_rel_filepath=genesis_ssz_rel_filepath,
genesis_validators_root=genesis_validators_root,
)
shared_utils = import_module("../../shared_utils/shared_utils.star")
prelaunch_data_generator_launcher = import_module(
"../../prelaunch_data_generator/prelaunch_data_generator_launcher/prelaunch_data_generator_launcher.star"
)
el_cl_genesis_data = import_module("./el_cl_genesis_data.star")
GENESIS_VALUES_PATH = "/opt"
GENESIS_VALUES_FILENAME = "values.env"
def generate_el_cl_genesis_data(
plan,
image,
genesis_generation_config_yml_template,
genesis_unix_timestamp,
network_id,
deposit_contract_address,
seconds_per_slot,
preregistered_validator_keys_mnemonic,
total_num_validator_keys_to_preregister,
genesis_delay,
max_churn,
ejection_balance,
capella_fork_epoch,
deneb_fork_epoch,
electra_fork_epoch,
):
template_data = new_env_file_for_el_cl_genesis_data(
genesis_unix_timestamp,
network_id,
deposit_contract_address,
seconds_per_slot,
preregistered_validator_keys_mnemonic,
total_num_validator_keys_to_preregister,
genesis_delay,
max_churn,
ejection_balance,
capella_fork_epoch,
deneb_fork_epoch,
electra_fork_epoch,
)
genesis_generation_template = shared_utils.new_template_and_data(
genesis_generation_config_yml_template, template_data
)
genesis_values_and_dest_filepath = {}
genesis_values_and_dest_filepath[
GENESIS_VALUES_FILENAME
] = genesis_generation_template
genesis_generation_config_artifact_name = plan.render_templates(
genesis_values_and_dest_filepath, "genesis-el-cl-env-file"
)
genesis = plan.run_sh(
run="cp /opt/values.env /config/values.env && ./entrypoint.sh all",
image=image,
files={GENESIS_VALUES_PATH: genesis_generation_config_artifact_name},
store=[
"/data",
],
wait=None,
)
# this is super hacky lmao
genesis_validators_root = plan.run_sh(
run="cat /data/data/custom_config_data/genesis_validators_root.txt",
image="busybox",
files={"/data": genesis.files_artifacts[0]},
wait=None,
)
result = el_cl_genesis_data.new_el_cl_genesis_data(
genesis.files_artifacts[0], genesis_validators_root.output
)
return result
def new_env_file_for_el_cl_genesis_data(
genesis_unix_timestamp,
network_id,
deposit_contract_address,
seconds_per_slot,
preregistered_validator_keys_mnemonic,
total_num_validator_keys_to_preregister,
genesis_delay,
max_churn,
ejection_balance,
capella_fork_epoch,
deneb_fork_epoch,
electra_fork_epoch,
):
return {
"UnixTimestamp": genesis_unix_timestamp,
"NetworkId": network_id,
"DepositContractAddress": deposit_contract_address,
"SecondsPerSlot": seconds_per_slot,
"PreregisteredValidatorKeysMnemonic": preregistered_validator_keys_mnemonic,
"NumValidatorKeysToPreregister": total_num_validator_keys_to_preregister,
"GenesisDelay": genesis_delay,
"MaxChurn": max_churn,
"EjectionBalance": ejection_balance,
"CapellaForkEpoch": capella_fork_epoch,
"DenebForkEpoch": deneb_fork_epoch,
"ElectraForkEpoch": electra_fork_epoch,
}
def new_el_genesis_data(
files_artifact_uuid,
jwt_secret_relative_filepath,
geth_genesis_json_relative_filepath,
erigon_genesis_json_relative_filepath,
nethermind_genesis_json_relative_filepath,
besu_genesis_json_relative_filepath,
):
return struct(
files_artifact_uuid=files_artifact_uuid,
jwt_secret_relative_filepath=jwt_secret_relative_filepath,
geth_genesis_json_relative_filepath=geth_genesis_json_relative_filepath,
erigon_genesis_json_relative_filepath=erigon_genesis_json_relative_filepath,
nethermind_genesis_json_relative_filepath=nethermind_genesis_json_relative_filepath,
besu_genesis_json_relative_filepath=besu_genesis_json_relative_filepath,
)
shared_utils = import_module("../../shared_utils/shared_utils.star")
el_genesis = import_module(
"../../prelaunch_data_generator/el_genesis/el_genesis_data.star"
)
prelaunch_data_generator_launcher = import_module(
"../../prelaunch_data_generator/prelaunch_data_generator_launcher/prelaunch_data_generator_launcher.star"
)
CONFIG_DIRPATH_ON_GENERATOR = "/config"
GENESIS_CONFIG_FILENAME = "genesis-config.yaml"
OUTPUT_DIRPATH_ON_GENERATOR = "/output"
GETH_GENESIS_FILENAME = "genesis.json"
ERIGON_GENESIS_FILENAME = "erigon.json"
NETHERMIND_GENESIS_FILENAME = "nethermind.json"
BESU_GENESIS_FILENAME = "besu.json"
TRUSTED_SETUP_FILENAME = "trusted_setup.txt"
JWT_SECRET_FILENAME = "jwtsecret"
SUCCESSFUL_EXEC_CMD_EXIT_CODE = 0
# Mapping of output genesis filename -> generator to create the file
all_genesis_generation_cmds = {
GETH_GENESIS_FILENAME: lambda genesis_config_filepath_on_generator: [
"python3",
"/apps/el-gen/genesis_geth.py",
genesis_config_filepath_on_generator,
],
ERIGON_GENESIS_FILENAME: lambda genesis_config_filepath_on_generator: [
"python3",
"/apps/el-gen/genesis_geth.py",
genesis_config_filepath_on_generator,
],
NETHERMIND_GENESIS_FILENAME: lambda genesis_config_filepath_on_generator: [
"python3",
"/apps/el-gen/genesis_chainspec.py",
genesis_config_filepath_on_generator,
],
BESU_GENESIS_FILENAME: lambda genesis_config_filepath_on_generator: [
"python3",
"/apps/el-gen/genesis_besu.py",
genesis_config_filepath_on_generator,
],
}
def generate_el_genesis_data(
plan,
genesis_generation_config_template,
genesis_unix_timestamp,
network_id,
deposit_contract_address,
genesis_delay,
seconds_per_slot,
capella_fork_epoch,
deneb_fork_epoch,
electra_fork_epoch,
):
template_data = genesis_generation_config_template_data(
network_id,
deposit_contract_address,
genesis_unix_timestamp,
genesis_delay,
seconds_per_slot,
capella_fork_epoch,
deneb_fork_epoch,
electra_fork_epoch,
)
genesis_config_file_template_and_data = shared_utils.new_template_and_data(
genesis_generation_config_template, template_data
)
template_and_data_by_rel_dest_filepath = {}
template_and_data_by_rel_dest_filepath[
GENESIS_CONFIG_FILENAME
] = genesis_config_file_template_and_data
genesis_generation_config_artifact_name = plan.render_templates(
template_and_data_by_rel_dest_filepath, name="genesis-generation-config-el"
)
# TODO(old) Make this the actual data generator - comment copied from the original module
launcher_service_name = (
prelaunch_data_generator_launcher.launch_prelaunch_data_generator(
plan,
{
CONFIG_DIRPATH_ON_GENERATOR: genesis_generation_config_artifact_name,
},
"el-genesis-data",
capella_fork_epoch,
electra_fork_epoch,
)
)
all_dirpaths_to_create_on_generator = [
CONFIG_DIRPATH_ON_GENERATOR,
OUTPUT_DIRPATH_ON_GENERATOR,
]
all_dirpath_creation_commands = []
for dirpath_to_create_on_generator in all_dirpaths_to_create_on_generator:
all_dirpath_creation_commands.append(
"mkdir -p {0}".format(dirpath_to_create_on_generator),
)
dir_creation_cmd = [
"bash",
"-c",
" && ".join(all_dirpath_creation_commands),
]
dir_creation_cmd_result = plan.exec(
recipe=ExecRecipe(command=dir_creation_cmd), service_name=launcher_service_name
)
plan.verify(dir_creation_cmd_result["code"], "==", SUCCESSFUL_EXEC_CMD_EXIT_CODE)
genesis_config_filepath_on_generator = shared_utils.path_join(
CONFIG_DIRPATH_ON_GENERATOR, GENESIS_CONFIG_FILENAME
)
genesis_filename_to_relative_filepath_in_artifact = {}
for output_filename, generation_cmd in all_genesis_generation_cmds.items():
cmd = generation_cmd(genesis_config_filepath_on_generator)
output_filepath_on_generator = shared_utils.path_join(
OUTPUT_DIRPATH_ON_GENERATOR, output_filename
)
cmd.append(">")
cmd.append(output_filepath_on_generator)
cmd_to_execute = ["bash", "-c", " ".join(cmd)]
cmd_to_execute_result = plan.exec(
recipe=ExecRecipe(command=cmd_to_execute),
service_name=launcher_service_name,
)
plan.verify(cmd_to_execute_result["code"], "==", SUCCESSFUL_EXEC_CMD_EXIT_CODE)
genesis_filename_to_relative_filepath_in_artifact[
output_filename
] = shared_utils.path_join(
shared_utils.path_base(OUTPUT_DIRPATH_ON_GENERATOR),
output_filename,
)
shared_utils.download_trusted_setup(
plan,
launcher_service_name,
shared_utils.path_join(OUTPUT_DIRPATH_ON_GENERATOR, TRUSTED_SETUP_FILENAME),
)
jwt_secret_filepath_on_generator = shared_utils.path_join(
OUTPUT_DIRPATH_ON_GENERATOR, JWT_SECRET_FILENAME
)
jwt_secret_generation_cmd = [
"bash",
"-c",
"openssl rand -hex 32 | tr -d \"\\n\" | sed 's/^/0x/' > {0}".format(
jwt_secret_filepath_on_generator,
),
]
jwt_secret_generation_cmd_result = plan.exec(
recipe=ExecRecipe(command=jwt_secret_generation_cmd),
service_name=launcher_service_name,
)
plan.verify(
jwt_secret_generation_cmd_result["code"], "==", SUCCESSFUL_EXEC_CMD_EXIT_CODE
)
el_genesis_data_artifact_name = plan.store_service_files(
launcher_service_name, OUTPUT_DIRPATH_ON_GENERATOR, name="el-genesis-data"
)
result = el_genesis.new_el_genesis_data(
el_genesis_data_artifact_name,
shared_utils.path_join(
shared_utils.path_base(OUTPUT_DIRPATH_ON_GENERATOR), JWT_SECRET_FILENAME
),
genesis_filename_to_relative_filepath_in_artifact[GETH_GENESIS_FILENAME],
genesis_filename_to_relative_filepath_in_artifact[ERIGON_GENESIS_FILENAME],
genesis_filename_to_relative_filepath_in_artifact[NETHERMIND_GENESIS_FILENAME],
genesis_filename_to_relative_filepath_in_artifact[BESU_GENESIS_FILENAME],
)
# TODO(gyani) remove the container when the job is done - this is a resource leaker
return result
def genesis_generation_config_template_data(
network_id,
deposit_contract_address,
unix_timestamp,
genesis_delay,
seconds_per_slot,
capella_fork_epoch,
deneb_fork_epoch,
electra_fork_epoch,
):
return {
"NetworkId": network_id,
"DepositContractAddress": deposit_contract_address,
"UnixTimestamp": unix_timestamp,
"GenesisDelay": genesis_delay,
"SecondsPerSlot": seconds_per_slot,
"CapellaForkEpoch": capella_fork_epoch,
"DenebForkEpoch": deneb_fork_epoch,
"ElectraForkEpoch": electra_fork_epoch,
}
......@@ -3,52 +3,63 @@ def new_prefunded_account(address, private_key):
# This information was generated by:
# 1) Installing Wagyu: https://github.com/AleoHQ/wagyu
# 2) Running `wagyu ethereum import-hd -m MNEMONIC_FROM_GENESIS -d PREFUNDED_ACCOUNT_DERIVATION_PATH`
# 3) Copying the outputted information
# 1) https://iancoleman.io/bip39/
# 2) Enter the mnemonic (unless you use the default)
# 3) Copying the pubkey/priv key outputted information
PRE_FUNDED_ACCOUNTS = [
# UTC--2021-12-22T19-14-08.590377700Z--878705ba3f8bc32fcf7f4caa1a35e72af65cf766
# m/44'/60'/0'/0/0
new_prefunded_account(
"0x878705ba3f8Bc32FCf7F4CAa1A35E72AF65CF766",
"ef5177cd0b6b21c87db5a0bf35d4084a8a57a9d6a064f86d51ac85f2b873a4e2",
"0x8943545177806ED17B9F23F0a21ee5948eCaa776",
"bcdf20249abf0ed6d944c0288fad489e33f66b3960d9e6229c1cd214ed3bbe31",
),
# UTC--2021-12-22T19-14-13.423928600Z--4e9a3d9d1cd2a2b2371b8b3f489ae72259886f1a
# m/44'/60'/0'/0/1
new_prefunded_account(
"0x4E9A3d9D1cd2A2b2371b8b3F489aE72259886f1A",
"48fcc39ae27a0e8bf0274021ae6ebd8fe4a0e12623d61464c498900b28feb567",
"0xE25583099BA105D9ec0A67f5Ae86D90e50036425",
"39725efee3fb28614de3bacaffe4cc4bd8c436257e2c8bb887c4b5c4be45e76d",
),
# UTC--2021-12-22T19-14-16.977667900Z--df8466f277964bb7a0ffd819403302c34dcd530a
# m/44'/60'/0'/0/2
new_prefunded_account(
"0xdF8466f277964Bb7a0FFD819403302C34DCD530A",
"7988b3a148716ff800414935b305436493e1f25237a2a03e5eebc343735e2f31",
"0x614561D2d143621E126e87831AEF287678B442b8",
"53321db7c1e331d93a11a41d16f004d7ff63972ec8ec7c25db329728ceeb1710",
),
# UTC--2021-12-22T19-14-21.531351400Z--5c613e39fc0ad91afda24587e6f52192d75fba50
# m/44'/60'/0'/0/3
new_prefunded_account(
"0x5c613e39Fc0Ad91AfDA24587e6f52192d75FBA50",
"b3c409b6b0b3aa5e65ab2dc1930534608239a478106acf6f3d9178e9f9b00b35",
"0xf93Ee4Cf8c6c40b329b0c0626F28333c132CF241",
"ab63b23eb7941c1251757e24b3d2350d2bc05c3c388d06f8fe6feafefb1e8c70",
),
# UTC--2021-12-22T19-14-25.369306000Z--375ae6107f8cc4cf34842b71c6f746a362ad8eac
# m/44'/60'/0'/0/4
new_prefunded_account(
"0x375ae6107f8cC4cF34842B71C6F746a362Ad8EAc",
"df9bb6de5d3dc59595bcaa676397d837ff49441d211878c024eabda2cd067c9f",
"0x802dCbE1B1A97554B4F50DB5119E37E8e7336417",
"5d2344259f42259f82d2c140aa66102ba89b57b4883ee441a8b312622bd42491",
),
# UTC--2021-12-22T19-14-33.473095100Z--1f6298457c5d76270325b724da5d1953923a6b88
# m/44'/60'/0'/0/5
new_prefunded_account(
"0x1F6298457C5d76270325B724Da5d1953923a6B88",
"7da08f856b5956d40a72968f93396f6acff17193f013e8053f6fbb6c08c194d6",
"0xAe95d8DA9244C37CaC0a3e16BA966a8e852Bb6D6",
"27515f805127bebad2fb9b183508bdacb8c763da16f54e0678b16e8f28ef3fff",
),
# Use geth account import to generate the key inside genesis-prefunded-keys/geth
# use password "password"
# UTC--2023-05-19T11-17-22.403583626Z--fe08e6f330f4e5e624ad759625b71b2e52594feb
# m/44'/60'/0'/0/6
new_prefunded_account(
"0xFE08e6f330F4E5E624Ad759625B71B2e52594FEB",
"17fdf89989597e8bcac6cdfcc001b6241c64cece2c358ffc818b72ca70f5e1ce",
"0x2c57d1CFC6d5f8E4182a56b4cf75421472eBAEa4",
"7ff1a4c1d57e5e784d327c4c7651e952350bc271f156afb3d00d20f5ef924856",
),
# m/44'/60'/0'/0/7
new_prefunded_account(
"0x741bFE4802cE1C4b5b00F9Df2F5f179A1C89171A",
"3a91003acaf4c21b3953d94fa4a6db694fa69e5242b2e37be05dd82761058899",
),
# m/44'/60'/0'/0/8
new_prefunded_account(
"0xc3913d4D8bAb4914328651C2EAE817C8b78E1f4c",
"bb1d0f125b4fb2bb173c318cdead45468474ca71474e2247776b2b4c0fa2d3f5",
),
# m/44'/60'/0'/0/9
new_prefunded_account(
"0x65D08a056c17Ae13370565B04cF77D2AfA1cB9FA",
"850643a0224065ecce3882673c21f56bcf6eef86274cc21cadff15930b59fc8c",
),
# m/44'/60'/0'/0/10
new_prefunded_account(
"0x3e95dFbBaF6B348396E6674C7871546dCC568e56",
"94eb3102993b41ec55c241060f47daa0f6372e2e3ad7e91612ae36c364042e44",
),
]
......@@ -56,17 +56,3 @@ def read_file_from_service(plan, service_name, filename):
),
)
return output["output"]
def download_trusted_setup(plan, service_name, output_filepath):
plan.exec(
service_name=service_name,
recipe=ExecRecipe(
command=[
"wget",
"-O",
output_filepath,
"https://raw.githubusercontent.com/ethereum/c-kzg-4844/main/src/trusted_setup.txt",
]
),
)
# The path on the module container where static files are housed
STATIC_FILES_DIRPATH = "/static_files"
# EL_CL Genesis config
EL_CL_GENESIS_GENERATION_CONFIG_TEMPLATE_FILEPATH = (
STATIC_FILES_DIRPATH + "/genesis-generation-config/el-cl/values.env.tmpl"
)
# EL Forkmon config
EL_FORKMON_CONFIG_TEMPLATE_FILEPATH = (
STATIC_FILES_DIRPATH + "/el-forkmon-config/config.toml.tmpl"
......@@ -35,3 +40,19 @@ GRAFANA_DASHBOARD_PROVIDERS_CONFIG_TEMPLATE_FILEPATH = (
GRAFANA_DASHBOARDS_CONFIG_DIRPATH = (
STATIC_FILES_DIRPATH + GRAFANA_CONFIG_DIRPATH + "/dashboards"
)
# Geth + CL genesis generation
GENESIS_GENERATION_CONFIG_DIRPATH = STATIC_FILES_DIRPATH + "/genesis-generation-config"
EL_GENESIS_GENERATION_CONFIG_DIRPATH = GENESIS_GENERATION_CONFIG_DIRPATH + "/el"
EL_GENESIS_GENERATION_CONFIG_TEMPLATE_FILEPATH = (
EL_GENESIS_GENERATION_CONFIG_DIRPATH + "/genesis-config.yaml.tmpl"
)
CL_GENESIS_GENERATION_CONFIG_DIRPATH = GENESIS_GENERATION_CONFIG_DIRPATH + "/cl"
CL_GENESIS_GENERATION_CONFIG_TEMPLATE_FILEPATH = (
CL_GENESIS_GENERATION_CONFIG_DIRPATH + "/config.yaml.tmpl"
)
CL_GENESIS_GENERATION_MNEMONICS_TEMPLATE_FILEPATH = (
CL_GENESIS_GENERATION_CONFIG_DIRPATH + "/mnemonics.yaml.tmpl"
)
......@@ -5,7 +5,7 @@ logging:
# Chain network configuration
chain:
name: "kurtosis-testnet"
configPath: "/cl-genesis-data/output/config.yaml"
configPath: "/data/data/custom_config_data/config.yaml"
displayName: "Kurtosis Testnet"
# HTTP Server configuration
......
# Extends the mainnet preset
# This *could* be 'minimal', but it's not recommended to use because not every client supports 'minimal'
PRESET_BASE: 'mainnet'
CONFIG_NAME: testnet # needs to exist because of Prysm. Otherwise it conflicts with mainnet genesis
# Genesis
# ---------------------------------------------------------------
# `2**14` (= 16,384)
MIN_GENESIS_ACTIVE_VALIDATOR_COUNT: {{ .NumValidatorKeysToPreregister }}
MIN_GENESIS_TIME: {{ .UnixTimestamp }}
GENESIS_FORK_VERSION: 0x10000038
GENESIS_DELAY: {{ .GenesisDelay }}
# Forking
# ---------------------------------------------------------------
# Some forks are disabled for now:
# - These may be re-assigned to another fork-version later
# - Temporarily set to max uint64 value: 2**64 - 1
# Note: The module runs a merged chain so ALTAIR_FORK_EPOCH, BELLATRIX_FORK_EPOCH and TERMINAL_TOTAL_DIFFICULTY
# are all hardcoded to zero.
# Altair
ALTAIR_FORK_VERSION: 0x20000038
ALTAIR_FORK_EPOCH: 0
# Merge
BELLATRIX_FORK_VERSION: 0x30000038
BELLATRIX_FORK_EPOCH: 0
TERMINAL_TOTAL_DIFFICULTY: 0
# 0x0000...000 indicates that we use TERMINAL_TOTAL_DIFFICULTY instead of a block has to trigger the merge
TERMINAL_BLOCK_HASH: 0x0000000000000000000000000000000000000000000000000000000000000000
# NOTE: This is commented out because Nimbus warns us that it's an unrecognized parameter
TERMINAL_BLOCK_HASH_ACTIVATION_EPOCH: 18446744073709551615
# Capella
CAPELLA_FORK_VERSION: 0x40000038
CAPELLA_FORK_EPOCH: {{ .CapellaForkEpoch }}
# DENEB
DENEB_FORK_VERSION: 0x50000038
DENEB_FORK_EPOCH: {{ .DenebForkEpoch }}
# Electra
ELECTRA_FORK_VERSION: 0x60000038
ELECTRA_FORK_EPOCH: {{ .ElectraForkEpoch }}
# Time parameters
# ---------------------------------------------------------------
# 12 seconds
SECONDS_PER_SLOT: {{ .SecondsPerSlot }}
# 5 epochs ~0.5 hours
MIN_VALIDATOR_WITHDRAWABILITY_DELAY: 1
# 2**8 (= 256) epochs ~27 hours
SHARD_COMMITTEE_PERIOD: 1
# It's very important that SECONDS_PER_ETH1_BLOCK * ETH1_FOLLOW_DISTANCE is a good amount of time, else
# jitter will cause the Beacon nodes to think they're far behind the Eth1 nodes and give up syncing
SECONDS_PER_ETH1_BLOCK: {{ .SecondsPerSlot }}
ETH1_FOLLOW_DISTANCE: 12
# Validator cycle
# ---------------------------------------------------------------
# 2**2 (= 4)
INACTIVITY_SCORE_BIAS: 4
# 2**4 (= 16)
INACTIVITY_SCORE_RECOVERY_RATE: 16
# 2**4 * 10**9 (= 16,000,000,000) Gwei
EJECTION_BALANCE: 16000000000
# 2**2 (= 4)
MIN_PER_EPOCH_CHURN_LIMIT: 4
# 2**16 (= 65,536)
CHURN_LIMIT_QUOTIENT: 65536
# [Deneb:EIP7514] 2**3 (= 8)
MAX_PER_EPOCH_ACTIVATION_CHURN_LIMIT: 8
# Fork choice
# ---------------------------------------------------------------
# 40%
PROPOSER_SCORE_BOOST: 40
# Deposit contract
# ---------------------------------------------------------------
DEPOSIT_CHAIN_ID: {{ .NetworkId }}
DEPOSIT_NETWORK_ID: {{ .NetworkId }}
DEPOSIT_CONTRACT_ADDRESS: {{ .DepositContractAddress }}
# Networking
# ---------------------------------------------------------------
# `10 * 2**20` (= 10485760, 10 MiB)
GOSSIP_MAX_SIZE: 10485760
# `2**10` (= 1024)
MAX_REQUEST_BLOCKS: 1024
# `2**8` (= 256)
EPOCHS_PER_SUBNET_SUBSCRIPTION: 256
# `MIN_VALIDATOR_WITHDRAWABILITY_DELAY + CHURN_LIMIT_QUOTIENT // 2` (= 33024, ~5 months)
MIN_EPOCHS_FOR_BLOCK_REQUESTS: 33024
# `10 * 2**20` (=10485760, 10 MiB)
MAX_CHUNK_SIZE: 10485760
# 5s
TTFB_TIMEOUT: 5
# 10s
RESP_TIMEOUT: 10
ATTESTATION_PROPAGATION_SLOT_RANGE: 32
# 500ms
MAXIMUM_GOSSIP_CLOCK_DISPARITY: 500
MESSAGE_DOMAIN_INVALID_SNAPPY: 0x00000000
MESSAGE_DOMAIN_VALID_SNAPPY: 0x01000000
# 2 subnets per node
SUBNETS_PER_NODE: 2
# 2**8 (= 64)
ATTESTATION_SUBNET_COUNT: 64
ATTESTATION_SUBNET_EXTRA_BITS: 0
# ceillog2(ATTESTATION_SUBNET_COUNT) + ATTESTATION_SUBNET_EXTRA_BITS
ATTESTATION_SUBNET_PREFIX_BITS: 6
# Deneb
# `2**7` (=128)
MAX_REQUEST_BLOCKS_DENEB: 128
# MAX_REQUEST_BLOCKS_DENEB * MAX_BLOBS_PER_BLOCK
MAX_REQUEST_BLOB_SIDECARS: 768
# `2**12` (= 4096 epochs, ~18 days)
MIN_EPOCHS_FOR_BLOB_SIDECARS_REQUESTS: 4096
# `6`
BLOB_SIDECAR_SUBNET_COUNT: 6
# `uint64(6)`
MAX_BLOBS_PER_BLOCK: 6
- mnemonic: "{{ .PreregisteredValidatorKeysMnemonic }}" # a 24 word BIP 39 mnemonic
# Number of validator keys to preregister inside the outputted CL genesis.ssz
count: {{ .NumValidatorKeysToPreregister }}
export CHAIN_ID="{{ .NetworkId }}"
export DEPOSIT_CONTRACT_ADDRESS="{{ .DepositContractAddress }}"
export EL_AND_CL_MNEMONIC="{{ .PreregisteredValidatorKeysMnemonic }}"
export CL_EXEC_BLOCK="0"
export SLOT_DURATION_IN_SECONDS={{ .SecondsPerSlot }}
export DEPOSIT_CONTRACT_BLOCK="0x0000000000000000000000000000000000000000000000000000000000000000"
export NUMBER_OF_VALIDATORS={{ .NumValidatorKeysToPreregister }}
export GENESIS_FORK_VERSION="0x10000038"
export ALTAIR_FORK_VERSION="0x20000038"
export BELLATRIX_FORK_VERSION="0x30000038"
export CAPELLA_FORK_VERSION="0x40000038"
export CAPELLA_FORK_EPOCH="{{ .CapellaForkEpoch }}"
export DENEB_FORK_VERSION="0x50000038"
export DENEB_FORK_EPOCH="{{ .DenebForkEpoch }}"
export ELECTRA_FORK_VERSION="0x60000038"
export ELECTRA_FORK_EPOCH="{{ .ElectraForkEpoch }}"
export WITHDRAWAL_TYPE="0x00"
export WITHDRAWAL_ADDRESS=0xf97e180c050e5Ab072211Ad2C213Eb5AEE4DF134
export GENESIS_TIMESTAMP={{ .UnixTimestamp }}
export GENESIS_DELAY={{ .GenesisDelay }}
export MAX_CHURN={{ .MaxChurn }}
export EJECTION_BALANCE=16000000000
# NOTE: This does NOT have any relevance to the mnemonics & validator keys in the CL genesis!
mnemonic: "stumble horn valley travel milk void screen bulk wink hood cup item glove setup wrong toward erase invite saddle this poverty basket index lab"
el_premine:
"m/44'/60'/0'/0/0": 1000000000ETH
"m/44'/60'/0'/0/1": 1000000000ETH
"m/44'/60'/0'/0/2": 1000000000ETH
"m/44'/60'/0'/0/3": 1000000000ETH
"m/44'/60'/0'/0/4": 1000000000ETH
"m/44'/60'/0'/0/5": 1000000000ETH
"m/44'/60'/0'/0/6": 1000000000ETH
el_premine_addrs: {}
chain_id: {{ .NetworkId }}
deposit_contract_address: "{{ .DepositContractAddress }}"
genesis_timestamp: {{ .UnixTimestamp }}
# Note: The module runs a merged chain so terminal_total_difficulty is hardcoded to zero.
terminal_total_difficulty: 0
genesis_delay: {{ .GenesisDelay }}
slot_duration_in_seconds: {{ .SecondsPerSlot }}
capella_fork_epoch: {{ .CapellaForkEpoch }}
deneb_fork_epoch: {{ .DenebForkEpoch }}
electra_fork_epoch: {{ .ElectraForkEpoch }}
{"address":"878705ba3f8bc32fcf7f4caa1a35e72af65cf766","crypto":{"cipher":"aes-128-ctr","ciphertext":"f02daebbf456faf787c5cd61a33ce780857c1ca10b00972aa451f0e9688e4ead","cipherparams":{"iv":"ef1668814155862f0653f15dae845e58"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"55e5ee70d3e882d2f00a073eda252ff01437abf51d7bfa76c06dcc73f7e8f1a3"},"mac":"d8d04625d0769fe286756734f946c78663961b74f0caaff1d768f0d255632f04"},"id":"5fb9083a-a221-412b-b0e0-921e22cc9645","version":3}
{"address":"4e9a3d9d1cd2a2b2371b8b3f489ae72259886f1a","crypto":{"cipher":"aes-128-ctr","ciphertext":"ab715382b1e1f13d927b2e3d22e087a51ccb72b32f9bac71727ec8438ecb6d54","cipherparams":{"iv":"dee12212262986854a0bfd9a5c766ced"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"7112f2fed838981fde1ca00cdd1d95630981bd22f772666fafd0778525cf1cc4"},"mac":"2a75795bb0513859355ce2086668398ee821a2e708edd856f8a85cf638fede9a"},"id":"f849b7fe-aff7-454f-91e1-838de2a8da6b","version":3}
{"address":"df8466f277964bb7a0ffd819403302c34dcd530a","crypto":{"cipher":"aes-128-ctr","ciphertext":"322e59ab95797f2ea9a1162e3f28e2ff7e27415b6e9d7d990a197e09dc9043d7","cipherparams":{"iv":"6179d5971b93a09799ace7371801e371"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"5ac65d7e25467366764d4539e8ae0c78d31dce4002042c06d3971b103c95f2a3"},"mac":"b5d060f2c0a5f8446dd4d718eee66c7eeff3feb90aafa8201fd7501c8f5c180a"},"id":"c5fda7a7-816a-4740-8804-afdc0d410cfb","version":3}
{"address":"5c613e39fc0ad91afda24587e6f52192d75fba50","crypto":{"cipher":"aes-128-ctr","ciphertext":"4ba38c15225d92f2cbac5eafb7cf5ef358332037cd9730dce595a7a4cc3a39d0","cipherparams":{"iv":"6a83dc5b43b0c9c8948905ccc697455a"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"cdfa581366dbc4f566404b0ac64d9d0c1a8a9d24202fe3c428212f020fd6cdbb"},"mac":"95a2e987cbe87d4b532f830df8c5cabc8a7bbd4e70eda672252ed4d8b967e660"},"id":"09d1b784-fb8f-4d25-8720-a683bb0c13ab","version":3}
{"address":"375ae6107f8cc4cf34842b71c6f746a362ad8eac","crypto":{"cipher":"aes-128-ctr","ciphertext":"ab13f28ad41bcb73f5ae982a5bde37ba737515fef848ea365911be3d97682530","cipherparams":{"iv":"fb4d9bfab1d9c5d47e46052ea80275e1"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"56ba7f86161cb419f27c19b5845b6dd8033927ff0d362863e5723e3568d5d0c7"},"mac":"ad9197d47c57c601313d49fb15392a29c8a16418d1bf6f39ac3b822bd5205593"},"id":"353e4c37-a37f-4b2a-8729-81460c6a92d4","version":3}
{"address":"1f6298457c5d76270325b724da5d1953923a6b88","crypto":{"cipher":"aes-128-ctr","ciphertext":"42348bd719f9225cc91184a3daf7005a89cec8be7d907c92c57ac01f29b61e2d","cipherparams":{"iv":"ee8d92dde2c3dc230f1f6e765641e0ce"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"74992f3587a487202cd76d6aa625af6b0e5b2f68eb0ea3647edb4541ce24adb9"},"mac":"27cd4f0aa624fce848aebccbd80efda35d615da2d274cc39e5185170d2ff4017"},"id":"27bfc138-d358-4c21-b040-93458f11e4c4","version":3}
{"address":"fe08e6f330f4e5e624ad759625b71b2e52594feb","crypto":{"cipher":"aes-128-ctr","ciphertext":"df41d4a4eef8ce781354c4058eac980bd349c12b40efeba38189e3d20f65eccd","cipherparams":{"iv":"c8ee56c122b8b70ab026a80ddaeaf987"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"d284320c522d4cec86d2965f8827ca63429f95c1f0a02f410393754f44b49480"},"mac":"c8d798da5f3de89fccf0a9d502f9bfb89876bee6c86d3d9176f043d9a8310579"},"id":"c9320f41-e707-49a2-9271-660c59e3bbdc","version":3}
# The path on the module container where static files are housed
STATIC_FILES_DIRPATH = "/static_files"
# Geth + CL genesis generation
GENESIS_GENERATION_CONFIG_DIRPATH = STATIC_FILES_DIRPATH + "/genesis-generation-config"
EL_GENESIS_GENERATION_CONFIG_DIRPATH = GENESIS_GENERATION_CONFIG_DIRPATH + "/el"
EL_GENESIS_GENERATION_CONFIG_TEMPLATE_FILEPATH = (
EL_GENESIS_GENERATION_CONFIG_DIRPATH + "/genesis-config.yaml.tmpl"
)
CL_GENESIS_GENERATION_CONFIG_DIRPATH = GENESIS_GENERATION_CONFIG_DIRPATH + "/cl"
CL_GENESIS_GENERATION_CONFIG_TEMPLATE_FILEPATH = (
CL_GENESIS_GENERATION_CONFIG_DIRPATH + "/config.yaml.tmpl"
)
CL_GENESIS_GENERATION_MNEMONICS_TEMPLATE_FILEPATH = (
CL_GENESIS_GENERATION_CONFIG_DIRPATH + "/mnemonics.yaml.tmpl"
)
# Prefunded keys
PREFUNDED_KEYS_DIRPATH = STATIC_FILES_DIRPATH + "/genesis-prefunded-keys"
GETH_PREFUNDED_KEYS_DIRPATH = PREFUNDED_KEYS_DIRPATH + "/geth"
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment