Skip to content

Commit 23628b2

Browse files
authored
feat: Add Tx_spamer_params and move MEV to the bottom of main.star (#208)
PR adds a possibility to push custom params to Tx_Spammer. tested with flag --txcount=100 - Looking at Tx_Spammer logs change is applied. Also addressing #168 --------- Co-authored-by: Kamil Chodoła <kamil@nethermind.io>
1 parent 3bbcca7 commit 23628b2

File tree

4 files changed

+71
-51
lines changed

4 files changed

+71
-51
lines changed

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,12 @@ To configure the package behaviour, you can modify your `network_params.json` fi
202202
"deneb_fork_epoch": 4,
203203
"electra_fork_epoch": null,
204204
},
205+
206+
// Configuration place for transaction spammer - https://github.com/MariusVanDerWijden/tx-fuzz
207+
"tx_spammer_params": {
208+
// A list of optional extra params that will be passed to the TX Spammer container for modifying its behaviour
209+
"tx_spammer_extra_args": []
210+
}
205211

206212
// True by defaults such that in addition to the Ethereum network:
207213
// - A transaction spammer is launched to fake transactions sent to the network

main.star

Lines changed: 48 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -52,57 +52,14 @@ def run(plan, args = {}):
5252
for participant in all_participants:
5353
all_el_client_contexts.append(participant.el_client_context)
5454
all_cl_client_contexts.append(participant.cl_client_context)
55-
56-
57-
mev_endpoints = []
58-
# passed external relays get priority
59-
# perhaps add mev_type External or remove this
60-
if hasattr(participant, "builder_network_params") and participant.builder_network_params != None:
61-
mev_endpoints = participant.builder_network_params.relay_end_points
62-
# otherwise dummy relays spinup if chosen
63-
elif args_with_right_defaults.mev_type and args_with_right_defaults.mev_type == MOCK_MEV_TYPE:
64-
el_uri = "{0}:{1}".format(all_el_client_contexts[0].ip_addr, all_el_client_contexts[0].engine_rpc_port_num)
65-
beacon_uri = "{0}:{1}".format(all_cl_client_contexts[0].ip_addr, all_cl_client_contexts[0].http_port_num)
66-
jwt_secret = all_el_client_contexts[0].jwt_secret
67-
endpoint = mock_mev_launcher_module.launch_mock_mev(plan, el_uri, beacon_uri, jwt_secret, args_with_right_defaults.global_client_log_level)
68-
mev_endpoints.append(endpoint)
69-
elif args_with_right_defaults.mev_type and args_with_right_defaults.mev_type == FULL_MEV_TYPE:
70-
el_uri = "http://{0}:{1}".format(all_el_client_contexts[0].ip_addr, all_el_client_contexts[0].rpc_port_num)
71-
builder_uri = "http://{0}:{1}".format(all_el_client_contexts[-1].ip_addr, all_el_client_contexts[-1].rpc_port_num)
72-
beacon_uri = ["http://{0}:{1}".format(context.ip_addr, context.http_port_num) for context in all_cl_client_contexts][-1]
73-
beacon_uris = beacon_uri
74-
first_cl_client = all_cl_client_contexts[0]
75-
first_client_beacon_name = first_cl_client.beacon_service_name
76-
mev_flood_module.launch_mev_flood(plan, mev_params.mev_flood_image, el_uri, genesis_constants.PRE_FUNDED_ACCOUNTS)
77-
epoch_recipe = GetHttpRequestRecipe(
78-
endpoint = "/eth/v2/beacon/blocks/head",
79-
port_id = HTTP_PORT_ID_FOR_FACT,
80-
extract = {
81-
"epoch": ".data.message.body.attestations[0].data.target.epoch"
82-
}
83-
)
84-
plan.wait(recipe = epoch_recipe, field = "extract.epoch", assertion = ">=", target_value = str(network_params.capella_fork_epoch), timeout = "20m", service_name = first_client_beacon_name)
85-
plan.print("epoch 2 reached, can begin mev stuff")
86-
endpoint = mev_relay_launcher_module.launch_mev_relay(plan, mev_params, network_params.network_id, beacon_uris, genesis_validators_root, builder_uri, network_params.seconds_per_slot, network_params.slots_per_epoch)
87-
mev_flood_module.spam_in_background(plan, el_uri, mev_params.mev_flood_extra_args, mev_params.mev_flood_seconds_per_bundle, genesis_constants.PRE_FUNDED_ACCOUNTS)
88-
if args_with_right_defaults.mev_params.launch_custom_flood:
89-
mev_custom_flood_module.spam_in_background(plan, genesis_constants.PRE_FUNDED_ACCOUNTS[-1].private_key, genesis_constants.PRE_FUNDED_ACCOUNTS[0].address, el_uri)
90-
mev_endpoints.append(endpoint)
91-
92-
# spin up the mev boost contexts if some endpoints for relays have been passed
93-
all_mevboost_contexts = []
94-
if mev_endpoints:
95-
for index, participant in enumerate(all_participants):
96-
mev_boost_launcher = mev_boost_launcher_module.new_mev_boost_launcher(MEV_BOOST_SHOULD_CHECK_RELAY, mev_endpoints)
97-
mev_boost_service_name = "{0}{1}".format(parse_input.MEV_BOOST_SERVICE_NAME_PREFIX, index)
98-
mev_boost_context = mev_boost_launcher_module.launch(plan, mev_boost_launcher, mev_boost_service_name, network_params.network_id, mev_params.mev_boost_image)
99-
all_mevboost_contexts.append(mev_boost_context)
55+
10056

