@@ -8,28 +8,25 @@ beacond = import_module("./src/nodes/consensus/beacond/launcher.star")
88networks = import_module ("./src/networks/networks.star" )
99port_spec_lib = import_module ("./src/lib/port_spec.star" )
1010nodes = import_module ("./src/nodes/nodes.star" )
11- nginx = import_module ("./src/services/nginx/nginx.star" )
1211constants = import_module ("./src/constants.star" )
1312spamoor = import_module ("./src/services/spamoor/launcher.star" )
1413prometheus = import_module ("./src/observability/prometheus/prometheus.star" )
1514grafana = import_module ("./src/observability/grafana/grafana.star" )
1615pyroscope = import_module ("./src/observability/pyroscope/pyroscope.star" )
1716tx_fuzz = import_module ("./src/services/tx_fuzz/launcher.star" )
18- blutgang = import_module ("./src/services/blutgang/launcher.star" )
1917blockscout = import_module ("./src/services/blockscout/launcher.star" )
2018sequencer = import_module ("./src/services/sequencer/launcher.star" )
2119preconf_config = import_module ("./src/preconf/config.star" )
2220flashblock_monitor = import_module ("./src/services/flashblock-monitor/launcher.star" )
2321
24- def run (plan , network_configuration = {}, node_settings = {}, eth_json_rpc_endpoints = [], additional_services = [], metrics_enabled_services = [], preconf = {}):
22+ def run (plan , network_configuration = {}, node_settings = {}, additional_services = [], metrics_enabled_services = [], preconf = {}):
2523 """
2624 Initiates the execution plan with the specified number of validators and arguments.
2725
2826 Args:
2927 plan: The execution plan to be run.
3028 network_configuration: Network configuration including validators, full nodes, seed nodes.
3129 node_settings: Node-specific settings.
32- eth_json_rpc_endpoints: RPC endpoint configurations.
3330 additional_services: Additional services to launch.
3431 metrics_enabled_services: Services with metrics enabled.
3532 preconf: Preconfirmation configuration. If provided, enables preconf with:
@@ -172,9 +169,11 @@ def run(plan, network_configuration = {}, node_settings = {}, eth_json_rpc_endpo
172169 for n , seed in enumerate (seed_nodes ):
173170 seed_node_config = beacond .create_node_config (plan , seed , consensus_node_peering_info , seed .el_service_name , chain_id , chain_spec , genesis_deposits_root , genesis_deposit_count_hex , jwt_file , kzg_trusted_setup )
174171 seed_node_configs [seed .cl_service_name ] = seed_node_config
175- seed_nodes_clients = plan .add_services (
176- configs = seed_node_configs ,
177- )
172+ seed_nodes_clients = {}
173+ if seed_node_configs != {}:
174+ seed_nodes_clients = plan .add_services (
175+ configs = seed_node_configs ,
176+ )
178177 for n , seed_client in enumerate (seed_nodes ):
179178 peer_info = beacond .get_peer_info (plan , seed_client .cl_service_name )
180179 consensus_node_peering_info .append (peer_info )
@@ -356,38 +355,46 @@ def run(plan, network_configuration = {}, node_settings = {}, eth_json_rpc_endpo
356355 for n , seed_node in enumerate (seed_nodes ):
357356 beacond .dial_unsafe_peers (plan , seed_node .cl_service_name , all_consensus_peering_info )
358357
359- # Get only the first rpc endpoint
360- eth_json_rpc_endpoint = eth_json_rpc_endpoints [0 ]
361- endpoint_type = eth_json_rpc_endpoint ["type" ]
362- plan .print ("RPC Endpoint Type:" , endpoint_type )
363- if endpoint_type == "nginx" :
364- plan .print ("Launching RPCs for " , endpoint_type )
365- nginx .get_config (plan , eth_json_rpc_endpoint ["clients" ])
366-
367- elif endpoint_type == "blutgang" :
368- plan .print ("Launching blutgang" )
369- blutgang_config_template = read_file (
370- constants .BLUTGANG_CONFIG_TEMPLATE_FILEPATH ,
371- )
372- blutgang .launch_blutgang (
373- plan ,
374- blutgang_config_template ,
375- full_node_el_clients ,
376- eth_json_rpc_endpoint ["clients" ],
377- "kurtosis" ,
378- )
379-
380- else :
381- plan .print ("Invalid type for eth_json_rpc_endpoint" )
358+ # If no seed nodes exist, bootstrap peering from the first validator
359+ # so that nodes can discover each other via PEX.
360+ if len (seed_nodes ) == 0 and len (validators ) > 0 :
361+ beacond .dial_unsafe_peers (plan , validators [0 ].cl_service_name , all_consensus_peering_info )
362+
363+ # Bootstrap EL peering: use first validator as a static peer so
364+ # all EL nodes can discover each other via devp2p.
365+ bootstrap_enode = execution .get_enode_addr (plan , validators [0 ].el_service_name )
366+ el_services_to_peer = []
367+ for node in full_nodes :
368+ el_services_to_peer .append (node .el_service_name )
369+ for node in preconf_rpc_nodes :
370+ el_services_to_peer .append (node .el_service_name )
371+ if sequencer_node :
372+ el_services_to_peer .append (sequencer_node .el_service_name )
373+ for node in validators [1 :]:
374+ el_services_to_peer .append (node .el_service_name )
375+ for el_name in el_services_to_peer :
376+ execution .add_peer (plan , el_name , bootstrap_enode )
377+
378+ # For preconf topologies: add direct EL peering between the sequencer
379+ # and tx-receiving nodes (preconf RPC, full nodes) so that transactions
380+ # gossip directly to the sequencer without routing through validator-0.
381+ if preconf_cfg and sequencer_node :
382+ sequencer_enode = execution .get_enode_addr (plan , sequencer_node .el_service_name )
383+ for node in preconf_rpc_nodes :
384+ execution .add_peer (plan , node .el_service_name , sequencer_enode )
385+ for node in full_nodes :
386+ execution .add_peer (plan , node .el_service_name , sequencer_enode )
382387
383388 # 8. Start additional services
384389 prometheus_url = ""
385390 for s_dict in additional_services :
386391 s = service_module .parse_service_from_dict (s_dict )
387392 if s .name == "spamoor" :
388393 plan .print ("Launching spamoor" )
389- ip_spamoor = plan .get_service (endpoint_type ).ip_address
390- port_spamoor = plan .get_service (endpoint_type ).ports ["http" ].number
394+ first_full_el_name = full_nodes [0 ].el_service_name
395+ first_full_el = full_node_el_clients [first_full_el_name ]
396+ ip_spamoor = first_full_el .ip_address
397+ port_spamoor = first_full_el .ports ["eth-json-rpc" ].number
391398 spamoor .launch_spamoor (
392399 plan ,
393400 constants .PRE_FUNDED_ACCOUNTS [next_free_prefunded_account ],
@@ -400,7 +407,6 @@ def run(plan, network_configuration = {}, node_settings = {}, eth_json_rpc_endpo
400407 if "replicas" not in s_dict :
401408 s .replicas = 1
402409 next_free_prefunded_account = tx_fuzz .launch_tx_fuzzes (plan , s .replicas , next_free_prefunded_account , full_node_el_client_configs , full_node_el_clients , [])
403- # next_free_prefunded_account = tx_fuzz.launch_tx_fuzzes_gang(plan, s.replicas, next_free_prefunded_account, [])
404410
405411 elif s .name == "prometheus" :
406412 prometheus_url = prometheus .start (plan , metrics_enabled_services )
0 commit comments