-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
176 lines (154 loc) · 5.77 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
import BenchmarkSection from '../components/BenchmarkSection';
import styles from '../styles/Home.module.css';
const filecoinRpcUrls = [
"https://rpc.ankr.com/filecoin",
"https://fil-mainnet-1.rpc.laconic.com/rpc/v1",
"https://filecoin.chainup.net/rpc/v1",
"https://api.node.glif.io",
"https://filfox.info/rpc/v1",
"https://filecoin.drpc.org"
];
const ethereumRpcUrls = [
"https://rpc.ankr.com/eth",
"https://1rpc.io/eth",
"https://public.stackup.sh/api/v1/node/ethereum-mainnet",
"https://ethereum.blockpi.network/v1/rpc/public",
"https://eth-pokt.nodies.app",
];
const rpcMethods = [
'eth_blockNumber',
'eth_getBlockByNumber',
'eth_getBlockByHash',
'eth_getBlockTransactionCountByNumber',
'eth_getBlockTransactionCountByHash',
'eth_getTransactionByHash',
'eth_getTransactionReceipt',
'eth_call',
'eth_getLogs',
'eth_getBalance',
'eth_gasPrice'
];
const methodParams = (latestBlockNumber, latestBlockHash, latestTransactionHash) => ({
'eth_blockNumber': [],
'eth_getBlockByNumber': [latestBlockNumber, true],
'eth_getBlockByHash': [latestBlockHash, true],
'eth_getBlockTransactionCountByNumber': [latestBlockNumber],
'eth_getBlockTransactionCountByHash': [latestBlockHash],
'eth_getTransactionByHash': [latestTransactionHash],
'eth_getTransactionReceipt': [latestTransactionHash],
'eth_call': [{ to: "0x7B90337f65fAA2B2B8ed583ba1Ba6EB0C9D7eA44", "data": "0x70a082310000000000000000000000007B90337f65fAA2B2B8ed583ba1Ba6EB0C9D7eA44" }, "latest"],
'eth_getLogs': [{ fromBlock: "latest", address: "0x0000000000000000000000000000000000000000" }],
'eth_getBalance': ["0x0000000000000000000000000000000000000000", "latest"],
'eth_gasPrice': []
});
const fetchLatestBlockInfo = async (rpcUrl) => {
const blockNumberResult = await benchmarkRpc(rpcUrl, 'eth_blockNumber', []);
if (blockNumberResult.error) throw new Error(blockNumberResult.errorMessage);
const latestBlockNumber = blockNumberResult.result;
const blockResult = await benchmarkRpc(rpcUrl, 'eth_getBlockByNumber', [latestBlockNumber, true]);
if (blockResult.error) throw new Error(blockResult.errorMessage);
const latestBlockHash = blockResult.result.hash;
const latestTransactionHash = blockResult.result.transactions.length > 0 ? blockResult.result.transactions[0].hash : null;
return { latestBlockNumber, latestBlockHash, latestTransactionHash };
};
const benchmarkRpc = async (rpcUrl, method, params) => {
const requestData = {
jsonrpc: '2.0',
method,
params,
id: 1
};
const startTime = performance.now();
try {
const response = await fetch(rpcUrl, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(requestData)
});
const endTime = performance.now();
const result = await response.json();
if (!response.ok) {
const errorMessage = result.error ? result.error.message : `HTTP error! status: ${response.status}`;
throw new Error(errorMessage);
}
if (result.error) {
throw new Error(result.error.message);
}
return { time: endTime - startTime, result: result.result, error: false, errorMessage: '' };
} catch (error) {
const endTime = performance.now();
return { time: endTime - startTime, error: true, errorMessage: `${error.message} (${(endTime - startTime).toFixed(2)} ms)` };
}
};
const fetchBenchmarkData = async (rpcUrls, rpcMethods) => {
const results = [];
for (const rpcUrl of rpcUrls) {
try {
const { latestBlockNumber, latestBlockHash, latestTransactionHash } = await fetchLatestBlockInfo(rpcUrl);
const params = methodParams(latestBlockNumber, latestBlockHash, latestTransactionHash);
const responses = [];
for (const method of rpcMethods) {
const param = params[method];
if (param.includes(null)) {
responses.push({
method,
time: 0,
error: true,
errorMessage: 'No transaction hash available'
});
} else {
const result = await benchmarkRpc(rpcUrl, method, param);
responses.push({ method, ...result });
}
}
results.push({ rpcUrl, responses });
} catch (error) {
results.push({
rpcUrl,
responses: rpcMethods.map(method => ({
method,
time: 0,
error: true,
errorMessage: error.message
}))
});
}
}
return results;
};
const Home = () => {
return (
<div className={styles.container}>
<div className={styles.decor}>
<h1 className={styles.title}>RPC Benchmark</h1>
<div className={styles.content}>
<p>
This application benchmarks various Ethereum JSON-RPC endpoints. It performs multiple tasks such as fetching block numbers, block details, transaction details, and more.
</p>
<p>
The results are displayed in a table where each row represents an RPC method and each column represents an RPC URL. Yellow cells indicate response times greater than 200 ms, while red cells indicate response times greater than 500 ms.
</p>
<p>
The summary rows at the bottom show the average and median response times for each RPC method across all URLs.
</p>
<p>
Source code available on <a href="https://github.com/snissn/benchmark-rpc" target="_blank" rel="noopener noreferrer">GitHub</a>.
</p>
</div>
</div>
<BenchmarkSection
title="Filecoin ETH RPC Benchmark"
rpcUrls={filecoinRpcUrls}
rpcMethods={rpcMethods}
fetchBenchmarkData={fetchBenchmarkData}
/>
<BenchmarkSection
title="Ethereum RPC Benchmark"
rpcUrls={ethereumRpcUrls}
rpcMethods={rpcMethods}
fetchBenchmarkData={fetchBenchmarkData}
/>
</div>
);
};
export default Home;