Skip to content

Commit 1985d40

Browse files
committed
feat: add txpool-viz
1 parent e3abf47 commit 1985d40

7 files changed

Lines changed: 229 additions & 0 deletions

File tree

main.star

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ get_prefunded_accounts = import_module(
5656
"./src/prefunded_accounts/get_prefunded_accounts.star"
5757
)
5858
spamoor = import_module("./src/spamoor/spamoor.star")
59+
txpool_viz = import_module("./src/txpool_viz/txpool_viz.star")
5960

6061
GRAFANA_USER = "admin"
6162
GRAFANA_PASSWORD = "admin"
@@ -475,6 +476,18 @@ def run(plan, args={}):
475476
global_node_selectors,
476477
)
477478
plan.print("Successfully launched tx-fuzz")
479+
elif additional_service == "txpool_viz":
480+
plan.print("Launching txpool-viz")
481+
txpool_viz_config_template = read_file(
482+
static_files.TXPOOL_VIZ_CONFIG_TEMPLATE_FILEPATH
483+
)
484+
txpool_viz.launch_txpool_viz(
485+
plan,
486+
txpool_viz_config_template,
487+
all_participants,
488+
args_with_right_defaults.txpool_viz_params,
489+
global_node_selectors
490+
)
478491
elif additional_service == "forkmon":
479492
plan.print("Launching el forkmon")
480493
forkmon_config_template = read_file(

src/package_io/constants.star

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ MEV_RS_MEV_TYPE = "mev-rs"
9393
COMMIT_BOOST_MEV_TYPE = "commit-boost"
9494
DEFAULT_DORA_IMAGE = "ethpandaops/dora:latest"
9595
DEFAULT_SPAMOOR_IMAGE = "ethpandaops/spamoor:latest"
96+
DEFAULT_TXPOOL_VIZ_IMAGE = "punkhazardlabs/txpool-viz:latest"
9697
DEFAULT_ASSERTOOR_IMAGE = "ethpandaops/assertoor:latest"
9798
DEFAULT_SNOOPER_IMAGE = "ethpandaops/rpc-snooper:latest"
9899
DEFAULT_ETHEREUM_GENESIS_GENERATOR_IMAGE = (

src/package_io/input_parser.star

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ ATTR_TO_BE_SKIPPED_AT_ROOT = (
7474
"dora_params",
7575
"docker_cache_params",
7676
"assertoor_params",
77+
"txpool_viz_params",
7778
"prometheus_params",
7879
"grafana_params",
7980
"tx_fuzz_params",
@@ -179,6 +180,8 @@ def input_parser(plan, input_args):
179180
for sub_attr in input_args["spamoor_params"]:
180181
sub_value = input_args["spamoor_params"][sub_attr]
181182
result["spamoor_params"][sub_attr] = sub_value
183+
elif attr == "txpool_viz_params":
184+
result["txpool_viz_params"] = get_txpool_viz_params(input_args)
182185
elif attr == "ethereum_genesis_generator_params":
183186
for sub_attr in input_args["ethereum_genesis_generator_params"]:
184187
sub_value = input_args["ethereum_genesis_generator_params"][sub_attr]
@@ -545,6 +548,19 @@ def input_parser(plan, input_args):
545548
spammers=result["spamoor_params"]["spammers"],
546549
extra_args=result["spamoor_params"]["extra_args"],
547550
),
551+
txpool_viz_params=struct(
552+
image=result["txpool_viz_params"]["image"],
553+
min_cpu=result["txpool_viz_params"]["min_cpu"],
554+
max_cpu=result["txpool_viz_params"]["max_cpu"],
555+
min_mem=result["txpool_viz_params"]["min_mem"],
556+
max_mem=result["txpool_viz_params"]["max_mem"],
557+
extra_args=result["txpool_viz_params"]["extra_args"],
558+
polling=result["txpool_viz_params"]["polling"],
559+
filters=result["txpool_viz_params"]["filters"],
560+
focil_enabled=result["txpool_viz_params"]["focil_enabled"],
561+
log_level=result["txpool_viz_params"]["log_level"],
562+
env=result["txpool_viz_params"]["env"],
563+
),
548564
additional_services=result["additional_services"],
549565
wait_for_finalization=result["wait_for_finalization"],
550566
global_log_level=result["global_log_level"],
@@ -1618,6 +1634,7 @@ def docker_cache_image_override(plan, result):
16181634
"prometheus_params.image",
16191635
"grafana_params.image",
16201636
"spamoor_params.image",
1637+
"txpool_viz_params.image",
16211638
"ethereum_genesis_generator_params.image",
16221639
]
16231640

@@ -1696,3 +1713,39 @@ def get_default_ethereum_genesis_generator_params():
16961713
return {
16971714
"image": constants.DEFAULT_ETHEREUM_GENESIS_GENERATOR_IMAGE,
16981715
}
1716+
def get_txpool_viz_params(input_args):
1717+
image = input_args.get("txpool_viz_params", {}).get("image", constants.DEFAULT_TXPOOL_VIZ_IMAGE)
1718+
min_cpu = input_args.get("txpool_viz_params", {}).get("min_cpu", False)
1719+
max_cpu = input_args.get("txpool_viz_params", {}).get("max_cpu", False)
1720+
min_mem = input_args.get("txpool_viz_params", {}).get("min_mem", False)
1721+
max_mem = input_args.get("txpool_viz_params", {}).get("max_mem", False)
1722+
extra_args = input_args.get("txpool_viz_params", {}).get("extra_args", [])
1723+
polling_args = input_args.get("txpool_viz_params", {}).get("polling", {})
1724+
filters_args = input_args.get("txpool_viz_params", {}).get("filters", {})
1725+
focil_enabled = input_args.get("txpool_viz_params", {}).get("focil_enabled", "false")
1726+
log_level = input_args.get("txpool_viz_params", {}).get("log_level", "info")
1727+
env = input_args.get("txpool_viz_params", {}).get("env", {})
1728+
1729+
polling_config = {
1730+
"interval": polling_args.get("interval", "0.5s"),
1731+
"timeout": polling_args.get("timeout", "3s"),
1732+
}
1733+
1734+
filters_config = {
1735+
"min_gas_price": filters_args.get("min_gas_price", "1gwei"),
1736+
}
1737+
1738+
return {
1739+
"image": image,
1740+
"min_cpu": min_cpu,
1741+
"max_cpu": max_cpu,
1742+
"min_mem": min_mem,
1743+
"max_mem": max_mem,
1744+
"extra_args": extra_args,
1745+
"polling": polling_config,
1746+
"filters": filters_config,
1747+
"focil_enabled": focil_enabled,
1748+
"log_level": log_level,
1749+
"env": env,
1750+
}
1751+

src/package_io/sanity_check.star

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,19 @@ SUBCATEGORY_PARAMS = {
306306
"mev",
307307
"other",
308308
],
309+
"txpool_viz_params": [
310+
"image",
311+
"min_cpu",
312+
"max_cpu",
313+
"min_mem",
314+
"max_mem",
315+
"extra_args",
316+
"polling",
317+
"filters",
318+
"focil_enabled",
319+
"log_level",
320+
"env"
321+
]
309322
}
310323

