Skip to content

Commit 2a97753

Browse files
committed
feat: add benchmark for trin
1 parent c56bb62 commit 2a97753

File tree

11 files changed

+548
-4
lines changed

11 files changed

+548
-4
lines changed

.circleci/config.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ jobs:
235235
# parallelism level should be set to the amount of simulators we have or greater
236236
# The reason for this is the CI code currently only supports 1 input at a time
237237
# if we have a parallelism level of 5 and 6 sims one test runner will get 2 test sims and fail
238-
parallelism: 19
238+
parallelism: 20
239239
steps:
240240
- checkout
241241
- run:

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,4 @@
77
.vscode/
88
# Ignore downloaded consensus specs test data
99
testing/ef-tests/mainnet*
10-
10+
bin/trin-bench/logs*

Cargo.lock

Lines changed: 22 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
[workspace]
22
members = [
33
"bin/portal-bridge",
4-
"bin/trin",
4+
"bin/trin",
5+
"bin/trin-bench",
56
"bin/trin-execution",
67
"crates/ethportal-api",
78
"crates/e2store",
@@ -15,7 +16,7 @@ members = [
1516
"crates/subnetworks/history",
1617
"crates/subnetworks/state",
1718
"crates/utils",
18-
"crates/validation",
19+
"crates/validation",
1920
"testing/ef-tests",
2021
"testing/ethportal-peertest",
2122
"testing/utp",
@@ -120,3 +121,8 @@ trin-validation = { path = "crates/validation" }
120121
#
121122
# See: https://github.com/eira-fransham/crunchy/issues/13
122123
crunchy = "=0.2.2"
124+
125+
126+
[profile.profiling]
127+
inherits = "release"
128+
debug = true

bin/trin-bench/Cargo.toml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
[package]
2+
name = "trin-bench"
3+
authors.workspace = true
4+
categories.workspace = true
5+
edition.workspace = true
6+
keywords.workspace = true
7+
license.workspace = true
8+
readme.workspace = true
9+
repository.workspace = true
10+
rust-version.workspace = true
11+
version.workspace = true
12+
13+
[dependencies]
14+
anyhow.workspace = true
15+
clap.workspace = true
16+
ethportal-api.workspace = true
17+
e2store.workspace = true
18+
futures.workspace = true
19+
humanize-duration.workspace = true
20+
jsonrpsee.workspace = true
21+
portal-bridge.workspace = true
22+
reqwest.workspace = true
23+
tokio.workspace = true
24+
tracing.workspace = true
25+
tracing-subscriber.workspace = true
26+
trin-execution.workspace = true
27+
trin-utils.workspace = true
28+
trin-validation.workspace = true
29+
url.workspace = true

bin/trin-bench/Makefile

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
bench-trin:
2+
@echo "Running Trin Bench"
3+
@./run-bench.sh trin
4+
@echo "Down running Trin Bench"
5+
6+
bench-trin-perf:
7+
@echo "Running Trin Bench"
8+
@./run-bench.sh trin perf
9+
@echo "Down running Trin Bench"
10+
11+
clean:
12+
sudo rm -r logs

bin/trin-bench/README.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Trin Bench
2+
Trin bench is for testing Trin performance and being able to recreate situations reliably to verify if performance improvements or regressions happen
3+
4+
## To run benchmark with Trin
5+
```sh
6+
make bench-trin
7+
```
8+
9+
## To run benchmark with Trin and generate flamegraphs
10+
```sh
11+
make bench-trin-perf
12+
```
13+
14+
## Clean results
15+
```sh
16+
make clean
17+
```
18+
19+
## View the results
20+
21+
The results such as logs can be viewed in the generate `logs` folder
22+
23+
`trin_benchmark.log` will contain the logs of the bench mark coordinator
24+
25+
`data_sender` and `data_receiver` is the data directory
26+
`data_sender.log` and `data_receiver.log` are the logs of the portal clients
27+
if perf mode is ran the portal client will be profiled and flamegraphs will be generated `data_sender.svg` and `data_receiver.svg`
28+
29+
The `past_runs` directory archives the logs and flamegraphs of previous runs

bin/trin-bench/run-bench.sh

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
#!/bin/bash
2+
3+
# Define log directories
4+
LOG_DIR="logs"
5+
PAST_RUNS_DIR="$LOG_DIR/past_runs"
6+
mkdir -p "$PAST_RUNS_DIR"
7+
8+
# Create data directories for portal client instances
9+
DATA_DIR_SENDER="data_sender"
10+
DATA_DIR_RECEIVER="data_receiver"
11+
mkdir -p "$LOG_DIR/$DATA_DIR_SENDER" "$LOG_DIR/$DATA_DIR_RECEIVER"
12+
13+
# Check first argument: portal client selection
14+
PORTAL_CLIENT="$1"
15+
VALID_CLIENTS=("trin" "fluffy" "shisui" "ultralight" "samba")
16+
if [[ ! " ${VALID_CLIENTS[@]} " =~ " $PORTAL_CLIENT " ]]; then
17+
echo "Error: Invalid portal client specified. Choose from: ${VALID_CLIENTS[*]}"
18+
exit 1
19+
fi
20+
21+
# Check second argument: perf flag
22+
USE_PERF=false
23+
if [ "$2" == "perf" ]; then
24+
USE_PERF=true
25+
fi
26+
27+
# Clone portal-accumulators repository if not already present
28+
if [ ! -d "../../portal-accumulators" ]; then
29+
git clone https://github.com/ethereum/portal-accumulators ../../portal-accumulators || { echo "Failed to clone portal-accumulators"; exit 1; }
30+
fi
31+
32+
# Build trin-benchmark-coordinator with release profile
33+
pushd ../.. || { echo "Failed to change directory"; exit 1; }
34+
cargo build --release -p trin-bench || { echo "Failed to build trin-benchmark-coordinator"; exit 1; }
35+
popd || { echo "Failed to return to original directory"; exit 1; }
36+
37+
if [ "$PORTAL_CLIENT" == "trin" ]; then
38+
pushd ../.. || { echo "Failed to change directory"; exit 1; }
39+
cargo build --release -p trin || { echo "Failed to build trin"; exit 1; }
40+
popd || { echo "Failed to return to original directory"; exit 1; }
41+
fi
42+
43+
# Define process PIDs
44+
PIDS=()
45+
46+
# Find available ports dynamically and ensure they are unique
47+
find_unused_port() {
48+
local port=$1
49+
while ss -tuln | awk '{print $4}' | grep -q ":$port$"; do
50+
port=$((port + 1))
51+
done
52+
echo $port
53+
}
54+
55+
PORT_SENDER=$(find_unused_port 9050)
56+
PORT_RECEIVER=$(find_unused_port $((PORT_SENDER + 10)))
57+
EXT_PORT_SENDER=$(find_unused_port 9100)
58+
EXT_PORT_RECEIVER=$(find_unused_port $((EXT_PORT_SENDER + 10)))
59+
60+
# Check if perf flag is passed
61+
USE_PERF=false
62+
if [ "$1" == "perf" ]; then
63+
USE_PERF=true
64+
fi
65+
66+
run_trin() {
67+
local log_file="$1"
68+
local web3_address="$2"
69+
local external_address="$3"
70+
local discovery_port="$4"
71+
local data_dir="$5"
72+
local mb="$6"
73+
74+
if $USE_PERF; then
75+
cargo flamegraph --profile release -c "record -F 97 --call-graph dwarf,64000 -g -o $log_file.perf" --release --output "$log_file.svg" -p trin -- \
76+
--web3-transport http \
77+
--web3-http-address "$web3_address" \
78+
--mb "$mb" \
79+
--bootnodes none \
80+
--external-address "$external_address" \
81+
--discovery-port "$discovery_port" \
82+
--data-dir "$data_dir" \
83+
--max-radius 100 \
84+
> "$log_file.log" 2>&1 &
85+
else
86+
../../target/release/trin \
87+
--web3-transport http \
88+
--web3-http-address "$web3_address" \
89+
--mb "$mb" \
90+
--bootnodes none \
91+
--external-address "$external_address" \
92+
--discovery-port "$discovery_port" \
93+
--data-dir "$data_dir" \
94+
--max-radius 100 \
95+
> "$log_file.log" 2>&1 &
96+
fi
97+
PIDS+=("$!")
98+
}
99+
100+
if [ "$PORTAL_CLIENT" == "trin" ]; then
101+
# Run trin sender
102+
run_trin "$LOG_DIR/$DATA_DIR_SENDER" "http://127.0.0.1:$PORT_SENDER/" "127.0.0.1:$EXT_PORT_SENDER" "$EXT_PORT_SENDER" "$LOG_DIR/$DATA_DIR_SENDER" "0"
103+
104+
# Run trin receiver
105+
run_trin "$LOG_DIR/$DATA_DIR_RECEIVER" "http://127.0.0.1:$PORT_RECEIVER/" "127.0.0.1:$EXT_PORT_RECEIVER" "$EXT_PORT_RECEIVER" "$LOG_DIR/$DATA_DIR_RECEIVER" "10000"
106+
fi
107+
108+
# Run trin benchmark coordinator
109+
../../target/release/trin-bench \
110+
--web3-http-address-node-1 http://127.0.0.1:$PORT_SENDER/ \
111+
--web3-http-address-node-2 http://127.0.0.1:$PORT_RECEIVER/ \
112+
--epoch-accumulator-path ../../portal-accumulators \
113+
--start-era1 1000 \
114+
--end-era1 1010 \
115+
> "$LOG_DIR/trin_benchmark.log" 2>&1 &
116+
TRIN_BENCH_PID=$!
117+
118+
echo "Started Benchmark"
119+
120+
CLEANED_UP=false
121+
cleanup() {
122+
if $CLEANED_UP; then
123+
return
124+
fi
125+
CLEANED_UP=true
126+
echo "Finished benchmark. Stopping processes..."
127+
128+
for PID in "${PIDS[@]}"; do
129+
if kill -0 "$PID" 2>/dev/null; then
130+
echo "Killing process with PID $PID..."
131+
kill -SIGINT "$PID"
132+
pkill -SIGINT -P "$PID"
133+
fi
134+
done
135+
136+
for PID in "${PIDS[@]}"; do
137+
if kill -0 "$PID" 2>/dev/null; then
138+
echo "Waiting process with PID $PID..."
139+
wait "$PID" 2>/dev/null
140+
fi
141+
done
142+
143+
if kill -0 "$TRIN_BENCH_PID" 2>/dev/null; then
144+
echo "Stopping trin-bench with PID $TRIN_BENCH_PID..."
145+
kill -SIGINT "$TRIN_BENCH_PID"
146+
wait "$TRIN_BENCH_PID" 2>/dev/null
147+
fi
148+
149+
echo "All processes stopped."
150+
sudo rm -rf "$LOG_DIR/$DATA_DIR_SENDER" "$LOG_DIR/$DATA_DIR_RECEIVER" "$LOG_DIR/$DATA_DIR_SENDER.perf" "$LOG_DIR/$DATA_DIR_RECEIVER.perf"
151+
152+
# Generate timestamp-based folder name
153+
TIMESTAMP=$(date +%s)
154+
PERF_TAG=$([ "$USE_PERF" == true ] && echo "_perf" || echo "")
155+
RUN_FOLDER="$PAST_RUNS_DIR/${TIMESTAMP}_${PORTAL_CLIENT}${PERF_TAG}"
156+
mkdir -p "$RUN_FOLDER"
157+
158+
# Move logs and performance files to the archive folder
159+
find "$LOG_DIR" -maxdepth 1 -type f -name "*.log" -exec mv {} "$RUN_FOLDER/" \;
160+
find "$LOG_DIR" -maxdepth 1 -type f -name "*.svg" -exec mv {} "$RUN_FOLDER/" \;
161+
162+
echo "Archived logs to $RUN_FOLDER"
163+
}
164+
165+
trap cleanup SIGINT SIGTERM ERR
166+
wait "$TRIN_BENCH_PID"
167+
trap - SIGINT SIGTERM ERR
168+
cleanup

bin/trin-bench/src/cli.rs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
use std::path::PathBuf;
2+
3+
use clap::Parser;
4+
use url::Url;
5+
6+
pub const APP_NAME: &str = "trin-bench";
7+
const DEFAULT_EPOCH_ACC_PATH: &str = "./portal-accumulators";
8+
9+
#[derive(Parser, Debug, Clone)]
10+
#[command(
11+
name = "Trin Bench",
12+
about = "Benchmarks sending blocks from one trin client to another"
13+
)]
14+
pub struct TrinBenchConfig {
15+
#[arg(
16+
long = "web3-http-address-node-1",
17+
help = "address to accept json-rpc http connections"
18+
)]
19+
pub web3_http_address_node_1: Url,
20+
21+
#[arg(
22+
long = "web3-http-address-node-2",
23+
help = "address to accept json-rpc http connections"
24+
)]
25+
pub web3_http_address_node_2: Url,
26+
27+
#[arg(
28+
long,
29+
help = "The first era to start sending blocks from",
30+
default_value = "1"
31+
)]
32+
pub start_era1: u16,
33+
34+
#[arg(long, help = "The last era to send blocks from", default_value = "5")]
35+
pub end_era1: u16,
36+
37+
#[arg(
38+
long = "epoch-accumulator-path",
39+
help = "Path to epoch accumulator repo for bridge mode",
40+
default_value = DEFAULT_EPOCH_ACC_PATH
41+
)]
42+
pub epoch_acc_path: PathBuf,
43+
44+
#[arg(
45+
long,
46+
help = "The max amount of offer requests to have open at any given time",
47+
default_value = "10"
48+
)]
49+
pub offer_concurrency: usize,
50+
}

bin/trin-bench/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pub mod cli;

0 commit comments

Comments
 (0)