10157
if not args_with_right_defaults.launch_additional_services:
10258
return
10359

10460
plan.print("Launching transaction spammer")
105-
transaction_spammer.launch_transaction_spammer(plan, genesis_constants.PRE_FUNDED_ACCOUNTS, all_el_client_contexts[0])
61+
tx_spammer_params = args_with_right_defaults.tx_spammer_params
62+
transaction_spammer.launch_transaction_spammer(plan, genesis_constants.PRE_FUNDED_ACCOUNTS, all_el_client_contexts[0], tx_spammer_params)
10663
plan.print("Succesfully launched transaction spammer")
10764

10865
plan.print("Launching Blob spammer")
@@ -184,4 +141,49 @@ def run(plan, args = {}):
184141
)
185142
output = struct(grafana_info = grafana_info)
186143

144+
145+
mev_endpoints = []
146+
# passed external relays get priority
147+
# perhaps add mev_type External or remove this
148+
if hasattr(participant, "builder_network_params") and participant.builder_network_params != None:
149+
mev_endpoints = participant.builder_network_params.relay_end_points
150+
# otherwise dummy relays spinup if chosen
151+
elif args_with_right_defaults.mev_type and args_with_right_defaults.mev_type == MOCK_MEV_TYPE:
152+
el_uri = "{0}:{1}".format(all_el_client_contexts[0].ip_addr, all_el_client_contexts[0].engine_rpc_port_num)
153+
beacon_uri = "{0}:{1}".format(all_cl_client_contexts[0].ip_addr, all_cl_client_contexts[0].http_port_num)
154+
jwt_secret = all_el_client_contexts[0].jwt_secret
155+
endpoint = mock_mev_launcher_module.launch_mock_mev(plan, el_uri, beacon_uri, jwt_secret, args_with_right_defaults.global_client_log_level)
156+
mev_endpoints.append(endpoint)
157+
elif args_with_right_defaults.mev_type and args_with_right_defaults.mev_type == FULL_MEV_TYPE:
158+
el_uri = "http://{0}:{1}".format(all_el_client_contexts[0].ip_addr, all_el_client_contexts[0].rpc_port_num)
159+
builder_uri = "http://{0}:{1}".format(all_el_client_contexts[-1].ip_addr, all_el_client_contexts[-1].rpc_port_num)
160+
beacon_uri = ["http://{0}:{1}".format(context.ip_addr, context.http_port_num) for context in all_cl_client_contexts][-1]
161+
beacon_uris = beacon_uri
162+
first_cl_client = all_cl_client_contexts[0]
163+
first_client_beacon_name = first_cl_client.beacon_service_name
164+
mev_flood_module.launch_mev_flood(plan, mev_params.mev_flood_image, el_uri, genesis_constants.PRE_FUNDED_ACCOUNTS)
165+
epoch_recipe = GetHttpRequestRecipe(
166+
endpoint = "/eth/v2/beacon/blocks/head",
167+
port_id = HTTP_PORT_ID_FOR_FACT,
168+
extract = {
169+
"epoch": ".data.message.body.attestations[0].data.target.epoch"
170+
}
171+
)
172+
plan.wait(recipe = epoch_recipe, field = "extract.epoch", assertion = ">=", target_value = str(network_params.capella_fork_epoch), timeout = "20m", service_name = first_client_beacon_name)
173+
plan.print("epoch 2 reached, can begin mev stuff")
174+
endpoint = mev_relay_launcher_module.launch_mev_relay(plan, mev_params, network_params.network_id, beacon_uris, genesis_validators_root, builder_uri, network_params.seconds_per_slot, network_params.slots_per_epoch)
175+
mev_flood_module.spam_in_background(plan, el_uri, mev_params.mev_flood_extra_args, mev_params.mev_flood_seconds_per_bundle, genesis_constants.PRE_FUNDED_ACCOUNTS)
176+
if args_with_right_defaults.mev_params.launch_custom_flood:
177+
mev_custom_flood_module.spam_in_background(plan, genesis_constants.PRE_FUNDED_ACCOUNTS[-1].private_key, genesis_constants.PRE_FUNDED_ACCOUNTS[0].address, el_uri)
178+
mev_endpoints.append(endpoint)
179+
180+
# spin up the mev boost contexts if some endpoints for relays have been passed
181+
all_mevboost_contexts = []
182+
if mev_endpoints:
183+
for index, participant in enumerate(all_participants):
184+
mev_boost_launcher = mev_boost_launcher_module.new_mev_boost_launcher(MEV_BOOST_SHOULD_CHECK_RELAY, mev_endpoints)
185+
mev_boost_service_name = "{0}{1}".format(parse_input.MEV_BOOST_SERVICE_NAME_PREFIX, index)
186+
mev_boost_context = mev_boost_launcher_module.launch(plan, mev_boost_launcher, mev_boost_service_name, network_params.network_id, mev_params.mev_boost_image)
187+
all_mevboost_contexts.append(mev_boost_context)
188+
187189
return output

