Skip to content

Commit 8ac1ef4

Browse files
author
David Himmelstrup
authored
Merge branch 'main' into lemmih/metrics-docs
2 parents 8852001 + 4341111 commit 8ac1ef4

File tree

26 files changed

+1380
-344
lines changed

26 files changed

+1380
-344
lines changed

.github/workflows/js-lint.yml

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
name: JS linters
2+
3+
# Cancel workflow if there is a new change to the branch.
4+
concurrency:
5+
group: ${{ github.workflow }}-${{ github.ref }}
6+
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
7+
8+
on:
9+
merge_group:
10+
pull_request:
11+
branches:
12+
- main
13+
push:
14+
branches:
15+
- main
16+
paths:
17+
- 'benchmarks/**'
18+
19+
jobs:
20+
run-js-linters:
21+
runs-on: ubuntu-latest
22+
steps:
23+
- uses: actions/checkout@v4
24+
- uses: actions/setup-node@v4
25+
with:
26+
node-version: "18"
27+
- run: |
28+
cd benchmarks/
29+
corepack enable
30+
yarn install --immutable
31+
yarn js-lint
32+
yarn js-fmt-check

.gitignore

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,6 @@ web_modules/
189189
.yarn-integrity
190190

191191
# dotenv environment variable files
192-
.env
193192
.env.development.local
194193
.env.test.local
195194
.env.production.local
@@ -389,4 +388,4 @@ rust-project.json
389388

390389
# End of https://www.toptal.com/developers/gitignore/api/go,rust,rust-analyzer,osx,visualstudiocode,intellij+all,yarn,node,ruby
391390

392-
lychee-report.md
391+
lychee-report.md

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131

3232
### Changed
3333