311324
ADDITIONAL_SERVICES_PARAMS = [
@@ -327,6 +340,7 @@ ADDITIONAL_SERVICES_PARAMS = [
327340
"apache",
328341
"tracoor",
329342
"spamoor",
343+
"txpool_viz"
330344
]
331345

332346
ADDITIONAL_CATEGORY_PARAMS = {

src/static_files/static_files.star

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,3 +118,10 @@ FLASHBOTS_RBUILDER_CONFIG_FILEPATH = (
118118
COMMIT_BOOST_CONFIG_FILEPATH = (
119119
STATIC_FILES_DIRPATH + "/mev/commit-boost/cb-config.toml.tmpl"
120120
)
121+
122+
# txpool-viz config
123+
TXPOOL_VIZ_CONFIG_DIRPATH = "/txpool-viz-config"
124+
TXPOOL_VIZ_CONFIG_TEMPLATE_FILEPATH = (
125+
STATIC_FILES_DIRPATH + TXPOOL_VIZ_CONFIG_DIRPATH + "/config.yaml.tmpl"
126+
)
127+

src/txpool_viz/txpool_viz.star

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
redis_module = import_module("github.com/kurtosis-tech/redis-package/main.star")
2+
postgres_module = import_module("github.com/kurtosis-tech/postgres-package/main.star")
3+
shared_utils = import_module("../shared_utils/shared_utils.star")
4+
5+
HTTP_PORT_NUMBER= 8080
6+
TXPOOL_VIZ_SERVICE_NAME="txpool-viz"
7+
8+
TXPOOL_VIZ_CONFIG_FILENAME = "config.yaml"
9+
TXPOOL_VIZ_CONFIG_PATH="/cfg/"
10+
11+
# The min/max CPU/memory that txpool-viz can use.
12+
MIN_CPU = 100
13+
MAX_CPU = 1000
14+
MIN_MEM = 128
15+
MAX_MEM = 1024
16+
17+
def launch_txpool_viz(
18+
plan,
19+
config_template,
20+
network_participants,
21+
txpool_viz_params,
22+
global_node_selectors
23+
):
24+
endpoints_list = []
25+
for participant in network_participants:
26+
el_metrics_info = participant.el_context.el_metrics_info
27+
endpoints_list.append({
28+
"Name": el_metrics_info[0]["name"] if el_metrics_info else "unknown",
29+
"RPCUrl": participant.el_context.rpc_http_url,
30+
"Socket": participant.el_context.ws_url
31+
})
32+
33+
beacon_endpoints = []
34+
for participant in network_participants:
35+
beacon_endpoints.append({
36+
"Name": participant.cl_context.beacon_service_name,
37+
"BeaconUrl": participant.cl_context.beacon_http_url,
38+
})
39+
40+
# config data & template
41+
template_data = txpool_viz_config_template_data(txpool_viz_params, endpoints_list, beacon_endpoints)
42+
43+
template_and_data = shared_utils.new_template_and_data(
44+
config_template, template_data
45+
)
46+
47+
file_config = {}
48+
file_config[TXPOOL_VIZ_CONFIG_FILENAME] = template_and_data
49+
50+
config_files_artifact_name = plan.render_templates(
51+
config=file_config,
52+
name="txpool-viz-config",
53+
)
54+
55+
postgres = postgres_module.run(
56+
plan,
57+
service_name="txpool-viz-postgres",
58+
)
59+
60+
# attaching redis server
61+
redis = redis_module.run(
62+
plan,
63+
service_name="txpool-viz-redis",
64+
)
65+
66+
redis_url = "redis://" + redis.hostname + ":" + str(redis.port_number) + "/0"
67+
68+
environment_variables = dict(txpool_viz_params.env)
69+
environment_variables.update({
70+
"POSTGRES_URL": postgres.url,
71+
"REDIS_URL": redis_url,
72+
"PORT": str(HTTP_PORT_NUMBER),
73+
"ENV": "prod",
74+
})
75+
76+
service_config = get_service_config(environment_variables, txpool_viz_params, global_node_selectors, config_files_artifact_name)
77+
78+
txpoolviz = plan.add_service(TXPOOL_VIZ_SERVICE_NAME, config=service_config)
79+
80+
def get_service_config(environment_variables, txpool_viz_params, node_selectors, files_artifact):
81+
return ServiceConfig(
82+
image=txpool_viz_params.image,
83+
ports= {
84+
shared_utils.HTTP_APPLICATION_PROTOCOL: PortSpec(
85+
number=HTTP_PORT_NUMBER,
86+
application_protocol=shared_utils.HTTP_APPLICATION_PROTOCOL,
87+
transport_protocol=shared_utils.TCP_PROTOCOL,
88+
),
89+
},
90+
env_vars=environment_variables,
91+
min_cpu=txpool_viz_params.min_cpu or MIN_CPU,
92+
max_cpu=txpool_viz_params.max_cpu or MAX_CPU,
93+
min_memory=txpool_viz_params.min_mem or MIN_MEM,
94+
max_memory=txpool_viz_params.max_mem or MAX_MEM,
95+
files = {
96+
TXPOOL_VIZ_CONFIG_PATH : files_artifact
97+
},
98+
node_selectors=node_selectors,
99+
)
100+
101+
def txpool_viz_config_template_data(config, endpoints_list, beacon_endpoints):
102+
cfg = dict(config.extra_args)
103+
cfg.update({
104+
"Endpoints": endpoints_list,
105+
"Polling": config.polling,
106+
"Filters": config.filters,
107+
"LogLevel": config.log_level,
108+
})
109+
110+
if config.focil_enabled == "true":
111+
cfg["FocilEnabled"] = config.focil_enabled
112+
cfg["BeaconEndpoints"] = beacon_endpoints
113+
114+
return cfg
115+
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
endpoints:
2+
{{- range .Endpoints }}
3+
- name: {{ .Name }}
4+
rpc_url: "{{ .RPCUrl }}"
5+
socket: "{{ .Socket }}"
6+
{{- end }}
7+
8+
{{- if eq .FocilEnabled "true" }}
9+
focil_enabled: true
10+
beacon_urls:
11+
{{- range .BeaconEndpoints }}
12+
- name: {{ .Name }}
13+
beacon_url: "{{ .BeaconUrl }}"
14+
{{- end }}
15+
{{- end }}
16+
17+
polling:
18+
interval: {{ .Polling.interval }}
19+
timeout: {{ .Polling.timeout }}
20+
21+
filters:
22+
min_gas_price: {{ .Filters.MinGasPrice }}
23+
24+
log_level: "{{ .LogLevel }}"
25+
26+
extra_args: {{ .ExtraArgs }}

0 commit comments

Comments
 (0)