src/package_io/parse_input.star

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
FLASHBOTS_MEV_BOOST_PORT = 18550
33
MEV_BOOST_SERVICE_NAME_PREFIX = "mev-boost-"
44

5-
ATTR_TO_BE_SKIPPED_AT_ROOT = ("network_params", "participants", "mev_params")
5+
ATTR_TO_BE_SKIPPED_AT_ROOT = ("network_params", "participants", "mev_params", "tx_spammer_params")
66

77
package_io_constants = import_module("github.com/kurtosis-tech/eth-network-package/package_io/constants.star")
88
package_io_parser = import_module("github.com/kurtosis-tech/eth-network-package/package_io/input_parser.star")
@@ -35,6 +35,8 @@ def parse_input(plan, input_args):
3535
if result.get("mev_type") == "full" and result["network_params"]["capella_fork_epoch"] == 0:
3636
fail("capella_fork_epoch needs to be set to a non-zero value when using full MEV, set it using network_params.capella_fork_epoch")
3737

38+
result["tx_spammer_params"] = get_default_tx_spammer_params()
39+
3840
return struct(
3941
participants=[struct(
4042
el_client_type=participant["el_client_type"],
@@ -73,6 +75,9 @@ def parse_input(plan, input_args):
7375
mev_flood_seconds_per_bundle = result["mev_params"]["mev_flood_seconds_per_bundle"],
7476
launch_custom_flood = result["mev_params"]["launch_custom_flood"],
7577
),
78+
tx_spammer_params = struct(
79+
tx_spammer_extra_args = result["tx_spammer_params"]["tx_spammer_extra_args"],
80+
),
7681
launch_additional_services=result["launch_additional_services"],
7782
wait_for_finalization=result["wait_for_finalization"],
7883
wait_for_verifications=result["wait_for_verifications"],
@@ -98,6 +103,11 @@ def get_default_mev_params():
98103
"launch_custom_flood": False
99104
}
100105

106+
def get_default_tx_spammer_params():
107+
return {
108+
"tx_spammer_extra_args": []
109+
}
110+
101111
# TODO perhaps clean this up into a map
102112
def enrich_mev_extra_params(parsed_arguments_dict, mev_prefix, mev_port, mev_type):
103113
for index, participant in enumerate(parsed_arguments_dict["participants"]):
Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,20 @@
1+
#TODO: Add Image and Service Name to tx_spammer_params
12
IMAGE_NAME = "ethpandaops/tx-fuzz:latest"
23
SERVICE_NAME = "transaction-spammer"
34

4-
def launch_transaction_spammer(plan, prefunded_addresses, el_client_context):
5-
config = get_config(prefunded_addresses, el_client_context)
5+
def launch_transaction_spammer(plan, prefunded_addresses, el_client_context, tx_spammer_params):
6+
config = get_config(prefunded_addresses, el_client_context, tx_spammer_params.tx_spammer_extra_args)
67
plan.add_service(SERVICE_NAME, config)
78

89

9-
def get_config(prefunded_addresses, el_client_context):
10+
def get_config(prefunded_addresses, el_client_context, tx_spammer_extra_args):
1011
return ServiceConfig(
1112
image = IMAGE_NAME,
1213
cmd = [
1314
"spam",
1415
"--rpc=http://{0}:{1}".format(el_client_context.ip_addr, el_client_context.rpc_port_num),
15-
"--sk={0}".format(prefunded_addresses[3].private_key),
16+
"--sk={0}".format(prefunded_addresses[0].private_key),
17+
"{0}".format(" ".join(tx_spammer_extra_args))
1618
]
1719
)
1820

0 commit comments

Comments
 (0)