34+
- [#5452](https://github.com/ChainSafe/forest/pull/5452) Speed up void database migration.
35+
3436
### Removed
3537

3638
- [#5449](https://github.com/ChainSafe/forest/pull/5449) Remove unnecessary/duplicate metrics.
@@ -39,6 +41,8 @@
3941

4042
### Fixed
4143

44+
- [#5458](https://github.com/ChainSafe/forest/pull/5458) Fix stack overflow occurring when running Forest in debug mode.
45+
4246
## Forest v0.25.0 "Bombadil"
4347

4448
This is a mandatory release for calibnet node operators. It includes the revised NV25 _Teep_ network upgrade at epoch `2_523_454` which corresponds to `2025-03-26T23:00:00Z`. This release also includes a number of new RPC methods, fixes and other improvements. Be sure to check the breaking changes before upgrading.

benchmarks/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
.yarn
2+
node_modules

benchmarks/Makefile

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
all-forest-cloud:
2+
k6 cloud run -e K6_TEST_URL=http://localhost:2345/rpc/v1 --local-execution tests/all.js
3+
4+
all-lotus-cloud:
5+
k6 cloud run -e K6_TEST_URL=http://localhost:1234/rpc/v1 --local-execution tests/all.js
6+
7+
all-forest-local:
8+
k6 run -e K6_TEST_URL=http://localhost:2345/rpc/v1 tests/all.js
9+
10+
all-lotus-local:
11+
k6 run -e K6_TEST_URL=http://localhost:1234/rpc/v1 tests/all.js
12+
13+
.PHONY: all-forest-cloud all-lotus-cloud all-forest-local all-lotus-local

benchmarks/README.md

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# K6 benchmarking for Filecoin JSON-RPC
2+
3+
Implementation-agnostic benchmark for RPC
4+
5+
## Requirements
6+
7+
This benchmarking suite requires [k6](https://grafana.com/docs/k6/latest/) installed on the host. Follow the instructions for your operating system. Alternatively, you can run them via Docker.
8+
9+
## Local benchmarks
10+
11+
You can run the benchmarks fully locally. To do so, you will need a running Filecoin node; ensure it's synced.
12+
13+
Sample benchmark run:
14+
15+
```bash
16+
k6 run -e K6_TEST_URL=http://localhost:2345/rpc/v1 tests/all.js --duration 30s --vus 20
17+
```
18+
19+
## Upload benchmarks to Grafana Cloud
20+
21+
You can create a free account on Grafana Cloud (the free tier should suffice if you run the tests locally). Login with `k6 cloud login --token <token>`. Now, you can run the benchmarks locally but have them uploaded to your Grafana Cloud for visual inspection and comparisons.
22+
23+
```bash
24+
k6 cloud run -e K6_TEST_URL=http://localhost:2345/rpc/v1 --local-execution tests/top5.js
25+
```
26+
27+
## Configuring benchmarks
28+
29+
Read about [k6 options](https://grafana.com/docs/k6/latest/using-k6/k6-options/).
30+
31+
## Environment variables
32+
33+
| Name | Description | Type | Default |
34+
| --------------- | --------------------------- | ---- | ------------------------------ |
35+
| `K6_TEST_URL` | Node RPC endpoint | URL | `http://localhost:2345/rpc/v1` |
36+
| `K6_TEST_DEBUG` | Print additional debug info | bool | false |
37+
38+
## Pitfalls
39+
40+
- Don't run the benchmarks in a environment with shared CPU, e.g., on a VPS. The results will vary depending on the load on that CPU.
41+
- Don't run the node in a virtualized environment, e.g., Docker for Mac. Use a native build.
42+
- Ensure your test parameters match your hardware. Ensure your machine is not saturated, e.g., `k6` itself using most of the resources and leaving the node with too little CPU/RAM. If need be, run the test on separate machines. `k6` and the node could also be limited, e.g., via Docker.
43+
44+
## Potential improvements
45+
46+
- [ ] include more methods
47+
- [ ] rewrite in TypeScript
48+
- [ ] visualize results locally

benchmarks/eslint.config.mjs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { defineConfig } from "eslint/config";
2+
import globals from "globals";
3+
import js from "@eslint/js";
4+
5+
6+
export default defineConfig([
7+
{ files: ["**/*.{js,mjs,cjs}"] },
8+
{ files: ["**/*.{js,mjs,cjs}"], languageOptions: { globals: globals.browser } },
9+
{ files: ["**/*.{js,mjs,cjs}"], plugins: { js }, extends: ["js/recommended"] },
10+
11+
// Those don't play well with `k6`
12+
{ files: ["**/*.{js,mjs,cjs}"], rules: { "no-unused-vars": "off" } },
13+
{ files: ["**/*.{js,mjs,cjs}"], rules: { "no-undef": "off" } },
14+
]);

benchmarks/methods/index.js

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
//
2+
// The methods here are defined with sample parameters. They are meant to be used on the mainnet and might not work on other networks.
3+
// Also, some of the parameters might stop working at some point. More refinement is needed to make them more robust.
4+
//
5+
6+
export const filecoinChainHead = {
7+
name: "Filecoin.ChainHead",
8+
params: [],
9+
};
10+
11+
export const filecoinStateMinerPower = {
12+
name: "Filecoin.StateMinerPower",
13+
params: ["t01000", []],
14+
};
15+
16+
export const filecoinStateMinerInfo = {
17+
name: "Filecoin.StateMinerInfo",
18+
params: ["t01000", []],
19+
};
20+
21+
export const filecoinStateMarketStorageDeal = {
22+
name: "Filecoin.StateMarketStorageDeal",
23+
params: [109704581, []],
24+
};
25+
26+
export const ethChainId = {
27+
name: "eth_chainId",
28+
params: [],
29+
};
30+
31+
export const ethCall = {
32+
name: "eth_call",
33+
params: [
34+
{
35+
data: "0xf8b2cb4f000000000000000000000000cbff24ded1ce6b53712078759233ac8f91ea71b6",
36+
from: null,
37+
gas: "0x0",
38+
gasPrice: "0x0",
39+
to: "0x0c1d86d34e469770339b53613f3a2343accd62cb",
40+
value: "0x0",
41+
},
42+
"latest",
43+
],
44+
};
45+
46+
export const ethGasPrice = {
47+
name: "eth_gasPrice",
48+
params: [],
49+
};
50+
51+
export const ethGetBalance = {
52+
name: "eth_getBalance",
53+
params: ["0x6743938A48fC8799A5608EF079C53f3cF3B84398", "latest"],
54+
};
55+
56+
//
57+
// Groupings of methods. Either arbitrary or based on data shared by RPC providers.
58+
//
59+
60+
// All methods we have implemented in test scripts so far.
61+
export const allMethods = [
62+
filecoinChainHead,
63+
filecoinStateMinerPower,
64+
filecoinStateMinerInfo,
65+
filecoinStateMarketStorageDeal,
66+
ethChainId,
67+
ethCall,
68+
ethGasPrice,
69+
ethGetBalance,
70+
];
71+
72+
// The top 5 methods according to Hubert's metal die roll.
73+
export const top5Methods = [
74+
filecoinChainHead,
75+
ethCall,
76+
ethChainId,
77+
ethGetBalance,
78+
// should be `ChainNotify`, but it's a subscription method, so it's tricky to test
79+
filecoinStateMinerPower,
80+
];

benchmarks/package.json

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"name": "k6-forest",
3+
"version": "1.0.0",
4+
"scripts": {
5+
"js-lint": "eslint '**/*.js'",
6+
"js-fmt": "prettier --write '**/*.js'",
7+
"js-fmt-check": "prettier --check '**/*.js'"
8+
},
9+
"keywords": [],
10+
"author": "",
11+
"license": "MIT",
12+
"description": "",
13+
"devDependencies": {
14+
"@eslint/js": "^9.22.0",
15+
"@types/k6": "^0.57.1",
16+
"eslint": "^9.22.0",
17+
"globals": "^16.0.0",
18+
"prettier": "^3.5.3"
19+
},
20+
"packageManager": "yarn@4.7.0"
21+
}

benchmarks/tests/all.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import http from "k6/http";
2+
3+
import { allMethods } from "../methods/index.js";
4+
import { sendRpcRequest, assertSuccess } from "../utils/rpc.js";
5+
import { regularBenchmarkParams } from "../utils/benchmark_params.js";
6+
7+
const url = __ENV.K6_TEST_URL || "http://localhost:2345/rpc/v1";
8+
9+
export let options = regularBenchmarkParams;
10+
11+
// the function that will be executed for each VU (virtual user)
12+
export default function () {
13+
for (const method of allMethods) {
14+
const response = sendRpcRequest(url, method);
15+
assertSuccess(response);
16+
}
17+
}

0 commit comments

Comments
 (0)