Skip to content

Commit 48f0e04

Browse files
authored
feat: add load-test payload worker for base-load-test integration (#171)
1 parent f62eef2 commit 48f0e04

12 files changed

Lines changed: 474 additions & 57 deletions

File tree

.github/workflows/_build-binaries.yaml

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ on:
1919
description: "Base Reth Node version to build"
2020
required: false
2121
type: string
22-
default: "main"
22+
default: "feature/load-test-benchmark"
2323

2424
# Set minimal permissions for all jobs by default
2525
permissions:
@@ -155,6 +155,8 @@ jobs:
155155

156156
- name: Set up Rust
157157
uses: actions-rust-lang/setup-rust-toolchain@9399c7bb15d4c7d47b27263d024f0a4978346ba4 # v1.11.0
158+
with:
159+
cache: false
158160

159161
- name: Cache base-reth-node binaries
160162
uses: actions/cache@2f8e54208210a422b2efd51efaa6bd6d7ca8920f # v3.4.3
@@ -163,9 +165,10 @@ jobs:
163165
path: |
164166
~/bin/base-reth-node
165167
~/bin/builder
166-
key: ${{ runner.os }}-base-reth-node-builder-${{ inputs.base_reth_node_version }}
168+
~/bin/base-load-test
169+
key: ${{ runner.os }}-base-reth-node-builder-load-test-${{ inputs.base_reth_node_version }}
167170

168-
- name: Build base-reth-node and base-builder
171+
- name: Build base-reth-node, base-builder, and base-load-test
169172
if: steps.cache-base-reth-node.outputs.cache-hit != 'true'
170173
run: |
171174
unset CI
@@ -188,6 +191,13 @@ jobs:
188191
path: ~/bin/builder
189192
retention-days: 1
190193

194+
- name: Upload base-load-test artifact
195+
uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0
196+
with:
197+
name: base-load-test
198+
path: ~/bin/base-load-test
199+
retention-days: 1
200+
191201
build-op-program:
192202
runs-on: ubuntu-latest
193203
permissions:

.github/workflows/examples.yaml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ jobs:
1818
with:
1919
optimism_version: 3019251e80aa248e91743addd3e833190acb26f1
2020
geth_version: 6cbfcd5161083bcd4052edc3022d9f99c6fe40e0
21-
base_reth_node_version: main
2221

2322
example-benchmarks:
2423
runs-on: ubuntu-latest

.github/workflows/load-test.yaml

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
name: Load Test
2+
3+
on:
4+
pull_request:
5+
workflow_dispatch:
6+
7+
concurrency:
8+
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
9+
cancel-in-progress: true
10+
11+
jobs:
12+
build-binaries:
13+
name: Build binaries
14+
uses: ./.github/workflows/_build-binaries.yaml
15+
16+
load-test:
17+
name: Run load test benchmark
18+
runs-on: ubuntu-latest
19+
needs: [build-binaries]
20+
steps:
21+
- name: Harden the runner (Audit all outbound calls)
22+
uses: step-security/harden-runner@002fdce3c6a235733a90a27c80493a3241e56863 # v2.12.1
23+
with:
24+
egress-policy: audit
25+
26+
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
27+
28+
- name: Set up Go
29+
uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0
30+
31+
- name: Download base-reth-node
32+
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
33+
with:
34+
name: base-reth-node
35+
path: ${{ runner.temp }}/bin/
36+
37+
- name: Download builder
38+
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
39+
with:
40+
name: builder
41+
path: ${{ runner.temp }}/bin/
42+
43+
- name: Download base-load-test
44+
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
45+
with:
46+
name: base-load-test
47+
path: ${{ runner.temp }}/bin/
48+
49+
- name: Make binaries executable
50+
run: chmod +x ${{ runner.temp }}/bin/*
51+
52+
- name: Run load test benchmark
53+
run: |
54+
mkdir -p ${{ runner.temp }}/data-dir
55+
mkdir -p ${{ runner.temp }}/output
56+
57+
go run benchmark/cmd/main.go \
58+
--log.level info \
59+
run \
60+
--config configs/examples/load-test.yml \
61+
--root-dir ${{ runner.temp }}/data-dir \
62+
--output-dir ${{ runner.temp }}/output \
63+
--builder-bin ${{ runner.temp }}/bin/builder \
64+
--base-reth-node-bin ${{ runner.temp }}/bin/base-reth-node \
65+
--load-test-bin ${{ runner.temp }}/bin/base-load-test
66+
67+
- name: Setup Node.js
68+
if: always()
69+
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
70+
with:
71+
node-version: "20"
72+
73+
- name: Build Report
74+
if: always()
75+
run: |
76+
cp -r ${{ runner.temp }}/output/ ./output/ || true
77+
pushd report
78+
npm install
79+
npm run build
80+
popd
81+
82+
- name: Upload Output
83+
if: always()
84+
uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0
85+
with:
86+
name: load-test-output
87+
path: ${{ runner.temp }}/output/
88+
retention-days: 7
89+
90+
- name: Upload Report
91+
if: always()
92+
uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0
93+
with:
94+
name: load-test-report
95+
path: report/dist/
96+
retention-days: 7

benchmark/flags/flags.go

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,22 +15,24 @@ func prefixEnvVars(name string) []string {
1515
}
1616

1717
const (
18-
ConfigFlagName = "config"
19-
RootDirFlagName = "root-dir"
20-
OutputDirFlagName = "output-dir"
21-
TxFuzzBinFlagName = "tx-fuzz-bin"
22-
ProxyPortFlagName = "proxy-port"
23-
BenchmarkRunIDFlagName = "benchmark-run-id"
24-
MachineTypeFlagName = "machine-type"
25-
MachineProviderFlagName = "machine-provider"
26-
MachineRegionFlagName = "machine-region"
27-
FileSystemFlagName = "file-system"
18+
ConfigFlagName = "config"
19+
RootDirFlagName = "root-dir"
20+
OutputDirFlagName = "output-dir"
21+
TxFuzzBinFlagName = "tx-fuzz-bin"
22+
LoadTestBinFlagName = "load-test-bin"
23+
ProxyPortFlagName = "proxy-port"
24+
BenchmarkRunIDFlagName = "benchmark-run-id"
25+
MachineTypeFlagName = "machine-type"
26+
MachineProviderFlagName = "machine-provider"
27+
MachineRegionFlagName = "machine-region"
28+
FileSystemFlagName = "file-system"
2829
ParallelTxBatchesFlagName = "parallel-tx-batches"
2930
)
3031

3132
// TxFuzz defaults
3233
const (
33-
DefaultTxFuzzBin = "../tx-fuzz/cmd/livefuzzer/livefuzzer"
34+
DefaultTxFuzzBin = "../tx-fuzz/cmd/livefuzzer/livefuzzer"
35+
DefaultLoadTestBin = "./base-load-test"
3436
)
3537

3638
var (
@@ -62,6 +64,13 @@ var (
6264
EnvVars: opservice.PrefixEnvVar(EnvVarPrefix, "TX_FUZZ_BIN"),
6365
}
6466

67+
LoadTestBinFlag = &cli.StringFlag{
68+
Name: LoadTestBinFlagName,
69+
Usage: "Load test binary path",
70+
Value: DefaultLoadTestBin,
71+
EnvVars: opservice.PrefixEnvVar(EnvVarPrefix, "LOAD_TEST_BIN"),
72+
}
73+
6574
ProxyPortFlag = &cli.IntFlag{
6675
Name: "proxy-port",
6776
Usage: "Proxy port",
@@ -116,6 +125,7 @@ var RunFlags = []cli.Flag{
116125
RootDirFlag,
117126
OutputDirFlag,
118127
TxFuzzBinFlag,
128+
LoadTestBinFlag,
119129
ProxyPortFlag,
120130
BenchmarkRunIDFlag,
121131
MachineTypeFlag,

clients/build-base-reth-node.sh

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,13 @@ fi
4040

4141
# Checkout specified version/commit
4242
echo "Checking out version: $BASE_RETH_NODE_VERSION"
43-
git checkout -f "$BASE_RETH_NODE_VERSION"
43+
git fetch origin "$BASE_RETH_NODE_VERSION" || true
44+
git checkout -f "$BASE_RETH_NODE_VERSION" || git checkout -f "origin/$BASE_RETH_NODE_VERSION"
4445

4546
# Build the binaries using cargo
46-
echo "Building base-reth-node and base-builder with cargo..."
47-
# Build with maxperf profile
47+
echo "Building base-reth-node, base-builder, and base-load-test with cargo..."
4848
cargo build --bin base-reth-node --bin base-builder --profile maxperf
49+
cargo build -p base-load-tests --bin base-load-test --profile maxperf
4950

5051
# Copy binaries to output directory
5152
echo "Copying binaries to output directory..."
@@ -74,4 +75,11 @@ else
7475
exit 1
7576
fi
7677

77-
echo "base-reth-node and base-builder binaries built successfully and placed in $FINAL_OUTPUT_DIR/"
78+
if [ -f "target/maxperf/base-load-test" ]; then
79+
cp target/maxperf/base-load-test "$FINAL_OUTPUT_DIR/"
80+
else
81+
echo "No base-load-test binary found"
82+
exit 1
83+
fi
84+
85+
echo "Binaries built successfully and placed in $FINAL_OUTPUT_DIR/"

clients/versions.env

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ GETH_VERSION="v1.101604.0"
1212

1313
# Base Reth Node Configuration
1414
BASE_RETH_NODE_REPO="https://github.com/base/base"
15-
BASE_RETH_NODE_VERSION="main"
15+
BASE_RETH_NODE_VERSION="feature/load-test-benchmark"
1616

1717
# Build Configuration
1818
# BUILD_DIR="./build"

configs/examples/load-test.yml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
name: Load test throughput test
2+
description: Test builder throughput using base-load-test binary as transaction generator
3+
payloads:
4+
- name: Load Test
5+
type: load-test
6+
id: load-test
7+
sender_count: 10
8+
transactions:
9+
- weight: 70
10+
type: transfer
11+
- weight: 20
12+
type: calldata
13+
max_size: 256
14+
- weight: 10
15+
type: precompile
16+
target: sha256
17+
18+
benchmarks:
19+
- variables:
20+
- type: payload
21+
value: load-test
22+
- type: node_type
23+
value: builder
24+
- type: validator_node_type
25+
value: base-reth-node
26+
- type: num_blocks
27+
value: 10
28+
- type: gas_limit
29+
value: 1000000000

runner/clients/common/proxy/proxy.go

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ import (
2222
"github.com/ethereum/go-ethereum/common"
2323
ethTypes "github.com/ethereum/go-ethereum/core/types"
2424
"github.com/ethereum/go-ethereum/log"
25-
"github.com/ethereum/go-ethereum/rlp"
2625
)
2726

2827
type ProxyServer struct {
@@ -196,11 +195,13 @@ func (p *ProxyServer) OverrideRequest(method string, rawParams json.RawMessage)
196195
return false, nil, fmt.Errorf("failed to decode hex: %w", err)
197196
}
198197

199-
err = rlp.DecodeBytes(rawTxBytes, &tx)
198+
// Use UnmarshalBinary to support both legacy and typed (EIP-2718) transactions.
199+
// The previous rlp.DecodeBytes only handled legacy transactions.
200+
err = tx.UnmarshalBinary(rawTxBytes)
200201

201202
if err != nil {
202-
p.log.Error("failed to decode RLP", "err", err)
203-
return false, nil, fmt.Errorf("failed to decode RLP: %w", err)
203+
p.log.Error("failed to decode transaction", "err", err)
204+
return false, nil, fmt.Errorf("failed to decode transaction: %w", err)
204205
}
205206

206207
p.pendingTxs = append(p.pendingTxs, &tx)
@@ -217,21 +218,21 @@ func (p *ProxyServer) DebugResponse(method string, params json.RawMessage, respB
217218
p.log.Debug("method", "method", method)
218219
p.log.Debug("params", "params", params)
219220

220-
// Try gzip decompression; fall back to raw body if the response is plain JSON.
221221
gzipReader, err := gzip.NewReader(bytes.NewReader(respBody))
222222
if err != nil {
223-
p.log.Debug("Response body", "body", string(respBody))
223+
p.log.Error("Error creating gzip reader", "err", err)
224224
return
225225
}
226226
defer func() {
227227
if err := gzipReader.Close(); err != nil {
228-
p.log.Debug("Error closing gzip reader", "err", err)
228+
p.log.Error("Error closing gzip reader", "err", err)
229229
}
230230
}()
231231

232232
uncompressedBody, err := io.ReadAll(gzipReader)
233+
233234
if err != nil {
234-
p.log.Debug("Error reading uncompressed response body", "err", err)
235+
p.log.Error("Error reading uncompressed response body", "err", err)
235236
return
236237
}
237238
p.log.Debug("Uncompressed body", "body", string(uncompressedBody))

0 commit comments

Comments
 (0)