Compare commits
3387 Commits
harmony-va
...
jules_wip_
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d03c00f9a9 | ||
|
|
f9ea6d118c | ||
|
|
318c4d26f5 | ||
|
|
ef273ee331 | ||
|
|
e4f6ca8ee7 | ||
|
|
7cf79509e3 | ||
|
|
6d46471536 | ||
|
|
779a2e76f9 | ||
|
|
c5710c33b1 | ||
|
|
97cf8fd6fa | ||
|
|
57cfa421b4 | ||
|
|
b70e0f4afb | ||
|
|
dea6cf315e | ||
|
|
c08a43eb02 | ||
|
|
3b43c15074 | ||
|
|
596dba9ad9 | ||
|
|
73f70555d2 | ||
|
|
0c06f20666 | ||
|
|
431b159146 | ||
|
|
d78f41e521 | ||
|
|
23bf18eb83 | ||
|
|
b22dfd6d10 | ||
|
|
46c320ef52 | ||
|
|
2daa7560de | ||
|
|
90e8af4644 | ||
|
|
f6161e575d | ||
|
|
1c14c8a861 | ||
|
|
5a557f574f | ||
|
|
36cc615903 | ||
|
|
6055d17a4d | ||
|
|
f18cd800dc | ||
|
|
e136521e26 | ||
|
|
04fdcaccfe | ||
|
|
0ab7a45d64 | ||
|
|
07871d8efc | ||
|
|
f2b91ac1c0 | ||
|
|
e2218f499c | ||
|
|
a048e4c292 | ||
|
|
8a74e4e149 | ||
|
|
19b079da16 | ||
|
|
355f538d8b | ||
|
|
1856f17848 | ||
|
|
5688b0b8c4 | ||
|
|
1ceeae7bea | ||
|
|
ce41dc7fb3 | ||
|
|
cc8c1a3c81 | ||
|
|
a70284eec1 | ||
|
|
edb6e7518b | ||
|
|
b71851d43f | ||
|
|
39323d19eb | ||
|
|
1feac516b4 | ||
|
|
3d10d7b32b | ||
|
|
2706436d16 | ||
|
|
03735aeed6 | ||
|
|
5aeb68cfb6 | ||
|
|
78b0f0669d | ||
|
|
0cfacad7e6 | ||
|
|
a7be4c90d6 | ||
|
|
15a2cd6ac0 | ||
|
|
1575dadaca | ||
|
|
af80ad8d74 | ||
|
|
e29ea29547 | ||
|
|
25b2310699 | ||
|
|
d246befaea | ||
|
|
b82fb47f00 | ||
|
|
6d0a5d9d6d | ||
|
|
b0fc62b701 | ||
|
|
87e9ba6b9e | ||
|
|
5cc07f93a7 | ||
|
|
edf8d469fb | ||
|
|
9e634508c7 | ||
|
|
1495a49144 | ||
|
|
dd662dfdd0 | ||
|
|
c8ae2e4f91 | ||
|
|
61d95baef9 | ||
|
|
958432e343 | ||
|
|
0f5d7e9651 | ||
|
|
2a987f64a2 | ||
|
|
2d8c58f13e | ||
|
|
5978ad47da | ||
|
|
af15054bf5 | ||
|
|
58a3233ffd | ||
|
|
ff729a2f44 | ||
|
|
a600aabfab | ||
|
|
16e30d2b48 | ||
|
|
84bf18d6e4 | ||
|
|
e57fdad3fe | ||
|
|
860921b712 | ||
|
|
6c7ceaab90 | ||
|
|
5135a30790 | ||
|
|
5492883a2c | ||
|
|
4f7fe9a256 | ||
|
|
bbd93c0ffb | ||
|
|
295135dc8d | ||
|
|
6173215cdc | ||
|
|
0edd43dc56 | ||
|
|
aa79b3128d | ||
|
|
a8354bebbe | ||
|
|
a1eedd6d01 | ||
|
|
72876114c3 | ||
|
|
7ee7456752 | ||
|
|
27576f3cb4 | ||
|
|
b9fb679727 | ||
|
|
e97864a989 | ||
|
|
f51ad3db00 | ||
|
|
f073412959 | ||
|
|
bc12f3d42c | ||
|
|
1dc50366cb | ||
|
|
86ae0c4545 | ||
|
|
29a55e7e6f | ||
|
|
7661d8c7db | ||
|
|
a6bd111ce6 | ||
|
|
16090503d4 | ||
|
|
2a13b59aae | ||
|
|
85a5862f90 | ||
|
|
8b6133287e | ||
|
|
c648d1304a | ||
|
|
62fde28752 | ||
|
|
c5671b50c3 | ||
|
|
5a04784b1c | ||
|
|
39e3b4a9d6 | ||
|
|
fb964d86a1 | ||
|
|
2eda458a23 | ||
|
|
747e8077a0 | ||
|
|
4baf955ce2 | ||
|
|
9c32719987 | ||
|
|
59e1608b67 | ||
|
|
b13e48e897 | ||
|
|
5a38f4960b | ||
|
|
646def7d2b | ||
|
|
84e66e2697 | ||
|
|
b21f82fc17 | ||
|
|
017f5e9bec | ||
|
|
228fb63f02 | ||
|
|
1818ead761 | ||
|
|
6a9ab07495 | ||
|
|
cd6ad78d11 | ||
|
|
b2f6d8ef45 | ||
|
|
22a7b3ea1b | ||
|
|
88140231ce | ||
|
|
ca84033a14 | ||
|
|
9afe08dff2 | ||
|
|
6e477bd5f0 | ||
|
|
5a1c0bf495 | ||
|
|
70d727d7ad | ||
|
|
6f0e5ac218 | ||
|
|
aa2b598b32 | ||
|
|
3587d82931 | ||
|
|
0d902eb69b | ||
|
|
af0c8cd7e2 | ||
|
|
98abb33fc8 | ||
|
|
f2855d3a2c | ||
|
|
44461bffcd | ||
|
|
d5598f5446 | ||
|
|
07bbfb22cc | ||
|
|
ddf85ee8f9 | ||
|
|
22ce16f065 | ||
|
|
bfccfdbadc | ||
|
|
8c654c70d1 | ||
|
|
f43859c298 | ||
|
|
0396014baf | ||
|
|
cd0adc475b | ||
|
|
eb5197aca3 | ||
|
|
b69db72c80 | ||
|
|
34c1c62a7d | ||
|
|
4a4dfbda1d | ||
|
|
648db38954 | ||
|
|
1b489f5a94 | ||
|
|
c9188fa6c7 | ||
|
|
f92b61c228 | ||
|
|
3d98079a2a | ||
|
|
c83ed6d7d3 | ||
|
|
0b139fed3d | ||
|
|
1ba136a4f8 | ||
|
|
8e2243616b | ||
|
|
3fbde2d791 | ||
|
|
781e6535b6 | ||
|
|
85ee5afd87 | ||
|
|
be54827b7d | ||
|
|
30ae1caff4 | ||
|
|
4eedfa81e0 | ||
|
|
12c72587e6 | ||
|
|
88c9eb7a2c | ||
|
|
b3893280b8 | ||
|
|
4718d739a8 | ||
|
|
211bd2684b | ||
|
|
b56880f5a2 | ||
|
|
d6350bfde1 | ||
|
|
ea255de1cd | ||
|
|
f2b642c20d | ||
|
|
25502ae1a1 | ||
|
|
ae1cbd0493 | ||
|
|
83ce10ec3d | ||
|
|
232748632a | ||
|
|
f171abb333 | ||
|
|
4722460091 | ||
|
|
f15132a8d1 | ||
|
|
4d199f81bb | ||
|
|
104f2d8e1c | ||
|
|
b930803d21 | ||
|
|
362f6bd577 | ||
|
|
fca23f8205 | ||
|
|
1241776349 | ||
|
|
a6d574c9a9 | ||
|
|
d28181236c | ||
|
|
94bc176586 | ||
|
|
002b2fa99c | ||
|
|
1f13edad78 | ||
|
|
fd2abeb162 | ||
|
|
079aefb865 | ||
|
|
639d8b60c8 | ||
|
|
8c104531b4 | ||
|
|
8ff330d38b | ||
|
|
06faa1d9f4 | ||
|
|
740dbd59de | ||
|
|
e8b5cce384 | ||
|
|
4ffde02488 | ||
|
|
e61b97ff4e | ||
|
|
9d22af0d73 | ||
|
|
7c66e91f2c | ||
|
|
f23b099659 | ||
|
|
15f9691b37 | ||
|
|
3b90a9bbde | ||
|
|
8b1cb957d1 | ||
|
|
fe505dd239 | ||
|
|
7086278d67 | ||
|
|
ba1f06506d | ||
|
|
c7d8a6e534 | ||
|
|
e618db0aea | ||
|
|
9650e2f978 | ||
|
|
41027d8aa3 | ||
|
|
071eff21ee | ||
|
|
e109dc0e35 | ||
|
|
ef725c1768 | ||
|
|
2684dec118 | ||
|
|
191fd11d93 | ||
|
|
0a6c5e9fb5 | ||
|
|
7c28a5d536 | ||
|
|
7a82a4dbf4 | ||
|
|
5af24a34af | ||
|
|
9ba491ab8b | ||
|
|
e7657a133c | ||
|
|
088f42cb11 | ||
|
|
125452c7d4 | ||
|
|
153abf5805 | ||
|
|
5c63c62859 | ||
|
|
cbfe770a1a | ||
|
|
12579f612f | ||
|
|
1d16a45496 | ||
|
|
fa05b914a6 | ||
|
|
ab10340dca | ||
|
|
d18aa9ca72 | ||
|
|
dca2a0ef60 | ||
|
|
d69a8cb0de | ||
|
|
a44ea07293 | ||
|
|
d935624364 | ||
|
|
5a080c522c | ||
|
|
1eb8a58fb2 | ||
|
|
4331a5ac4a | ||
|
|
bfd8392e41 | ||
|
|
ca59cb50eb | ||
|
|
c3d5534520 | ||
|
|
ba2103d7c0 | ||
|
|
9f3710ddaa | ||
|
|
4b17d54280 | ||
|
|
b12409b2f6 | ||
|
|
90e26f3523 | ||
|
|
33d0bfe2c3 | ||
|
|
1d85c22974 | ||
|
|
ed2cf87989 | ||
|
|
cca3d8e7e1 | ||
|
|
037a01b7c2 | ||
|
|
08b27a4a3b | ||
|
|
e1985a117f | ||
|
|
a1fc35b87f | ||
|
|
938bf33053 | ||
|
|
9c40ab7451 | ||
|
|
339af89892 | ||
|
|
b6f5c17a9f | ||
|
|
5524999d55 | ||
|
|
053b1aa97b | ||
|
|
4ed74e9c75 | ||
|
|
f7b7934dd1 | ||
|
|
8a74589cfb | ||
|
|
04c5e41ae9 | ||
|
|
762011a809 | ||
|
|
93baaace61 | ||
|
|
c7259dad75 | ||
|
|
1ded879d2d | ||
|
|
a379057318 | ||
|
|
e6529fcb7c | ||
|
|
d960ca7acd | ||
|
|
e44909c46d | ||
|
|
12fd383dd8 | ||
|
|
2cbe0c3986 | ||
|
|
88deee2125 | ||
|
|
fa1876de72 | ||
|
|
056e59248d | ||
|
|
0dd9af2905 | ||
|
|
eae44c31e7 | ||
|
|
ef5ce7fa1d | ||
|
|
8f598d464c | ||
|
|
2da52e423b | ||
|
|
37c16701f2 | ||
|
|
54d3e75710 | ||
|
|
c4b032577e | ||
|
|
a1f3fd7109 | ||
|
|
221a0629e0 | ||
|
|
e4d3bfb019 | ||
|
|
04145934f2 | ||
|
|
0fe081bbce | ||
|
|
d38e7b675e | ||
|
|
821d75d3ea | ||
|
|
87bc69108c | ||
|
|
4f12b8d0ed | ||
|
|
efa0a7c56d | ||
|
|
98eb25f7b5 | ||
|
|
464ba456b8 | ||
|
|
a3bacf5347 | ||
|
|
3f06f3f1b1 | ||
|
|
6a0823a64d | ||
|
|
4e8f6dbe58 | ||
|
|
81d3d0bf41 | ||
|
|
f7acaa9c85 | ||
|
|
3303bd1d6d | ||
|
|
8ff2f5a2ba | ||
|
|
066af74c86 | ||
|
|
15baa3183a | ||
|
|
0605685825 | ||
|
|
2116f29f2b | ||
|
|
78148783c8 | ||
|
|
45ea204eea | ||
|
|
3fbd7432e6 | ||
|
|
40ecc82a94 | ||
|
|
3167e1e80d | ||
|
|
e6c7869c83 | ||
|
|
8ade443259 | ||
|
|
064199f312 | ||
|
|
809d2857a6 | ||
|
|
9193cf91ab | ||
|
|
d4ddf5bd52 | ||
|
|
9f1450597f | ||
|
|
3d12f51a75 | ||
|
|
bc6f08e6d9 | ||
|
|
58e992ba1d | ||
|
|
35840e9cce | ||
|
|
1813c7f354 | ||
|
|
cc47c8a543 | ||
|
|
b65b02ad75 | ||
|
|
21fabe3e68 | ||
|
|
55659ed6f0 | ||
|
|
4206a48d04 | ||
|
|
92caabd3a9 | ||
|
|
9d016c8c9e | ||
|
|
355f1d32ed | ||
|
|
9bd49dd1d2 | ||
|
|
73e144a92a | ||
|
|
08ae2bc826 | ||
|
|
fdca7f7762 | ||
|
|
1b7a44e4d5 | ||
|
|
333a21b528 | ||
|
|
e5ef332e0e | ||
|
|
d6c1eb0211 | ||
|
|
2c4a031c2b | ||
|
|
2e2842bd83 | ||
|
|
77963a6021 | ||
|
|
40cd48af0d | ||
|
|
1b93862b79 | ||
|
|
c898f72e71 | ||
|
|
4206e6ee66 | ||
|
|
e1b256de74 | ||
|
|
3177bc5a0b | ||
|
|
55f544fc92 | ||
|
|
ce7f425339 | ||
|
|
3d3b59e13a | ||
|
|
7102146c1d | ||
|
|
9334c6c9e9 | ||
|
|
47eb68d99a | ||
|
|
6e6390f8be | ||
|
|
62d44aa62c | ||
|
|
c2230b8f33 | ||
|
|
8ea3f5b7d5 | ||
|
|
22180bcf2d | ||
|
|
81b368c9ed | ||
|
|
03fa670d1a | ||
|
|
18c410d6ac | ||
|
|
10367e06fb | ||
|
|
0359d06d65 | ||
|
|
c0379e2994 | ||
|
|
19cc4caa89 | ||
|
|
d6fa540b64 | ||
|
|
31c48eaf3c | ||
|
|
697265c2b0 | ||
|
|
a248b01e9e | ||
|
|
e9b473bddc | ||
|
|
7cf48f7061 | ||
|
|
eef099ef47 | ||
|
|
7029b7392d | ||
|
|
0a69a6bb44 | ||
|
|
77e71635c6 | ||
|
|
6e321ca221 | ||
|
|
e439ade5ab | ||
|
|
1948c22eba | ||
|
|
95d64d3d9c | ||
|
|
b3b73b2cad | ||
|
|
73c76e28b3 | ||
|
|
45da1d7bda | ||
|
|
3aeefd6fa5 | ||
|
|
86641804a7 | ||
|
|
7bfcc128c4 | ||
|
|
e26ff24d4a | ||
|
|
bf1c587253 | ||
|
|
c36b14229e | ||
|
|
2a3f74bd0d | ||
|
|
f5de048804 | ||
|
|
058517a20d | ||
|
|
80d2faa98f | ||
|
|
96d9081230 | ||
|
|
f99b715f77 | ||
|
|
61a583441a | ||
|
|
4a71b12a2c | ||
|
|
e1649ab259 | ||
|
|
f9245415fd | ||
|
|
9719ceb420 | ||
|
|
dcc2cb9b65 | ||
|
|
8f1ecf48ae | ||
|
|
3decde68d7 | ||
|
|
a90397b2e9 | ||
|
|
8fb39d33fb | ||
|
|
ab919e76ef | ||
|
|
b7c7080167 | ||
|
|
1f974f0b85 | ||
|
|
b2e3fe185f | ||
|
|
165aeb6866 | ||
|
|
d1b3f02248 | ||
|
|
91bb9d55da | ||
|
|
7358814ebd | ||
|
|
3a1406bc55 | ||
|
|
2aa0a2d5a8 | ||
|
|
8bd6cde31f | ||
|
|
869b14fc38 | ||
|
|
d2ad1f1428 | ||
|
|
40f6648de1 | ||
|
|
4db3ef3562 | ||
|
|
144d3c3650 | ||
|
|
6b9d512003 | ||
|
|
a2db3cefdb | ||
|
|
73a2a804da | ||
|
|
02caf42380 | ||
|
|
876de679ae | ||
|
|
5790c21c32 | ||
|
|
6c54fdb6bd | ||
|
|
ef812230f3 | ||
|
|
7d55b39c3a | ||
|
|
f9cdd75cf8 | ||
|
|
61764ef61e | ||
|
|
2659865064 | ||
|
|
52a49b45c4 | ||
|
|
1351a225b6 | ||
|
|
dd4725930e | ||
|
|
24191ba4f0 | ||
|
|
6080bb144b | ||
|
|
02cf2b32b1 | ||
|
|
e98fc0072a | ||
|
|
1c5b0c2f0f | ||
|
|
f5c4c0507a | ||
|
|
3568b58816 | ||
|
|
a907c000d3 | ||
|
|
dc758a8c7d | ||
|
|
537d7406a3 | ||
|
|
81c04e3f23 | ||
|
|
21c50072c3 | ||
|
|
49a2d601c5 | ||
|
|
a524b0b7cd | ||
|
|
56e165ebfb | ||
|
|
f1bcd0aef2 | ||
|
|
a2679d1d0b | ||
|
|
aa7ebb8454 | ||
|
|
7bc2c6857e | ||
|
|
23fa663cdd | ||
|
|
7d6ceb74d8 | ||
|
|
1829f2394e | ||
|
|
fa2c706daa | ||
|
|
cd75b35ce7 | ||
|
|
38ba497057 | ||
|
|
7e2ea8baaf | ||
|
|
de873b0a60 | ||
|
|
310b48b1fb | ||
|
|
2f046b49dd | ||
|
|
b653ad153c | ||
|
|
6db2d5df50 | ||
|
|
fda35b3792 | ||
|
|
8d0cbfc483 | ||
|
|
96f33135b1 | ||
|
|
8ba07ac2cf | ||
|
|
a919bcdbbc | ||
|
|
ca7dceae80 | ||
|
|
85e2ef4c3f | ||
|
|
a74d493743 | ||
|
|
42c9ebc55f | ||
|
|
64619a5037 | ||
|
|
3354f15bef | ||
|
|
cfd1031962 | ||
|
|
e259c428bd | ||
|
|
ad3f353c8b | ||
|
|
2a86ab6270 | ||
|
|
76618c9c31 | ||
|
|
d71084ce32 | ||
|
|
8240f4ca74 | ||
|
|
e94d9f80e6 | ||
|
|
ddec133f2a | ||
|
|
d842d0101d | ||
|
|
3517530076 | ||
|
|
43500c2405 | ||
|
|
bb687505de | ||
|
|
23499ad176 | ||
|
|
dff30fed8b | ||
|
|
6df1ca59d5 | ||
|
|
4b14f4b589 | ||
|
|
a3739d0d6b | ||
|
|
65ab9eec06 | ||
|
|
ccbb06dc05 | ||
|
|
790d6807f5 | ||
|
|
0b673534c5 | ||
|
|
358e014ad7 | ||
|
|
a6279455cd | ||
|
|
e422b415d0 | ||
|
|
5dc086ddeb | ||
|
|
0533c3c905 | ||
|
|
09d8656e33 | ||
|
|
912cc9388b | ||
|
|
6b0036ef5d | ||
|
|
592e1ba957 | ||
|
|
5a9f310e13 | ||
|
|
4384e527c7 | ||
|
|
d782c70c75 | ||
|
|
3df500c911 | ||
|
|
e04c199ca4 | ||
|
|
c7eef48e07 | ||
|
|
7c4220f2b5 | ||
|
|
c4ae3e8850 | ||
|
|
2e45eade58 | ||
|
|
fba5ba7a1d | ||
|
|
b12c5fd113 | ||
|
|
a665373b50 | ||
|
|
5bbe1a5565 | ||
|
|
412e130d46 | ||
|
|
5bcd9f5469 | ||
|
|
c78a336884 | ||
|
|
d54ae62ab1 | ||
|
|
e3781d0b36 | ||
|
|
447882395e | ||
|
|
39bbbd6494 | ||
|
|
9f62aa2d2f | ||
|
|
59b2f0f24d | ||
|
|
1a2e99ddc3 | ||
|
|
b6c60eea6b | ||
|
|
6c21f202fa | ||
|
|
18b1ddcfc3 | ||
|
|
11641209d0 | ||
|
|
6a5815bc5b | ||
|
|
cb77ca59de | ||
|
|
9f02efc4a3 | ||
|
|
b6418a495a | ||
|
|
fccfbd6515 | ||
|
|
9930a53f6d | ||
|
|
fbf8d20f62 | ||
|
|
596324a554 | ||
|
|
160761f632 | ||
|
|
889d64c1c0 | ||
|
|
09d6593e85 | ||
|
|
1b40e92de2 | ||
|
|
360b4effb8 | ||
|
|
a549aadb5b | ||
|
|
4001b9ab79 | ||
|
|
aa86d6fcd2 | ||
|
|
beed4d2637 | ||
|
|
7e2206ae18 | ||
|
|
c241595dfd | ||
|
|
b3c69ea511 | ||
|
|
d837b89d4a | ||
|
|
14625b13a7 | ||
|
|
360a37e673 | ||
|
|
52b2227df1 | ||
|
|
6220b2bc24 | ||
|
|
8a0e84a90f | ||
|
|
ce28c61601 | ||
|
|
bb1b5105cd | ||
|
|
a300c5be58 | ||
|
|
2f3319cd11 | ||
|
|
738a34f786 | ||
|
|
e8f8f8b0b2 | ||
|
|
4cd47f1d04 | ||
|
|
81a6e765d4 | ||
|
|
75cf385648 | ||
|
|
c812ac1dea | ||
|
|
b857dd7068 | ||
|
|
d315bef269 | ||
|
|
a4560ca392 | ||
|
|
613a536432 | ||
|
|
9afff9d756 | ||
|
|
8c3647c887 | ||
|
|
edda4f89f4 | ||
|
|
fa8e38da57 | ||
|
|
fdd9ae8bca | ||
|
|
e92198da88 | ||
|
|
187144f72d | ||
|
|
d2f95ab832 | ||
|
|
2c4a591d38 | ||
|
|
d5cc45bb24 | ||
|
|
428938f5b2 | ||
|
|
785983ee7e | ||
|
|
a5d3b5d213 | ||
|
|
3fa5cc4900 | ||
|
|
6b8108b470 | ||
|
|
5b87c35356 | ||
|
|
1529bf3bfc | ||
|
|
2869855f04 | ||
|
|
4c0dda7425 | ||
|
|
5eacd839e8 | ||
|
|
cb350ce446 | ||
|
|
4616a4b0bf | ||
|
|
31b33d533a | ||
|
|
6070b6ec4c | ||
|
|
6abcf9a126 | ||
|
|
e4296a117c | ||
|
|
00997f8bc0 | ||
|
|
0f89b5ddf6 | ||
|
|
20e9d26d44 | ||
|
|
5ce47e35dd | ||
|
|
e2f9b2f634 | ||
|
|
57434f06a6 | ||
|
|
d2ec1b1d23 | ||
|
|
673e4cd0a5 | ||
|
|
9fa87ecc59 | ||
|
|
b8e9114c8a | ||
|
|
2bd682d0d6 | ||
|
|
3bd4679c52 | ||
|
|
1d937a07ab | ||
|
|
fcdb322d2f | ||
|
|
abd303aba8 | ||
|
|
71df3fee70 | ||
|
|
eeb94ff99a | ||
|
|
4e7f1ce6ca | ||
|
|
c8e765d134 | ||
|
|
ba6eb35830 | ||
|
|
dd8b92ddc6 | ||
|
|
42a8ed5761 | ||
|
|
6283e3fa1a | ||
|
|
6ec304e4d6 | ||
|
|
15b5008c6c | ||
|
|
71382469cb | ||
|
|
bf76ae4efe | ||
|
|
57a2dae63e | ||
|
|
0122689aaf | ||
|
|
5c89c5ab65 | ||
|
|
48729847a4 | ||
|
|
acafbe4406 | ||
|
|
32ebc7ca2b | ||
|
|
e4c9778db7 | ||
|
|
21acc360b4 | ||
|
|
fec5a956cd | ||
|
|
24f12d7b94 | ||
|
|
0a1c490e87 | ||
|
|
86e08f54a9 | ||
|
|
f7502178eb | ||
|
|
7b187639b1 | ||
|
|
cd673e89e2 | ||
|
|
1a68c43f79 | ||
|
|
a8ac15094c | ||
|
|
74161fdf89 | ||
|
|
2a5def2334 | ||
|
|
5da176d58a | ||
|
|
7c34e72fe1 | ||
|
|
021f8bddf6 | ||
|
|
8f4feae8ef | ||
|
|
22ca91a61e | ||
|
|
ecc9a7f709 | ||
|
|
5947402c38 | ||
|
|
8a04e82516 | ||
|
|
846385627c | ||
|
|
fbf0fef203 | ||
|
|
150e721d9f | ||
|
|
1f913f7505 | ||
|
|
021a6ebc83 | ||
|
|
661b6c1315 | ||
|
|
5a0915d68c | ||
|
|
6ba821f721 | ||
|
|
afdadf8f8b | ||
|
|
1600e04fef | ||
|
|
4c7560053d | ||
|
|
69454c7e27 | ||
|
|
9804628c8b | ||
|
|
d69d91e46f | ||
|
|
fd6991a6ab | ||
|
|
04f23897b4 | ||
|
|
95c74c917d | ||
|
|
098991a688 | ||
|
|
55ce0f9653 | ||
|
|
04d13fa4ea | ||
|
|
bf867d6b1a | ||
|
|
0dad48e9bd | ||
|
|
6d1f2ff816 | ||
|
|
8b16461f83 | ||
|
|
bede49b624 | ||
|
|
91f4c21573 | ||
|
|
c33a1acd5f | ||
|
|
8da8e5af3c | ||
|
|
6751e15468 | ||
|
|
ddfb8ad99d | ||
|
|
ffc62a3130 | ||
|
|
052125a4bf | ||
|
|
a6dc64aff8 | ||
|
|
de39ebe07f | ||
|
|
f33a72b6ff | ||
|
|
1306b400cf | ||
|
|
ca692fbdd9 | ||
|
|
674e559d5a | ||
|
|
398a9a916f | ||
|
|
0f4bb6a7ea | ||
|
|
37a484af18 | ||
|
|
81dbfa8a1c | ||
|
|
c1ae806ef0 | ||
|
|
d6fc0261ab | ||
|
|
9829b7427b | ||
|
|
a862f5fc10 | ||
|
|
c6e2708689 | ||
|
|
fa0b08a6cb | ||
|
|
e0ea45a5e5 | ||
|
|
da8fcd51bd | ||
|
|
fc3808716b | ||
|
|
d6e7ac9ab8 | ||
|
|
298e6b9636 | ||
|
|
afcefe4c6f | ||
|
|
f533d6bba6 | ||
|
|
1e25c4f52a | ||
|
|
67e5aeb77d | ||
|
|
4cc066551a | ||
|
|
d3517085fa | ||
|
|
c64a90d92e | ||
|
|
f39a5763d6 | ||
|
|
5038b0f721 | ||
|
|
177455c2ed | ||
|
|
fe6048e1aa | ||
|
|
7e37f1d012 | ||
|
|
77fe6e0c60 | ||
|
|
4d431ad75d | ||
|
|
bf98fd35ff | ||
|
|
86e4ed49f2 | ||
|
|
13b3db2327 | ||
|
|
acde267881 | ||
|
|
eb2e27ca54 | ||
|
|
6eb96a4531 | ||
|
|
a4ba04b1d1 | ||
|
|
d8e634a725 | ||
|
|
df4b44b838 | ||
|
|
42feb2166a | ||
|
|
f1c791685c | ||
|
|
f4745d7484 | ||
|
|
231009dade | ||
|
|
85ed047d60 | ||
|
|
f1c2ee776d | ||
|
|
1ff6e59982 | ||
|
|
549390fe06 | ||
|
|
b95cd28983 | ||
|
|
20081d0d53 | ||
|
|
5bcfcdab1a | ||
|
|
5c49ea6fca | ||
|
|
108e37fd6d | ||
|
|
339a09c1b8 | ||
|
|
60aaf6b194 | ||
|
|
19d631fdc6 | ||
|
|
74db467697 | ||
|
|
50fd75c33e | ||
|
|
e80a076f71 | ||
|
|
0c52bbd9d0 | ||
|
|
c3e4e91c1b | ||
|
|
feacfbfc29 | ||
|
|
75b3720a17 | ||
|
|
6895fae601 | ||
|
|
04e1fc542c | ||
|
|
436d82f759 | ||
|
|
6326cca752 | ||
|
|
1476e2032f | ||
|
|
2b82a11bcf | ||
|
|
3ca021b6c8 | ||
|
|
ab83982bf3 | ||
|
|
5aa26694b2 | ||
|
|
47e3ddad12 | ||
|
|
48ad1fa0d5 | ||
|
|
97384d28db | ||
|
|
d767ea905d | ||
|
|
934cbbd16d | ||
|
|
1661c82394 | ||
|
|
a077068316 | ||
|
|
c991c5a333 | ||
|
|
62c7af241a | ||
|
|
3f9e0ff860 | ||
|
|
286941154d | ||
|
|
54b50584f4 | ||
|
|
8fcedfeddf | ||
|
|
e00ef5b0c3 | ||
|
|
8f62df644f | ||
|
|
9699235a63 | ||
|
|
16c89b550b | ||
|
|
d7755a1519 | ||
|
|
117ecfd7c1 | ||
|
|
877edb5bb1 | ||
|
|
8175d9e1de | ||
|
|
f1e4953ace | ||
|
|
7aaa67d886 | ||
|
|
82a3c4b5e1 | ||
|
|
2d5989d4fc | ||
|
|
7459c22470 | ||
|
|
a2dab10c4f | ||
|
|
34f6c45146 | ||
|
|
f7795d916c | ||
|
|
b10e94a8d6 | ||
|
|
b955f5f1bf | ||
|
|
072beff0e4 | ||
|
|
475fdc5bb6 | ||
|
|
1a8bd4aeb5 | ||
|
|
681c8390b3 | ||
|
|
c44b27e4ea | ||
|
|
67445fffe2 | ||
|
|
e05d094ea0 | ||
|
|
a1c80e521c | ||
|
|
9e4c34922b | ||
|
|
7e168203d3 | ||
|
|
a5f1736211 | ||
|
|
e9c866d85b | ||
|
|
e8ce9793e2 | ||
|
|
13d7cf8fd3 | ||
|
|
5ab6790148 | ||
|
|
ed6ed26de4 | ||
|
|
2f2e0547f5 | ||
|
|
b20a8c119a | ||
|
|
ce1db6ccec | ||
|
|
fb850fc53d | ||
|
|
0dc6cb2088 | ||
|
|
16811b0629 | ||
|
|
03dba4352e | ||
|
|
6b61a3ed9b | ||
|
|
5c8aad323e | ||
|
|
e28442f146 | ||
|
|
7cb7a8c04e | ||
|
|
c9b9598f1c | ||
|
|
778a41982c | ||
|
|
78ef14f92f | ||
|
|
22b5237d49 | ||
|
|
d714869c57 | ||
|
|
3f74d2c880 | ||
|
|
1ae26e3b39 | ||
|
|
7dbadfcee8 | ||
|
|
27065430bc | ||
|
|
a52bf9ff7b | ||
|
|
0459b4a0c5 | ||
|
|
71a8d9b66b | ||
|
|
daa5b43c12 | ||
|
|
cdc7bd301f | ||
|
|
93c074c216 | ||
|
|
b6c1823ccf | ||
|
|
3dc980afd9 | ||
|
|
370f73e2fc | ||
|
|
5fc967bc14 | ||
|
|
bf21b8d301 | ||
|
|
972d31f892 | ||
|
|
3b51820e95 | ||
|
|
526879337f | ||
|
|
4b54a6b074 | ||
|
|
8ba371176d | ||
|
|
9dfff441e2 | ||
|
|
e86636a52f | ||
|
|
c1565e2adf | ||
|
|
538c48e61d | ||
|
|
ce86a91f21 | ||
|
|
9b0f1dfc77 | ||
|
|
de5c886808 | ||
|
|
f59838c36d | ||
|
|
ecd591ada3 | ||
|
|
7183070ed4 | ||
|
|
425e7266f2 | ||
|
|
5af4c7c904 | ||
|
|
67e12023a0 | ||
|
|
575a33f6a9 | ||
|
|
b2319be6cc | ||
|
|
eb1c955705 | ||
|
|
a6c94940df | ||
|
|
870d099f0d | ||
|
|
873c11f09d | ||
|
|
352dd07e26 | ||
|
|
8fffa07a64 | ||
|
|
7f6a7d2030 | ||
|
|
b83f8a9780 | ||
|
|
e31302fc4c | ||
|
|
c73acf342a | ||
|
|
4704817f65 | ||
|
|
868a84443f | ||
|
|
4e9b032d42 | ||
|
|
36c7178bb6 | ||
|
|
7748ce0cd8 | ||
|
|
a9a293ce7b | ||
|
|
d0b7e1edd7 | ||
|
|
01d4c85fdc | ||
|
|
6323da5d0e | ||
|
|
26e70a4238 | ||
|
|
bcd7b26ef4 | ||
|
|
8ef9d90959 | ||
|
|
a58f520072 | ||
|
|
54ae0a397b | ||
|
|
3f4f6256ba | ||
|
|
68ed55b321 | ||
|
|
8db2c30d72 | ||
|
|
29b522ab3a | ||
|
|
217ea08c4b | ||
|
|
656bef202d | ||
|
|
3c3b84f729 | ||
|
|
482bc07e7e | ||
|
|
3b064da000 | ||
|
|
211b4526d9 | ||
|
|
f0032665e3 | ||
|
|
d189b8d1d0 | ||
|
|
118b6a5a0e | ||
|
|
8468327236 | ||
|
|
b70ed9b791 | ||
|
|
5f76152f33 | ||
|
|
b5083c71d9 | ||
|
|
1056feab7e | ||
|
|
b6d3e39df6 | ||
|
|
3265446bd9 | ||
|
|
1b9860885b | ||
|
|
2eee8e9c47 | ||
|
|
f2af5b3254 | ||
|
|
939d22ecb0 | ||
|
|
5970d0f953 | ||
|
|
9e41f705a1 | ||
|
|
a5983f9cb9 | ||
|
|
a5d3afe086 | ||
|
|
3b8e27149d | ||
|
|
37729e1110 | ||
|
|
c0df43119d | ||
|
|
eb23591f5b | ||
|
|
1f941ca26c | ||
|
|
68a3179e6c | ||
|
|
de597f9985 | ||
|
|
b8ce5f1319 | ||
|
|
cdb36e8b82 | ||
|
|
a6ea97e2d1 | ||
|
|
95ae8c109d | ||
|
|
8954702640 | ||
|
|
97604b92b8 | ||
|
|
57eecf611f | ||
|
|
71f1930023 | ||
|
|
9049a88672 | ||
|
|
b4cd75587e | ||
|
|
81888e7f1d | ||
|
|
38f0db07b5 | ||
|
|
df80758e55 | ||
|
|
77e24c9401 | ||
|
|
3b7a425edd | ||
|
|
0e85af9526 | ||
|
|
271d9041ce | ||
|
|
e5824ffcea | ||
|
|
33c57189f4 | ||
|
|
7acdb81fff | ||
|
|
c72b36e523 | ||
|
|
d91779dd3c | ||
|
|
eb8d6f2acf | ||
|
|
dbf8f690bf | ||
|
|
a22e11f355 | ||
|
|
fbd4f822f1 | ||
|
|
3dd35a500e | ||
|
|
663f90b6d1 | ||
|
|
769525d3f5 | ||
|
|
8ea5fac889 | ||
|
|
1b9cca5a7c | ||
|
|
2165a688b9 | ||
|
|
557337206b | ||
|
|
15c7d5daa9 | ||
|
|
552ad8c83c | ||
|
|
2d3452c97e | ||
|
|
03347cea73 | ||
|
|
8c0119ee99 | ||
|
|
ab684cdf14 | ||
|
|
8d5afcb191 | ||
|
|
7a90ef6427 | ||
|
|
6b08ee0ae8 | ||
|
|
6699a7bd92 | ||
|
|
a736583d3c | ||
|
|
d60630178e | ||
|
|
37b3e49b15 | ||
|
|
64dd0ab387 | ||
|
|
8fc0e6ab9b | ||
|
|
3f329001ff | ||
|
|
09f2cc01d3 | ||
|
|
cfdc71f001 | ||
|
|
6b56d96ba5 | ||
|
|
8afc132b68 | ||
|
|
8b9e26a8c6 | ||
|
|
003bcc7e7b | ||
|
|
d9c65cb01a | ||
|
|
907c90297d | ||
|
|
a412965c27 | ||
|
|
42835e3e2c | ||
|
|
abdfab5d95 | ||
|
|
aca2301a2c | ||
|
|
0c4c456610 | ||
|
|
3b4f46da64 | ||
|
|
fbd00a2314 | ||
|
|
a3c6df3a7b | ||
|
|
75005e0c2c | ||
|
|
a1df3cd1bc | ||
|
|
0188c40405 | ||
|
|
5e66c3f215 | ||
|
|
28d7e8894c | ||
|
|
9de26aab82 | ||
|
|
c64022bd8b | ||
|
|
ba4e65c06a | ||
|
|
035706fa12 | ||
|
|
aa5e92a5df | ||
|
|
56d8cba406 | ||
|
|
cc4d8fafe8 | ||
|
|
5c864d34bd | ||
|
|
1f085da99f | ||
|
|
ba97af0a0f | ||
|
|
9c7c057300 | ||
|
|
fcfb960215 | ||
|
|
975442bcc0 | ||
|
|
453c1bc9c2 | ||
|
|
9960f6144a | ||
|
|
1ff954ca5e | ||
|
|
6b32697954 | ||
|
|
9c0e2ad482 | ||
|
|
52b4629f1a | ||
|
|
c46767b0a6 | ||
|
|
46d3918a6b | ||
|
|
4c56c42bb0 | ||
|
|
b9fd88cdcb | ||
|
|
92730d49a7 | ||
|
|
8a3ba3d1b3 | ||
|
|
68ba9d07fd | ||
|
|
eb696ccd39 | ||
|
|
2d4e870b53 | ||
|
|
11efd1bc38 | ||
|
|
6bbba05710 | ||
|
|
48efc4fc65 | ||
|
|
e4484b1712 | ||
|
|
97f0148e42 | ||
|
|
2832ca186a | ||
|
|
1ef4598ca0 | ||
|
|
e50dc2deee | ||
|
|
c139630997 | ||
|
|
d887840138 | ||
|
|
70036ec47b | ||
|
|
97c3396af0 | ||
|
|
525879052a | ||
|
|
693959699c | ||
|
|
5e20ed40ca | ||
|
|
65e17d8009 | ||
|
|
9a07aafabb | ||
|
|
a98d858591 | ||
|
|
2f731d6828 | ||
|
|
5449adc8f8 | ||
|
|
2c3afa42cd | ||
|
|
0e6287cd95 | ||
|
|
979e0d3a8d | ||
|
|
87bbb1f003 | ||
|
|
7790dc1daa | ||
|
|
74d5fb09af | ||
|
|
8af40dba2b | ||
|
|
4807aa4a0f | ||
|
|
e8a5eb4bbf | ||
|
|
1cfcd14b20 | ||
|
|
48558da40a | ||
|
|
78fb3dc32f | ||
|
|
86ec93ce53 | ||
|
|
dadca852fd | ||
|
|
527a8760cb | ||
|
|
f07a57f4b3 | ||
|
|
b3bb447baa | ||
|
|
5f52d93478 | ||
|
|
5159490e75 | ||
|
|
1ac9afbd19 | ||
|
|
22f9372a83 | ||
|
|
86b1007e05 | ||
|
|
2eaa8f99e4 | ||
|
|
228d527af3 | ||
|
|
57f5091dcd | ||
|
|
dd8c5f6aa5 | ||
|
|
fa4a9a43bd | ||
|
|
a1b3d48f1f | ||
|
|
4e17308d86 | ||
|
|
910d32c05d | ||
|
|
a0c850fb3b | ||
|
|
0f52619c36 | ||
|
|
62b049b2e1 | ||
|
|
247d64bed5 | ||
|
|
bb94e499e5 | ||
|
|
dc1f1183ab | ||
|
|
6072a158d2 | ||
|
|
429993aee7 | ||
|
|
b8e56c770e | ||
|
|
13cd30d24b | ||
|
|
242e2804b8 | ||
|
|
bc8ef71083 | ||
|
|
e7cf69dd9d | ||
|
|
c025dac861 | ||
|
|
d9521aac6b | ||
|
|
4ae0790ce6 | ||
|
|
7d0f71ef48 | ||
|
|
33b50a34b2 | ||
|
|
6278827e52 | ||
|
|
8cda78738e | ||
|
|
38997477ca | ||
|
|
55edc8efcf | ||
|
|
7e905ba31e | ||
|
|
fe910a6bbe | ||
|
|
52238722a3 | ||
|
|
442d3a463e | ||
|
|
f7c36e18c9 | ||
|
|
24252922ee | ||
|
|
bf437081df | ||
|
|
7117a1102b | ||
|
|
7dcebb7a8e | ||
|
|
232dd8698e | ||
|
|
31dcc6fdd0 | ||
|
|
6f64867a27 | ||
|
|
9427ddf511 | ||
|
|
767129bb16 | ||
|
|
c9ac737987 | ||
|
|
5226085db4 | ||
|
|
5433c9a8cd | ||
|
|
27b2fb4b44 | ||
|
|
297eaf6860 | ||
|
|
0f08614981 | ||
|
|
15f59e61c4 | ||
|
|
a71e239cf8 | ||
|
|
08da99d3c7 | ||
|
|
b5b375e983 | ||
|
|
209af925bd | ||
|
|
347795ea5c | ||
|
|
fff0810a36 | ||
|
|
45c1bdf475 | ||
|
|
e564e13631 | ||
|
|
517f44d8e1 | ||
|
|
33975e7a6e | ||
|
|
ce91a0e350 | ||
|
|
bfee6a7653 | ||
|
|
45bf4723f8 | ||
|
|
2badd3463b | ||
|
|
36047f8b70 | ||
|
|
ded4785699 | ||
|
|
2397fbcb78 | ||
|
|
12f5895284 | ||
|
|
cc5a644d7e | ||
|
|
519d11a607 | ||
|
|
a05561d01f | ||
|
|
161a14934c | ||
|
|
02dff8aa69 | ||
|
|
76d4382462 | ||
|
|
217f139f38 | ||
|
|
e3ed2c6f09 | ||
|
|
1ccb674599 | ||
|
|
e1744657a4 | ||
|
|
0cbe9e4656 | ||
|
|
9ceece41c5 | ||
|
|
d6801912e7 | ||
|
|
ff61dd22dc | ||
|
|
c5c6942151 | ||
|
|
f79919776b | ||
|
|
6277c1ad1c | ||
|
|
4fb24d8d0d | ||
|
|
7bcabb9ffd | ||
|
|
110a31e52b | ||
|
|
4c6bf353ae | ||
|
|
8656b63553 | ||
|
|
487aca2851 | ||
|
|
f708f65cfc | ||
|
|
05f6f36eb4 | ||
|
|
4d23b18a16 | ||
|
|
1c373bc8bc | ||
|
|
6173017749 | ||
|
|
2af51f57d5 | ||
|
|
a95bbd1345 | ||
|
|
21f06357b6 | ||
|
|
d39739f8ad | ||
|
|
8e0a995b36 | ||
|
|
ca4423065a | ||
|
|
62188450c1 | ||
|
|
70c765ae34 | ||
|
|
ada3984c2f | ||
|
|
066c10713e | ||
|
|
2c7311c970 | ||
|
|
b07e7499c7 | ||
|
|
c7cad346c8 | ||
|
|
7c648002fe | ||
|
|
d2a49a88c6 | ||
|
|
2a838c99fe | ||
|
|
507cf0370e | ||
|
|
4f268fe59a | ||
|
|
227c1d83cd | ||
|
|
6c4da93d15 | ||
|
|
2a9d504fa9 | ||
|
|
fc809a95c7 | ||
|
|
363b2a444f | ||
|
|
35a7169a72 | ||
|
|
2782ab84e0 | ||
|
|
e7cd7ef208 | ||
|
|
2be3932f3d | ||
|
|
75a73652df | ||
|
|
e4b652c13b | ||
|
|
a62971623f | ||
|
|
b1cd72c194 | ||
|
|
5a445fb562 | ||
|
|
3b78a06496 | ||
|
|
16c2da133d | ||
|
|
845c4c85d8 | ||
|
|
fe404c0bcb | ||
|
|
2434eb63f1 | ||
|
|
b8be36373b | ||
|
|
ee263139a0 | ||
|
|
c3c306cb6e | ||
|
|
c0aebe0d86 | ||
|
|
966cc2a620 | ||
|
|
ea8aed4d96 | ||
|
|
6d0d874b69 | ||
|
|
208db1b64f | ||
|
|
8d273928c9 | ||
|
|
c5bf946201 | ||
|
|
e8e3476b10 | ||
|
|
6b6f3482f1 | ||
|
|
5de61a1082 | ||
|
|
2f826806c2 | ||
|
|
7c8ffd3347 | ||
|
|
6526a10ea0 | ||
|
|
75aae4a826 | ||
|
|
be024a7625 | ||
|
|
c0f077d531 | ||
|
|
a782ec3d7e | ||
|
|
c40a0b2b4a | ||
|
|
dece12e555 | ||
|
|
54a0d4e5f6 | ||
|
|
d0cf554463 | ||
|
|
67dcdbe57f | ||
|
|
6f1c6c5bce | ||
|
|
78554cb066 | ||
|
|
e3fdb3fab6 | ||
|
|
0cebb54c00 | ||
|
|
b9a6178238 | ||
|
|
35e241e0ce | ||
|
|
81d57c75e4 | ||
|
|
059ec0fee5 | ||
|
|
0659f70f5d | ||
|
|
890610a510 | ||
|
|
ce77d4202b | ||
|
|
7040a86f30 | ||
|
|
0461aa4943 | ||
|
|
a543cdf5f3 | ||
|
|
8232798521 | ||
|
|
8f7fd7f0a4 | ||
|
|
186d855bc1 | ||
|
|
18c879b224 | ||
|
|
abf39a84c4 | ||
|
|
546acbbc35 | ||
|
|
39a3dc4c0e | ||
|
|
9d069638ff | ||
|
|
034a53f563 | ||
|
|
fd50ee4b30 | ||
|
|
9d35619362 | ||
|
|
4c075d6749 | ||
|
|
0a87672269 | ||
|
|
4a11ba6bf4 | ||
|
|
9af2fbfb14 | ||
|
|
fb469e00b1 | ||
|
|
041bc7760c | ||
|
|
42466c6e91 | ||
|
|
f20bc90b24 | ||
|
|
e496c64f6a | ||
|
|
342a390704 | ||
|
|
86f870fe91 | ||
|
|
73e72904d3 | ||
|
|
1b0f87d565 | ||
|
|
04062f675a | ||
|
|
1b7ddcbb50 | ||
|
|
9d491cbc9e | ||
|
|
cf5ef9b5ca | ||
|
|
144644fc26 | ||
|
|
c24c890227 | ||
|
|
116e0c5584 | ||
|
|
4922d40c4a | ||
|
|
e656142601 | ||
|
|
5a12c6a61d | ||
|
|
1f0b59a538 | ||
|
|
4744ad38d3 | ||
|
|
8c69893c8a | ||
|
|
58fe579555 | ||
|
|
f621a0c152 | ||
|
|
d192edfe50 | ||
|
|
8a13d4abb1 | ||
|
|
f99b0bf172 | ||
|
|
99028e4c42 | ||
|
|
ebec3de353 | ||
|
|
12b2732ddf | ||
|
|
c82b5819c3 | ||
|
|
694abee654 | ||
|
|
3324ae5d7f | ||
|
|
498705a5a8 | ||
|
|
07c2a00a37 | ||
|
|
740311896c | ||
|
|
c8aafee5f1 | ||
|
|
d8a10e6c82 | ||
|
|
74e85c0698 | ||
|
|
78bab70a05 | ||
|
|
a4b01ba358 | ||
|
|
95c48c3d6f | ||
|
|
2b6b6fd107 | ||
|
|
1af7f87567 | ||
|
|
b8db21b3d4 | ||
|
|
37d5a5caea | ||
|
|
4033f1c09d | ||
|
|
b937a8a8ad | ||
|
|
e5d1027763 | ||
|
|
68460dfe4f | ||
|
|
18754a0c8f | ||
|
|
b2a86290c6 | ||
|
|
8d04a393f4 | ||
|
|
ec00eb49c2 | ||
|
|
6117123c4a | ||
|
|
f3ed6f2a1c | ||
|
|
737a271e26 | ||
|
|
7f6af4cd5e | ||
|
|
bc74fd1414 | ||
|
|
3c5c76382f | ||
|
|
dc4710ef18 | ||
|
|
3c7d537898 | ||
|
|
603349518a | ||
|
|
166575953e | ||
|
|
3aa725102a | ||
|
|
249cffdee7 | ||
|
|
bb95f8adce | ||
|
|
2ee9222251 | ||
|
|
8776b382e7 | ||
|
|
421e8e6052 | ||
|
|
449606eb1d | ||
|
|
915ae99711 | ||
|
|
27bea18931 | ||
|
|
ae23308523 | ||
|
|
ba36be78d8 | ||
|
|
c2c0cb5a2f | ||
|
|
e38d778899 | ||
|
|
10c0063295 | ||
|
|
ba91e8c024 | ||
|
|
fa2153dd4a | ||
|
|
39ad0d25b5 | ||
|
|
c3198d4b3c | ||
|
|
eaea6796b7 | ||
|
|
eaf29a931a | ||
|
|
699a454bbd | ||
|
|
1420117854 | ||
|
|
cd490b43ee | ||
|
|
9dd87cc73c | ||
|
|
4a07c61cfa | ||
|
|
5ac00a77b3 | ||
|
|
5169fe0751 | ||
|
|
d3ccc28d2c | ||
|
|
92fb5d3c2a | ||
|
|
f7451b6d2c | ||
|
|
0c82ef1f83 | ||
|
|
ca2c3861a1 | ||
|
|
e7bc0a56f0 | ||
|
|
d78e615869 | ||
|
|
8a0657669d | ||
|
|
4f3d904594 | ||
|
|
2d97c54741 | ||
|
|
90a4d3ce55 | ||
|
|
658e64a67b | ||
|
|
3ad79dced3 | ||
|
|
df7c4b12af | ||
|
|
f788e75947 | ||
|
|
31941a7446 | ||
|
|
05c87006ac | ||
|
|
7291c047ad | ||
|
|
e0887aff53 | ||
|
|
592e317e82 | ||
|
|
bb0fb37fd7 | ||
|
|
a81c05cd5d | ||
|
|
0c955dbeb1 | ||
|
|
d85e5bdc96 | ||
|
|
7db695a94b | ||
|
|
bbaeff524e | ||
|
|
15453f264c | ||
|
|
e77335f84f | ||
|
|
72cf47d0f1 | ||
|
|
4b1012c0e0 | ||
|
|
0dfe49484f | ||
|
|
2d7b84544b | ||
|
|
00dbee6696 | ||
|
|
08b1ef0df2 | ||
|
|
925ccbadb9 | ||
|
|
f9cde96de0 | ||
|
|
d308602cb6 | ||
|
|
a3547fd432 | ||
|
|
759045035c | ||
|
|
72ed5de513 | ||
|
|
c415429b31 | ||
|
|
99ad467449 | ||
|
|
7881123910 | ||
|
|
27ce017de2 | ||
|
|
27faab2b9b | ||
|
|
eaf7ed9b4f | ||
|
|
94ccec871e | ||
|
|
e469731eeb | ||
|
|
1027470287 | ||
|
|
b3ead4ab76 | ||
|
|
22c7ed8d56 | ||
|
|
9ae6963441 | ||
|
|
168f3bae0d | ||
|
|
182b36114a | ||
|
|
9e962018ca | ||
|
|
620d1ab696 | ||
|
|
168d0d04a1 | ||
|
|
f0989bff07 | ||
|
|
e55802af54 | ||
|
|
b091448b98 | ||
|
|
bad75e211b | ||
|
|
56a90cd688 | ||
|
|
5e01eb445e | ||
|
|
c2dfaf6192 | ||
|
|
881d2e3c6c | ||
|
|
c6da52d9d6 | ||
|
|
aea68dc422 | ||
|
|
12858a4388 | ||
|
|
e75b544788 | ||
|
|
95819e9884 | ||
|
|
09c94f55e6 | ||
|
|
c61b1964af | ||
|
|
2a16f5b3a1 | ||
|
|
c299275992 | ||
|
|
422a4d0f5a | ||
|
|
c4ad96701f | ||
|
|
e69ca8805c | ||
|
|
3a3845decf | ||
|
|
3dca497c52 | ||
|
|
039f902065 | ||
|
|
7a2c5699aa | ||
|
|
455b633f87 | ||
|
|
cad4819cc5 | ||
|
|
aaae21a747 | ||
|
|
86203e4c74 | ||
|
|
a2431070a5 | ||
|
|
4352e5e37b | ||
|
|
d41f231705 | ||
|
|
1fdde3bc8c | ||
|
|
e62e204cac | ||
|
|
381159a0d7 | ||
|
|
7793a32a0d | ||
|
|
00cd9aafb8 | ||
|
|
55ba3ebcaa | ||
|
|
16a8d82ea8 | ||
|
|
8ac87b7c28 | ||
|
|
ef94c32e50 | ||
|
|
98a7faa0b5 | ||
|
|
3238af6086 | ||
|
|
e4055a6ffa | ||
|
|
bf91065d8c | ||
|
|
bb7e4eb9b3 | ||
|
|
f5860f9b3d | ||
|
|
68572a6285 | ||
|
|
58bd2bd587 | ||
|
|
a51df66b4b | ||
|
|
6a16a0e4fc | ||
|
|
c65f279074 | ||
|
|
777956191b | ||
|
|
89f199bcd2 | ||
|
|
68f0f98cc6 | ||
|
|
c5f3952c42 | ||
|
|
14df6ea00a | ||
|
|
c36667850b | ||
|
|
e1a2dec38a | ||
|
|
94a4547b0e | ||
|
|
4dbfb26767 | ||
|
|
1f45610cbb | ||
|
|
e0bad01cf0 | ||
|
|
65788673d8 | ||
|
|
670b8bce16 | ||
|
|
42ec54e512 | ||
|
|
9dd151af58 | ||
|
|
d5aab68175 | ||
|
|
3586424217 | ||
|
|
764a987395 | ||
|
|
84e1236582 | ||
|
|
9b09e08daf | ||
|
|
e7b3d2b998 | ||
|
|
3c56a0b8cb | ||
|
|
488b729004 | ||
|
|
bfcbe68c35 | ||
|
|
d9d96fc1ad | ||
|
|
9fc832022e | ||
|
|
6c2e2e1b02 | ||
|
|
0b85297d76 | ||
|
|
03b8ce32d9 | ||
|
|
ddcebe4744 | ||
|
|
a827cab203 | ||
|
|
573da345ce | ||
|
|
1bbfe1ee10 | ||
|
|
121acebe3b | ||
|
|
ff0ef06f08 | ||
|
|
c74423ce03 | ||
|
|
81e7f6e50d | ||
|
|
26dd8f118b | ||
|
|
fb7ff43a61 | ||
|
|
9a7bfac022 | ||
|
|
2e34b1734b | ||
|
|
512594a4c2 | ||
|
|
36bae6707d | ||
|
|
635c5407a8 | ||
|
|
4abbf293f8 | ||
|
|
dcbd9d2e81 | ||
|
|
4449dc0444 | ||
|
|
4abfa497be | ||
|
|
5005597969 | ||
|
|
38cd0baf87 | ||
|
|
d952e5c0f4 | ||
|
|
221aa34077 | ||
|
|
09718ce61e | ||
|
|
9abacb22cc | ||
|
|
54c2da9a3c | ||
|
|
b809bcab8a | ||
|
|
3468d97747 | ||
|
|
97827e00c2 | ||
|
|
6e63a06707 | ||
|
|
92c205d896 | ||
|
|
006f34d40c | ||
|
|
fb4b769814 | ||
|
|
bd2ef46f9b | ||
|
|
bc2f40994f | ||
|
|
d34f0d2c2e | ||
|
|
ac50b97a5a | ||
|
|
2c2a09878c | ||
|
|
4ae5c77f2d | ||
|
|
97439ad751 | ||
|
|
12cdf6a9cb | ||
|
|
acea00d0f4 | ||
|
|
3cb23ff2b1 | ||
|
|
6f5709463c | ||
|
|
ecc3f97892 | ||
|
|
d3130f0ea2 | ||
|
|
8aa9af34e7 | ||
|
|
5435c59eec | ||
|
|
af46f41578 | ||
|
|
53e287ce79 | ||
|
|
fb0665c141 | ||
|
|
94c443dbac | ||
|
|
41ad2761fc | ||
|
|
e97d947294 | ||
|
|
a756d45cb2 | ||
|
|
ddeba389c8 | ||
|
|
26eb9f430f | ||
|
|
89b7b1607f | ||
|
|
46ff876a04 | ||
|
|
d0887fd183 | ||
|
|
0284e260e2 | ||
|
|
b4cac40a24 | ||
|
|
273abcea31 | ||
|
|
4a6c4b7cc6 | ||
|
|
610a152446 | ||
|
|
108f126c1f | ||
|
|
283040ace0 | ||
|
|
375856bd13 | ||
|
|
8ed7698702 | ||
|
|
202555f320 | ||
|
|
4a84f6e149 | ||
|
|
2c14893d16 | ||
|
|
28e89bcf16 | ||
|
|
b165482ed9 | ||
|
|
ba35ff8a6d | ||
|
|
cc3538a407 | ||
|
|
3d2026421c | ||
|
|
51f400fe59 | ||
|
|
664cc8ccb2 | ||
|
|
05e7216a09 | ||
|
|
24cdf0b4e6 | ||
|
|
0592b7b9b6 | ||
|
|
6752469c8d | ||
|
|
63a47db15c | ||
|
|
86642de9ca | ||
|
|
ebb804e9b8 | ||
|
|
2e40528e33 | ||
|
|
b7fbf030ae | ||
|
|
1882de3f16 | ||
|
|
808082a7c2 | ||
|
|
2375550c7c | ||
|
|
10cbf262c2 | ||
|
|
7c7cc48fba | ||
|
|
9a802e1252 | ||
|
|
5db8749420 | ||
|
|
ac697688f0 | ||
|
|
a5c4cc0aca | ||
|
|
d08713822e | ||
|
|
61ff75b36e | ||
|
|
1ddebffc49 | ||
|
|
2bc376f8e8 | ||
|
|
ad4887659a | ||
|
|
2531c6eab7 | ||
|
|
bb1b563d76 | ||
|
|
f8b6adb95e | ||
|
|
eefa603b38 | ||
|
|
9bf6a91048 | ||
|
|
0c36a6488c | ||
|
|
e7e25aeb43 | ||
|
|
e2e2d2704d | ||
|
|
325abbed2c | ||
|
|
e081e1d220 | ||
|
|
24ade40556 | ||
|
|
e37c67bbb9 | ||
|
|
7ffba3114f | ||
|
|
0c56968419 | ||
|
|
6f9bb930a5 | ||
|
|
cda4598863 | ||
|
|
95bd317d56 | ||
|
|
f29ef5a236 | ||
|
|
18aa6600e7 | ||
|
|
d4287dd205 | ||
|
|
ea140229ae | ||
|
|
5bd28a4878 | ||
|
|
933c5174fd | ||
|
|
0f31d7fd46 | ||
|
|
05bc981714 | ||
|
|
2c1622b52b | ||
|
|
407b7ffd0a | ||
|
|
8e80fd6c8a | ||
|
|
62fca8931f | ||
|
|
4af8d3a65e | ||
|
|
fb6ebad7bf | ||
|
|
d52ce39184 | ||
|
|
6636b47344 | ||
|
|
107cdd9983 | ||
|
|
e69b6e6fc2 | ||
|
|
aa8c4a93e6 | ||
|
|
7643078aa2 | ||
|
|
51129f590f | ||
|
|
82cffd4953 | ||
|
|
3a8bc7ec2f | ||
|
|
6163377682 | ||
|
|
82f08a87d1 | ||
|
|
1700537df1 | ||
|
|
d23e06e321 | ||
|
|
1e4623a4f0 | ||
|
|
18532b349b | ||
|
|
0efdc2e71a | ||
|
|
f5b25b0da5 | ||
|
|
33c98457ca | ||
|
|
e0478f5774 | ||
|
|
34d3fb4925 | ||
|
|
01883fca09 | ||
|
|
a5e0200878 | ||
|
|
014cc3fc51 | ||
|
|
6a79b839df | ||
|
|
8242f85f4c | ||
|
|
901a96f511 | ||
|
|
803786263c | ||
|
|
9ac56cc9a7 | ||
|
|
43bd3903d6 | ||
|
|
bf49142a59 | ||
|
|
33de7762fb | ||
|
|
9547a26193 | ||
|
|
75d39e10e5 | ||
|
|
9bf038343e | ||
|
|
21963b6b3d | ||
|
|
b8dc48866c | ||
|
|
3e1135c458 | ||
|
|
216e33af86 | ||
|
|
4a8a350710 | ||
|
|
7994cf7d0e | ||
|
|
1ce52e8e57 | ||
|
|
d2fa8cb535 | ||
|
|
c9421b6947 | ||
|
|
926728a29d | ||
|
|
3ac96e6121 | ||
|
|
3d9f645a3c | ||
|
|
d7da405614 | ||
|
|
fd2519a0fc | ||
|
|
ea8912fff3 | ||
|
|
f5a73b7ff0 | ||
|
|
6220c2eb2c | ||
|
|
f44a091ec4 | ||
|
|
4de425066e | ||
|
|
956a8f0b01 | ||
|
|
d69f2ce122 | ||
|
|
0ca6a9e52d | ||
|
|
115ec3cd06 | ||
|
|
7b0df6cbf8 | ||
|
|
75d06ef967 | ||
|
|
7f9d5200ef | ||
|
|
e7d371cd2f | ||
|
|
57fce1908b | ||
|
|
9e91f100d9 | ||
|
|
8777dd736b | ||
|
|
3b16fb7243 | ||
|
|
40ebc8f7c5 | ||
|
|
9654c88357 | ||
|
|
f9aaa67a51 | ||
|
|
94ca54ff0d | ||
|
|
ff35adf9ae | ||
|
|
4a1dde629e | ||
|
|
328ac28244 | ||
|
|
908c5bc93e | ||
|
|
d945358d25 | ||
|
|
3e77cde88c | ||
|
|
90075c746b | ||
|
|
e15c0bf9c0 | ||
|
|
ecd51a45ee | ||
|
|
b352b58afb | ||
|
|
5f098bf14f | ||
|
|
a7c1bac157 | ||
|
|
474cd78e03 | ||
|
|
5bd851283c | ||
|
|
a6a4811230 | ||
|
|
b4d826b247 | ||
|
|
b37b71e4ec | ||
|
|
7158dfa838 | ||
|
|
1bfcb8c512 | ||
|
|
e2131027d5 | ||
|
|
e26290121c | ||
|
|
832a4f09fa | ||
|
|
56fed20b4e | ||
|
|
42ad013dd1 | ||
|
|
5b9a94c808 | ||
|
|
33294cbea0 | ||
|
|
6af917da86 | ||
|
|
fbe02e26a2 | ||
|
|
3f0f433faa | ||
|
|
c799568aa6 | ||
|
|
dcd09ea5aa | ||
|
|
acf47cc2e1 | ||
|
|
837c35d3ba | ||
|
|
52838f1cf5 | ||
|
|
ae7045b607 | ||
|
|
a3a428b0e5 | ||
|
|
9257179d2d | ||
|
|
3e1e0ff9ab | ||
|
|
f4a663db24 | ||
|
|
a91ae0ddd0 | ||
|
|
9fcd4f9a6b | ||
|
|
88ec7cbd31 | ||
|
|
4603a04c3b | ||
|
|
afa19bb887 | ||
|
|
9134e3d21f | ||
|
|
11f737c75f | ||
|
|
b0f12276c8 | ||
|
|
68b2e612ba | ||
|
|
3f9ab7adf3 | ||
|
|
c00cf4486e | ||
|
|
bac273fa23 | ||
|
|
2435ce388b | ||
|
|
a299f72036 | ||
|
|
6b9c423c32 | ||
|
|
d930c640ba | ||
|
|
a66e72528f | ||
|
|
0d792d5088 | ||
|
|
59b132ee62 | ||
|
|
a12c17bada | ||
|
|
d601f3aa33 | ||
|
|
271a39d176 | ||
|
|
9e8036186d | ||
|
|
5ad15b9823 | ||
|
|
70fd7e0346 | ||
|
|
5cb026697a | ||
|
|
6cf158fe36 | ||
|
|
d37ac5dd93 | ||
|
|
03eeb4737f | ||
|
|
2bb25ffef7 | ||
|
|
7c37f5dcce | ||
|
|
fc8b64f82b | ||
|
|
a3c9c0e0ac | ||
|
|
0a935a9bd3 | ||
|
|
321c3c6f18 | ||
|
|
088ab82e51 | ||
|
|
9c09a7a4e3 | ||
|
|
ec90cb9a54 | ||
|
|
b14ed827bb | ||
|
|
70c72dcdca | ||
|
|
cf05d1eeb2 | ||
|
|
f62e1ce178 | ||
|
|
6038bb8c9c | ||
|
|
357799e3c7 | ||
|
|
786bcbb9fd | ||
|
|
d78ab74a66 | ||
|
|
2705057a2a | ||
|
|
d54e3f3ac9 | ||
|
|
0e2bf75e05 | ||
|
|
6e9c1ddcaa | ||
|
|
e4ad028a5f | ||
|
|
34d3488a2c | ||
|
|
ef1d9f0cfc | ||
|
|
39dd51c282 | ||
|
|
13b3ade46b | ||
|
|
1640630d4d | ||
|
|
8a55588c21 | ||
|
|
d3526dbac9 | ||
|
|
8cfbf4c268 | ||
|
|
3c14f627fe | ||
|
|
3842460115 | ||
|
|
590c21013b | ||
|
|
e1bf532680 | ||
|
|
f55b51d47f | ||
|
|
42cab51487 | ||
|
|
1bcd168590 | ||
|
|
a1e8474193 | ||
|
|
c1daf236dc | ||
|
|
0df30b5087 | ||
|
|
7ccb694f79 | ||
|
|
54050b4825 | ||
|
|
4f07ef0291 | ||
|
|
e2f9c6b340 | ||
|
|
c65d2653d1 | ||
|
|
b879e23407 | ||
|
|
2ab53a937a | ||
|
|
31ca3b5482 | ||
|
|
86347fd849 | ||
|
|
90eca50f2b | ||
|
|
2f2794905e | ||
|
|
ca90b62324 | ||
|
|
ddb37f5b54 | ||
|
|
f82245a946 | ||
|
|
3b50b7523e | ||
|
|
ff843759db | ||
|
|
137e776118 | ||
|
|
aa81a19a04 | ||
|
|
e5e16f0dcc | ||
|
|
1ac35d7eeb | ||
|
|
eca977ca2d | ||
|
|
69d097f488 | ||
|
|
739a19f63c | ||
|
|
fdab516df6 | ||
|
|
6559dfec99 | ||
|
|
ba798c659a | ||
|
|
99c19a64c5 | ||
|
|
43f5856b2e | ||
|
|
c575bd727a | ||
|
|
af89b63ef0 | ||
|
|
c6a90a3a43 | ||
|
|
3af587dd70 | ||
|
|
e1f8c9b4a3 | ||
|
|
5da8fb507d | ||
|
|
87ea6162e8 | ||
|
|
427def01bf | ||
|
|
8e541f55d5 | ||
|
|
666e70cc66 | ||
|
|
7dafb9e4e2 | ||
|
|
71a205d8bb | ||
|
|
025bf91980 | ||
|
|
195bc67947 | ||
|
|
9b600ee651 | ||
|
|
a8f2ae8d56 | ||
|
|
61aeb6380d | ||
|
|
9d2d6304f9 | ||
|
|
0b2633add8 | ||
|
|
4cceb4a9dd | ||
|
|
9f758da034 | ||
|
|
f51a2d742d | ||
|
|
f4cd56a842 | ||
|
|
d9256870a3 | ||
|
|
64ac80246f | ||
|
|
1c765c4fec | ||
|
|
e2d2915dc6 | ||
|
|
55808d71cf | ||
|
|
0ce8327aec | ||
|
|
f48b86aff6 | ||
|
|
60f54ac1a2 | ||
|
|
1d9b382656 | ||
|
|
c4367ebf83 | ||
|
|
c6478c42f4 | ||
|
|
a56168a9f4 | ||
|
|
bd77c974d4 | ||
|
|
0ccd9bbb10 | ||
|
|
e91e24e915 | ||
|
|
06e8e94b81 | ||
|
|
2857257cdf | ||
|
|
eed2aebc9f | ||
|
|
b3c7040e85 | ||
|
|
27aac1a258 | ||
|
|
384f60408a | ||
|
|
bdffbd3052 | ||
|
|
9abd904bde | ||
|
|
48f1ecf7fc | ||
|
|
5ee15f3367 | ||
|
|
5598734467 | ||
|
|
622e04314a | ||
|
|
8751079128 | ||
|
|
5d76b86d0c | ||
|
|
f553c9964d | ||
|
|
62c652ca23 | ||
|
|
d88835bce4 | ||
|
|
41e92b4d70 | ||
|
|
a4e4fb6157 | ||
|
|
0b54f3568d | ||
|
|
0c22a58ddd | ||
|
|
07cbefa8a4 | ||
|
|
f5c771a36c | ||
|
|
c02fae6be8 | ||
|
|
494fcf53b5 | ||
|
|
c706027a21 | ||
|
|
d9ff90cb7a | ||
|
|
47922feefb | ||
|
|
d0fedcd243 | ||
|
|
669b6107f9 | ||
|
|
9f5f8e8cca | ||
|
|
b89aa58260 | ||
|
|
48f3e109d8 | ||
|
|
e6bf392f25 | ||
|
|
662c8308ad | ||
|
|
4a209279be | ||
|
|
cf97a3ebf7 | ||
|
|
852c53bd49 | ||
|
|
9f34021ba5 | ||
|
|
cdc3057520 | ||
|
|
6756b4b24b | ||
|
|
cab02417d8 | ||
|
|
3c56a30c98 | ||
|
|
5f46dcc097 | ||
|
|
7c47667d19 | ||
|
|
6693e07e10 | ||
|
|
0d6453086d | ||
|
|
e30a1e8795 | ||
|
|
5dabc44699 | ||
|
|
4447e49f0c | ||
|
|
ff4d45482d | ||
|
|
e7803b1d68 | ||
|
|
bb995ccb1a | ||
|
|
f97e28f939 | ||
|
|
3821af347d | ||
|
|
25c16b2c81 | ||
|
|
f546981377 | ||
|
|
7d35dba31f | ||
|
|
5ee332aba5 | ||
|
|
80a8c1f0a5 | ||
|
|
939300f84a | ||
|
|
cdd85770c5 | ||
|
|
4db32f4dff | ||
|
|
ab3b0631c0 | ||
|
|
bbcbc7c599 | ||
|
|
6f02c0453d | ||
|
|
4eb09c6662 | ||
|
|
b0af5c86e3 | ||
|
|
dc05b1b571 | ||
|
|
60f97b4807 | ||
|
|
0a46467bb8 | ||
|
|
20c4e8f003 | ||
|
|
8c02e70f79 | ||
|
|
08a292f3ff | ||
|
|
965cd0c9f8 | ||
|
|
fa020e88a5 | ||
|
|
f71e45b8e5 | ||
|
|
dfa1e8238c | ||
|
|
83d54888d8 | ||
|
|
5809ac3670 | ||
|
|
ba3dde63dd | ||
|
|
fcccb06b7c | ||
|
|
a1ceec81dc | ||
|
|
bfba840f98 | ||
|
|
7a1563915d | ||
|
|
ab7f9b9cec | ||
|
|
270ff15621 | ||
|
|
ef05004508 | ||
|
|
57d8d0d582 | ||
|
|
69a92cab71 | ||
|
|
37de16d3ce | ||
|
|
d3cc2de14d | ||
|
|
2a133511da | ||
|
|
7daef1d46d | ||
|
|
c1edf978d0 | ||
|
|
773b04eb46 | ||
|
|
6538716288 | ||
|
|
db60b243e5 | ||
|
|
1757657d84 | ||
|
|
915a8e58c4 | ||
|
|
dd60cd3970 | ||
|
|
c86e0adcf3 | ||
|
|
fb0edb9186 | ||
|
|
42297439a5 | ||
|
|
dcafde3a1c | ||
|
|
49b4c82480 | ||
|
|
0b8ea35893 | ||
|
|
c057ea791a | ||
|
|
a66a66490b | ||
|
|
4395ed71ff | ||
|
|
7731f31eb0 | ||
|
|
5496e4a1e5 | ||
|
|
62f35c5a56 | ||
|
|
9b23529483 | ||
|
|
c1ec1471d4 | ||
|
|
25e4470c7b | ||
|
|
a0f7896228 | ||
|
|
b1f2f9b250 | ||
|
|
53402c490b | ||
|
|
b8f2bfc238 | ||
|
|
e18e6f5fcd | ||
|
|
a3bd1b0b2e | ||
|
|
9cb5d9f95a | ||
|
|
322c62152d | ||
|
|
32de12c179 | ||
|
|
34a0ba0647 | ||
|
|
6743b05ab3 | ||
|
|
684152643b | ||
|
|
b00a13498c | ||
|
|
4d5d488a88 | ||
|
|
72f5d52852 | ||
|
|
124b95b5a4 | ||
|
|
d34580f230 | ||
|
|
eb1df3ecaf | ||
|
|
3c57c18293 | ||
|
|
1d5e13bc2b | ||
|
|
c8eac8eb17 | ||
|
|
92d702e050 | ||
|
|
3e2699dd4e | ||
|
|
d76f1ff61f | ||
|
|
a34419f14e | ||
|
|
33da00c46d | ||
|
|
c2c2094e36 | ||
|
|
e33706abf5 | ||
|
|
c101c360a2 | ||
|
|
1357e85f6d | ||
|
|
a0b7159ebe | ||
|
|
de59e7c233 | ||
|
|
0034c942a8 | ||
|
|
30bd1befd4 | ||
|
|
71e8e8987c | ||
|
|
e4f5be87e4 | ||
|
|
ae1728ff9d | ||
|
|
bd32edc758 | ||
|
|
f27e6827c7 | ||
|
|
b7e5c61ca4 | ||
|
|
6896c3a907 | ||
|
|
2b31c4c495 | ||
|
|
3dbe874a97 | ||
|
|
c77d05968c | ||
|
|
15c06809ed | ||
|
|
ff5ee8934b | ||
|
|
0b180f9472 | ||
|
|
062213a0b1 | ||
|
|
78b1874cc3 | ||
|
|
6afb72c47d | ||
|
|
d7fbdfb28e | ||
|
|
de11c1c953 | ||
|
|
af92f58b74 | ||
|
|
fdc8191914 | ||
|
|
4fb0044224 | ||
|
|
3f8281e3c0 | ||
|
|
eab6ef2a9b | ||
|
|
04ef2d887f | ||
|
|
21dcb803fe | ||
|
|
59b4a85412 | ||
|
|
b199af7242 | ||
|
|
8081e7215e | ||
|
|
32745d9f18 | ||
|
|
a013a92b55 | ||
|
|
0535bc8541 | ||
|
|
22b06275a4 | ||
|
|
507196e185 | ||
|
|
5f06ad9453 | ||
|
|
f3206e3eaa | ||
|
|
c9c6c6f5ac | ||
|
|
216b64136f | ||
|
|
36346d9e6e | ||
|
|
9f4472491d | ||
|
|
bf193f0918 | ||
|
|
ad9ce66bcb | ||
|
|
3736563397 | ||
|
|
17703cf0d4 | ||
|
|
99f89aa93f | ||
|
|
52aae5b4eb | ||
|
|
e9d56711d6 | ||
|
|
4d48c17e3f | ||
|
|
729a09d780 | ||
|
|
6d6ffeeae8 | ||
|
|
5df69f4d5e | ||
|
|
32481783ab | ||
|
|
0a0fe40e57 | ||
|
|
0dbf1cf5c7 | ||
|
|
2abfe53d42 | ||
|
|
2183d7c593 | ||
|
|
4856d70345 | ||
|
|
80c9a9c5f2 | ||
|
|
ebdfeda20a | ||
|
|
bd8e0db743 | ||
|
|
8608417cf5 | ||
|
|
ec57f36345 | ||
|
|
0afa8b872d | ||
|
|
87671e1ebb | ||
|
|
00d92ca50b | ||
|
|
c86a06bc52 | ||
|
|
b0da99c5dd | ||
|
|
676c58fd9a | ||
|
|
62a3925551 | ||
|
|
20d70ee317 | ||
|
|
960a361347 | ||
|
|
d4e1b2ec20 | ||
|
|
46f15f6755 | ||
|
|
b6ae195cb7 | ||
|
|
c22973f322 | ||
|
|
a7d00f119b | ||
|
|
a1b841a94d | ||
|
|
667bf4b036 | ||
|
|
1986e29f15 | ||
|
|
33fd941711 | ||
|
|
1813f500c1 | ||
|
|
020c83dfc9 | ||
|
|
6a52d26462 | ||
|
|
17566e8c7f | ||
|
|
856585d16e | ||
|
|
2e96e51102 | ||
|
|
31f2a0f954 | ||
|
|
050505d1d4 | ||
|
|
c975435c72 | ||
|
|
12e2ab46aa | ||
|
|
314a8148c3 | ||
|
|
3e4ce0354a | ||
|
|
5771bbef02 | ||
|
|
217c89f340 | ||
|
|
f3a95fbf7d | ||
|
|
afb3d9716c | ||
|
|
8cad973636 | ||
|
|
41060f4d72 | ||
|
|
fd48ccb46c | ||
|
|
624812ee3e | ||
|
|
43a06887b7 | ||
|
|
6bb50e5a3f | ||
|
|
6181be12c0 | ||
|
|
be9798262a | ||
|
|
d5d3efb549 | ||
|
|
a490423b3f | ||
|
|
7d7ce9549e | ||
|
|
eab8289c77 | ||
|
|
9e90373317 | ||
|
|
6e896b53ff | ||
|
|
46b855b838 | ||
|
|
f083fa2494 | ||
|
|
b4d46b5669 | ||
|
|
852c77088d | ||
|
|
4448cac071 | ||
|
|
8d47554a47 | ||
|
|
e3aceb3c4c | ||
|
|
1d2c6adde6 | ||
|
|
0232b5124c | ||
|
|
c3825e5cbc | ||
|
|
b34d70dae9 | ||
|
|
4090708b38 | ||
|
|
f6a1ad4185 | ||
|
|
4a006efd6e | ||
|
|
44df9e433d | ||
|
|
bd0ae44938 | ||
|
|
083a636247 | ||
|
|
1827e25bb9 | ||
|
|
6192204ba3 | ||
|
|
5f9a84ba40 | ||
|
|
9b06ce40b6 | ||
|
|
de4d0d8fbe | ||
|
|
eec6153ede | ||
|
|
5cd9eeb651 | ||
|
|
d28a327cf7 | ||
|
|
8333da6004 | ||
|
|
fa8f120dae | ||
|
|
905aead44e | ||
|
|
c58177e230 | ||
|
|
05f03ed192 | ||
|
|
f792ee7af5 | ||
|
|
cb3fb44da1 | ||
|
|
361237acca | ||
|
|
778799ed7b | ||
|
|
a09578be06 | ||
|
|
1545aab55a | ||
|
|
86cb0d912b | ||
|
|
6593ddd9e3 | ||
|
|
c87832d1e3 | ||
|
|
0245930c89 | ||
|
|
7d876e8137 | ||
|
|
a8255c218e | ||
|
|
f79e76dd30 | ||
|
|
f5e76ebab3 | ||
|
|
8f36a32da6 | ||
|
|
11fbd6d797 | ||
|
|
e2999f4bbb | ||
|
|
dce2f81a3b | ||
|
|
4d24791dd1 | ||
|
|
a8c286f820 | ||
|
|
29efdbd346 | ||
|
|
23c21c9ec3 | ||
|
|
95587dbc4e | ||
|
|
e670df8768 | ||
|
|
b1bb37aaee | ||
|
|
8b4b080abe | ||
|
|
035fac71b2 | ||
|
|
8ae7e25e02 | ||
|
|
7be3ca6a8e | ||
|
|
dd37d4c409 | ||
|
|
630e27623f | ||
|
|
87305d6f23 | ||
|
|
2d5d3db3f5 | ||
|
|
f25661fed3 | ||
|
|
e9af2773ac | ||
|
|
aff7a47966 | ||
|
|
68d190f6c9 | ||
|
|
6a9e8f8db6 | ||
|
|
c68a913b15 | ||
|
|
62c374ec72 | ||
|
|
0f23f7c0cd | ||
|
|
de360ef9c2 | ||
|
|
f2149b1d28 | ||
|
|
4a357f3685 | ||
|
|
399381ddab | ||
|
|
6016184417 | ||
|
|
f38b0ed2f8 | ||
|
|
479fbf499b | ||
|
|
cc54e2f21e | ||
|
|
0aa7c955c4 | ||
|
|
2125053663 | ||
|
|
0a0e30cf61 | ||
|
|
01e805b484 | ||
|
|
157da49e8c | ||
|
|
6187f57b41 | ||
|
|
f249198169 | ||
|
|
99bb5f9de5 | ||
|
|
f1ee7c2583 | ||
|
|
008c729f42 | ||
|
|
fa0cfa8ce1 | ||
|
|
c58e094ff7 | ||
|
|
0e7817184e | ||
|
|
e923ceb384 | ||
|
|
4aaebe16d0 | ||
|
|
de22d5a38a | ||
|
|
bd67e2fefe | ||
|
|
01296611cc | ||
|
|
d90a39593e | ||
|
|
f11615832d | ||
|
|
7731aad4f1 | ||
|
|
45f2900250 | ||
|
|
bb41d17047 | ||
|
|
fc980407c2 | ||
|
|
03cd9ae1d0 | ||
|
|
da3526a50b | ||
|
|
e1bca8337f | ||
|
|
89e99a9319 | ||
|
|
f7cb92e1ec | ||
|
|
90e66b78e6 | ||
|
|
3def8cc77b | ||
|
|
34878cf527 | ||
|
|
dacd6f2d65 | ||
|
|
5848581890 | ||
|
|
543d499f2e | ||
|
|
e25b8a57c0 | ||
|
|
dd1db5ef13 | ||
|
|
7cba27f732 | ||
|
|
4c752f6157 | ||
|
|
07b07b2208 | ||
|
|
d455725f74 | ||
|
|
da991ae504 | ||
|
|
c34b370ad5 | ||
|
|
3bc546f701 | ||
|
|
df992a70ea | ||
|
|
8afe4606fc | ||
|
|
e5cbff1b92 | ||
|
|
b1782a5541 | ||
|
|
9bcc185102 | ||
|
|
2cecef5511 | ||
|
|
508b4999af | ||
|
|
38db9c1750 | ||
|
|
5a23f0bf21 | ||
|
|
68b6c69723 | ||
|
|
99bc757497 | ||
|
|
638234e97c | ||
|
|
53f4ee80e2 | ||
|
|
faad14993b | ||
|
|
c82464ac83 | ||
|
|
12e5776bcf | ||
|
|
249b9b2b14 | ||
|
|
1dde92c74f | ||
|
|
c9fdf48c43 | ||
|
|
15a49f32c3 | ||
|
|
e6fab97249 | ||
|
|
09b5c80f88 | ||
|
|
a01638ae01 | ||
|
|
bda22f8328 | ||
|
|
f1759a000d | ||
|
|
8b7808d61d | ||
|
|
2c276de976 | ||
|
|
4f130a3f52 | ||
|
|
b78256c025 | ||
|
|
7e10f4cf9e | ||
|
|
e61541c4a9 | ||
|
|
487899b8b6 | ||
|
|
235596c306 | ||
|
|
3d5df1af3e | ||
|
|
8736fe2844 | ||
|
|
17d89995a4 | ||
|
|
17fba3bb43 | ||
|
|
5024d5a1c5 | ||
|
|
6d83f14045 | ||
|
|
9f54e37239 | ||
|
|
7c252a1d7c | ||
|
|
6134250100 | ||
|
|
4821fb094b | ||
|
|
364272f9ca | ||
|
|
c4db864982 | ||
|
|
4c7d911bf3 | ||
|
|
b9e436c4a5 | ||
|
|
65a1b21f91 | ||
|
|
96fbdba5f5 | ||
|
|
59e0bd8c6b | ||
|
|
4913a7eb83 | ||
|
|
4863317fab | ||
|
|
397d82493f | ||
|
|
c2d1c0d148 | ||
|
|
2f204507c2 | ||
|
|
9ac98eea0f | ||
|
|
f44aa5541f | ||
|
|
a2566076c8 | ||
|
|
475fcb4c21 | ||
|
|
0e34199386 | ||
|
|
43e4d02c35 | ||
|
|
f8e1f0ccf4 | ||
|
|
bcae174cb0 | ||
|
|
92d4e2e2f8 | ||
|
|
abbb294c4a | ||
|
|
16637d2b60 | ||
|
|
09001707be | ||
|
|
1c20ed878a | ||
|
|
994f440672 | ||
|
|
2b2c7572b2 | ||
|
|
9c209cfcc1 | ||
|
|
77d93454a2 | ||
|
|
0dd2b510ac | ||
|
|
1ed6b40d7c | ||
|
|
e3571d0444 | ||
|
|
253f5bebf9 | ||
|
|
07a808f6ad | ||
|
|
61c2025345 | ||
|
|
2f4bc11408 | ||
|
|
ff6f4c1e87 | ||
|
|
adccfb06fd | ||
|
|
9d42c2defb | ||
|
|
57549f3cc3 | ||
|
|
a97aa7238b | ||
|
|
fa09bd4748 | ||
|
|
61fe5ecf87 | ||
|
|
cd76603996 | ||
|
|
26de04f61f | ||
|
|
7efe727024 | ||
|
|
51f4d22ab0 | ||
|
|
b21228fedb | ||
|
|
de7affedf0 | ||
|
|
25eb746d45 | ||
|
|
c14e8a41ff | ||
|
|
a41f223cb9 | ||
|
|
f749a9564b | ||
|
|
ce8167f0dd | ||
|
|
fccedcc532 | ||
|
|
83fb9ddfb8 | ||
|
|
1506401dc1 | ||
|
|
a9572b720c | ||
|
|
00052dfa44 | ||
|
|
125e9717eb | ||
|
|
74f6aabb0e | ||
|
|
8bcd9697bc | ||
|
|
99eaf640f3 | ||
|
|
27783acb28 | ||
|
|
8d4ffaac96 | ||
|
|
c703088370 | ||
|
|
00da516923 | ||
|
|
d644f7f02b | ||
|
|
9858c98c78 | ||
|
|
f3e6c9f991 | ||
|
|
0217450f33 | ||
|
|
a2bd7ca7ca | ||
|
|
c26d2003c0 | ||
|
|
bae06a4681 | ||
|
|
366bb8e5e5 | ||
|
|
9f4ac2d8b2 | ||
|
|
d27693b1e5 | ||
|
|
8db5c30f8f | ||
|
|
ed96d394dd | ||
|
|
81afd8274a | ||
|
|
a6ceb5c758 | ||
|
|
60d3d5681e | ||
|
|
68d1ab5495 | ||
|
|
24595bdb57 | ||
|
|
27ebd2136a | ||
|
|
d4449d445e | ||
|
|
ce0ca0234b | ||
|
|
2c38f6bbb2 | ||
|
|
648c4d63c5 | ||
|
|
e6f6807110 | ||
|
|
d8e572165d | ||
|
|
ecef80d8c2 | ||
|
|
962d3c788a | ||
|
|
8d0950cbb4 | ||
|
|
a65e3cc7ed | ||
|
|
dab409f649 | ||
|
|
468718327d | ||
|
|
3dd1d66eb5 | ||
|
|
012379b56c | ||
|
|
f6901a6501 | ||
|
|
2d920ab392 | ||
|
|
f6bf087a27 | ||
|
|
eb93e9e7e8 | ||
|
|
0d5c197058 | ||
|
|
10a51943dc | ||
|
|
3f22d9f7b9 | ||
|
|
f44f172625 | ||
|
|
a250046807 | ||
|
|
c4b7b527d7 | ||
|
|
624ad08374 | ||
|
|
034ec13009 | ||
|
|
b90aefdce5 | ||
|
|
9d518791eb | ||
|
|
31458cd045 | ||
|
|
ba57f74fdf | ||
|
|
0612986875 | ||
|
|
496ce8ebf1 | ||
|
|
daaf8bb221 | ||
|
|
f34e7ce667 | ||
|
|
b0f40e2ac6 | ||
|
|
21dd0c95ef | ||
|
|
fba825626f | ||
|
|
f69081ec4e | ||
|
|
dca9138c1b | ||
|
|
90995f8e6c | ||
|
|
16a03cd9ea | ||
|
|
9d414b123b | ||
|
|
c83fd35b80 | ||
|
|
59a0369f8a | ||
|
|
dab6283658 | ||
|
|
48c1360554 | ||
|
|
8da3e98c83 | ||
|
|
3c32852fd9 | ||
|
|
367f9928ab | ||
|
|
70b15f804b | ||
|
|
40a7d93801 | ||
|
|
0d72a7d0a7 | ||
|
|
bbb3cd28b3 | ||
|
|
fa64d26843 | ||
|
|
cf257870e3 | ||
|
|
6d18778286 | ||
|
|
eb12637cc3 | ||
|
|
d873bb263a | ||
|
|
cb2aaef19e | ||
|
|
0e608d282b | ||
|
|
80a2c9c0e5 | ||
|
|
583652a276 | ||
|
|
7305512c72 | ||
|
|
84e2c0f4a4 | ||
|
|
5a347724fe | ||
|
|
1d059d0bb8 | ||
|
|
b720d2c74e | ||
|
|
d67a169626 | ||
|
|
0dbf236167 | ||
|
|
4c73bc0492 | ||
|
|
ce7c32da47 | ||
|
|
08109790e6 | ||
|
|
db1b22ae5e | ||
|
|
8ae5f5d570 | ||
|
|
ef09e3dda1 | ||
|
|
f0abac5047 | ||
|
|
ee040d7ca2 | ||
|
|
ee0cd975ec | ||
|
|
a7eaff414e | ||
|
|
ca9c451885 | ||
|
|
18f9936238 | ||
|
|
c6d793bcb7 | ||
|
|
8e34db7740 | ||
|
|
cf61b549b3 | ||
|
|
2ddacc43b5 | ||
|
|
43e9cc1d23 | ||
|
|
dda64f1291 | ||
|
|
4e59addb33 | ||
|
|
29ef71b33c | ||
|
|
7500c65647 | ||
|
|
fde7d45171 | ||
|
|
a7df497245 | ||
|
|
51d2959d3c | ||
|
|
f3f93f6dda | ||
|
|
964c49d016 | ||
|
|
cabe143e45 | ||
|
|
efa7dda32f | ||
|
|
a3458f7ee0 | ||
|
|
9f7f6c479c | ||
|
|
70699d59b8 | ||
|
|
58354128ff | ||
|
|
14781b1b33 | ||
|
|
f34cc18025 | ||
|
|
e60eaa48ad | ||
|
|
486cc6f799 | ||
|
|
6bb6d270b6 | ||
|
|
994a4a4d8f | ||
|
|
cbdbc4de0c | ||
|
|
5a83083009 | ||
|
|
903d2b419d | ||
|
|
07f5134dee | ||
|
|
9e07c51727 | ||
|
|
ac21386665 | ||
|
|
2209c9acb1 | ||
|
|
628cc5b3a0 | ||
|
|
02efe6d649 | ||
|
|
a631fcfafc | ||
|
|
3269de9cbf | ||
|
|
40374f6823 | ||
|
|
cedbbdc470 | ||
|
|
458eb8081f | ||
|
|
0cc2954725 | ||
|
|
26dff9a849 | ||
|
|
448aa7d022 | ||
|
|
b265526ce7 | ||
|
|
3a4ff87005 | ||
|
|
252b378e4b | ||
|
|
56a9951fee | ||
|
|
b35fe4d4f7 | ||
|
|
8db61343cf | ||
|
|
ee28a9dcd7 | ||
|
|
c6b36c3c0b | ||
|
|
61b819dda3 | ||
|
|
e2e17e21b8 | ||
|
|
43928c2810 | ||
|
|
9198bc3709 | ||
|
|
084089958a | ||
|
|
c40207a536 | ||
|
|
1f1fa2e643 | ||
|
|
6735bafec4 | ||
|
|
1ffb7a4f50 | ||
|
|
b450cec1af | ||
|
|
3be1851090 | ||
|
|
5d5ff900e5 | ||
|
|
2c9a893ed7 | ||
|
|
5fcd9571a4 | ||
|
|
78b1a2d8f9 | ||
|
|
d776277986 | ||
|
|
fc737d9e7e | ||
|
|
484749bdd7 | ||
|
|
6227d97e48 | ||
|
|
e05fa83aa6 | ||
|
|
848a3334df | ||
|
|
8b8334f2ed | ||
|
|
15eb8a3442 | ||
|
|
f4f58cf430 | ||
|
|
b2080926c5 | ||
|
|
dd44f904d9 | ||
|
|
0568929aa6 | ||
|
|
714c5cb1c8 | ||
|
|
68b0449fc7 | ||
|
|
b18bbcfb86 | ||
|
|
6ca8a95dcd | ||
|
|
f4c2af0618 | ||
|
|
a3cb98d2c0 | ||
|
|
3d43be95aa | ||
|
|
29e2a7fda9 | ||
|
|
54ecb3577a | ||
|
|
d72622208f | ||
|
|
f43e09c9f8 | ||
|
|
e86ca7ad1c | ||
|
|
f33a3de62f | ||
|
|
467c5469f1 | ||
|
|
85d5b4bb63 | ||
|
|
6369d2fc61 | ||
|
|
be541d9ec1 | ||
|
|
53c01989b9 | ||
|
|
a9f5ee4532 | ||
|
|
10907ab3b9 | ||
|
|
9041549d65 | ||
|
|
79371a9e5f | ||
|
|
41fc5d96bd | ||
|
|
c7c91b33f1 | ||
|
|
512d884b04 | ||
|
|
e8a7c440fd | ||
|
|
402ad21df0 | ||
|
|
c2cc346052 | ||
|
|
debdc13be7 | ||
|
|
74512caa56 | ||
|
|
2d8f241b21 | ||
|
|
32c99c6b80 | ||
|
|
1c94561b74 | ||
|
|
159abfcb3a | ||
|
|
4920756db1 | ||
|
|
6470297efd | ||
|
|
531deb1596 | ||
|
|
5785de265a | ||
|
|
3f86a152e6 | ||
|
|
d75e3fb6e5 | ||
|
|
de2906b353 | ||
|
|
456cb03faf | ||
|
|
f164e29116 | ||
|
|
22ebeff495 | ||
|
|
eaa84807d5 | ||
|
|
bc627a5160 | ||
|
|
a1e41d8c01 | ||
|
|
22dcd5d826 | ||
|
|
72180aff88 | ||
|
|
d009a36e23 | ||
|
|
dbfa00bac1 | ||
|
|
595aa08c6e | ||
|
|
f8b9f7a17d | ||
|
|
8f74627a4a | ||
|
|
bf62ff8a32 | ||
|
|
ed353ca490 | ||
|
|
7817fe2fda | ||
|
|
8e2b639b75 | ||
|
|
28867d5532 | ||
|
|
7e61e4ea45 | ||
|
|
3f2e96997e | ||
|
|
cab000cc97 | ||
|
|
5c949e86d8 | ||
|
|
58f7db98d6 | ||
|
|
78421c3a6b | ||
|
|
9b8e2ab154 | ||
|
|
852d67a828 | ||
|
|
11eb3107cf | ||
|
|
e84fa6b643 | ||
|
|
dd644e0910 | ||
|
|
b2ef62295f | ||
|
|
debd7e56da | ||
|
|
cefe892917 | ||
|
|
e5e064687d | ||
|
|
fc5f43f4b7 | ||
|
|
cdcef4942f | ||
|
|
d97f52dd08 | ||
|
|
531531993a | ||
|
|
f283dc17cd | ||
|
|
51cfb62b09 | ||
|
|
dc1279f075 | ||
|
|
f6fa297fcf | ||
|
|
1a02518fd4 | ||
|
|
a9d366a6ca | ||
|
|
34c595a213 | ||
|
|
9ba6364fad | ||
|
|
563c672b56 | ||
|
|
7ff25d5f73 | ||
|
|
2a8102f67c | ||
|
|
70ef2101ea | ||
|
|
bb5f444c6b | ||
|
|
30a776186b | ||
|
|
ad744e07da | ||
|
|
992b541464 | ||
|
|
7901f5ee7b | ||
|
|
3e0aad6b0c | ||
|
|
de2472b659 | ||
|
|
c70034d091 | ||
|
|
be5d9526dc | ||
|
|
7884feba5b | ||
|
|
ed3e943a6c | ||
|
|
92d81faa7a | ||
|
|
8777f3a424 | ||
|
|
1e522241ee | ||
|
|
fc70c0b5a0 | ||
|
|
e150f73a50 | ||
|
|
88887ce059 | ||
|
|
cada9fa30d | ||
|
|
f555984da3 | ||
|
|
dce7b8b832 | ||
|
|
6969049fce | ||
|
|
81b1cdb80f | ||
|
|
57d23d4ca6 | ||
|
|
de9d7dd33c | ||
|
|
b2537534df | ||
|
|
6d691107f2 | ||
|
|
dbe45ca6b3 | ||
|
|
b6b12b7271 | ||
|
|
e62a8fef0a | ||
|
|
ff2e21ddd3 | ||
|
|
2b99d2e1e9 | ||
|
|
a3674c42db | ||
|
|
00364fd11e | ||
|
|
a6b5599d29 | ||
|
|
61751657da | ||
|
|
40a496124c | ||
|
|
0c414cc90e | ||
|
|
ee2fd76691 | ||
|
|
805bc249d4 | ||
|
|
bdc48da5ba | ||
|
|
fe08e56d63 | ||
|
|
1a6464dc18 | ||
|
|
08957600c1 | ||
|
|
b551288b95 | ||
|
|
cfbab12cf6 | ||
|
|
d574602f2b | ||
|
|
dd50a9ff66 | ||
|
|
442ad89abe | ||
|
|
006f680e13 | ||
|
|
0f78e2e308 | ||
|
|
8f598bde9f | ||
|
|
9829b55dcb | ||
|
|
3195ddd044 | ||
|
|
4a519edc4d | ||
|
|
e9a941d76a | ||
|
|
31bbe2fef9 | ||
|
|
0ac1b07419 | ||
|
|
aeb5811ba1 | ||
|
|
998a98cbdd | ||
|
|
b8ede65b1c | ||
|
|
615640f3e0 | ||
|
|
28f817f9d9 | ||
|
|
3a1238ee6e | ||
|
|
556eadd088 | ||
|
|
4a17e3a74a | ||
|
|
68376144ab | ||
|
|
38680d3e6f | ||
|
|
e66c2066bf | ||
|
|
b9e41669c4 | ||
|
|
307ba72fa9 | ||
|
|
e7cbf5830e | ||
|
|
56ea6b861f | ||
|
|
d7a96d50a3 | ||
|
|
da0793dc53 | ||
|
|
eb2eb3b8fe | ||
|
|
9e0804123a | ||
|
|
9197d0b3dc | ||
|
|
8e34cba621 | ||
|
|
c44b76f747 | ||
|
|
b777e5a0ed | ||
|
|
caf7df7b0c | ||
|
|
3538395bed | ||
|
|
357ca6e9ca | ||
|
|
b7c2cffb13 | ||
|
|
e54050b60b | ||
|
|
78c5ec9bea | ||
|
|
4808637b2e | ||
|
|
90219ab8da | ||
|
|
3303bf960f | ||
|
|
2b633e5aa8 | ||
|
|
38dbebf7d5 | ||
|
|
ca0128b0dc | ||
|
|
859a7f1373 | ||
|
|
3562a7df32 | ||
|
|
cfd51c2627 | ||
|
|
f53fcb3bbc | ||
|
|
5d537571ae | ||
|
|
e84519646e | ||
|
|
818db4a42e | ||
|
|
760ebc8347 | ||
|
|
882e313516 | ||
|
|
1c047dd3cf | ||
|
|
8f349a0f09 | ||
|
|
8327e0d1fa | ||
|
|
bf3cdb855f | ||
|
|
f331090f16 | ||
|
|
8b1602130b | ||
|
|
39ad932274 | ||
|
|
6dcb0fafc0 | ||
|
|
208ab56d0e | ||
|
|
07f867ad6d | ||
|
|
50fde8f9bf | ||
|
|
ff6b2c4e32 | ||
|
|
6a468a25ad | ||
|
|
7c30323708 | ||
|
|
8ce16c67e8 | ||
|
|
7e1c1b8a7d | ||
|
|
f21320e667 | ||
|
|
dbc1de12e1 | ||
|
|
f01d7f1535 | ||
|
|
7b1e3cddcc | ||
|
|
886fb42c5e | ||
|
|
cbb587c043 | ||
|
|
e1bf52860e | ||
|
|
8e62c18e16 | ||
|
|
9047693b1f | ||
|
|
d6bcc68bae | ||
|
|
97b0383924 | ||
|
|
e40152acae | ||
|
|
a68650ca56 | ||
|
|
06c1c55b59 | ||
|
|
920911d833 | ||
|
|
80c1faed7a | ||
|
|
6a5334d1d2 | ||
|
|
66a4fc138e | ||
|
|
aa6cd65d37 | ||
|
|
9d459c294d | ||
|
|
b08e95f2ec | ||
|
|
bbb68ff7c4 | ||
|
|
90951b9802 | ||
|
|
0541554986 | ||
|
|
198567c10e | ||
|
|
097cf904f1 | ||
|
|
7cd3c5a8af | ||
|
|
2452bb56a7 | ||
|
|
2e6127811c | ||
|
|
e09547feab | ||
|
|
9e5f1eb2d7 | ||
|
|
90b94119f2 | ||
|
|
a2865f1586 | ||
|
|
d436a5d9b8 | ||
|
|
e0c238206c | ||
|
|
a7e1232fb4 | ||
|
|
6f0e9c7256 | ||
|
|
9891cf33f1 | ||
|
|
85464ece1b | ||
|
|
cd6f6b06cd | ||
|
|
39291859ec | ||
|
|
37cb3bdc77 | ||
|
|
0d59d95b5b | ||
|
|
e23f645442 | ||
|
|
e626ceb6f3 | ||
|
|
2e656a5d05 | ||
|
|
6777cffbd4 | ||
|
|
8bf0200220 | ||
|
|
45c64dcabf | ||
|
|
d00c7a5d65 | ||
|
|
4529a19763 | ||
|
|
d57d405e1b | ||
|
|
e5e71aca37 | ||
|
|
8bb341f696 | ||
|
|
cb6dfcbd0d | ||
|
|
6ca3aa2d4b | ||
|
|
1d956f2ffb | ||
|
|
52dce3bde7 | ||
|
|
078a4efdc5 | ||
|
|
3c5121e423 | ||
|
|
25bf469b57 | ||
|
|
549676bb1b | ||
|
|
4a2ae8a1f7 | ||
|
|
08c7858450 | ||
|
|
f67c8c6604 | ||
|
|
2bfa6bc650 | ||
|
|
c9230c75f8 | ||
|
|
bb90df86f3 | ||
|
|
76e9833b1c | ||
|
|
21ce573416 | ||
|
|
0be8adb641 | ||
|
|
42a70603a8 | ||
|
|
1fc8f8c3f8 | ||
|
|
a4508906c9 | ||
|
|
203c955ab1 | ||
|
|
1d01601abf | ||
|
|
5d15eacbd0 | ||
|
|
b9558bdaf7 | ||
|
|
a14c53ced8 | ||
|
|
f1dd692a10 | ||
|
|
709fbb3aea | ||
|
|
c77879a0aa | ||
|
|
41f05f4f4f | ||
|
|
7b7f02cbbb | ||
|
|
124d2ed057 | ||
|
|
eb194fa0f3 | ||
|
|
eb0f7ed1dc | ||
|
|
07519f677b | ||
|
|
8e4c7ca951 | ||
|
|
358e7b8f73 | ||
|
|
f29b2d7a5a | ||
|
|
ec858e0e2e | ||
|
|
e9a33706cf | ||
|
|
ffc37ede08 | ||
|
|
b7248a04ff | ||
|
|
782c121628 | ||
|
|
7c8932030a | ||
|
|
c91bd27a0d | ||
|
|
a5341f715d | ||
|
|
f2c41be269 | ||
|
|
67b4a181f1 | ||
|
|
b18778f96b | ||
|
|
869c523461 | ||
|
|
ac2452449e | ||
|
|
74be6c515d | ||
|
|
e87d403a87 | ||
|
|
3d5e600195 | ||
|
|
4e227c17b8 | ||
|
|
cdd298d34e | ||
|
|
f710a2904c | ||
|
|
0edf9c3e5b | ||
|
|
205a873549 | ||
|
|
2ea644076a | ||
|
|
0511e7ed10 | ||
|
|
4363ad2d1c | ||
|
|
1a30703b5a | ||
|
|
d9c69f0384 | ||
|
|
9a91da6e4f | ||
|
|
bc88334121 | ||
|
|
ec95880ac3 | ||
|
|
f2315059e8 | ||
|
|
91cb6b4d5f | ||
|
|
8a85201ae7 | ||
|
|
ef91590602 | ||
|
|
a114c5d4b6 | ||
|
|
03488dbd76 | ||
|
|
e961effb51 | ||
|
|
ab8dd5f7af | ||
|
|
bed939da0c | ||
|
|
8369a4d6b3 | ||
|
|
22e8613d08 | ||
|
|
12a64b10ee | ||
|
|
b43fed1d39 | ||
|
|
0528ab823d | ||
|
|
ba26b78674 | ||
|
|
d0f99b6adf | ||
|
|
382467b1c5 | ||
|
|
d94fde42b5 | ||
|
|
32ad2865bd | ||
|
|
0dc8ec6dcf | ||
|
|
4991108e18 | ||
|
|
3ee77d44ad | ||
|
|
f2777d6c3b | ||
|
|
a269a2d8af | ||
|
|
6d7e8422ac | ||
|
|
6482321617 | ||
|
|
9db8810c7f | ||
|
|
d9c68992f1 | ||
|
|
e20cdede10 | ||
|
|
156525003c | ||
|
|
3023c102b3 | ||
|
|
3b9873b91d | ||
|
|
2f28084d9c | ||
|
|
84adad7cfd | ||
|
|
cab1f355da | ||
|
|
523c3bb413 | ||
|
|
f1401a7693 | ||
|
|
f51601d77d | ||
|
|
74d315519b | ||
|
|
cb1afd5aab | ||
|
|
0031407fff | ||
|
|
b410a3123a | ||
|
|
4eed5f219f | ||
|
|
37b1d8bb84 | ||
|
|
11ee4ee9c4 | ||
|
|
09b616fe7f | ||
|
|
e9f49878e0 | ||
|
|
3a4a1e73ec | ||
|
|
7ccaab0a6d | ||
|
|
dd2fe64355 | ||
|
|
5353f48c17 | ||
|
|
6648247d0a | ||
|
|
8fbc473992 | ||
|
|
4a0d23d8a1 | ||
|
|
2d2c0c2393 | ||
|
|
d7f9122983 | ||
|
|
bbae1bd48a | ||
|
|
11a0c5a766 | ||
|
|
e33c22e61c | ||
|
|
473d9738de | ||
|
|
0e009632ff | ||
|
|
d870e0a7f8 | ||
|
|
72e3f18531 | ||
|
|
d3a91e951d | ||
|
|
2ab9331b1f | ||
|
|
f631dca7ab | ||
|
|
87571b6099 | ||
|
|
e3bbd2b4d2 | ||
|
|
55b56670ae | ||
|
|
c5eeb2c136 | ||
|
|
69ad058c39 | ||
|
|
5a4e908c2f | ||
|
|
ff74f89bbc | ||
|
|
54b2ab3d12 | ||
|
|
2cb0ccebfb | ||
|
|
e6816215f5 | ||
|
|
1aeae9f9d8 | ||
|
|
18ecd2efbd | ||
|
|
d2ff66e529 | ||
|
|
852cb95ca6 | ||
|
|
319964a0b9 | ||
|
|
e23c563dc1 | ||
|
|
32391d5069 | ||
|
|
c45031f24b | ||
|
|
d224282d73 | ||
|
|
8570011973 | ||
|
|
d5b26e80b5 | ||
|
|
7898e5691a | ||
|
|
f93474073a | ||
|
|
831acfa75c | ||
|
|
3465d8b944 | ||
|
|
b22c3d41d2 | ||
|
|
a2bf1d1870 | ||
|
|
a83755b6e3 | ||
|
|
753b3ba30b | ||
|
|
158dbc8235 | ||
|
|
fa0c77004b | ||
|
|
52dfafb7f5 | ||
|
|
d2ac90a484 | ||
|
|
1e18e4e052 | ||
|
|
09e3ecde8e | ||
|
|
3f970cef35 | ||
|
|
e060eeca87 | ||
|
|
b64344d306 | ||
|
|
380d95e7a5 | ||
|
|
74d61b95a3 | ||
|
|
151c767b35 | ||
|
|
2b4f41c4eb | ||
|
|
542ea0d46e | ||
|
|
ab3ac54566 | ||
|
|
8e1e8460a5 | ||
|
|
0b87a3e429 | ||
|
|
e361e60f93 | ||
|
|
676971bfa9 | ||
|
|
0df8656abd | ||
|
|
dbb51b6f40 | ||
|
|
87db0f1b7c | ||
|
|
c22b8b7e01 | ||
|
|
810843a592 | ||
|
|
d264f843ac | ||
|
|
b4f72adad4 | ||
|
|
95cfb4e62c | ||
|
|
18a4e27315 | ||
|
|
bebec472d3 | ||
|
|
885cd2945e | ||
|
|
10c3a8e6e6 | ||
|
|
9973ac5dbd | ||
|
|
43b2d916ae | ||
|
|
90bd2338bf | ||
|
|
7b770239cd | ||
|
|
4cf497314b | ||
|
|
3ce59b84ff | ||
|
|
8c893cd195 | ||
|
|
8ac4fd47e1 | ||
|
|
4aee4737a9 | ||
|
|
e86aa844c5 | ||
|
|
2528fb58fb | ||
|
|
b47b03a945 | ||
|
|
52cc47a3b4 | ||
|
|
1d29e1ef73 | ||
|
|
93310f3aba | ||
|
|
526bb3d006 | ||
|
|
faf41b2e2c | ||
|
|
1eca59ad15 | ||
|
|
e8741ef0da | ||
|
|
d8b2f0bfa2 | ||
|
|
9b31fa08f2 | ||
|
|
bffb6242df | ||
|
|
3671aa635f | ||
|
|
6f762782e8 | ||
|
|
e16fa85294 | ||
|
|
a8e22c635f | ||
|
|
da0b5f1673 | ||
|
|
8fdfa5dc77 | ||
|
|
25e93d9a27 | ||
|
|
28d7accdf5 | ||
|
|
c4d2d958f9 | ||
|
|
ef2d87e7f8 | ||
|
|
030d67afb5 | ||
|
|
4fea049c2d | ||
|
|
5252dc47bb | ||
|
|
ba8e95775d | ||
|
|
afde8777b1 | ||
|
|
2b5bf8c307 | ||
|
|
002bf6dab5 | ||
|
|
d9d1195552 | ||
|
|
4b01ff192b | ||
|
|
6d5cf07f3a | ||
|
|
24a7539bcc | ||
|
|
b11596c20d | ||
|
|
5baffa724f | ||
|
|
f60fa60d0d | ||
|
|
143a2f10ae | ||
|
|
bde2220783 | ||
|
|
0df4b867fa | ||
|
|
c1e61042a4 | ||
|
|
53ca285d5a | ||
|
|
7e48b287a0 | ||
|
|
4f383b8009 | ||
|
|
00295ba8ae | ||
|
|
751bb532e5 | ||
|
|
a2758c9ff1 | ||
|
|
fe2deea1b0 | ||
|
|
cbe2b1c903 | ||
|
|
d8fbd33ec4 | ||
|
|
8a4a9dd56e | ||
|
|
0ef3dfa1f3 | ||
|
|
4aa326cdec | ||
|
|
cc49b98e8f | ||
|
|
98d25c91b4 | ||
|
|
7fbc5e1567 | ||
|
|
9bafbe7c3b | ||
|
|
2cc27e2c3f | ||
|
|
aaf4a31edc | ||
|
|
12d62ac932 | ||
|
|
24ea8cdbdb | ||
|
|
1fe1ebd142 | ||
|
|
7201d3fb4e | ||
|
|
916dc87412 | ||
|
|
bc5cb84b7d | ||
|
|
163774c8fa | ||
|
|
34807b3b6a | ||
|
|
cabe11b8bb | ||
|
|
a716b82931 | ||
|
|
ee66c24e6e | ||
|
|
fafc0fa051 | ||
|
|
213d972132 | ||
|
|
1fba148e1a | ||
|
|
a297ef6f7a | ||
|
|
4741d6cb39 | ||
|
|
bafbacf33e | ||
|
|
1ba6073bcf | ||
|
|
b2b12a3b39 | ||
|
|
f9e6ab6990 | ||
|
|
dd585b8afb | ||
|
|
60912c1ab7 | ||
|
|
94b654ec8b | ||
|
|
3ed5dba101 | ||
|
|
a52023aa5c | ||
|
|
6d8324ded8 | ||
|
|
c8552100f8 | ||
|
|
80ecafdb0b | ||
|
|
c220f5cb84 | ||
|
|
a58c45afcb | ||
|
|
baf5f3cdd8 | ||
|
|
e31b548633 | ||
|
|
c1c0e54c21 | ||
|
|
d5313803dd | ||
|
|
f0ee4c3038 | ||
|
|
f2f6b83979 | ||
|
|
a30706db18 | ||
|
|
426232b477 | ||
|
|
cc3d064256 | ||
|
|
f7126a4620 | ||
|
|
ee43c5990a | ||
|
|
3a3815564d | ||
|
|
5cc1583360 | ||
|
|
145b92b4e0 | ||
|
|
8624205ac3 | ||
|
|
5e532f3fdb | ||
|
|
7354b17b08 | ||
|
|
6bd35eae88 | ||
|
|
14fbeb86ee | ||
|
|
5d5a1c8146 | ||
|
|
82cb2bdbde | ||
|
|
b82c3d8415 | ||
|
|
632f9e9157 | ||
|
|
e0d684a014 | ||
|
|
fd1bb7ddff | ||
|
|
7611d4583c | ||
|
|
63c0c63427 | ||
|
|
60b12ef154 | ||
|
|
16970cd980 | ||
|
|
58e7b7a014 | ||
|
|
7b654f5523 | ||
|
|
fcd1b669c2 | ||
|
|
24bd04fee2 | ||
|
|
68c716b7a9 | ||
|
|
6451e6bab8 | ||
|
|
894e464af8 | ||
|
|
bac89dcd18 | ||
|
|
5c68b48267 | ||
|
|
12625e82b0 | ||
|
|
d5049475cd | ||
|
|
e1edc72d4e | ||
|
|
8e5368e211 | ||
|
|
8063a81d4d | ||
|
|
564d265a91 | ||
|
|
fce36dc430 | ||
|
|
91dcdc706b | ||
|
|
e9195f2c1a | ||
|
|
ee1707bf0f | ||
|
|
c9ae74831e | ||
|
|
b81e637fcf | ||
|
|
4d4b9060c6 | ||
|
|
03ce92bfc1 | ||
|
|
b2de047014 | ||
|
|
2b6e1020aa | ||
|
|
208fcfbf53 | ||
|
|
4f282a205a | ||
|
|
8f5a05c6a9 | ||
|
|
015670c2ce | ||
|
|
ff8791e6fc | ||
|
|
e4056bc0c3 | ||
|
|
c7656c6fd8 | ||
|
|
a6bc330a97 | ||
|
|
e8267ff402 | ||
|
|
078b88cd16 | ||
|
|
1b228c0c35 | ||
|
|
6db5e213eb | ||
|
|
6011dac0ce | ||
|
|
edb8d2bfc5 | ||
|
|
e33d3a5d85 | ||
|
|
c894badf77 | ||
|
|
971e5ee6f9 | ||
|
|
6211f15994 | ||
|
|
eba55b0098 | ||
|
|
97f3bb4644 | ||
|
|
ac25454915 | ||
|
|
a59dbb66dc | ||
|
|
80cc6ce977 | ||
|
|
5e3263dec3 | ||
|
|
aab7c74474 | ||
|
|
115916a9f9 | ||
|
|
9cf3c5b71e | ||
|
|
a12453aa1d | ||
|
|
adfff835d1 | ||
|
|
4fdba5f39a | ||
|
|
5a89240a61 | ||
|
|
4b40259c93 | ||
|
|
79e58187f1 | ||
|
|
cca28c35a7 | ||
|
|
7163d7e630 | ||
|
|
81f70d04c2 | ||
|
|
7f5b7fbec6 | ||
|
|
2f4a4011f8 | ||
|
|
0553baaac8 | ||
|
|
4a8b3a4cc1 | ||
|
|
31cda87d29 | ||
|
|
eaae1ef854 | ||
|
|
e91ef6a623 | ||
|
|
5073b5543c | ||
|
|
ef6c33b3b4 | ||
|
|
44d6000048 | ||
|
|
a8a60fb947 | ||
|
|
badd46c679 | ||
|
|
d7d4acbb58 | ||
|
|
80d7e588b6 | ||
|
|
7a37728c8b | ||
|
|
16d1a1abce | ||
|
|
066b7be393 | ||
|
|
8c4e29d98b | ||
|
|
63beaf9258 | ||
|
|
9e0b47a9fc | ||
|
|
2ab055e7a8 | ||
|
|
d30accaa19 | ||
|
|
48fdbf0aac | ||
|
|
989d2c06c8 | ||
|
|
04d4dd003f | ||
|
|
be497cfcaf | ||
|
|
3dbdefe715 | ||
|
|
303dcdca99 | ||
|
|
cfb4490a6d | ||
|
|
d5e5288bd2 | ||
|
|
1b0de278ae | ||
|
|
0fbcaf1c7e | ||
|
|
0ac21e3c4e | ||
|
|
b693c45ddd | ||
|
|
460478c6a2 | ||
|
|
0136227b4c | ||
|
|
f6d85e4014 | ||
|
|
22c91bf68c | ||
|
|
a50380028f | ||
|
|
1c8dd77738 | ||
|
|
ffd67953f7 | ||
|
|
8a483e88fa | ||
|
|
529a5f00f4 | ||
|
|
e66fe77265 | ||
|
|
ae3dc849e4 | ||
|
|
fabe1aa013 | ||
|
|
0ccb87cb94 | ||
|
|
ea12105a03 | ||
|
|
76b214e5bf | ||
|
|
1a9e41eca3 | ||
|
|
1f5d23a1a9 | ||
|
|
9554eaa726 | ||
|
|
fae11760d2 | ||
|
|
417f01da21 | ||
|
|
b6f1f4f2ab | ||
|
|
7c81a895d5 | ||
|
|
ba0674fcb1 | ||
|
|
6abd3efb95 | ||
|
|
5d7e8809e3 | ||
|
|
499dcdd4c4 | ||
|
|
be27baa9e5 | ||
|
|
7410de9dcf | ||
|
|
b966320f77 | ||
|
|
dbdb6e963c | ||
|
|
7235941152 | ||
|
|
2d7342c91a | ||
|
|
e3b2558333 | ||
|
|
b625adc085 | ||
|
|
8a6cd18038 | ||
|
|
1b1913d335 | ||
|
|
a825b27ccd | ||
|
|
8665068892 | ||
|
|
b4a68effbc | ||
|
|
0567c540ce | ||
|
|
a24a94df2b | ||
|
|
7108f5521b | ||
|
|
ca8ec01603 | ||
|
|
9a0e0e7e6c | ||
|
|
5244b20f21 | ||
|
|
b108e7ad9a | ||
|
|
2242491f83 | ||
|
|
6206fed2f8 | ||
|
|
1f9087aee2 | ||
|
|
20059b3ebf | ||
|
|
e70a7d78ab | ||
|
|
f757bb53d9 | ||
|
|
d4439b4cd4 | ||
|
|
6e0abad03c | ||
|
|
8647d4467d | ||
|
|
593d610461 | ||
|
|
569f5c3f9b | ||
|
|
355c998d60 | ||
|
|
52aa024568 | ||
|
|
5b024c9a36 | ||
|
|
d06f8949bf | ||
|
|
0f6ad2bca8 | ||
|
|
aed1577472 | ||
|
|
805e283687 | ||
|
|
97eb058ecf | ||
|
|
9aea8d8c8a | ||
|
|
e5ae6029c2 | ||
|
|
822f21eea8 | ||
|
|
fea3390ef3 | ||
|
|
839da8855c | ||
|
|
10bb09a8cc | ||
|
|
b09445ffae | ||
|
|
8ac4b09771 | ||
|
|
3d2f33309a | ||
|
|
27862bf4c9 | ||
|
|
e847bfa9fc | ||
|
|
8055376766 | ||
|
|
515be43181 | ||
|
|
ae1597fb53 | ||
|
|
d174d77c0d | ||
|
|
30bedc0c15 | ||
|
|
d2782e3433 | ||
|
|
38c14d7d9b | ||
|
|
e825e4fa37 | ||
|
|
dc7998aa74 | ||
|
|
431b9430e2 | ||
|
|
34a209dee9 | ||
|
|
1a0b185def | ||
|
|
aae8cc43f9 | ||
|
|
8775a70590 | ||
|
|
33705263e3 | ||
|
|
a34dc194a1 | ||
|
|
5d377d0e51 | ||
|
|
b01b21f271 | ||
|
|
fe28278076 | ||
|
|
f95d277640 | ||
|
|
770e777e15 | ||
|
|
41848d2dc1 | ||
|
|
f722a9e4ca | ||
|
|
c646654d65 | ||
|
|
2310f4bb02 | ||
|
|
9d3c09e499 | ||
|
|
160da9ebea | ||
|
|
cf2a242872 | ||
|
|
4c18e0e983 | ||
|
|
05de20ee72 | ||
|
|
74a9f8ac7f | ||
|
|
8e55c751f8 | ||
|
|
c046563bef | ||
|
|
dd0e402511 | ||
|
|
9de6badecc | ||
|
|
cc02077bf4 | ||
|
|
115c4fd30f | ||
|
|
b24601f47a | ||
|
|
297d2be210 | ||
|
|
5f36d3920b | ||
|
|
b80cd5f40d | ||
|
|
26a0c276f3 | ||
|
|
fae0461504 | ||
|
|
9673c5223b | ||
|
|
faa4c41b89 | ||
|
|
00b8453faf | ||
|
|
7f3824b5f9 | ||
|
|
7ab717dc91 | ||
|
|
e76bf13833 | ||
|
|
633227fb49 | ||
|
|
f89e002d9a | ||
|
|
7c082289f9 | ||
|
|
d24d7b45a3 | ||
|
|
33e2908492 | ||
|
|
b10221e068 | ||
|
|
766caca32d | ||
|
|
892c5eb1e6 | ||
|
|
7f1cb0474e | ||
|
|
a28269caee | ||
|
|
2bf10202ae | ||
|
|
629a72f068 | ||
|
|
8713748aad | ||
|
|
fe828e0645 | ||
|
|
93afe6ccae | ||
|
|
a77d152f8d | ||
|
|
d620891dff | ||
|
|
4a5ef8721e | ||
|
|
2f48795651 | ||
|
|
623c458776 | ||
|
|
224326487c | ||
|
|
b935d3e71f | ||
|
|
459e253686 | ||
|
|
7a07b719a8 | ||
|
|
5c06b75b12 | ||
|
|
165a7426d1 | ||
|
|
147d398067 | ||
|
|
bf8653ae6c | ||
|
|
7ca937a745 | ||
|
|
785aac52c5 | ||
|
|
c70dc42833 | ||
|
|
e18d3bd2be | ||
|
|
52adfce138 | ||
|
|
b5dc667a1c | ||
|
|
8a7fa9ef6f | ||
|
|
11ac3d9f0a | ||
|
|
a66da89fdb | ||
|
|
1d03732438 | ||
|
|
70b1ccb458 | ||
|
|
b119d8da26 | ||
|
|
6ddc7d5926 |
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
.env
|
||||
363
README.md
363
README.md
@@ -1,20 +1,353 @@
|
||||
Place val.key and val.pass into ./harmony/keyfiles
|
||||
# Blockchain Node Configurations
|
||||
|
||||
```
|
||||
docker-compose up -d
|
||||
```
|
||||
Check if Bootstrap is working.
|
||||
```
|
||||
docker logs -f pokt_dokt_harmony-mainnet_1
|
||||
```
|
||||
Logs are at:
|
||||
```
|
||||
harmony/log
|
||||
This directory contains Docker Compose configurations for various blockchain networks and node implementations.
|
||||
|
||||
## Directory Structure
|
||||
|
||||
- Root level YAML files (e.g. `ethereum-mainnet.yml`, `arbitrum-one.yml`) - Main Docker Compose configurations for specific networks
|
||||
- Network-specific subdirectories - Contain additional configurations, genesis files, and client-specific implementations
|
||||
- Utility scripts (e.g. `show-networks.sh`, `logs.sh`) - Helper scripts for managing and monitoring nodes
|
||||
|
||||
## Node Types
|
||||
|
||||
This repository supports multiple node types for various blockchain networks:
|
||||
|
||||
- **Ethereum networks**: Mainnet, Sepolia, Holesky
|
||||
- **Layer 2 networks**: Arbitrum, Optimism, Base, Scroll, ZKSync Era, etc.
|
||||
- **Alternative L1 networks**: Avalanche, BSC, Fantom, Polygon, etc.
|
||||
|
||||
Most networks have both archive and pruned node configurations available, with support for different client implementations (Geth, Erigon, Reth, etc.).
|
||||
|
||||
## Quick Start
|
||||
|
||||
1. Create a `.env` file in this directory (see example below)
|
||||
2. Select which node configurations you want to run by adding them to the `COMPOSE_FILE` variable
|
||||
3. Run `docker compose up -d`
|
||||
4. Access your RPC endpoints at `https://yourdomain.tld/path` or `http://localhost:port`
|
||||
|
||||
### Example .env File
|
||||
|
||||
```bash
|
||||
# Domain settings
|
||||
DOMAIN=203-0-113-42.traefik.me # Use your PUBLIC IP with dots replaced by hyphens
|
||||
MAIL=your-email@example.com # Required for Let's Encrypt SSL
|
||||
WHITELIST=0.0.0.0/0 # IP whitelist for access (0.0.0.0/0 allows all)
|
||||
|
||||
# Public IP (required for many chains)
|
||||
IP=203.0.113.42 # Your PUBLIC IP (get it with: curl ipinfo.io/ip)
|
||||
|
||||
# Network settings
|
||||
CHAINS_SUBNET=192.168.0.0/26
|
||||
|
||||
# RPC provider endpoints (fallback/bootstrap nodes)
|
||||
ETHEREUM_MAINNET_EXECUTION_RPC=https://ethereum-rpc.publicnode.com
|
||||
ETHEREUM_MAINNET_EXECUTION_WS=wss://ethereum-rpc.publicnode.com
|
||||
ETHEREUM_MAINNET_BEACON_REST=https://ethereum-beacon-api.publicnode.com
|
||||
|
||||
ETHEREUM_SEPOLIA_EXECUTION_RPC=https://ethereum-sepolia-rpc.publicnode.com
|
||||
ETHEREUM_SEPOLIA_EXECUTION_WS=wss://ethereum-sepolia-rpc.publicnode.com
|
||||
ETHEREUM_SEPOLIA_BEACON_REST=https://ethereum-sepolia-beacon-api.publicnode.com
|
||||
|
||||
ARBITRUM_SEPOLIA_EXECUTION_RPC=https://arbitrum-sepolia-rpc.publicnode.com
|
||||
ARBITRUM_SEPOLIA_EXECUTION_WS=wss://arbitrum-sepolia-rpc.publicnode.com
|
||||
|
||||
# SSL settings (set NO_SSL=true to disable SSL)
|
||||
# NO_SSL=true
|
||||
|
||||
# Docker Compose configuration
|
||||
# Always include base.yml and rpc.yml, then add the networks you want
|
||||
COMPOSE_FILE=base.yml:rpc.yml:ethereum-mainnet.yml
|
||||
```
|
||||
|
||||
HARMONY QUERY
|
||||
```
|
||||
curl --location --request POST 'https://$DOMAIN/' --header 'Content-Type: application/json' --data-raw '{"jsonrpc": "2.0", "method": "hmy_latestHeader", "params": [], "id": 1}'
|
||||
## Usage
|
||||
|
||||
To start nodes defined in your `.env` file:
|
||||
|
||||
```bash
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
[HMY CLI Flags](https://docs.harmony.one/home/network/validators/node-setup/installing-updating/installing-node/using-binary#option-2-setup-using-flag-parsing)
|
||||
### Ports
|
||||
|
||||
The default ports are defined in the templates. They are randomised to avoid conflicts. Some configurations can require 7 ports to be opened for P2P discovery. Docker will override any UFW firewall rule that you define on the host. You should prevent the containers to try to reach out to other nodes on local IP ranges.
|
||||
|
||||
You can use the following service definition as a starting point. Replace the {{ chains_subnet }} with the subnet of your network. Default is 192.168.0.0/26.
|
||||
|
||||
```
|
||||
[Unit]
|
||||
Description= iptables firewall docker fix
|
||||
After=docker.service
|
||||
|
||||
[Service]
|
||||
ExecStart=/usr/local/bin/iptables-firewall.sh start
|
||||
RemainAfterExit=true
|
||||
StandardOutput=journal
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
PATH="/sbin:/usr/sbin:/bin:/usr/bin"
|
||||
|
||||
# Flush existing rules in the DOCKER-USER chain
|
||||
# this is potentially dangerous if other scripts write in that chain too but for now this should be the only one
|
||||
iptables -F DOCKER-USER
|
||||
|
||||
# block heise.de to test it's working. ./ping.sh heise.de will ping from a container in the subnet.
|
||||
iptables -I DOCKER-USER -s {{ chains_subnet }} -d 193.99.144.80/32 -j REJECT
|
||||
|
||||
# block local networks
|
||||
iptables -I DOCKER-USER -s {{ chains_subnet }} -d 192.168.0.0/16 -j REJECT
|
||||
iptables -I DOCKER-USER -s {{ chains_subnet }} -d 172.16.0.0/12 -j REJECT
|
||||
iptables -I DOCKER-USER -s {{ chains_subnet }} -d 10.0.0.0/8 -j REJECT
|
||||
|
||||
# accept the subnet so containers can reach each other.
|
||||
iptables -I DOCKER-USER -s {{ chains_subnet }} -d {{ chains_subnet }} -j ACCEPT
|
||||
|
||||
# I don't know why that is
|
||||
iptables -I DOCKER-USER -s {{ chains_subnet }} -d 10.13.13.0/24 -j ACCEPT
|
||||
```
|
||||
|
||||
|
||||
### Node Structure
|
||||
|
||||
In general Nodes can have one or all of the following components:
|
||||
|
||||
- a client (execution layer)
|
||||
- a node (for consensus)
|
||||
- a relay (for data availability access)
|
||||
- a database (external to the client mostly zk rollups, can have mulitple databases)
|
||||
- a proxy (to map http access and websockets to the same endpoint)
|
||||
|
||||
The simplest examples have only a client. The compose files define one entrypoint to query the node. usually it's the client otherwise it's the proxy. some clients have multiple entrypoints because they allow to query the consensus layer and the execution layer.
|
||||
|
||||
In the root folder of this repository you can find convenience yml files which are symlinks to specific compose files. The naming for the symlinks follow the principle {network_name}-{chain_name}.yml which leaves the client and bd type unspecified so they are defaults.
|
||||
|
||||
|
||||
### Syncing
|
||||
|
||||
The configurations aim to work standalone restoring state as much as possible from public sources. Using snapshots can help syncing faster. For some configurations it's not reasonably possible to maintain a version that can be bootstrapped from scratch using only the compose file.
|
||||
|
||||
|
||||
### Naming conventions
|
||||
|
||||
- default client is the default client for the network. Usually it's geth or op-geth.
|
||||
- default sync mode is pruned. If available clients are snap synced.
|
||||
- default node is op-node or prysm or whatever is the default for the network (e.g. beacon-kit for berachain, goat for goat, etc.)
|
||||
- default sync mode for nodes is pruned
|
||||
- default client for archive nodes is (op-)erigon or (op-)reth
|
||||
- default sync mode for (op-)reth and (op-)erigon is archive-trace.
|
||||
- default sync mode for erigon3 is pruned-trace.
|
||||
- default db is postgres
|
||||
- default proxy is nginx
|
||||
|
||||
#### Node features
|
||||
|
||||
The idea is to assume a default node configuration that is able to drive the execution client. In case the beacon node database has special features then the file name would include the features after a double hyphen. e.g. `ethereum-mainnet-geth-pruned-pebble-hash--lighthouse-pruned-blobs.yml` would be a node that has a pruned execution client and a pruned beacon node database with a complete blob history.
|
||||
|
||||
#### Container names
|
||||
|
||||
The docker containers are generally named using the base name and the component suffix. The base name is generally the network name and the chain name and the sync mode archive in case of archive nodes. The rationale is that it doesn't make sense to run 2 pruned nodes for the same chain on the same machine as well as 2 archive nodes for the same chain. The volumes that are created in /var/lib/docker/volumes are using the full name of the node including the sync mode and database features. This is to allow switching out the implementation of parts of the configuration and not causing conflicts, e.g. exchanging prysm for nimbus as node implementation but keep using the same exection client. Environment variables are also using the full name of the component that they are defined for.
|
||||
|
||||
|
||||
## Utility Scripts
|
||||
|
||||
This directory includes several useful scripts to help you manage and monitor your nodes:
|
||||
|
||||
### Status and Monitoring
|
||||
|
||||
- `show-status.sh [config-name]` - Check sync status of all configured nodes (or specific config if provided)
|
||||
- `show-db-size.sh` - Display disk usage of all Docker volumes, sorted by size
|
||||
- `show-networks.sh` - List all available network configurations
|
||||
- `show-running.sh` - List currently running containers
|
||||
- `sync-status.sh <config-name>` - Check synchronization status of a specific configuration
|
||||
- `logs.sh <config-name>` - View logs of all containers for a specific configuration
|
||||
- `latest.sh <config-name>` - Get the latest block number and hash of a local node
|
||||
- `ping.sh <container-name>` - Test connectivity to a container from inside the Docker network
|
||||
|
||||
### Node Management
|
||||
|
||||
- `stop.sh <config-name>` - Stop all containers for a specific configuration
|
||||
- `force-recreate.sh <config-name>` - Force recreate all containers for a specific configuration
|
||||
- `backup-node.sh <config-name> [webdav_url]` - Backup Docker volumes for a configuration (locally or to WebDAV)
|
||||
- `restore-volumes.sh <config-name> [http_url]` - Restore Docker volumes from backup (local or HTTP source)
|
||||
- `cleanup-backups.sh` - Clean up old backup files
|
||||
- `list-backups.sh` - List available backup files
|
||||
- `op-wheel.sh` - Tool for Optimism rollup maintenance, including rewinding to a specific block
|
||||
|
||||
|
||||
Note: `<config-name>` refers to the compose file name without the .yml extension (e.g., `ethereum-mainnet` for ethereum-mainnet.yml)
|
||||
|
||||
|
||||
#### Nuclear option to recreate a node
|
||||
|
||||
```bash
|
||||
./stop.sh <config-name> && ./rm.sh <config-name> && ./delete-volumes.sh <config-name> && ./force-recreate.sh <config-name> && ./logs.sh <config-name>
|
||||
```
|
||||
|
||||
#### Debugging tips
|
||||
|
||||
To get the configuration name for one of the commands use `./show-status.sh` which lists all the configrations and their status to copy paste for further inspection with e.g. `./catchup.sh <config-name>` or repeated use of `./latest.sh <config-name>` which will give you and idea if the sync is actually progressing and if it is on the canonical chain.
|
||||
Note: some configurations use staged sync which means that there is no measurable progress on the RPC in between bacthes of processed blocks. In any case `./logs.sh <config-name>` will give you insights into problems, potentially filtered by a LLM to spot common errors. It could be that clients are syncing slower than the chain progresses.
|
||||
|
||||
#### Further automation
|
||||
|
||||
You can chain `./success-if-almost-synced.sh <config-name> <age-of-last-block-in-seconds-to-be-considered-almost-synced>` with other scripts to create more complex automation, e.g. notify you once a node synced up to chainhead or adding the node to the dshackle configuration or taking a backup to clone the node to a different server.
|
||||
|
||||
#### OP Wheel Usage Example
|
||||
|
||||
Be aware that this is dangerous because you skip every check for your rollups op-geth execution client database to be consistent.
|
||||
|
||||
```bash
|
||||
# Rewind an Optimism rollup to a specific block
|
||||
./op-wheel.sh engine set-forkchoice --unsafe=0x111AC7F --safe=0x111AC7F --finalized=0x111AC7F \
|
||||
--engine=http://op-lisk-sepolia:8551/ --engine.open=http://op-lisk-sepolia:8545 \
|
||||
--engine.jwt-secret-path=/jwtsecret
|
||||
```
|
||||
|
||||
Nuclear option:
|
||||
```bash
|
||||
# Finalize the latest locally available block of an Optimism rollup
|
||||
./op-wheel-finalize-latest-block.sh <client_service_name> (<node_service_name>)
|
||||
```
|
||||
|
||||
Where `<client_service_name>` is the name of the client service in the compose file and `<node_service_name>` is the name of the node service in the compose file which defaults to `<client_service_name>-node`.
|
||||
|
||||
## SSL Certificates and IP Configuration
|
||||
|
||||
### Public IP Configuration
|
||||
|
||||
Many blockchain nodes require your public IP address to function properly:
|
||||
|
||||
1. Get your public IP address:
|
||||
```bash
|
||||
curl ipinfo.io/ip
|
||||
```
|
||||
|
||||
2. Add this IP to your `.env` file:
|
||||
```bash
|
||||
IP=203.0.113.42 # Your actual public IP
|
||||
```
|
||||
|
||||
3. This IP is used by several chains for P2P discovery and network communication
|
||||
|
||||
### SSL Certificates with Traefik
|
||||
|
||||
This system uses Traefik as a reverse proxy for SSL certificates:
|
||||
|
||||
1. By default, certificates are obtained from Let's Encrypt
|
||||
2. Use your **public** IP address with traefik.me by replacing dots with hyphens
|
||||
```
|
||||
# If your public IP is 203.0.113.42
|
||||
DOMAIN=203-0-113-42.traefik.me
|
||||
```
|
||||
3. Traefik.me automatically generates valid SSL certificates for this domain
|
||||
4. For production, use your own domain and set MAIL for Let's Encrypt notifications
|
||||
5. To disable SSL, set `NO_SSL=true` in your .env file
|
||||
|
||||
## Configuration
|
||||
|
||||
Each network configuration includes:
|
||||
|
||||
- Node client software (Geth, Erigon, etc.)
|
||||
- Synchronization type (archive or pruned)
|
||||
- Database backend and configuration
|
||||
- Network-specific parameters
|
||||
|
||||
## Accessing RPC Endpoints
|
||||
|
||||
Once your nodes are running, you can access the RPC endpoints at:
|
||||
|
||||
- HTTPS: `https://yourdomain.tld/ethereum` (or other network paths)
|
||||
- HTTP: `http://yourdomain.tld/ethereum` (or other network paths)
|
||||
- WebSocket: `wss://yourdomain.tld/ethereum` (same URL as HTTP/HTTPS)
|
||||
|
||||
All services use standard ports (80 for HTTP, 443 for HTTPS), so no port specification is required in the URL.
|
||||
|
||||
## Resource Requirements
|
||||
|
||||
Different node types have different hardware requirements:
|
||||
|
||||
- Pruned Ethereum node: ~500GB disk, 8GB RAM
|
||||
- Archive Ethereum node: ~2TB disk, 16GB RAM
|
||||
- L2 nodes typically require less resources than L1 nodes
|
||||
- Consider using SSD or NVMe storage for better performance
|
||||
|
||||
## DRPC Integration
|
||||
|
||||
This system includes support for DRPC (Decentralized RPC) integration, allowing you to monetize your RPC nodes by selling excess capacity:
|
||||
|
||||
### Setting Up DRPC
|
||||
|
||||
1. Add `drpc.yml` to your `COMPOSE_FILE` variable in `.env`
|
||||
2. Configure the following variables in your `.env` file:
|
||||
```
|
||||
GW_DOMAIN=your-gateway-domain.com
|
||||
GW_REDIS_RAM=2gb # Memory allocation for Redis
|
||||
DRPC_VERSION=0.64.16 # Or latest version
|
||||
```
|
||||
3. Generate the upstream configurations for dshackle:
|
||||
```bash
|
||||
# Using domain URLs (default)
|
||||
./upstreams.sh
|
||||
|
||||
```
|
||||
|
||||
The `upstreams.sh` script automatically detects all running nodes on your machine and generates the appropriate configuration for the dshackle load balancer. This allows you to connect your nodes to drpc.org and sell RPC capacity.
|
||||
|
||||
For more information about DRPC, visit [drpc.org](https://drpc.org/).
|
||||
|
||||
## Supported Networks
|
||||
|
||||
This repository supports a comprehensive range of blockchain networks:
|
||||
|
||||
### Layer 1 Networks
|
||||
- **Major Networks**: Ethereum (Mainnet, Sepolia, Holesky), BSC, Polygon, Avalanche, Gnosis
|
||||
- **Alternative L1s**: Fantom, Core, Berachain, Ronin, Viction, Fuse, Tron, ThunderCore
|
||||
- **Emerging L1s**: Goat, AlephZero, Haqq, Taiko, Rootstock
|
||||
|
||||
### Layer 2 Networks
|
||||
- **OP Stack**: Optimism, Base, Zora, Mode, Blast, Fraxtal, Bob, Boba, Worldchain, Metal, Ink, Lisk, SNAX, Celo
|
||||
- **Arbitrum Ecosystem**: Arbitrum One, Arbitrum Nova, Everclear, Playblock, Real, Connext, OpenCampusCodex
|
||||
- **Other L2s**: Linea, Scroll, zkSync Era, Metis, Moonbeam
|
||||
|
||||
Most networks support multiple node implementations (Geth, Erigon, Reth) and environments (mainnet, testnet).
|
||||
|
||||
## Backup and Restore System
|
||||
|
||||
This repository includes a comprehensive backup and restore system for Docker volumes:
|
||||
|
||||
### Local Backups
|
||||
|
||||
- `backup-node.sh <config-name>` - Create a backup of all volumes for a configuration to the `/backup` directory
|
||||
- `restore-volumes.sh <config-name>` - Restore volumes from the latest backup in the `/backup` directory
|
||||
|
||||
### Remote Backups
|
||||
|
||||
To serve backups via HTTP and WebDAV:
|
||||
|
||||
1. Add `backup-http.yml` to your `COMPOSE_FILE` variable in `.env`
|
||||
2. This exposes:
|
||||
- HTTP access to backups at `https://yourdomain.tld/backup`
|
||||
- WebDAV access at `https://yourdomain.tld/dav`
|
||||
|
||||
### Cross-Server Backup and Restore
|
||||
|
||||
For multi-server setups:
|
||||
|
||||
1. On server A: Include `backup-http.yml` in `COMPOSE_FILE` to serve backups
|
||||
2. On server B: Use restore from server A's backups:
|
||||
```bash
|
||||
# Restore directly from server A
|
||||
./restore-volumes.sh ethereum-mainnet https://serverA.domain.tld/backup/
|
||||
```
|
||||
|
||||
3. Create backups on server B and send to server A via WebDAV:
|
||||
```bash
|
||||
# Backup to server A's WebDAV
|
||||
./backup-node.sh ethereum-mainnet https://serverA.domain.tld/dav
|
||||
```
|
||||
|
||||
This allows for efficient volume transfers between servers without needing SSH access.
|
||||
1
abstract-mainnet.yml
Symbolic link
1
abstract-mainnet.yml
Symbolic link
@@ -0,0 +1 @@
|
||||
abstract/external-node/abstract-mainnet-external-node-pruned.yml
|
||||
1
abstract-testnet.yml
Symbolic link
1
abstract-testnet.yml
Symbolic link
@@ -0,0 +1 @@
|
||||
abstract/external-node/abstract-testnet-external-node-pruned.yml
|
||||
@@ -0,0 +1,172 @@
|
||||
---
|
||||
x-logging-defaults: &logging-defaults
|
||||
driver: json-file
|
||||
options:
|
||||
max-size: "10m"
|
||||
max-file: "3"
|
||||
|
||||
# Usage:
|
||||
#
|
||||
# mkdir rpc && cd rpc
|
||||
#
|
||||
# git init
|
||||
# git remote add origin https://github.com/StakeSquid/ethereum-rpc-docker.git
|
||||
# git fetch origin vibe
|
||||
# git checkout origin/vibe
|
||||
#
|
||||
# docker run --rm alpine sh -c "printf '0x'; head -c32 /dev/urandom | xxd -p -c 64" > .jwtsecret
|
||||
#
|
||||
# env
|
||||
# ...
|
||||
# IP=$(curl ipinfo.io/ip)
|
||||
# DOMAIN=${IP}.traefik.me
|
||||
# COMPOSE_FILE=base.yml:rpc.yml:abstract/external-node/abstract-mainnet-external-node-archive.yml
|
||||
#
|
||||
# docker compose up -d
|
||||
#
|
||||
# curl -X POST https://${IP}.traefik.me/abstract-mainnet-archive \
|
||||
# -H "Content-Type: application/json" \
|
||||
# --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'
|
||||
|
||||
services:
|
||||
abstract-mainnet-archive-client:
|
||||
image: ${ABSTRACT_EXTERNAL_NODE_IMAGE:-matterlabs/external-node}:${ABSTRACT_MAINNET_EXTERNAL_NODE_VERSION:-v27.5.7}
|
||||
sysctls:
|
||||
# TCP Performance
|
||||
net.ipv4.tcp_slow_start_after_idle: 0 # Disable slow start after idle
|
||||
net.ipv4.tcp_no_metrics_save: 1 # Disable metrics cache
|
||||
net.ipv4.tcp_rmem: 4096 87380 16777216 # Increase TCP read buffers
|
||||
net.ipv4.tcp_wmem: 4096 87380 16777216 # Increase TCP write buffers
|
||||
net.core.somaxconn: 32768 # Higher connection queue
|
||||
# Memory/Connection Management
|
||||
# net.core.netdev_max_backlog: 50000 # Increase network buffer
|
||||
net.ipv4.tcp_max_syn_backlog: 30000 # More SYN requests
|
||||
net.ipv4.tcp_max_tw_buckets: 2000000 # Allow more TIME_WAIT sockets
|
||||
ulimits:
|
||||
nofile: 1048576 # Max open files (for RPC/WS connections)
|
||||
user: root
|
||||
ports:
|
||||
- 12612:12612
|
||||
- 12612:12612/udp
|
||||
expose:
|
||||
- 8545
|
||||
- 8546
|
||||
environment:
|
||||
- DATABASE_POOL_SIZE=50
|
||||
- DATABASE_URL=postgres://postgres:notsecurepassword@abstract-mainnet-archive-db:5430/zksync_local_ext_node
|
||||
- EN_API_NAMESAPCES=eth,net,web3,debug,pubsub,debug,zks
|
||||
- EN_ETH_CLIENT_URL=${ETHEREUM_MAINNET_EXECUTION_RPC}
|
||||
- EN_HEALTHCHECK_PORT=3081
|
||||
- EN_HTTP_PORT=8545
|
||||
- EN_L1_CHAIN_ID=1
|
||||
- EN_L2_CHAIN_ID=2741
|
||||
- EN_MAIN_NODE_URL=https://api.mainnet.abs.xyz
|
||||
- EN_MAX_RESPONSE_BODY_SIZE_MB=30
|
||||
- EN_MAX_RESPONSE_BODY_SIZE_OVERRIDES_MB=eth_getLogs=100,eth_getBlockReceipts=None
|
||||
- EN_MERKLE_TREE_PATH=./db/ext-node/lightweight
|
||||
- EN_PROMETHEUS_PORT=3322
|
||||
- EN_PRUNING_ENABLED=false
|
||||
- EN_REQ_ENTITIES_LIMIT=100000
|
||||
- EN_SNAPSHOTS_OBJECT_STORE_BUCKET_BASE_URL=raas-abstract-mainnet-external-node-snapshots
|
||||
- EN_SNAPSHOTS_OBJECT_STORE_MODE=GCSAnonymousReadOnly
|
||||
- EN_SNAPSHOTS_RECOVERY_ENABLED=true
|
||||
- EN_STATE_CACHE_PATH=./db/ext-node/state_keeper
|
||||
- EN_WS_PORT=8546
|
||||
- RUST_LOG=warn,zksync=info,zksync_core::metadata_calculator=debug,zksync_state=info,zksync_utils=info,zksync_web3_decl::client=error
|
||||
restart: unless-stopped
|
||||
stop_grace_period: 5m
|
||||
networks:
|
||||
- chains
|
||||
volumes:
|
||||
- ${ABSTRACT_MAINNET_EXTERNAL_NODE_ARCHIVE_DATA:-abstract-mainnet-external-node-archive}:/db
|
||||
- /slowdisk:/slowdisk
|
||||
logging: *logging-defaults
|
||||
labels:
|
||||
- prometheus-scrape.enabled=false
|
||||
|
||||
abstract-mainnet-archive:
|
||||
image: nginx
|
||||
expose:
|
||||
- '80'
|
||||
environment:
|
||||
PROXY_HOST: abstract-mainnet-archive-client
|
||||
RPC_PATH: ''
|
||||
RPC_PORT: 8545
|
||||
WS_PATH: ''
|
||||
WS_PORT: 8546
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
- abstract-mainnet-archive-client
|
||||
networks:
|
||||
- chains
|
||||
volumes:
|
||||
- ./nginx-proxy:/etc/nginx/templates
|
||||
logging: *logging-defaults
|
||||
labels:
|
||||
- prometheus-scrape.enabled=false
|
||||
- traefik.enable=true
|
||||
- traefik.http.middlewares.abstract-mainnet-external-node-archive-stripprefix.stripprefix.prefixes=/abstract-mainnet-archive
|
||||
- traefik.http.services.abstract-mainnet-external-node-archive.loadbalancer.server.port=80
|
||||
- ${NO_SSL:-traefik.http.routers.abstract-mainnet-external-node-archive.entrypoints=websecure}
|
||||
- ${NO_SSL:-traefik.http.routers.abstract-mainnet-external-node-archive.tls.certresolver=myresolver}
|
||||
- ${NO_SSL:-traefik.http.routers.abstract-mainnet-external-node-archive.rule=Host(`$DOMAIN`) && (Path(`/abstract-mainnet-archive`) || Path(`/abstract-mainnet-archive/`))}
|
||||
- ${NO_SSL:+traefik.http.routers.abstract-mainnet-external-node-archive.rule=Path(`/abstract-mainnet-archive`) || Path(`/abstract-mainnet-archive/`)}
|
||||
- traefik.http.routers.abstract-mainnet-external-node-archive.middlewares=abstract-mainnet-external-node-archive-stripprefix, ipallowlist
|
||||
|
||||
abstract-mainnet-archive-db:
|
||||
image: postgres:14
|
||||
expose:
|
||||
- 5430
|
||||
environment:
|
||||
- PGPORT=5430
|
||||
- POSTGRES_PASSWORD=notsecurepassword
|
||||
command: >
|
||||
postgres
|
||||
-c max_connections=200
|
||||
-c log_error_verbosity=terse
|
||||
-c shared_buffers=2GB
|
||||
-c effective_cache_size=4GB
|
||||
-c maintenance_work_mem=1GB
|
||||
-c checkpoint_completion_target=0.9
|
||||
-c random_page_cost=1.1
|
||||
-c effective_io_concurrency=200
|
||||
-c min_wal_size=4GB
|
||||
-c max_wal_size=16GB
|
||||
-c max_worker_processes=16
|
||||
-c checkpoint_timeout=1800
|
||||
networks:
|
||||
- chains
|
||||
volumes:
|
||||
- ${ABSTRACT_MAINNET_EXTERNAL_NODE_ARCHIVE__DB_DATA:-abstract-mainnet-external-node-archive_db}:/var/lib/postgresql/data
|
||||
healthcheck:
|
||||
interval: 1s
|
||||
timeout: 3s
|
||||
test: [CMD-SHELL, psql -U postgres -c "select exists (select * from pg_stat_activity where datname = '' and application_name = 'pg_restore')" | grep -e ".f$$"]
|
||||
logging: *logging-defaults
|
||||
|
||||
volumes:
|
||||
abstract-mainnet-external-node-archive:
|
||||
abstract-mainnet-external-node-archive_db:
|
||||
|
||||
x-upstreams:
|
||||
- id: $${ID}
|
||||
labels:
|
||||
provider: $${PROVIDER}
|
||||
connection:
|
||||
generic:
|
||||
rpc:
|
||||
url: $${RPC_URL}
|
||||
ws:
|
||||
frameSize: 20Mb
|
||||
msgSize: 50Mb
|
||||
url: $${WS_URL}
|
||||
chain: abstract
|
||||
method-groups:
|
||||
enabled:
|
||||
- debug
|
||||
- filter
|
||||
methods:
|
||||
disabled:
|
||||
enabled:
|
||||
- name: txpool_content # TODO: should be disabled for rollup nodes
|
||||
...
|
||||
172
abstract/external-node/abstract-mainnet-external-node-pruned.yml
Normal file
172
abstract/external-node/abstract-mainnet-external-node-pruned.yml
Normal file
@@ -0,0 +1,172 @@
|
||||
---
|
||||
x-logging-defaults: &logging-defaults
|
||||
driver: json-file
|
||||
options:
|
||||
max-size: "10m"
|
||||
max-file: "3"
|
||||
|
||||
# Usage:
|
||||
#
|
||||
# mkdir rpc && cd rpc
|
||||
#
|
||||
# git init
|
||||
# git remote add origin https://github.com/StakeSquid/ethereum-rpc-docker.git
|
||||
# git fetch origin vibe
|
||||
# git checkout origin/vibe
|
||||
#
|
||||
# docker run --rm alpine sh -c "printf '0x'; head -c32 /dev/urandom | xxd -p -c 64" > .jwtsecret
|
||||
#
|
||||
# env
|
||||
# ...
|
||||
# IP=$(curl ipinfo.io/ip)
|
||||
# DOMAIN=${IP}.traefik.me
|
||||
# COMPOSE_FILE=base.yml:rpc.yml:abstract/external-node/abstract-mainnet-external-node-pruned.yml
|
||||
#
|
||||
# docker compose up -d
|
||||
#
|
||||
# curl -X POST https://${IP}.traefik.me/abstract-mainnet \
|
||||
# -H "Content-Type: application/json" \
|
||||
# --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'
|
||||
|
||||
services:
|
||||
abstract-mainnet-client:
|
||||
image: ${ABSTRACT_EXTERNAL_NODE_IMAGE:-matterlabs/external-node}:${ABSTRACT_MAINNET_EXTERNAL_NODE_VERSION:-v27.5.7}
|
||||
sysctls:
|
||||
# TCP Performance
|
||||
net.ipv4.tcp_slow_start_after_idle: 0 # Disable slow start after idle
|
||||
net.ipv4.tcp_no_metrics_save: 1 # Disable metrics cache
|
||||
net.ipv4.tcp_rmem: 4096 87380 16777216 # Increase TCP read buffers
|
||||
net.ipv4.tcp_wmem: 4096 87380 16777216 # Increase TCP write buffers
|
||||
net.core.somaxconn: 32768 # Higher connection queue
|
||||
# Memory/Connection Management
|
||||
# net.core.netdev_max_backlog: 50000 # Increase network buffer
|
||||
net.ipv4.tcp_max_syn_backlog: 30000 # More SYN requests
|
||||
net.ipv4.tcp_max_tw_buckets: 2000000 # Allow more TIME_WAIT sockets
|
||||
ulimits:
|
||||
nofile: 1048576 # Max open files (for RPC/WS connections)
|
||||
user: root
|
||||
ports:
|
||||
- 14370:14370
|
||||
- 14370:14370/udp
|
||||
expose:
|
||||
- 8545
|
||||
- 8546
|
||||
environment:
|
||||
- DATABASE_POOL_SIZE=50
|
||||
- DATABASE_URL=postgres://postgres:notsecurepassword@abstract-mainnet-db:5430/zksync_local_ext_node
|
||||
- EN_API_NAMESAPCES=eth,net,web3,debug,pubsub,debug,zks
|
||||
- EN_ETH_CLIENT_URL=${ETHEREUM_MAINNET_EXECUTION_RPC}
|
||||
- EN_HEALTHCHECK_PORT=3081
|
||||
- EN_HTTP_PORT=8545
|
||||
- EN_L1_CHAIN_ID=1
|
||||
- EN_L2_CHAIN_ID=2741
|
||||
- EN_MAIN_NODE_URL=https://api.mainnet.abs.xyz
|
||||
- EN_MAX_RESPONSE_BODY_SIZE_MB=30
|
||||
- EN_MAX_RESPONSE_BODY_SIZE_OVERRIDES_MB=eth_getLogs=100,eth_getBlockReceipts=None
|
||||
- EN_MERKLE_TREE_PATH=./db/ext-node/lightweight
|
||||
- EN_PROMETHEUS_PORT=3322
|
||||
- EN_PRUNING_ENABLED=true
|
||||
- EN_REQ_ENTITIES_LIMIT=100000
|
||||
- EN_SNAPSHOTS_OBJECT_STORE_BUCKET_BASE_URL=raas-abstract-mainnet-external-node-snapshots
|
||||
- EN_SNAPSHOTS_OBJECT_STORE_MODE=GCSAnonymousReadOnly
|
||||
- EN_SNAPSHOTS_RECOVERY_ENABLED=true
|
||||
- EN_STATE_CACHE_PATH=./db/ext-node/state_keeper
|
||||
- EN_WS_PORT=8546
|
||||
- RUST_LOG=warn,zksync=info,zksync_core::metadata_calculator=debug,zksync_state=info,zksync_utils=info,zksync_web3_decl::client=error
|
||||
restart: unless-stopped
|
||||
stop_grace_period: 5m
|
||||
networks:
|
||||
- chains
|
||||
volumes:
|
||||
- ${ABSTRACT_MAINNET_EXTERNAL_NODE_PRUNED_DATA:-abstract-mainnet-external-node-pruned}:/db
|
||||
- /slowdisk:/slowdisk
|
||||
logging: *logging-defaults
|
||||
labels:
|
||||
- prometheus-scrape.enabled=false
|
||||
|
||||
abstract-mainnet:
|
||||
image: nginx
|
||||
expose:
|
||||
- '80'
|
||||
environment:
|
||||
PROXY_HOST: abstract-mainnet-client
|
||||
RPC_PATH: ''
|
||||
RPC_PORT: 8545
|
||||
WS_PATH: ''
|
||||
WS_PORT: 8546
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
- abstract-mainnet-client
|
||||
networks:
|
||||
- chains
|
||||
volumes:
|
||||
- ./nginx-proxy:/etc/nginx/templates
|
||||
logging: *logging-defaults
|
||||
labels:
|
||||
- prometheus-scrape.enabled=false
|
||||
- traefik.enable=true
|
||||
- traefik.http.middlewares.abstract-mainnet-external-node-pruned-stripprefix.stripprefix.prefixes=/abstract-mainnet
|
||||
- traefik.http.services.abstract-mainnet-external-node-pruned.loadbalancer.server.port=80
|
||||
- ${NO_SSL:-traefik.http.routers.abstract-mainnet-external-node-pruned.entrypoints=websecure}
|
||||
- ${NO_SSL:-traefik.http.routers.abstract-mainnet-external-node-pruned.tls.certresolver=myresolver}
|
||||
- ${NO_SSL:-traefik.http.routers.abstract-mainnet-external-node-pruned.rule=Host(`$DOMAIN`) && (Path(`/abstract-mainnet`) || Path(`/abstract-mainnet/`))}
|
||||
- ${NO_SSL:+traefik.http.routers.abstract-mainnet-external-node-pruned.rule=Path(`/abstract-mainnet`) || Path(`/abstract-mainnet/`)}
|
||||
- traefik.http.routers.abstract-mainnet-external-node-pruned.middlewares=abstract-mainnet-external-node-pruned-stripprefix, ipallowlist
|
||||
|
||||
abstract-mainnet-db:
|
||||
image: postgres:14
|
||||
expose:
|
||||
- 5430
|
||||
environment:
|
||||
- PGPORT=5430
|
||||
- POSTGRES_PASSWORD=notsecurepassword
|
||||
command: >
|
||||
postgres
|
||||
-c max_connections=200
|
||||
-c log_error_verbosity=terse
|
||||
-c shared_buffers=2GB
|
||||
-c effective_cache_size=4GB
|
||||
-c maintenance_work_mem=1GB
|
||||
-c checkpoint_completion_target=0.9
|
||||
-c random_page_cost=1.1
|
||||
-c effective_io_concurrency=200
|
||||
-c min_wal_size=4GB
|
||||
-c max_wal_size=16GB
|
||||
-c max_worker_processes=16
|
||||
-c checkpoint_timeout=1800
|
||||
networks:
|
||||
- chains
|
||||
volumes:
|
||||
- ${ABSTRACT_MAINNET_EXTERNAL_NODE_PRUNED__DB_DATA:-abstract-mainnet-external-node-pruned_db}:/var/lib/postgresql/data
|
||||
healthcheck:
|
||||
interval: 1s
|
||||
timeout: 3s
|
||||
test: [CMD-SHELL, psql -U postgres -c "select exists (select * from pg_stat_activity where datname = '' and application_name = 'pg_restore')" | grep -e ".f$$"]
|
||||
logging: *logging-defaults
|
||||
|
||||
volumes:
|
||||
abstract-mainnet-external-node-pruned:
|
||||
abstract-mainnet-external-node-pruned_db:
|
||||
|
||||
x-upstreams:
|
||||
- id: $${ID}
|
||||
labels:
|
||||
provider: $${PROVIDER}
|
||||
connection:
|
||||
generic:
|
||||
rpc:
|
||||
url: $${RPC_URL}
|
||||
ws:
|
||||
frameSize: 20Mb
|
||||
msgSize: 50Mb
|
||||
url: $${WS_URL}
|
||||
chain: abstract
|
||||
method-groups:
|
||||
enabled:
|
||||
- debug
|
||||
- filter
|
||||
methods:
|
||||
disabled:
|
||||
enabled:
|
||||
- name: txpool_content # TODO: should be disabled for rollup nodes
|
||||
...
|
||||
@@ -0,0 +1,172 @@
|
||||
---
|
||||
x-logging-defaults: &logging-defaults
|
||||
driver: json-file
|
||||
options:
|
||||
max-size: "10m"
|
||||
max-file: "3"
|
||||
|
||||
# Usage:
|
||||
#
|
||||
# mkdir rpc && cd rpc
|
||||
#
|
||||
# git init
|
||||
# git remote add origin https://github.com/StakeSquid/ethereum-rpc-docker.git
|
||||
# git fetch origin vibe
|
||||
# git checkout origin/vibe
|
||||
#
|
||||
# docker run --rm alpine sh -c "printf '0x'; head -c32 /dev/urandom | xxd -p -c 64" > .jwtsecret
|
||||
#
|
||||
# env
|
||||
# ...
|
||||
# IP=$(curl ipinfo.io/ip)
|
||||
# DOMAIN=${IP}.traefik.me
|
||||
# COMPOSE_FILE=base.yml:rpc.yml:abstract/external-node/abstract-testnet-external-node-archive.yml
|
||||
#
|
||||
# docker compose up -d
|
||||
#
|
||||
# curl -X POST https://${IP}.traefik.me/abstract-testnet-archive \
|
||||
# -H "Content-Type: application/json" \
|
||||
# --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'
|
||||
|
||||
services:
|
||||
abstract-testnet-archive-client:
|
||||
image: ${ABSTRACT_EXTERNAL_NODE_IMAGE:-matterlabs/external-node}:${ABSTRACT_TESTNET_EXTERNAL_NODE_VERSION:-v28.2.1}
|
||||
sysctls:
|
||||
# TCP Performance
|
||||
net.ipv4.tcp_slow_start_after_idle: 0 # Disable slow start after idle
|
||||
net.ipv4.tcp_no_metrics_save: 1 # Disable metrics cache
|
||||
net.ipv4.tcp_rmem: 4096 87380 16777216 # Increase TCP read buffers
|
||||
net.ipv4.tcp_wmem: 4096 87380 16777216 # Increase TCP write buffers
|
||||
net.core.somaxconn: 32768 # Higher connection queue
|
||||
# Memory/Connection Management
|
||||
# net.core.netdev_max_backlog: 50000 # Increase network buffer
|
||||
net.ipv4.tcp_max_syn_backlog: 30000 # More SYN requests
|
||||
net.ipv4.tcp_max_tw_buckets: 2000000 # Allow more TIME_WAIT sockets
|
||||
ulimits:
|
||||
nofile: 1048576 # Max open files (for RPC/WS connections)
|
||||
user: root
|
||||
ports:
|
||||
- 14028:14028
|
||||
- 14028:14028/udp
|
||||
expose:
|
||||
- 8545
|
||||
- 8546
|
||||
environment:
|
||||
- DATABASE_POOL_SIZE=50
|
||||
- DATABASE_URL=postgres://postgres:notsecurepassword@abstract-testnet-archive-db:5430/zksync_local_ext_node
|
||||
- EN_API_NAMESAPCES=eth,net,web3,debug,pubsub,debug,zks
|
||||
- EN_ETH_CLIENT_URL=${ETHEREUM_SEPOLIA_EXECUTION_RPC}
|
||||
- EN_HEALTHCHECK_PORT=3081
|
||||
- EN_HTTP_PORT=8545
|
||||
- EN_L1_CHAIN_ID=11155111
|
||||
- EN_L2_CHAIN_ID=11124
|
||||
- EN_MAIN_NODE_URL=https://api.testnet.abs.xyz
|
||||
- EN_MAX_RESPONSE_BODY_SIZE_MB=30
|
||||
- EN_MAX_RESPONSE_BODY_SIZE_OVERRIDES_MB=eth_getLogs=100,eth_getBlockReceipts=None
|
||||
- EN_MERKLE_TREE_PATH=./db/ext-node/lightweight
|
||||
- EN_PROMETHEUS_PORT=3322
|
||||
- EN_PRUNING_ENABLED=false
|
||||
- EN_REQ_ENTITIES_LIMIT=100000
|
||||
- EN_SNAPSHOTS_OBJECT_STORE_BUCKET_BASE_URL=abstract-testnet-external-node-snapshots
|
||||
- EN_SNAPSHOTS_OBJECT_STORE_MODE=GCSAnonymousReadOnly
|
||||
- EN_SNAPSHOTS_RECOVERY_ENABLED=true
|
||||
- EN_STATE_CACHE_PATH=./db/ext-node/state_keeper
|
||||
- EN_WS_PORT=8546
|
||||
- RUST_LOG=warn,zksync=info,zksync_core::metadata_calculator=debug,zksync_state=info,zksync_utils=info,zksync_web3_decl::client=error
|
||||
restart: unless-stopped
|
||||
stop_grace_period: 5m
|
||||
networks:
|
||||
- chains
|
||||
volumes:
|
||||
- ${ABSTRACT_TESTNET_EXTERNAL_NODE_ARCHIVE_DATA:-abstract-testnet-external-node-archive}:/db
|
||||
- /slowdisk:/slowdisk
|
||||
logging: *logging-defaults
|
||||
labels:
|
||||
- prometheus-scrape.enabled=false
|
||||
|
||||
abstract-testnet-archive:
|
||||
image: nginx
|
||||
expose:
|
||||
- '80'
|
||||
environment:
|
||||
PROXY_HOST: abstract-testnet-archive-client
|
||||
RPC_PATH: ''
|
||||
RPC_PORT: 8545
|
||||
WS_PATH: ''
|
||||
WS_PORT: 8546
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
- abstract-testnet-archive-client
|
||||
networks:
|
||||
- chains
|
||||
volumes:
|
||||
- ./nginx-proxy:/etc/nginx/templates
|
||||
logging: *logging-defaults
|
||||
labels:
|
||||
- prometheus-scrape.enabled=false
|
||||
- traefik.enable=true
|
||||
- traefik.http.middlewares.abstract-testnet-external-node-archive-stripprefix.stripprefix.prefixes=/abstract-testnet-archive
|
||||
- traefik.http.services.abstract-testnet-external-node-archive.loadbalancer.server.port=80
|
||||
- ${NO_SSL:-traefik.http.routers.abstract-testnet-external-node-archive.entrypoints=websecure}
|
||||
- ${NO_SSL:-traefik.http.routers.abstract-testnet-external-node-archive.tls.certresolver=myresolver}
|
||||
- ${NO_SSL:-traefik.http.routers.abstract-testnet-external-node-archive.rule=Host(`$DOMAIN`) && (Path(`/abstract-testnet-archive`) || Path(`/abstract-testnet-archive/`))}
|
||||
- ${NO_SSL:+traefik.http.routers.abstract-testnet-external-node-archive.rule=Path(`/abstract-testnet-archive`) || Path(`/abstract-testnet-archive/`)}
|
||||
- traefik.http.routers.abstract-testnet-external-node-archive.middlewares=abstract-testnet-external-node-archive-stripprefix, ipallowlist
|
||||
|
||||
abstract-testnet-archive-db:
|
||||
image: postgres:14
|
||||
expose:
|
||||
- 5430
|
||||
environment:
|
||||
- PGPORT=5430
|
||||
- POSTGRES_PASSWORD=notsecurepassword
|
||||
command: >
|
||||
postgres
|
||||
-c max_connections=200
|
||||
-c log_error_verbosity=terse
|
||||
-c shared_buffers=2GB
|
||||
-c effective_cache_size=4GB
|
||||
-c maintenance_work_mem=1GB
|
||||
-c checkpoint_completion_target=0.9
|
||||
-c random_page_cost=1.1
|
||||
-c effective_io_concurrency=200
|
||||
-c min_wal_size=4GB
|
||||
-c max_wal_size=16GB
|
||||
-c max_worker_processes=16
|
||||
-c checkpoint_timeout=1800
|
||||
networks:
|
||||
- chains
|
||||
volumes:
|
||||
- ${ABSTRACT_TESTNET_EXTERNAL_NODE_ARCHIVE__DB_DATA:-abstract-testnet-external-node-archive_db}:/var/lib/postgresql/data
|
||||
healthcheck:
|
||||
interval: 1s
|
||||
timeout: 3s
|
||||
test: [CMD-SHELL, psql -U postgres -c "select exists (select * from pg_stat_activity where datname = '' and application_name = 'pg_restore')" | grep -e ".f$$"]
|
||||
logging: *logging-defaults
|
||||
|
||||
volumes:
|
||||
abstract-testnet-external-node-archive:
|
||||
abstract-testnet-external-node-archive_db:
|
||||
|
||||
x-upstreams:
|
||||
- id: $${ID}
|
||||
labels:
|
||||
provider: $${PROVIDER}
|
||||
connection:
|
||||
generic:
|
||||
rpc:
|
||||
url: $${RPC_URL}
|
||||
ws:
|
||||
frameSize: 20Mb
|
||||
msgSize: 50Mb
|
||||
url: $${WS_URL}
|
||||
chain: abstract-sepolia
|
||||
method-groups:
|
||||
enabled:
|
||||
- debug
|
||||
- filter
|
||||
methods:
|
||||
disabled:
|
||||
enabled:
|
||||
- name: txpool_content # TODO: should be disabled for rollup nodes
|
||||
...
|
||||
172
abstract/external-node/abstract-testnet-external-node-pruned.yml
Normal file
172
abstract/external-node/abstract-testnet-external-node-pruned.yml
Normal file
@@ -0,0 +1,172 @@
|
||||
---
|
||||
x-logging-defaults: &logging-defaults
|
||||
driver: json-file
|
||||
options:
|
||||
max-size: "10m"
|
||||
max-file: "3"
|
||||
|
||||
# Usage:
|
||||
#
|
||||
# mkdir rpc && cd rpc
|
||||
#
|
||||
# git init
|
||||
# git remote add origin https://github.com/StakeSquid/ethereum-rpc-docker.git
|
||||
# git fetch origin vibe
|
||||
# git checkout origin/vibe
|
||||
#
|
||||
# docker run --rm alpine sh -c "printf '0x'; head -c32 /dev/urandom | xxd -p -c 64" > .jwtsecret
|
||||
#
|
||||
# env
|
||||
# ...
|
||||
# IP=$(curl ipinfo.io/ip)
|
||||
# DOMAIN=${IP}.traefik.me
|
||||
# COMPOSE_FILE=base.yml:rpc.yml:abstract/external-node/abstract-testnet-external-node-pruned.yml
|
||||
#
|
||||
# docker compose up -d
|
||||
#
|
||||
# curl -X POST https://${IP}.traefik.me/abstract-testnet \
|
||||
# -H "Content-Type: application/json" \
|
||||
# --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'
|
||||
|
||||
services:
|
||||
abstract-testnet-client:
|
||||
image: ${ABSTRACT_EXTERNAL_NODE_IMAGE:-matterlabs/external-node}:${ABSTRACT_TESTNET_EXTERNAL_NODE_VERSION:-v28.2.1}
|
||||
sysctls:
|
||||
# TCP Performance
|
||||
net.ipv4.tcp_slow_start_after_idle: 0 # Disable slow start after idle
|
||||
net.ipv4.tcp_no_metrics_save: 1 # Disable metrics cache
|
||||
net.ipv4.tcp_rmem: 4096 87380 16777216 # Increase TCP read buffers
|
||||
net.ipv4.tcp_wmem: 4096 87380 16777216 # Increase TCP write buffers
|
||||
net.core.somaxconn: 32768 # Higher connection queue
|
||||
# Memory/Connection Management
|
||||
# net.core.netdev_max_backlog: 50000 # Increase network buffer
|
||||
net.ipv4.tcp_max_syn_backlog: 30000 # More SYN requests
|
||||
net.ipv4.tcp_max_tw_buckets: 2000000 # Allow more TIME_WAIT sockets
|
||||
ulimits:
|
||||
nofile: 1048576 # Max open files (for RPC/WS connections)
|
||||
user: root
|
||||
ports:
|
||||
- 12157:12157
|
||||
- 12157:12157/udp
|
||||
expose:
|
||||
- 8545
|
||||
- 8546
|
||||
environment:
|
||||
- DATABASE_POOL_SIZE=50
|
||||
- DATABASE_URL=postgres://postgres:notsecurepassword@abstract-testnet-db:5430/zksync_local_ext_node
|
||||
- EN_API_NAMESAPCES=eth,net,web3,debug,pubsub,debug,zks
|
||||
- EN_ETH_CLIENT_URL=${ETHEREUM_SEPOLIA_EXECUTION_RPC}
|
||||
- EN_HEALTHCHECK_PORT=3081
|
||||
- EN_HTTP_PORT=8545
|
||||
- EN_L1_CHAIN_ID=11155111
|
||||
- EN_L2_CHAIN_ID=11124
|
||||
- EN_MAIN_NODE_URL=https://api.testnet.abs.xyz
|
||||
- EN_MAX_RESPONSE_BODY_SIZE_MB=30
|
||||
- EN_MAX_RESPONSE_BODY_SIZE_OVERRIDES_MB=eth_getLogs=100,eth_getBlockReceipts=None
|
||||
- EN_MERKLE_TREE_PATH=./db/ext-node/lightweight
|
||||
- EN_PROMETHEUS_PORT=3322
|
||||
- EN_PRUNING_ENABLED=true
|
||||
- EN_REQ_ENTITIES_LIMIT=100000
|
||||
- EN_SNAPSHOTS_OBJECT_STORE_BUCKET_BASE_URL=abstract-testnet-external-node-snapshots
|
||||
- EN_SNAPSHOTS_OBJECT_STORE_MODE=GCSAnonymousReadOnly
|
||||
- EN_SNAPSHOTS_RECOVERY_ENABLED=true
|
||||
- EN_STATE_CACHE_PATH=./db/ext-node/state_keeper
|
||||
- EN_WS_PORT=8546
|
||||
- RUST_LOG=warn,zksync=info,zksync_core::metadata_calculator=debug,zksync_state=info,zksync_utils=info,zksync_web3_decl::client=error
|
||||
restart: unless-stopped
|
||||
stop_grace_period: 5m
|
||||
networks:
|
||||
- chains
|
||||
volumes:
|
||||
- ${ABSTRACT_TESTNET_EXTERNAL_NODE_PRUNED_DATA:-abstract-testnet-external-node-pruned}:/db
|
||||
- /slowdisk:/slowdisk
|
||||
logging: *logging-defaults
|
||||
labels:
|
||||
- prometheus-scrape.enabled=false
|
||||
|
||||
abstract-testnet:
|
||||
image: nginx
|
||||
expose:
|
||||
- '80'
|
||||
environment:
|
||||
PROXY_HOST: abstract-testnet-client
|
||||
RPC_PATH: ''
|
||||
RPC_PORT: 8545
|
||||
WS_PATH: ''
|
||||
WS_PORT: 8546
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
- abstract-testnet-client
|
||||
networks:
|
||||
- chains
|
||||
volumes:
|
||||
- ./nginx-proxy:/etc/nginx/templates
|
||||
logging: *logging-defaults
|
||||
labels:
|
||||
- prometheus-scrape.enabled=false
|
||||
- traefik.enable=true
|
||||
- traefik.http.middlewares.abstract-testnet-external-node-pruned-stripprefix.stripprefix.prefixes=/abstract-testnet
|
||||
- traefik.http.services.abstract-testnet-external-node-pruned.loadbalancer.server.port=80
|
||||
- ${NO_SSL:-traefik.http.routers.abstract-testnet-external-node-pruned.entrypoints=websecure}
|
||||
- ${NO_SSL:-traefik.http.routers.abstract-testnet-external-node-pruned.tls.certresolver=myresolver}
|
||||
- ${NO_SSL:-traefik.http.routers.abstract-testnet-external-node-pruned.rule=Host(`$DOMAIN`) && (Path(`/abstract-testnet`) || Path(`/abstract-testnet/`))}
|
||||
- ${NO_SSL:+traefik.http.routers.abstract-testnet-external-node-pruned.rule=Path(`/abstract-testnet`) || Path(`/abstract-testnet/`)}
|
||||
- traefik.http.routers.abstract-testnet-external-node-pruned.middlewares=abstract-testnet-external-node-pruned-stripprefix, ipallowlist
|
||||
|
||||
abstract-testnet-db:
|
||||
image: postgres:14
|
||||
expose:
|
||||
- 5430
|
||||
environment:
|
||||
- PGPORT=5430
|
||||
- POSTGRES_PASSWORD=notsecurepassword
|
||||
command: >
|
||||
postgres
|
||||
-c max_connections=200
|
||||
-c log_error_verbosity=terse
|
||||
-c shared_buffers=2GB
|
||||
-c effective_cache_size=4GB
|
||||
-c maintenance_work_mem=1GB
|
||||
-c checkpoint_completion_target=0.9
|
||||
-c random_page_cost=1.1
|
||||
-c effective_io_concurrency=200
|
||||
-c min_wal_size=4GB
|
||||
-c max_wal_size=16GB
|
||||
-c max_worker_processes=16
|
||||
-c checkpoint_timeout=1800
|
||||
networks:
|
||||
- chains
|
||||
volumes:
|
||||
- ${ABSTRACT_TESTNET_EXTERNAL_NODE_PRUNED__DB_DATA:-abstract-testnet-external-node-pruned_db}:/var/lib/postgresql/data
|
||||
healthcheck:
|
||||
interval: 1s
|
||||
timeout: 3s
|
||||
test: [CMD-SHELL, psql -U postgres -c "select exists (select * from pg_stat_activity where datname = '' and application_name = 'pg_restore')" | grep -e ".f$$"]
|
||||
logging: *logging-defaults
|
||||
|
||||
volumes:
|
||||
abstract-testnet-external-node-pruned:
|
||||
abstract-testnet-external-node-pruned_db:
|
||||
|
||||
x-upstreams:
|
||||
- id: $${ID}
|
||||
labels:
|
||||
provider: $${PROVIDER}
|
||||
connection:
|
||||
generic:
|
||||
rpc:
|
||||
url: $${RPC_URL}
|
||||
ws:
|
||||
frameSize: 20Mb
|
||||
msgSize: 50Mb
|
||||
url: $${WS_URL}
|
||||
chain: abstract-sepolia
|
||||
method-groups:
|
||||
enabled:
|
||||
- debug
|
||||
- filter
|
||||
methods:
|
||||
disabled:
|
||||
enabled:
|
||||
- name: txpool_content # TODO: should be disabled for rollup nodes
|
||||
...
|
||||
1
alephzero-mainnet-archive.yml
Symbolic link
1
alephzero-mainnet-archive.yml
Symbolic link
@@ -0,0 +1 @@
|
||||
arb/nitro/alephzero-mainnet-nitro-archive-pebble-hash.yml
|
||||
1
alephzero-mainnet.yml
Symbolic link
1
alephzero-mainnet.yml
Symbolic link
@@ -0,0 +1 @@
|
||||
arb/nitro/alephzero-mainnet-nitro-pruned-pebble-path.yml
|
||||
1
alephzero-sepolia-archive.yml
Symbolic link
1
alephzero-sepolia-archive.yml
Symbolic link
@@ -0,0 +1 @@
|
||||
arb/nitro/alephzero-sepolia-nitro-archive-leveldb-hash.yml
|
||||
1
alephzero-sepolia.yml
Symbolic link
1
alephzero-sepolia.yml
Symbolic link
@@ -0,0 +1 @@
|
||||
arb/nitro/alephzero-sepolia-nitro-pruned-pebble-path.yml
|
||||
5
arb/alephzero/mainnet/baseConfig.json
Normal file
5
arb/alephzero/mainnet/baseConfig.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"chain": {
|
||||
"info-json": "[{\"chain-id\":41455,\"parent-chain-id\":1,\"parent-chain-is-arbitrum\":false,\"chain-config\":{\"homesteadBlock\":0,\"daoForkBlock\":null,\"daoForkSupport\":true,\"eip150Block\":0,\"eip150Hash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"eip155Block\":0,\"eip158Block\":0,\"byzantiumBlock\":0,\"constantinopleBlock\":0,\"petersburgBlock\":0,\"istanbulBlock\":0,\"muirGlacierBlock\":0,\"berlinBlock\":0,\"londonBlock\":0,\"clique\":{\"period\":0,\"epoch\":0},\"arbitrum\":{\"EnableArbOS\":true,\"AllowDebugPrecompiles\":false,\"DataAvailabilityCommittee\":true,\"InitialArbOSVersion\":20,\"GenesisBlockNum\":0,\"MaxCodeSize\":98304,\"MaxInitCodeSize\":49152,\"InitialChainOwner\":\"0x257812604076712675ae9788F5Bd738173CA3CE0\"},\"chainId\":41455},\"rollup\":{\"bridge\":\"0x41Ec9456AB918f2aBA81F38c03Eb0B93b78E84d9\",\"inbox\":\"0x56D8EC76a421063e1907503aDd3794c395256AEb\",\"sequencer-inbox\":\"0xF75206c49c1694594E3e69252E519434f1579876\",\"rollup\":\"0x1CA12290D954CFe022323b6A6Df92113ed6b1C98\",\"validator-utils\":\"0x2b0E04Dc90e3fA58165CB41E2834B44A56E766aF\",\"validator-wallet-creator\":\"0x9CAd81628aB7D8e239F1A5B497313341578c5F71\",\"deployed-at\":20412468}}]"
|
||||
}
|
||||
}
|
||||
6
arb/alephzero/sepolia/baseConfig.json
Normal file
6
arb/alephzero/sepolia/baseConfig.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"chain": {
|
||||
"info-json": "[{\"chain-id\":2039,\"parent-chain-id\":11155111,\"parent-chain-is-arbitrum\":false,\"chain-name\":\"Aleph Zero EVM testnet\",\"chain-config\":{\"homesteadBlock\":0,\"daoForkBlock\":null,\"daoForkSupport\":true,\"eip150Block\":0,\"eip150Hash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"eip155Block\":0,\"eip158Block\":0,\"byzantiumBlock\":0,\"constantinopleBlock\":0,\"petersburgBlock\":0,\"istanbulBlock\":0,\"muirGlacierBlock\":0,\"berlinBlock\":0,\"londonBlock\":0,\"clique\":{\"period\":0,\"epoch\":0},\"arbitrum\":{\"EnableArbOS\":true,\"AllowDebugPrecompiles\":false,\"DataAvailabilityCommittee\":true,\"InitialArbOSVersion\":20,\"GenesisBlockNum\":0,\"MaxCodeSize\":98304,\"MaxInitCodeSize\":49152,\"InitialChainOwner\":\"0x4c6dfF3e40e82a1fB599e062051726a9f7808a18\"},\"chainId\":2039},\"rollup\":{\"bridge\":\"0xCB5c0B38C45Fad0C20591E26b0b3C3809123994A\",\"inbox\":\"0xb27fd27987a71a6B77Fb8705bFb6010C411083EB\",\"sequencer-inbox\":\"0x16Ef70c48EF4BaaCfdaa4AfdD37F69332832a0bD\",\"rollup\":\"0xC8C08A4DbbF3367c8441151591c3d935947CB42F\",\"validator-utils\":\"0xb33Dca7b17c72CFC311D68C543cd4178E0d7ce55\",\"validator-wallet-creator\":\"0x75500812ADC9E51b721BEa31Df322EEc66967DDF\",\"deployed-at\":5827184}}]",
|
||||
"name": "Aleph Zero EVM testnet"
|
||||
}
|
||||
}
|
||||
113
arb/arbnode/arbitrum-one-arbnode-archive-leveldb-hash.yml
Normal file
113
arb/arbnode/arbitrum-one-arbnode-archive-leveldb-hash.yml
Normal file
@@ -0,0 +1,113 @@
|
||||
---
|
||||
x-logging-defaults: &logging-defaults
|
||||
driver: json-file
|
||||
options:
|
||||
max-size: "10m"
|
||||
max-file: "3"
|
||||
|
||||
# Usage:
|
||||
#
|
||||
# mkdir rpc && cd rpc
|
||||
#
|
||||
# git init
|
||||
# git remote add origin https://github.com/StakeSquid/ethereum-rpc-docker.git
|
||||
# git fetch origin vibe
|
||||
# git checkout origin/vibe
|
||||
#
|
||||
# docker run --rm alpine sh -c "printf '0x'; head -c32 /dev/urandom | xxd -p -c 64" > .jwtsecret
|
||||
#
|
||||
# env
|
||||
# ...
|
||||
# IP=$(curl ipinfo.io/ip)
|
||||
# DOMAIN=${IP}.traefik.me
|
||||
# COMPOSE_FILE=base.yml:rpc.yml:arb/arbnode/arbitrum-one-arbnode-archive-leveldb-hash.yml
|
||||
#
|
||||
# docker compose up -d
|
||||
#
|
||||
# curl -X POST https://${IP}.traefik.me/arbitrum-one-arbnode-archive \
|
||||
# -H "Content-Type: application/json" \
|
||||
# --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'
|
||||
|
||||
services:
|
||||
arbitrum-one-arbnode-archive:
|
||||
image: ${ARBITRUM_ARBNODE_IMAGE:-offchainlabs/arb-node}:${ARBITRUM_ONE_ARBNODE_VERSION:-v1.4.5-e97c1a4}
|
||||
sysctls:
|
||||
# TCP Performance
|
||||
net.ipv4.tcp_slow_start_after_idle: 0 # Disable slow start after idle
|
||||
net.ipv4.tcp_no_metrics_save: 1 # Disable metrics cache
|
||||
net.ipv4.tcp_rmem: 4096 87380 16777216 # Increase TCP read buffers
|
||||
net.ipv4.tcp_wmem: 4096 87380 16777216 # Increase TCP write buffers
|
||||
net.core.somaxconn: 32768 # Higher connection queue
|
||||
# Memory/Connection Management
|
||||
# net.core.netdev_max_backlog: 50000 # Increase network buffer
|
||||
net.ipv4.tcp_max_syn_backlog: 30000 # More SYN requests
|
||||
net.ipv4.tcp_max_tw_buckets: 2000000 # Allow more TIME_WAIT sockets
|
||||
ulimits:
|
||||
nofile: 1048576 # Max open files (for RPC/WS connections)
|
||||
user: root
|
||||
expose:
|
||||
- 8545
|
||||
- 8546
|
||||
entrypoint: [/home/user/go/bin/arb-node]
|
||||
command:
|
||||
- --core.checkpoint-gas-frequency=156250000
|
||||
- --l1.url=${ETHEREUM_MAINNET_EXECUTION_RPC}
|
||||
- --l2.disable-upstream
|
||||
- --metrics
|
||||
- --metrics-server.addr=0.0.0.0
|
||||
- --metrics-server.port=7070
|
||||
- --node.cache.allow-slow-lookup
|
||||
- --node.chain-id=42161
|
||||
- --node.rpc.addr=0.0.0.0
|
||||
- --node.rpc.enable-l1-calls
|
||||
- --node.rpc.port=8545
|
||||
- --node.rpc.tracing.enable
|
||||
- --node.rpc.tracing.namespace=trace
|
||||
- --node.ws.addr=0.0.0.0
|
||||
- --node.ws.port=8546
|
||||
- --persistent.chain=/data/datadir/
|
||||
- --persistent.global-config=/data/
|
||||
restart: unless-stopped
|
||||
stop_grace_period: 5m
|
||||
networks:
|
||||
- chains
|
||||
volumes:
|
||||
- ${ARBITRUM_ONE_ARBNODE_ARCHIVE_LEVELDB_HASH_DATA:-arbitrum-one-arbnode-archive-leveldb-hash}:/data
|
||||
- /slowdisk:/slowdisk
|
||||
logging: *logging-defaults
|
||||
labels:
|
||||
- prometheus-scrape.enabled=false
|
||||
- traefik.enable=true
|
||||
- traefik.http.middlewares.arbitrum-one-arbnode-archive-leveldb-hash-stripprefix.stripprefix.prefixes=/arbitrum-one-arbnode-archive
|
||||
- traefik.http.services.arbitrum-one-arbnode-archive-leveldb-hash.loadbalancer.server.port=8545
|
||||
- ${NO_SSL:-traefik.http.routers.arbitrum-one-arbnode-archive-leveldb-hash.entrypoints=websecure}
|
||||
- ${NO_SSL:-traefik.http.routers.arbitrum-one-arbnode-archive-leveldb-hash.tls.certresolver=myresolver}
|
||||
- ${NO_SSL:-traefik.http.routers.arbitrum-one-arbnode-archive-leveldb-hash.rule=Host(`$DOMAIN`) && (Path(`/arbitrum-one-arbnode-archive`) || Path(`/arbitrum-one-arbnode-archive/`))}
|
||||
- ${NO_SSL:+traefik.http.routers.arbitrum-one-arbnode-archive-leveldb-hash.rule=Path(`/arbitrum-one-arbnode-archive`) || Path(`/arbitrum-one-arbnode-archive/`)}
|
||||
- traefik.http.routers.arbitrum-one-arbnode-archive-leveldb-hash.middlewares=arbitrum-one-arbnode-archive-leveldb-hash-stripprefix, ipallowlist
|
||||
|
||||
volumes:
|
||||
arbitrum-one-arbnode-archive-leveldb-hash:
|
||||
|
||||
x-upstreams:
|
||||
- id: $${ID}
|
||||
labels:
|
||||
provider: $${PROVIDER}
|
||||
connection:
|
||||
generic:
|
||||
rpc:
|
||||
url: $${RPC_URL}
|
||||
ws:
|
||||
frameSize: 20Mb
|
||||
msgSize: 50Mb
|
||||
url: $${WS_URL}
|
||||
chain: arbitrum
|
||||
method-groups:
|
||||
enabled:
|
||||
- debug
|
||||
- filter
|
||||
methods:
|
||||
disabled:
|
||||
enabled:
|
||||
- name: txpool_content # TODO: should be disabled for rollup nodes
|
||||
...
|
||||
6
arb/connext/sepolia/baseConfig.json
Normal file
6
arb/connext/sepolia/baseConfig.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"chain": {
|
||||
"info-json": "[{\"chain-id\":6398,\"parent-chain-id\":11155111,\"parent-chain-is-arbitrum\":false,\"chain-name\":\"Connext Sepolia\",\"chain-config\":{\"homesteadBlock\":0,\"daoForkBlock\":null,\"daoForkSupport\":true,\"eip150Block\":0,\"eip150Hash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"eip155Block\":0,\"eip158Block\":0,\"byzantiumBlock\":0,\"constantinopleBlock\":0,\"petersburgBlock\":0,\"istanbulBlock\":0,\"muirGlacierBlock\":0,\"berlinBlock\":0,\"londonBlock\":0,\"clique\":{\"period\":0,\"epoch\":0},\"arbitrum\":{\"EnableArbOS\":true,\"AllowDebugPrecompiles\":false,\"DataAvailabilityCommittee\":true,\"InitialArbOSVersion\":20,\"GenesisBlockNum\":0,\"MaxCodeSize\":24576,\"MaxInitCodeSize\":49152,\"InitialChainOwner\":\"0x8ECD393576Ca37a7e5095f31bdfE21F606FF5F75\"},\"chainId\":6398},\"rollup\":{\"bridge\":\"0xf0b58FA876005898798a66A04EE09159C199CB7A\",\"inbox\":\"0x7bc7DAF843bf57c54D41D912F8221A2eE830c320\",\"sequencer-inbox\":\"0x7f5C1a58014E9DE69663CAc441bfa4C5d94b7E64\",\"rollup\":\"0xE6D7bf11A6264BACa59e8fAD7f6985FaC8f62e60\",\"validator-utils\":\"0xb33Dca7b17c72CFC311D68C543cd4178E0d7ce55\",\"validator-wallet-creator\":\"0x75500812ADC9E51b721BEa31Df322EEc66967DDF\",\"deployed-at\":5780509}}]",
|
||||
"name": "Connext Sepolia"
|
||||
}
|
||||
}
|
||||
6
arb/everclear/mainnet/baseConfig.json
Normal file
6
arb/everclear/mainnet/baseConfig.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"chain": {
|
||||
"name": "Everclear Mainnet",
|
||||
"info-json": "[{\"chain-id\":25327,\"parent-chain-id\":1,\"parent-chain-is-arbitrum\":false,\"chain-name\":\"Everclear Mainnet\",\"chain-config\":{\"homesteadBlock\":0,\"daoForkBlock\":null,\"daoForkSupport\":true,\"eip150Block\":0,\"eip150Hash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"eip155Block\":0,\"eip158Block\":0,\"byzantiumBlock\":0,\"constantinopleBlock\":0,\"petersburgBlock\":0,\"istanbulBlock\":0,\"muirGlacierBlock\":0,\"berlinBlock\":0,\"londonBlock\":0,\"clique\":{\"period\":0,\"epoch\":0},\"arbitrum\":{\"EnableArbOS\":true,\"AllowDebugPrecompiles\":false,\"DataAvailabilityCommittee\":true,\"InitialArbOSVersion\":20,\"GenesisBlockNum\":0,\"MaxCodeSize\":24576,\"MaxInitCodeSize\":49152,\"InitialChainOwner\":\"0x98a426C8ED821cAaef1b4BF7D29b514dcef970C0\"},\"chainId\":25327},\"rollup\":{\"bridge\":\"0x4eb4fB614e1aa3634513319F4Ec7334bC4321356\",\"inbox\":\"0x97FdC935c5E25613AA13a054C7Aa71cf751DB495\",\"sequencer-inbox\":\"0x7B0517E0104dB60198f9d573C0aB8d480207827E\",\"rollup\":\"0xc6CAd31D83E33Fc8fBc855f36ef9Cb2fCE070f5C\",\"validator-utils\":\"0x2b0E04Dc90e3fA58165CB41E2834B44A56E766aF\",\"validator-wallet-creator\":\"0x9CAd81628aB7D8e239F1A5B497313341578c5F71\",\"deployed-at\":20684364}}]"
|
||||
}
|
||||
}
|
||||
145
arb/fireeth/arbitrum-one-fireeth-pruned-pebble-hash.yml
Normal file
145
arb/fireeth/arbitrum-one-fireeth-pruned-pebble-hash.yml
Normal file
@@ -0,0 +1,145 @@
|
||||
---
|
||||
|
||||
# Usage:
|
||||
#
|
||||
# mkdir rpc && cd rpc
|
||||
#
|
||||
# git init
|
||||
# git remote add origin https://github.com/StakeSquid/ethereum-rpc-docker.git
|
||||
# git fetch origin vibe
|
||||
# git checkout origin/vibe
|
||||
#
|
||||
# docker run --rm alpine sh -c "printf '0x'; head -c32 /dev/urandom | xxd -p -c 64" > .jwtsecret
|
||||
#
|
||||
# env
|
||||
# ...
|
||||
# IP=$(curl ipinfo.io/ip)
|
||||
# DOMAIN=${IP}.traefik.me
|
||||
# COMPOSE_FILE=base.yml:rpc.yml:arb/fireeth/arbitrum-one-fireeth-pruned-pebble-hash.yml
|
||||
#
|
||||
# docker compose up -d
|
||||
#
|
||||
# curl -X POST https://${IP}.traefik.me/arbitrum-one \
|
||||
# -H "Content-Type: application/json" \
|
||||
# --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'
|
||||
x-logging-defaults: &logging-defaults
|
||||
driver: json-file
|
||||
options:
|
||||
max-size: 10m
|
||||
max-file: '3'
|
||||
|
||||
services:
|
||||
arbitrum-one:
|
||||
image: ${ARBITRUM_FIREETH_IMAGE:-ghcr.io/streamingfast/firehose-ethereum}:${ARBITRUM_ONE_FIREETH_VERSION:-v2.11.7-nitro-nitro-v3.5.5-fh3.0}
|
||||
sysctls:
|
||||
# TCP Performance
|
||||
net.ipv4.tcp_slow_start_after_idle: 0 # Disable slow start after idle
|
||||
net.ipv4.tcp_no_metrics_save: 1 # Disable metrics cache
|
||||
net.ipv4.tcp_rmem: 4096 87380 16777216 # Increase TCP read buffers
|
||||
net.ipv4.tcp_wmem: 4096 87380 16777216 # Increase TCP write buffers
|
||||
net.core.somaxconn: 32768 # Higher connection queue
|
||||
# Memory/Connection Management
|
||||
# net.core.netdev_max_backlog: 50000 # Increase network buffer
|
||||
net.ipv4.tcp_max_syn_backlog: 30000 # More SYN requests
|
||||
net.ipv4.tcp_max_tw_buckets: 2000000 # Allow more TIME_WAIT sockets
|
||||
ulimits:
|
||||
nofile: 1048576 # Max open files (for RPC/WS connections)
|
||||
user: root
|
||||
expose:
|
||||
- 8545
|
||||
environment:
|
||||
- ${ARBITRUM_ONE_FIREETH_PRUNED_PEBBLE_HASH_S3_BLOCKS_STORE:-/firehose-data/storage/merged-blocks}
|
||||
entrypoint: [sh, -c, 'exec fireeth -c /config/firehose.yml start --substreams-rpc-endpoints "${ ARBITRUM_ONE_EXECUTION_RPC}" --reader-node-arguments "$*"', _]
|
||||
command:
|
||||
- --execution.caching.archive=false
|
||||
- --execution.caching.state-scheme=hash
|
||||
- --execution.rpc.gas-cap=600000000
|
||||
- --execution.sequencer.enable=false
|
||||
- --firehose-enabled
|
||||
- --http.addr=0.0.0.0
|
||||
- --http.api=eth,net,web3,debug,admin,txpool,engine
|
||||
- --http.corsdomain=*
|
||||
- --http.port=8545
|
||||
- --http.vhosts=*
|
||||
- --init.download-path=/tmp
|
||||
- --init.latest=pruned
|
||||
- --persistent.chain=/firehose-data/reader/data/arbitrum-one
|
||||
- --persistent.db-engine=pebble
|
||||
- --ws.addr=0.0.0.0
|
||||
- --ws.origins=*
|
||||
- --ws.port=8545
|
||||
restart: unless-stopped
|
||||
stop_grace_period: 5m
|
||||
networks:
|
||||
- chains
|
||||
volumes:
|
||||
- ${ARBITRUM_ONE_FIREETH_PRUNED_PEBBLE_HASH_DATA:-arbitrum-one-fireeth-pruned-pebble-hash}:/firehose-data
|
||||
- ${ARBITRUM_ONE_FIREETH_PRUNED_PEBBLE_HASH_MERGED_BLOCKS_DATA:-arbitrum-one-fireeth-pruned-pebble-hash-blocks}:/firehose-data/storage/merged-blocks
|
||||
- /slowdisk:/slowdisk
|
||||
logging: *logging-defaults
|
||||
labels:
|
||||
- traefik.enable=true
|
||||
- traefik.http.middlewares.arbitrum-one-fireeth-pruned-pebble-hash-stripprefix.stripprefix.prefixes=/arbitrum-one
|
||||
- traefik.http.services.arbitrum-one-fireeth-pruned-pebble-hash.loadbalancer.server.port=8545
|
||||
- ${NO_SSL:-traefik.http.routers.arbitrum-one-fireeth-pruned-pebble-hash.entrypoints=websecure}
|
||||
- ${NO_SSL:-traefik.http.routers.arbitrum-one-fireeth-pruned-pebble-hash.tls.certresolver=myresolver}
|
||||
- ${NO_SSL:-traefik.http.routers.arbitrum-one-fireeth-pruned-pebble-hash.rule=Host(`$DOMAIN`) && (Path(`/arbitrum-one`) || Path(`/arbitrum-one/`))}
|
||||
- ${NO_SSL:+traefik.http.routers.arbitrum-one-fireeth-pruned-pebble-hash.rule=Path(`/arbitrum-one`) || Path(`/arbitrum-one/`)}
|
||||
- traefik.http.routers.arbitrum-one-fireeth-pruned-pebble-hash.middlewares=arbitrum-one-fireeth-pruned-pebble-hash-stripprefix, ipallowlist
|
||||
- traefik.http.services.arbitrum-one-fireeth-pruned-pebble-hash-firehose.loadbalancer.server.scheme=h2c
|
||||
- traefik.http.routers.arbitrum-one-fireeth-pruned-pebble-hash-firehose.service=arbitrum-one-fireeth-pruned-pebble-hash-firehose
|
||||
- traefik.http.services.arbitrum-one-fireeth-pruned-pebble-hash-firehose.loadbalancer.server.port=10015
|
||||
- traefik.http.routers.arbitrum-one-fireeth-pruned-pebble-hash-firehose.entrypoints=grpc
|
||||
- ${NO_SSL:-traefik.http.routers.arbitrum-one-fireeth-pruned-pebble-hash-firehose.tls.certresolver=myresolver}
|
||||
- traefik.http.routers.arbitrum-one-fireeth-pruned-pebble-hash-firehose.rule=Host(`arbitrum-one.${DOMAIN}`)
|
||||
- traefik.http.routers.arbitrum-one-fireeth-pruned-pebble-hash-firehose.middlewares=ipallowlist
|
||||
- traefik.http.services.arbitrum-one-fireeth-pruned-pebble-hash-substreams.loadbalancer.server.scheme=h2c
|
||||
- traefik.http.routers.arbitrum-one-fireeth-pruned-pebble-hash-substreams.service=arbitrum-one-fireeth-pruned-pebble-hash-substreams
|
||||
- traefik.http.services.arbitrum-one-fireeth-pruned-pebble-hash-substreams.loadbalancer.server.port=10016
|
||||
- traefik.http.routers.arbitrum-one-fireeth-pruned-pebble-hash-substreams.entrypoints=grpc
|
||||
- ${NO_SSL:-traefik.http.routers.arbitrum-one-fireeth-pruned-pebble-hash-substreams.tls.certresolver=myresolver}
|
||||
- traefik.http.routers.arbitrum-one-fireeth-pruned-pebble-hash-substreams.rule=Host(`arbitrum-one-substreams.${DOMAIN}`)
|
||||
- traefik.http.routers.arbitrum-one-fireeth-pruned-pebble-hash-substreams.middlewares=ipallowlist
|
||||
|
||||
volumes:
|
||||
arbitrum-one-fireeth-pruned-pebble-hash:
|
||||
arbitrum-one-fireeth-pruned-pebble-hash-blocks:
|
||||
|
||||
x-upstreams:
|
||||
- id: $${ID}
|
||||
labels:
|
||||
provider: $${PROVIDER}
|
||||
connection:
|
||||
generic:
|
||||
rpc:
|
||||
url: $${RPC_URL}
|
||||
ws:
|
||||
frameSize: 20Mb
|
||||
msgSize: 50Mb
|
||||
url: $${WS_URL}
|
||||
chain: arbitrum
|
||||
method-groups:
|
||||
enabled:
|
||||
- debug
|
||||
- filter
|
||||
methods:
|
||||
disabled:
|
||||
enabled:
|
||||
- name: txpool_content # TODO: should be disabled for rollup nodes
|
||||
# standard geth only
|
||||
- name: debug_getRawBlock
|
||||
- name: debug_getRawTransaction
|
||||
- name: debug_getRawReceipts
|
||||
- name: debug_getRawHeader
|
||||
- name: debug_getBadBlocks
|
||||
# non standard geth only slightly dangerous
|
||||
- name: debug_intermediateRoots
|
||||
- name: debug_dumpBlock
|
||||
# standard geth and erigon
|
||||
- name: debug_accountRange
|
||||
- name: debug_getModifiedAccountsByNumber
|
||||
- name: debug_getModifiedAccountsByHash
|
||||
# non standard geth and erigon
|
||||
- name: eth_getRawTransactionByHash
|
||||
- name: eth_getRawTransactionByBlockHashAndIndex
|
||||
...
|
||||
100
arb/nitro/alephzero-mainnet-nitro-archive-leveldb-hash.yml
Normal file
100
arb/nitro/alephzero-mainnet-nitro-archive-leveldb-hash.yml
Normal file
@@ -0,0 +1,100 @@
|
||||
---
|
||||
|
||||
services:
|
||||
alephzero-mainnet-archive:
|
||||
image: ${ALEPHZERO_NITRO_IMAGE:-offchainlabs/nitro-node}:${ALEPHZERO_MAINNET_NITRO_VERSION:-v3.5.3-0a9c975}
|
||||
sysctls:
|
||||
# TCP Performance
|
||||
net.ipv4.tcp_slow_start_after_idle: 0 # Disable slow start after idle
|
||||
net.ipv4.tcp_no_metrics_save: 1 # Disable metrics cache
|
||||
net.ipv4.tcp_rmem: 4096 87380 16777216 # Increase TCP read buffers
|
||||
net.ipv4.tcp_wmem: 4096 87380 16777216 # Increase TCP write buffers
|
||||
net.core.somaxconn: 32768 # Higher connection queue
|
||||
# Memory/Connection Management
|
||||
# net.core.netdev_max_backlog: 50000 # Increase network buffer
|
||||
net.ipv4.tcp_max_syn_backlog: 30000 # More SYN requests
|
||||
net.ipv4.tcp_max_tw_buckets: 2000000 # Allow more TIME_WAIT sockets
|
||||
ulimits:
|
||||
nofile: 1048576 # Max open files (for RPC/WS connections)
|
||||
user: root
|
||||
expose:
|
||||
- 8545
|
||||
command:
|
||||
- --conf.file=/config/baseConfig.json
|
||||
- --execution.caching.archive=true
|
||||
- --execution.caching.state-scheme=hash
|
||||
- --execution.forwarding-target=https://rpc.alephzero.raas.gelato.cloud
|
||||
- --execution.rpc.gas-cap=600000000
|
||||
- --execution.sequencer.enable=false
|
||||
- --http.addr=0.0.0.0
|
||||
- --http.api=eth,net,web3,arb,txpool,debug
|
||||
- --http.corsdomain=*
|
||||
- --http.port=8545
|
||||
- --http.vhosts=*
|
||||
- --node.batch-poster.enable=false
|
||||
- --node.data-availability.enable=true
|
||||
- --node.data-availability.parent-chain-node-url=${ETHEREUM_MAINNET_EXECUTION_RPC}
|
||||
- --node.data-availability.rest-aggregator.enable=true
|
||||
- --node.data-availability.rest-aggregator.urls=https://das.alephzero.raas.gelato.cloud
|
||||
- --node.data-availability.sequencer-inbox-address=0x1411949971076304187394088912578077660717096867958
|
||||
- --node.feed.input.url=wss://feed.alephzero.raas.gelato.cloud
|
||||
- --node.sequencer=false
|
||||
- --node.staker.enable=false
|
||||
- --parent-chain.blob-client.beacon-url=${ETHEREUM_MAINNET_BEACON_REST}
|
||||
- --parent-chain.connection.url=${ETHEREUM_MAINNET_EXECUTION_RPC}
|
||||
- --persistent.chain=/root/.arbitrum/alephzero-mainnet-archive
|
||||
- --persistent.db-engine=leveldb
|
||||
- --ws.addr=0.0.0.0
|
||||
- --ws.origins=*
|
||||
- --ws.port=8545
|
||||
restart: unless-stopped
|
||||
stop_grace_period: 5m
|
||||
networks:
|
||||
- chains
|
||||
volumes:
|
||||
- ${ALEPHZERO_MAINNET_NITRO_ARCHIVE_LEVELDB_HASH_DATA:-alephzero-mainnet-nitro-archive-leveldb-hash}:/root/.arbitrum
|
||||
- ./arb/alephzero/mainnet:/config
|
||||
- /slowdisk:/slowdisk
|
||||
labels:
|
||||
- traefik.enable=true
|
||||
- traefik.http.middlewares.alephzero-mainnet-nitro-archive-leveldb-hash-stripprefix.stripprefix.prefixes=/alephzero-mainnet-archive
|
||||
- traefik.http.services.alephzero-mainnet-nitro-archive-leveldb-hash.loadbalancer.server.port=8545
|
||||
- ${NO_SSL:-traefik.http.routers.alephzero-mainnet-nitro-archive-leveldb-hash.entrypoints=websecure}
|
||||
- ${NO_SSL:-traefik.http.routers.alephzero-mainnet-nitro-archive-leveldb-hash.tls.certresolver=myresolver}
|
||||
- ${NO_SSL:-traefik.http.routers.alephzero-mainnet-nitro-archive-leveldb-hash.rule=Host(`$DOMAIN`) && PathPrefix(`/alephzero-mainnet-archive`)}
|
||||
- ${NO_SSL:+traefik.http.routers.alephzero-mainnet-nitro-archive-leveldb-hash.rule=PathPrefix(`/alephzero-mainnet-archive`)}
|
||||
- traefik.http.routers.alephzero-mainnet-nitro-archive-leveldb-hash.middlewares=alephzero-mainnet-nitro-archive-leveldb-hash-stripprefix, ipwhitelist
|
||||
|
||||
volumes:
|
||||
alephzero-mainnet-nitro-archive-leveldb-hash:
|
||||
|
||||
x-upstreams:
|
||||
- id: $${ID}
|
||||
labels:
|
||||
provider: $${PROVIDER}
|
||||
chain: alephzero
|
||||
method-groups:
|
||||
enabled:
|
||||
- debug
|
||||
- filter
|
||||
methods:
|
||||
disabled:
|
||||
enabled:
|
||||
- name: txpool_content # TODO: should be disabled for rollup nodes
|
||||
# standard geth only
|
||||
- name: debug_getRawBlock
|
||||
- name: debug_getRawTransaction
|
||||
- name: debug_getRawReceipts
|
||||
- name: debug_getRawHeader
|
||||
- name: debug_getBadBlocks
|
||||
# non standard geth only slightly dangerous
|
||||
- name: debug_intermediateRoots
|
||||
- name: debug_dumpBlock
|
||||
# standard geth and erigon
|
||||
- name: debug_accountRange
|
||||
- name: debug_getModifiedAccountsByNumber
|
||||
- name: debug_getModifiedAccountsByHash
|
||||
# non standard geth and erigon
|
||||
- name: eth_getRawTransactionByHash
|
||||
- name: eth_getRawTransactionByBlockHashAndIndex
|
||||
...
|
||||
143
arb/nitro/alephzero-mainnet-nitro-archive-pebble-hash.yml
Normal file
143
arb/nitro/alephzero-mainnet-nitro-archive-pebble-hash.yml
Normal file
@@ -0,0 +1,143 @@
|
||||
---
|
||||
x-logging-defaults: &logging-defaults
|
||||
driver: json-file
|
||||
options:
|
||||
max-size: "10m"
|
||||
max-file: "3"
|
||||
|
||||
# Usage:
|
||||
#
|
||||
# mkdir rpc && cd rpc
|
||||
#
|
||||
# git init
|
||||
# git remote add origin https://github.com/StakeSquid/ethereum-rpc-docker.git
|
||||
# git fetch origin vibe
|
||||
# git checkout origin/vibe
|
||||
#
|
||||
# docker run --rm alpine sh -c "printf '0x'; head -c32 /dev/urandom | xxd -p -c 64" > .jwtsecret
|
||||
#
|
||||
# env
|
||||
# ...
|
||||
# IP=$(curl ipinfo.io/ip)
|
||||
# DOMAIN=${IP}.traefik.me
|
||||
# COMPOSE_FILE=base.yml:rpc.yml:arb/nitro/alephzero-mainnet-nitro-archive-pebble-hash.yml
|
||||
#
|
||||
# docker compose up -d
|
||||
#
|
||||
# curl -X POST https://${IP}.traefik.me/alephzero-mainnet-archive \
|
||||
# -H "Content-Type: application/json" \
|
||||
# --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'
|
||||
|
||||
services:
|
||||
alephzero-mainnet-archive:
|
||||
image: ${ALEPHZERO_NITRO_IMAGE:-offchainlabs/nitro-node}:${ALEPHZERO_MAINNET_NITRO_VERSION:-v3.6.4-28199cd}
|
||||
sysctls:
|
||||
# TCP Performance
|
||||
net.ipv4.tcp_slow_start_after_idle: 0 # Disable slow start after idle
|
||||
net.ipv4.tcp_no_metrics_save: 1 # Disable metrics cache
|
||||
net.ipv4.tcp_rmem: 4096 87380 16777216 # Increase TCP read buffers
|
||||
net.ipv4.tcp_wmem: 4096 87380 16777216 # Increase TCP write buffers
|
||||
net.core.somaxconn: 32768 # Higher connection queue
|
||||
# Memory/Connection Management
|
||||
# net.core.netdev_max_backlog: 50000 # Increase network buffer
|
||||
net.ipv4.tcp_max_syn_backlog: 30000 # More SYN requests
|
||||
net.ipv4.tcp_max_tw_buckets: 2000000 # Allow more TIME_WAIT sockets
|
||||
ulimits:
|
||||
nofile: 1048576 # Max open files (for RPC/WS connections)
|
||||
user: root
|
||||
expose:
|
||||
- 8545
|
||||
command:
|
||||
- --conf.file=/config/baseConfig.json
|
||||
- --execution.caching.archive=true
|
||||
- --execution.forwarding-target=https://rpc.alephzero.raas.gelato.cloud
|
||||
- --execution.rpc.gas-cap=600000000
|
||||
- --execution.sequencer.enable=false
|
||||
- --http.addr=0.0.0.0
|
||||
- --http.api=eth,net,web3,arb,txpool,debug
|
||||
- --http.corsdomain=*
|
||||
- --http.port=8545
|
||||
- --http.vhosts=*
|
||||
- --init.download-path=/tmp
|
||||
- --metrics
|
||||
- --metrics-server.addr=0.0.0.0
|
||||
- --metrics-server.port=6070
|
||||
- --node.batch-poster.enable=false
|
||||
- --node.data-availability.enable=true
|
||||
- --node.data-availability.parent-chain-node-url=${ETHEREUM_MAINNET_EXECUTION_RPC}
|
||||
- --node.data-availability.rest-aggregator.enable=true
|
||||
- --node.data-availability.rest-aggregator.urls=https://das.alephzero.raas.gelato.cloud
|
||||
- --node.data-availability.sequencer-inbox-address=0x1411949971076304187394088912578077660717096867958
|
||||
- --node.feed.input.url=wss://feed.alephzero.raas.gelato.cloud
|
||||
- --node.sequencer=false
|
||||
- --node.staker.enable=false
|
||||
- --parent-chain.blob-client.beacon-url=${ETHEREUM_MAINNET_BEACON_REST}
|
||||
- --parent-chain.connection.url=${ETHEREUM_MAINNET_EXECUTION_RPC}
|
||||
- --persistent.chain=/root/.arbitrum/alephzero-mainnet-archive
|
||||
- --persistent.db-engine=pebble
|
||||
- --ws.addr=0.0.0.0
|
||||
- --ws.origins=*
|
||||
- --ws.port=8545
|
||||
restart: unless-stopped
|
||||
stop_grace_period: 5m
|
||||
networks:
|
||||
- chains
|
||||
volumes:
|
||||
- ${ALEPHZERO_MAINNET_NITRO_ARCHIVE_PEBBLE_HASH_DATA:-alephzero-mainnet-nitro-archive-pebble-hash}:/root/.arbitrum
|
||||
- ./arb/alephzero/mainnet:/config
|
||||
- /slowdisk:/slowdisk
|
||||
logging: *logging-defaults
|
||||
labels:
|
||||
- prometheus-scrape.enabled=true
|
||||
- prometheus-scrape.port=6070
|
||||
- prometheus-scrape.path=/debug/metrics/prometheus
|
||||
- traefik.enable=true
|
||||
- traefik.http.middlewares.alephzero-mainnet-nitro-archive-pebble-hash-stripprefix.stripprefix.prefixes=/alephzero-mainnet-archive
|
||||
- traefik.http.services.alephzero-mainnet-nitro-archive-pebble-hash.loadbalancer.server.port=8545
|
||||
- ${NO_SSL:-traefik.http.routers.alephzero-mainnet-nitro-archive-pebble-hash.entrypoints=websecure}
|
||||
- ${NO_SSL:-traefik.http.routers.alephzero-mainnet-nitro-archive-pebble-hash.tls.certresolver=myresolver}
|
||||
- ${NO_SSL:-traefik.http.routers.alephzero-mainnet-nitro-archive-pebble-hash.rule=Host(`$DOMAIN`) && (Path(`/alephzero-mainnet-archive`) || Path(`/alephzero-mainnet-archive/`))}
|
||||
- ${NO_SSL:+traefik.http.routers.alephzero-mainnet-nitro-archive-pebble-hash.rule=Path(`/alephzero-mainnet-archive`) || Path(`/alephzero-mainnet-archive/`)}
|
||||
- traefik.http.routers.alephzero-mainnet-nitro-archive-pebble-hash.middlewares=alephzero-mainnet-nitro-archive-pebble-hash-stripprefix, ipallowlist
|
||||
|
||||
volumes:
|
||||
alephzero-mainnet-nitro-archive-pebble-hash:
|
||||
|
||||
x-upstreams:
|
||||
- id: $${ID}
|
||||
labels:
|
||||
provider: $${PROVIDER}
|
||||
connection:
|
||||
generic:
|
||||
rpc:
|
||||
url: $${RPC_URL}
|
||||
ws:
|
||||
frameSize: 20Mb
|
||||
msgSize: 50Mb
|
||||
url: $${WS_URL}
|
||||
chain: alephzero
|
||||
method-groups:
|
||||
enabled:
|
||||
- debug
|
||||
- filter
|
||||
methods:
|
||||
disabled:
|
||||
enabled:
|
||||
- name: txpool_content # TODO: should be disabled for rollup nodes
|
||||
# standard geth only
|
||||
- name: debug_getRawBlock
|
||||
- name: debug_getRawTransaction
|
||||
- name: debug_getRawReceipts
|
||||
- name: debug_getRawHeader
|
||||
- name: debug_getBadBlocks
|
||||
# non standard geth only slightly dangerous
|
||||
- name: debug_intermediateRoots
|
||||
- name: debug_dumpBlock
|
||||
# standard geth and erigon
|
||||
- name: debug_accountRange
|
||||
- name: debug_getModifiedAccountsByNumber
|
||||
- name: debug_getModifiedAccountsByHash
|
||||
# non standard geth and erigon
|
||||
- name: eth_getRawTransactionByHash
|
||||
- name: eth_getRawTransactionByBlockHashAndIndex
|
||||
...
|
||||
146
arb/nitro/alephzero-mainnet-nitro-pruned-pebble-path.yml
Normal file
146
arb/nitro/alephzero-mainnet-nitro-pruned-pebble-path.yml
Normal file
@@ -0,0 +1,146 @@
|
||||
---
|
||||
x-logging-defaults: &logging-defaults
|
||||
driver: json-file
|
||||
options:
|
||||
max-size: "10m"
|
||||
max-file: "3"
|
||||
|
||||
# Usage:
|
||||
#
|
||||
# mkdir rpc && cd rpc
|
||||
#
|
||||
# git init
|
||||
# git remote add origin https://github.com/StakeSquid/ethereum-rpc-docker.git
|
||||
# git fetch origin vibe
|
||||
# git checkout origin/vibe
|
||||
#
|
||||
# docker run --rm alpine sh -c "printf '0x'; head -c32 /dev/urandom | xxd -p -c 64" > .jwtsecret
|
||||
#
|
||||
# env
|
||||
# ...
|
||||
# IP=$(curl ipinfo.io/ip)
|
||||
# DOMAIN=${IP}.traefik.me
|
||||
# COMPOSE_FILE=base.yml:rpc.yml:arb/nitro/alephzero-mainnet-nitro-pruned-pebble-path.yml
|
||||
#
|
||||
# docker compose up -d
|
||||
#
|
||||
# curl -X POST https://${IP}.traefik.me/alephzero-mainnet \
|
||||
# -H "Content-Type: application/json" \
|
||||
# --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'
|
||||
|
||||
services:
|
||||
alephzero-mainnet:
|
||||
image: ${ALEPHZERO_NITRO_IMAGE:-offchainlabs/nitro-node}:${ALEPHZERO_MAINNET_NITRO_VERSION:-v3.6.4-28199cd}
|
||||
sysctls:
|
||||
# TCP Performance
|
||||
net.ipv4.tcp_slow_start_after_idle: 0 # Disable slow start after idle
|
||||
net.ipv4.tcp_no_metrics_save: 1 # Disable metrics cache
|
||||
net.ipv4.tcp_rmem: 4096 87380 16777216 # Increase TCP read buffers
|
||||
net.ipv4.tcp_wmem: 4096 87380 16777216 # Increase TCP write buffers
|
||||
net.core.somaxconn: 32768 # Higher connection queue
|
||||
# Memory/Connection Management
|
||||
# net.core.netdev_max_backlog: 50000 # Increase network buffer
|
||||
net.ipv4.tcp_max_syn_backlog: 30000 # More SYN requests
|
||||
net.ipv4.tcp_max_tw_buckets: 2000000 # Allow more TIME_WAIT sockets
|
||||
ulimits:
|
||||
nofile: 1048576 # Max open files (for RPC/WS connections)
|
||||
user: root
|
||||
expose:
|
||||
- 8545
|
||||
command:
|
||||
- --conf.file=/config/baseConfig.json
|
||||
- --execution.caching.archive=false
|
||||
- --execution.caching.state-scheme=path
|
||||
- --execution.forwarding-target=https://rpc.alephzero.raas.gelato.cloud
|
||||
- --execution.rpc.gas-cap=600000000
|
||||
- --execution.sequencer.enable=false
|
||||
- --http.addr=0.0.0.0
|
||||
- --http.api=eth,net,web3,arb,txpool,debug
|
||||
- --http.corsdomain=*
|
||||
- --http.port=8545
|
||||
- --http.vhosts=*
|
||||
- --init.download-path=/tmp
|
||||
- --metrics
|
||||
- --metrics-server.addr=0.0.0.0
|
||||
- --metrics-server.port=6070
|
||||
- --node.batch-poster.enable=false
|
||||
- --node.data-availability.enable=true
|
||||
- --node.data-availability.parent-chain-node-url=${ETHEREUM_MAINNET_EXECUTION_RPC}
|
||||
- --node.data-availability.rest-aggregator.enable=true
|
||||
- --node.data-availability.rest-aggregator.urls=https://das.alephzero.raas.gelato.cloud
|
||||
- --node.data-availability.sequencer-inbox-address=0x1411949971076304187394088912578077660717096867958
|
||||
- --node.feed.input.url=wss://feed.alephzero.raas.gelato.cloud
|
||||
- --node.sequencer=false
|
||||
- --node.staker.enable=false
|
||||
- --parent-chain.blob-client.beacon-url=${ETHEREUM_MAINNET_BEACON_REST}
|
||||
- --parent-chain.connection.url=${ETHEREUM_MAINNET_EXECUTION_RPC}
|
||||
- --persistent.chain=/root/.arbitrum/alephzero-mainnet
|
||||
- --persistent.db-engine=pebble
|
||||
- --ws.addr=0.0.0.0
|
||||
- --ws.origins=*
|
||||
- --ws.port=8545
|
||||
restart: unless-stopped
|
||||
stop_grace_period: 5m
|
||||
networks:
|
||||
- chains
|
||||
volumes:
|
||||
- ${ALEPHZERO_MAINNET_NITRO_PRUNED_PEBBLE_PATH_DATA:-alephzero-mainnet-nitro-pruned-pebble-path}:/root/.arbitrum
|
||||
- ./arb/alephzero/mainnet:/config
|
||||
- /slowdisk:/slowdisk
|
||||
logging: *logging-defaults
|
||||
labels:
|
||||
- prometheus-scrape.enabled=true
|
||||
- prometheus-scrape.port=6070
|
||||
- prometheus-scrape.path=/debug/metrics/prometheus
|
||||
- traefik.enable=true
|
||||
- traefik.http.middlewares.alephzero-mainnet-nitro-pruned-pebble-path-stripprefix.stripprefix.prefixes=/alephzero-mainnet
|
||||
- traefik.http.services.alephzero-mainnet-nitro-pruned-pebble-path.loadbalancer.server.port=8545
|
||||
- ${NO_SSL:-traefik.http.routers.alephzero-mainnet-nitro-pruned-pebble-path.entrypoints=websecure}
|
||||
- ${NO_SSL:-traefik.http.routers.alephzero-mainnet-nitro-pruned-pebble-path.tls.certresolver=myresolver}
|
||||
- ${NO_SSL:-traefik.http.routers.alephzero-mainnet-nitro-pruned-pebble-path.rule=Host(`$DOMAIN`) && (Path(`/alephzero-mainnet`) || Path(`/alephzero-mainnet/`))}
|
||||
- ${NO_SSL:+traefik.http.routers.alephzero-mainnet-nitro-pruned-pebble-path.rule=Path(`/alephzero-mainnet`) || Path(`/alephzero-mainnet/`)}
|
||||
- traefik.http.routers.alephzero-mainnet-nitro-pruned-pebble-path.middlewares=alephzero-mainnet-nitro-pruned-pebble-path-stripprefix, ipallowlist
|
||||
|
||||
volumes:
|
||||
alephzero-mainnet-nitro-pruned-pebble-path:
|
||||
|
||||
x-upstreams:
|
||||
- id: $${ID}
|
||||
labels:
|
||||
provider: $${PROVIDER}
|
||||
connection:
|
||||
generic:
|
||||
rpc:
|
||||
url: $${RPC_URL}
|
||||
ws:
|
||||
frameSize: 20Mb
|
||||
msgSize: 50Mb
|
||||
url: $${WS_URL}
|
||||
chain: alephzero
|
||||
method-groups:
|
||||
enabled:
|
||||
- debug
|
||||
- filter
|
||||
methods:
|
||||
disabled:
|
||||
# not compatible with path state scheme
|
||||
- name: debug_traceBlockByHash
|
||||
enabled:
|
||||
- name: txpool_content # TODO: should be disabled for rollup nodes
|
||||
# standard geth only
|
||||
- name: debug_getRawBlock
|
||||
- name: debug_getRawTransaction
|
||||
- name: debug_getRawReceipts
|
||||
- name: debug_getRawHeader
|
||||
- name: debug_getBadBlocks
|
||||
# non standard geth only slightly dangerous
|
||||
- name: debug_intermediateRoots
|
||||
- name: debug_dumpBlock
|
||||
# standard geth and erigon
|
||||
- name: debug_accountRange
|
||||
- name: debug_getModifiedAccountsByNumber
|
||||
- name: debug_getModifiedAccountsByHash
|
||||
# non standard geth and erigon
|
||||
- name: eth_getRawTransactionByHash
|
||||
- name: eth_getRawTransactionByBlockHashAndIndex
|
||||
...
|
||||
100
arb/nitro/alephzero-sepolia-nitro-archive-leveldb-hash.yml
Normal file
100
arb/nitro/alephzero-sepolia-nitro-archive-leveldb-hash.yml
Normal file
@@ -0,0 +1,100 @@
|
||||
---
|
||||
|
||||
services:
|
||||
alephzero-sepolia-archive:
|
||||
image: ${ALEPHZERO_NITRO_IMAGE:-offchainlabs/nitro-node}:${ALEPHZERO_SEPOLIA_NITRO_VERSION:-v3.5.3-0a9c975}
|
||||
sysctls:
|
||||
# TCP Performance
|
||||
net.ipv4.tcp_slow_start_after_idle: 0 # Disable slow start after idle
|
||||
net.ipv4.tcp_no_metrics_save: 1 # Disable metrics cache
|
||||
net.ipv4.tcp_rmem: 4096 87380 16777216 # Increase TCP read buffers
|
||||
net.ipv4.tcp_wmem: 4096 87380 16777216 # Increase TCP write buffers
|
||||
net.core.somaxconn: 32768 # Higher connection queue
|
||||
# Memory/Connection Management
|
||||
# net.core.netdev_max_backlog: 50000 # Increase network buffer
|
||||
net.ipv4.tcp_max_syn_backlog: 30000 # More SYN requests
|
||||
net.ipv4.tcp_max_tw_buckets: 2000000 # Allow more TIME_WAIT sockets
|
||||
ulimits:
|
||||
nofile: 1048576 # Max open files (for RPC/WS connections)
|
||||
user: root
|
||||
expose:
|
||||
- 8545
|
||||
command:
|
||||
- --conf.file=/config/baseConfig.json
|
||||
- --execution.caching.archive=true
|
||||
- --execution.caching.state-scheme=hash
|
||||
- --execution.forwarding-target=https://rpc.alephzero-testnet.gelato.digital
|
||||
- --execution.rpc.gas-cap=600000000
|
||||
- --execution.sequencer.enable=false
|
||||
- --http.addr=0.0.0.0
|
||||
- --http.api=eth,net,web3,arb,txpool,debug
|
||||
- --http.corsdomain=*
|
||||
- --http.port=8545
|
||||
- --http.vhosts=*
|
||||
- --node.batch-poster.enable=false
|
||||
- --node.data-availability.enable=true
|
||||
- --node.data-availability.parent-chain-node-url=${ETHEREUM_SEPOLIA_EXECUTION_RPC}
|
||||
- --node.data-availability.rest-aggregator.enable=true
|
||||
- --node.data-availability.rest-aggregator.urls=https://das.alephzero-testnet.gelato.digital
|
||||
- --node.data-availability.sequencer-inbox-address=0x130937498521962644184395825246273622310592356541
|
||||
- --node.feed.input.url=wss://feed.alephzero-testnet.gelato.digital
|
||||
- --node.sequencer=false
|
||||
- --node.staker.enable=false
|
||||
- --parent-chain.blob-client.beacon-url=${ETHEREUM_SEPOLIA_BEACON_REST}
|
||||
- --parent-chain.connection.url=${ETHEREUM_SEPOLIA_EXECUTION_RPC}
|
||||
- --persistent.chain=/root/.arbitrum/alephzero-sepolia-archive
|
||||
- --persistent.db-engine=leveldb
|
||||
- --ws.addr=0.0.0.0
|
||||
- --ws.origins=*
|
||||
- --ws.port=8545
|
||||
restart: unless-stopped
|
||||
stop_grace_period: 5m
|
||||
networks:
|
||||
- chains
|
||||
volumes:
|
||||
- ${ALEPHZERO_SEPOLIA_NITRO_ARCHIVE_LEVELDB_HASH_DATA:-alephzero-sepolia-nitro-archive-leveldb-hash}:/root/.arbitrum
|
||||
- ./arb/alephzero/sepolia:/config
|
||||
- /slowdisk:/slowdisk
|
||||
labels:
|
||||
- traefik.enable=true
|
||||
- traefik.http.middlewares.alephzero-sepolia-nitro-archive-leveldb-hash-stripprefix.stripprefix.prefixes=/alephzero-sepolia-archive
|
||||
- traefik.http.services.alephzero-sepolia-nitro-archive-leveldb-hash.loadbalancer.server.port=8545
|
||||
- ${NO_SSL:-traefik.http.routers.alephzero-sepolia-nitro-archive-leveldb-hash.entrypoints=websecure}
|
||||
- ${NO_SSL:-traefik.http.routers.alephzero-sepolia-nitro-archive-leveldb-hash.tls.certresolver=myresolver}
|
||||
- ${NO_SSL:-traefik.http.routers.alephzero-sepolia-nitro-archive-leveldb-hash.rule=Host(`$DOMAIN`) && PathPrefix(`/alephzero-sepolia-archive`)}
|
||||
- ${NO_SSL:+traefik.http.routers.alephzero-sepolia-nitro-archive-leveldb-hash.rule=PathPrefix(`/alephzero-sepolia-archive`)}
|
||||
- traefik.http.routers.alephzero-sepolia-nitro-archive-leveldb-hash.middlewares=alephzero-sepolia-nitro-archive-leveldb-hash-stripprefix, ipwhitelist
|
||||
|
||||
volumes:
|
||||
alephzero-sepolia-nitro-archive-leveldb-hash:
|
||||
|
||||
x-upstreams:
|
||||
- id: $${ID}
|
||||
labels:
|
||||
provider: $${PROVIDER}
|
||||
chain: alephzero-sepolia
|
||||
method-groups:
|
||||
enabled:
|
||||
- debug
|
||||
- filter
|
||||
methods:
|
||||
disabled:
|
||||
enabled:
|
||||
- name: txpool_content # TODO: should be disabled for rollup nodes
|
||||
# standard geth only
|
||||
- name: debug_getRawBlock
|
||||
- name: debug_getRawTransaction
|
||||
- name: debug_getRawReceipts
|
||||
- name: debug_getRawHeader
|
||||
- name: debug_getBadBlocks
|
||||
# non standard geth only slightly dangerous
|
||||
- name: debug_intermediateRoots
|
||||
- name: debug_dumpBlock
|
||||
# standard geth and erigon
|
||||
- name: debug_accountRange
|
||||
- name: debug_getModifiedAccountsByNumber
|
||||
- name: debug_getModifiedAccountsByHash
|
||||
# non standard geth and erigon
|
||||
- name: eth_getRawTransactionByHash
|
||||
- name: eth_getRawTransactionByBlockHashAndIndex
|
||||
...
|
||||
143
arb/nitro/alephzero-sepolia-nitro-archive-pebble-hash.yml
Normal file
143
arb/nitro/alephzero-sepolia-nitro-archive-pebble-hash.yml
Normal file
@@ -0,0 +1,143 @@
|
||||
---
|
||||
x-logging-defaults: &logging-defaults
|
||||
driver: json-file
|
||||
options:
|
||||
max-size: "10m"
|
||||
max-file: "3"
|
||||
|
||||
# Usage:
|
||||
#
|
||||
# mkdir rpc && cd rpc
|
||||
#
|
||||
# git init
|
||||
# git remote add origin https://github.com/StakeSquid/ethereum-rpc-docker.git
|
||||
# git fetch origin vibe
|
||||
# git checkout origin/vibe
|
||||
#
|
||||
# docker run --rm alpine sh -c "printf '0x'; head -c32 /dev/urandom | xxd -p -c 64" > .jwtsecret
|
||||
#
|
||||
# env
|
||||
# ...
|
||||
# IP=$(curl ipinfo.io/ip)
|
||||
# DOMAIN=${IP}.traefik.me
|
||||
# COMPOSE_FILE=base.yml:rpc.yml:arb/nitro/alephzero-sepolia-nitro-archive-pebble-hash.yml
|
||||
#
|
||||
# docker compose up -d
|
||||
#
|
||||
# curl -X POST https://${IP}.traefik.me/alephzero-sepolia-archive \
|
||||
# -H "Content-Type: application/json" \
|
||||
# --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'
|
||||
|
||||
services:
|
||||
alephzero-sepolia-archive:
|
||||
image: ${ALEPHZERO_NITRO_IMAGE:-offchainlabs/nitro-node}:${ALEPHZERO_SEPOLIA_NITRO_VERSION:-v3.6.4-28199cd}
|
||||
sysctls:
|
||||
# TCP Performance
|
||||
net.ipv4.tcp_slow_start_after_idle: 0 # Disable slow start after idle
|
||||
net.ipv4.tcp_no_metrics_save: 1 # Disable metrics cache
|
||||
net.ipv4.tcp_rmem: 4096 87380 16777216 # Increase TCP read buffers
|
||||
net.ipv4.tcp_wmem: 4096 87380 16777216 # Increase TCP write buffers
|
||||
net.core.somaxconn: 32768 # Higher connection queue
|
||||
# Memory/Connection Management
|
||||
# net.core.netdev_max_backlog: 50000 # Increase network buffer
|
||||
net.ipv4.tcp_max_syn_backlog: 30000 # More SYN requests
|
||||
net.ipv4.tcp_max_tw_buckets: 2000000 # Allow more TIME_WAIT sockets
|
||||
ulimits:
|
||||
nofile: 1048576 # Max open files (for RPC/WS connections)
|
||||
user: root
|
||||
expose:
|
||||
- 8545
|
||||
command:
|
||||
- --conf.file=/config/baseConfig.json
|
||||
- --execution.caching.archive=true
|
||||
- --execution.forwarding-target=https://rpc.alephzero-testnet.gelato.digital
|
||||
- --execution.rpc.gas-cap=600000000
|
||||
- --execution.sequencer.enable=false
|
||||
- --http.addr=0.0.0.0
|
||||
- --http.api=eth,net,web3,arb,txpool,debug
|
||||
- --http.corsdomain=*
|
||||
- --http.port=8545
|
||||
- --http.vhosts=*
|
||||
- --init.download-path=/tmp
|
||||
- --metrics
|
||||
- --metrics-server.addr=0.0.0.0
|
||||
- --metrics-server.port=6070
|
||||
- --node.batch-poster.enable=false
|
||||
- --node.data-availability.enable=true
|
||||
- --node.data-availability.parent-chain-node-url=${ETHEREUM_SEPOLIA_EXECUTION_RPC}
|
||||
- --node.data-availability.rest-aggregator.enable=true
|
||||
- --node.data-availability.rest-aggregator.urls=https://das.alephzero-testnet.gelato.digital
|
||||
- --node.data-availability.sequencer-inbox-address=0x130937498521962644184395825246273622310592356541
|
||||
- --node.feed.input.url=wss://feed.alephzero-testnet.gelato.digital
|
||||
- --node.sequencer=false
|
||||
- --node.staker.enable=false
|
||||
- --parent-chain.blob-client.beacon-url=${ETHEREUM_SEPOLIA_BEACON_REST}
|
||||
- --parent-chain.connection.url=${ETHEREUM_SEPOLIA_EXECUTION_RPC}
|
||||
- --persistent.chain=/root/.arbitrum/alephzero-sepolia-archive
|
||||
- --persistent.db-engine=pebble
|
||||
- --ws.addr=0.0.0.0
|
||||
- --ws.origins=*
|
||||
- --ws.port=8545
|
||||
restart: unless-stopped
|
||||
stop_grace_period: 5m
|
||||
networks:
|
||||
- chains
|
||||
volumes:
|
||||
- ${ALEPHZERO_SEPOLIA_NITRO_ARCHIVE_PEBBLE_HASH_DATA:-alephzero-sepolia-nitro-archive-pebble-hash}:/root/.arbitrum
|
||||
- ./arb/alephzero/sepolia:/config
|
||||
- /slowdisk:/slowdisk
|
||||
logging: *logging-defaults
|
||||
labels:
|
||||
- prometheus-scrape.enabled=true
|
||||
- prometheus-scrape.port=6070
|
||||
- prometheus-scrape.path=/debug/metrics/prometheus
|
||||
- traefik.enable=true
|
||||
- traefik.http.middlewares.alephzero-sepolia-nitro-archive-pebble-hash-stripprefix.stripprefix.prefixes=/alephzero-sepolia-archive
|
||||
- traefik.http.services.alephzero-sepolia-nitro-archive-pebble-hash.loadbalancer.server.port=8545
|
||||
- ${NO_SSL:-traefik.http.routers.alephzero-sepolia-nitro-archive-pebble-hash.entrypoints=websecure}
|
||||
- ${NO_SSL:-traefik.http.routers.alephzero-sepolia-nitro-archive-pebble-hash.tls.certresolver=myresolver}
|
||||
- ${NO_SSL:-traefik.http.routers.alephzero-sepolia-nitro-archive-pebble-hash.rule=Host(`$DOMAIN`) && (Path(`/alephzero-sepolia-archive`) || Path(`/alephzero-sepolia-archive/`))}
|
||||
- ${NO_SSL:+traefik.http.routers.alephzero-sepolia-nitro-archive-pebble-hash.rule=Path(`/alephzero-sepolia-archive`) || Path(`/alephzero-sepolia-archive/`)}
|
||||
- traefik.http.routers.alephzero-sepolia-nitro-archive-pebble-hash.middlewares=alephzero-sepolia-nitro-archive-pebble-hash-stripprefix, ipallowlist
|
||||
|
||||
volumes:
|
||||
alephzero-sepolia-nitro-archive-pebble-hash:
|
||||
|
||||
x-upstreams:
|
||||
- id: $${ID}
|
||||
labels:
|
||||
provider: $${PROVIDER}
|
||||
connection:
|
||||
generic:
|
||||
rpc:
|
||||
url: $${RPC_URL}
|
||||
ws:
|
||||
frameSize: 20Mb
|
||||
msgSize: 50Mb
|
||||
url: $${WS_URL}
|
||||
chain: alephzero-sepolia
|
||||
method-groups:
|
||||
enabled:
|
||||
- debug
|
||||
- filter
|
||||
methods:
|
||||
disabled:
|
||||
enabled:
|
||||
- name: txpool_content # TODO: should be disabled for rollup nodes
|
||||
# standard geth only
|
||||
- name: debug_getRawBlock
|
||||
- name: debug_getRawTransaction
|
||||
- name: debug_getRawReceipts
|
||||
- name: debug_getRawHeader
|
||||
- name: debug_getBadBlocks
|
||||
# non standard geth only slightly dangerous
|
||||
- name: debug_intermediateRoots
|
||||
- name: debug_dumpBlock
|
||||
# standard geth and erigon
|
||||
- name: debug_accountRange
|
||||
- name: debug_getModifiedAccountsByNumber
|
||||
- name: debug_getModifiedAccountsByHash
|
||||
# non standard geth and erigon
|
||||
- name: eth_getRawTransactionByHash
|
||||
- name: eth_getRawTransactionByBlockHashAndIndex
|
||||
...
|
||||
146
arb/nitro/alephzero-sepolia-nitro-pruned-pebble-path.yml
Normal file
146
arb/nitro/alephzero-sepolia-nitro-pruned-pebble-path.yml
Normal file
@@ -0,0 +1,146 @@
|
||||
---
|
||||
x-logging-defaults: &logging-defaults
|
||||
driver: json-file
|
||||
options:
|
||||
max-size: "10m"
|
||||
max-file: "3"
|
||||
|
||||
# Usage:
|
||||
#
|
||||
# mkdir rpc && cd rpc
|
||||
#
|
||||
# git init
|
||||
# git remote add origin https://github.com/StakeSquid/ethereum-rpc-docker.git
|
||||
# git fetch origin vibe
|
||||
# git checkout origin/vibe
|
||||
#
|
||||
# docker run --rm alpine sh -c "printf '0x'; head -c32 /dev/urandom | xxd -p -c 64" > .jwtsecret
|
||||
#
|
||||
# env
|
||||
# ...
|
||||
# IP=$(curl ipinfo.io/ip)
|
||||
# DOMAIN=${IP}.traefik.me
|
||||
# COMPOSE_FILE=base.yml:rpc.yml:arb/nitro/alephzero-sepolia-nitro-pruned-pebble-path.yml
|
||||
#
|
||||
# docker compose up -d
|
||||
#
|
||||
# curl -X POST https://${IP}.traefik.me/alephzero-sepolia \
|
||||
# -H "Content-Type: application/json" \
|
||||
# --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'
|
||||
|
||||
services:
|
||||
alephzero-sepolia:
|
||||
image: ${ALEPHZERO_NITRO_IMAGE:-offchainlabs/nitro-node}:${ALEPHZERO_SEPOLIA_NITRO_VERSION:-v3.6.4-28199cd}
|
||||
sysctls:
|
||||
# TCP Performance
|
||||
net.ipv4.tcp_slow_start_after_idle: 0 # Disable slow start after idle
|
||||
net.ipv4.tcp_no_metrics_save: 1 # Disable metrics cache
|
||||
net.ipv4.tcp_rmem: 4096 87380 16777216 # Increase TCP read buffers
|
||||
net.ipv4.tcp_wmem: 4096 87380 16777216 # Increase TCP write buffers
|
||||
net.core.somaxconn: 32768 # Higher connection queue
|
||||
# Memory/Connection Management
|
||||
# net.core.netdev_max_backlog: 50000 # Increase network buffer
|
||||
net.ipv4.tcp_max_syn_backlog: 30000 # More SYN requests
|
||||
net.ipv4.tcp_max_tw_buckets: 2000000 # Allow more TIME_WAIT sockets
|
||||
ulimits:
|
||||
nofile: 1048576 # Max open files (for RPC/WS connections)
|
||||
user: root
|
||||
expose:
|
||||
- 8545
|
||||
command:
|
||||
- --conf.file=/config/baseConfig.json
|
||||
- --execution.caching.archive=false
|
||||
- --execution.caching.state-scheme=path
|
||||
- --execution.forwarding-target=https://rpc.alephzero-testnet.gelato.digital
|
||||
- --execution.rpc.gas-cap=600000000
|
||||
- --execution.sequencer.enable=false
|
||||
- --http.addr=0.0.0.0
|
||||
- --http.api=eth,net,web3,arb,txpool,debug
|
||||
- --http.corsdomain=*
|
||||
- --http.port=8545
|
||||
- --http.vhosts=*
|
||||
- --init.download-path=/tmp
|
||||
- --metrics
|
||||
- --metrics-server.addr=0.0.0.0
|
||||
- --metrics-server.port=6070
|
||||
- --node.batch-poster.enable=false
|
||||
- --node.data-availability.enable=true
|
||||
- --node.data-availability.parent-chain-node-url=${ETHEREUM_SEPOLIA_EXECUTION_RPC}
|
||||
- --node.data-availability.rest-aggregator.enable=true
|
||||
- --node.data-availability.rest-aggregator.urls=https://das.alephzero-testnet.gelato.digital
|
||||
- --node.data-availability.sequencer-inbox-address=0x130937498521962644184395825246273622310592356541
|
||||
- --node.feed.input.url=wss://feed.alephzero-testnet.gelato.digital
|
||||
- --node.sequencer=false
|
||||
- --node.staker.enable=false
|
||||
- --parent-chain.blob-client.beacon-url=${ETHEREUM_SEPOLIA_BEACON_REST}
|
||||
- --parent-chain.connection.url=${ETHEREUM_SEPOLIA_EXECUTION_RPC}
|
||||
- --persistent.chain=/root/.arbitrum/alephzero-sepolia
|
||||
- --persistent.db-engine=pebble
|
||||
- --ws.addr=0.0.0.0
|
||||
- --ws.origins=*
|
||||
- --ws.port=8545
|
||||
restart: unless-stopped
|
||||
stop_grace_period: 5m
|
||||
networks:
|
||||
- chains
|
||||
volumes:
|
||||
- ${ALEPHZERO_SEPOLIA_NITRO_PRUNED_PEBBLE_PATH_DATA:-alephzero-sepolia-nitro-pruned-pebble-path}:/root/.arbitrum
|
||||
- ./arb/alephzero/sepolia:/config
|
||||
- /slowdisk:/slowdisk
|
||||
logging: *logging-defaults
|
||||
labels:
|
||||
- prometheus-scrape.enabled=true
|
||||
- prometheus-scrape.port=6070
|
||||
- prometheus-scrape.path=/debug/metrics/prometheus
|
||||
- traefik.enable=true
|
||||
- traefik.http.middlewares.alephzero-sepolia-nitro-pruned-pebble-path-stripprefix.stripprefix.prefixes=/alephzero-sepolia
|
||||
- traefik.http.services.alephzero-sepolia-nitro-pruned-pebble-path.loadbalancer.server.port=8545
|
||||
- ${NO_SSL:-traefik.http.routers.alephzero-sepolia-nitro-pruned-pebble-path.entrypoints=websecure}
|
||||
- ${NO_SSL:-traefik.http.routers.alephzero-sepolia-nitro-pruned-pebble-path.tls.certresolver=myresolver}
|
||||
- ${NO_SSL:-traefik.http.routers.alephzero-sepolia-nitro-pruned-pebble-path.rule=Host(`$DOMAIN`) && (Path(`/alephzero-sepolia`) || Path(`/alephzero-sepolia/`))}
|
||||
- ${NO_SSL:+traefik.http.routers.alephzero-sepolia-nitro-pruned-pebble-path.rule=Path(`/alephzero-sepolia`) || Path(`/alephzero-sepolia/`)}
|
||||
- traefik.http.routers.alephzero-sepolia-nitro-pruned-pebble-path.middlewares=alephzero-sepolia-nitro-pruned-pebble-path-stripprefix, ipallowlist
|
||||
|
||||
volumes:
|
||||
alephzero-sepolia-nitro-pruned-pebble-path:
|
||||
|
||||
x-upstreams:
|
||||
- id: $${ID}
|
||||
labels:
|
||||
provider: $${PROVIDER}
|
||||
connection:
|
||||
generic:
|
||||
rpc:
|
||||
url: $${RPC_URL}
|
||||
ws:
|
||||
frameSize: 20Mb
|
||||
msgSize: 50Mb
|
||||
url: $${WS_URL}
|
||||
chain: alephzero-sepolia
|
||||
method-groups:
|
||||
enabled:
|
||||
- debug
|
||||
- filter
|
||||
methods:
|
||||
disabled:
|
||||
# not compatible with path state scheme
|
||||
- name: debug_traceBlockByHash
|
||||
enabled:
|
||||
- name: txpool_content # TODO: should be disabled for rollup nodes
|
||||
# standard geth only
|
||||
- name: debug_getRawBlock
|
||||
- name: debug_getRawTransaction
|
||||
- name: debug_getRawReceipts
|
||||
- name: debug_getRawHeader
|
||||
- name: debug_getBadBlocks
|
||||
# non standard geth only slightly dangerous
|
||||
- name: debug_intermediateRoots
|
||||
- name: debug_dumpBlock
|
||||
# standard geth and erigon
|
||||
- name: debug_accountRange
|
||||
- name: debug_getModifiedAccountsByNumber
|
||||
- name: debug_getModifiedAccountsByHash
|
||||
# non standard geth and erigon
|
||||
- name: eth_getRawTransactionByHash
|
||||
- name: eth_getRawTransactionByBlockHashAndIndex
|
||||
...
|
||||
136
arb/nitro/arbitrum-nova-nitro-archive-leveldb-hash.yml
Normal file
136
arb/nitro/arbitrum-nova-nitro-archive-leveldb-hash.yml
Normal file
@@ -0,0 +1,136 @@
|
||||
---
|
||||
x-logging-defaults: &logging-defaults
|
||||
driver: json-file
|
||||
options:
|
||||
max-size: "10m"
|
||||
max-file: "3"
|
||||
|
||||
# Usage:
|
||||
#
|
||||
# mkdir rpc && cd rpc
|
||||
#
|
||||
# git init
|
||||
# git remote add origin https://github.com/StakeSquid/ethereum-rpc-docker.git
|
||||
# git fetch origin vibe
|
||||
# git checkout origin/vibe
|
||||
#
|
||||
# docker run --rm alpine sh -c "printf '0x'; head -c32 /dev/urandom | xxd -p -c 64" > .jwtsecret
|
||||
#
|
||||
# env
|
||||
# ...
|
||||
# IP=$(curl ipinfo.io/ip)
|
||||
# DOMAIN=${IP}.traefik.me
|
||||
# COMPOSE_FILE=base.yml:rpc.yml:arb/nitro/arbitrum-nova-nitro-archive-leveldb-hash.yml
|
||||
#
|
||||
# docker compose up -d
|
||||
#
|
||||
# curl -X POST https://${IP}.traefik.me/arbitrum-nova-archive \
|
||||
# -H "Content-Type: application/json" \
|
||||
# --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'
|
||||
|
||||
services:
|
||||
arbitrum-nova-archive:
|
||||
image: ${ARBITRUM_NITRO_IMAGE:-offchainlabs/nitro-node}:${ARBITRUM_NOVA_NITRO_VERSION:-v3.6.4-28199cd}
|
||||
sysctls:
|
||||
# TCP Performance
|
||||
net.ipv4.tcp_slow_start_after_idle: 0 # Disable slow start after idle
|
||||
net.ipv4.tcp_no_metrics_save: 1 # Disable metrics cache
|
||||
net.ipv4.tcp_rmem: 4096 87380 16777216 # Increase TCP read buffers
|
||||
net.ipv4.tcp_wmem: 4096 87380 16777216 # Increase TCP write buffers
|
||||
net.core.somaxconn: 32768 # Higher connection queue
|
||||
# Memory/Connection Management
|
||||
# net.core.netdev_max_backlog: 50000 # Increase network buffer
|
||||
net.ipv4.tcp_max_syn_backlog: 30000 # More SYN requests
|
||||
net.ipv4.tcp_max_tw_buckets: 2000000 # Allow more TIME_WAIT sockets
|
||||
ulimits:
|
||||
nofile: 1048576 # Max open files (for RPC/WS connections)
|
||||
user: root
|
||||
expose:
|
||||
- 8545
|
||||
command:
|
||||
- --chain.id=42170
|
||||
- --execution.caching.archive=true
|
||||
- --execution.rpc.gas-cap=600000000
|
||||
- --execution.sequencer.enable=false
|
||||
- --http.addr=0.0.0.0
|
||||
- --http.api=eth,net,web3,arb,txpool,debug
|
||||
- --http.corsdomain=*
|
||||
- --http.port=8545
|
||||
- --http.vhosts=*
|
||||
- --init.download-path=/tmp
|
||||
- --init.latest=archive
|
||||
- --metrics
|
||||
- --metrics-server.addr=0.0.0.0
|
||||
- --metrics-server.port=6070
|
||||
- --node.batch-poster.enable=false
|
||||
- --node.sequencer=false
|
||||
- --node.staker.enable=false
|
||||
- --parent-chain.blob-client.beacon-url=${ETHEREUM_MAINNET_BEACON_REST}
|
||||
- --parent-chain.connection.url=${ETHEREUM_MAINNET_EXECUTION_RPC}
|
||||
- --persistent.chain=/root/.arbitrum/arbitrum-nova-archive
|
||||
- --ws.addr=0.0.0.0
|
||||
- --ws.origins=*
|
||||
- --ws.port=8545
|
||||
restart: unless-stopped
|
||||
stop_grace_period: 5m
|
||||
networks:
|
||||
- chains
|
||||
volumes:
|
||||
- ${ARBITRUM_NOVA_NITRO_ARCHIVE_LEVELDB_HASH_DATA:-arbitrum-nova-nitro-archive-leveldb-hash}:/root/.arbitrum
|
||||
- ./tmp/arbitrum-nova-archive:/tmp
|
||||
- /slowdisk:/slowdisk
|
||||
logging: *logging-defaults
|
||||
labels:
|
||||
- prometheus-scrape.enabled=true
|
||||
- prometheus-scrape.port=6070
|
||||
- prometheus-scrape.path=/debug/metrics/prometheus
|
||||
- traefik.enable=true
|
||||
- traefik.http.middlewares.arbitrum-nova-nitro-archive-leveldb-hash-stripprefix.stripprefix.prefixes=/arbitrum-nova-archive
|
||||
- traefik.http.services.arbitrum-nova-nitro-archive-leveldb-hash.loadbalancer.server.port=8545
|
||||
- ${NO_SSL:-traefik.http.routers.arbitrum-nova-nitro-archive-leveldb-hash.entrypoints=websecure}
|
||||
- ${NO_SSL:-traefik.http.routers.arbitrum-nova-nitro-archive-leveldb-hash.tls.certresolver=myresolver}
|
||||
- ${NO_SSL:-traefik.http.routers.arbitrum-nova-nitro-archive-leveldb-hash.rule=Host(`$DOMAIN`) && (Path(`/arbitrum-nova-archive`) || Path(`/arbitrum-nova-archive/`))}
|
||||
- ${NO_SSL:+traefik.http.routers.arbitrum-nova-nitro-archive-leveldb-hash.rule=Path(`/arbitrum-nova-archive`) || Path(`/arbitrum-nova-archive/`)}
|
||||
- traefik.http.routers.arbitrum-nova-nitro-archive-leveldb-hash.middlewares=arbitrum-nova-nitro-archive-leveldb-hash-stripprefix, ipallowlist
|
||||
|
||||
volumes:
|
||||
arbitrum-nova-nitro-archive-leveldb-hash:
|
||||
|
||||
x-upstreams:
|
||||
- id: $${ID}
|
||||
labels:
|
||||
provider: $${PROVIDER}
|
||||
connection:
|
||||
generic:
|
||||
rpc:
|
||||
url: $${RPC_URL}
|
||||
ws:
|
||||
frameSize: 20Mb
|
||||
msgSize: 50Mb
|
||||
url: $${WS_URL}
|
||||
chain: arbitrum-nova
|
||||
method-groups:
|
||||
enabled:
|
||||
- debug
|
||||
- filter
|
||||
methods:
|
||||
disabled:
|
||||
enabled:
|
||||
- name: txpool_content # TODO: should be disabled for rollup nodes
|
||||
# standard geth only
|
||||
- name: debug_getRawBlock
|
||||
- name: debug_getRawTransaction
|
||||
- name: debug_getRawReceipts
|
||||
- name: debug_getRawHeader
|
||||
- name: debug_getBadBlocks
|
||||
# non standard geth only slightly dangerous
|
||||
- name: debug_intermediateRoots
|
||||
- name: debug_dumpBlock
|
||||
# standard geth and erigon
|
||||
- name: debug_accountRange
|
||||
- name: debug_getModifiedAccountsByNumber
|
||||
- name: debug_getModifiedAccountsByHash
|
||||
# non standard geth and erigon
|
||||
- name: eth_getRawTransactionByHash
|
||||
- name: eth_getRawTransactionByBlockHashAndIndex
|
||||
...
|
||||
137
arb/nitro/arbitrum-nova-nitro-pruned-pebble-hash.yml
Normal file
137
arb/nitro/arbitrum-nova-nitro-pruned-pebble-hash.yml
Normal file
@@ -0,0 +1,137 @@
|
||||
---
|
||||
x-logging-defaults: &logging-defaults
|
||||
driver: json-file
|
||||
options:
|
||||
max-size: "10m"
|
||||
max-file: "3"
|
||||
|
||||
# Usage:
|
||||
#
|
||||
# mkdir rpc && cd rpc
|
||||
#
|
||||
# git init
|
||||
# git remote add origin https://github.com/StakeSquid/ethereum-rpc-docker.git
|
||||
# git fetch origin vibe
|
||||
# git checkout origin/vibe
|
||||
#
|
||||
# docker run --rm alpine sh -c "printf '0x'; head -c32 /dev/urandom | xxd -p -c 64" > .jwtsecret
|
||||
#
|
||||
# env
|
||||
# ...
|
||||
# IP=$(curl ipinfo.io/ip)
|
||||
# DOMAIN=${IP}.traefik.me
|
||||
# COMPOSE_FILE=base.yml:rpc.yml:arb/nitro/arbitrum-nova-nitro-pruned-pebble-hash.yml
|
||||
#
|
||||
# docker compose up -d
|
||||
#
|
||||
# curl -X POST https://${IP}.traefik.me/arbitrum-nova \
|
||||
# -H "Content-Type: application/json" \
|
||||
# --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'
|
||||
|
||||
services:
|
||||
arbitrum-nova:
|
||||
image: ${ARBITRUM_NITRO_IMAGE:-offchainlabs/nitro-node}:${ARBITRUM_NOVA_NITRO_VERSION:-v3.6.4-28199cd}
|
||||
sysctls:
|
||||
# TCP Performance
|
||||
net.ipv4.tcp_slow_start_after_idle: 0 # Disable slow start after idle
|
||||
net.ipv4.tcp_no_metrics_save: 1 # Disable metrics cache
|
||||
net.ipv4.tcp_rmem: 4096 87380 16777216 # Increase TCP read buffers
|
||||
net.ipv4.tcp_wmem: 4096 87380 16777216 # Increase TCP write buffers
|
||||
net.core.somaxconn: 32768 # Higher connection queue
|
||||
# Memory/Connection Management
|
||||
# net.core.netdev_max_backlog: 50000 # Increase network buffer
|
||||
net.ipv4.tcp_max_syn_backlog: 30000 # More SYN requests
|
||||
net.ipv4.tcp_max_tw_buckets: 2000000 # Allow more TIME_WAIT sockets
|
||||
ulimits:
|
||||
nofile: 1048576 # Max open files (for RPC/WS connections)
|
||||
user: root
|
||||
expose:
|
||||
- 8545
|
||||
command:
|
||||
- --chain.id=42170
|
||||
- --execution.caching.archive=false
|
||||
- --execution.rpc.gas-cap=600000000
|
||||
- --execution.sequencer.enable=false
|
||||
- --http.addr=0.0.0.0
|
||||
- --http.api=eth,net,web3,arb,txpool,debug
|
||||
- --http.corsdomain=*
|
||||
- --http.port=8545
|
||||
- --http.vhosts=*
|
||||
- --init.download-path=/tmp
|
||||
- --init.latest=pruned
|
||||
- --metrics
|
||||
- --metrics-server.addr=0.0.0.0
|
||||
- --metrics-server.port=6070
|
||||
- --node.batch-poster.enable=false
|
||||
- --node.sequencer=false
|
||||
- --node.staker.enable=false
|
||||
- --parent-chain.blob-client.beacon-url=${ETHEREUM_MAINNET_BEACON_REST}
|
||||
- --parent-chain.connection.url=${ETHEREUM_MAINNET_EXECUTION_RPC}
|
||||
- --persistent.chain=/root/.arbitrum/arbitrum-nova
|
||||
- --persistent.db-engine=pebble
|
||||
- --ws.addr=0.0.0.0
|
||||
- --ws.origins=*
|
||||
- --ws.port=8545
|
||||
restart: unless-stopped
|
||||
stop_grace_period: 5m
|
||||
networks:
|
||||
- chains
|
||||
volumes:
|
||||
- ${ARBITRUM_NOVA_NITRO_PRUNED_PEBBLE_HASH_DATA:-arbitrum-nova-nitro-pruned-pebble-hash}:/root/.arbitrum
|
||||
- ./tmp/arbitrum-nova:/tmp
|
||||
- /slowdisk:/slowdisk
|
||||
logging: *logging-defaults
|
||||
labels:
|
||||
- prometheus-scrape.enabled=true
|
||||
- prometheus-scrape.port=6070
|
||||
- prometheus-scrape.path=/debug/metrics/prometheus
|
||||
- traefik.enable=true
|
||||
- traefik.http.middlewares.arbitrum-nova-nitro-pruned-pebble-hash-stripprefix.stripprefix.prefixes=/arbitrum-nova
|
||||
- traefik.http.services.arbitrum-nova-nitro-pruned-pebble-hash.loadbalancer.server.port=8545
|
||||
- ${NO_SSL:-traefik.http.routers.arbitrum-nova-nitro-pruned-pebble-hash.entrypoints=websecure}
|
||||
- ${NO_SSL:-traefik.http.routers.arbitrum-nova-nitro-pruned-pebble-hash.tls.certresolver=myresolver}
|
||||
- ${NO_SSL:-traefik.http.routers.arbitrum-nova-nitro-pruned-pebble-hash.rule=Host(`$DOMAIN`) && (Path(`/arbitrum-nova`) || Path(`/arbitrum-nova/`))}
|
||||
- ${NO_SSL:+traefik.http.routers.arbitrum-nova-nitro-pruned-pebble-hash.rule=Path(`/arbitrum-nova`) || Path(`/arbitrum-nova/`)}
|
||||
- traefik.http.routers.arbitrum-nova-nitro-pruned-pebble-hash.middlewares=arbitrum-nova-nitro-pruned-pebble-hash-stripprefix, ipallowlist
|
||||
|
||||
volumes:
|
||||
arbitrum-nova-nitro-pruned-pebble-hash:
|
||||
|
||||
x-upstreams:
|
||||
- id: $${ID}
|
||||
labels:
|
||||
provider: $${PROVIDER}
|
||||
connection:
|
||||
generic:
|
||||
rpc:
|
||||
url: $${RPC_URL}
|
||||
ws:
|
||||
frameSize: 20Mb
|
||||
msgSize: 50Mb
|
||||
url: $${WS_URL}
|
||||
chain: arbitrum-nova
|
||||
method-groups:
|
||||
enabled:
|
||||
- debug
|
||||
- filter
|
||||
methods:
|
||||
disabled:
|
||||
enabled:
|
||||
- name: txpool_content # TODO: should be disabled for rollup nodes
|
||||
# standard geth only
|
||||
- name: debug_getRawBlock
|
||||
- name: debug_getRawTransaction
|
||||
- name: debug_getRawReceipts
|
||||
- name: debug_getRawHeader
|
||||
- name: debug_getBadBlocks
|
||||
# non standard geth only slightly dangerous
|
||||
- name: debug_intermediateRoots
|
||||
- name: debug_dumpBlock
|
||||
# standard geth and erigon
|
||||
- name: debug_accountRange
|
||||
- name: debug_getModifiedAccountsByNumber
|
||||
- name: debug_getModifiedAccountsByHash
|
||||
# non standard geth and erigon
|
||||
- name: eth_getRawTransactionByHash
|
||||
- name: eth_getRawTransactionByBlockHashAndIndex
|
||||
...
|
||||
142
arb/nitro/arbitrum-one-nitro-archive-leveldb-hash--benchmark.yml
Normal file
142
arb/nitro/arbitrum-one-nitro-archive-leveldb-hash--benchmark.yml
Normal file
@@ -0,0 +1,142 @@
|
||||
---
|
||||
|
||||
# Usage:
|
||||
#
|
||||
# mkdir rpc && cd rpc
|
||||
#
|
||||
# git init
|
||||
# git remote add origin https://github.com/StakeSquid/ethereum-rpc-docker.git
|
||||
# git fetch origin vibe
|
||||
# git checkout origin/vibe
|
||||
#
|
||||
# docker run --rm alpine sh -c "printf '0x'; head -c32 /dev/urandom | xxd -p -c 64" > .jwtsecret
|
||||
#
|
||||
# env
|
||||
# ...
|
||||
# IP=$(curl ipinfo.io/ip)
|
||||
# DOMAIN=${IP}.traefik.me
|
||||
# COMPOSE_FILE=base.yml:rpc.yml:arb/nitro/arbitrum-one-nitro-archive-leveldb-hash--benchmark.yml
|
||||
#
|
||||
# docker compose up -d
|
||||
#
|
||||
# curl -X POST https://${IP}.traefik.me/arbitrum-one-archive \
|
||||
# -H "Content-Type: application/json" \
|
||||
# --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'
|
||||
|
||||
services:
|
||||
arbitrum-one-archive:
|
||||
image: ${ARBITRUM_NITRO_IMAGE:-offchainlabs/nitro-node}:${ARBITRUM_ONE_NITRO_VERSION:-v3.5.5-90ee45c}
|
||||
sysctls:
|
||||
# TCP Performance
|
||||
net.ipv4.tcp_slow_start_after_idle: 0 # Disable slow start after idle
|
||||
net.ipv4.tcp_no_metrics_save: 1 # Disable metrics cache
|
||||
net.ipv4.tcp_rmem: 4096 87380 16777216 # Increase TCP read buffers
|
||||
net.ipv4.tcp_wmem: 4096 87380 16777216 # Increase TCP write buffers
|
||||
net.core.somaxconn: 32768 # Higher connection queue
|
||||
# Memory/Connection Management
|
||||
# net.core.netdev_max_backlog: 50000 # Increase network buffer
|
||||
net.ipv4.tcp_max_syn_backlog: 30000 # More SYN requests
|
||||
net.ipv4.tcp_max_tw_buckets: 2000000 # Allow more TIME_WAIT sockets
|
||||
ulimits:
|
||||
nofile: 1048576 # Max open files (for RPC/WS connections)
|
||||
user: root
|
||||
expose:
|
||||
- 8545
|
||||
command:
|
||||
- --chain.id=42161
|
||||
- --execution.caching.archive=true
|
||||
- --execution.caching.state-scheme=hash
|
||||
- --execution.rpc.gas-cap=600000000
|
||||
- --execution.sequencer.enable=false
|
||||
- --http.addr=0.0.0.0
|
||||
- --http.api=eth,net,web3,arb,txpool,debug
|
||||
- --http.corsdomain=*
|
||||
- --http.port=8545
|
||||
- --http.vhosts=*
|
||||
- --init.latest=archive
|
||||
- --node.batch-poster.enable=false
|
||||
- --node.sequencer=false
|
||||
- --node.staker.enable=false
|
||||
- --parent-chain.blob-client.beacon-url=${ETHEREUM_MAINNET_BEACON_REST}
|
||||
- --parent-chain.connection.url=${ETHEREUM_MAINNET_EXECUTION_RPC}
|
||||
- --persistent.chain=/root/.arbitrum/arbitrum-one-archive
|
||||
- --persistent.db-engine=leveldb
|
||||
- --ws.addr=0.0.0.0
|
||||
- --ws.origins=*
|
||||
- --ws.port=8545
|
||||
restart: unless-stopped
|
||||
stop_grace_period: 5m
|
||||
networks:
|
||||
- chains
|
||||
volumes:
|
||||
- ${ARBITRUM_ONE_NITRO_ARCHIVE_LEVELDB_HASH_DATA:-arbitrum-one-nitro-archive-leveldb-hash}:/root/.arbitrum
|
||||
- ./tmp/arbitrum-one-archive:/tmp
|
||||
- /slowdisk:/slowdisk
|
||||
|
||||
arbitrum-one-archive-benchmark:
|
||||
build:
|
||||
context: ./benchmark-proxy
|
||||
dockerfile: Dockerfile
|
||||
expose:
|
||||
- '8545'
|
||||
environment:
|
||||
- ENABLE_DETAILED_LOGS=${BENCHMARK_PROXY_VERBOSE:-false}
|
||||
- LISTEN_ADDR=:8545
|
||||
- PRIMARY_BACKEND=http://arbitrum-one-archive:8545
|
||||
- SUMMARY_INTERVAL=60
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
- arbitrum-one-archive
|
||||
networks:
|
||||
- chains
|
||||
labels:
|
||||
- traefik.enable=true
|
||||
- traefik.http.middlewares.arbitrum-one-nitro-archive-leveldb-hash-stripprefix.stripprefix.prefixes=/arbitrum-one-archive
|
||||
- traefik.http.services.arbitrum-one-nitro-archive-leveldb-hash.loadbalancer.server.port=8545
|
||||
- ${NO_SSL:-traefik.http.routers.arbitrum-one-nitro-archive-leveldb-hash.entrypoints=websecure}
|
||||
- ${NO_SSL:-traefik.http.routers.arbitrum-one-nitro-archive-leveldb-hash.tls.certresolver=myresolver}
|
||||
- ${NO_SSL:-traefik.http.routers.arbitrum-one-nitro-archive-leveldb-hash.rule=Host(`$DOMAIN`) && (Path(`/arbitrum-one-archive`) || Path(`/arbitrum-one-archive/`))}
|
||||
- ${NO_SSL:+traefik.http.routers.arbitrum-one-nitro-archive-leveldb-hash.rule=Path(`/arbitrum-one-archive`) || Path(`/arbitrum-one-archive/`)}
|
||||
- traefik.http.routers.arbitrum-one-nitro-archive-leveldb-hash.middlewares=arbitrum-one-nitro-archive-leveldb-hash-stripprefix, ipallowlist
|
||||
|
||||
volumes:
|
||||
arbitrum-one-nitro-archive-leveldb-hash:
|
||||
|
||||
x-upstreams:
|
||||
- id: $${ID}
|
||||
labels:
|
||||
provider: $${PROVIDER}
|
||||
connection:
|
||||
generic:
|
||||
rpc:
|
||||
url: $${RPC_URL}
|
||||
ws:
|
||||
frameSize: 20Mb
|
||||
msgSize: 50Mb
|
||||
url: $${WS_URL}
|
||||
chain: arbitrum
|
||||
method-groups:
|
||||
enabled:
|
||||
- debug
|
||||
- filter
|
||||
methods:
|
||||
disabled:
|
||||
enabled:
|
||||
- name: txpool_content # TODO: should be disabled for rollup nodes
|
||||
# standard geth only
|
||||
- name: debug_getRawBlock
|
||||
- name: debug_getRawTransaction
|
||||
- name: debug_getRawReceipts
|
||||
- name: debug_getRawHeader
|
||||
- name: debug_getBadBlocks
|
||||
# non standard geth only slightly dangerous
|
||||
- name: debug_intermediateRoots
|
||||
- name: debug_dumpBlock
|
||||
# standard geth and erigon
|
||||
- name: debug_accountRange
|
||||
- name: debug_getModifiedAccountsByNumber
|
||||
- name: debug_getModifiedAccountsByHash
|
||||
# non standard geth and erigon
|
||||
- name: eth_getRawTransactionByHash
|
||||
- name: eth_getRawTransactionByBlockHashAndIndex
|
||||
...
|
||||
207
arb/nitro/arbitrum-one-nitro-archive-leveldb-hash.yml
Normal file
207
arb/nitro/arbitrum-one-nitro-archive-leveldb-hash.yml
Normal file
@@ -0,0 +1,207 @@
|
||||
---
|
||||
x-logging-defaults: &logging-defaults
|
||||
driver: json-file
|
||||
options:
|
||||
max-size: "10m"
|
||||
max-file: "3"
|
||||
|
||||
# Usage:
|
||||
#
|
||||
# mkdir rpc && cd rpc
|
||||
#
|
||||
# git init
|
||||
# git remote add origin https://github.com/StakeSquid/ethereum-rpc-docker.git
|
||||
# git fetch origin vibe
|
||||
# git checkout origin/vibe
|
||||
#
|
||||
# docker run --rm alpine sh -c "printf '0x'; head -c32 /dev/urandom | xxd -p -c 64" > .jwtsecret
|
||||
#
|
||||
# env
|
||||
# ...
|
||||
# IP=$(curl ipinfo.io/ip)
|
||||
# DOMAIN=${IP}.traefik.me
|
||||
# COMPOSE_FILE=base.yml:rpc.yml:arb/nitro/arbitrum-one-nitro-archive-leveldb-hash.yml
|
||||
#
|
||||
# docker compose up -d
|
||||
#
|
||||
# curl -X POST https://${IP}.traefik.me/arbitrum-one-archive \
|
||||
# -H "Content-Type: application/json" \
|
||||
# --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'
|
||||
|
||||
services:
|
||||
arbitrum-one-archive:
|
||||
image: ${ARBITRUM_NITRO_IMAGE:-offchainlabs/nitro-node}:${ARBITRUM_ONE_NITRO_VERSION:-v3.6.4-28199cd}
|
||||
sysctls:
|
||||
# TCP Performance
|
||||
net.ipv4.tcp_slow_start_after_idle: 0 # Disable slow start after idle
|
||||
net.ipv4.tcp_no_metrics_save: 1 # Disable metrics cache
|
||||
net.ipv4.tcp_rmem: 4096 87380 16777216 # Increase TCP read buffers
|
||||
net.ipv4.tcp_wmem: 4096 87380 16777216 # Increase TCP write buffers
|
||||
net.core.somaxconn: 32768 # Higher connection queue
|
||||
# Memory/Connection Management
|
||||
# net.core.netdev_max_backlog: 50000 # Increase network buffer
|
||||
net.ipv4.tcp_max_syn_backlog: 30000 # More SYN requests
|
||||
net.ipv4.tcp_max_tw_buckets: 2000000 # Allow more TIME_WAIT sockets
|
||||
ulimits:
|
||||
nofile: 1048576 # Max open files (for RPC/WS connections)
|
||||
user: root
|
||||
expose:
|
||||
- 8545
|
||||
command:
|
||||
- --chain.id=42161
|
||||
- --execution.caching.archive=true
|
||||
- --execution.rpc.classic-redirect=http://arbitrum-one-arbnode-archive:8545
|
||||
- --execution.rpc.gas-cap=600000000
|
||||
- --execution.sequencer.enable=false
|
||||
- --http.addr=0.0.0.0
|
||||
- --http.api=eth,net,web3,arb,txpool,debug
|
||||
- --http.corsdomain=*
|
||||
- --http.port=8545
|
||||
- --http.vhosts=*
|
||||
- --init.download-path=/tmp
|
||||
- --init.latest=archive
|
||||
- --metrics
|
||||
- --metrics-server.addr=0.0.0.0
|
||||
- --metrics-server.port=6070
|
||||
- --node.batch-poster.enable=false
|
||||
- --node.sequencer=false
|
||||
- --node.staker.enable=false
|
||||
- --parent-chain.blob-client.beacon-url=${ETHEREUM_MAINNET_BEACON_REST}
|
||||
- --parent-chain.connection.url=${ETHEREUM_MAINNET_EXECUTION_RPC}
|
||||
- --persistent.chain=/root/.arbitrum/arbitrum-one-archive
|
||||
- --ws.addr=0.0.0.0
|
||||
- --ws.origins=*
|
||||
- --ws.port=8545
|
||||
restart: unless-stopped
|
||||
stop_grace_period: 5m
|
||||
networks:
|
||||
- chains
|
||||
volumes:
|
||||
- ${ARBITRUM_ONE_NITRO_ARCHIVE_LEVELDB_HASH_DATA:-arbitrum-one-nitro-archive-leveldb-hash}:/root/.arbitrum
|
||||
- ./tmp/arbitrum-one-archive:/tmp
|
||||
- /slowdisk:/slowdisk
|
||||
logging: *logging-defaults
|
||||
labels:
|
||||
- prometheus-scrape.enabled=true
|
||||
- prometheus-scrape.port=6070
|
||||
- prometheus-scrape.path=/debug/metrics/prometheus
|
||||
- traefik.enable=true
|
||||
- traefik.http.middlewares.arbitrum-one-nitro-archive-leveldb-hash-stripprefix.stripprefix.prefixes=/arbitrum-one-archive
|
||||
- traefik.http.services.arbitrum-one-nitro-archive-leveldb-hash.loadbalancer.server.port=8545
|
||||
- ${NO_SSL:-traefik.http.routers.arbitrum-one-nitro-archive-leveldb-hash.entrypoints=websecure}
|
||||
- ${NO_SSL:-traefik.http.routers.arbitrum-one-nitro-archive-leveldb-hash.tls.certresolver=myresolver}
|
||||
- ${NO_SSL:-traefik.http.routers.arbitrum-one-nitro-archive-leveldb-hash.rule=Host(`$DOMAIN`) && (Path(`/arbitrum-one-archive`) || Path(`/arbitrum-one-archive/`))}
|
||||
- ${NO_SSL:+traefik.http.routers.arbitrum-one-nitro-archive-leveldb-hash.rule=Path(`/arbitrum-one-archive`) || Path(`/arbitrum-one-archive/`)}
|
||||
- traefik.http.routers.arbitrum-one-nitro-archive-leveldb-hash.middlewares=arbitrum-one-nitro-archive-leveldb-hash-stripprefix, ipallowlist
|
||||
|
||||
arbitrum-one-arbnode-archive:
|
||||
image: ${ARBITRUM_ARBNODE_IMAGE:-offchainlabs/arb-node}:${ARBITRUM_ONE_ARBNODE_VERSION:-v1.4.5-e97c1a4}
|
||||
sysctls:
|
||||
# TCP Performance
|
||||
net.ipv4.tcp_slow_start_after_idle: 0 # Disable slow start after idle
|
||||
net.ipv4.tcp_no_metrics_save: 1 # Disable metrics cache
|
||||
net.ipv4.tcp_rmem: 4096 87380 16777216 # Increase TCP read buffers
|
||||
net.ipv4.tcp_wmem: 4096 87380 16777216 # Increase TCP write buffers
|
||||
net.core.somaxconn: 32768 # Higher connection queue
|
||||
# Memory/Connection Management
|
||||
# net.core.netdev_max_backlog: 50000 # Increase network buffer
|
||||
net.ipv4.tcp_max_syn_backlog: 30000 # More SYN requests
|
||||
net.ipv4.tcp_max_tw_buckets: 2000000 # Allow more TIME_WAIT sockets
|
||||
ulimits:
|
||||
nofile: 1048576 # Max open files (for RPC/WS connections)
|
||||
user: root
|
||||
expose:
|
||||
- 8545
|
||||
- 8546
|
||||
entrypoint: [/home/user/go/bin/arb-node]
|
||||
command:
|
||||
- --core.checkpoint-gas-frequency=156250000
|
||||
- --l1.url=${ETHEREUM_MAINNET_EXECUTION_RPC}
|
||||
- --l2.disable-upstream
|
||||
- --metrics
|
||||
- --metrics-server.addr=0.0.0.0
|
||||
- --metrics-server.port=7070
|
||||
- --node.cache.allow-slow-lookup
|
||||
- --node.chain-id=42161
|
||||
- --node.rpc.addr=0.0.0.0
|
||||
- --node.rpc.enable-l1-calls
|
||||
- --node.rpc.port=8545
|
||||
- --node.rpc.tracing.enable
|
||||
- --node.rpc.tracing.namespace=trace
|
||||
- --node.ws.addr=0.0.0.0
|
||||
- --node.ws.port=8546
|
||||
- --persistent.chain=/data/datadir/
|
||||
- --persistent.global-config=/data/
|
||||
restart: unless-stopped
|
||||
stop_grace_period: 5m
|
||||
networks:
|
||||
- chains
|
||||
volumes:
|
||||
- ${ARBITRUM_ONE_ARBNODE_ARCHIVE_LEVELDB_HASH_DATA:-arbitrum-one-arbnode-archive-leveldb-hash}:/data
|
||||
- /slowdisk:/slowdisk
|
||||
logging: *logging-defaults
|
||||
labels:
|
||||
- prometheus-scrape.enabled=false
|
||||
|
||||
volumes:
|
||||
arbitrum-one-arbnode-archive-leveldb-hash:
|
||||
arbitrum-one-nitro-archive-leveldb-hash:
|
||||
|
||||
x-upstreams:
|
||||
- id: $${ID}
|
||||
labels:
|
||||
provider: $${PROVIDER}
|
||||
connection:
|
||||
generic:
|
||||
rpc:
|
||||
url: $${RPC_URL}
|
||||
ws:
|
||||
frameSize: 20Mb
|
||||
msgSize: 50Mb
|
||||
url: $${WS_URL}
|
||||
chain: arbitrum
|
||||
method-groups:
|
||||
enabled:
|
||||
- debug
|
||||
- filter
|
||||
methods:
|
||||
disabled:
|
||||
enabled:
|
||||
- name: txpool_content # TODO: should be disabled for rollup nodes
|
||||
# standard geth only
|
||||
- name: debug_getRawBlock
|
||||
- name: debug_getRawTransaction
|
||||
- name: debug_getRawReceipts
|
||||
- name: debug_getRawHeader
|
||||
- name: debug_getBadBlocks
|
||||
# non standard geth only slightly dangerous
|
||||
- name: debug_intermediateRoots
|
||||
- name: debug_dumpBlock
|
||||
# standard geth and erigon
|
||||
- name: debug_accountRange
|
||||
- name: debug_getModifiedAccountsByNumber
|
||||
- name: debug_getModifiedAccountsByHash
|
||||
# non standard geth and erigon
|
||||
- name: eth_getRawTransactionByHash
|
||||
- name: eth_getRawTransactionByBlockHashAndIndex
|
||||
- id: $${ID}
|
||||
labels:
|
||||
provider: $${PROVIDER}
|
||||
connection:
|
||||
generic:
|
||||
rpc:
|
||||
url: $${RPC_URL}
|
||||
ws:
|
||||
frameSize: 20Mb
|
||||
msgSize: 50Mb
|
||||
url: $${WS_URL}
|
||||
chain: arbitrum
|
||||
method-groups:
|
||||
enabled:
|
||||
- debug
|
||||
- filter
|
||||
methods:
|
||||
disabled:
|
||||
enabled:
|
||||
- name: txpool_content # TODO: should be disabled for rollup nodes
|
||||
...
|
||||
208
arb/nitro/arbitrum-one-nitro-archive-pebble-hash.yml
Normal file
208
arb/nitro/arbitrum-one-nitro-archive-pebble-hash.yml
Normal file
@@ -0,0 +1,208 @@
|
||||
---
|
||||
x-logging-defaults: &logging-defaults
|
||||
driver: json-file
|
||||
options:
|
||||
max-size: "10m"
|
||||
max-file: "3"
|
||||
|
||||
# Usage:
|
||||
#
|
||||
# mkdir rpc && cd rpc
|
||||
#
|
||||
# git init
|
||||
# git remote add origin https://github.com/StakeSquid/ethereum-rpc-docker.git
|
||||
# git fetch origin vibe
|
||||
# git checkout origin/vibe
|
||||
#
|
||||
# docker run --rm alpine sh -c "printf '0x'; head -c32 /dev/urandom | xxd -p -c 64" > .jwtsecret
|
||||
#
|
||||
# env
|
||||
# ...
|
||||
# IP=$(curl ipinfo.io/ip)
|
||||
# DOMAIN=${IP}.traefik.me
|
||||
# COMPOSE_FILE=base.yml:rpc.yml:arb/nitro/arbitrum-one-nitro-archive-pebble-hash.yml
|
||||
#
|
||||
# docker compose up -d
|
||||
#
|
||||
# curl -X POST https://${IP}.traefik.me/arbitrum-one-archive \
|
||||
# -H "Content-Type: application/json" \
|
||||
# --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'
|
||||
|
||||
services:
|
||||
arbitrum-one-archive:
|
||||
image: ${ARBITRUM_NITRO_IMAGE:-offchainlabs/nitro-node}:${ARBITRUM_ONE_NITRO_VERSION:-v3.6.4-28199cd}
|
||||
sysctls:
|
||||
# TCP Performance
|
||||
net.ipv4.tcp_slow_start_after_idle: 0 # Disable slow start after idle
|
||||
net.ipv4.tcp_no_metrics_save: 1 # Disable metrics cache
|
||||
net.ipv4.tcp_rmem: 4096 87380 16777216 # Increase TCP read buffers
|
||||
net.ipv4.tcp_wmem: 4096 87380 16777216 # Increase TCP write buffers
|
||||
net.core.somaxconn: 32768 # Higher connection queue
|
||||
# Memory/Connection Management
|
||||
# net.core.netdev_max_backlog: 50000 # Increase network buffer
|
||||
net.ipv4.tcp_max_syn_backlog: 30000 # More SYN requests
|
||||
net.ipv4.tcp_max_tw_buckets: 2000000 # Allow more TIME_WAIT sockets
|
||||
ulimits:
|
||||
nofile: 1048576 # Max open files (for RPC/WS connections)
|
||||
user: root
|
||||
expose:
|
||||
- 8545
|
||||
command:
|
||||
- --chain.id=42161
|
||||
- --execution.caching.archive=true
|
||||
- --execution.rpc.classic-redirect=http://arbitrum-one-arbnode-archive:8545
|
||||
- --execution.rpc.gas-cap=600000000
|
||||
- --execution.sequencer.enable=false
|
||||
- --http.addr=0.0.0.0
|
||||
- --http.api=eth,net,web3,arb,txpool,debug
|
||||
- --http.corsdomain=*
|
||||
- --http.port=8545
|
||||
- --http.vhosts=*
|
||||
- --init.download-path=/tmp
|
||||
- --init.latest=archive
|
||||
- --metrics
|
||||
- --metrics-server.addr=0.0.0.0
|
||||
- --metrics-server.port=6070
|
||||
- --node.batch-poster.enable=false
|
||||
- --node.sequencer=false
|
||||
- --node.staker.enable=false
|
||||
- --parent-chain.blob-client.beacon-url=${ETHEREUM_MAINNET_BEACON_REST}
|
||||
- --parent-chain.connection.url=${ETHEREUM_MAINNET_EXECUTION_RPC}
|
||||
- --persistent.chain=/root/.arbitrum/arbitrum-one-archive
|
||||
- --persistent.db-engine=pebble
|
||||
- --ws.addr=0.0.0.0
|
||||
- --ws.origins=*
|
||||
- --ws.port=8545
|
||||
restart: unless-stopped
|
||||
stop_grace_period: 5m
|
||||
networks:
|
||||
- chains
|
||||
volumes:
|
||||
- ${ARBITRUM_ONE_NITRO_ARCHIVE_PEBBLE_HASH_DATA:-arbitrum-one-nitro-archive-pebble-hash}:/root/.arbitrum
|
||||
- ./tmp/arbitrum-one-archive:/tmp
|
||||
- /slowdisk:/slowdisk
|
||||
logging: *logging-defaults
|
||||
labels:
|
||||
- prometheus-scrape.enabled=true
|
||||
- prometheus-scrape.port=6070
|
||||
- prometheus-scrape.path=/debug/metrics/prometheus
|
||||
- traefik.enable=true
|
||||
- traefik.http.middlewares.arbitrum-one-nitro-archive-pebble-hash-stripprefix.stripprefix.prefixes=/arbitrum-one-archive
|
||||
- traefik.http.services.arbitrum-one-nitro-archive-pebble-hash.loadbalancer.server.port=8545
|
||||
- ${NO_SSL:-traefik.http.routers.arbitrum-one-nitro-archive-pebble-hash.entrypoints=websecure}
|
||||
- ${NO_SSL:-traefik.http.routers.arbitrum-one-nitro-archive-pebble-hash.tls.certresolver=myresolver}
|
||||
- ${NO_SSL:-traefik.http.routers.arbitrum-one-nitro-archive-pebble-hash.rule=Host(`$DOMAIN`) && (Path(`/arbitrum-one-archive`) || Path(`/arbitrum-one-archive/`))}
|
||||
- ${NO_SSL:+traefik.http.routers.arbitrum-one-nitro-archive-pebble-hash.rule=Path(`/arbitrum-one-archive`) || Path(`/arbitrum-one-archive/`)}
|
||||
- traefik.http.routers.arbitrum-one-nitro-archive-pebble-hash.middlewares=arbitrum-one-nitro-archive-pebble-hash-stripprefix, ipallowlist
|
||||
|
||||
arbitrum-one-arbnode-archive:
|
||||
image: ${ARBITRUM_ARBNODE_IMAGE:-offchainlabs/arb-node}:${ARBITRUM_ONE_ARBNODE_VERSION:-v1.4.5-e97c1a4}
|
||||
sysctls:
|
||||
# TCP Performance
|
||||
net.ipv4.tcp_slow_start_after_idle: 0 # Disable slow start after idle
|
||||
net.ipv4.tcp_no_metrics_save: 1 # Disable metrics cache
|
||||
net.ipv4.tcp_rmem: 4096 87380 16777216 # Increase TCP read buffers
|
||||
net.ipv4.tcp_wmem: 4096 87380 16777216 # Increase TCP write buffers
|
||||
net.core.somaxconn: 32768 # Higher connection queue
|
||||
# Memory/Connection Management
|
||||
# net.core.netdev_max_backlog: 50000 # Increase network buffer
|
||||
net.ipv4.tcp_max_syn_backlog: 30000 # More SYN requests
|
||||
net.ipv4.tcp_max_tw_buckets: 2000000 # Allow more TIME_WAIT sockets
|
||||
ulimits:
|
||||
nofile: 1048576 # Max open files (for RPC/WS connections)
|
||||
user: root
|
||||
expose:
|
||||
- 8545
|
||||
- 8546
|
||||
entrypoint: [/home/user/go/bin/arb-node]
|
||||
command:
|
||||
- --core.checkpoint-gas-frequency=156250000
|
||||
- --l1.url=${ETHEREUM_MAINNET_EXECUTION_RPC}
|
||||
- --l2.disable-upstream
|
||||
- --metrics
|
||||
- --metrics-server.addr=0.0.0.0
|
||||
- --metrics-server.port=7070
|
||||
- --node.cache.allow-slow-lookup
|
||||
- --node.chain-id=42161
|
||||
- --node.rpc.addr=0.0.0.0
|
||||
- --node.rpc.enable-l1-calls
|
||||
- --node.rpc.port=8545
|
||||
- --node.rpc.tracing.enable
|
||||
- --node.rpc.tracing.namespace=trace
|
||||
- --node.ws.addr=0.0.0.0
|
||||
- --node.ws.port=8546
|
||||
- --persistent.chain=/data/datadir/
|
||||
- --persistent.global-config=/data/
|
||||
restart: unless-stopped
|
||||
stop_grace_period: 5m
|
||||
networks:
|
||||
- chains
|
||||
volumes:
|
||||
- ${ARBITRUM_ONE_ARBNODE_ARCHIVE_LEVELDB_HASH_DATA:-arbitrum-one-arbnode-archive-leveldb-hash}:/data
|
||||
- /slowdisk:/slowdisk
|
||||
logging: *logging-defaults
|
||||
labels:
|
||||
- prometheus-scrape.enabled=false
|
||||
|
||||
volumes:
|
||||
arbitrum-one-arbnode-archive-leveldb-hash:
|
||||
arbitrum-one-nitro-archive-pebble-hash:
|
||||
|
||||
x-upstreams:
|
||||
- id: $${ID}
|
||||
labels:
|
||||
provider: $${PROVIDER}
|
||||
connection:
|
||||
generic:
|
||||
rpc:
|
||||
url: $${RPC_URL}
|
||||
ws:
|
||||
frameSize: 20Mb
|
||||
msgSize: 50Mb
|
||||
url: $${WS_URL}
|
||||
chain: arbitrum
|
||||
method-groups:
|
||||
enabled:
|
||||
- debug
|
||||
- filter
|
||||
methods:
|
||||
disabled:
|
||||
enabled:
|
||||
- name: txpool_content # TODO: should be disabled for rollup nodes
|
||||
# standard geth only
|
||||
- name: debug_getRawBlock
|
||||
- name: debug_getRawTransaction
|
||||
- name: debug_getRawReceipts
|
||||
- name: debug_getRawHeader
|
||||
- name: debug_getBadBlocks
|
||||
# non standard geth only slightly dangerous
|
||||
- name: debug_intermediateRoots
|
||||
- name: debug_dumpBlock
|
||||
# standard geth and erigon
|
||||
- name: debug_accountRange
|
||||
- name: debug_getModifiedAccountsByNumber
|
||||
- name: debug_getModifiedAccountsByHash
|
||||
# non standard geth and erigon
|
||||
- name: eth_getRawTransactionByHash
|
||||
- name: eth_getRawTransactionByBlockHashAndIndex
|
||||
- id: $${ID}
|
||||
labels:
|
||||
provider: $${PROVIDER}
|
||||
connection:
|
||||
generic:
|
||||
rpc:
|
||||
url: $${RPC_URL}
|
||||
ws:
|
||||
frameSize: 20Mb
|
||||
msgSize: 50Mb
|
||||
url: $${WS_URL}
|
||||
chain: arbitrum
|
||||
method-groups:
|
||||
enabled:
|
||||
- debug
|
||||
- filter
|
||||
methods:
|
||||
disabled:
|
||||
enabled:
|
||||
- name: txpool_content # TODO: should be disabled for rollup nodes
|
||||
...
|
||||
157
arb/nitro/arbitrum-one-nitro-pruned-pebble-hash--benchmark.yml
Normal file
157
arb/nitro/arbitrum-one-nitro-pruned-pebble-hash--benchmark.yml
Normal file
@@ -0,0 +1,157 @@
|
||||
---
|
||||
x-logging-defaults: &logging-defaults
|
||||
driver: json-file
|
||||
options:
|
||||
max-size: "10m"
|
||||
max-file: "3"
|
||||
|
||||
# Usage:
|
||||
#
|
||||
# mkdir rpc && cd rpc
|
||||
#
|
||||
# git init
|
||||
# git remote add origin https://github.com/StakeSquid/ethereum-rpc-docker.git
|
||||
# git fetch origin vibe
|
||||
# git checkout origin/vibe
|
||||
#
|
||||
# docker run --rm alpine sh -c "printf '0x'; head -c32 /dev/urandom | xxd -p -c 64" > .jwtsecret
|
||||
#
|
||||
# env
|
||||
# ...
|
||||
# IP=$(curl ipinfo.io/ip)
|
||||
# DOMAIN=${IP}.traefik.me
|
||||
# COMPOSE_FILE=base.yml:rpc.yml:arb/nitro/arbitrum-one-nitro-pruned-pebble-hash--benchmark.yml
|
||||
#
|
||||
# docker compose up -d
|
||||
#
|
||||
# curl -X POST https://${IP}.traefik.me/arbitrum-one \
|
||||
# -H "Content-Type: application/json" \
|
||||
# --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'
|
||||
|
||||
services:
|
||||
arbitrum-one:
|
||||
image: ${ARBITRUM_NITRO_IMAGE:-offchainlabs/nitro-node}:${ARBITRUM_ONE_NITRO_VERSION:-v3.6.4-28199cd}
|
||||
sysctls:
|
||||
# TCP Performance
|
||||
net.ipv4.tcp_slow_start_after_idle: 0 # Disable slow start after idle
|
||||
net.ipv4.tcp_no_metrics_save: 1 # Disable metrics cache
|
||||
net.ipv4.tcp_rmem: 4096 87380 16777216 # Increase TCP read buffers
|
||||
net.ipv4.tcp_wmem: 4096 87380 16777216 # Increase TCP write buffers
|
||||
net.core.somaxconn: 32768 # Higher connection queue
|
||||
# Memory/Connection Management
|
||||
# net.core.netdev_max_backlog: 50000 # Increase network buffer
|
||||
net.ipv4.tcp_max_syn_backlog: 30000 # More SYN requests
|
||||
net.ipv4.tcp_max_tw_buckets: 2000000 # Allow more TIME_WAIT sockets
|
||||
ulimits:
|
||||
nofile: 1048576 # Max open files (for RPC/WS connections)
|
||||
user: root
|
||||
expose:
|
||||
- 8545
|
||||
command:
|
||||
- --chain.id=42161
|
||||
- --execution.caching.archive=false
|
||||
- --execution.rpc.gas-cap=600000000
|
||||
- --execution.sequencer.enable=false
|
||||
- --http.addr=0.0.0.0
|
||||
- --http.api=eth,net,web3,arb,txpool,debug
|
||||
- --http.corsdomain=*
|
||||
- --http.port=8545
|
||||
- --http.vhosts=*
|
||||
- --init.download-path=/tmp
|
||||
- --init.latest=pruned
|
||||
- --metrics
|
||||
- --metrics-server.addr=0.0.0.0
|
||||
- --metrics-server.port=6070
|
||||
- --node.batch-poster.enable=false
|
||||
- --node.sequencer=false
|
||||
- --node.staker.enable=false
|
||||
- --parent-chain.blob-client.beacon-url=${ETHEREUM_MAINNET_BEACON_REST}
|
||||
- --parent-chain.connection.url=${ETHEREUM_MAINNET_EXECUTION_RPC}
|
||||
- --persistent.chain=/root/.arbitrum/arbitrum-one
|
||||
- --persistent.db-engine=pebble
|
||||
- --ws.addr=0.0.0.0
|
||||
- --ws.origins=*
|
||||
- --ws.port=8545
|
||||
restart: unless-stopped
|
||||
stop_grace_period: 5m
|
||||
networks:
|
||||
- chains
|
||||
volumes:
|
||||
- ${ARBITRUM_ONE_NITRO_PRUNED_PEBBLE_HASH_DATA:-arbitrum-one-nitro-pruned-pebble-hash}:/root/.arbitrum
|
||||
- ./tmp/arbitrum-one:/tmp
|
||||
- /slowdisk:/slowdisk
|
||||
logging: *logging-defaults
|
||||
labels:
|
||||
- prometheus-scrape.enabled=true
|
||||
- prometheus-scrape.port=6070
|
||||
- prometheus-scrape.path=/debug/metrics/prometheus
|
||||
|
||||
arbitrum-one-benchmark:
|
||||
build:
|
||||
context: ./benchmark-proxy
|
||||
dockerfile: Dockerfile
|
||||
expose:
|
||||
- '8545'
|
||||
environment:
|
||||
- ENABLE_DETAILED_LOGS=${BENCHMARK_PROXY_VERBOSE:-false}
|
||||
- LISTEN_ADDR=:8545
|
||||
- PRIMARY_BACKEND=http://arbitrum-one:8545
|
||||
- SUMMARY_INTERVAL=60
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
- arbitrum-one
|
||||
networks:
|
||||
- chains
|
||||
logging: *logging-defaults
|
||||
labels:
|
||||
- prometheus-scrape.enabled=false
|
||||
- traefik.enable=true
|
||||
- traefik.http.middlewares.arbitrum-one-nitro-pruned-pebble-hash-stripprefix.stripprefix.prefixes=/arbitrum-one
|
||||
- traefik.http.services.arbitrum-one-nitro-pruned-pebble-hash.loadbalancer.server.port=8545
|
||||
- ${NO_SSL:-traefik.http.routers.arbitrum-one-nitro-pruned-pebble-hash.entrypoints=websecure}
|
||||
- ${NO_SSL:-traefik.http.routers.arbitrum-one-nitro-pruned-pebble-hash.tls.certresolver=myresolver}
|
||||
- ${NO_SSL:-traefik.http.routers.arbitrum-one-nitro-pruned-pebble-hash.rule=Host(`$DOMAIN`) && (Path(`/arbitrum-one`) || Path(`/arbitrum-one/`))}
|
||||
- ${NO_SSL:+traefik.http.routers.arbitrum-one-nitro-pruned-pebble-hash.rule=Path(`/arbitrum-one`) || Path(`/arbitrum-one/`)}
|
||||
- traefik.http.routers.arbitrum-one-nitro-pruned-pebble-hash.middlewares=arbitrum-one-nitro-pruned-pebble-hash-stripprefix, ipallowlist
|
||||
|
||||
volumes:
|
||||
arbitrum-one-nitro-pruned-pebble-hash:
|
||||
|
||||
x-upstreams:
|
||||
- id: $${ID}
|
||||
labels:
|
||||
provider: $${PROVIDER}
|
||||
connection:
|
||||
generic:
|
||||
rpc:
|
||||
url: $${RPC_URL}
|
||||
ws:
|
||||
frameSize: 20Mb
|
||||
msgSize: 50Mb
|
||||
url: $${WS_URL}
|
||||
chain: arbitrum
|
||||
method-groups:
|
||||
enabled:
|
||||
- debug
|
||||
- filter
|
||||
methods:
|
||||
disabled:
|
||||
enabled:
|
||||
- name: txpool_content # TODO: should be disabled for rollup nodes
|
||||
# standard geth only
|
||||
- name: debug_getRawBlock
|
||||
- name: debug_getRawTransaction
|
||||
- name: debug_getRawReceipts
|
||||
- name: debug_getRawHeader
|
||||
- name: debug_getBadBlocks
|
||||
# non standard geth only slightly dangerous
|
||||
- name: debug_intermediateRoots
|
||||
- name: debug_dumpBlock
|
||||
# standard geth and erigon
|
||||
- name: debug_accountRange
|
||||
- name: debug_getModifiedAccountsByNumber
|
||||
- name: debug_getModifiedAccountsByHash
|
||||
# non standard geth and erigon
|
||||
- name: eth_getRawTransactionByHash
|
||||
- name: eth_getRawTransactionByBlockHashAndIndex
|
||||
...
|
||||
201
arb/nitro/arbitrum-one-nitro-pruned-pebble-hash--fireeth.yml
Normal file
201
arb/nitro/arbitrum-one-nitro-pruned-pebble-hash--fireeth.yml
Normal file
@@ -0,0 +1,201 @@
|
||||
---
|
||||
x-logging-defaults: &logging-defaults
|
||||
driver: json-file
|
||||
options:
|
||||
max-size: "10m"
|
||||
max-file: "3"
|
||||
|
||||
# Usage:
|
||||
#
|
||||
# mkdir rpc && cd rpc
|
||||
#
|
||||
# git init
|
||||
# git remote add origin https://github.com/StakeSquid/ethereum-rpc-docker.git
|
||||
# git fetch origin vibe
|
||||
# git checkout origin/vibe
|
||||
#
|
||||
# docker run --rm alpine sh -c "printf '0x'; head -c32 /dev/urandom | xxd -p -c 64" > .jwtsecret
|
||||
#
|
||||
# env
|
||||
# ...
|
||||
# IP=$(curl ipinfo.io/ip)
|
||||
# DOMAIN=${IP}.traefik.me
|
||||
# COMPOSE_FILE=base.yml:rpc.yml:arb/nitro/arbitrum-one-nitro-pruned-pebble-hash--fireeth.yml
|
||||
#
|
||||
# docker compose up -d
|
||||
#
|
||||
# curl -X POST https://${IP}.traefik.me/arbitrum-one \
|
||||
# -H "Content-Type: application/json" \
|
||||
# --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'
|
||||
|
||||
services:
|
||||
arbitrum-one:
|
||||
image: ${ARBITRUM_FIREETH_IMAGE:-ghcr.io/streamingfast/firehose-ethereum}:${ARBITRUM_ONE_FIREETH_VERSION:-v2.11.7-nitro-nitro-v3.5.5-fh3.0}
|
||||
sysctls:
|
||||
# TCP Performance
|
||||
net.ipv4.tcp_slow_start_after_idle: 0 # Disable slow start after idle
|
||||
net.ipv4.tcp_no_metrics_save: 1 # Disable metrics cache
|
||||
net.ipv4.tcp_rmem: 4096 87380 16777216 # Increase TCP read buffers
|
||||
net.ipv4.tcp_wmem: 4096 87380 16777216 # Increase TCP write buffers
|
||||
net.core.somaxconn: 32768 # Higher connection queue
|
||||
# Memory/Connection Management
|
||||
# net.core.netdev_max_backlog: 50000 # Increase network buffer
|
||||
net.ipv4.tcp_max_syn_backlog: 30000 # More SYN requests
|
||||
net.ipv4.tcp_max_tw_buckets: 2000000 # Allow more TIME_WAIT sockets
|
||||
ulimits:
|
||||
nofile: 1048576 # Max open files (for RPC/WS connections)
|
||||
user: root
|
||||
expose:
|
||||
- 8545
|
||||
entrypoint: [sh, -c, exec fireeth start reader-node --log-to-file=false --reader-node-arguments "$*", _]
|
||||
command:
|
||||
- --chain.id=42161
|
||||
- --execution.caching.archive=false
|
||||
- --execution.rpc.gas-cap=600000000
|
||||
- --execution.sequencer.enable=false
|
||||
- --http.addr=0.0.0.0
|
||||
- --http.api=eth,net,web3,arb,txpool,debug
|
||||
- --http.corsdomain=*
|
||||
- --http.port=8545
|
||||
- --http.vhosts=*
|
||||
- --init.download-path=/tmp
|
||||
- --init.latest=pruned
|
||||
- --metrics
|
||||
- --metrics-server.addr=0.0.0.0
|
||||
- --metrics-server.port=6070
|
||||
- --node.batch-poster.enable=false
|
||||
- --node.sequencer=false
|
||||
- --node.staker.enable=false
|
||||
- --parent-chain.blob-client.beacon-url=${ETHEREUM_MAINNET_BEACON_REST}
|
||||
- --parent-chain.connection.url=${ETHEREUM_MAINNET_EXECUTION_RPC}
|
||||
- --persistent.chain=/root/.arbitrum/arbitrum-one
|
||||
- --persistent.db-engine=pebble
|
||||
- --ws.addr=0.0.0.0
|
||||
- --ws.origins=*
|
||||
- --ws.port=8545
|
||||
restart: unless-stopped
|
||||
stop_grace_period: 5m
|
||||
networks:
|
||||
- chains
|
||||
volumes:
|
||||
- ${ARBITRUM_ONE_FIREETH_DATA:-arbitrum-one-fireeth}:/app/firehose-data
|
||||
- ${ARBITRUM_ONE_NITRO_PRUNED_PEBBLE_HASH_DATA:-arbitrum-one-nitro-pruned-pebble-hash}:/root/.arbitrum
|
||||
- ./tmp/arbitrum-one:/tmp
|
||||
- /slowdisk:/slowdisk
|
||||
logging: *logging-defaults
|
||||
labels:
|
||||
- prometheus-scrape.enabled=true
|
||||
- prometheus-scrape.port=6070
|
||||
- prometheus-scrape.path=/debug/metrics/prometheus
|
||||
- traefik.enable=true
|
||||
- traefik.http.middlewares.arbitrum-one-nitro-pruned-pebble-hash-stripprefix.stripprefix.prefixes=/arbitrum-one
|
||||
- traefik.http.services.arbitrum-one-nitro-pruned-pebble-hash.loadbalancer.server.port=8545
|
||||
- ${NO_SSL:-traefik.http.routers.arbitrum-one-nitro-pruned-pebble-hash.entrypoints=websecure}
|
||||
- ${NO_SSL:-traefik.http.routers.arbitrum-one-nitro-pruned-pebble-hash.tls.certresolver=myresolver}
|
||||
- ${NO_SSL:-traefik.http.routers.arbitrum-one-nitro-pruned-pebble-hash.rule=Host(`$DOMAIN`) && (Path(`/arbitrum-one`) || Path(`/arbitrum-one/`))}
|
||||
- ${NO_SSL:+traefik.http.routers.arbitrum-one-nitro-pruned-pebble-hash.rule=Path(`/arbitrum-one`) || Path(`/arbitrum-one/`)}
|
||||
- traefik.http.routers.arbitrum-one-nitro-pruned-pebble-hash.middlewares=arbitrum-one-nitro-pruned-pebble-hash-stripprefix, ipallowlist
|
||||
|
||||
arbitrum-one-firehose:
|
||||
image: ${ARBITRUM_FIREETH_IMAGE:-ghcr.io/streamingfast/firehose-ethereum}:${ARBITRUM_ONE_FIREETH_VERSION:-v2.11.7-nitro-nitro-v3.5.5-fh3.0}
|
||||
expose:
|
||||
- 10015
|
||||
- 10014
|
||||
environment:
|
||||
- ${ARBITRUM_ONE_FIREETH_BLOCKS_STORE:-/app/firehose-data/storage/merged-blocks}
|
||||
entrypoint: [sh, -c, exec fireeth --config-file="" --log-to-file=false start firehose index-builder relayer merger $@, _]
|
||||
command:
|
||||
- --firehose-rate-limit-bucket-fill-rate=${ARBITRUM_ONE_FIREHOSE_RATE_LIMIT_BUCKET_FILL_RATE:-1s}
|
||||
- --firehose-rate-limit-bucket-size=${ARBITRUM_ONE_FIREHOSE_RATE_LIMIT_BUCKET_SIZE:-200}
|
||||
- --log-to-file=false
|
||||
- --relayer-source=arbitrum-one:10010
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
- arbitrum-one
|
||||
networks:
|
||||
- chains
|
||||
volumes:
|
||||
- ${ARBITRUM_ONE_FIREETH_DATA:-arbitrum-one-fireeth}:/app/firehose-data
|
||||
logging: *logging-defaults
|
||||
labels:
|
||||
- prometheus-scrape.enabled=false
|
||||
- traefik.enable=true
|
||||
- traefik.http.services.arbitrum-one-nitro-pruned-pebble-hash-firehose.loadbalancer.server.scheme=h2c
|
||||
- traefik.http.routers.arbitrum-one-nitro-pruned-pebble-hash-firehose.service=arbitrum-one-nitro-pruned-pebble-hash-firehose
|
||||
- traefik.http.services.arbitrum-one-nitro-pruned-pebble-hash-firehose.loadbalancer.server.port=10015
|
||||
- traefik.http.routers.arbitrum-one-nitro-pruned-pebble-hash-firehose.entrypoints=grpc
|
||||
- ${NO_SSL:-traefik.http.routers.arbitrum-one-nitro-pruned-pebble-hash-firehose.tls.certresolver=myresolver}
|
||||
- traefik.http.routers.arbitrum-one-nitro-pruned-pebble-hash-firehose.rule=Host(`arbitrum-one-firehose.${DOMAIN}`)
|
||||
- traefik.http.routers.arbitrum-one-nitro-pruned-pebble-hash-firehose.middlewares=ipallowlist
|
||||
|
||||
arbitrum-one-events:
|
||||
image: ${ARBITRUM_FIREETH_IMAGE:-ghcr.io/streamingfast/firehose-ethereum}:${ARBITRUM_ONE_FIREETH_VERSION:-v2.11.7-nitro-nitro-v3.5.5-fh3.0}
|
||||
expose:
|
||||
- 10016
|
||||
entrypoint: [sh, -c, exec fireeth --config-file="" --log-to-file=false start substreams-tier1 substreams-tier2 $@, _]
|
||||
command:
|
||||
- --common-live-blocks-addr=arbitrum-one-firehose:10014
|
||||
- --log-to-file=false
|
||||
- --substreams-block-execution-timeout=${ARBITRUM_ONE_SUBSTREAMS_BLOCK_EXECUTION_TIMEOUT:-3m0s}
|
||||
- --substreams-rpc-endpoints=${ARBITRUM_ONE_EXECUTION_ARCHIVE_RPC}
|
||||
- --substreams-tier1-max-subrequests=${ARBITRUM_ONE_SUBSTREAMS_TIER1_MAX_SUBREQUESTS:-4}
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
- arbitrum-one
|
||||
networks:
|
||||
- chains
|
||||
volumes:
|
||||
- ${ARBITRUM_ONE_FIREETH_DATA:-arbitrum-one-fireeth}:/app/firehose-data
|
||||
logging: *logging-defaults
|
||||
labels:
|
||||
- traefik.enable=true
|
||||
- traefik.http.services.arbitrum-one-nitro-pruned-pebble-hash-events.loadbalancer.server.scheme=h2c
|
||||
- traefik.http.routers.arbitrum-one-nitro-pruned-pebble-hash-events.service=arbitrum-one-nitro-pruned-pebble-hash-events
|
||||
- traefik.http.services.arbitrum-one-nitro-pruned-pebble-hash-events.loadbalancer.server.port=10016
|
||||
- traefik.http.routers.arbitrum-one-nitro-pruned-pebble-hash-events.entrypoints=grpc
|
||||
- ${NO_SSL:-traefik.http.routers.arbitrum-one-nitro-pruned-pebble-hash-events.tls.certresolver=myresolver}
|
||||
- traefik.http.routers.arbitrum-one-nitro-pruned-pebble-hash-events.rule=Host(`arbitrum-one-events.${DOMAIN}`)
|
||||
- traefik.http.routers.arbitrum-one-nitro-pruned-pebble-hash-events.middlewares=ipallowlist
|
||||
|
||||
volumes:
|
||||
arbitrum-one-nitro-pruned-pebble-hash:
|
||||
arbitrum-one-nitro-pruned-pebble-hash_fireeth:
|
||||
|
||||
x-upstreams:
|
||||
- id: $${ID}
|
||||
labels:
|
||||
provider: $${PROVIDER}
|
||||
connection:
|
||||
generic:
|
||||
rpc:
|
||||
url: $${RPC_URL}
|
||||
ws:
|
||||
frameSize: 20Mb
|
||||
msgSize: 50Mb
|
||||
url: $${WS_URL}
|
||||
chain: arbitrum
|
||||
method-groups:
|
||||
enabled:
|
||||
- debug
|
||||
- filter
|
||||
methods:
|
||||
disabled:
|
||||
enabled:
|
||||
- name: txpool_content # TODO: should be disabled for rollup nodes
|
||||
# standard geth only
|
||||
- name: debug_getRawBlock
|
||||
- name: debug_getRawTransaction
|
||||
- name: debug_getRawReceipts
|
||||
- name: debug_getRawHeader
|
||||
- name: debug_getBadBlocks
|
||||
# non standard geth only slightly dangerous
|
||||
- name: debug_intermediateRoots
|
||||
- name: debug_dumpBlock
|
||||
# standard geth and erigon
|
||||
- name: debug_accountRange
|
||||
- name: debug_getModifiedAccountsByNumber
|
||||
- name: debug_getModifiedAccountsByHash
|
||||
# non standard geth and erigon
|
||||
- name: eth_getRawTransactionByHash
|
||||
- name: eth_getRawTransactionByBlockHashAndIndex
|
||||
...
|
||||
137
arb/nitro/arbitrum-one-nitro-pruned-pebble-hash.yml
Normal file
137
arb/nitro/arbitrum-one-nitro-pruned-pebble-hash.yml
Normal file
@@ -0,0 +1,137 @@
|
||||
---
|
||||
x-logging-defaults: &logging-defaults
|
||||
driver: json-file
|
||||
options:
|
||||
max-size: "10m"
|
||||
max-file: "3"
|
||||
|
||||
# Usage:
|
||||
#
|
||||
# mkdir rpc && cd rpc
|
||||
#
|
||||
# git init
|
||||
# git remote add origin https://github.com/StakeSquid/ethereum-rpc-docker.git
|
||||
# git fetch origin vibe
|
||||
# git checkout origin/vibe
|
||||
#
|
||||
# docker run --rm alpine sh -c "printf '0x'; head -c32 /dev/urandom | xxd -p -c 64" > .jwtsecret
|
||||
#
|
||||
# env
|
||||
# ...
|
||||
# IP=$(curl ipinfo.io/ip)
|
||||
# DOMAIN=${IP}.traefik.me
|
||||
# COMPOSE_FILE=base.yml:rpc.yml:arb/nitro/arbitrum-one-nitro-pruned-pebble-hash.yml
|
||||
#
|
||||
# docker compose up -d
|
||||
#
|
||||
# curl -X POST https://${IP}.traefik.me/arbitrum-one \
|
||||
# -H "Content-Type: application/json" \
|
||||
# --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'
|
||||
|
||||
services:
|
||||
arbitrum-one:
|
||||
image: ${ARBITRUM_NITRO_IMAGE:-offchainlabs/nitro-node}:${ARBITRUM_ONE_NITRO_VERSION:-v3.6.4-28199cd}
|
||||
sysctls:
|
||||
# TCP Performance
|
||||
net.ipv4.tcp_slow_start_after_idle: 0 # Disable slow start after idle
|
||||
net.ipv4.tcp_no_metrics_save: 1 # Disable metrics cache
|
||||
net.ipv4.tcp_rmem: 4096 87380 16777216 # Increase TCP read buffers
|
||||
net.ipv4.tcp_wmem: 4096 87380 16777216 # Increase TCP write buffers
|
||||
net.core.somaxconn: 32768 # Higher connection queue
|
||||
# Memory/Connection Management
|
||||
# net.core.netdev_max_backlog: 50000 # Increase network buffer
|
||||
net.ipv4.tcp_max_syn_backlog: 30000 # More SYN requests
|
||||
net.ipv4.tcp_max_tw_buckets: 2000000 # Allow more TIME_WAIT sockets
|
||||
ulimits:
|
||||
nofile: 1048576 # Max open files (for RPC/WS connections)
|
||||
user: root
|
||||
expose:
|
||||
- 8545
|
||||
command:
|
||||
- --chain.id=42161
|
||||
- --execution.caching.archive=false
|
||||
- --execution.rpc.gas-cap=600000000
|
||||
- --execution.sequencer.enable=false
|
||||
- --http.addr=0.0.0.0
|
||||
- --http.api=eth,net,web3,arb,txpool,debug
|
||||
- --http.corsdomain=*
|
||||
- --http.port=8545
|
||||
- --http.vhosts=*
|
||||
- --init.download-path=/tmp
|
||||
- --init.latest=pruned
|
||||
- --metrics
|
||||
- --metrics-server.addr=0.0.0.0
|
||||
- --metrics-server.port=6070
|
||||
- --node.batch-poster.enable=false
|
||||
- --node.sequencer=false
|
||||
- --node.staker.enable=false
|
||||
- --parent-chain.blob-client.beacon-url=${ETHEREUM_MAINNET_BEACON_REST}
|
||||
- --parent-chain.connection.url=${ETHEREUM_MAINNET_EXECUTION_RPC}
|
||||
- --persistent.chain=/root/.arbitrum/arbitrum-one
|
||||
- --persistent.db-engine=pebble
|
||||
- --ws.addr=0.0.0.0
|
||||
- --ws.origins=*
|
||||
- --ws.port=8545
|
||||
restart: unless-stopped
|
||||
stop_grace_period: 5m
|
||||
networks:
|
||||
- chains
|
||||
volumes:
|
||||
- ${ARBITRUM_ONE_NITRO_PRUNED_PEBBLE_HASH_DATA:-arbitrum-one-nitro-pruned-pebble-hash}:/root/.arbitrum
|
||||
- ./tmp/arbitrum-one:/tmp
|
||||
- /slowdisk:/slowdisk
|
||||
logging: *logging-defaults
|
||||
labels:
|
||||
- prometheus-scrape.enabled=true
|
||||
- prometheus-scrape.port=6070
|
||||
- prometheus-scrape.path=/debug/metrics/prometheus
|
||||
- traefik.enable=true
|
||||
- traefik.http.middlewares.arbitrum-one-nitro-pruned-pebble-hash-stripprefix.stripprefix.prefixes=/arbitrum-one
|
||||
- traefik.http.services.arbitrum-one-nitro-pruned-pebble-hash.loadbalancer.server.port=8545
|
||||
- ${NO_SSL:-traefik.http.routers.arbitrum-one-nitro-pruned-pebble-hash.entrypoints=websecure}
|
||||
- ${NO_SSL:-traefik.http.routers.arbitrum-one-nitro-pruned-pebble-hash.tls.certresolver=myresolver}
|
||||
- ${NO_SSL:-traefik.http.routers.arbitrum-one-nitro-pruned-pebble-hash.rule=Host(`$DOMAIN`) && (Path(`/arbitrum-one`) || Path(`/arbitrum-one/`))}
|
||||
- ${NO_SSL:+traefik.http.routers.arbitrum-one-nitro-pruned-pebble-hash.rule=Path(`/arbitrum-one`) || Path(`/arbitrum-one/`)}
|
||||
- traefik.http.routers.arbitrum-one-nitro-pruned-pebble-hash.middlewares=arbitrum-one-nitro-pruned-pebble-hash-stripprefix, ipallowlist
|
||||
|
||||
volumes:
|
||||
arbitrum-one-nitro-pruned-pebble-hash:
|
||||
|
||||
x-upstreams:
|
||||
- id: $${ID}
|
||||
labels:
|
||||
provider: $${PROVIDER}
|
||||
connection:
|
||||
generic:
|
||||
rpc:
|
||||
url: $${RPC_URL}
|
||||
ws:
|
||||
frameSize: 20Mb
|
||||
msgSize: 50Mb
|
||||
url: $${WS_URL}
|
||||
chain: arbitrum
|
||||
method-groups:
|
||||
enabled:
|
||||
- debug
|
||||
- filter
|
||||
methods:
|
||||
disabled:
|
||||
enabled:
|
||||
- name: txpool_content # TODO: should be disabled for rollup nodes
|
||||
# standard geth only
|
||||
- name: debug_getRawBlock
|
||||
- name: debug_getRawTransaction
|
||||
- name: debug_getRawReceipts
|
||||
- name: debug_getRawHeader
|
||||
- name: debug_getBadBlocks
|
||||
# non standard geth only slightly dangerous
|
||||
- name: debug_intermediateRoots
|
||||
- name: debug_dumpBlock
|
||||
# standard geth and erigon
|
||||
- name: debug_accountRange
|
||||
- name: debug_getModifiedAccountsByNumber
|
||||
- name: debug_getModifiedAccountsByHash
|
||||
# non standard geth and erigon
|
||||
- name: eth_getRawTransactionByHash
|
||||
- name: eth_getRawTransactionByBlockHashAndIndex
|
||||
...
|
||||
137
arb/nitro/arbitrum-sepolia-nitro-archive-pebble-hash.yml
Normal file
137
arb/nitro/arbitrum-sepolia-nitro-archive-pebble-hash.yml
Normal file
@@ -0,0 +1,137 @@
|
||||
---
|
||||
x-logging-defaults: &logging-defaults
|
||||
driver: json-file
|
||||
options:
|
||||
max-size: "10m"
|
||||
max-file: "3"
|
||||
|
||||
# Usage:
|
||||
#
|
||||
# mkdir rpc && cd rpc
|
||||
#
|
||||
# git init
|
||||
# git remote add origin https://github.com/StakeSquid/ethereum-rpc-docker.git
|
||||
# git fetch origin vibe
|
||||
# git checkout origin/vibe
|
||||
#
|
||||
# docker run --rm alpine sh -c "printf '0x'; head -c32 /dev/urandom | xxd -p -c 64" > .jwtsecret
|
||||
#
|
||||
# env
|
||||
# ...
|
||||
# IP=$(curl ipinfo.io/ip)
|
||||
# DOMAIN=${IP}.traefik.me
|
||||
# COMPOSE_FILE=base.yml:rpc.yml:arb/nitro/arbitrum-sepolia-nitro-archive-pebble-hash.yml
|
||||
#
|
||||
# docker compose up -d
|
||||
#
|
||||
# curl -X POST https://${IP}.traefik.me/arbitrum-sepolia-archive \
|
||||
# -H "Content-Type: application/json" \
|
||||
# --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'
|
||||
|
||||
services:
|
||||
arbitrum-sepolia-archive:
|
||||
image: ${ARBITRUM_NITRO_IMAGE:-offchainlabs/nitro-node}:${ARBITRUM_SEPOLIA_NITRO_VERSION:-v3.6.4-28199cd}
|
||||
sysctls:
|
||||
# TCP Performance
|
||||
net.ipv4.tcp_slow_start_after_idle: 0 # Disable slow start after idle
|
||||
net.ipv4.tcp_no_metrics_save: 1 # Disable metrics cache
|
||||
net.ipv4.tcp_rmem: 4096 87380 16777216 # Increase TCP read buffers
|
||||
net.ipv4.tcp_wmem: 4096 87380 16777216 # Increase TCP write buffers
|
||||
net.core.somaxconn: 32768 # Higher connection queue
|
||||
# Memory/Connection Management
|
||||
# net.core.netdev_max_backlog: 50000 # Increase network buffer
|
||||
net.ipv4.tcp_max_syn_backlog: 30000 # More SYN requests
|
||||
net.ipv4.tcp_max_tw_buckets: 2000000 # Allow more TIME_WAIT sockets
|
||||
ulimits:
|
||||
nofile: 1048576 # Max open files (for RPC/WS connections)
|
||||
user: root
|
||||
expose:
|
||||
- 8545
|
||||
command:
|
||||
- --chain.id=421614
|
||||
- --execution.caching.archive=true
|
||||
- --execution.rpc.gas-cap=600000000
|
||||
- --execution.sequencer.enable=false
|
||||
- --http.addr=0.0.0.0
|
||||
- --http.api=eth,net,web3,arb,txpool,debug
|
||||
- --http.corsdomain=*
|
||||
- --http.port=8545
|
||||
- --http.vhosts=*
|
||||
- --init.download-path=/tmp
|
||||
- --init.latest=archive
|
||||
- --metrics
|
||||
- --metrics-server.addr=0.0.0.0
|
||||
- --metrics-server.port=6070
|
||||
- --node.batch-poster.enable=false
|
||||
- --node.sequencer=false
|
||||
- --node.staker.enable=false
|
||||
- --parent-chain.blob-client.beacon-url=${ETHEREUM_SEPOLIA_BEACON_REST}
|
||||
- --parent-chain.connection.url=${ETHEREUM_SEPOLIA_EXECUTION_RPC}
|
||||
- --persistent.chain=/root/.arbitrum/arbitrum-sepolia-archive
|
||||
- --persistent.db-engine=pebble
|
||||
- --ws.addr=0.0.0.0
|
||||
- --ws.origins=*
|
||||
- --ws.port=8545
|
||||
restart: unless-stopped
|
||||
stop_grace_period: 5m
|
||||
networks:
|
||||
- chains
|
||||
volumes:
|
||||
- ${ARBITRUM_SEPOLIA_NITRO_ARCHIVE_PEBBLE_HASH_DATA:-arbitrum-sepolia-nitro-archive-pebble-hash}:/root/.arbitrum
|
||||
- ./tmp/arbitrum-sepolia-archive:/tmp
|
||||
- /slowdisk:/slowdisk
|
||||
logging: *logging-defaults
|
||||
labels:
|
||||
- prometheus-scrape.enabled=true
|
||||
- prometheus-scrape.port=6070
|
||||
- prometheus-scrape.path=/debug/metrics/prometheus
|
||||
- traefik.enable=true
|
||||
- traefik.http.middlewares.arbitrum-sepolia-nitro-archive-pebble-hash-stripprefix.stripprefix.prefixes=/arbitrum-sepolia-archive
|
||||
- traefik.http.services.arbitrum-sepolia-nitro-archive-pebble-hash.loadbalancer.server.port=8545
|
||||
- ${NO_SSL:-traefik.http.routers.arbitrum-sepolia-nitro-archive-pebble-hash.entrypoints=websecure}
|
||||
- ${NO_SSL:-traefik.http.routers.arbitrum-sepolia-nitro-archive-pebble-hash.tls.certresolver=myresolver}
|
||||
- ${NO_SSL:-traefik.http.routers.arbitrum-sepolia-nitro-archive-pebble-hash.rule=Host(`$DOMAIN`) && (Path(`/arbitrum-sepolia-archive`) || Path(`/arbitrum-sepolia-archive/`))}
|
||||
- ${NO_SSL:+traefik.http.routers.arbitrum-sepolia-nitro-archive-pebble-hash.rule=Path(`/arbitrum-sepolia-archive`) || Path(`/arbitrum-sepolia-archive/`)}
|
||||
- traefik.http.routers.arbitrum-sepolia-nitro-archive-pebble-hash.middlewares=arbitrum-sepolia-nitro-archive-pebble-hash-stripprefix, ipallowlist
|
||||
|
||||
volumes:
|
||||
arbitrum-sepolia-nitro-archive-pebble-hash:
|
||||
|
||||
x-upstreams:
|
||||
- id: $${ID}
|
||||
labels:
|
||||
provider: $${PROVIDER}
|
||||
connection:
|
||||
generic:
|
||||
rpc:
|
||||
url: $${RPC_URL}
|
||||
ws:
|
||||
frameSize: 20Mb
|
||||
msgSize: 50Mb
|
||||
url: $${WS_URL}
|
||||
chain: arbitrum-sepolia
|
||||
method-groups:
|
||||
enabled:
|
||||
- debug
|
||||
- filter
|
||||
methods:
|
||||
disabled:
|
||||
enabled:
|
||||
- name: txpool_content # TODO: should be disabled for rollup nodes
|
||||
# standard geth only
|
||||
- name: debug_getRawBlock
|
||||
- name: debug_getRawTransaction
|
||||
- name: debug_getRawReceipts
|
||||
- name: debug_getRawHeader
|
||||
- name: debug_getBadBlocks
|
||||
# non standard geth only slightly dangerous
|
||||
- name: debug_intermediateRoots
|
||||
- name: debug_dumpBlock
|
||||
# standard geth and erigon
|
||||
- name: debug_accountRange
|
||||
- name: debug_getModifiedAccountsByNumber
|
||||
- name: debug_getModifiedAccountsByHash
|
||||
# non standard geth and erigon
|
||||
- name: eth_getRawTransactionByHash
|
||||
- name: eth_getRawTransactionByBlockHashAndIndex
|
||||
...
|
||||
137
arb/nitro/arbitrum-sepolia-nitro-pruned-pebble-hash.yml
Normal file
137
arb/nitro/arbitrum-sepolia-nitro-pruned-pebble-hash.yml
Normal file
@@ -0,0 +1,137 @@
|
||||
---
|
||||
x-logging-defaults: &logging-defaults
|
||||
driver: json-file
|
||||
options:
|
||||
max-size: "10m"
|
||||
max-file: "3"
|
||||
|
||||
# Usage:
|
||||
#
|
||||
# mkdir rpc && cd rpc
|
||||
#
|
||||
# git init
|
||||
# git remote add origin https://github.com/StakeSquid/ethereum-rpc-docker.git
|
||||
# git fetch origin vibe
|
||||
# git checkout origin/vibe
|
||||
#
|
||||
# docker run --rm alpine sh -c "printf '0x'; head -c32 /dev/urandom | xxd -p -c 64" > .jwtsecret
|
||||
#
|
||||
# env
|
||||
# ...
|
||||
# IP=$(curl ipinfo.io/ip)
|
||||
# DOMAIN=${IP}.traefik.me
|
||||
# COMPOSE_FILE=base.yml:rpc.yml:arb/nitro/arbitrum-sepolia-nitro-pruned-pebble-hash.yml
|
||||
#
|
||||
# docker compose up -d
|
||||
#
|
||||
# curl -X POST https://${IP}.traefik.me/arbitrum-sepolia \
|
||||
# -H "Content-Type: application/json" \
|
||||
# --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'
|
||||
|
||||
services:
|
||||
arbitrum-sepolia:
|
||||
image: ${ARBITRUM_NITRO_IMAGE:-offchainlabs/nitro-node}:${ARBITRUM_SEPOLIA_NITRO_VERSION:-v3.6.4-28199cd}
|
||||
sysctls:
|
||||
# TCP Performance
|
||||
net.ipv4.tcp_slow_start_after_idle: 0 # Disable slow start after idle
|
||||
net.ipv4.tcp_no_metrics_save: 1 # Disable metrics cache
|
||||
net.ipv4.tcp_rmem: 4096 87380 16777216 # Increase TCP read buffers
|
||||
net.ipv4.tcp_wmem: 4096 87380 16777216 # Increase TCP write buffers
|
||||
net.core.somaxconn: 32768 # Higher connection queue
|
||||
# Memory/Connection Management
|
||||
# net.core.netdev_max_backlog: 50000 # Increase network buffer
|
||||
net.ipv4.tcp_max_syn_backlog: 30000 # More SYN requests
|
||||
net.ipv4.tcp_max_tw_buckets: 2000000 # Allow more TIME_WAIT sockets
|
||||
ulimits:
|
||||
nofile: 1048576 # Max open files (for RPC/WS connections)
|
||||
user: root
|
||||
expose:
|
||||
- 8545
|
||||
command:
|
||||
- --chain.id=421614
|
||||
- --execution.caching.archive=false
|
||||
- --execution.rpc.gas-cap=600000000
|
||||
- --execution.sequencer.enable=false
|
||||
- --http.addr=0.0.0.0
|
||||
- --http.api=eth,net,web3,arb,txpool,debug
|
||||
- --http.corsdomain=*
|
||||
- --http.port=8545
|
||||
- --http.vhosts=*
|
||||
- --init.download-path=/tmp
|
||||
- --init.latest=pruned
|
||||
- --metrics
|
||||
- --metrics-server.addr=0.0.0.0
|
||||
- --metrics-server.port=6070
|
||||
- --node.batch-poster.enable=false
|
||||
- --node.sequencer=false
|
||||
- --node.staker.enable=false
|
||||
- --parent-chain.blob-client.beacon-url=${ETHEREUM_SEPOLIA_BEACON_REST}
|
||||
- --parent-chain.connection.url=${ETHEREUM_SEPOLIA_EXECUTION_RPC}
|
||||
- --persistent.chain=/root/.arbitrum/arbitrum-sepolia
|
||||
- --persistent.db-engine=pebble
|
||||
- --ws.addr=0.0.0.0
|
||||
- --ws.origins=*
|
||||
- --ws.port=8545
|
||||
restart: unless-stopped
|
||||
stop_grace_period: 5m
|
||||
networks:
|
||||
- chains
|
||||
volumes:
|
||||
- ${ARBITRUM_SEPOLIA_NITRO_PRUNED_PEBBLE_HASH_DATA:-arbitrum-sepolia-nitro-pruned-pebble-hash}:/root/.arbitrum
|
||||
- ./tmp/arbitrum-sepolia:/tmp
|
||||
- /slowdisk:/slowdisk
|
||||
logging: *logging-defaults
|
||||
labels:
|
||||
- prometheus-scrape.enabled=true
|
||||
- prometheus-scrape.port=6070
|
||||
- prometheus-scrape.path=/debug/metrics/prometheus
|
||||
- traefik.enable=true
|
||||
- traefik.http.middlewares.arbitrum-sepolia-nitro-pruned-pebble-hash-stripprefix.stripprefix.prefixes=/arbitrum-sepolia
|
||||
- traefik.http.services.arbitrum-sepolia-nitro-pruned-pebble-hash.loadbalancer.server.port=8545
|
||||
- ${NO_SSL:-traefik.http.routers.arbitrum-sepolia-nitro-pruned-pebble-hash.entrypoints=websecure}
|
||||
- ${NO_SSL:-traefik.http.routers.arbitrum-sepolia-nitro-pruned-pebble-hash.tls.certresolver=myresolver}
|
||||
- ${NO_SSL:-traefik.http.routers.arbitrum-sepolia-nitro-pruned-pebble-hash.rule=Host(`$DOMAIN`) && (Path(`/arbitrum-sepolia`) || Path(`/arbitrum-sepolia/`))}
|
||||
- ${NO_SSL:+traefik.http.routers.arbitrum-sepolia-nitro-pruned-pebble-hash.rule=Path(`/arbitrum-sepolia`) || Path(`/arbitrum-sepolia/`)}
|
||||
- traefik.http.routers.arbitrum-sepolia-nitro-pruned-pebble-hash.middlewares=arbitrum-sepolia-nitro-pruned-pebble-hash-stripprefix, ipallowlist
|
||||
|
||||
volumes:
|
||||
arbitrum-sepolia-nitro-pruned-pebble-hash:
|
||||
|
||||
x-upstreams:
|
||||
- id: $${ID}
|
||||
labels:
|
||||
provider: $${PROVIDER}
|
||||
connection:
|
||||
generic:
|
||||
rpc:
|
||||
url: $${RPC_URL}
|
||||
ws:
|
||||
frameSize: 20Mb
|
||||
msgSize: 50Mb
|
||||
url: $${WS_URL}
|
||||
chain: arbitrum-sepolia
|
||||
method-groups:
|
||||
enabled:
|
||||
- debug
|
||||
- filter
|
||||
methods:
|
||||
disabled:
|
||||
enabled:
|
||||
- name: txpool_content # TODO: should be disabled for rollup nodes
|
||||
# standard geth only
|
||||
- name: debug_getRawBlock
|
||||
- name: debug_getRawTransaction
|
||||
- name: debug_getRawReceipts
|
||||
- name: debug_getRawHeader
|
||||
- name: debug_getBadBlocks
|
||||
# non standard geth only slightly dangerous
|
||||
- name: debug_intermediateRoots
|
||||
- name: debug_dumpBlock
|
||||
# standard geth and erigon
|
||||
- name: debug_accountRange
|
||||
- name: debug_getModifiedAccountsByNumber
|
||||
- name: debug_getModifiedAccountsByHash
|
||||
# non standard geth and erigon
|
||||
- name: eth_getRawTransactionByHash
|
||||
- name: eth_getRawTransactionByBlockHashAndIndex
|
||||
...
|
||||
57
arb/nitro/arbitrum-sepolia-nitro-pruned-pebble-path.yml
Normal file
57
arb/nitro/arbitrum-sepolia-nitro-pruned-pebble-path.yml
Normal file
@@ -0,0 +1,57 @@
|
||||
|
||||
|
||||
services:
|
||||
arbitrum-sepolia:
|
||||
image: 'offchainlabs/nitro-node:${NITRO_VERSION:-v3.5.3-0a9c975}'
|
||||
stop_grace_period: 3m
|
||||
user: root
|
||||
volumes:
|
||||
- 'arbitrum-sepolia-nitro-pruned-pebble-path:/root/.arbitrum'
|
||||
|
||||
- './tmp/arbitrum-sepolia:/tmp'
|
||||
expose:
|
||||
- 8545
|
||||
command:
|
||||
- --chain.id=421614
|
||||
- --execution.caching.state-scheme=path
|
||||
- --execution.rpc.gas-cap=600000000
|
||||
- --execution.caching.archive=false
|
||||
- --execution.sequencer.enable=false
|
||||
- --persistent.db-engine=pebble
|
||||
- --persistent.chain=/root/.arbitrum/arbitrum-sepolia
|
||||
- --parent-chain.connection.url=${ETHEREUM_SEPOLIA_EXECUTION_RPC}
|
||||
- --parent-chain.blob-client.beacon-url=${ETHEREUM_SEPOLIA_BEACON_REST}
|
||||
- --http.addr=0.0.0.0
|
||||
- --http.port=8545
|
||||
- --http.vhosts=*
|
||||
- --http.corsdomain=*
|
||||
- --http.api=eth,net,web3,arb,txpool,debug
|
||||
- --ws.port=8545
|
||||
- --ws.addr=0.0.0.0
|
||||
- --ws.origins=*
|
||||
- --ws.api=eth,net,web3,arb,txpool,debug
|
||||
- --metrics
|
||||
- --metrics-server.addr=0.0.0.0
|
||||
- --metrics-server.port=6070
|
||||
- --log-type=json
|
||||
- --node.sequencer=false
|
||||
- --node.staker.enable=false
|
||||
- --node.batch-poster.enable=false
|
||||
|
||||
|
||||
|
||||
|
||||
restart: unless-stopped
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.middlewares.arbitrum-sepolia-nitro-pruned-pebble-path-stripprefix.stripprefix.prefixes=/arbitrum-sepolia"
|
||||
- "traefik.http.services.arbitrum-sepolia-nitro-pruned-pebble-path.loadbalancer.server.port=8545"
|
||||
- "traefik.http.routers.arbitrum-sepolia-nitro-pruned-pebble-path.entrypoints=websecure"
|
||||
- "traefik.http.routers.arbitrum-sepolia-nitro-pruned-pebble-path.tls.certresolver=myresolver"
|
||||
- "traefik.http.routers.arbitrum-sepolia-nitro-pruned-pebble-path.rule=Host(`$DOMAIN`) && PathPrefix(`/arbitrum-sepolia`)"
|
||||
- "traefik.http.routers.arbitrum-sepolia-nitro-pruned-pebble-path.middlewares=arbitrum-sepolia-nitro-pruned-pebble-path-stripprefix, ipwhitelist"
|
||||
networks:
|
||||
- chains
|
||||
|
||||
volumes:
|
||||
arbitrum-sepolia-nitro-pruned-pebble-path:
|
||||
142
arb/nitro/connext-sepolia-nitro-archive-leveldb-hash.yml
Normal file
142
arb/nitro/connext-sepolia-nitro-archive-leveldb-hash.yml
Normal file
@@ -0,0 +1,142 @@
|
||||
---
|
||||
x-logging-defaults: &logging-defaults
|
||||
driver: json-file
|
||||
options:
|
||||
max-size: "10m"
|
||||
max-file: "3"
|
||||
|
||||
# Usage:
|
||||
#
|
||||
# mkdir rpc && cd rpc
|
||||
#
|
||||
# git init
|
||||
# git remote add origin https://github.com/StakeSquid/ethereum-rpc-docker.git
|
||||
# git fetch origin vibe
|
||||
# git checkout origin/vibe
|
||||
#
|
||||
# docker run --rm alpine sh -c "printf '0x'; head -c32 /dev/urandom | xxd -p -c 64" > .jwtsecret
|
||||
#
|
||||
# env
|
||||
# ...
|
||||
# IP=$(curl ipinfo.io/ip)
|
||||
# DOMAIN=${IP}.traefik.me
|
||||
# COMPOSE_FILE=base.yml:rpc.yml:arb/nitro/connext-sepolia-nitro-archive-leveldb-hash.yml
|
||||
#
|
||||
# docker compose up -d
|
||||
#
|
||||
# curl -X POST https://${IP}.traefik.me/connext-sepolia-archive \
|
||||
# -H "Content-Type: application/json" \
|
||||
# --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'
|
||||
|
||||
services:
|
||||
connext-sepolia-archive:
|
||||
image: ${CONNEXT_NITRO_IMAGE:-offchainlabs/nitro-node}:${CONNEXT_SEPOLIA_NITRO_VERSION:-v3.6.4-28199cd}
|
||||
sysctls:
|
||||
# TCP Performance
|
||||
net.ipv4.tcp_slow_start_after_idle: 0 # Disable slow start after idle
|
||||
net.ipv4.tcp_no_metrics_save: 1 # Disable metrics cache
|
||||
net.ipv4.tcp_rmem: 4096 87380 16777216 # Increase TCP read buffers
|
||||
net.ipv4.tcp_wmem: 4096 87380 16777216 # Increase TCP write buffers
|
||||
net.core.somaxconn: 32768 # Higher connection queue
|
||||
# Memory/Connection Management
|
||||
# net.core.netdev_max_backlog: 50000 # Increase network buffer
|
||||
net.ipv4.tcp_max_syn_backlog: 30000 # More SYN requests
|
||||
net.ipv4.tcp_max_tw_buckets: 2000000 # Allow more TIME_WAIT sockets
|
||||
ulimits:
|
||||
nofile: 1048576 # Max open files (for RPC/WS connections)
|
||||
user: root
|
||||
expose:
|
||||
- 8545
|
||||
command:
|
||||
- --conf.file=/config/baseConfig.json
|
||||
- --execution.caching.archive=true
|
||||
- --execution.forwarding-target=https://rpc.connext-sepolia.gelato.digital
|
||||
- --execution.rpc.gas-cap=600000000
|
||||
- --execution.sequencer.enable=false
|
||||
- --http.addr=0.0.0.0
|
||||
- --http.api=eth,net,web3,arb,txpool,debug
|
||||
- --http.corsdomain=*
|
||||
- --http.port=8545
|
||||
- --http.vhosts=*
|
||||
- --init.download-path=/tmp
|
||||
- --metrics
|
||||
- --metrics-server.addr=0.0.0.0
|
||||
- --metrics-server.port=6070
|
||||
- --node.batch-poster.enable=false
|
||||
- --node.data-availability.enable=true
|
||||
- --node.data-availability.parent-chain-node-url=${ETHEREUM_SEPOLIA_EXECUTION_RPC}
|
||||
- --node.data-availability.rest-aggregator.enable=true
|
||||
- --node.data-availability.rest-aggregator.urls=https://das.connext-sepolia.gelato.digital
|
||||
- --node.data-availability.sequencer-inbox-address=0x727095791318912381473707332248435763608420056676
|
||||
- --node.feed.input.url=wss://feed.connext-sepolia.gelato.digital
|
||||
- --node.sequencer=false
|
||||
- --node.staker.enable=false
|
||||
- --parent-chain.blob-client.beacon-url=${ETHEREUM_SEPOLIA_BEACON_REST}
|
||||
- --parent-chain.connection.url=${ETHEREUM_SEPOLIA_EXECUTION_RPC}
|
||||
- --persistent.chain=/root/.arbitrum/connext-sepolia-archive
|
||||
- --ws.addr=0.0.0.0
|
||||
- --ws.origins=*
|
||||
- --ws.port=8545
|
||||
restart: unless-stopped
|
||||
stop_grace_period: 5m
|
||||
networks:
|
||||
- chains
|
||||
volumes:
|
||||
- ${CONNEXT_SEPOLIA_NITRO_ARCHIVE_LEVELDB_HASH_DATA:-connext-sepolia-nitro-archive-leveldb-hash}:/root/.arbitrum
|
||||
- ./arb/connext/sepolia:/config
|
||||
- /slowdisk:/slowdisk
|
||||
logging: *logging-defaults
|
||||
labels:
|
||||
- prometheus-scrape.enabled=true
|
||||
- prometheus-scrape.port=6070
|
||||
- prometheus-scrape.path=/debug/metrics/prometheus
|
||||
- traefik.enable=true
|
||||
- traefik.http.middlewares.connext-sepolia-nitro-archive-leveldb-hash-stripprefix.stripprefix.prefixes=/connext-sepolia-archive
|
||||
- traefik.http.services.connext-sepolia-nitro-archive-leveldb-hash.loadbalancer.server.port=8545
|
||||
- ${NO_SSL:-traefik.http.routers.connext-sepolia-nitro-archive-leveldb-hash.entrypoints=websecure}
|
||||
- ${NO_SSL:-traefik.http.routers.connext-sepolia-nitro-archive-leveldb-hash.tls.certresolver=myresolver}
|
||||
- ${NO_SSL:-traefik.http.routers.connext-sepolia-nitro-archive-leveldb-hash.rule=Host(`$DOMAIN`) && (Path(`/connext-sepolia-archive`) || Path(`/connext-sepolia-archive/`))}
|
||||
- ${NO_SSL:+traefik.http.routers.connext-sepolia-nitro-archive-leveldb-hash.rule=Path(`/connext-sepolia-archive`) || Path(`/connext-sepolia-archive/`)}
|
||||
- traefik.http.routers.connext-sepolia-nitro-archive-leveldb-hash.middlewares=connext-sepolia-nitro-archive-leveldb-hash-stripprefix, ipallowlist
|
||||
|
||||
volumes:
|
||||
connext-sepolia-nitro-archive-leveldb-hash:
|
||||
|
||||
x-upstreams:
|
||||
- id: $${ID}
|
||||
labels:
|
||||
provider: $${PROVIDER}
|
||||
connection:
|
||||
generic:
|
||||
rpc:
|
||||
url: $${RPC_URL}
|
||||
ws:
|
||||
frameSize: 20Mb
|
||||
msgSize: 50Mb
|
||||
url: $${WS_URL}
|
||||
chain: everclear-sepolia
|
||||
method-groups:
|
||||
enabled:
|
||||
- debug
|
||||
- filter
|
||||
methods:
|
||||
disabled:
|
||||
enabled:
|
||||
- name: txpool_content # TODO: should be disabled for rollup nodes
|
||||
# standard geth only
|
||||
- name: debug_getRawBlock
|
||||
- name: debug_getRawTransaction
|
||||
- name: debug_getRawReceipts
|
||||
- name: debug_getRawHeader
|
||||
- name: debug_getBadBlocks
|
||||
# non standard geth only slightly dangerous
|
||||
- name: debug_intermediateRoots
|
||||
- name: debug_dumpBlock
|
||||
# standard geth and erigon
|
||||
- name: debug_accountRange
|
||||
- name: debug_getModifiedAccountsByNumber
|
||||
- name: debug_getModifiedAccountsByHash
|
||||
# non standard geth and erigon
|
||||
- name: eth_getRawTransactionByHash
|
||||
- name: eth_getRawTransactionByBlockHashAndIndex
|
||||
...
|
||||
146
arb/nitro/connext-sepolia-nitro-pruned-pebble-path.yml
Normal file
146
arb/nitro/connext-sepolia-nitro-pruned-pebble-path.yml
Normal file
@@ -0,0 +1,146 @@
|
||||
---
|
||||
x-logging-defaults: &logging-defaults
|
||||
driver: json-file
|
||||
options:
|
||||
max-size: "10m"
|
||||
max-file: "3"
|
||||
|
||||
# Usage:
|
||||
#
|
||||
# mkdir rpc && cd rpc
|
||||
#
|
||||
# git init
|
||||
# git remote add origin https://github.com/StakeSquid/ethereum-rpc-docker.git
|
||||
# git fetch origin vibe
|
||||
# git checkout origin/vibe
|
||||
#
|
||||
# docker run --rm alpine sh -c "printf '0x'; head -c32 /dev/urandom | xxd -p -c 64" > .jwtsecret
|
||||
#
|
||||
# env
|
||||
# ...
|
||||
# IP=$(curl ipinfo.io/ip)
|
||||
# DOMAIN=${IP}.traefik.me
|
||||
# COMPOSE_FILE=base.yml:rpc.yml:arb/nitro/connext-sepolia-nitro-pruned-pebble-path.yml
|
||||
#
|
||||
# docker compose up -d
|
||||
#
|
||||
# curl -X POST https://${IP}.traefik.me/connext-sepolia \
|
||||
# -H "Content-Type: application/json" \
|
||||
# --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'
|
||||
|
||||
services:
|
||||
connext-sepolia:
|
||||
image: ${CONNEXT_NITRO_IMAGE:-offchainlabs/nitro-node}:${CONNEXT_SEPOLIA_NITRO_VERSION:-v3.6.4-28199cd}
|
||||
sysctls:
|
||||
# TCP Performance
|
||||
net.ipv4.tcp_slow_start_after_idle: 0 # Disable slow start after idle
|
||||
net.ipv4.tcp_no_metrics_save: 1 # Disable metrics cache
|
||||
net.ipv4.tcp_rmem: 4096 87380 16777216 # Increase TCP read buffers
|
||||
net.ipv4.tcp_wmem: 4096 87380 16777216 # Increase TCP write buffers
|
||||
net.core.somaxconn: 32768 # Higher connection queue
|
||||
# Memory/Connection Management
|
||||
# net.core.netdev_max_backlog: 50000 # Increase network buffer
|
||||
net.ipv4.tcp_max_syn_backlog: 30000 # More SYN requests
|
||||
net.ipv4.tcp_max_tw_buckets: 2000000 # Allow more TIME_WAIT sockets
|
||||
ulimits:
|
||||
nofile: 1048576 # Max open files (for RPC/WS connections)
|
||||
user: root
|
||||
expose:
|
||||
- 8545
|
||||
command:
|
||||
- --conf.file=/config/baseConfig.json
|
||||
- --execution.caching.archive=false
|
||||
- --execution.caching.state-scheme=path
|
||||
- --execution.forwarding-target=https://rpc.connext-sepolia.gelato.digital
|
||||
- --execution.rpc.gas-cap=600000000
|
||||
- --execution.sequencer.enable=false
|
||||
- --http.addr=0.0.0.0
|
||||
- --http.api=eth,net,web3,arb,txpool,debug
|
||||
- --http.corsdomain=*
|
||||
- --http.port=8545
|
||||
- --http.vhosts=*
|
||||
- --init.download-path=/tmp
|
||||
- --metrics
|
||||
- --metrics-server.addr=0.0.0.0
|
||||
- --metrics-server.port=6070
|
||||
- --node.batch-poster.enable=false
|
||||
- --node.data-availability.enable=true
|
||||
- --node.data-availability.parent-chain-node-url=${ETHEREUM_SEPOLIA_EXECUTION_RPC}
|
||||
- --node.data-availability.rest-aggregator.enable=true
|
||||
- --node.data-availability.rest-aggregator.urls=https://das.connext-sepolia.gelato.digital
|
||||
- --node.data-availability.sequencer-inbox-address=0x727095791318912381473707332248435763608420056676
|
||||
- --node.feed.input.url=wss://feed.connext-sepolia.gelato.digital
|
||||
- --node.sequencer=false
|
||||
- --node.staker.enable=false
|
||||
- --parent-chain.blob-client.beacon-url=${ETHEREUM_SEPOLIA_BEACON_REST}
|
||||
- --parent-chain.connection.url=${ETHEREUM_SEPOLIA_EXECUTION_RPC}
|
||||
- --persistent.chain=/root/.arbitrum/connext-sepolia
|
||||
- --persistent.db-engine=pebble
|
||||
- --ws.addr=0.0.0.0
|
||||
- --ws.origins=*
|
||||
- --ws.port=8545
|
||||
restart: unless-stopped
|
||||
stop_grace_period: 5m
|
||||
networks:
|
||||
- chains
|
||||
volumes:
|
||||
- ${CONNEXT_SEPOLIA_NITRO_PRUNED_PEBBLE_PATH_DATA:-connext-sepolia-nitro-pruned-pebble-path}:/root/.arbitrum
|
||||
- ./arb/connext/sepolia:/config
|
||||
- /slowdisk:/slowdisk
|
||||
logging: *logging-defaults
|
||||
labels:
|
||||
- prometheus-scrape.enabled=true
|
||||
- prometheus-scrape.port=6070
|
||||
- prometheus-scrape.path=/debug/metrics/prometheus
|
||||
- traefik.enable=true
|
||||
- traefik.http.middlewares.connext-sepolia-nitro-pruned-pebble-path-stripprefix.stripprefix.prefixes=/connext-sepolia
|
||||
- traefik.http.services.connext-sepolia-nitro-pruned-pebble-path.loadbalancer.server.port=8545
|
||||
- ${NO_SSL:-traefik.http.routers.connext-sepolia-nitro-pruned-pebble-path.entrypoints=websecure}
|
||||
- ${NO_SSL:-traefik.http.routers.connext-sepolia-nitro-pruned-pebble-path.tls.certresolver=myresolver}
|
||||
- ${NO_SSL:-traefik.http.routers.connext-sepolia-nitro-pruned-pebble-path.rule=Host(`$DOMAIN`) && (Path(`/connext-sepolia`) || Path(`/connext-sepolia/`))}
|
||||
- ${NO_SSL:+traefik.http.routers.connext-sepolia-nitro-pruned-pebble-path.rule=Path(`/connext-sepolia`) || Path(`/connext-sepolia/`)}
|
||||
- traefik.http.routers.connext-sepolia-nitro-pruned-pebble-path.middlewares=connext-sepolia-nitro-pruned-pebble-path-stripprefix, ipallowlist
|
||||
|
||||
volumes:
|
||||
connext-sepolia-nitro-pruned-pebble-path:
|
||||
|
||||
x-upstreams:
|
||||
- id: $${ID}
|
||||
labels:
|
||||
provider: $${PROVIDER}
|
||||
connection:
|
||||
generic:
|
||||
rpc:
|
||||
url: $${RPC_URL}
|
||||
ws:
|
||||
frameSize: 20Mb
|
||||
msgSize: 50Mb
|
||||
url: $${WS_URL}
|
||||
chain: everclear-sepolia
|
||||
method-groups:
|
||||
enabled:
|
||||
- debug
|
||||
- filter
|
||||
methods:
|
||||
disabled:
|
||||
# not compatible with path state scheme
|
||||
- name: debug_traceBlockByHash
|
||||
enabled:
|
||||
- name: txpool_content # TODO: should be disabled for rollup nodes
|
||||
# standard geth only
|
||||
- name: debug_getRawBlock
|
||||
- name: debug_getRawTransaction
|
||||
- name: debug_getRawReceipts
|
||||
- name: debug_getRawHeader
|
||||
- name: debug_getBadBlocks
|
||||
# non standard geth only slightly dangerous
|
||||
- name: debug_intermediateRoots
|
||||
- name: debug_dumpBlock
|
||||
# standard geth and erigon
|
||||
- name: debug_accountRange
|
||||
- name: debug_getModifiedAccountsByNumber
|
||||
- name: debug_getModifiedAccountsByHash
|
||||
# non standard geth and erigon
|
||||
- name: eth_getRawTransactionByHash
|
||||
- name: eth_getRawTransactionByBlockHashAndIndex
|
||||
...
|
||||
142
arb/nitro/everclear-mainnet-nitro-archive-leveldb-hash.yml
Normal file
142
arb/nitro/everclear-mainnet-nitro-archive-leveldb-hash.yml
Normal file
@@ -0,0 +1,142 @@
|
||||
---
|
||||
x-logging-defaults: &logging-defaults
|
||||
driver: json-file
|
||||
options:
|
||||
max-size: "10m"
|
||||
max-file: "3"
|
||||
|
||||
# Usage:
|
||||
#
|
||||
# mkdir rpc && cd rpc
|
||||
#
|
||||
# git init
|
||||
# git remote add origin https://github.com/StakeSquid/ethereum-rpc-docker.git
|
||||
# git fetch origin vibe
|
||||
# git checkout origin/vibe
|
||||
#
|
||||
# docker run --rm alpine sh -c "printf '0x'; head -c32 /dev/urandom | xxd -p -c 64" > .jwtsecret
|
||||
#
|
||||
# env
|
||||
# ...
|
||||
# IP=$(curl ipinfo.io/ip)
|
||||
# DOMAIN=${IP}.traefik.me
|
||||
# COMPOSE_FILE=base.yml:rpc.yml:arb/nitro/everclear-mainnet-nitro-archive-leveldb-hash.yml
|
||||
#
|
||||
# docker compose up -d
|
||||
#
|
||||
# curl -X POST https://${IP}.traefik.me/everclear-mainnet-archive \
|
||||
# -H "Content-Type: application/json" \
|
||||
# --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'
|
||||
|
||||
services:
|
||||
everclear-mainnet-archive:
|
||||
image: ${EVERCLEAR_NITRO_IMAGE:-offchainlabs/nitro-node}:${EVERCLEAR_MAINNET_NITRO_VERSION:-v3.6.4-28199cd}
|
||||
sysctls:
|
||||
# TCP Performance
|
||||
net.ipv4.tcp_slow_start_after_idle: 0 # Disable slow start after idle
|
||||
net.ipv4.tcp_no_metrics_save: 1 # Disable metrics cache
|
||||
net.ipv4.tcp_rmem: 4096 87380 16777216 # Increase TCP read buffers
|
||||
net.ipv4.tcp_wmem: 4096 87380 16777216 # Increase TCP write buffers
|
||||
net.core.somaxconn: 32768 # Higher connection queue
|
||||
# Memory/Connection Management
|
||||
# net.core.netdev_max_backlog: 50000 # Increase network buffer
|
||||
net.ipv4.tcp_max_syn_backlog: 30000 # More SYN requests
|
||||
net.ipv4.tcp_max_tw_buckets: 2000000 # Allow more TIME_WAIT sockets
|
||||
ulimits:
|
||||
nofile: 1048576 # Max open files (for RPC/WS connections)
|
||||
user: root
|
||||
expose:
|
||||
- 8545
|
||||
command:
|
||||
- --conf.file=/config/baseConfig.json
|
||||
- --execution.caching.archive=true
|
||||
- --execution.forwarding-target=https://rpc.everclear.raas.gelato.cloud
|
||||
- --execution.rpc.gas-cap=600000000
|
||||
- --execution.sequencer.enable=false
|
||||
- --http.addr=0.0.0.0
|
||||
- --http.api=eth,net,web3,arb,txpool,debug
|
||||
- --http.corsdomain=*
|
||||
- --http.port=8545
|
||||
- --http.vhosts=*
|
||||
- --init.download-path=/tmp
|
||||
- --metrics
|
||||
- --metrics-server.addr=0.0.0.0
|
||||
- --metrics-server.port=6070
|
||||
- --node.batch-poster.enable=false
|
||||
- --node.data-availability.enable=true
|
||||
- --node.data-availability.parent-chain-node-url=${ETHEREUM_MAINNET_EXECUTION_RPC}
|
||||
- --node.data-availability.rest-aggregator.enable=true
|
||||
- --node.data-availability.rest-aggregator.urls=https://das.everclear.raas.gelato.cloud
|
||||
- --node.data-availability.sequencer-inbox-address=0x727095791318912381473707332248435763608420056676
|
||||
- --node.feed.input.url=wss://feed.everclear.raas.gelato.cloud
|
||||
- --node.sequencer=false
|
||||
- --node.staker.enable=false
|
||||
- --parent-chain.blob-client.beacon-url=${ETHEREUM_MAINNET_BEACON_REST}
|
||||
- --parent-chain.connection.url=${ETHEREUM_MAINNET_EXECUTION_RPC}
|
||||
- --persistent.chain=/root/.arbitrum/everclear-mainnet-archive
|
||||
- --ws.addr=0.0.0.0
|
||||
- --ws.origins=*
|
||||
- --ws.port=8545
|
||||
restart: unless-stopped
|
||||
stop_grace_period: 5m
|
||||
networks:
|
||||
- chains
|
||||
volumes:
|
||||
- ${EVERCLEAR_MAINNET_NITRO_ARCHIVE_LEVELDB_HASH_DATA:-everclear-mainnet-nitro-archive-leveldb-hash}:/root/.arbitrum
|
||||
- ./arb/everclear/mainnet:/config
|
||||
- /slowdisk:/slowdisk
|
||||
logging: *logging-defaults
|
||||
labels:
|
||||
- prometheus-scrape.enabled=true
|
||||
- prometheus-scrape.port=6070
|
||||
- prometheus-scrape.path=/debug/metrics/prometheus
|
||||
- traefik.enable=true
|
||||
- traefik.http.middlewares.everclear-mainnet-nitro-archive-leveldb-hash-stripprefix.stripprefix.prefixes=/everclear-mainnet-archive
|
||||
- traefik.http.services.everclear-mainnet-nitro-archive-leveldb-hash.loadbalancer.server.port=8545
|
||||
- ${NO_SSL:-traefik.http.routers.everclear-mainnet-nitro-archive-leveldb-hash.entrypoints=websecure}
|
||||
- ${NO_SSL:-traefik.http.routers.everclear-mainnet-nitro-archive-leveldb-hash.tls.certresolver=myresolver}
|
||||
- ${NO_SSL:-traefik.http.routers.everclear-mainnet-nitro-archive-leveldb-hash.rule=Host(`$DOMAIN`) && (Path(`/everclear-mainnet-archive`) || Path(`/everclear-mainnet-archive/`))}
|
||||
- ${NO_SSL:+traefik.http.routers.everclear-mainnet-nitro-archive-leveldb-hash.rule=Path(`/everclear-mainnet-archive`) || Path(`/everclear-mainnet-archive/`)}
|
||||
- traefik.http.routers.everclear-mainnet-nitro-archive-leveldb-hash.middlewares=everclear-mainnet-nitro-archive-leveldb-hash-stripprefix, ipallowlist
|
||||
|
||||
volumes:
|
||||
everclear-mainnet-nitro-archive-leveldb-hash:
|
||||
|
||||
x-upstreams:
|
||||
- id: $${ID}
|
||||
labels:
|
||||
provider: $${PROVIDER}
|
||||
connection:
|
||||
generic:
|
||||
rpc:
|
||||
url: $${RPC_URL}
|
||||
ws:
|
||||
frameSize: 20Mb
|
||||
msgSize: 50Mb
|
||||
url: $${WS_URL}
|
||||
chain: everclear
|
||||
method-groups:
|
||||
enabled:
|
||||
- debug
|
||||
- filter
|
||||
methods:
|
||||
disabled:
|
||||
enabled:
|
||||
- name: txpool_content # TODO: should be disabled for rollup nodes
|
||||
# standard geth only
|
||||
- name: debug_getRawBlock
|
||||
- name: debug_getRawTransaction
|
||||
- name: debug_getRawReceipts
|
||||
- name: debug_getRawHeader
|
||||
- name: debug_getBadBlocks
|
||||
# non standard geth only slightly dangerous
|
||||
- name: debug_intermediateRoots
|
||||
- name: debug_dumpBlock
|
||||
# standard geth and erigon
|
||||
- name: debug_accountRange
|
||||
- name: debug_getModifiedAccountsByNumber
|
||||
- name: debug_getModifiedAccountsByHash
|
||||
# non standard geth and erigon
|
||||
- name: eth_getRawTransactionByHash
|
||||
- name: eth_getRawTransactionByBlockHashAndIndex
|
||||
...
|
||||
146
arb/nitro/everclear-mainnet-nitro-pruned-pebble-path.yml
Normal file
146
arb/nitro/everclear-mainnet-nitro-pruned-pebble-path.yml
Normal file
@@ -0,0 +1,146 @@
|
||||
---
|
||||
x-logging-defaults: &logging-defaults
|
||||
driver: json-file
|
||||
options:
|
||||
max-size: "10m"
|
||||
max-file: "3"
|
||||
|
||||
# Usage:
|
||||
#
|
||||
# mkdir rpc && cd rpc
|
||||
#
|
||||
# git init
|
||||
# git remote add origin https://github.com/StakeSquid/ethereum-rpc-docker.git
|
||||
# git fetch origin vibe
|
||||
# git checkout origin/vibe
|
||||
#
|
||||
# docker run --rm alpine sh -c "printf '0x'; head -c32 /dev/urandom | xxd -p -c 64" > .jwtsecret
|
||||
#
|
||||
# env
|
||||
# ...
|
||||
# IP=$(curl ipinfo.io/ip)
|
||||
# DOMAIN=${IP}.traefik.me
|
||||
# COMPOSE_FILE=base.yml:rpc.yml:arb/nitro/everclear-mainnet-nitro-pruned-pebble-path.yml
|
||||
#
|
||||
# docker compose up -d
|
||||
#
|
||||
# curl -X POST https://${IP}.traefik.me/everclear-mainnet \
|
||||
# -H "Content-Type: application/json" \
|
||||
# --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'
|
||||
|
||||
services:
|
||||
everclear-mainnet:
|
||||
image: ${EVERCLEAR_NITRO_IMAGE:-offchainlabs/nitro-node}:${EVERCLEAR_MAINNET_NITRO_VERSION:-v3.6.4-28199cd}
|
||||
sysctls:
|
||||
# TCP Performance
|
||||
net.ipv4.tcp_slow_start_after_idle: 0 # Disable slow start after idle
|
||||
net.ipv4.tcp_no_metrics_save: 1 # Disable metrics cache
|
||||
net.ipv4.tcp_rmem: 4096 87380 16777216 # Increase TCP read buffers
|
||||
net.ipv4.tcp_wmem: 4096 87380 16777216 # Increase TCP write buffers
|
||||
net.core.somaxconn: 32768 # Higher connection queue
|
||||
# Memory/Connection Management
|
||||
# net.core.netdev_max_backlog: 50000 # Increase network buffer
|
||||
net.ipv4.tcp_max_syn_backlog: 30000 # More SYN requests
|
||||
net.ipv4.tcp_max_tw_buckets: 2000000 # Allow more TIME_WAIT sockets
|
||||
ulimits:
|
||||
nofile: 1048576 # Max open files (for RPC/WS connections)
|
||||
user: root
|
||||
expose:
|
||||
- 8545
|
||||
command:
|
||||
- --conf.file=/config/baseConfig.json
|
||||
- --execution.caching.archive=false
|
||||
- --execution.caching.state-scheme=path
|
||||
- --execution.forwarding-target=https://rpc.everclear.raas.gelato.cloud
|
||||
- --execution.rpc.gas-cap=600000000
|
||||
- --execution.sequencer.enable=false
|
||||
- --http.addr=0.0.0.0
|
||||
- --http.api=eth,net,web3,arb,txpool,debug
|
||||
- --http.corsdomain=*
|
||||
- --http.port=8545
|
||||
- --http.vhosts=*
|
||||
- --init.download-path=/tmp
|
||||
- --metrics
|
||||
- --metrics-server.addr=0.0.0.0
|
||||
- --metrics-server.port=6070
|
||||
- --node.batch-poster.enable=false
|
||||
- --node.data-availability.enable=true
|
||||
- --node.data-availability.parent-chain-node-url=${ETHEREUM_MAINNET_EXECUTION_RPC}
|
||||
- --node.data-availability.rest-aggregator.enable=true
|
||||
- --node.data-availability.rest-aggregator.urls=https://das.everclear.raas.gelato.cloud
|
||||
- --node.data-availability.sequencer-inbox-address=0x727095791318912381473707332248435763608420056676
|
||||
- --node.feed.input.url=wss://feed.everclear.raas.gelato.cloud
|
||||
- --node.sequencer=false
|
||||
- --node.staker.enable=false
|
||||
- --parent-chain.blob-client.beacon-url=${ETHEREUM_MAINNET_BEACON_REST}
|
||||
- --parent-chain.connection.url=${ETHEREUM_MAINNET_EXECUTION_RPC}
|
||||
- --persistent.chain=/root/.arbitrum/everclear-mainnet
|
||||
- --persistent.db-engine=pebble
|
||||
- --ws.addr=0.0.0.0
|
||||
- --ws.origins=*
|
||||
- --ws.port=8545
|
||||
restart: unless-stopped
|
||||
stop_grace_period: 5m
|
||||
networks:
|
||||
- chains
|
||||
volumes:
|
||||
- ${EVERCLEAR_MAINNET_NITRO_PRUNED_PEBBLE_PATH_DATA:-everclear-mainnet-nitro-pruned-pebble-path}:/root/.arbitrum
|
||||
- ./arb/everclear/mainnet:/config
|
||||
- /slowdisk:/slowdisk
|
||||
logging: *logging-defaults
|
||||
labels:
|
||||
- prometheus-scrape.enabled=true
|
||||
- prometheus-scrape.port=6070
|
||||
- prometheus-scrape.path=/debug/metrics/prometheus
|
||||
- traefik.enable=true
|
||||
- traefik.http.middlewares.everclear-mainnet-nitro-pruned-pebble-path-stripprefix.stripprefix.prefixes=/everclear-mainnet
|
||||
- traefik.http.services.everclear-mainnet-nitro-pruned-pebble-path.loadbalancer.server.port=8545
|
||||
- ${NO_SSL:-traefik.http.routers.everclear-mainnet-nitro-pruned-pebble-path.entrypoints=websecure}
|
||||
- ${NO_SSL:-traefik.http.routers.everclear-mainnet-nitro-pruned-pebble-path.tls.certresolver=myresolver}
|
||||
- ${NO_SSL:-traefik.http.routers.everclear-mainnet-nitro-pruned-pebble-path.rule=Host(`$DOMAIN`) && (Path(`/everclear-mainnet`) || Path(`/everclear-mainnet/`))}
|
||||
- ${NO_SSL:+traefik.http.routers.everclear-mainnet-nitro-pruned-pebble-path.rule=Path(`/everclear-mainnet`) || Path(`/everclear-mainnet/`)}
|
||||
- traefik.http.routers.everclear-mainnet-nitro-pruned-pebble-path.middlewares=everclear-mainnet-nitro-pruned-pebble-path-stripprefix, ipallowlist
|
||||
|
||||
volumes:
|
||||
everclear-mainnet-nitro-pruned-pebble-path:
|
||||
|
||||
x-upstreams:
|
||||
- id: $${ID}
|
||||
labels:
|
||||
provider: $${PROVIDER}
|
||||
connection:
|
||||
generic:
|
||||
rpc:
|
||||
url: $${RPC_URL}
|
||||
ws:
|
||||
frameSize: 20Mb
|
||||
msgSize: 50Mb
|
||||
url: $${WS_URL}
|
||||
chain: everclear
|
||||
method-groups:
|
||||
enabled:
|
||||
- debug
|
||||
- filter
|
||||
methods:
|
||||
disabled:
|
||||
# not compatible with path state scheme
|
||||
- name: debug_traceBlockByHash
|
||||
enabled:
|
||||
- name: txpool_content # TODO: should be disabled for rollup nodes
|
||||
# standard geth only
|
||||
- name: debug_getRawBlock
|
||||
- name: debug_getRawTransaction
|
||||
- name: debug_getRawReceipts
|
||||
- name: debug_getRawHeader
|
||||
- name: debug_getBadBlocks
|
||||
# non standard geth only slightly dangerous
|
||||
- name: debug_intermediateRoots
|
||||
- name: debug_dumpBlock
|
||||
# standard geth and erigon
|
||||
- name: debug_accountRange
|
||||
- name: debug_getModifiedAccountsByNumber
|
||||
- name: debug_getModifiedAccountsByHash
|
||||
# non standard geth and erigon
|
||||
- name: eth_getRawTransactionByHash
|
||||
- name: eth_getRawTransactionByBlockHashAndIndex
|
||||
...
|
||||
141
arb/nitro/opencampuscodex-sepolia-nitro-archive-leveldb-hash.yml
Normal file
141
arb/nitro/opencampuscodex-sepolia-nitro-archive-leveldb-hash.yml
Normal file
@@ -0,0 +1,141 @@
|
||||
---
|
||||
x-logging-defaults: &logging-defaults
|
||||
driver: json-file
|
||||
options:
|
||||
max-size: "10m"
|
||||
max-file: "3"
|
||||
|
||||
# Usage:
|
||||
#
|
||||
# mkdir rpc && cd rpc
|
||||
#
|
||||
# git init
|
||||
# git remote add origin https://github.com/StakeSquid/ethereum-rpc-docker.git
|
||||
# git fetch origin vibe
|
||||
# git checkout origin/vibe
|
||||
#
|
||||
# docker run --rm alpine sh -c "printf '0x'; head -c32 /dev/urandom | xxd -p -c 64" > .jwtsecret
|
||||
#
|
||||
# env
|
||||
# ...
|
||||
# IP=$(curl ipinfo.io/ip)
|
||||
# DOMAIN=${IP}.traefik.me
|
||||
# COMPOSE_FILE=base.yml:rpc.yml:arb/nitro/opencampuscodex-sepolia-nitro-archive-leveldb-hash.yml
|
||||
#
|
||||
# docker compose up -d
|
||||
#
|
||||
# curl -X POST https://${IP}.traefik.me/opencampuscodex-sepolia-archive \
|
||||
# -H "Content-Type: application/json" \
|
||||
# --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'
|
||||
|
||||
services:
|
||||
opencampuscodex-sepolia-archive:
|
||||
image: ${OPENCAMPUSCODEX_NITRO_IMAGE:-offchainlabs/nitro-node}:${OPENCAMPUSCODEX_SEPOLIA_NITRO_VERSION:-v3.6.4-28199cd}
|
||||
sysctls:
|
||||
# TCP Performance
|
||||
net.ipv4.tcp_slow_start_after_idle: 0 # Disable slow start after idle
|
||||
net.ipv4.tcp_no_metrics_save: 1 # Disable metrics cache
|
||||
net.ipv4.tcp_rmem: 4096 87380 16777216 # Increase TCP read buffers
|
||||
net.ipv4.tcp_wmem: 4096 87380 16777216 # Increase TCP write buffers
|
||||
net.core.somaxconn: 32768 # Higher connection queue
|
||||
# Memory/Connection Management
|
||||
# net.core.netdev_max_backlog: 50000 # Increase network buffer
|
||||
net.ipv4.tcp_max_syn_backlog: 30000 # More SYN requests
|
||||
net.ipv4.tcp_max_tw_buckets: 2000000 # Allow more TIME_WAIT sockets
|
||||
ulimits:
|
||||
nofile: 1048576 # Max open files (for RPC/WS connections)
|
||||
user: root
|
||||
expose:
|
||||
- 8545
|
||||
command:
|
||||
- --conf.file=/config/baseConfig.json
|
||||
- --execution.caching.archive=true
|
||||
- --execution.forwarding-target=https://rpc.open-campus-codex.gelato.digital
|
||||
- --execution.rpc.gas-cap=600000000
|
||||
- --execution.sequencer.enable=false
|
||||
- --http.addr=0.0.0.0
|
||||
- --http.api=eth,net,web3,arb,txpool,debug
|
||||
- --http.corsdomain=*
|
||||
- --http.port=8545
|
||||
- --http.vhosts=*
|
||||
- --init.download-path=/tmp
|
||||
- --metrics
|
||||
- --metrics-server.addr=0.0.0.0
|
||||
- --metrics-server.port=6070
|
||||
- --node.batch-poster.enable=false
|
||||
- --node.data-availability.enable=true
|
||||
- --node.data-availability.parent-chain-node-url=${ARBITRUM_SEPOLIA_EXECUTION_RPC}
|
||||
- --node.data-availability.rest-aggregator.enable=true
|
||||
- --node.data-availability.rest-aggregator.urls=https://das.open-campus-codex.gelato.digital
|
||||
- --node.data-availability.sequencer-inbox-address=0xe347C1223381b9Dcd6c0F61cf81c90175A7Bae77
|
||||
- --node.feed.input.url=wss://feed.open-campus-codex.gelato.digital
|
||||
- --node.sequencer=false
|
||||
- --node.staker.enable=false
|
||||
- --parent-chain.connection.url=${ARBITRUM_SEPOLIA_EXECUTION_RPC}
|
||||
- --persistent.chain=/root/.arbitrum/opencampuscodex-sepolia-archive
|
||||
- --ws.addr=0.0.0.0
|
||||
- --ws.origins=*
|
||||
- --ws.port=8545
|
||||
restart: unless-stopped
|
||||
stop_grace_period: 5m
|
||||
networks:
|
||||
- chains
|
||||
volumes:
|
||||
- ${OPENCAMPUSCODEX_SEPOLIA_NITRO_ARCHIVE_LEVELDB_HASH_DATA:-opencampuscodex-sepolia-nitro-archive-leveldb-hash}:/root/.arbitrum
|
||||
- ./arb/opencampuscodex/arbitrum-sepolia:/config
|
||||
- /slowdisk:/slowdisk
|
||||
logging: *logging-defaults
|
||||
labels:
|
||||
- prometheus-scrape.enabled=true
|
||||
- prometheus-scrape.port=6070
|
||||
- prometheus-scrape.path=/debug/metrics/prometheus
|
||||
- traefik.enable=true
|
||||
- traefik.http.middlewares.opencampuscodex-sepolia-nitro-archive-leveldb-hash-stripprefix.stripprefix.prefixes=/opencampuscodex-sepolia-archive
|
||||
- traefik.http.services.opencampuscodex-sepolia-nitro-archive-leveldb-hash.loadbalancer.server.port=8545
|
||||
- ${NO_SSL:-traefik.http.routers.opencampuscodex-sepolia-nitro-archive-leveldb-hash.entrypoints=websecure}
|
||||
- ${NO_SSL:-traefik.http.routers.opencampuscodex-sepolia-nitro-archive-leveldb-hash.tls.certresolver=myresolver}
|
||||
- ${NO_SSL:-traefik.http.routers.opencampuscodex-sepolia-nitro-archive-leveldb-hash.rule=Host(`$DOMAIN`) && (Path(`/opencampuscodex-sepolia-archive`) || Path(`/opencampuscodex-sepolia-archive/`))}
|
||||
- ${NO_SSL:+traefik.http.routers.opencampuscodex-sepolia-nitro-archive-leveldb-hash.rule=Path(`/opencampuscodex-sepolia-archive`) || Path(`/opencampuscodex-sepolia-archive/`)}
|
||||
- traefik.http.routers.opencampuscodex-sepolia-nitro-archive-leveldb-hash.middlewares=opencampuscodex-sepolia-nitro-archive-leveldb-hash-stripprefix, ipallowlist
|
||||
|
||||
volumes:
|
||||
opencampuscodex-sepolia-nitro-archive-leveldb-hash:
|
||||
|
||||
x-upstreams:
|
||||
- id: $${ID}
|
||||
labels:
|
||||
provider: $${PROVIDER}
|
||||
connection:
|
||||
generic:
|
||||
rpc:
|
||||
url: $${RPC_URL}
|
||||
ws:
|
||||
frameSize: 20Mb
|
||||
msgSize: 50Mb
|
||||
url: $${WS_URL}
|
||||
chain: open-campus-codex-sepolia
|
||||
method-groups:
|
||||
enabled:
|
||||
- debug
|
||||
- filter
|
||||
methods:
|
||||
disabled:
|
||||
enabled:
|
||||
- name: txpool_content # TODO: should be disabled for rollup nodes
|
||||
# standard geth only
|
||||
- name: debug_getRawBlock
|
||||
- name: debug_getRawTransaction
|
||||
- name: debug_getRawReceipts
|
||||
- name: debug_getRawHeader
|
||||
- name: debug_getBadBlocks
|
||||
# non standard geth only slightly dangerous
|
||||
- name: debug_intermediateRoots
|
||||
- name: debug_dumpBlock
|
||||
# standard geth and erigon
|
||||
- name: debug_accountRange
|
||||
- name: debug_getModifiedAccountsByNumber
|
||||
- name: debug_getModifiedAccountsByHash
|
||||
# non standard geth and erigon
|
||||
- name: eth_getRawTransactionByHash
|
||||
- name: eth_getRawTransactionByBlockHashAndIndex
|
||||
...
|
||||
120
arb/nitro/opencampuscodex-sepolia-nitro-pruned-pebble-hash.yml
Normal file
120
arb/nitro/opencampuscodex-sepolia-nitro-pruned-pebble-hash.yml
Normal file
@@ -0,0 +1,120 @@
|
||||
# use at your own risk
|
||||
|
||||
services:
|
||||
opencampuscodex-sepolia:
|
||||
image: ${OPENCAMPUSCODEX_NITRO_IMAGE:-offchainlabs/nitro-node}:${OPENCAMPUSCODEX_SEPOLIA_NITRO_VERSION:-v3.5.3-0a9c975}
|
||||
user: root
|
||||
ulimits:
|
||||
nofile: 1048576 # Max open files (for RPC/WS connections)
|
||||
sysctls:
|
||||
# TCP Performance
|
||||
net.ipv4.tcp_slow_start_after_idle: 0 # Disable slow start after idle
|
||||
net.ipv4.tcp_no_metrics_save: 1 # Disable metrics cache
|
||||
net.ipv4.tcp_rmem: 4096 87380 16777216 # Increase TCP read buffers
|
||||
net.ipv4.tcp_wmem: 4096 87380 16777216 # Increase TCP write buffers
|
||||
net.core.somaxconn: 32768 # Higher connection queue
|
||||
# Memory/Connection Management
|
||||
net.core.netdev_max_backlog: 50000 # Increase network buffer
|
||||
net.ipv4.tcp_max_syn_backlog: 30000 # More SYN requests
|
||||
net.ipv4.tcp_max_tw_buckets: 2000000 # Allow more TIME_WAIT sockets
|
||||
expose:
|
||||
- 8545
|
||||
- 8551
|
||||
|
||||
ports:
|
||||
- 10938:10938
|
||||
- 10938:10938/udp
|
||||
volumes:
|
||||
- ${OPENCAMPUSCODEX_SEPOLIA_NITRO_PRUNED_PEBBLE_HASH_DATA:-opencampuscodex-sepolia-nitro-pruned-pebble-hash}:/root/.arbitrum
|
||||
- /slowdisk:/slowdisk
|
||||
|
||||
- .jwtsecret:/jwtsecret:ro
|
||||
|
||||
- ./tmp/opencampuscodex-sepolia:/tmp
|
||||
|
||||
command:
|
||||
- --datadir=/root/.arbitrum
|
||||
- --port=10938
|
||||
- --bind=0.0.0.0
|
||||
- --nat=extip:${IP}
|
||||
- --http
|
||||
- --http.port=8545
|
||||
- --http.vhosts=*
|
||||
- --ws
|
||||
- --ws.port=8545
|
||||
- --ws.origins=*
|
||||
- --ws.addr=0.0.0.0
|
||||
- --http.addr=0.0.0.0
|
||||
- --maxpeers=50
|
||||
- --http.api=eth,net,web3,arb,txpool,debug
|
||||
- --ws.api=eth,net,web3,arb,txpool,debug
|
||||
|
||||
- --rpc.gascap=600000000
|
||||
- --rpc.returndatalimit=10000000
|
||||
- --rpc.txfeecap=0
|
||||
|
||||
- --execution.caching.state-scheme=hash
|
||||
- --execution.rpc.gas-cap=600000000
|
||||
- --execution.caching.archive=false
|
||||
- --execution.sequencer.enable=false
|
||||
- --persistent.db-engine=pebble
|
||||
- --persistent.chain=/root/.arbitrum/opencampuscodex-sepolia
|
||||
|
||||
- --conf.file=/config/baseConfig.json
|
||||
|
||||
- --node.sequencer=false
|
||||
- --node.staker.enable=false
|
||||
- --node.batch-poster.enable=false
|
||||
- --node.data-availability.enable=true
|
||||
- --node.data-availability.sequencer-inbox-address=0xe347C1223381b9Dcd6c0F61cf81c90175A7Bae77
|
||||
- --node.data-availability.parent-chain-node-url=${ARBITRUM_SEPOLIA_EXECUTION_RPC}
|
||||
- --node.data-availability.rest-aggregator.enable=true
|
||||
- --node.data-availability.rest-aggregator.urls=https://das.open-campus-codex.gelato.digital
|
||||
|
||||
- --node.feed.input.url=wss://feed.open-campus-codex.gelato.digital
|
||||
- --execution.forwarding-target=https://rpc.open-campus-codex.gelato.digital
|
||||
- --parent-chain.connection.url=${ARBITRUM_SEPOLIA_EXECUTION_RPC}
|
||||
|
||||
networks:
|
||||
- chains
|
||||
restart: unless-stopped
|
||||
stop_grace_period: 5m
|
||||
labels:
|
||||
- traefik.enable=true
|
||||
- traefik.http.middlewares.opencampuscodex-sepolia-nitro-pruned-pebble-hash-stripprefix.stripprefix.prefixes=/opencampuscodex-sepolia
|
||||
- traefik.http.services.opencampuscodex-sepolia-nitro-pruned-pebble-hash.loadbalancer.server.port=8545
|
||||
- ${NO_SSL:-traefik.http.routers.opencampuscodex-sepolia-nitro-pruned-pebble-hash.entrypoints=websecure}
|
||||
- ${NO_SSL:-traefik.http.routers.opencampuscodex-sepolia-nitro-pruned-pebble-hash.tls.certresolver=myresolver}
|
||||
- ${NO_SSL:-traefik.http.routers.opencampuscodex-sepolia-nitro-pruned-pebble-hash.rule=Host(`$DOMAIN`) && PathPrefix(`/opencampuscodex-sepolia`)}
|
||||
- ${NO_SSL:+traefik.http.routers.opencampuscodex-sepolia-nitro-pruned-pebble-hash.rule=PathPrefix(`/opencampuscodex-sepolia`)}
|
||||
- traefik.http.routers.opencampuscodex-sepolia-nitro-pruned-pebble-hash.middlewares=opencampuscodex-sepolia-nitro-pruned-pebble-hash-stripprefix, ipwhitelist
|
||||
|
||||
volumes:
|
||||
opencampuscodex-sepolia-nitro-pruned-pebble-hash:
|
||||
|
||||
x-upstreams:
|
||||
- chain: open-campus-codex-sepolia
|
||||
method-groups:
|
||||
enabled:
|
||||
- debug
|
||||
- filter
|
||||
|
||||
methods:
|
||||
disabled:
|
||||
enabled:
|
||||
# standard geth only
|
||||
- name: debug_getRawBlock
|
||||
- name: debug_getRawTransaction
|
||||
- name: debug_getRawReceipts
|
||||
- name: debug_getRawHeader
|
||||
- name: debug_getBadBlocks
|
||||
# non standard geth only slightly dangerous
|
||||
- name: debug_intermediateRoots
|
||||
- name: debug_dumpBlock
|
||||
# standard geth and erigon
|
||||
- name: debug_accountRange
|
||||
- name: debug_getModifiedAccountsByNumber
|
||||
- name: debug_getModifiedAccountsByHash
|
||||
# non standard geth and erigon
|
||||
- name: eth_getRawTransactionByHash
|
||||
- name: eth_getRawTransactionByBlockHashAndIndex
|
||||
145
arb/nitro/opencampuscodex-sepolia-nitro-pruned-pebble-path.yml
Normal file
145
arb/nitro/opencampuscodex-sepolia-nitro-pruned-pebble-path.yml
Normal file
@@ -0,0 +1,145 @@
|
||||
---
|
||||
x-logging-defaults: &logging-defaults
|
||||
driver: json-file
|
||||
options:
|
||||
max-size: "10m"
|
||||
max-file: "3"
|
||||
|
||||
# Usage:
|
||||
#
|
||||
# mkdir rpc && cd rpc
|
||||
#
|
||||
# git init
|
||||
# git remote add origin https://github.com/StakeSquid/ethereum-rpc-docker.git
|
||||
# git fetch origin vibe
|
||||
# git checkout origin/vibe
|
||||
#
|
||||
# docker run --rm alpine sh -c "printf '0x'; head -c32 /dev/urandom | xxd -p -c 64" > .jwtsecret
|
||||
#
|
||||
# env
|
||||
# ...
|
||||
# IP=$(curl ipinfo.io/ip)
|
||||
# DOMAIN=${IP}.traefik.me
|
||||
# COMPOSE_FILE=base.yml:rpc.yml:arb/nitro/opencampuscodex-sepolia-nitro-pruned-pebble-path.yml
|
||||
#
|
||||
# docker compose up -d
|
||||
#
|
||||
# curl -X POST https://${IP}.traefik.me/opencampuscodex-sepolia \
|
||||
# -H "Content-Type: application/json" \
|
||||
# --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'
|
||||
|
||||
services:
|
||||
opencampuscodex-sepolia:
|
||||
image: ${OPENCAMPUSCODEX_NITRO_IMAGE:-offchainlabs/nitro-node}:${OPENCAMPUSCODEX_SEPOLIA_NITRO_VERSION:-v3.6.4-28199cd}
|
||||
sysctls:
|
||||
# TCP Performance
|
||||
net.ipv4.tcp_slow_start_after_idle: 0 # Disable slow start after idle
|
||||
net.ipv4.tcp_no_metrics_save: 1 # Disable metrics cache
|
||||
net.ipv4.tcp_rmem: 4096 87380 16777216 # Increase TCP read buffers
|
||||
net.ipv4.tcp_wmem: 4096 87380 16777216 # Increase TCP write buffers
|
||||
net.core.somaxconn: 32768 # Higher connection queue
|
||||
# Memory/Connection Management
|
||||
# net.core.netdev_max_backlog: 50000 # Increase network buffer
|
||||
net.ipv4.tcp_max_syn_backlog: 30000 # More SYN requests
|
||||
net.ipv4.tcp_max_tw_buckets: 2000000 # Allow more TIME_WAIT sockets
|
||||
ulimits:
|
||||
nofile: 1048576 # Max open files (for RPC/WS connections)
|
||||
user: root
|
||||
expose:
|
||||
- 8545
|
||||
command:
|
||||
- --conf.file=/config/baseConfig.json
|
||||
- --execution.caching.archive=false
|
||||
- --execution.caching.state-scheme=path
|
||||
- --execution.forwarding-target=https://rpc.open-campus-codex.gelato.digital
|
||||
- --execution.rpc.gas-cap=600000000
|
||||
- --execution.sequencer.enable=false
|
||||
- --http.addr=0.0.0.0
|
||||
- --http.api=eth,net,web3,arb,txpool,debug
|
||||
- --http.corsdomain=*
|
||||
- --http.port=8545
|
||||
- --http.vhosts=*
|
||||
- --init.download-path=/tmp
|
||||
- --metrics
|
||||
- --metrics-server.addr=0.0.0.0
|
||||
- --metrics-server.port=6070
|
||||
- --node.batch-poster.enable=false
|
||||
- --node.data-availability.enable=true
|
||||
- --node.data-availability.parent-chain-node-url=${ARBITRUM_SEPOLIA_EXECUTION_RPC}
|
||||
- --node.data-availability.rest-aggregator.enable=true
|
||||
- --node.data-availability.rest-aggregator.urls=https://das.open-campus-codex.gelato.digital
|
||||
- --node.data-availability.sequencer-inbox-address=0xe347C1223381b9Dcd6c0F61cf81c90175A7Bae77
|
||||
- --node.feed.input.url=wss://feed.open-campus-codex.gelato.digital
|
||||
- --node.sequencer=false
|
||||
- --node.staker.enable=false
|
||||
- --parent-chain.connection.url=${ARBITRUM_SEPOLIA_EXECUTION_RPC}
|
||||
- --persistent.chain=/root/.arbitrum/opencampuscodex-sepolia
|
||||
- --persistent.db-engine=pebble
|
||||
- --ws.addr=0.0.0.0
|
||||
- --ws.origins=*
|
||||
- --ws.port=8545
|
||||
restart: unless-stopped
|
||||
stop_grace_period: 5m
|
||||
networks:
|
||||
- chains
|
||||
volumes:
|
||||
- ${OPENCAMPUSCODEX_SEPOLIA_NITRO_PRUNED_PEBBLE_PATH_DATA:-opencampuscodex-sepolia-nitro-pruned-pebble-path}:/root/.arbitrum
|
||||
- ./arb/opencampuscodex/arbitrum-sepolia:/config
|
||||
- /slowdisk:/slowdisk
|
||||
logging: *logging-defaults
|
||||
labels:
|
||||
- prometheus-scrape.enabled=true
|
||||
- prometheus-scrape.port=6070
|
||||
- prometheus-scrape.path=/debug/metrics/prometheus
|
||||
- traefik.enable=true
|
||||
- traefik.http.middlewares.opencampuscodex-sepolia-nitro-pruned-pebble-path-stripprefix.stripprefix.prefixes=/opencampuscodex-sepolia
|
||||
- traefik.http.services.opencampuscodex-sepolia-nitro-pruned-pebble-path.loadbalancer.server.port=8545
|
||||
- ${NO_SSL:-traefik.http.routers.opencampuscodex-sepolia-nitro-pruned-pebble-path.entrypoints=websecure}
|
||||
- ${NO_SSL:-traefik.http.routers.opencampuscodex-sepolia-nitro-pruned-pebble-path.tls.certresolver=myresolver}
|
||||
- ${NO_SSL:-traefik.http.routers.opencampuscodex-sepolia-nitro-pruned-pebble-path.rule=Host(`$DOMAIN`) && (Path(`/opencampuscodex-sepolia`) || Path(`/opencampuscodex-sepolia/`))}
|
||||
- ${NO_SSL:+traefik.http.routers.opencampuscodex-sepolia-nitro-pruned-pebble-path.rule=Path(`/opencampuscodex-sepolia`) || Path(`/opencampuscodex-sepolia/`)}
|
||||
- traefik.http.routers.opencampuscodex-sepolia-nitro-pruned-pebble-path.middlewares=opencampuscodex-sepolia-nitro-pruned-pebble-path-stripprefix, ipallowlist
|
||||
|
||||
volumes:
|
||||
opencampuscodex-sepolia-nitro-pruned-pebble-path:
|
||||
|
||||
x-upstreams:
|
||||
- id: $${ID}
|
||||
labels:
|
||||
provider: $${PROVIDER}
|
||||
connection:
|
||||
generic:
|
||||
rpc:
|
||||
url: $${RPC_URL}
|
||||
ws:
|
||||
frameSize: 20Mb
|
||||
msgSize: 50Mb
|
||||
url: $${WS_URL}
|
||||
chain: open-campus-codex-sepolia
|
||||
method-groups:
|
||||
enabled:
|
||||
- debug
|
||||
- filter
|
||||
methods:
|
||||
disabled:
|
||||
# not compatible with path state scheme
|
||||
- name: debug_traceBlockByHash
|
||||
enabled:
|
||||
- name: txpool_content # TODO: should be disabled for rollup nodes
|
||||
# standard geth only
|
||||
- name: debug_getRawBlock
|
||||
- name: debug_getRawTransaction
|
||||
- name: debug_getRawReceipts
|
||||
- name: debug_getRawHeader
|
||||
- name: debug_getBadBlocks
|
||||
# non standard geth only slightly dangerous
|
||||
- name: debug_intermediateRoots
|
||||
- name: debug_dumpBlock
|
||||
# standard geth and erigon
|
||||
- name: debug_accountRange
|
||||
- name: debug_getModifiedAccountsByNumber
|
||||
- name: debug_getModifiedAccountsByHash
|
||||
# non standard geth and erigon
|
||||
- name: eth_getRawTransactionByHash
|
||||
- name: eth_getRawTransactionByBlockHashAndIndex
|
||||
...
|
||||
141
arb/nitro/playblock-mainnet-nitro-archive-leveldb-hash.yml
Normal file
141
arb/nitro/playblock-mainnet-nitro-archive-leveldb-hash.yml
Normal file
@@ -0,0 +1,141 @@
|
||||
---
|
||||
x-logging-defaults: &logging-defaults
|
||||
driver: json-file
|
||||
options:
|
||||
max-size: "10m"
|
||||
max-file: "3"
|
||||
|
||||
# Usage:
|
||||
#
|
||||
# mkdir rpc && cd rpc
|
||||
#
|
||||
# git init
|
||||
# git remote add origin https://github.com/StakeSquid/ethereum-rpc-docker.git
|
||||
# git fetch origin vibe
|
||||
# git checkout origin/vibe
|
||||
#
|
||||
# docker run --rm alpine sh -c "printf '0x'; head -c32 /dev/urandom | xxd -p -c 64" > .jwtsecret
|
||||
#
|
||||
# env
|
||||
# ...
|
||||
# IP=$(curl ipinfo.io/ip)
|
||||
# DOMAIN=${IP}.traefik.me
|
||||
# COMPOSE_FILE=base.yml:rpc.yml:arb/nitro/playblock-mainnet-nitro-archive-leveldb-hash.yml
|
||||
#
|
||||
# docker compose up -d
|
||||
#
|
||||
# curl -X POST https://${IP}.traefik.me/playblock-mainnet-archive \
|
||||
# -H "Content-Type: application/json" \
|
||||
# --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'
|
||||
|
||||
services:
|
||||
playblock-mainnet-archive:
|
||||
image: ${PLAYBLOCK_NITRO_IMAGE:-offchainlabs/nitro-node}:${PLAYBLOCK_MAINNET_NITRO_VERSION:-v3.6.4-28199cd}
|
||||
sysctls:
|
||||
# TCP Performance
|
||||
net.ipv4.tcp_slow_start_after_idle: 0 # Disable slow start after idle
|
||||
net.ipv4.tcp_no_metrics_save: 1 # Disable metrics cache
|
||||
net.ipv4.tcp_rmem: 4096 87380 16777216 # Increase TCP read buffers
|
||||
net.ipv4.tcp_wmem: 4096 87380 16777216 # Increase TCP write buffers
|
||||
net.core.somaxconn: 32768 # Higher connection queue
|
||||
# Memory/Connection Management
|
||||
# net.core.netdev_max_backlog: 50000 # Increase network buffer
|
||||
net.ipv4.tcp_max_syn_backlog: 30000 # More SYN requests
|
||||
net.ipv4.tcp_max_tw_buckets: 2000000 # Allow more TIME_WAIT sockets
|
||||
ulimits:
|
||||
nofile: 1048576 # Max open files (for RPC/WS connections)
|
||||
user: root
|
||||
expose:
|
||||
- 8545
|
||||
command:
|
||||
- --conf.file=/config/baseConfig.json
|
||||
- --execution.caching.archive=true
|
||||
- --execution.forwarding-target=https://rpc.playblock.io
|
||||
- --execution.rpc.gas-cap=600000000
|
||||
- --execution.sequencer.enable=false
|
||||
- --http.addr=0.0.0.0
|
||||
- --http.api=eth,net,web3,arb,txpool,debug
|
||||
- --http.corsdomain=*
|
||||
- --http.port=8545
|
||||
- --http.vhosts=*
|
||||
- --init.download-path=/tmp
|
||||
- --metrics
|
||||
- --metrics-server.addr=0.0.0.0
|
||||
- --metrics-server.port=6070
|
||||
- --node.batch-poster.enable=false
|
||||
- --node.data-availability.enable=true
|
||||
- --node.data-availability.parent-chain-node-url=${ARBITRUM_NOVA_EXECUTION_RPC}
|
||||
- --node.data-availability.rest-aggregator.enable=true
|
||||
- --node.data-availability.rest-aggregator.urls=https://das.playblock.io
|
||||
- --node.data-availability.sequencer-inbox-address=0x1297541082195356755105700451499873350464260779639
|
||||
- --node.feed.input.url=wss://feed.playblock.io
|
||||
- --node.sequencer=false
|
||||
- --node.staker.enable=false
|
||||
- --parent-chain.connection.url=${ARBITRUM_NOVA_EXECUTION_RPC}
|
||||
- --persistent.chain=/root/.arbitrum/playblock-mainnet-archive
|
||||
- --ws.addr=0.0.0.0
|
||||
- --ws.origins=*
|
||||
- --ws.port=8545
|
||||
restart: unless-stopped
|
||||
stop_grace_period: 5m
|
||||
networks:
|
||||
- chains
|
||||
volumes:
|
||||
- ${PLAYBLOCK_MAINNET_NITRO_ARCHIVE_LEVELDB_HASH_DATA:-playblock-mainnet-nitro-archive-leveldb-hash}:/root/.arbitrum
|
||||
- ./arb/playblock/arbitrum-nova:/config
|
||||
- /slowdisk:/slowdisk
|
||||
logging: *logging-defaults
|
||||
labels:
|
||||
- prometheus-scrape.enabled=true
|
||||
- prometheus-scrape.port=6070
|
||||
- prometheus-scrape.path=/debug/metrics/prometheus
|
||||
- traefik.enable=true
|
||||
- traefik.http.middlewares.playblock-mainnet-nitro-archive-leveldb-hash-stripprefix.stripprefix.prefixes=/playblock-mainnet-archive
|
||||
- traefik.http.services.playblock-mainnet-nitro-archive-leveldb-hash.loadbalancer.server.port=8545
|
||||
- ${NO_SSL:-traefik.http.routers.playblock-mainnet-nitro-archive-leveldb-hash.entrypoints=websecure}
|
||||
- ${NO_SSL:-traefik.http.routers.playblock-mainnet-nitro-archive-leveldb-hash.tls.certresolver=myresolver}
|
||||
- ${NO_SSL:-traefik.http.routers.playblock-mainnet-nitro-archive-leveldb-hash.rule=Host(`$DOMAIN`) && (Path(`/playblock-mainnet-archive`) || Path(`/playblock-mainnet-archive/`))}
|
||||
- ${NO_SSL:+traefik.http.routers.playblock-mainnet-nitro-archive-leveldb-hash.rule=Path(`/playblock-mainnet-archive`) || Path(`/playblock-mainnet-archive/`)}
|
||||
- traefik.http.routers.playblock-mainnet-nitro-archive-leveldb-hash.middlewares=playblock-mainnet-nitro-archive-leveldb-hash-stripprefix, ipallowlist
|
||||
|
||||
volumes:
|
||||
playblock-mainnet-nitro-archive-leveldb-hash:
|
||||
|
||||
x-upstreams:
|
||||
- id: $${ID}
|
||||
labels:
|
||||
provider: $${PROVIDER}
|
||||
connection:
|
||||
generic:
|
||||
rpc:
|
||||
url: $${RPC_URL}
|
||||
ws:
|
||||
frameSize: 20Mb
|
||||
msgSize: 50Mb
|
||||
url: $${WS_URL}
|
||||
chain: playnance
|
||||
method-groups:
|
||||
enabled:
|
||||
- debug
|
||||
- filter
|
||||
methods:
|
||||
disabled:
|
||||
enabled:
|
||||
- name: txpool_content # TODO: should be disabled for rollup nodes
|
||||
# standard geth only
|
||||
- name: debug_getRawBlock
|
||||
- name: debug_getRawTransaction
|
||||
- name: debug_getRawReceipts
|
||||
- name: debug_getRawHeader
|
||||
- name: debug_getBadBlocks
|
||||
# non standard geth only slightly dangerous
|
||||
- name: debug_intermediateRoots
|
||||
- name: debug_dumpBlock
|
||||
# standard geth and erigon
|
||||
- name: debug_accountRange
|
||||
- name: debug_getModifiedAccountsByNumber
|
||||
- name: debug_getModifiedAccountsByHash
|
||||
# non standard geth and erigon
|
||||
- name: eth_getRawTransactionByHash
|
||||
- name: eth_getRawTransactionByBlockHashAndIndex
|
||||
...
|
||||
145
arb/nitro/playblock-mainnet-nitro-pruned-pebble-path.yml
Normal file
145
arb/nitro/playblock-mainnet-nitro-pruned-pebble-path.yml
Normal file
@@ -0,0 +1,145 @@
|
||||
---
|
||||
x-logging-defaults: &logging-defaults
|
||||
driver: json-file
|
||||
options:
|
||||
max-size: "10m"
|
||||
max-file: "3"
|
||||
|
||||
# Usage:
|
||||
#
|
||||
# mkdir rpc && cd rpc
|
||||
#
|
||||
# git init
|
||||
# git remote add origin https://github.com/StakeSquid/ethereum-rpc-docker.git
|
||||
# git fetch origin vibe
|
||||
# git checkout origin/vibe
|
||||
#
|
||||
# docker run --rm alpine sh -c "printf '0x'; head -c32 /dev/urandom | xxd -p -c 64" > .jwtsecret
|
||||
#
|
||||
# env
|
||||
# ...
|
||||
# IP=$(curl ipinfo.io/ip)
|
||||
# DOMAIN=${IP}.traefik.me
|
||||
# COMPOSE_FILE=base.yml:rpc.yml:arb/nitro/playblock-mainnet-nitro-pruned-pebble-path.yml
|
||||
#
|
||||
# docker compose up -d
|
||||
#
|
||||
# curl -X POST https://${IP}.traefik.me/playblock-mainnet \
|
||||
# -H "Content-Type: application/json" \
|
||||
# --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'
|
||||
|
||||
services:
|
||||
playblock-mainnet:
|
||||
image: ${PLAYBLOCK_NITRO_IMAGE:-offchainlabs/nitro-node}:${PLAYBLOCK_MAINNET_NITRO_VERSION:-v3.6.4-28199cd}
|
||||
sysctls:
|
||||
# TCP Performance
|
||||
net.ipv4.tcp_slow_start_after_idle: 0 # Disable slow start after idle
|
||||
net.ipv4.tcp_no_metrics_save: 1 # Disable metrics cache
|
||||
net.ipv4.tcp_rmem: 4096 87380 16777216 # Increase TCP read buffers
|
||||
net.ipv4.tcp_wmem: 4096 87380 16777216 # Increase TCP write buffers
|
||||
net.core.somaxconn: 32768 # Higher connection queue
|
||||
# Memory/Connection Management
|
||||
# net.core.netdev_max_backlog: 50000 # Increase network buffer
|
||||
net.ipv4.tcp_max_syn_backlog: 30000 # More SYN requests
|
||||
net.ipv4.tcp_max_tw_buckets: 2000000 # Allow more TIME_WAIT sockets
|
||||
ulimits:
|
||||
nofile: 1048576 # Max open files (for RPC/WS connections)
|
||||
user: root
|
||||
expose:
|
||||
- 8545
|
||||
command:
|
||||
- --conf.file=/config/baseConfig.json
|
||||
- --execution.caching.archive=false
|
||||
- --execution.caching.state-scheme=path
|
||||
- --execution.forwarding-target=https://rpc.playblock.io
|
||||
- --execution.rpc.gas-cap=600000000
|
||||
- --execution.sequencer.enable=false
|
||||
- --http.addr=0.0.0.0
|
||||
- --http.api=eth,net,web3,arb,txpool,debug
|
||||
- --http.corsdomain=*
|
||||
- --http.port=8545
|
||||
- --http.vhosts=*
|
||||
- --init.download-path=/tmp
|
||||
- --metrics
|
||||
- --metrics-server.addr=0.0.0.0
|
||||
- --metrics-server.port=6070
|
||||
- --node.batch-poster.enable=false
|
||||
- --node.data-availability.enable=true
|
||||
- --node.data-availability.parent-chain-node-url=${ARBITRUM_NOVA_EXECUTION_RPC}
|
||||
- --node.data-availability.rest-aggregator.enable=true
|
||||
- --node.data-availability.rest-aggregator.urls=https://das.playblock.io
|
||||
- --node.data-availability.sequencer-inbox-address=0x1297541082195356755105700451499873350464260779639
|
||||
- --node.feed.input.url=wss://feed.playblock.io
|
||||
- --node.sequencer=false
|
||||
- --node.staker.enable=false
|
||||
- --parent-chain.connection.url=${ARBITRUM_NOVA_EXECUTION_RPC}
|
||||
- --persistent.chain=/root/.arbitrum/playblock-mainnet
|
||||
- --persistent.db-engine=pebble
|
||||
- --ws.addr=0.0.0.0
|
||||
- --ws.origins=*
|
||||
- --ws.port=8545
|
||||
restart: unless-stopped
|
||||
stop_grace_period: 5m
|
||||
networks:
|
||||
- chains
|
||||
volumes:
|
||||
- ${PLAYBLOCK_MAINNET_NITRO_PRUNED_PEBBLE_PATH_DATA:-playblock-mainnet-nitro-pruned-pebble-path}:/root/.arbitrum
|
||||
- ./arb/playblock/arbitrum-nova:/config
|
||||
- /slowdisk:/slowdisk
|
||||
logging: *logging-defaults
|
||||
labels:
|
||||
- prometheus-scrape.enabled=true
|
||||
- prometheus-scrape.port=6070
|
||||
- prometheus-scrape.path=/debug/metrics/prometheus
|
||||
- traefik.enable=true
|
||||
- traefik.http.middlewares.playblock-mainnet-nitro-pruned-pebble-path-stripprefix.stripprefix.prefixes=/playblock-mainnet
|
||||
- traefik.http.services.playblock-mainnet-nitro-pruned-pebble-path.loadbalancer.server.port=8545
|
||||
- ${NO_SSL:-traefik.http.routers.playblock-mainnet-nitro-pruned-pebble-path.entrypoints=websecure}
|
||||
- ${NO_SSL:-traefik.http.routers.playblock-mainnet-nitro-pruned-pebble-path.tls.certresolver=myresolver}
|
||||
- ${NO_SSL:-traefik.http.routers.playblock-mainnet-nitro-pruned-pebble-path.rule=Host(`$DOMAIN`) && (Path(`/playblock-mainnet`) || Path(`/playblock-mainnet/`))}
|
||||
- ${NO_SSL:+traefik.http.routers.playblock-mainnet-nitro-pruned-pebble-path.rule=Path(`/playblock-mainnet`) || Path(`/playblock-mainnet/`)}
|
||||
- traefik.http.routers.playblock-mainnet-nitro-pruned-pebble-path.middlewares=playblock-mainnet-nitro-pruned-pebble-path-stripprefix, ipallowlist
|
||||
|
||||
volumes:
|
||||
playblock-mainnet-nitro-pruned-pebble-path:
|
||||
|
||||
x-upstreams:
|
||||
- id: $${ID}
|
||||
labels:
|
||||
provider: $${PROVIDER}
|
||||
connection:
|
||||
generic:
|
||||
rpc:
|
||||
url: $${RPC_URL}
|
||||
ws:
|
||||
frameSize: 20Mb
|
||||
msgSize: 50Mb
|
||||
url: $${WS_URL}
|
||||
chain: playnance
|
||||
method-groups:
|
||||
enabled:
|
||||
- debug
|
||||
- filter
|
||||
methods:
|
||||
disabled:
|
||||
# not compatible with path state scheme
|
||||
- name: debug_traceBlockByHash
|
||||
enabled:
|
||||
- name: txpool_content # TODO: should be disabled for rollup nodes
|
||||
# standard geth only
|
||||
- name: debug_getRawBlock
|
||||
- name: debug_getRawTransaction
|
||||
- name: debug_getRawReceipts
|
||||
- name: debug_getRawHeader
|
||||
- name: debug_getBadBlocks
|
||||
# non standard geth only slightly dangerous
|
||||
- name: debug_intermediateRoots
|
||||
- name: debug_dumpBlock
|
||||
# standard geth and erigon
|
||||
- name: debug_accountRange
|
||||
- name: debug_getModifiedAccountsByNumber
|
||||
- name: debug_getModifiedAccountsByHash
|
||||
# non standard geth and erigon
|
||||
- name: eth_getRawTransactionByHash
|
||||
- name: eth_getRawTransactionByBlockHashAndIndex
|
||||
...
|
||||
142
arb/nitro/real-mainnet-nitro-archive-leveldb-hash.yml
Normal file
142
arb/nitro/real-mainnet-nitro-archive-leveldb-hash.yml
Normal file
@@ -0,0 +1,142 @@
|
||||
---
|
||||
x-logging-defaults: &logging-defaults
|
||||
driver: json-file
|
||||
options:
|
||||
max-size: "10m"
|
||||
max-file: "3"
|
||||
|
||||
# Usage:
|
||||
#
|
||||
# mkdir rpc && cd rpc
|
||||
#
|
||||
# git init
|
||||
# git remote add origin https://github.com/StakeSquid/ethereum-rpc-docker.git
|
||||
# git fetch origin vibe
|
||||
# git checkout origin/vibe
|
||||
#
|
||||
# docker run --rm alpine sh -c "printf '0x'; head -c32 /dev/urandom | xxd -p -c 64" > .jwtsecret
|
||||
#
|
||||
# env
|
||||
# ...
|
||||
# IP=$(curl ipinfo.io/ip)
|
||||
# DOMAIN=${IP}.traefik.me
|
||||
# COMPOSE_FILE=base.yml:rpc.yml:arb/nitro/real-mainnet-nitro-archive-leveldb-hash.yml
|
||||
#
|
||||
# docker compose up -d
|
||||
#
|
||||
# curl -X POST https://${IP}.traefik.me/real-mainnet-archive \
|
||||
# -H "Content-Type: application/json" \
|
||||
# --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'
|
||||
|
||||
services:
|
||||
real-mainnet-archive:
|
||||
image: ${REAL_NITRO_IMAGE:-offchainlabs/nitro-node}:${REAL_MAINNET_NITRO_VERSION:-v3.6.4-28199cd}
|
||||
sysctls:
|
||||
# TCP Performance
|
||||
net.ipv4.tcp_slow_start_after_idle: 0 # Disable slow start after idle
|
||||
net.ipv4.tcp_no_metrics_save: 1 # Disable metrics cache
|
||||
net.ipv4.tcp_rmem: 4096 87380 16777216 # Increase TCP read buffers
|
||||
net.ipv4.tcp_wmem: 4096 87380 16777216 # Increase TCP write buffers
|
||||
net.core.somaxconn: 32768 # Higher connection queue
|
||||
# Memory/Connection Management
|
||||
# net.core.netdev_max_backlog: 50000 # Increase network buffer
|
||||
net.ipv4.tcp_max_syn_backlog: 30000 # More SYN requests
|
||||
net.ipv4.tcp_max_tw_buckets: 2000000 # Allow more TIME_WAIT sockets
|
||||
ulimits:
|
||||
nofile: 1048576 # Max open files (for RPC/WS connections)
|
||||
user: root
|
||||
expose:
|
||||
- 8545
|
||||
command:
|
||||
- --conf.file=/config/baseConfig.json
|
||||
- --execution.caching.archive=true
|
||||
- --execution.forwarding-target=https://rpc.realforreal.gelato.digital
|
||||
- --execution.rpc.gas-cap=600000000
|
||||
- --execution.sequencer.enable=false
|
||||
- --http.addr=0.0.0.0
|
||||
- --http.api=eth,net,web3,arb,txpool,debug
|
||||
- --http.corsdomain=*
|
||||
- --http.port=8545
|
||||
- --http.vhosts=*
|
||||
- --init.download-path=/tmp
|
||||
- --metrics
|
||||
- --metrics-server.addr=0.0.0.0
|
||||
- --metrics-server.port=6070
|
||||
- --node.batch-poster.enable=false
|
||||
- --node.data-availability.enable=true
|
||||
- --node.data-availability.parent-chain-node-url=${ETHEREUM_MAINNET_EXECUTION_RPC}
|
||||
- --node.data-availability.rest-aggregator.enable=true
|
||||
- --node.data-availability.rest-aggregator.urls=https://das.realforreal.gelato.digital
|
||||
- --node.data-availability.sequencer-inbox-address=0x466813324240923703236721233648302990016039913376
|
||||
- --node.feed.input.url=wss://feed.realforreal.gelato.digital
|
||||
- --node.sequencer=false
|
||||
- --node.staker.enable=false
|
||||
- --parent-chain.blob-client.beacon-url=${ETHEREUM_MAINNET_BEACON_REST}
|
||||
- --parent-chain.connection.url=${ETHEREUM_MAINNET_EXECUTION_RPC}
|
||||
- --persistent.chain=/root/.arbitrum/real-mainnet-archive
|
||||
- --ws.addr=0.0.0.0
|
||||
- --ws.origins=*
|
||||
- --ws.port=8545
|
||||
restart: unless-stopped
|
||||
stop_grace_period: 5m
|
||||
networks:
|
||||
- chains
|
||||
volumes:
|
||||
- ${REAL_MAINNET_NITRO_ARCHIVE_LEVELDB_HASH_DATA:-real-mainnet-nitro-archive-leveldb-hash}:/root/.arbitrum
|
||||
- ./arb/real/mainnet:/config
|
||||
- /slowdisk:/slowdisk
|
||||
logging: *logging-defaults
|
||||
labels:
|
||||
- prometheus-scrape.enabled=true
|
||||
- prometheus-scrape.port=6070
|
||||
- prometheus-scrape.path=/debug/metrics/prometheus
|
||||
- traefik.enable=true
|
||||
- traefik.http.middlewares.real-mainnet-nitro-archive-leveldb-hash-stripprefix.stripprefix.prefixes=/real-mainnet-archive
|
||||
- traefik.http.services.real-mainnet-nitro-archive-leveldb-hash.loadbalancer.server.port=8545
|
||||
- ${NO_SSL:-traefik.http.routers.real-mainnet-nitro-archive-leveldb-hash.entrypoints=websecure}
|
||||
- ${NO_SSL:-traefik.http.routers.real-mainnet-nitro-archive-leveldb-hash.tls.certresolver=myresolver}
|
||||
- ${NO_SSL:-traefik.http.routers.real-mainnet-nitro-archive-leveldb-hash.rule=Host(`$DOMAIN`) && (Path(`/real-mainnet-archive`) || Path(`/real-mainnet-archive/`))}
|
||||
- ${NO_SSL:+traefik.http.routers.real-mainnet-nitro-archive-leveldb-hash.rule=Path(`/real-mainnet-archive`) || Path(`/real-mainnet-archive/`)}
|
||||
- traefik.http.routers.real-mainnet-nitro-archive-leveldb-hash.middlewares=real-mainnet-nitro-archive-leveldb-hash-stripprefix, ipallowlist
|
||||
|
||||
volumes:
|
||||
real-mainnet-nitro-archive-leveldb-hash:
|
||||
|
||||
x-upstreams:
|
||||
- id: $${ID}
|
||||
labels:
|
||||
provider: $${PROVIDER}
|
||||
connection:
|
||||
generic:
|
||||
rpc:
|
||||
url: $${RPC_URL}
|
||||
ws:
|
||||
frameSize: 20Mb
|
||||
msgSize: 50Mb
|
||||
url: $${WS_URL}
|
||||
chain: real
|
||||
method-groups:
|
||||
enabled:
|
||||
- debug
|
||||
- filter
|
||||
methods:
|
||||
disabled:
|
||||
enabled:
|
||||
- name: txpool_content # TODO: should be disabled for rollup nodes
|
||||
# standard geth only
|
||||
- name: debug_getRawBlock
|
||||
- name: debug_getRawTransaction
|
||||
- name: debug_getRawReceipts
|
||||
- name: debug_getRawHeader
|
||||
- name: debug_getBadBlocks
|
||||
# non standard geth only slightly dangerous
|
||||
- name: debug_intermediateRoots
|
||||
- name: debug_dumpBlock
|
||||
# standard geth and erigon
|
||||
- name: debug_accountRange
|
||||
- name: debug_getModifiedAccountsByNumber
|
||||
- name: debug_getModifiedAccountsByHash
|
||||
# non standard geth and erigon
|
||||
- name: eth_getRawTransactionByHash
|
||||
- name: eth_getRawTransactionByBlockHashAndIndex
|
||||
...
|
||||
143
arb/nitro/real-mainnet-nitro-archive-pebble-hash.yml
Normal file
143
arb/nitro/real-mainnet-nitro-archive-pebble-hash.yml
Normal file
@@ -0,0 +1,143 @@
|
||||
---
|
||||
x-logging-defaults: &logging-defaults
|
||||
driver: json-file
|
||||
options:
|
||||
max-size: "10m"
|
||||
max-file: "3"
|
||||
|
||||
# Usage:
|
||||
#
|
||||
# mkdir rpc && cd rpc
|
||||
#
|
||||
# git init
|
||||
# git remote add origin https://github.com/StakeSquid/ethereum-rpc-docker.git
|
||||
# git fetch origin vibe
|
||||
# git checkout origin/vibe
|
||||
#
|
||||
# docker run --rm alpine sh -c "printf '0x'; head -c32 /dev/urandom | xxd -p -c 64" > .jwtsecret
|
||||
#
|
||||
# env
|
||||
# ...
|
||||
# IP=$(curl ipinfo.io/ip)
|
||||
# DOMAIN=${IP}.traefik.me
|
||||
# COMPOSE_FILE=base.yml:rpc.yml:arb/nitro/real-mainnet-nitro-archive-pebble-hash.yml
|
||||
#
|
||||
# docker compose up -d
|
||||
#
|
||||
# curl -X POST https://${IP}.traefik.me/real-mainnet-archive \
|
||||
# -H "Content-Type: application/json" \
|
||||
# --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'
|
||||
|
||||
services:
|
||||
real-mainnet-archive:
|
||||
image: ${REAL_NITRO_IMAGE:-offchainlabs/nitro-node}:${REAL_MAINNET_NITRO_VERSION:-v3.6.4-28199cd}
|
||||
sysctls:
|
||||
# TCP Performance
|
||||
net.ipv4.tcp_slow_start_after_idle: 0 # Disable slow start after idle
|
||||
net.ipv4.tcp_no_metrics_save: 1 # Disable metrics cache
|
||||
net.ipv4.tcp_rmem: 4096 87380 16777216 # Increase TCP read buffers
|
||||
net.ipv4.tcp_wmem: 4096 87380 16777216 # Increase TCP write buffers
|
||||
net.core.somaxconn: 32768 # Higher connection queue
|
||||
# Memory/Connection Management
|
||||
# net.core.netdev_max_backlog: 50000 # Increase network buffer
|
||||
net.ipv4.tcp_max_syn_backlog: 30000 # More SYN requests
|
||||
net.ipv4.tcp_max_tw_buckets: 2000000 # Allow more TIME_WAIT sockets
|
||||
ulimits:
|
||||
nofile: 1048576 # Max open files (for RPC/WS connections)
|
||||
user: root
|
||||
expose:
|
||||
- 8545
|
||||
command:
|
||||
- --conf.file=/config/baseConfig.json
|
||||
- --execution.caching.archive=true
|
||||
- --execution.forwarding-target=https://rpc.realforreal.gelato.digital
|
||||
- --execution.rpc.gas-cap=600000000
|
||||
- --execution.sequencer.enable=false
|
||||
- --http.addr=0.0.0.0
|
||||
- --http.api=eth,net,web3,arb,txpool,debug
|
||||
- --http.corsdomain=*
|
||||
- --http.port=8545
|
||||
- --http.vhosts=*
|
||||
- --init.download-path=/tmp
|
||||
- --metrics
|
||||
- --metrics-server.addr=0.0.0.0
|
||||
- --metrics-server.port=6070
|
||||
- --node.batch-poster.enable=false
|
||||
- --node.data-availability.enable=true
|
||||
- --node.data-availability.parent-chain-node-url=${ETHEREUM_MAINNET_EXECUTION_RPC}
|
||||
- --node.data-availability.rest-aggregator.enable=true
|
||||
- --node.data-availability.rest-aggregator.urls=https://das.realforreal.gelato.digital
|
||||
- --node.data-availability.sequencer-inbox-address=0x466813324240923703236721233648302990016039913376
|
||||
- --node.feed.input.url=wss://feed.realforreal.gelato.digital
|
||||
- --node.sequencer=false
|
||||
- --node.staker.enable=false
|
||||
- --parent-chain.blob-client.beacon-url=${ETHEREUM_MAINNET_BEACON_REST}
|
||||
- --parent-chain.connection.url=${ETHEREUM_MAINNET_EXECUTION_RPC}
|
||||
- --persistent.chain=/root/.arbitrum/real-mainnet-archive
|
||||
- --persistent.db-engine=pebble
|
||||
- --ws.addr=0.0.0.0
|
||||
- --ws.origins=*
|
||||
- --ws.port=8545
|
||||
restart: unless-stopped
|
||||
stop_grace_period: 5m
|
||||
networks:
|
||||
- chains
|
||||
volumes:
|
||||
- ${REAL_MAINNET_NITRO_ARCHIVE_PEBBLE_HASH_DATA:-real-mainnet-nitro-archive-pebble-hash}:/root/.arbitrum
|
||||
- ./arb/real/mainnet:/config
|
||||
- /slowdisk:/slowdisk
|
||||
logging: *logging-defaults
|
||||
labels:
|
||||
- prometheus-scrape.enabled=true
|
||||
- prometheus-scrape.port=6070
|
||||
- prometheus-scrape.path=/debug/metrics/prometheus
|
||||
- traefik.enable=true
|
||||
- traefik.http.middlewares.real-mainnet-nitro-archive-pebble-hash-stripprefix.stripprefix.prefixes=/real-mainnet-archive
|
||||
- traefik.http.services.real-mainnet-nitro-archive-pebble-hash.loadbalancer.server.port=8545
|
||||
- ${NO_SSL:-traefik.http.routers.real-mainnet-nitro-archive-pebble-hash.entrypoints=websecure}
|
||||
- ${NO_SSL:-traefik.http.routers.real-mainnet-nitro-archive-pebble-hash.tls.certresolver=myresolver}
|
||||
- ${NO_SSL:-traefik.http.routers.real-mainnet-nitro-archive-pebble-hash.rule=Host(`$DOMAIN`) && (Path(`/real-mainnet-archive`) || Path(`/real-mainnet-archive/`))}
|
||||
- ${NO_SSL:+traefik.http.routers.real-mainnet-nitro-archive-pebble-hash.rule=Path(`/real-mainnet-archive`) || Path(`/real-mainnet-archive/`)}
|
||||
- traefik.http.routers.real-mainnet-nitro-archive-pebble-hash.middlewares=real-mainnet-nitro-archive-pebble-hash-stripprefix, ipallowlist
|
||||
|
||||
volumes:
|
||||
real-mainnet-nitro-archive-pebble-hash:
|
||||
|
||||
x-upstreams:
|
||||
- id: $${ID}
|
||||
labels:
|
||||
provider: $${PROVIDER}
|
||||
connection:
|
||||
generic:
|
||||
rpc:
|
||||
url: $${RPC_URL}
|
||||
ws:
|
||||
frameSize: 20Mb
|
||||
msgSize: 50Mb
|
||||
url: $${WS_URL}
|
||||
chain: real
|
||||
method-groups:
|
||||
enabled:
|
||||
- debug
|
||||
- filter
|
||||
methods:
|
||||
disabled:
|
||||
enabled:
|
||||
- name: txpool_content # TODO: should be disabled for rollup nodes
|
||||
# standard geth only
|
||||
- name: debug_getRawBlock
|
||||
- name: debug_getRawTransaction
|
||||
- name: debug_getRawReceipts
|
||||
- name: debug_getRawHeader
|
||||
- name: debug_getBadBlocks
|
||||
# non standard geth only slightly dangerous
|
||||
- name: debug_intermediateRoots
|
||||
- name: debug_dumpBlock
|
||||
# standard geth and erigon
|
||||
- name: debug_accountRange
|
||||
- name: debug_getModifiedAccountsByNumber
|
||||
- name: debug_getModifiedAccountsByHash
|
||||
# non standard geth and erigon
|
||||
- name: eth_getRawTransactionByHash
|
||||
- name: eth_getRawTransactionByBlockHashAndIndex
|
||||
...
|
||||
146
arb/nitro/real-mainnet-nitro-pruned-pebble-path.yml
Normal file
146
arb/nitro/real-mainnet-nitro-pruned-pebble-path.yml
Normal file
@@ -0,0 +1,146 @@
|
||||
---
|
||||
x-logging-defaults: &logging-defaults
|
||||
driver: json-file
|
||||
options:
|
||||
max-size: "10m"
|
||||
max-file: "3"
|
||||
|
||||
# Usage:
|
||||
#
|
||||
# mkdir rpc && cd rpc
|
||||
#
|
||||
# git init
|
||||
# git remote add origin https://github.com/StakeSquid/ethereum-rpc-docker.git
|
||||
# git fetch origin vibe
|
||||
# git checkout origin/vibe
|
||||
#
|
||||
# docker run --rm alpine sh -c "printf '0x'; head -c32 /dev/urandom | xxd -p -c 64" > .jwtsecret
|
||||
#
|
||||
# env
|
||||
# ...
|
||||
# IP=$(curl ipinfo.io/ip)
|
||||
# DOMAIN=${IP}.traefik.me
|
||||
# COMPOSE_FILE=base.yml:rpc.yml:arb/nitro/real-mainnet-nitro-pruned-pebble-path.yml
|
||||
#
|
||||
# docker compose up -d
|
||||
#
|
||||
# curl -X POST https://${IP}.traefik.me/real-mainnet \
|
||||
# -H "Content-Type: application/json" \
|
||||
# --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'
|
||||
|
||||
services:
|
||||
real-mainnet:
|
||||
image: ${REAL_NITRO_IMAGE:-offchainlabs/nitro-node}:${REAL_MAINNET_NITRO_VERSION:-v3.6.4-28199cd}
|
||||
sysctls:
|
||||
# TCP Performance
|
||||
net.ipv4.tcp_slow_start_after_idle: 0 # Disable slow start after idle
|
||||
net.ipv4.tcp_no_metrics_save: 1 # Disable metrics cache
|
||||
net.ipv4.tcp_rmem: 4096 87380 16777216 # Increase TCP read buffers
|
||||
net.ipv4.tcp_wmem: 4096 87380 16777216 # Increase TCP write buffers
|
||||
net.core.somaxconn: 32768 # Higher connection queue
|
||||
# Memory/Connection Management
|
||||
# net.core.netdev_max_backlog: 50000 # Increase network buffer
|
||||
net.ipv4.tcp_max_syn_backlog: 30000 # More SYN requests
|
||||
net.ipv4.tcp_max_tw_buckets: 2000000 # Allow more TIME_WAIT sockets
|
||||
ulimits:
|
||||
nofile: 1048576 # Max open files (for RPC/WS connections)
|
||||
user: root
|
||||
expose:
|
||||
- 8545
|
||||
command:
|
||||
- --conf.file=/config/baseConfig.json
|
||||
- --execution.caching.archive=false
|
||||
- --execution.caching.state-scheme=path
|
||||
- --execution.forwarding-target=https://rpc.realforreal.gelato.digital
|
||||
- --execution.rpc.gas-cap=600000000
|
||||
- --execution.sequencer.enable=false
|
||||
- --http.addr=0.0.0.0
|
||||
- --http.api=eth,net,web3,arb,txpool,debug
|
||||
- --http.corsdomain=*
|
||||
- --http.port=8545
|
||||
- --http.vhosts=*
|
||||
- --init.download-path=/tmp
|
||||
- --metrics
|
||||
- --metrics-server.addr=0.0.0.0
|
||||
- --metrics-server.port=6070
|
||||
- --node.batch-poster.enable=false
|
||||
- --node.data-availability.enable=true
|
||||
- --node.data-availability.parent-chain-node-url=${ETHEREUM_MAINNET_EXECUTION_RPC}
|
||||
- --node.data-availability.rest-aggregator.enable=true
|
||||
- --node.data-availability.rest-aggregator.urls=https://das.realforreal.gelato.digital
|
||||
- --node.data-availability.sequencer-inbox-address=0x466813324240923703236721233648302990016039913376
|
||||
- --node.feed.input.url=wss://feed.realforreal.gelato.digital
|
||||
- --node.sequencer=false
|
||||
- --node.staker.enable=false
|
||||
- --parent-chain.blob-client.beacon-url=${ETHEREUM_MAINNET_BEACON_REST}
|
||||
- --parent-chain.connection.url=${ETHEREUM_MAINNET_EXECUTION_RPC}
|
||||
- --persistent.chain=/root/.arbitrum/real-mainnet
|
||||
- --persistent.db-engine=pebble
|
||||
- --ws.addr=0.0.0.0
|
||||
- --ws.origins=*
|
||||
- --ws.port=8545
|
||||
restart: unless-stopped
|
||||
stop_grace_period: 5m
|
||||
networks:
|
||||
- chains
|
||||
volumes:
|
||||
- ${REAL_MAINNET_NITRO_PRUNED_PEBBLE_PATH_DATA:-real-mainnet-nitro-pruned-pebble-path}:/root/.arbitrum
|
||||
- ./arb/real/mainnet:/config
|
||||
- /slowdisk:/slowdisk
|
||||
logging: *logging-defaults
|
||||
labels:
|
||||
- prometheus-scrape.enabled=true
|
||||
- prometheus-scrape.port=6070
|
||||
- prometheus-scrape.path=/debug/metrics/prometheus
|
||||
- traefik.enable=true
|
||||
- traefik.http.middlewares.real-mainnet-nitro-pruned-pebble-path-stripprefix.stripprefix.prefixes=/real-mainnet
|
||||
- traefik.http.services.real-mainnet-nitro-pruned-pebble-path.loadbalancer.server.port=8545
|
||||
- ${NO_SSL:-traefik.http.routers.real-mainnet-nitro-pruned-pebble-path.entrypoints=websecure}
|
||||
- ${NO_SSL:-traefik.http.routers.real-mainnet-nitro-pruned-pebble-path.tls.certresolver=myresolver}
|
||||
- ${NO_SSL:-traefik.http.routers.real-mainnet-nitro-pruned-pebble-path.rule=Host(`$DOMAIN`) && (Path(`/real-mainnet`) || Path(`/real-mainnet/`))}
|
||||
- ${NO_SSL:+traefik.http.routers.real-mainnet-nitro-pruned-pebble-path.rule=Path(`/real-mainnet`) || Path(`/real-mainnet/`)}
|
||||
- traefik.http.routers.real-mainnet-nitro-pruned-pebble-path.middlewares=real-mainnet-nitro-pruned-pebble-path-stripprefix, ipallowlist
|
||||
|
||||
volumes:
|
||||
real-mainnet-nitro-pruned-pebble-path:
|
||||
|
||||
x-upstreams:
|
||||
- id: $${ID}
|
||||
labels:
|
||||
provider: $${PROVIDER}
|
||||
connection:
|
||||
generic:
|
||||
rpc:
|
||||
url: $${RPC_URL}
|
||||
ws:
|
||||
frameSize: 20Mb
|
||||
msgSize: 50Mb
|
||||
url: $${WS_URL}
|
||||
chain: real
|
||||
method-groups:
|
||||
enabled:
|
||||
- debug
|
||||
- filter
|
||||
methods:
|
||||
disabled:
|
||||
# not compatible with path state scheme
|
||||
- name: debug_traceBlockByHash
|
||||
enabled:
|
||||
- name: txpool_content # TODO: should be disabled for rollup nodes
|
||||
# standard geth only
|
||||
- name: debug_getRawBlock
|
||||
- name: debug_getRawTransaction
|
||||
- name: debug_getRawReceipts
|
||||
- name: debug_getRawHeader
|
||||
- name: debug_getBadBlocks
|
||||
# non standard geth only slightly dangerous
|
||||
- name: debug_intermediateRoots
|
||||
- name: debug_dumpBlock
|
||||
# standard geth and erigon
|
||||
- name: debug_accountRange
|
||||
- name: debug_getModifiedAccountsByNumber
|
||||
- name: debug_getModifiedAccountsByHash
|
||||
# non standard geth and erigon
|
||||
- name: eth_getRawTransactionByHash
|
||||
- name: eth_getRawTransactionByBlockHashAndIndex
|
||||
...
|
||||
6
arb/opencampuscodex/arbitrum-sepolia/baseConfig.json
Normal file
6
arb/opencampuscodex/arbitrum-sepolia/baseConfig.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"chain": {
|
||||
"info-json": "[{\"chain-id\":656476,\"parent-chain-id\":421614,\"parent-chain-is-arbitrum\":true,\"chain-name\":\"Codex\",\"chain-config\":{\"homesteadBlock\":0,\"daoForkBlock\":null,\"daoForkSupport\":true,\"eip150Block\":0,\"eip150Hash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"eip155Block\":0,\"eip158Block\":0,\"byzantiumBlock\":0,\"constantinopleBlock\":0,\"petersburgBlock\":0,\"istanbulBlock\":0,\"muirGlacierBlock\":0,\"berlinBlock\":0,\"londonBlock\":0,\"clique\":{\"period\":0,\"epoch\":0},\"arbitrum\":{\"EnableArbOS\":true,\"AllowDebugPrecompiles\":false,\"DataAvailabilityCommittee\":true,\"InitialArbOSVersion\":20,\"GenesisBlockNum\":0,\"MaxCodeSize\":24576,\"MaxInitCodeSize\":49152,\"InitialChainOwner\":\"0xF46B08D9E85df74b6f24Ad85A6a655c02857D5b8\"},\"chainId\":656476},\"rollup\":{\"bridge\":\"0xbf3D64671154D1FB0b27Cb1decbE1094d7016448\",\"inbox\":\"0x67F231eDC83a66556148673863e73D705422A678\",\"sequencer-inbox\":\"0xd5131c1924f080D45CA3Ae97262c0015F675004b\",\"rollup\":\"0x0A94003d3482128c89395aBd94a41DA8eeBB59f7\",\"validator-utils\":\"0xB11EB62DD2B352886A4530A9106fE427844D515f\",\"validator-wallet-creator\":\"0xEb9885B6c0e117D339F47585cC06a2765AaE2E0b\",\"deployed-at\":41549214}}]",
|
||||
"name": "Codex"
|
||||
}
|
||||
}
|
||||
6
arb/playblock/arbitrum-nova/baseConfig.json
Normal file
6
arb/playblock/arbitrum-nova/baseConfig.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"chain": {
|
||||
"info-json": "[{\"chain-id\":1829,\"parent-chain-id\":42170,\"parent-chain-is-arbitrum\":true,\"chain-name\":\"Playblock\",\"chain-config\":{\"homesteadBlock\":0,\"daoForkBlock\":null,\"daoForkSupport\":true,\"eip150Block\":0,\"eip150Hash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"eip155Block\":0,\"eip158Block\":0,\"byzantiumBlock\":0,\"constantinopleBlock\":0,\"petersburgBlock\":0,\"istanbulBlock\":0,\"muirGlacierBlock\":0,\"berlinBlock\":0,\"londonBlock\":0,\"clique\":{\"period\":0,\"epoch\":0},\"arbitrum\":{\"EnableArbOS\":true,\"AllowDebugPrecompiles\":false,\"DataAvailabilityCommittee\":true,\"InitialArbOSVersion\":11,\"GenesisBlockNum\":0,\"MaxCodeSize\":24576,\"MaxInitCodeSize\":49152,\"InitialChainOwner\":\"0x10Fe3cb853F7ef551E1598d91436e95d41Aea45a\"},\"chainId\":1829},\"rollup\":{\"bridge\":\"0xD4FE46D2533E7d03382ac6cACF0547F336e59DC0\",\"inbox\":\"0xFF55fB76F5671dD9eB6c62EffF8D693Bb161a3ad\",\"sequencer-inbox\":\"0xe347C1223381b9Dcd6c0F61cf81c90175A7Bae77\",\"rollup\":\"0x04ea347cC6A258A7F65D67aFb60B1d487062A1d0\",\"validator-utils\":\"0x6c21303F5986180B1394d2C89f3e883890E2867b\",\"validator-wallet-creator\":\"0x2b0E04Dc90e3fA58165CB41E2834B44A56E766aF\",\"deployed-at\":55663578}}]",
|
||||
"name": "Playblock"
|
||||
}
|
||||
}
|
||||
6
arb/real/mainnet/baseConfig.json
Normal file
6
arb/real/mainnet/baseConfig.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"chain": {
|
||||
"info-json": "[{\"chain-id\":111188,\"parent-chain-id\":1,\"parent-chain-is-arbitrum\":false,\"chain-name\":\"real\",\"chain-config\":{\"homesteadBlock\":0,\"daoForkBlock\":null,\"daoForkSupport\":true,\"eip150Block\":0,\"eip150Hash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"eip155Block\":0,\"eip158Block\":0,\"byzantiumBlock\":0,\"constantinopleBlock\":0,\"petersburgBlock\":0,\"istanbulBlock\":0,\"muirGlacierBlock\":0,\"berlinBlock\":0,\"londonBlock\":0,\"clique\":{\"period\":0,\"epoch\":0},\"arbitrum\":{\"EnableArbOS\":true,\"AllowDebugPrecompiles\":false,\"DataAvailabilityCommittee\":true,\"InitialArbOSVersion\":11,\"GenesisBlockNum\":0,\"MaxCodeSize\":24576,\"MaxInitCodeSize\":49152,\"InitialChainOwner\":\"0xbB0385FebfD25E01527617938129A34bD497331e\"},\"chainId\":111188},\"rollup\":{\"bridge\":\"0x39D2EEcC8B55f46aE64789E2494dE777cDDeED03\",\"inbox\":\"0xf538671ddd60eE54BdD6FBb0E309c491A7A2df11\",\"sequencer-inbox\":\"0x51C4a227D59E49E26Ea07D8e4E9Af163da4c87A0\",\"rollup\":\"0xc4F7B37bE2bBbcF07373F28c61b1A259dfe49d2a\",\"validator-utils\":\"0x2b0E04Dc90e3fA58165CB41E2834B44A56E766aF\",\"validator-wallet-creator\":\"0x9CAd81628aB7D8e239F1A5B497313341578c5F71\",\"deployed-at\":19446518}}]",
|
||||
"name": "real"
|
||||
}
|
||||
}
|
||||
1
arbitrum-nova.yml
Symbolic link
1
arbitrum-nova.yml
Symbolic link
@@ -0,0 +1 @@
|
||||
arb/nitro/arbitrum-nova-nitro-pruned-pebble-hash.yml
|
||||
45
arbitrum-one-mainnet-arbnode-archive-trace.yml
Normal file
45
arbitrum-one-mainnet-arbnode-archive-trace.yml
Normal file
@@ -0,0 +1,45 @@
|
||||
services:
|
||||
arbitrum-classic:
|
||||
image: 'offchainlabs/arb-node:v1.4.5-e97c1a4'
|
||||
stop_grace_period: 30s
|
||||
user: root
|
||||
volumes:
|
||||
- ${ARBITRUM_ONE_MAINNET_ARBNODE_ARCHIVE_TRACE_DATA:-arbitrum-one-mainnet-arbnode-archive-trace}:/data
|
||||
- ./arbitrum/classic-entrypoint.sh:/entrypoint.sh
|
||||
expose:
|
||||
- 8547
|
||||
- 8548
|
||||
entrypoint: ["/home/user/go/bin/arb-node"]
|
||||
command:
|
||||
- --l1.url=http://eth.drpc.org
|
||||
- --core.checkpoint-gas-frequency=156250000
|
||||
- --node.rpc.enable-l1-calls
|
||||
- --node.cache.allow-slow-lookup
|
||||
- --node.rpc.tracing.enable
|
||||
- --node.rpc.addr=0.0.0.0
|
||||
- --node.rpc.port=8547
|
||||
- --node.rpc.tracing.namespace=trace
|
||||
- --node.chain-id=42161
|
||||
- --node.ws.addr=0.0.0.0
|
||||
- --node.ws.port=8548
|
||||
- --metrics
|
||||
- --metrics-server.addr=0.0.0.0
|
||||
- --metrics-server.port=7070
|
||||
- --l2.disable-upstream
|
||||
- --persistent.chain=/data/datadir/
|
||||
- --persistent.global-config=/data/
|
||||
restart: unless-stopped
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.middlewares.arbitrum-one-mainnet-arbnode-archive-trace-stripprefix.stripprefix.prefixes=/arbitrum-classic"
|
||||
- "traefik.http.services.arbitrum-one-mainnet-arbnode-archive-trace.loadbalancer.server.port=8547"
|
||||
- "${NO_SSL:-traefik.http.routers.arbitrum-one-mainnet-arbnode-archive-trace.entrypoints=websecure}"
|
||||
- "${NO_SSL:-traefik.http.routers.arbitrum-one-mainnet-arbnode-archive-trace.tls.certresolver=myresolver}"
|
||||
- "${NO_SSL:-traefik.http.routers.arbitrum-one-mainnet-arbnode-archive-trace.rule=Host(`$DOMAIN`) && PathPrefix(`/arbitrum-classic`)}"
|
||||
- "${NO_SSL:+traefik.http.routers.arbitrum-one-mainnet-arbnode-archive-trace.rule=PathPrefix(`/arbitrum-classic`)}"
|
||||
- "traefik.http.routers.arbitrum-one-mainnet-arbnode-archive-trace.middlewares=arbitrum-one-mainnet-arbnode-archive-trace-stripprefix, ipwhitelist"
|
||||
networks:
|
||||
- chains
|
||||
|
||||
volumes:
|
||||
arbitrum-one-mainnet-arbnode-archive-trace:
|
||||
1
arbitrum-one-nitro-archive.yml
Symbolic link
1
arbitrum-one-nitro-archive.yml
Symbolic link
@@ -0,0 +1 @@
|
||||
arb/nitro/alephzero-mainnet-nitro-archive-leveldb-hash.yml
|
||||
1
arbitrum-one.yml
Symbolic link
1
arbitrum-one.yml
Symbolic link
@@ -0,0 +1 @@
|
||||
arb/nitro/arbitrum-one-nitro-pruned-pebble-hash.yml
|
||||
1
arbitrum-sepolia-archive.yml
Symbolic link
1
arbitrum-sepolia-archive.yml
Symbolic link
@@ -0,0 +1 @@
|
||||
arb/nitro/arbitrum-sepolia-nitro-archive-pebble-hash.yml
|
||||
1
arbitrum-sepolia-nitro-pruned-pebble-hash.yml
Symbolic link
1
arbitrum-sepolia-nitro-pruned-pebble-hash.yml
Symbolic link
@@ -0,0 +1 @@
|
||||
arb/nitro/arbitrum-sepolia-nitro-pruned-pebble-hash.yml
|
||||
1
arbitrum-sepolia.yml
Symbolic link
1
arbitrum-sepolia.yml
Symbolic link
@@ -0,0 +1 @@
|
||||
arb/nitro/arbitrum-sepolia-nitro-pruned-pebble-hash.yml
|
||||
1
avalanche-fuji.yml
Symbolic link
1
avalanche-fuji.yml
Symbolic link
@@ -0,0 +1 @@
|
||||
avalanche/go/avalanche-fuji-go-pruned-pebbledb.yml
|
||||
1
avalanche-mainnet-archive.yml
Symbolic link
1
avalanche-mainnet-archive.yml
Symbolic link
@@ -0,0 +1 @@
|
||||
avalanche/go/avalanche-mainnet-go-archive-leveldb.yml
|
||||
51
avalanche-mainnet-go-archive.yml
Normal file
51
avalanche-mainnet-go-archive.yml
Normal file
@@ -0,0 +1,51 @@
|
||||
services:
|
||||
avalanche-archive-client:
|
||||
image: avaplatform/avalanchego:${AVALANCHEGO_VERSION:-v1.12.2}
|
||||
ulimits:
|
||||
nofile: 1048576
|
||||
expose:
|
||||
- "9650"
|
||||
- "30720"
|
||||
ports:
|
||||
- "30720:30720/tcp"
|
||||
- "30720:30720/udp"
|
||||
volumes:
|
||||
- ${AVALANCHE_MAINNET_GO_ARCHIVE_DATA:-avalanche-mainnet-go-archive}:/root/.avalanchego
|
||||
- ./avalanche/configs/chains/C/archive-config.json:/root/.avalanchego/configs/chains/C/config.json
|
||||
environment:
|
||||
- "IP=${IP}"
|
||||
networks:
|
||||
- chains
|
||||
command: "/avalanchego/build/avalanchego --http-host= --http-allowed-hosts=* --staking-port=30720 --public-ip=$IP"
|
||||
restart: unless-stopped
|
||||
|
||||
|
||||
avalanche-archive:
|
||||
restart: unless-stopped
|
||||
image: nginx
|
||||
depends_on:
|
||||
- avalanche-archive-client
|
||||
expose:
|
||||
- 80
|
||||
environment:
|
||||
PROXY_HOST: avalanche-archive-client
|
||||
RPC_PORT: 9650
|
||||
RPC_PATH: /ext/bc/C/rpc
|
||||
WS_PORT: 9650
|
||||
WS_PATH: /ext/bc/C/ws
|
||||
networks:
|
||||
- chains
|
||||
volumes:
|
||||
- ./nginx-proxy:/etc/nginx/templates
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.middlewares.avalanche-mainnet-go-archive-stripprefix.stripprefix.prefixes=/avalanche-archive"
|
||||
- "traefik.http.services.avalanche-mainnet-go-archive.loadbalancer.server.port=80"
|
||||
- "${NO_SSL:-traefik.http.routers.avalanche-mainnet-go-archive.entrypoints=websecure}"
|
||||
- "${NO_SSL:-traefik.http.routers.avalanche-mainnet-go-archive.tls.certresolver=myresolver}"
|
||||
- "${NO_SSL:-traefik.http.routers.avalanche-mainnet-go-archive.rule=Host(`$DOMAIN`) && PathPrefix(`/avalanche-archive`)}"
|
||||
- "${NO_SSL:+traefik.http.routers.avalanche-mainnet-go-archive.rule=PathPrefix(`/avalanche-archive`)}"
|
||||
- "traefik.http.routers.avalanche-mainnet-go-archive.middlewares=avalanche-mainnet-go-archive-stripprefix, ipwhitelist"
|
||||
|
||||
volumes:
|
||||
avalanche-mainnet-go-archive:
|
||||
1
avalanche-mainnet.yml
Symbolic link
1
avalanche-mainnet.yml
Symbolic link
@@ -0,0 +1 @@
|
||||
avalanche/go/avalanche-mainnet-go-pruned-pebbledb.yml
|
||||
4
avalanche/configs/chains/C/archive-config.json
Normal file
4
avalanche/configs/chains/C/archive-config.json
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"state-sync-enabled": false,
|
||||
"pruning-enabled": false
|
||||
}
|
||||
43
avalanche/configs/chains/C/config.json
Normal file
43
avalanche/configs/chains/C/config.json
Normal file
@@ -0,0 +1,43 @@
|
||||
{
|
||||
"snowman-api-enabled": false,
|
||||
"coreth-admin-api-enabled": false,
|
||||
"coreth-admin-api-dir": "",
|
||||
"eth-apis": [
|
||||
"public-eth",
|
||||
"public-eth-filter",
|
||||
"net",
|
||||
"web3",
|
||||
"internal-public-eth",
|
||||
"internal-public-blockchain",
|
||||
"internal-public-transaction-pool",
|
||||
"internal-public-account"
|
||||
],
|
||||
"continuous-profiler-dir": "",
|
||||
"continuous-profiler-frequency": 900000000000,
|
||||
"continuous-profiler-max-files": 5,
|
||||
"rpc-gas-cap": 50000000,
|
||||
"rpc-tx-fee-cap": 100,
|
||||
"preimages-enabled": false,
|
||||
"pruning-enabled": true,
|
||||
"snapshot-async": true,
|
||||
"snapshot-verification-enabled": false,
|
||||
"metrics-enabled": false,
|
||||
"metrics-expensive-enabled": false,
|
||||
"local-txs-enabled": false,
|
||||
"api-max-duration": 0,
|
||||
"ws-cpu-refill-rate": 0,
|
||||
"ws-cpu-max-stored": 0,
|
||||
"api-max-blocks-per-request": 0,
|
||||
"allow-unfinalized-queries": false,
|
||||
"allow-unprotected-txs": false,
|
||||
"keystore-directory": "",
|
||||
"keystore-external-signer": "",
|
||||
"keystore-insecure-unlock-allowed": false,
|
||||
"remote-tx-gossip-only-enabled": false,
|
||||
"tx-regossip-frequency": 60000000000,
|
||||
"tx-regossip-max-size": 15,
|
||||
"log-level": "debug",
|
||||
"offline-pruning-enabled": false,
|
||||
"offline-pruning-bloom-filter-size": 512,
|
||||
"offline-pruning-data-directory": ""
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"state-sync-enabled": true,
|
||||
"pruning-enabled": true,
|
||||
"offline-pruning-enabled": true,
|
||||
"offline-pruning-data-directory": "/root/.avalanchego/offline-pruning"
|
||||
}
|
||||
7
avalanche/configs/chains/C/fullnode-config.json
Normal file
7
avalanche/configs/chains/C/fullnode-config.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"state-sync-enabled": true,
|
||||
"pruning-enabled": true,
|
||||
"offline-pruning-enabled": false,
|
||||
"offline-pruning-data-directory": "/root/.avalanchego/offline-pruning",
|
||||
"rpc-gas-cap": 600000000
|
||||
}
|
||||
4
avalanche/fuji/archive/C/config.json
Normal file
4
avalanche/fuji/archive/C/config.json
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"state-sync-enabled": false,
|
||||
"pruning-enabled": false
|
||||
}
|
||||
0
avalanche/fuji/pruned/C/config.yml
Normal file
0
avalanche/fuji/pruned/C/config.yml
Normal file
128
avalanche/go/avalanche-fuji-go-archive-leveldb.yml
Normal file
128
avalanche/go/avalanche-fuji-go-archive-leveldb.yml
Normal file
@@ -0,0 +1,128 @@
|
||||
---
|
||||
x-logging-defaults: &logging-defaults
|
||||
driver: json-file
|
||||
options:
|
||||
max-size: "10m"
|
||||
max-file: "3"
|
||||
|
||||
# Usage:
|
||||
#
|
||||
# mkdir rpc && cd rpc
|
||||
#
|
||||
# git init
|
||||
# git remote add origin https://github.com/StakeSquid/ethereum-rpc-docker.git
|
||||
# git fetch origin vibe
|
||||
# git checkout origin/vibe
|
||||
#
|
||||
# docker run --rm alpine sh -c "printf '0x'; head -c32 /dev/urandom | xxd -p -c 64" > .jwtsecret
|
||||
#
|
||||
# env
|
||||
# ...
|
||||
# IP=$(curl ipinfo.io/ip)
|
||||
# DOMAIN=${IP}.traefik.me
|
||||
# COMPOSE_FILE=base.yml:rpc.yml:avalanche/go/avalanche-fuji-go-archive-leveldb.yml
|
||||
#
|
||||
# docker compose up -d
|
||||
#
|
||||
# curl -X POST https://${IP}.traefik.me/avalanche-fuji-archive \
|
||||
# -H "Content-Type: application/json" \
|
||||
# --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'
|
||||
|
||||
services:
|
||||
avalanche-fuji-archive-client:
|
||||
image: ${AVALANCHE_GO_IMAGE:-avaplatform/avalanchego}:${AVALANCHE_FUJI_GO_VERSION:-v1.13.0-fuji}
|
||||
sysctls:
|
||||
# TCP Performance
|
||||
net.ipv4.tcp_slow_start_after_idle: 0 # Disable slow start after idle
|
||||
net.ipv4.tcp_no_metrics_save: 1 # Disable metrics cache
|
||||
net.ipv4.tcp_rmem: 4096 87380 16777216 # Increase TCP read buffers
|
||||
net.ipv4.tcp_wmem: 4096 87380 16777216 # Increase TCP write buffers
|
||||
net.core.somaxconn: 32768 # Higher connection queue
|
||||
# Memory/Connection Management
|
||||
# net.core.netdev_max_backlog: 50000 # Increase network buffer
|
||||
net.ipv4.tcp_max_syn_backlog: 30000 # More SYN requests
|
||||
net.ipv4.tcp_max_tw_buckets: 2000000 # Allow more TIME_WAIT sockets
|
||||
ulimits:
|
||||
nofile: 1048576 # Max open files (for RPC/WS connections)
|
||||
user: root
|
||||
ports:
|
||||
- 10046:10046
|
||||
- 10046:10046/udp
|
||||
expose:
|
||||
- 9650
|
||||
- 9650
|
||||
entrypoint: [/avalanchego/build/avalanchego]
|
||||
command:
|
||||
- --chain-config-dir=/config/archive
|
||||
- --db-type=leveldb
|
||||
- --http-allowed-hosts=*
|
||||
- --http-host=
|
||||
- --network-id=fuji
|
||||
- --public-ip=${IP}
|
||||
- --staking-port=10046
|
||||
restart: unless-stopped
|
||||
stop_grace_period: 5m
|
||||
networks:
|
||||
- chains
|
||||
volumes:
|
||||
- ${AVALANCHE_FUJI_GO_ARCHIVE_LEVELDB_DATA:-avalanche-fuji-go-archive-leveldb}:/root/.avalanchego
|
||||
- ./avalanche/fuji:/config
|
||||
- /slowdisk:/slowdisk
|
||||
logging: *logging-defaults
|
||||
labels:
|
||||
- prometheus-scrape.enabled=false
|
||||
|
||||
avalanche-fuji-archive:
|
||||
image: nginx
|
||||
expose:
|
||||
- '80'
|
||||
environment:
|
||||
PROXY_HOST: avalanche-fuji-archive-client
|
||||
RPC_PATH: /ext/bc/C/rpc
|
||||
RPC_PORT: 9650
|
||||
WS_PATH: /ext/bc/C/ws
|
||||
WS_PORT: 9650
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
- avalanche-fuji-archive-client
|
||||
networks:
|
||||
- chains
|
||||
volumes:
|
||||
- ./nginx-proxy:/etc/nginx/templates
|
||||
logging: *logging-defaults
|
||||
labels:
|
||||
- prometheus-scrape.enabled=false
|
||||
- traefik.enable=true
|
||||
- traefik.http.middlewares.avalanche-fuji-go-archive-leveldb-stripprefix.stripprefix.prefixes=/avalanche-fuji-archive
|
||||
- traefik.http.services.avalanche-fuji-go-archive-leveldb.loadbalancer.server.port=80
|
||||
- ${NO_SSL:-traefik.http.routers.avalanche-fuji-go-archive-leveldb.entrypoints=websecure}
|
||||
- ${NO_SSL:-traefik.http.routers.avalanche-fuji-go-archive-leveldb.tls.certresolver=myresolver}
|
||||
- ${NO_SSL:-traefik.http.routers.avalanche-fuji-go-archive-leveldb.rule=Host(`$DOMAIN`) && (Path(`/avalanche-fuji-archive`) || Path(`/avalanche-fuji-archive/`))}
|
||||
- ${NO_SSL:+traefik.http.routers.avalanche-fuji-go-archive-leveldb.rule=Path(`/avalanche-fuji-archive`) || Path(`/avalanche-fuji-archive/`)}
|
||||
- traefik.http.routers.avalanche-fuji-go-archive-leveldb.middlewares=avalanche-fuji-go-archive-leveldb-stripprefix, ipallowlist
|
||||
|
||||
volumes:
|
||||
avalanche-fuji-go-archive-leveldb:
|
||||
|
||||
x-upstreams:
|
||||
- id: $${ID}
|
||||
labels:
|
||||
provider: $${PROVIDER}
|
||||
connection:
|
||||
generic:
|
||||
rpc:
|
||||
url: $${RPC_URL}
|
||||
ws:
|
||||
frameSize: 20Mb
|
||||
msgSize: 50Mb
|
||||
url: $${WS_URL}
|
||||
chain: avalanche
|
||||
method-groups:
|
||||
enabled:
|
||||
- debug
|
||||
- filter
|
||||
methods:
|
||||
disabled:
|
||||
enabled:
|
||||
- name: txpool_content # TODO: should be disabled for rollup nodes
|
||||
...
|
||||
128
avalanche/go/avalanche-fuji-go-pruned-pebbledb.yml
Normal file
128
avalanche/go/avalanche-fuji-go-pruned-pebbledb.yml
Normal file
@@ -0,0 +1,128 @@
|
||||
---
|
||||
x-logging-defaults: &logging-defaults
|
||||
driver: json-file
|
||||
options:
|
||||
max-size: "10m"
|
||||
max-file: "3"
|
||||
|
||||
# Usage:
|
||||
#
|
||||
# mkdir rpc && cd rpc
|
||||
#
|
||||
# git init
|
||||
# git remote add origin https://github.com/StakeSquid/ethereum-rpc-docker.git
|
||||
# git fetch origin vibe
|
||||
# git checkout origin/vibe
|
||||
#
|
||||
# docker run --rm alpine sh -c "printf '0x'; head -c32 /dev/urandom | xxd -p -c 64" > .jwtsecret
|
||||
#
|
||||
# env
|
||||
# ...
|
||||
# IP=$(curl ipinfo.io/ip)
|
||||
# DOMAIN=${IP}.traefik.me
|
||||
# COMPOSE_FILE=base.yml:rpc.yml:avalanche/go/avalanche-fuji-go-pruned-pebbledb.yml
|
||||
#
|
||||
# docker compose up -d
|
||||
#
|
||||
# curl -X POST https://${IP}.traefik.me/avalanche-fuji \
|
||||
# -H "Content-Type: application/json" \
|
||||
# --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'
|
||||
|
||||
services:
|
||||
avalanche-fuji-client:
|
||||
image: ${AVALANCHE_GO_IMAGE:-avaplatform/avalanchego}:${AVALANCHE_FUJI_GO_VERSION:-v1.13.0-fuji}
|
||||
sysctls:
|
||||
# TCP Performance
|
||||
net.ipv4.tcp_slow_start_after_idle: 0 # Disable slow start after idle
|
||||
net.ipv4.tcp_no_metrics_save: 1 # Disable metrics cache
|
||||
net.ipv4.tcp_rmem: 4096 87380 16777216 # Increase TCP read buffers
|
||||
net.ipv4.tcp_wmem: 4096 87380 16777216 # Increase TCP write buffers
|
||||
net.core.somaxconn: 32768 # Higher connection queue
|
||||
# Memory/Connection Management
|
||||
# net.core.netdev_max_backlog: 50000 # Increase network buffer
|
||||
net.ipv4.tcp_max_syn_backlog: 30000 # More SYN requests
|
||||
net.ipv4.tcp_max_tw_buckets: 2000000 # Allow more TIME_WAIT sockets
|
||||
ulimits:
|
||||
nofile: 1048576 # Max open files (for RPC/WS connections)
|
||||
user: root
|
||||
ports:
|
||||
- 10350:10350
|
||||
- 10350:10350/udp
|
||||
expose:
|
||||
- 9650
|
||||
- 9650
|
||||
entrypoint: [/avalanchego/build/avalanchego]
|
||||
command:
|
||||
- --chain-config-dir=/config/pruned
|
||||
- --db-type=pebbledb
|
||||
- --http-allowed-hosts=*
|
||||
- --http-host=
|
||||
- --network-id=fuji
|
||||
- --public-ip=${IP}
|
||||
- --staking-port=10350
|
||||
restart: unless-stopped
|
||||
stop_grace_period: 5m
|
||||
networks:
|
||||
- chains
|
||||
volumes:
|
||||
- ${AVALANCHE_FUJI_GO_PRUNED_PEBBLEDB_DATA:-avalanche-fuji-go-pruned-pebbledb}:/root/.avalanchego
|
||||
- ./avalanche/fuji:/config
|
||||
- /slowdisk:/slowdisk
|
||||
logging: *logging-defaults
|
||||
labels:
|
||||
- prometheus-scrape.enabled=false
|
||||
|
||||
avalanche-fuji:
|
||||
image: nginx
|
||||
expose:
|
||||
- '80'
|
||||
environment:
|
||||
PROXY_HOST: avalanche-fuji-client
|
||||
RPC_PATH: /ext/bc/C/rpc
|
||||
RPC_PORT: 9650
|
||||
WS_PATH: /ext/bc/C/ws
|
||||
WS_PORT: 9650
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
- avalanche-fuji-client
|
||||
networks:
|
||||
- chains
|
||||
volumes:
|
||||
- ./nginx-proxy:/etc/nginx/templates
|
||||
logging: *logging-defaults
|
||||
labels:
|
||||
- prometheus-scrape.enabled=false
|
||||
- traefik.enable=true
|
||||
- traefik.http.middlewares.avalanche-fuji-go-pruned-pebbledb-stripprefix.stripprefix.prefixes=/avalanche-fuji
|
||||
- traefik.http.services.avalanche-fuji-go-pruned-pebbledb.loadbalancer.server.port=80
|
||||
- ${NO_SSL:-traefik.http.routers.avalanche-fuji-go-pruned-pebbledb.entrypoints=websecure}
|
||||
- ${NO_SSL:-traefik.http.routers.avalanche-fuji-go-pruned-pebbledb.tls.certresolver=myresolver}
|
||||
- ${NO_SSL:-traefik.http.routers.avalanche-fuji-go-pruned-pebbledb.rule=Host(`$DOMAIN`) && (Path(`/avalanche-fuji`) || Path(`/avalanche-fuji/`))}
|
||||
- ${NO_SSL:+traefik.http.routers.avalanche-fuji-go-pruned-pebbledb.rule=Path(`/avalanche-fuji`) || Path(`/avalanche-fuji/`)}
|
||||
- traefik.http.routers.avalanche-fuji-go-pruned-pebbledb.middlewares=avalanche-fuji-go-pruned-pebbledb-stripprefix, ipallowlist
|
||||
|
||||
volumes:
|
||||
avalanche-fuji-go-pruned-pebbledb:
|
||||
|
||||
x-upstreams:
|
||||
- id: $${ID}
|
||||
labels:
|
||||
provider: $${PROVIDER}
|
||||
connection:
|
||||
generic:
|
||||
rpc:
|
||||
url: $${RPC_URL}
|
||||
ws:
|
||||
frameSize: 20Mb
|
||||
msgSize: 50Mb
|
||||
url: $${WS_URL}
|
||||
chain: avalanche
|
||||
method-groups:
|
||||
enabled:
|
||||
- debug
|
||||
- filter
|
||||
methods:
|
||||
disabled:
|
||||
enabled:
|
||||
- name: txpool_content # TODO: should be disabled for rollup nodes
|
||||
...
|
||||
128
avalanche/go/avalanche-mainnet-go-archive-leveldb.yml
Normal file
128
avalanche/go/avalanche-mainnet-go-archive-leveldb.yml
Normal file
@@ -0,0 +1,128 @@
|
||||
---
|
||||
x-logging-defaults: &logging-defaults
|
||||
driver: json-file
|
||||
options:
|
||||
max-size: "10m"
|
||||
max-file: "3"
|
||||
|
||||
# Usage:
|
||||
#
|
||||
# mkdir rpc && cd rpc
|
||||
#
|
||||
# git init
|
||||
# git remote add origin https://github.com/StakeSquid/ethereum-rpc-docker.git
|
||||
# git fetch origin vibe
|
||||
# git checkout origin/vibe
|
||||
#
|
||||
# docker run --rm alpine sh -c "printf '0x'; head -c32 /dev/urandom | xxd -p -c 64" > .jwtsecret
|
||||
#
|
||||
# env
|
||||
# ...
|
||||
# IP=$(curl ipinfo.io/ip)
|
||||
# DOMAIN=${IP}.traefik.me
|
||||
# COMPOSE_FILE=base.yml:rpc.yml:avalanche/go/avalanche-mainnet-go-archive-leveldb.yml
|
||||
#
|
||||
# docker compose up -d
|
||||
#
|
||||
# curl -X POST https://${IP}.traefik.me/avalanche-mainnet-archive \
|
||||
# -H "Content-Type: application/json" \
|
||||
# --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'
|
||||
|
||||
services:
|
||||
avalanche-mainnet-archive-client:
|
||||
image: ${AVALANCHE_GO_IMAGE:-avaplatform/avalanchego}:${AVALANCHE_MAINNET_GO_VERSION:-v1.13.0}
|
||||
sysctls:
|
||||
# TCP Performance
|
||||
net.ipv4.tcp_slow_start_after_idle: 0 # Disable slow start after idle
|
||||
net.ipv4.tcp_no_metrics_save: 1 # Disable metrics cache
|
||||
net.ipv4.tcp_rmem: 4096 87380 16777216 # Increase TCP read buffers
|
||||
net.ipv4.tcp_wmem: 4096 87380 16777216 # Increase TCP write buffers
|
||||
net.core.somaxconn: 32768 # Higher connection queue
|
||||
# Memory/Connection Management
|
||||
# net.core.netdev_max_backlog: 50000 # Increase network buffer
|
||||
net.ipv4.tcp_max_syn_backlog: 30000 # More SYN requests
|
||||
net.ipv4.tcp_max_tw_buckets: 2000000 # Allow more TIME_WAIT sockets
|
||||
ulimits:
|
||||
nofile: 1048576 # Max open files (for RPC/WS connections)
|
||||
user: root
|
||||
ports:
|
||||
- 12934:12934
|
||||
- 12934:12934/udp
|
||||
expose:
|
||||
- 9650
|
||||
- 9650
|
||||
entrypoint: [/avalanchego/build/avalanchego]
|
||||
command:
|
||||
- --chain-config-dir=/config/archive
|
||||
- --db-type=leveldb
|
||||
- --http-allowed-hosts=*
|
||||
- --http-host=
|
||||
- --network-id=mainnet
|
||||
- --public-ip=${IP}
|
||||
- --staking-port=12934
|
||||
restart: unless-stopped
|
||||
stop_grace_period: 5m
|
||||
networks:
|
||||
- chains
|
||||
volumes:
|
||||
- ${AVALANCHE_MAINNET_GO_ARCHIVE_LEVELDB_DATA:-avalanche-mainnet-go-archive-leveldb}:/root/.avalanchego
|
||||
- ./avalanche/mainnet:/config
|
||||
- /slowdisk:/slowdisk
|
||||
logging: *logging-defaults
|
||||
labels:
|
||||
- prometheus-scrape.enabled=false
|
||||
|
||||
avalanche-mainnet-archive:
|
||||
image: nginx
|
||||
expose:
|
||||
- '80'
|
||||
environment:
|
||||
PROXY_HOST: avalanche-mainnet-archive-client
|
||||
RPC_PATH: /ext/bc/C/rpc
|
||||
RPC_PORT: 9650
|
||||
WS_PATH: /ext/bc/C/ws
|
||||
WS_PORT: 9650
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
- avalanche-mainnet-archive-client
|
||||
networks:
|
||||
- chains
|
||||
volumes:
|
||||
- ./nginx-proxy:/etc/nginx/templates
|
||||
logging: *logging-defaults
|
||||
labels:
|
||||
- prometheus-scrape.enabled=false
|
||||
- traefik.enable=true
|
||||
- traefik.http.middlewares.avalanche-mainnet-go-archive-leveldb-stripprefix.stripprefix.prefixes=/avalanche-mainnet-archive
|
||||
- traefik.http.services.avalanche-mainnet-go-archive-leveldb.loadbalancer.server.port=80
|
||||
- ${NO_SSL:-traefik.http.routers.avalanche-mainnet-go-archive-leveldb.entrypoints=websecure}
|
||||
- ${NO_SSL:-traefik.http.routers.avalanche-mainnet-go-archive-leveldb.tls.certresolver=myresolver}
|
||||
- ${NO_SSL:-traefik.http.routers.avalanche-mainnet-go-archive-leveldb.rule=Host(`$DOMAIN`) && (Path(`/avalanche-mainnet-archive`) || Path(`/avalanche-mainnet-archive/`))}
|
||||
- ${NO_SSL:+traefik.http.routers.avalanche-mainnet-go-archive-leveldb.rule=Path(`/avalanche-mainnet-archive`) || Path(`/avalanche-mainnet-archive/`)}
|
||||
- traefik.http.routers.avalanche-mainnet-go-archive-leveldb.middlewares=avalanche-mainnet-go-archive-leveldb-stripprefix, ipallowlist
|
||||
|
||||
volumes:
|
||||
avalanche-mainnet-go-archive-leveldb:
|
||||
|
||||
x-upstreams:
|
||||
- id: $${ID}
|
||||
labels:
|
||||
provider: $${PROVIDER}
|
||||
connection:
|
||||
generic:
|
||||
rpc:
|
||||
url: $${RPC_URL}
|
||||
ws:
|
||||
frameSize: 20Mb
|
||||
msgSize: 50Mb
|
||||
url: $${WS_URL}
|
||||
chain: avalanche
|
||||
method-groups:
|
||||
enabled:
|
||||
- debug
|
||||
- filter
|
||||
methods:
|
||||
disabled:
|
||||
enabled:
|
||||
- name: txpool_content # TODO: should be disabled for rollup nodes
|
||||
...
|
||||
128
avalanche/go/avalanche-mainnet-go-pruned-pebbledb.yml
Normal file
128
avalanche/go/avalanche-mainnet-go-pruned-pebbledb.yml
Normal file
@@ -0,0 +1,128 @@
|
||||
---
|
||||
x-logging-defaults: &logging-defaults
|
||||
driver: json-file
|
||||
options:
|
||||
max-size: "10m"
|
||||
max-file: "3"
|
||||
|
||||
# Usage:
|
||||
#
|
||||
# mkdir rpc && cd rpc
|
||||
#
|
||||
# git init
|
||||
# git remote add origin https://github.com/StakeSquid/ethereum-rpc-docker.git
|
||||
# git fetch origin vibe
|
||||
# git checkout origin/vibe
|
||||
#
|
||||
# docker run --rm alpine sh -c "printf '0x'; head -c32 /dev/urandom | xxd -p -c 64" > .jwtsecret
|
||||
#
|
||||
# env
|
||||
# ...
|
||||
# IP=$(curl ipinfo.io/ip)
|
||||
# DOMAIN=${IP}.traefik.me
|
||||
# COMPOSE_FILE=base.yml:rpc.yml:avalanche/go/avalanche-mainnet-go-pruned-pebbledb.yml
|
||||
#
|
||||
# docker compose up -d
|
||||
#
|
||||
# curl -X POST https://${IP}.traefik.me/avalanche-mainnet \
|
||||
# -H "Content-Type: application/json" \
|
||||
# --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'
|
||||
|
||||
services:
|
||||
avalanche-mainnet-client:
|
||||
image: ${AVALANCHE_GO_IMAGE:-avaplatform/avalanchego}:${AVALANCHE_MAINNET_GO_VERSION:-v1.13.0}
|
||||
sysctls:
|
||||
# TCP Performance
|
||||
net.ipv4.tcp_slow_start_after_idle: 0 # Disable slow start after idle
|
||||
net.ipv4.tcp_no_metrics_save: 1 # Disable metrics cache
|
||||
net.ipv4.tcp_rmem: 4096 87380 16777216 # Increase TCP read buffers
|
||||
net.ipv4.tcp_wmem: 4096 87380 16777216 # Increase TCP write buffers
|
||||
net.core.somaxconn: 32768 # Higher connection queue
|
||||
# Memory/Connection Management
|
||||
# net.core.netdev_max_backlog: 50000 # Increase network buffer
|
||||
net.ipv4.tcp_max_syn_backlog: 30000 # More SYN requests
|
||||
net.ipv4.tcp_max_tw_buckets: 2000000 # Allow more TIME_WAIT sockets
|
||||
ulimits:
|
||||
nofile: 1048576 # Max open files (for RPC/WS connections)
|
||||
user: root
|
||||
ports:
|
||||
- 11929:11929
|
||||
- 11929:11929/udp
|
||||
expose:
|
||||
- 9650
|
||||
- 9650
|
||||
entrypoint: [/avalanchego/build/avalanchego]
|
||||
command:
|
||||
- --chain-config-dir=/config/pruned
|
||||
- --db-type=pebbledb
|
||||
- --http-allowed-hosts=*
|
||||
- --http-host=
|
||||
- --network-id=mainnet
|
||||
- --public-ip=${IP}
|
||||
- --staking-port=11929
|
||||
restart: unless-stopped
|
||||
stop_grace_period: 5m
|
||||
networks:
|
||||
- chains
|
||||
volumes:
|
||||
- ${AVALANCHE_MAINNET_GO_PRUNED_PEBBLEDB_DATA:-avalanche-mainnet-go-pruned-pebbledb}:/root/.avalanchego
|
||||
- ./avalanche/mainnet:/config
|
||||
- /slowdisk:/slowdisk
|
||||
logging: *logging-defaults
|
||||
labels:
|
||||
- prometheus-scrape.enabled=false
|
||||
|
||||
avalanche-mainnet:
|
||||
image: nginx
|
||||
expose:
|
||||
- '80'
|
||||
environment:
|
||||
PROXY_HOST: avalanche-mainnet-client
|
||||
RPC_PATH: /ext/bc/C/rpc
|
||||
RPC_PORT: 9650
|
||||
WS_PATH: /ext/bc/C/ws
|
||||
WS_PORT: 9650
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
- avalanche-mainnet-client
|
||||
networks:
|
||||
- chains
|
||||
volumes:
|
||||
- ./nginx-proxy:/etc/nginx/templates
|
||||
logging: *logging-defaults
|
||||
labels:
|
||||
- prometheus-scrape.enabled=false
|
||||
- traefik.enable=true
|
||||
- traefik.http.middlewares.avalanche-mainnet-go-pruned-pebbledb-stripprefix.stripprefix.prefixes=/avalanche-mainnet
|
||||
- traefik.http.services.avalanche-mainnet-go-pruned-pebbledb.loadbalancer.server.port=80
|
||||
- ${NO_SSL:-traefik.http.routers.avalanche-mainnet-go-pruned-pebbledb.entrypoints=websecure}
|
||||
- ${NO_SSL:-traefik.http.routers.avalanche-mainnet-go-pruned-pebbledb.tls.certresolver=myresolver}
|
||||
- ${NO_SSL:-traefik.http.routers.avalanche-mainnet-go-pruned-pebbledb.rule=Host(`$DOMAIN`) && (Path(`/avalanche-mainnet`) || Path(`/avalanche-mainnet/`))}
|
||||
- ${NO_SSL:+traefik.http.routers.avalanche-mainnet-go-pruned-pebbledb.rule=Path(`/avalanche-mainnet`) || Path(`/avalanche-mainnet/`)}
|
||||
- traefik.http.routers.avalanche-mainnet-go-pruned-pebbledb.middlewares=avalanche-mainnet-go-pruned-pebbledb-stripprefix, ipallowlist
|
||||
|
||||
volumes:
|
||||
avalanche-mainnet-go-pruned-pebbledb:
|
||||
|
||||
x-upstreams:
|
||||
- id: $${ID}
|
||||
labels:
|
||||
provider: $${PROVIDER}
|
||||
connection:
|
||||
generic:
|
||||
rpc:
|
||||
url: $${RPC_URL}
|
||||
ws:
|
||||
frameSize: 20Mb
|
||||
msgSize: 50Mb
|
||||
url: $${WS_URL}
|
||||
chain: avalanche
|
||||
method-groups:
|
||||
enabled:
|
||||
- debug
|
||||
- filter
|
||||
methods:
|
||||
disabled:
|
||||
enabled:
|
||||
- name: txpool_content # TODO: should be disabled for rollup nodes
|
||||
...
|
||||
4
avalanche/mainnet/archive/C/config.json
Normal file
4
avalanche/mainnet/archive/C/config.json
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"state-sync-enabled": false,
|
||||
"pruning-enabled": false
|
||||
}
|
||||
0
avalanche/mainnet/pruned/C/config.yml
Normal file
0
avalanche/mainnet/pruned/C/config.yml
Normal file
35
backup-http.yml
Normal file
35
backup-http.yml
Normal file
@@ -0,0 +1,35 @@
|
||||
services:
|
||||
backup-http:
|
||||
image: abassi/node-http-server:latest
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- /backup:/dir_to_serve
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.middlewares.backup-server-stripprefix.stripprefix.prefixes=/backup"
|
||||
- "traefik.http.services.backup-server.loadbalancer.server.port=8080"
|
||||
- "traefik.http.routers.backup-server.entrypoints=websecure"
|
||||
- "traefik.http.routers.backup-server.tls.certresolver=myresolver"
|
||||
- "traefik.http.routers.backup-server.rule=Host(`$DOMAIN`) && PathPrefix(`/backup`)"
|
||||
- "traefik.http.routers.backup-server.middlewares=backup-server-stripprefix"
|
||||
networks:
|
||||
- chains
|
||||
|
||||
backup-dav:
|
||||
image: 117503445/go_webdav:latest
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
- "dav=/null,/webdav,null,null,false"
|
||||
volumes:
|
||||
- /backup:/webdav
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.middlewares.backup-storage-stripprefix.stripprefix.prefixes=/dav"
|
||||
- "traefik.http.services.backup-storage.loadbalancer.server.port=80"
|
||||
- "traefik.http.routers.backup-storage.entrypoints=websecure"
|
||||
- "traefik.http.routers.backup-storage.tls.certresolver=myresolver"
|
||||
- "traefik.http.routers.backup-storage.rule=Host(`$DOMAIN`) && PathPrefix(`/dav`)"
|
||||
- "traefik.http.routers.backup-storage.middlewares=backup-storage-stripprefix"
|
||||
networks:
|
||||
- chains
|
||||
|
||||
51
backup-node.sh
Executable file
51
backup-node.sh
Executable file
@@ -0,0 +1,51 @@
|
||||
#!/bin/bash
|
||||
|
||||
backup_dir="/backup"
|
||||
|
||||
if [[ -n $2 ]]; then
|
||||
echo "upload backup via webdav to $2"
|
||||
else
|
||||
if [ ! -d "$backup_dir" ]; then
|
||||
echo "Error: /backup directory does not exist"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Read the JSON input and extract the list of keys
|
||||
keys=$(cat /root/rpc/$1.yml | yaml2json - | jq '.volumes' | jq -r 'keys[]')
|
||||
|
||||
# Iterate over the list of keys
|
||||
for key in $keys; do
|
||||
echo "Executing command with key: /var/lib/docker/volumes/rpc_$key/_data"
|
||||
|
||||
source_folder="/var/lib/docker/volumes/rpc_$key/_data"
|
||||
folder_size=$(du -shL "$source_folder" | awk '{
|
||||
size = $1
|
||||
sub(/[Kk]$/, "", size) # Remove 'K' suffix if present
|
||||
sub(/[Mm]$/, "", size) # Remove 'M' suffix if present
|
||||
sub(/[Gg]$/, "", size) # Remove 'G' suffix if present
|
||||
sub(/[Tt]$/, "", size) # Remove 'T' suffix if present
|
||||
if ($1 ~ /[Kk]$/) {
|
||||
size *= 0.001 # Convert kilobytes to gigabytes
|
||||
} else if ($1 ~ /[Mm]$/) {
|
||||
size *= 0.001 # Convert megabytes to gigabytes
|
||||
} else if ($1 ~ /[Tt]$/) {
|
||||
size *= 1000 # convert terabytes to gigabytes
|
||||
}
|
||||
print size
|
||||
}')
|
||||
|
||||
folder_size_gb=$(printf "%.0f" "$folder_size")
|
||||
|
||||
target_file="rpc_$key-$(date +'%Y-%m-%d-%H-%M-%S')-${folder_size_gb}G.tar.zst"
|
||||
|
||||
#echo "$target_file"
|
||||
|
||||
if [[ -n $2 ]]; then
|
||||
tar -cf - --dereference "$source_folder" | pv -pterb -s $(du -sb "$source_folder" | awk '{print $1}') | zstd | curl -X PUT --upload-file - "$2/null/uploading-$target_file"
|
||||
curl -X MOVE -H "Destination: /null/$target_file" "$2/null/uploading-$target_file"
|
||||
else
|
||||
tar -cf - --dereference "$source_folder" | pv -pterb -s $(du -sb "$source_folder" | awk '{print $1}') | zstd -o "/backup/uploading-$target_file"
|
||||
mv "/backup/uploading-$target_file" "/backup/$target_file"
|
||||
fi
|
||||
done
|
||||
1
base-mainnet-op-erigon-archive-trace.yml
Symbolic link
1
base-mainnet-op-erigon-archive-trace.yml
Symbolic link
@@ -0,0 +1 @@
|
||||
op/erigon/base-mainnet-op-erigon-archive-trace.yml
|
||||
1
base-mainnet-op-reth-archive-trace.yml
Symbolic link
1
base-mainnet-op-reth-archive-trace.yml
Symbolic link
@@ -0,0 +1 @@
|
||||
op/reth/base-mainnet-op-reth-archive-trace.yml
|
||||
1
base-mainnet-op-reth-pruned.yml
Symbolic link
1
base-mainnet-op-reth-pruned.yml
Symbolic link
@@ -0,0 +1 @@
|
||||
op/reth/base-mainnet-op-reth-pruned-trace.yml
|
||||
1
base-mainnet.yml
Symbolic link
1
base-mainnet.yml
Symbolic link
@@ -0,0 +1 @@
|
||||
op/geth/base-mainnet-op-geth-pruned-pebble-path.yml
|
||||
1
base-sepolia-op-reth-pruned.yml
Symbolic link
1
base-sepolia-op-reth-pruned.yml
Symbolic link
@@ -0,0 +1 @@
|
||||
op/reth/base-sepolia-op-reth-pruned-trace.yml
|
||||
1
base-sepolia.yml
Symbolic link
1
base-sepolia.yml
Symbolic link
@@ -0,0 +1 @@
|
||||
op/geth/base-sepolia-op-geth-pruned-pebble-path.yml
|
||||
6
base.yml
Normal file
6
base.yml
Normal file
@@ -0,0 +1,6 @@
|
||||
networks:
|
||||
chains:
|
||||
driver: bridge
|
||||
ipam:
|
||||
config:
|
||||
- subnet: ${CHAINS_SUBNET:-192.168.0.0/26}
|
||||
24
benchmark-proxy.yml
Normal file
24
benchmark-proxy.yml
Normal file
@@ -0,0 +1,24 @@
|
||||
services:
|
||||
benchmark-proxy:
|
||||
build:
|
||||
context: ./benchmark-proxy
|
||||
dockerfile: Dockerfile
|
||||
expose:
|
||||
- "8080"
|
||||
environment:
|
||||
- LISTEN_ADDR=:8080
|
||||
- SUMMARY_INTERVAL=60
|
||||
- PRIMARY_BACKEND=${BENCHMARK_PROXY_PRIMARY_BACKEND}
|
||||
- SECONDARY_BACKENDS=${BENCHMARK_PROXY_SECONDARY_BACKENDS}
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- chains
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.middlewares.benchmark-proxy-stripprefix.stripprefix.prefixes=/benchmark"
|
||||
- "traefik.http.services.benchmark-proxy.loadbalancer.server.port=8080"
|
||||
- "${NO_SSL:-traefik.http.routers.benchmark-proxy.entrypoints=websecure}"
|
||||
- "${NO_SSL:-traefik.http.routers.benchmark-proxy.tls.certresolver=myresolver}"
|
||||
- "${NO_SSL:-traefik.http.routers.benchmark-proxy.rule=Host(`$DOMAIN`) && PathPrefix(`/benchmark`)}"
|
||||
- "${NO_SSL:+traefik.http.routers.benchmark-proxy.rule=PathPrefix(`/benchmark`)}"
|
||||
- "traefik.http.routers.benchmark-proxy.middlewares=benchmark-proxy-stripprefix, ipwhitelist"
|
||||
27
benchmark-proxy/Dockerfile
Normal file
27
benchmark-proxy/Dockerfile
Normal file
@@ -0,0 +1,27 @@
|
||||
# Build stage
|
||||
FROM golang:1.21-alpine AS builder
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Initialize Go modules if not already done
|
||||
RUN go mod init benchmark-proxy
|
||||
|
||||
# Add the dependency before building
|
||||
RUN go get github.com/gorilla/websocket
|
||||
|
||||
# Copy source code
|
||||
COPY . .
|
||||
|
||||
# Build the application with CGO disabled for a static binary
|
||||
RUN CGO_ENABLED=0 go build -ldflags="-s -w" -o benchmark-proxy main.go
|
||||
|
||||
# Runtime stage (if you're using a multi-stage build)
|
||||
FROM alpine:latest
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Copy the binary from the build stage
|
||||
COPY --from=builder /app/benchmark-proxy .
|
||||
|
||||
# Run the application
|
||||
ENTRYPOINT ["./benchmark-proxy"]
|
||||
7
benchmark-proxy/go.mod
Normal file
7
benchmark-proxy/go.mod
Normal file
@@ -0,0 +1,7 @@
|
||||
module benchmark-proxy
|
||||
|
||||
go 1.21
|
||||
|
||||
require github.com/gorilla/websocket v1.5.1
|
||||
|
||||
require golang.org/x/net v0.17.0 // indirect
|
||||
4
benchmark-proxy/go.sum
Normal file
4
benchmark-proxy/go.sum
Normal file
@@ -0,0 +1,4 @@
|
||||
github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY=
|
||||
github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY=
|
||||
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
|
||||
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
|
||||
3235
benchmark-proxy/main.go
Normal file
3235
benchmark-proxy/main.go
Normal file
File diff suppressed because it is too large
Load Diff
22
benchmark_proxy_rust/Cargo.toml
Normal file
22
benchmark_proxy_rust/Cargo.toml
Normal file
@@ -0,0 +1,22 @@
|
||||
[package]
|
||||
name = "benchmark_proxy_rust"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
hyper = { version = "0.14", features = ["full"] }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
tokio-tungstenite = { version = "0.21", features = ["native-tls"] }
|
||||
log = "0.4"
|
||||
env_logger = "0.10"
|
||||
dashmap = "5.5"
|
||||
reqwest = { version = "0.11", features = ["json", "rustls-tls"], default-features = false }
|
||||
thiserror = "1.0"
|
||||
futures-util = "0.3"
|
||||
http = "0.2"
|
||||
url = "2.5"
|
||||
lazy_static = "1.4.0"
|
||||
343
benchmark_proxy_rust/src/block_height_tracker.rs
Normal file
343
benchmark_proxy_rust/src/block_height_tracker.rs
Normal file
@@ -0,0 +1,343 @@
|
||||
use crate::{config::AppConfig, structures::Backend};
|
||||
use dashmap::DashMap;
|
||||
use futures_util::{stream::SplitSink, SinkExt, StreamExt};
|
||||
use log::{debug, error, info, warn};
|
||||
use serde_json::json;
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
sync::{Arc, Mutex},
|
||||
time::{Duration, SystemTime},
|
||||
};
|
||||
use tokio::{
|
||||
net::TcpStream,
|
||||
sync::watch,
|
||||
task::JoinHandle,
|
||||
time::sleep,
|
||||
};
|
||||
use tokio_tungstenite::{
|
||||
connect_async,
|
||||
tungstenite::{protocol::Message as TungsteniteMessage, Error as TungsteniteError},
|
||||
MaybeTlsStream, WebSocketStream,
|
||||
};
|
||||
use url::Url;
|
||||
|
||||
const RECONNECT_DELAY: Duration = Duration::from_secs(10);
|
||||
|
||||
#[derive(serde::Deserialize, Debug)]
|
||||
struct SubscriptionMessage {
|
||||
#[allow(dead_code)] // May not be used if only checking method
|
||||
jsonrpc: Option<String>,
|
||||
method: Option<String>,
|
||||
params: Option<SubscriptionParams>,
|
||||
result: Option<serde_json::Value>, // For subscription ID confirmation
|
||||
id: Option<serde_json::Value>, // For request echo
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize, Debug)]
|
||||
struct SubscriptionParams {
|
||||
subscription: String,
|
||||
result: HeaderData,
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize, Debug)]
|
||||
struct HeaderData {
|
||||
number: String, // Hex string like "0x123"
|
||||
// Add other fields like "hash" if ever needed for more advanced logic
|
||||
}
|
||||
|
||||
pub struct BlockHeightTracker {
|
||||
config: Arc<AppConfig>,
|
||||
backends: Vec<Backend>,
|
||||
block_heights: Arc<DashMap<String, u64>>,
|
||||
last_update_times: Arc<DashMap<String, SystemTime>>,
|
||||
shutdown_tx: watch::Sender<bool>,
|
||||
tasks: Arc<Mutex<Vec<JoinHandle<()>>>>,
|
||||
enable_detailed_logs: bool,
|
||||
}
|
||||
|
||||
impl BlockHeightTracker {
|
||||
pub fn new(
|
||||
config: Arc<AppConfig>,
|
||||
all_backends: &[Backend],
|
||||
) -> Option<Arc<Self>> {
|
||||
if !config.enable_block_height_tracking {
|
||||
info!("BlockHeightTracker disabled by configuration.");
|
||||
return None;
|
||||
}
|
||||
|
||||
info!("Initializing BlockHeightTracker for {} backends.", all_backends.len());
|
||||
let (shutdown_tx, _shutdown_rx) = watch::channel(false); // _shutdown_rx cloned by tasks
|
||||
|
||||
Some(Arc::new(Self {
|
||||
config: config.clone(),
|
||||
backends: all_backends.to_vec(), // Clones the slice into a Vec
|
||||
block_heights: Arc::new(DashMap::new()),
|
||||
last_update_times: Arc::new(DashMap::new()),
|
||||
shutdown_tx,
|
||||
tasks: Arc::new(Mutex::new(Vec::new())),
|
||||
enable_detailed_logs: config.enable_detailed_logs,
|
||||
}))
|
||||
}
|
||||
|
||||
pub fn start_monitoring(self: Arc<Self>) {
|
||||
if self.backends.is_empty() {
|
||||
info!("BHT: No backends configured for monitoring.");
|
||||
return;
|
||||
}
|
||||
info!("BHT: Starting block height monitoring for {} backends.", self.backends.len());
|
||||
let mut tasks_guard = self.tasks.lock().unwrap();
|
||||
for backend in self.backends.clone() {
|
||||
// Only monitor if backend has a URL, primarily for non-primary roles or specific needs
|
||||
// For this implementation, we assume all backends in the list are candidates.
|
||||
let task_self = self.clone();
|
||||
let task_backend = backend.clone(); // Clone backend for the task
|
||||
let task_shutdown_rx = self.shutdown_tx.subscribe();
|
||||
|
||||
let task = tokio::spawn(async move {
|
||||
task_self
|
||||
.monitor_backend_connection(task_backend, task_shutdown_rx)
|
||||
.await;
|
||||
});
|
||||
tasks_guard.push(task);
|
||||
}
|
||||
}
|
||||
|
||||
async fn monitor_backend_connection(
|
||||
self: Arc<Self>,
|
||||
backend: Backend,
|
||||
mut shutdown_rx: watch::Receiver<bool>,
|
||||
) {
|
||||
info!("BHT: Starting monitoring for backend: {}", backend.name);
|
||||
loop { // Outer reconnect loop
|
||||
tokio::select! {
|
||||
biased;
|
||||
_ = shutdown_rx.changed() => {
|
||||
if *shutdown_rx.borrow() {
|
||||
info!("BHT: Shutdown signal received for {}, terminating monitoring.", backend.name);
|
||||
break; // Break outer reconnect loop
|
||||
}
|
||||
}
|
||||
_ = tokio::time::sleep(Duration::from_millis(10)) => { // Give a chance for shutdown signal before attempting connection
|
||||
// Proceed to connection attempt
|
||||
}
|
||||
}
|
||||
if *shutdown_rx.borrow() { break; }
|
||||
|
||||
|
||||
let mut ws_url = backend.url.clone();
|
||||
let scheme = if backend.url.scheme() == "https" { "wss" } else { "ws" };
|
||||
if let Err(_e) = ws_url.set_scheme(scheme) {
|
||||
error!("BHT: Failed to set scheme to {} for backend {}: {}", scheme, backend.name, backend.url);
|
||||
sleep(RECONNECT_DELAY).await;
|
||||
continue;
|
||||
}
|
||||
|
||||
if self.enable_detailed_logs {
|
||||
debug!("BHT: Attempting to connect to {} for backend {}", ws_url, backend.name);
|
||||
}
|
||||
|
||||
match connect_async(ws_url.clone()).await {
|
||||
Ok((ws_stream, _response)) => {
|
||||
if self.enable_detailed_logs {
|
||||
info!("BHT: Successfully connected to WebSocket for backend: {}", backend.name);
|
||||
}
|
||||
let (mut write, mut read) = ws_stream.split();
|
||||
|
||||
let subscribe_payload = json!({
|
||||
"jsonrpc": "2.0",
|
||||
"method": "eth_subscribe",
|
||||
"params": ["newHeads"],
|
||||
"id": 1 // Static ID for this subscription
|
||||
});
|
||||
|
||||
if let Err(e) = write.send(TungsteniteMessage::Text(subscribe_payload.to_string())).await {
|
||||
error!("BHT: Failed to send eth_subscribe to {}: {}. Retrying connection.", backend.name, e);
|
||||
// Connection will be retried by the outer loop after delay
|
||||
sleep(RECONNECT_DELAY).await;
|
||||
continue;
|
||||
}
|
||||
if self.enable_detailed_logs {
|
||||
debug!("BHT: Sent eth_subscribe payload to {}", backend.name);
|
||||
}
|
||||
|
||||
// Inner message reading loop
|
||||
loop {
|
||||
tokio::select! {
|
||||
biased;
|
||||
_ = shutdown_rx.changed() => {
|
||||
if *shutdown_rx.borrow() {
|
||||
info!("BHT: Shutdown signal for {}, closing WebSocket and stopping.", backend.name);
|
||||
// Attempt to close the WebSocket gracefully
|
||||
let _ = write.send(TungsteniteMessage::Close(None)).await;
|
||||
break; // Break inner message_read_loop
|
||||
}
|
||||
}
|
||||
maybe_message = read.next() => {
|
||||
match maybe_message {
|
||||
Some(Ok(message)) => {
|
||||
match message {
|
||||
TungsteniteMessage::Text(text_msg) => {
|
||||
if self.enable_detailed_logs {
|
||||
debug!("BHT: Received text from {}: {}", backend.name, text_msg);
|
||||
}
|
||||
match serde_json::from_str::<SubscriptionMessage>(&text_msg) {
|
||||
Ok(parsed_msg) => {
|
||||
if parsed_msg.method.as_deref() == Some("eth_subscription") {
|
||||
if let Some(params) = parsed_msg.params {
|
||||
let block_num_str = params.result.number;
|
||||
match u64::from_str_radix(block_num_str.trim_start_matches("0x"), 16) {
|
||||
Ok(block_num) => {
|
||||
self.block_heights.insert(backend.name.clone(), block_num);
|
||||
self.last_update_times.insert(backend.name.clone(), SystemTime::now());
|
||||
if self.enable_detailed_logs {
|
||||
debug!("BHT: Updated block height for {}: {} (raw: {})", backend.name, block_num, block_num_str);
|
||||
}
|
||||
}
|
||||
Err(e) => error!("BHT: Failed to parse block number hex '{}' for {}: {}", block_num_str, backend.name, e),
|
||||
}
|
||||
}
|
||||
} else if parsed_msg.id == Some(json!(1)) && parsed_msg.result.is_some() {
|
||||
if self.enable_detailed_logs {
|
||||
info!("BHT: Received subscription confirmation from {}: {:?}", backend.name, parsed_msg.result);
|
||||
}
|
||||
} else {
|
||||
if self.enable_detailed_logs {
|
||||
debug!("BHT: Received other JSON message from {}: {:?}", backend.name, parsed_msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
if self.enable_detailed_logs {
|
||||
warn!("BHT: Failed to parse JSON from {}: {}. Message: {}", backend.name, e, text_msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
TungsteniteMessage::Binary(bin_msg) => {
|
||||
if self.enable_detailed_logs {
|
||||
debug!("BHT: Received binary message from {} ({} bytes), ignoring.", backend.name, bin_msg.len());
|
||||
}
|
||||
}
|
||||
TungsteniteMessage::Ping(ping_data) => {
|
||||
if self.enable_detailed_logs { debug!("BHT: Received Ping from {}, sending Pong.", backend.name); }
|
||||
// tokio-tungstenite handles Pongs automatically by default if feature "rustls-pong" or "native-tls-pong" is enabled.
|
||||
// If not, manual send:
|
||||
// if let Err(e) = write.send(TungsteniteMessage::Pong(ping_data)).await {
|
||||
// error!("BHT: Failed to send Pong to {}: {}", backend.name, e);
|
||||
// break; // Break inner loop, connection might be unstable
|
||||
// }
|
||||
}
|
||||
TungsteniteMessage::Pong(_) => { /* Usually no action needed */ }
|
||||
TungsteniteMessage::Close(_) => {
|
||||
if self.enable_detailed_logs { info!("BHT: WebSocket closed by server for {}.", backend.name); }
|
||||
break; // Break inner loop
|
||||
}
|
||||
TungsteniteMessage::Frame(_) => { /* Raw frame, usually not handled directly */ }
|
||||
}
|
||||
}
|
||||
Some(Err(e)) => {
|
||||
match e {
|
||||
TungsteniteError::ConnectionClosed | TungsteniteError::AlreadyClosed => {
|
||||
if self.enable_detailed_logs { info!("BHT: WebSocket connection closed for {}.", backend.name); }
|
||||
}
|
||||
_ => {
|
||||
error!("BHT: Error reading from WebSocket for {}: {:?}. Attempting reconnect.", backend.name, e);
|
||||
}
|
||||
}
|
||||
break; // Break inner loop, will trigger reconnect
|
||||
}
|
||||
None => {
|
||||
if self.enable_detailed_logs { info!("BHT: WebSocket stream ended for {}. Attempting reconnect.", backend.name); }
|
||||
break; // Break inner loop, will trigger reconnect
|
||||
}
|
||||
}
|
||||
}
|
||||
} // End of inner select
|
||||
if *shutdown_rx.borrow() { break; } // Ensure inner loop breaks if shutdown occurred
|
||||
} // End of inner message reading loop
|
||||
}
|
||||
Err(e) => {
|
||||
warn!("BHT: Failed to connect to WebSocket for backend {}: {:?}. Retrying after delay.", backend.name, e);
|
||||
}
|
||||
}
|
||||
// If we are here, it means the connection was dropped or failed. Wait before retrying.
|
||||
if !*shutdown_rx.borrow() { // Don't sleep if shutting down
|
||||
sleep(RECONNECT_DELAY).await;
|
||||
}
|
||||
} // End of outer reconnect loop
|
||||
info!("BHT: Stopped monitoring backend {}.", backend.name);
|
||||
}
|
||||
|
||||
pub fn is_secondary_behind(&self, secondary_name: &str) -> bool {
|
||||
if !self.config.enable_block_height_tracking { return false; } // If tracking is off, assume not behind
|
||||
|
||||
let primary_info = self.backends.iter().find(|b| b.role == "primary");
|
||||
let primary_name = match primary_info {
|
||||
Some(b) => b.name.clone(),
|
||||
None => {
|
||||
if self.enable_detailed_logs {
|
||||
warn!("BHT: No primary backend configured for is_secondary_behind check.");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
let primary_height_opt = self.block_heights.get(&primary_name).map(|h_ref| *h_ref.value());
|
||||
|
||||
let primary_height = match primary_height_opt {
|
||||
Some(h) => h,
|
||||
None => {
|
||||
if self.enable_detailed_logs {
|
||||
debug!("BHT: Primary '{}' height unknown for is_secondary_behind check with {}.", primary_name, secondary_name);
|
||||
}
|
||||
return false; // Primary height unknown, can't reliably determine if secondary is behind
|
||||
}
|
||||
};
|
||||
|
||||
let secondary_height_opt = self.block_heights.get(secondary_name).map(|h_ref| *h_ref.value());
|
||||
|
||||
match secondary_height_opt {
|
||||
Some(secondary_height_val) => {
|
||||
if primary_height > secondary_height_val {
|
||||
let diff = primary_height - secondary_height_val;
|
||||
let is_behind = diff > self.config.max_blocks_behind;
|
||||
if self.enable_detailed_logs && is_behind {
|
||||
debug!("BHT: Secondary '{}' (height {}) is behind primary '{}' (height {}). Diff: {}, Max allowed: {}",
|
||||
secondary_name, secondary_height_val, primary_name, primary_height, diff, self.config.max_blocks_behind);
|
||||
}
|
||||
return is_behind;
|
||||
}
|
||||
false // Secondary is not behind or is ahead
|
||||
}
|
||||
None => {
|
||||
if self.enable_detailed_logs {
|
||||
debug!("BHT: Secondary '{}' height unknown, considering it behind primary '{}' (height {}).", secondary_name, primary_name, primary_height);
|
||||
}
|
||||
true // Secondary height unknown, assume it's behind if primary height is known
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_block_height_status(&self) -> HashMap<String, u64> {
|
||||
self.block_heights
|
||||
.iter()
|
||||
.map(|entry| (entry.key().clone(), *entry.value()))
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub async fn stop(&self) {
|
||||
info!("BHT: Sending shutdown signal to all monitoring tasks...");
|
||||
if self.shutdown_tx.send(true).is_err() {
|
||||
error!("BHT: Failed to send shutdown signal. Tasks might not terminate gracefully.");
|
||||
}
|
||||
|
||||
let mut tasks_guard = self.tasks.lock().unwrap();
|
||||
info!("BHT: Awaiting termination of {} monitoring tasks...", tasks_guard.len());
|
||||
for task in tasks_guard.drain(..) {
|
||||
if let Err(e) = task.await {
|
||||
error!("BHT: Error awaiting task termination: {:?}", e);
|
||||
}
|
||||
}
|
||||
info!("BHT: All monitoring tasks terminated.");
|
||||
}
|
||||
}
|
||||
169
benchmark_proxy_rust/src/config.rs
Normal file
169
benchmark_proxy_rust/src/config.rs
Normal file
@@ -0,0 +1,169 @@
|
||||
use std::env;
|
||||
use std::str::FromStr;
|
||||
use std::time::Duration;
|
||||
use url::Url;
|
||||
use thiserror::Error;
|
||||
use log::{warn, info};
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum ConfigError {
|
||||
#[error("Failed to parse environment variable '{var_name}': {source}")]
|
||||
ParseError {
|
||||
var_name: String,
|
||||
source: Box<dyn std::error::Error + Send + Sync>,
|
||||
},
|
||||
#[error("Missing required environment variable: {var_name}")]
|
||||
MissingVariable { var_name: String },
|
||||
#[error("Invalid URL format for '{var_name}': {url_str} - {source}")]
|
||||
UrlParseError {
|
||||
var_name: String,
|
||||
url_str: String,
|
||||
source: url::ParseError,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct AppConfig {
|
||||
pub listen_addr: String,
|
||||
pub primary_backend_url: Url,
|
||||
pub secondary_backend_urls: Vec<Url>,
|
||||
pub summary_interval_secs: u64,
|
||||
pub enable_detailed_logs: bool,
|
||||
pub enable_secondary_probing: bool,
|
||||
pub probe_interval_secs: u64,
|
||||
pub min_delay_buffer_ms: u64,
|
||||
pub probe_methods: Vec<String>,
|
||||
pub enable_block_height_tracking: bool,
|
||||
pub max_blocks_behind: u64,
|
||||
pub enable_expensive_method_routing: bool,
|
||||
pub max_body_size_bytes: usize,
|
||||
pub http_client_timeout_secs: u64,
|
||||
pub request_context_timeout_secs: u64,
|
||||
}
|
||||
|
||||
// Helper function to get and parse environment variables
|
||||
fn get_env_var<T: FromStr>(key: &str, default_value: T) -> T
|
||||
where
|
||||
<T as FromStr>::Err: std::fmt::Display,
|
||||
{
|
||||
match env::var(key) {
|
||||
Ok(val_str) => match val_str.parse::<T>() {
|
||||
Ok(val) => val,
|
||||
Err(e) => {
|
||||
warn!(
|
||||
"Failed to parse environment variable '{}' with value '{}': {}. Using default: {:?}",
|
||||
key, val_str, e, default_value
|
||||
);
|
||||
default_value
|
||||
}
|
||||
},
|
||||
Err(_) => default_value,
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function for boolean environment variables
|
||||
fn get_env_var_bool(key: &str, default_value: bool) -> bool {
|
||||
match env::var(key) {
|
||||
Ok(val_str) => val_str.to_lowercase() == "true",
|
||||
Err(_) => default_value,
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function for Vec<String> from comma-separated string
|
||||
fn get_env_var_vec_string(key: &str, default_value: Vec<String>) -> Vec<String> {
|
||||
match env::var(key) {
|
||||
Ok(val_str) => {
|
||||
if val_str.is_empty() {
|
||||
default_value
|
||||
} else {
|
||||
val_str.split(',').map(|s| s.trim().to_string()).collect()
|
||||
}
|
||||
}
|
||||
Err(_) => default_value,
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function for Vec<Url> from comma-separated string
|
||||
fn get_env_var_vec_url(key: &str, default_value: Vec<Url>) -> Result<Vec<Url>, ConfigError> {
|
||||
match env::var(key) {
|
||||
Ok(val_str) => {
|
||||
if val_str.is_empty() {
|
||||
return Ok(default_value);
|
||||
}
|
||||
val_str
|
||||
.split(',')
|
||||
.map(|s| s.trim())
|
||||
.filter(|s| !s.is_empty())
|
||||
.map(|url_str| {
|
||||
Url::parse(url_str).map_err(|e| ConfigError::UrlParseError {
|
||||
var_name: key.to_string(),
|
||||
url_str: url_str.to_string(),
|
||||
source: e,
|
||||
})
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
Err(_) => Ok(default_value),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub fn load_from_env() -> Result<AppConfig, ConfigError> {
|
||||
info!("Loading configuration from environment variables...");
|
||||
|
||||
let primary_backend_url_str = env::var("PRIMARY_BACKEND_URL").map_err(|_| {
|
||||
ConfigError::MissingVariable {
|
||||
var_name: "PRIMARY_BACKEND_URL".to_string(),
|
||||
}
|
||||
})?;
|
||||
let primary_backend_url =
|
||||
Url::parse(&primary_backend_url_str).map_err(|e| ConfigError::UrlParseError {
|
||||
var_name: "PRIMARY_BACKEND_URL".to_string(),
|
||||
url_str: primary_backend_url_str,
|
||||
source: e,
|
||||
})?;
|
||||
|
||||
let secondary_backend_urls = get_env_var_vec_url("SECONDARY_BACKEND_URLS", Vec::new())?;
|
||||
|
||||
let config = AppConfig {
|
||||
listen_addr: get_env_var("LISTEN_ADDR", "127.0.0.1:8080".to_string()),
|
||||
primary_backend_url,
|
||||
secondary_backend_urls,
|
||||
summary_interval_secs: get_env_var("SUMMARY_INTERVAL_SECS", 60),
|
||||
enable_detailed_logs: get_env_var_bool("ENABLE_DETAILED_LOGS", false),
|
||||
enable_secondary_probing: get_env_var_bool("ENABLE_SECONDARY_PROBING", true),
|
||||
probe_interval_secs: get_env_var("PROBE_INTERVAL_SECS", 10),
|
||||
min_delay_buffer_ms: get_env_var("MIN_DELAY_BUFFER_MS", 500),
|
||||
probe_methods: get_env_var_vec_string(
|
||||
"PROBE_METHODS",
|
||||
vec!["eth_blockNumber".to_string(), "net_version".to_string()],
|
||||
),
|
||||
enable_block_height_tracking: get_env_var_bool("ENABLE_BLOCK_HEIGHT_TRACKING", true),
|
||||
max_blocks_behind: get_env_var("MAX_BLOCKS_BEHIND", 5),
|
||||
enable_expensive_method_routing: get_env_var_bool("ENABLE_EXPENSIVE_METHOD_ROUTING", false),
|
||||
max_body_size_bytes: get_env_var("MAX_BODY_SIZE_BYTES", 10 * 1024 * 1024), // 10MB
|
||||
http_client_timeout_secs: get_env_var("HTTP_CLIENT_TIMEOUT_SECS", 30),
|
||||
request_context_timeout_secs: get_env_var("REQUEST_CONTEXT_TIMEOUT_SECS", 35),
|
||||
};
|
||||
|
||||
info!("Configuration loaded successfully: {:?}", config);
|
||||
Ok(config)
|
||||
}
|
||||
|
||||
impl AppConfig {
|
||||
pub fn http_client_timeout(&self) -> Duration {
|
||||
Duration::from_secs(self.http_client_timeout_secs)
|
||||
}
|
||||
|
||||
pub fn request_context_timeout(&self) -> Duration {
|
||||
Duration::from_secs(self.request_context_timeout_secs)
|
||||
}
|
||||
|
||||
pub fn summary_interval(&self) -> Duration {
|
||||
Duration::from_secs(self.summary_interval_secs)
|
||||
}
|
||||
|
||||
pub fn probe_interval(&self) -> Duration {
|
||||
Duration::from_secs(self.probe_interval_secs)
|
||||
}
|
||||
}
|
||||
12
benchmark_proxy_rust/src/main.rs
Normal file
12
benchmark_proxy_rust/src/main.rs
Normal file
@@ -0,0 +1,12 @@
|
||||
pub mod structures;
|
||||
pub mod config;
|
||||
pub mod stats_collector;
|
||||
pub mod secondary_probe;
|
||||
pub mod block_height_tracker;
|
||||
pub mod rpc_utils;
|
||||
pub mod request_handler;
|
||||
pub mod websocket_handler;
|
||||
|
||||
fn main() {
|
||||
println!("Hello, world!");
|
||||
}
|
||||
272
benchmark_proxy_rust/src/request_handler.rs
Normal file
272
benchmark_proxy_rust/src/request_handler.rs
Normal file
@@ -0,0 +1,272 @@
|
||||
use bytes::Bytes;
|
||||
use hyper::{Body, Request, Response, StatusCode};
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
use tokio::sync::mpsc;
|
||||
use log;
|
||||
|
||||
use crate::config::AppConfig;
|
||||
use crate::stats_collector::StatsCollector;
|
||||
use crate::secondary_probe::SecondaryProbe;
|
||||
use crate::block_height_tracker::BlockHeightTracker;
|
||||
use crate::structures::{Backend, BatchInfo};
|
||||
use crate::rpc_utils;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum BackendResult {
|
||||
Success {
|
||||
backend_name: String,
|
||||
response: reqwest::Response, // Send the whole reqwest::Response
|
||||
duration: std::time::Duration,
|
||||
},
|
||||
Error {
|
||||
backend_name: String,
|
||||
error: reqwest::Error, // Send the reqwest::Error
|
||||
duration: std::time::Duration,
|
||||
},
|
||||
}
|
||||
|
||||
fn calculate_secondary_delay(
|
||||
batch_info: &crate::structures::BatchInfo,
|
||||
probe: &Option<Arc<crate::secondary_probe::SecondaryProbe>>,
|
||||
stats: &Arc<crate::stats_collector::StatsCollector>,
|
||||
_config: &Arc<crate::config::AppConfig>, // _config might be used later for more complex logic
|
||||
) -> std::time::Duration {
|
||||
let mut max_delay = std::time::Duration::from_millis(0);
|
||||
let default_delay = std::time::Duration::from_millis(25); // Default from Go
|
||||
|
||||
if batch_info.methods.is_empty() {
|
||||
return default_delay;
|
||||
}
|
||||
|
||||
for method_name in &batch_info.methods {
|
||||
let current_method_delay = if let Some(p) = probe {
|
||||
p.get_delay_for_method(method_name)
|
||||
} else {
|
||||
// This will use the stubbed method from StatsCollector which currently returns 25ms
|
||||
stats.get_primary_p75_for_method(method_name)
|
||||
};
|
||||
if current_method_delay > max_delay {
|
||||
max_delay = current_method_delay;
|
||||
}
|
||||
}
|
||||
|
||||
if max_delay == std::time::Duration::from_millis(0) { // if all methods were unknown or had 0 delay
|
||||
if let Some(p) = probe {
|
||||
// Go code uses: probe.minResponseTime + probe.minDelayBuffer
|
||||
// probe.get_delay_for_method("") would approximate this if it falls back to min_response_time + buffer
|
||||
return p.get_delay_for_method(""); // Assuming empty method falls back to base delay
|
||||
}
|
||||
return default_delay;
|
||||
}
|
||||
max_delay
|
||||
}
|
||||
|
||||
pub async fn handle_http_request(
|
||||
req: Request<Body>,
|
||||
config: Arc<AppConfig>,
|
||||
stats_collector: Arc<StatsCollector>,
|
||||
http_client: Arc<reqwest::Client>,
|
||||
secondary_probe: Option<Arc<SecondaryProbe>>,
|
||||
block_height_tracker: Option<Arc<BlockHeightTracker>>,
|
||||
all_backends: Arc<Vec<Backend>>,
|
||||
) -> Result<Response<Body>, Box<dyn std::error::Error + Send + Sync>> {
|
||||
let _overall_start_time = std::time::Instant::now(); // To be used later with request_context_timeout
|
||||
|
||||
// 1. Read and limit request body
|
||||
let limited_body = hyper::body::Limited::new(req.into_body(), config.max_body_size_bytes);
|
||||
let body_bytes = match hyper::body::to_bytes(limited_body).await {
|
||||
Ok(bytes) => bytes,
|
||||
Err(e) => {
|
||||
log::error!("Failed to read request body or limit exceeded: {}", e);
|
||||
let mut err_resp = Response::new(Body::from(format!("Request body error: {}", e)));
|
||||
*err_resp.status_mut() = if e.is::<hyper::Error>() && e.downcast_ref::<hyper::Error>().map_or(false, |he| he.is_body_write_aborted() || format!("{}", he).contains("Too Large")) { // A bit heuristic for "Too Large"
|
||||
StatusCode::PAYLOAD_TOO_LARGE
|
||||
} else {
|
||||
StatusCode::BAD_REQUEST
|
||||
};
|
||||
return Ok(err_resp);
|
||||
}
|
||||
};
|
||||
|
||||
// 2. Parse Batch Info
|
||||
let batch_info = match rpc_utils::parse_batch_info(&body_bytes) {
|
||||
Ok(info) => info,
|
||||
Err(e) => {
|
||||
log::error!("Invalid JSON-RPC request: {}", e);
|
||||
let mut err_resp = Response::new(Body::from(format!("Invalid JSON-RPC: {}", e)));
|
||||
*err_resp.status_mut() = StatusCode::BAD_REQUEST;
|
||||
return Ok(err_resp);
|
||||
}
|
||||
};
|
||||
|
||||
let display_method = if batch_info.is_batch {
|
||||
format!("batch[{}]", batch_info.request_count)
|
||||
} else {
|
||||
batch_info.methods.get(0).cloned().unwrap_or_else(|| "unknown".to_string())
|
||||
};
|
||||
log::info!("Received request: Method: {}, IsBatch: {}, NumMethods: {}", display_method, batch_info.is_batch, batch_info.methods.len());
|
||||
|
||||
// 3. Calculate Secondary Delay
|
||||
let secondary_delay = calculate_secondary_delay(&batch_info, &secondary_probe, &stats_collector, &config);
|
||||
if config.enable_detailed_logs {
|
||||
log::debug!("Method: {}, Calculated secondary delay: {:?}", display_method, secondary_delay);
|
||||
}
|
||||
|
||||
// 4. Backend Filtering & Expensive Method Routing
|
||||
let mut target_backends: Vec<Backend> = (*all_backends).clone();
|
||||
|
||||
if batch_info.has_stateful {
|
||||
log::debug!("Stateful method detected in request '{}', targeting primary only.", display_method);
|
||||
target_backends.retain(|b| b.role == "primary");
|
||||
} else {
|
||||
// Filter by block height
|
||||
if let Some(bht) = &block_height_tracker {
|
||||
if config.enable_block_height_tracking { // Check if feature is enabled
|
||||
target_backends.retain(|b| {
|
||||
if b.role != "primary" && bht.is_secondary_behind(&b.name) {
|
||||
if config.enable_detailed_logs { log::info!("Skipping secondary {}: behind in block height for request {}", b.name, display_method); }
|
||||
// TODO: Add stat for skipped due to block height
|
||||
false
|
||||
} else { true }
|
||||
});
|
||||
}
|
||||
}
|
||||
// Filter by probe availability
|
||||
if let Some(sp) = &secondary_probe {
|
||||
if config.enable_secondary_probing { // Check if feature is enabled
|
||||
target_backends.retain(|b| {
|
||||
if b.role != "primary" && !sp.is_backend_available(&b.name) {
|
||||
if config.enable_detailed_logs { log::info!("Skipping secondary {}: not available via probe for request {}", b.name, display_method); }
|
||||
// TODO: Add stat for skipped due to probe unavailable
|
||||
false
|
||||
} else { true }
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let is_req_expensive = batch_info.methods.iter().any(|m| rpc_utils::is_expensive_method(m)) ||
|
||||
batch_info.methods.iter().any(|m| stats_collector.is_expensive_method_by_stats(m)); // Stubbed
|
||||
|
||||
if config.enable_expensive_method_routing && is_req_expensive && !batch_info.has_stateful {
|
||||
log::debug!("Expensive method detected in request {}. Attempting to route to a secondary.", display_method);
|
||||
// TODO: Complex expensive method routing logic.
|
||||
// For now, this placeholder doesn't change target_backends.
|
||||
// A real implementation would try to find the best secondary or stick to primary if none are suitable.
|
||||
}
|
||||
|
||||
// 5. Concurrent Request Dispatch
|
||||
let (response_tx, mut response_rx) = mpsc::channel::<BackendResult>(target_backends.len().max(1));
|
||||
let mut dispatched_count = 0;
|
||||
|
||||
for backend in target_backends { // target_backends is now filtered
|
||||
dispatched_count += 1;
|
||||
let task_body_bytes = body_bytes.clone();
|
||||
let task_http_client = http_client.clone();
|
||||
let task_response_tx = response_tx.clone();
|
||||
// task_backend_name, task_backend_url, task_backend_role are cloned from 'backend'
|
||||
let task_backend_name = backend.name.clone();
|
||||
let task_backend_url = backend.url.clone();
|
||||
let task_backend_role = backend.role.clone();
|
||||
let task_secondary_delay = secondary_delay;
|
||||
let task_config_detailed_logs = config.enable_detailed_logs;
|
||||
let task_http_timeout = config.http_client_timeout(); // Get Duration from config
|
||||
|
||||
tokio::spawn(async move {
|
||||
let backend_req_start_time = std::time::Instant::now();
|
||||
|
||||
if task_backend_role != "primary" {
|
||||
if task_config_detailed_logs {
|
||||
log::debug!("Secondary backend {} for request {} delaying for {:?}", task_backend_name, display_method, task_secondary_delay);
|
||||
}
|
||||
tokio::time::sleep(task_secondary_delay).await;
|
||||
}
|
||||
|
||||
let result = task_http_client
|
||||
.post(task_backend_url)
|
||||
.header("Content-Type", "application/json")
|
||||
// TODO: Copy relevant headers from original request 'req.headers()'
|
||||
.body(task_body_bytes)
|
||||
.timeout(task_http_timeout)
|
||||
.send()
|
||||
.await;
|
||||
|
||||
let duration = backend_req_start_time.elapsed();
|
||||
|
||||
match result {
|
||||
Ok(resp) => {
|
||||
if task_config_detailed_logs {
|
||||
log::debug!("Backend {} for request {} responded with status {}", task_backend_name, display_method, resp.status());
|
||||
}
|
||||
if task_response_tx.send(BackendResult::Success {
|
||||
backend_name: task_backend_name,
|
||||
response: resp,
|
||||
duration,
|
||||
}).await.is_err() {
|
||||
log::error!("Failed to send success to channel for request {}: receiver dropped", display_method);
|
||||
}
|
||||
}
|
||||
Err(err) => {
|
||||
if task_config_detailed_logs {
|
||||
log::error!("Backend {} for request {} request failed: {}", task_backend_name, display_method, err);
|
||||
}
|
||||
if task_response_tx.send(BackendResult::Error {
|
||||
backend_name: task_backend_name,
|
||||
error: err,
|
||||
duration,
|
||||
}).await.is_err() {
|
||||
log::error!("Failed to send error to channel for request {}: receiver dropped", display_method);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
drop(response_tx);
|
||||
|
||||
if dispatched_count == 0 {
|
||||
log::warn!("No backends available to dispatch request for method {}", display_method);
|
||||
// TODO: Add stat for no backend available
|
||||
let mut err_resp = Response::new(Body::from("No available backends for this request type."));
|
||||
*err_resp.status_mut() = StatusCode::SERVICE_UNAVAILABLE;
|
||||
return Ok(err_resp);
|
||||
}
|
||||
|
||||
// Placeholder: return the first received response
|
||||
if let Some(first_result) = response_rx.recv().await {
|
||||
if config.enable_detailed_logs {
|
||||
log::info!("First backend response for request {}: {:?}", display_method, first_result);
|
||||
}
|
||||
|
||||
match first_result {
|
||||
BackendResult::Success { backend_name: _, response: reqwest_resp, duration: _ } => {
|
||||
let mut hyper_resp_builder = Response::builder().status(reqwest_resp.status());
|
||||
for (name, value) in reqwest_resp.headers().iter() {
|
||||
hyper_resp_builder = hyper_resp_builder.header(name.clone(), value.clone());
|
||||
}
|
||||
let hyper_resp = hyper_resp_builder
|
||||
.body(Body::wrap_stream(reqwest_resp.bytes_stream()))
|
||||
.unwrap_or_else(|e| {
|
||||
log::error!("Error building response from backend for request {}: {}", display_method, e);
|
||||
let mut err_resp = Response::new(Body::from("Error processing backend response"));
|
||||
*err_resp.status_mut() = StatusCode::INTERNAL_SERVER_ERROR;
|
||||
err_resp
|
||||
});
|
||||
return Ok(hyper_resp);
|
||||
}
|
||||
BackendResult::Error { backend_name, error, duration: _ } => {
|
||||
log::error!("First response for request {} was an error from {}: {}", display_method, backend_name, error);
|
||||
let mut err_resp = Response::new(Body::from(format!("Error from backend {}: {}", backend_name, error)));
|
||||
*err_resp.status_mut() = StatusCode::BAD_GATEWAY;
|
||||
return Ok(err_resp);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
log::error!("No responses received from any dispatched backend for method {}", display_method);
|
||||
// TODO: Add stat for no response received
|
||||
let mut err_resp = Response::new(Body::from("No response from any backend."));
|
||||
*err_resp.status_mut() = StatusCode::GATEWAY_TIMEOUT;
|
||||
return Ok(err_resp);
|
||||
}
|
||||
// Note: Overall request context timeout and full response aggregation logic are still TODOs.
|
||||
}
|
||||
92
benchmark_proxy_rust/src/rpc_utils.rs
Normal file
92
benchmark_proxy_rust/src/rpc_utils.rs
Normal file
@@ -0,0 +1,92 @@
|
||||
use crate::structures::{BatchInfo, JsonRpcRequest};
|
||||
use std::collections::HashSet;
|
||||
use log;
|
||||
use serde_json; // Added for parsing
|
||||
|
||||
fn get_stateful_methods() -> HashSet<&'static str> {
|
||||
[
|
||||
"eth_newFilter", "eth_newBlockFilter", "eth_newPendingTransactionFilter",
|
||||
"eth_getFilterChanges", "eth_getFilterLogs", "eth_uninstallFilter",
|
||||
"eth_subscribe", "eth_unsubscribe", "eth_subscription", // "eth_subscription" is a notification, not a method client calls.
|
||||
// But if it appears in a batch for some reason, it's state-related.
|
||||
]
|
||||
.iter()
|
||||
.cloned()
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn get_expensive_methods() -> HashSet<&'static str> {
|
||||
[
|
||||
// Ethereum Debug API (typically Geth-specific)
|
||||
"debug_traceBlockByHash", "debug_traceBlockByNumber", "debug_traceCall", "debug_traceTransaction",
|
||||
"debug_storageRangeAt", "debug_getModifiedAccountsByHash", "debug_getModifiedAccountsByNumber",
|
||||
// Erigon/OpenEthereum Trace Module (more standard)
|
||||
"trace_block", "trace_call", "trace_callMany", "trace_filter", "trace_get", "trace_rawTransaction",
|
||||
"trace_replayBlockTransactions", "trace_replayTransaction", "trace_transaction",
|
||||
// Specific combinations that might be considered extra expensive
|
||||
"trace_replayBlockTransactions#vmTrace", // Example, depends on actual usage if # is method part
|
||||
"trace_replayTransaction#vmTrace",
|
||||
]
|
||||
.iter()
|
||||
.cloned()
|
||||
.collect()
|
||||
}
|
||||
|
||||
lazy_static::lazy_static! {
|
||||
static ref STATEFUL_METHODS: HashSet<&'static str> = get_stateful_methods();
|
||||
static ref EXPENSIVE_METHODS: HashSet<&'static str> = get_expensive_methods();
|
||||
}
|
||||
|
||||
pub fn is_stateful_method(method: &str) -> bool {
|
||||
STATEFUL_METHODS.contains(method)
|
||||
}
|
||||
|
||||
pub fn is_expensive_method(method: &str) -> bool {
|
||||
EXPENSIVE_METHODS.contains(method)
|
||||
}
|
||||
|
||||
pub fn parse_batch_info(body_bytes: &[u8]) -> Result<BatchInfo, String> {
|
||||
if body_bytes.is_empty() {
|
||||
return Err("Empty request body".to_string());
|
||||
}
|
||||
|
||||
// Try parsing as a batch (array) first
|
||||
match serde_json::from_slice::<Vec<JsonRpcRequest>>(body_bytes) {
|
||||
Ok(batch_reqs) => {
|
||||
if batch_reqs.is_empty() {
|
||||
return Err("Empty batch request".to_string());
|
||||
}
|
||||
let mut methods = Vec::new();
|
||||
let mut has_stateful = false;
|
||||
for req in &batch_reqs {
|
||||
methods.push(req.method.clone());
|
||||
if is_stateful_method(&req.method) {
|
||||
has_stateful = true;
|
||||
}
|
||||
}
|
||||
Ok(BatchInfo {
|
||||
is_batch: true,
|
||||
methods,
|
||||
request_count: batch_reqs.len(),
|
||||
has_stateful,
|
||||
})
|
||||
}
|
||||
Err(_e_batch) => {
|
||||
// If not a batch, try parsing as a single request
|
||||
match serde_json::from_slice::<JsonRpcRequest>(body_bytes) {
|
||||
Ok(single_req) => Ok(BatchInfo {
|
||||
is_batch: false,
|
||||
methods: vec![single_req.method.clone()],
|
||||
request_count: 1,
|
||||
has_stateful: is_stateful_method(&single_req.method),
|
||||
}),
|
||||
Err(_e_single) => {
|
||||
// Log the actual errors if needed for debugging, but return a generic one
|
||||
log::debug!("Failed to parse as batch: {}", _e_batch);
|
||||
log::debug!("Failed to parse as single: {}", _e_single);
|
||||
Err("Invalid JSON-RPC request format. Not a valid single request or batch.".to_string())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
383
benchmark_proxy_rust/src/secondary_probe.rs
Normal file
383
benchmark_proxy_rust/src/secondary_probe.rs
Normal file
@@ -0,0 +1,383 @@
|
||||
use crate::{
|
||||
config::AppConfig,
|
||||
structures::{Backend, JsonRpcRequest},
|
||||
};
|
||||
use chrono::Utc;
|
||||
use dashmap::DashMap;
|
||||
use log::{debug, error, info, warn};
|
||||
use reqwest::Client;
|
||||
use serde_json::json;
|
||||
use std::{
|
||||
cmp::min,
|
||||
sync::{
|
||||
atomic::{AtomicU32, Ordering},
|
||||
Arc, Mutex, RwLock,
|
||||
},
|
||||
time::{Duration, SystemTime},
|
||||
};
|
||||
use tokio::sync::watch;
|
||||
|
||||
const PROBE_REQUEST_COUNT: usize = 10;
|
||||
const DEFAULT_MIN_RESPONSE_TIME_MS: u64 = 15;
|
||||
const PROBE_CYCLE_DELAY_MS: u64 = 10;
|
||||
|
||||
pub struct SecondaryProbe {
|
||||
config: Arc<AppConfig>,
|
||||
backends: Vec<Backend>, // Only secondary backends
|
||||
client: Client,
|
||||
min_response_time: Arc<RwLock<Duration>>,
|
||||
method_timings: Arc<DashMap<String, Duration>>, // method_name -> min_duration
|
||||
backend_timings: Arc<DashMap<String, Duration>>, // backend_name -> min_duration
|
||||
|
||||
// Health state per backend
|
||||
backend_available: Arc<DashMap<String, bool>>,
|
||||
backend_error_count: Arc<DashMap<String, AtomicU32>>,
|
||||
backend_consecutive_success_count: Arc<DashMap<String, AtomicU32>>, // For recovery
|
||||
backend_last_success: Arc<DashMap<String, Mutex<SystemTime>>>,
|
||||
|
||||
last_probe_time: Arc<Mutex<SystemTime>>,
|
||||
failure_count: Arc<AtomicU32>, // Consecutive overall probe cycle failures
|
||||
last_success_time: Arc<Mutex<SystemTime>>, // Last time any probe in an overall cycle succeeded
|
||||
|
||||
shutdown_tx: watch::Sender<bool>,
|
||||
shutdown_rx: watch::Receiver<bool>,
|
||||
enable_detailed_logs: bool,
|
||||
}
|
||||
|
||||
impl SecondaryProbe {
|
||||
pub fn new(
|
||||
config: Arc<AppConfig>,
|
||||
all_backends: &[Backend],
|
||||
client: Client,
|
||||
) -> Option<Arc<Self>> {
|
||||
let secondary_backends: Vec<Backend> = all_backends
|
||||
.iter()
|
||||
.filter(|b| b.role.to_lowercase() == "secondary")
|
||||
.cloned()
|
||||
.collect();
|
||||
|
||||
if secondary_backends.is_empty() {
|
||||
info!("No secondary backends configured. SecondaryProbe will not be initialized.");
|
||||
return None;
|
||||
}
|
||||
|
||||
info!(
|
||||
"Initializing SecondaryProbe for {} secondary backends.",
|
||||
secondary_backends.len()
|
||||
);
|
||||
|
||||
let backend_available = Arc::new(DashMap::new());
|
||||
let backend_error_count = Arc::new(DashMap::new());
|
||||
let backend_consecutive_success_count = Arc::new(DashMap::new());
|
||||
let backend_last_success = Arc::new(DashMap::new());
|
||||
|
||||
for backend in &secondary_backends {
|
||||
backend_available.insert(backend.name.clone(), true);
|
||||
backend_error_count.insert(backend.name.clone(), AtomicU32::new(0));
|
||||
backend_consecutive_success_count.insert(backend.name.clone(), AtomicU32::new(0));
|
||||
backend_last_success.insert(backend.name.clone(), Mutex::new(SystemTime::now()));
|
||||
info!(" - Backend '{}' ({}) initialized as available.", backend.name, backend.url);
|
||||
}
|
||||
|
||||
let (shutdown_tx, shutdown_rx) = watch::channel(false);
|
||||
|
||||
Some(Arc::new(Self {
|
||||
config: config.clone(),
|
||||
backends: secondary_backends,
|
||||
client,
|
||||
min_response_time: Arc::new(RwLock::new(Duration::from_millis(
|
||||
DEFAULT_MIN_RESPONSE_TIME_MS, // Or load from config if needed
|
||||
))),
|
||||
method_timings: Arc::new(DashMap::new()),
|
||||
backend_timings: Arc::new(DashMap::new()),
|
||||
backend_available,
|
||||
backend_error_count,
|
||||
backend_consecutive_success_count,
|
||||
backend_last_success,
|
||||
last_probe_time: Arc::new(Mutex::new(SystemTime::now())),
|
||||
failure_count: Arc::new(AtomicU32::new(0)),
|
||||
last_success_time: Arc::new(Mutex::new(SystemTime::now())),
|
||||
shutdown_tx,
|
||||
shutdown_rx, // Receiver is cloneable
|
||||
enable_detailed_logs: config.enable_detailed_logs,
|
||||
}))
|
||||
}
|
||||
|
||||
pub fn start_periodic_probing(self: Arc<Self>) {
|
||||
if self.backends.is_empty() {
|
||||
info!("No secondary backends to probe. Periodic probing will not start.");
|
||||
return;
|
||||
}
|
||||
|
||||
info!(
|
||||
"Starting periodic probing for {} secondary backends. Probe interval: {}s. Probe methods: {:?}. Max errors: {}, Recovery threshold: {}.",
|
||||
self.backends.len(),
|
||||
self.config.probe_interval_secs,
|
||||
self.config.probe_methods,
|
||||
self.config.max_error_threshold,
|
||||
self.config.recovery_threshold
|
||||
);
|
||||
|
||||
// Run initial probe
|
||||
let initial_probe_self = self.clone();
|
||||
tokio::spawn(async move {
|
||||
if initial_probe_self.enable_detailed_logs {
|
||||
debug!("Running initial probe...");
|
||||
}
|
||||
initial_probe_self.run_probe().await;
|
||||
if initial_probe_self.enable_detailed_logs {
|
||||
debug!("Initial probe finished.");
|
||||
}
|
||||
});
|
||||
|
||||
// Start periodic probing task
|
||||
let mut interval = tokio::time::interval(self.config.probe_interval());
|
||||
let mut shutdown_rx_clone = self.shutdown_rx.clone();
|
||||
|
||||
tokio::spawn(async move {
|
||||
loop {
|
||||
tokio::select! {
|
||||
_ = interval.tick() => {
|
||||
if self.enable_detailed_logs {
|
||||
debug!("Running periodic probe cycle...");
|
||||
}
|
||||
self.run_probe().await;
|
||||
if self.enable_detailed_logs {
|
||||
debug!("Periodic probe cycle finished.");
|
||||
}
|
||||
}
|
||||
res = shutdown_rx_clone.changed() => {
|
||||
if res.is_err() || *shutdown_rx_clone.borrow() {
|
||||
info!("SecondaryProbe: Shutdown signal received or channel closed, stopping periodic probing.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
info!("SecondaryProbe: Periodic probing task has stopped.");
|
||||
});
|
||||
}
|
||||
|
||||
async fn run_probe(&self) {
|
||||
let mut successful_probes_in_overall_cycle = 0;
|
||||
let mut temp_method_timings: DashMap<String, Duration> = DashMap::new(); // method_name -> min_duration for this cycle
|
||||
let mut temp_backend_timings: DashMap<String, Duration> = DashMap::new(); // backend_name -> min_duration for this cycle
|
||||
let mut temp_overall_min_response_time = Duration::MAX;
|
||||
|
||||
for backend in &self.backends {
|
||||
let mut backend_cycle_successful_probes = 0;
|
||||
let mut backend_cycle_min_duration = Duration::MAX;
|
||||
|
||||
for method_name in &self.config.probe_methods {
|
||||
let mut method_min_duration_for_backend_this_cycle = Duration::MAX;
|
||||
|
||||
for i in 0..PROBE_REQUEST_COUNT {
|
||||
let probe_id = format!(
|
||||
"probe-{}-{}-{}-{}",
|
||||
backend.name,
|
||||
method_name,
|
||||
Utc::now().timestamp_nanos_opt().unwrap_or_else(|| SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap_or_default().as_nanos() as i64),
|
||||
i
|
||||
);
|
||||
let request_body = JsonRpcRequest {
|
||||
method: method_name.clone(),
|
||||
params: Some(json!([])),
|
||||
id: Some(json!(probe_id)),
|
||||
jsonrpc: Some("2.0".to_string()),
|
||||
};
|
||||
|
||||
let start_time = SystemTime::now();
|
||||
match self.client.post(backend.url.clone()).json(&request_body).timeout(self.config.http_client_timeout()).send().await {
|
||||
Ok(response) => {
|
||||
let duration = start_time.elapsed().unwrap_or_default();
|
||||
if response.status().is_success() {
|
||||
// TODO: Optionally parse JSON RPC response for error field
|
||||
backend_cycle_successful_probes += 1;
|
||||
successful_probes_in_overall_cycle += 1;
|
||||
|
||||
method_min_duration_for_backend_this_cycle = min(method_min_duration_for_backend_this_cycle, duration);
|
||||
backend_cycle_min_duration = min(backend_cycle_min_duration, duration);
|
||||
temp_overall_min_response_time = min(temp_overall_min_response_time, duration);
|
||||
|
||||
if self.enable_detailed_logs {
|
||||
debug!("Probe success: {} method {} ID {} took {:?}.", backend.name, method_name, probe_id, duration);
|
||||
}
|
||||
} else {
|
||||
if self.enable_detailed_logs {
|
||||
warn!("Probe failed (HTTP status {}): {} method {} ID {}. Body: {:?}", response.status(), backend.name, method_name, probe_id, response.text().await.unwrap_or_default());
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
if self.enable_detailed_logs {
|
||||
warn!("Probe error (request failed): {} method {} ID {}: {:?}", backend.name, method_name, probe_id, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
tokio::time::sleep(Duration::from_millis(PROBE_CYCLE_DELAY_MS)).await;
|
||||
} // End of PROBE_REQUEST_COUNT loop
|
||||
|
||||
if method_min_duration_for_backend_this_cycle != Duration::MAX {
|
||||
temp_method_timings
|
||||
.entry(method_name.clone())
|
||||
.and_modify(|current_min| *current_min = min(*current_min, method_min_duration_for_backend_this_cycle))
|
||||
.or_insert(method_min_duration_for_backend_this_cycle);
|
||||
}
|
||||
} // End of probe_methods loop
|
||||
|
||||
if backend_cycle_min_duration != Duration::MAX {
|
||||
temp_backend_timings.insert(backend.name.clone(), backend_cycle_min_duration);
|
||||
}
|
||||
self.update_backend_health(&backend.name, backend_cycle_successful_probes > 0);
|
||||
if self.enable_detailed_logs {
|
||||
debug!(
|
||||
"Probe sub-cycle for backend {}: {} successful probes. Min duration for this backend this cycle: {:?}. Current health: available={}",
|
||||
backend.name,
|
||||
backend_cycle_successful_probes,
|
||||
if backend_cycle_min_duration == Duration::MAX { None } else { Some(backend_cycle_min_duration) },
|
||||
self.is_backend_available(&backend.name)
|
||||
);
|
||||
}
|
||||
} // End of backends loop
|
||||
|
||||
// Update overall timings if any probe in the cycle was successful
|
||||
if successful_probes_in_overall_cycle > 0 {
|
||||
if temp_overall_min_response_time != Duration::MAX {
|
||||
let mut min_resp_time_guard = self.min_response_time.write().unwrap();
|
||||
*min_resp_time_guard = min(*min_resp_time_guard, temp_overall_min_response_time);
|
||||
if self.enable_detailed_logs {
|
||||
debug!("Global min_response_time updated to: {:?}", *min_resp_time_guard);
|
||||
}
|
||||
}
|
||||
|
||||
for entry in temp_method_timings.iter() {
|
||||
self.method_timings
|
||||
.entry(entry.key().clone())
|
||||
.and_modify(|current_min| *current_min = min(*current_min, *entry.value()))
|
||||
.or_insert(*entry.value());
|
||||
if self.enable_detailed_logs {
|
||||
debug!("Global method_timing for {} updated/set to: {:?}", entry.key(), *entry.value());
|
||||
}
|
||||
}
|
||||
|
||||
for entry in temp_backend_timings.iter() {
|
||||
self.backend_timings
|
||||
.entry(entry.key().clone())
|
||||
.and_modify(|current_min| *current_min = min(*current_min, *entry.value()))
|
||||
.or_insert(*entry.value());
|
||||
if self.enable_detailed_logs {
|
||||
debug!("Global backend_timing for {} updated/set to: {:?}", entry.key(), *entry.value());
|
||||
}
|
||||
}
|
||||
|
||||
self.failure_count.store(0, Ordering::Relaxed);
|
||||
*self.last_success_time.lock().unwrap() = SystemTime::now();
|
||||
if self.enable_detailed_logs {
|
||||
info!("Overall probe cycle completed with {} successes. Overall failure count reset.", successful_probes_in_overall_cycle);
|
||||
}
|
||||
|
||||
} else {
|
||||
let prev_failures = self.failure_count.fetch_add(1, Ordering::Relaxed);
|
||||
warn!(
|
||||
"Overall probe cycle completed with NO successful probes. Overall failure count incremented to {}.",
|
||||
prev_failures + 1
|
||||
);
|
||||
}
|
||||
|
||||
*self.last_probe_time.lock().unwrap() = SystemTime::now();
|
||||
}
|
||||
|
||||
fn update_backend_health(&self, backend_name: &str, is_cycle_success: bool) {
|
||||
let current_availability = self.is_backend_available(backend_name);
|
||||
let error_count_entry = self.backend_error_count.entry(backend_name.to_string()).or_insert_with(|| AtomicU32::new(0));
|
||||
let consecutive_success_entry = self.backend_consecutive_success_count.entry(backend_name.to_string()).or_insert_with(|| AtomicU32::new(0));
|
||||
|
||||
if is_cycle_success {
|
||||
error_count_entry.store(0, Ordering::Relaxed);
|
||||
consecutive_success_entry.fetch_add(1, Ordering::Relaxed);
|
||||
if let Some(mut last_success_guard) = self.backend_last_success.get_mut(backend_name) {
|
||||
*last_success_guard.lock().unwrap() = SystemTime::now();
|
||||
}
|
||||
|
||||
if !current_availability {
|
||||
let successes = consecutive_success_entry.load(Ordering::Relaxed);
|
||||
if successes >= self.config.recovery_threshold {
|
||||
self.backend_available.insert(backend_name.to_string(), true);
|
||||
info!("Backend {} recovered and is now AVAILABLE ({} consecutive successes met threshold {}).", backend_name, successes, self.config.recovery_threshold);
|
||||
consecutive_success_entry.store(0, Ordering::Relaxed); // Reset after recovery
|
||||
} else {
|
||||
if self.enable_detailed_logs {
|
||||
debug!("Backend {} had a successful probe cycle. Consecutive successes: {}. Needs {} for recovery.", backend_name, successes, self.config.recovery_threshold);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if self.enable_detailed_logs {
|
||||
debug!("Backend {} remains available, successful probe cycle.", backend_name);
|
||||
}
|
||||
}
|
||||
} else { // Probe cycle failed for this backend
|
||||
consecutive_success_entry.store(0, Ordering::Relaxed); // Reset consecutive successes on any failure
|
||||
let current_errors = error_count_entry.fetch_add(1, Ordering::Relaxed) + 1; // +1 because fetch_add returns previous value
|
||||
|
||||
if current_availability && current_errors >= self.config.max_error_threshold {
|
||||
self.backend_available.insert(backend_name.to_string(), false);
|
||||
warn!(
|
||||
"Backend {} has become UNAVAILABLE due to {} errors (threshold {}).",
|
||||
backend_name, current_errors, self.config.max_error_threshold
|
||||
);
|
||||
} else {
|
||||
if self.enable_detailed_logs {
|
||||
if current_availability {
|
||||
debug!("Backend {} is still available but error count increased to {}. Max errors before unavailable: {}", backend_name, current_errors, self.config.max_error_threshold);
|
||||
} else {
|
||||
debug!("Backend {} remains UNAVAILABLE, error count now {}.", backend_name, current_errors);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_delay_for_method(&self, method_name: &str) -> Duration {
|
||||
let base_delay = self
|
||||
.method_timings
|
||||
.get(method_name)
|
||||
.map(|timing_ref| *timing_ref.value())
|
||||
.unwrap_or_else(|| *self.min_response_time.read().unwrap()); // Read lock
|
||||
|
||||
let buffer = Duration::from_millis(self.config.min_delay_buffer_ms);
|
||||
let calculated_delay = base_delay.saturating_add(buffer);
|
||||
|
||||
let overall_failures = self.failure_count.load(Ordering::Relaxed);
|
||||
// Consider last_success_time to see if failures are recent and persistent
|
||||
let time_since_last_overall_success = SystemTime::now()
|
||||
.duration_since(*self.last_success_time.lock().unwrap()) // Lock for last_success_time
|
||||
.unwrap_or_default();
|
||||
|
||||
// Fallback logic: if many consecutive failures AND last success was long ago
|
||||
if overall_failures >= 3 && time_since_last_overall_success > self.config.probe_interval().saturating_mul(3) {
|
||||
warn!(
|
||||
"Probes failing ({} consecutive, last overall success {:?} ago). Using conservative fixed delay for method {}.",
|
||||
overall_failures, time_since_last_overall_success, method_name
|
||||
);
|
||||
return Duration::from_millis(self.config.min_delay_buffer_ms.saturating_mul(3));
|
||||
}
|
||||
|
||||
if self.enable_detailed_logs {
|
||||
debug!("Delay for method '{}': base {:?}, buffer {:?}, final {:?}", method_name, base_delay, buffer, calculated_delay);
|
||||
}
|
||||
calculated_delay
|
||||
}
|
||||
|
||||
pub fn is_backend_available(&self, backend_name: &str) -> bool {
|
||||
self.backend_available
|
||||
.get(backend_name)
|
||||
.map_or(false, |entry| *entry.value())
|
||||
}
|
||||
|
||||
pub fn stop(&self) {
|
||||
info!("SecondaryProbe: Sending shutdown signal...");
|
||||
if self.shutdown_tx.send(true).is_err() {
|
||||
error!("Failed to send shutdown signal to SecondaryProbe task. It might have already stopped or had no receiver.");
|
||||
}
|
||||
}
|
||||
}
|
||||
290
benchmark_proxy_rust/src/stats_collector.rs
Normal file
290
benchmark_proxy_rust/src/stats_collector.rs
Normal file
@@ -0,0 +1,290 @@
|
||||
use crate::structures::{ResponseStats, WebSocketStats, CuDataPoint, Backend};
|
||||
use crate::block_height_tracker::BlockHeightTracker;
|
||||
use crate::secondary_probe::SecondaryProbe;
|
||||
use std::time::{Duration, SystemTime};
|
||||
use std::sync::{Arc, Mutex, atomic::{AtomicU64, Ordering}};
|
||||
use dashmap::DashMap;
|
||||
use log::{debug, error, info, warn};
|
||||
|
||||
pub struct StatsCollector {
|
||||
pub request_stats: Arc<Mutex<Vec<ResponseStats>>>,
|
||||
pub method_stats: Arc<DashMap<String, Mutex<Vec<Duration>>>>, // method_name -> list of durations for primary
|
||||
pub backend_method_stats: Arc<DashMap<String, DashMap<String, Mutex<Vec<Duration>>>>>, // backend_name -> method_name -> list of durations
|
||||
pub backend_wins: Arc<DashMap<String, AtomicU64>>, // backend_name -> count
|
||||
pub method_backend_wins: Arc<DashMap<String, DashMap<String, AtomicU64>>>, // method_name -> backend_name -> count
|
||||
pub first_response_durations: Arc<Mutex<Vec<Duration>>>,
|
||||
pub actual_first_response_durations: Arc<Mutex<Vec<Duration>>>,
|
||||
pub method_first_response_durations: Arc<DashMap<String, Mutex<Vec<Duration>>>>,
|
||||
pub method_actual_first_response_durations: Arc<DashMap<String, Mutex<Vec<Duration>>>>,
|
||||
pub total_requests: Arc<AtomicU64>>,
|
||||
pub error_count: Arc<AtomicU64>>,
|
||||
pub skipped_secondary_requests: Arc<AtomicU64>>,
|
||||
pub ws_stats: Arc<Mutex<Vec<WebSocketStats>>>,
|
||||
pub total_ws_connections: Arc<AtomicU64>>,
|
||||
pub app_start_time: SystemTime,
|
||||
pub interval_start_time: Arc<Mutex<SystemTime>>,
|
||||
pub summary_interval: Duration,
|
||||
pub method_cu_prices: Arc<DashMap<String, u64>>,
|
||||
pub total_cu: Arc<AtomicU64>>,
|
||||
pub method_cu: Arc<DashMap<String, AtomicU64>>, // method_name -> total CU for this method in interval
|
||||
pub historical_cu: Arc<Mutex<Vec<CuDataPoint>>>,
|
||||
pub has_secondary_backends: bool,
|
||||
// Placeholders for probe and tracker - actual types will be defined later
|
||||
// pub secondary_probe: Option<Arc<SecondaryProbe>>,
|
||||
// pub block_height_tracker: Option<Arc<BlockHeightTracker>>,
|
||||
}
|
||||
|
||||
impl StatsCollector {
|
||||
pub fn new(summary_interval: Duration, has_secondary_backends: bool) -> Self {
|
||||
let method_cu_prices = Arc::new(DashMap::new());
|
||||
Self::init_cu_prices(&method_cu_prices);
|
||||
|
||||
StatsCollector {
|
||||
request_stats: Arc::new(Mutex::new(Vec::new())),
|
||||
method_stats: Arc::new(DashMap::new()),
|
||||
backend_method_stats: Arc::new(DashMap::new()),
|
||||
backend_wins: Arc::new(DashMap::new()),
|
||||
method_backend_wins: Arc::new(DashMap::new()),
|
||||
first_response_durations: Arc::new(Mutex::new(Vec::new())),
|
||||
actual_first_response_durations: Arc::new(Mutex::new(Vec::new())),
|
||||
method_first_response_durations: Arc::new(DashMap::new()),
|
||||
method_actual_first_response_durations: Arc::new(DashMap::new()),
|
||||
total_requests: Arc::new(AtomicU64::new(0)),
|
||||
error_count: Arc::new(AtomicU64::new(0)),
|
||||
skipped_secondary_requests: Arc::new(AtomicU64::new(0)),
|
||||
ws_stats: Arc::new(Mutex::new(Vec::new())),
|
||||
total_ws_connections: Arc::new(AtomicU64::new(0)),
|
||||
app_start_time: SystemTime::now(),
|
||||
interval_start_time: Arc::new(Mutex::new(SystemTime::now())),
|
||||
summary_interval,
|
||||
method_cu_prices,
|
||||
total_cu: Arc::new(AtomicU64::new(0)),
|
||||
method_cu: Arc::new(DashMap::new()),
|
||||
historical_cu: Arc::new(Mutex::new(Vec::new())),
|
||||
has_secondary_backends,
|
||||
}
|
||||
}
|
||||
|
||||
fn init_cu_prices(prices_map: &DashMap<String, u64>) {
|
||||
// Base CU
|
||||
prices_map.insert("eth_call".to_string(), 100);
|
||||
prices_map.insert("eth_estimateGas".to_string(), 150);
|
||||
prices_map.insert("eth_getLogs".to_string(), 200);
|
||||
prices_map.insert("eth_sendRawTransaction".to_string(), 250);
|
||||
prices_map.insert("trace_call".to_string(), 300);
|
||||
prices_map.insert("trace_replayBlockTransactions".to_string(), 500);
|
||||
// Default for unknown methods
|
||||
prices_map.insert("default".to_string(), 50);
|
||||
}
|
||||
|
||||
pub fn add_stats(&self, stats_vec: Vec<ResponseStats>) {
|
||||
if stats_vec.is_empty() {
|
||||
warn!("add_stats called with empty stats_vec");
|
||||
return;
|
||||
}
|
||||
|
||||
self.total_requests.fetch_add(1, Ordering::Relaxed);
|
||||
|
||||
let mut primary_stats: Option<&ResponseStats> = None;
|
||||
let mut winning_backend_name: Option<String> = None;
|
||||
let mut actual_first_response_duration: Option<Duration> = None;
|
||||
let mut first_response_duration_from_primary_or_fastest_secondary: Option<Duration> = None;
|
||||
|
||||
// Find the 'actual-first-response' if present and the primary response
|
||||
for stat in &stats_vec {
|
||||
if stat.backend_name == "actual-first-response" {
|
||||
actual_first_response_duration = Some(stat.duration);
|
||||
} else if stat.backend_name.contains("-primary") { // Assuming primary name contains "-primary"
|
||||
primary_stats = Some(stat);
|
||||
}
|
||||
}
|
||||
|
||||
let method_name = primary_stats.map_or_else(
|
||||
|| stats_vec.first().map_or_else(|| "unknown".to_string(), |s| s.method.clone()),
|
||||
|ps| ps.method.clone()
|
||||
);
|
||||
|
||||
|
||||
// Determine winning backend and first_response_duration_from_primary_or_fastest_secondary
|
||||
if self.has_secondary_backends {
|
||||
let mut fastest_duration = Duration::MAX;
|
||||
for stat in stats_vec.iter().filter(|s| s.backend_name != "actual-first-response" && s.error.is_none()) {
|
||||
if stat.duration < fastest_duration {
|
||||
fastest_duration = stat.duration;
|
||||
winning_backend_name = Some(stat.backend_name.clone());
|
||||
}
|
||||
}
|
||||
if fastest_duration != Duration::MAX {
|
||||
first_response_duration_from_primary_or_fastest_secondary = Some(fastest_duration);
|
||||
}
|
||||
} else {
|
||||
// If no secondary backends, primary is the winner if no error
|
||||
if let Some(ps) = primary_stats {
|
||||
if ps.error.is_none() {
|
||||
winning_backend_name = Some(ps.backend_name.clone());
|
||||
first_response_duration_from_primary_or_fastest_secondary = Some(ps.duration);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If no winner determined yet (e.g. all errored, or no secondary and primary errored),
|
||||
// and if primary_stats exists, consider it as the "winner" for error tracking purposes.
|
||||
if winning_backend_name.is_none() && primary_stats.is_some() {
|
||||
winning_backend_name = Some(primary_stats.unwrap().backend_name.clone());
|
||||
}
|
||||
|
||||
|
||||
// Update backend_wins and method_backend_wins
|
||||
if let Some(ref winner_name) = winning_backend_name {
|
||||
self.backend_wins.entry(winner_name.clone()).or_insert_with(|| AtomicU64::new(0)).fetch_add(1, Ordering::Relaxed);
|
||||
self.method_backend_wins.entry(method_name.clone()).or_default().entry(winner_name.clone()).or_insert_with(|| AtomicU64::new(0)).fetch_add(1, Ordering::Relaxed);
|
||||
}
|
||||
|
||||
// Update first_response_durations and actual_first_response_durations
|
||||
if let Some(duration) = first_response_duration_from_primary_or_fastest_secondary {
|
||||
self.first_response_durations.lock().unwrap().push(duration);
|
||||
self.method_first_response_durations.entry(method_name.clone()).or_insert_with(|| Mutex::new(Vec::new())).lock().unwrap().push(duration);
|
||||
}
|
||||
|
||||
if let Some(duration) = actual_first_response_duration {
|
||||
self.actual_first_response_durations.lock().unwrap().push(duration);
|
||||
self.method_actual_first_response_durations.entry(method_name.clone()).or_insert_with(|| Mutex::new(Vec::new())).lock().unwrap().push(duration);
|
||||
}
|
||||
|
||||
|
||||
let mut request_stats_guard = self.request_stats.lock().unwrap();
|
||||
for stat in stats_vec {
|
||||
if stat.backend_name == "actual-first-response" { // Already handled
|
||||
continue;
|
||||
}
|
||||
|
||||
request_stats_guard.push(stat.clone());
|
||||
|
||||
if stat.error.is_some() {
|
||||
if stat.error.as_deref() == Some("skipped by primary due to min_delay_buffer") {
|
||||
self.skipped_secondary_requests.fetch_add(1, Ordering::Relaxed);
|
||||
} else {
|
||||
self.error_count.fetch_add(1, Ordering::Relaxed);
|
||||
}
|
||||
}
|
||||
|
||||
// Update backend_method_stats for all backends
|
||||
self.backend_method_stats
|
||||
.entry(stat.backend_name.clone())
|
||||
.or_default()
|
||||
.entry(stat.method.clone())
|
||||
.or_insert_with(|| Mutex::new(Vec::new()))
|
||||
.lock()
|
||||
.unwrap()
|
||||
.push(stat.duration);
|
||||
|
||||
|
||||
// If the winning backend is primary and it's not a batch (batch handled separately), update method_stats and CUs
|
||||
// Assuming primary_stats contains the correct method name for CU calculation
|
||||
if let Some(ref winner_name_val) = winning_backend_name {
|
||||
if &stat.backend_name == winner_name_val && stat.backend_name.contains("-primary") && stat.error.is_none() {
|
||||
// Update method_stats (for primary)
|
||||
self.method_stats
|
||||
.entry(stat.method.clone())
|
||||
.or_insert_with(|| Mutex::new(Vec::new()))
|
||||
.lock()
|
||||
.unwrap()
|
||||
.push(stat.duration);
|
||||
|
||||
// Update CU
|
||||
let cu_price = self.method_cu_prices.get(&stat.method).map_or_else(
|
||||
|| self.method_cu_prices.get("default").map_or(0, |p| *p.value()),
|
||||
|p| *p.value()
|
||||
);
|
||||
if cu_price > 0 {
|
||||
self.total_cu.fetch_add(cu_price, Ordering::Relaxed);
|
||||
self.method_cu.entry(stat.method.clone()).or_insert_with(|| AtomicU64::new(0)).fetch_add(cu_price, Ordering::Relaxed);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_batch_stats(&self, methods: &[String], duration: Duration, backend_name: &str) {
|
||||
if !backend_name.contains("-primary") { // Only primary processes batches directly for now
|
||||
warn!("add_batch_stats called for non-primary backend: {}", backend_name);
|
||||
return;
|
||||
}
|
||||
|
||||
let mut batch_cu: u64 = 0;
|
||||
for method_name in methods {
|
||||
let cu_price = self.method_cu_prices.get(method_name).map_or_else(
|
||||
|| self.method_cu_prices.get("default").map_or(0, |p| *p.value()),
|
||||
|p| *p.value()
|
||||
);
|
||||
batch_cu += cu_price;
|
||||
|
||||
if cu_price > 0 {
|
||||
self.method_cu.entry(method_name.clone()).or_insert_with(|| AtomicU64::new(0)).fetch_add(cu_price, Ordering::Relaxed);
|
||||
}
|
||||
|
||||
// Update method_stats for each method in the batch on the primary
|
||||
self.method_stats
|
||||
.entry(method_name.clone())
|
||||
.or_insert_with(|| Mutex::new(Vec::new()))
|
||||
.lock()
|
||||
.unwrap()
|
||||
.push(duration); // Using the same duration for all methods in the batch as an approximation
|
||||
|
||||
// Update backend_method_stats
|
||||
self.backend_method_stats
|
||||
.entry(backend_name.to_string())
|
||||
.or_default()
|
||||
.entry(method_name.clone())
|
||||
.or_insert_with(|| Mutex::new(Vec::new()))
|
||||
.lock()
|
||||
.unwrap()
|
||||
.push(duration);
|
||||
}
|
||||
|
||||
if batch_cu > 0 {
|
||||
self.total_cu.fetch_add(batch_cu, Ordering::Relaxed);
|
||||
}
|
||||
// Note: total_requests is incremented by add_stats which should be called for the overall batch request
|
||||
}
|
||||
|
||||
|
||||
pub fn add_websocket_stats(&self, ws_stat: WebSocketStats) {
|
||||
if ws_stat.error.is_some() {
|
||||
self.error_count.fetch_add(1, Ordering::Relaxed);
|
||||
}
|
||||
self.ws_stats.lock().unwrap().push(ws_stat);
|
||||
self.total_ws_connections.fetch_add(1, Ordering::Relaxed);
|
||||
}
|
||||
|
||||
// STUBBED METHODS - to be implemented later
|
||||
pub fn get_primary_p75_for_method(&self, _method: &str) -> std::time::Duration {
|
||||
// Placeholder: return a default fixed duration
|
||||
log::debug!("StatsCollector::get_primary_p75_for_method called (stub)");
|
||||
std::time::Duration::from_millis(25) // Default from Go's calculateBatchDelay fallback
|
||||
}
|
||||
|
||||
pub fn get_primary_p50_for_method(&self, _method: &str) -> std::time::Duration {
|
||||
// Placeholder: return a default fixed duration
|
||||
log::debug!("StatsCollector::get_primary_p50_for_method called (stub)");
|
||||
std::time::Duration::from_millis(15)
|
||||
}
|
||||
|
||||
pub fn is_expensive_method_by_stats(&self, _method: &str) -> bool {
|
||||
// Placeholder: always return false
|
||||
log::debug!("StatsCollector::is_expensive_method_by_stats called (stub)");
|
||||
false
|
||||
}
|
||||
|
||||
pub fn select_best_secondary_for_expensive_method(
|
||||
&self,
|
||||
_method: &str,
|
||||
_backends: &[Backend],
|
||||
_block_height_tracker: &Option<Arc<BlockHeightTracker>>,
|
||||
_secondary_probe: &Option<Arc<SecondaryProbe>>,
|
||||
) -> Option<Backend> {
|
||||
// Placeholder: always return None
|
||||
log::debug!("StatsCollector::select_best_secondary_for_expensive_method called (stub)");
|
||||
None
|
||||
}
|
||||
}
|
||||
107
benchmark_proxy_rust/src/structures.rs
Normal file
107
benchmark_proxy_rust/src/structures.rs
Normal file
@@ -0,0 +1,107 @@
|
||||
use serde::{Serialize, Deserialize};
|
||||
use url::Url;
|
||||
use http::StatusCode;
|
||||
use std::time::{Duration, SystemTime};
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||
pub struct JsonRpcRequest {
|
||||
pub method: String,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub id: Option<serde_json::Value>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub jsonrpc: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub params: Option<serde_json::Value>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||
pub struct BatchInfo {
|
||||
pub is_batch: bool,
|
||||
pub methods: Vec<String>,
|
||||
pub request_count: usize,
|
||||
pub has_stateful: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||
pub struct Backend {
|
||||
#[serde(with = "url_serde")]
|
||||
pub url: Url,
|
||||
pub name: String,
|
||||
pub role: String, // Consider an enum BackendRole { Primary, Secondary } later
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||
pub struct ResponseStats {
|
||||
pub backend_name: String,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
#[serde(with = "http_serde_status_code_option", default)]
|
||||
pub status_code: Option<StatusCode>,
|
||||
#[serde(with = "humantime_serde")]
|
||||
pub duration: Duration,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub error: Option<String>,
|
||||
pub method: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
pub struct WebSocketStats {
|
||||
pub backend_name: String,
|
||||
pub error: Option<String>, // Default Option<String> serde is fine
|
||||
pub connect_time: std::time::Duration, // Default Duration serde (secs/nanos struct)
|
||||
pub is_active: bool,
|
||||
pub client_to_backend_messages: u64,
|
||||
pub backend_to_client_messages: u64,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||
pub struct CuDataPoint {
|
||||
pub timestamp: SystemTime,
|
||||
pub cu: u64,
|
||||
}
|
||||
|
||||
// Helper module for serializing/deserializing Option<http::StatusCode>
|
||||
mod http_serde_status_code_option {
|
||||
use http::StatusCode;
|
||||
use serde::{self, Deserializer, Serializer, AsOwned};
|
||||
|
||||
pub fn serialize<S>(status_code: &Option<StatusCode>, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
match status_code {
|
||||
Some(sc) => serializer.serialize_some(&sc.as_u16()),
|
||||
None => serializer.serialize_none(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn deserialize<'de, D>(deserializer: D) -> Result<Option<StatusCode>, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
Option::<u16>::deserialize(deserializer)?
|
||||
.map(|code| StatusCode::from_u16(code).map_err(serde::de::Error::custom))
|
||||
.transpose()
|
||||
}
|
||||
}
|
||||
|
||||
// Helper module for serializing/deserializing url::Url
|
||||
mod url_serde {
|
||||
use url::Url;
|
||||
use serde::{self, Deserializer, Serializer};
|
||||
|
||||
pub fn serialize<S>(url: &Url, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
serializer.serialize_str(url.as_str())
|
||||
}
|
||||
|
||||
pub fn deserialize<'de, D>(deserializer: D) -> Result<Url, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
String::deserialize(deserializer)?
|
||||
.parse()
|
||||
.map_err(serde::de::Error::custom)
|
||||
}
|
||||
}
|
||||
228
benchmark_proxy_rust/src/websocket_handler.rs
Normal file
228
benchmark_proxy_rust/src/websocket_handler.rs
Normal file
@@ -0,0 +1,228 @@
|
||||
use std::sync::Arc;
|
||||
use std::time::{Duration, Instant};
|
||||
use hyper::{Body, Request, Response, StatusCode};
|
||||
use hyper_tungstenite::HyperWebsocket;
|
||||
use log;
|
||||
use tokio_tungstenite::tungstenite::protocol::Message;
|
||||
use futures_util::{stream::StreamExt, sink::SinkExt};
|
||||
|
||||
use crate::config::AppConfig;
|
||||
use crate::stats_collector::StatsCollector;
|
||||
use crate::structures::{Backend, WebSocketStats}; // Ensure WebSocketStats has new fields
|
||||
|
||||
pub async fn handle_websocket_request(
|
||||
mut req: Request<Body>,
|
||||
app_config: Arc<AppConfig>,
|
||||
stats_collector: Arc<StatsCollector>,
|
||||
all_backends: Arc<Vec<Backend>>,
|
||||
) -> Result<Response<Body>, Box<dyn std::error::Error + Send + Sync + 'static>> {
|
||||
let upgrade_start_time = Instant::now();
|
||||
|
||||
// Check for upgrade request
|
||||
if !hyper_tungstenite::is_upgrade_request(&req) {
|
||||
log::warn!("Not a WebSocket upgrade request");
|
||||
let mut resp = Response::new(Body::from("Not a WebSocket upgrade request"));
|
||||
*resp.status_mut() = StatusCode::BAD_REQUEST;
|
||||
return Ok(resp);
|
||||
}
|
||||
|
||||
// Attempt to upgrade the connection
|
||||
let (response, websocket) = match hyper_tungstenite::upgrade(&mut req, None) {
|
||||
Ok((resp, ws)) => (resp, ws),
|
||||
Err(e) => {
|
||||
log::error!("WebSocket upgrade failed: {}", e);
|
||||
let mut resp = Response::new(Body::from(format!("WebSocket upgrade failed: {}", e)));
|
||||
*resp.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; // Or BAD_REQUEST
|
||||
return Ok(resp);
|
||||
}
|
||||
};
|
||||
|
||||
// Spawn a task to handle the WebSocket connection after sending 101
|
||||
tokio::spawn(async move {
|
||||
match websocket.await {
|
||||
Ok(ws_stream) => {
|
||||
let client_ws_stream = ws_stream;
|
||||
if app_config.enable_detailed_logs {
|
||||
log::info!("Client WebSocket connection established.");
|
||||
}
|
||||
// Successfully upgraded client connection, now connect to primary backend
|
||||
proxy_websocket_to_primary(client_ws_stream, app_config, stats_collector, all_backends).await;
|
||||
}
|
||||
Err(e) => {
|
||||
log::error!("Error awaiting client WebSocket upgrade: {}", e);
|
||||
// No actual client WS connection to record stats against other than the failed upgrade attempt
|
||||
let stats = WebSocketStats {
|
||||
backend_name: "client_upgrade_failed".to_string(),
|
||||
error: Some(format!("Client WS upgrade await error: {}", e)),
|
||||
connect_time: upgrade_start_time.elapsed(),
|
||||
is_active: false,
|
||||
client_to_backend_messages: 0,
|
||||
backend_to_client_messages: 0,
|
||||
};
|
||||
stats_collector.add_websocket_stats(stats);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Return the 101 Switching Protocols response to the client
|
||||
Ok(response)
|
||||
}
|
||||
|
||||
async fn proxy_websocket_to_primary(
|
||||
mut client_ws_stream: HyperWebsocket, // Made mutable for close()
|
||||
app_config: Arc<AppConfig>,
|
||||
stats_collector: Arc<StatsCollector>,
|
||||
all_backends: Arc<Vec<Backend>>,
|
||||
) {
|
||||
let connect_to_primary_start_time = Instant::now();
|
||||
let mut client_to_backend_msg_count: u64 = 0;
|
||||
let mut backend_to_client_msg_count: u64 = 0;
|
||||
let mut ws_stats_error: Option<String> = None;
|
||||
let mut backend_name_for_stats = "primary_unknown".to_string();
|
||||
|
||||
// 1. Find Primary Backend
|
||||
let primary_backend = match all_backends.iter().find(|b| b.role == "primary") {
|
||||
Some(pb) => {
|
||||
backend_name_for_stats = pb.name.clone();
|
||||
pb
|
||||
}
|
||||
None => {
|
||||
log::error!("No primary backend configured for WebSocket proxy.");
|
||||
ws_stats_error = Some("No primary backend configured".to_string());
|
||||
// Close client connection gracefully if possible
|
||||
let _ = client_ws_stream.close(None).await; // HyperWebsocket uses close method
|
||||
// Record stats and return
|
||||
let stats = WebSocketStats {
|
||||
backend_name: backend_name_for_stats,
|
||||
error: ws_stats_error,
|
||||
connect_time: connect_to_primary_start_time.elapsed(),
|
||||
is_active: false,
|
||||
client_to_backend_messages,
|
||||
backend_to_client_messages,
|
||||
};
|
||||
stats_collector.add_websocket_stats(stats);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
backend_name_for_stats = primary_backend.name.clone(); // Ensure it's set if primary_backend was found
|
||||
|
||||
// 2. Connect to Primary Backend's WebSocket
|
||||
let mut ws_url = primary_backend.url.clone();
|
||||
let scheme = if ws_url.scheme() == "https" { "wss" } else { "ws" };
|
||||
if ws_url.set_scheme(scheme).is_err() {
|
||||
log::error!("Failed to set WebSocket scheme for backend URL: {}", primary_backend.url);
|
||||
ws_stats_error = Some(format!("Invalid backend URL scheme for {}", primary_backend.url));
|
||||
let _ = client_ws_stream.close(None).await;
|
||||
let stats = WebSocketStats {
|
||||
backend_name: backend_name_for_stats,
|
||||
error: ws_stats_error,
|
||||
connect_time: connect_to_primary_start_time.elapsed(),
|
||||
is_active: false,
|
||||
client_to_backend_messages,
|
||||
backend_to_client_messages,
|
||||
};
|
||||
stats_collector.add_websocket_stats(stats);
|
||||
return;
|
||||
}
|
||||
|
||||
let backend_connect_attempt_time = Instant::now();
|
||||
let backend_ws_result = tokio_tungstenite::connect_async(ws_url.clone()).await;
|
||||
let connect_duration = backend_connect_attempt_time.elapsed(); // This is backend connection time
|
||||
|
||||
let backend_ws_stream_conn = match backend_ws_result {
|
||||
Ok((stream, _response)) => {
|
||||
if app_config.enable_detailed_logs {
|
||||
log::info!("Successfully connected to primary backend WebSocket: {}", primary_backend.name);
|
||||
}
|
||||
stream
|
||||
}
|
||||
Err(e) => {
|
||||
log::error!("Failed to connect to primary backend {} WebSocket: {}", primary_backend.name, e);
|
||||
ws_stats_error = Some(format!("Primary backend connect error: {}", e));
|
||||
let _ = client_ws_stream.close(None).await; // Close client connection
|
||||
let stats = WebSocketStats {
|
||||
backend_name: backend_name_for_stats,
|
||||
error: ws_stats_error,
|
||||
connect_time: connect_duration,
|
||||
is_active: false,
|
||||
client_to_backend_messages,
|
||||
backend_to_client_messages,
|
||||
};
|
||||
stats_collector.add_websocket_stats(stats);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
// 3. Proxying Logic
|
||||
let (mut client_ws_tx, mut client_ws_rx) = client_ws_stream.split();
|
||||
let (mut backend_ws_tx, mut backend_ws_rx) = backend_ws_stream_conn.split();
|
||||
|
||||
let client_to_backend_task = async {
|
||||
while let Some(msg_result) = client_ws_rx.next().await {
|
||||
match msg_result {
|
||||
Ok(msg) => {
|
||||
if app_config.enable_detailed_logs { log::trace!("C->B: {:?}", msg); }
|
||||
if backend_ws_tx.send(msg).await.is_err() {
|
||||
if app_config.enable_detailed_logs { log::debug!("Error sending to backend, C->B loop breaking."); }
|
||||
break;
|
||||
}
|
||||
client_to_backend_msg_count += 1;
|
||||
}
|
||||
Err(e) => {
|
||||
log::warn!("Error reading from client WebSocket: {}", e);
|
||||
// Use a closure to capture `e` by reference for the format macro.
|
||||
ws_stats_error.get_or_insert_with(|| { let e_ref = &e; format!("Client read error: {}", e_ref) });
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Try to close the backend sink gracefully if client read loop ends
|
||||
if app_config.enable_detailed_logs { log::debug!("C->B proxy loop finished. Closing backend_ws_tx.");}
|
||||
let _ = backend_ws_tx.close().await;
|
||||
};
|
||||
|
||||
let backend_to_client_task = async {
|
||||
while let Some(msg_result) = backend_ws_rx.next().await {
|
||||
match msg_result {
|
||||
Ok(msg) => {
|
||||
if app_config.enable_detailed_logs { log::trace!("B->C: {:?}", msg); }
|
||||
if client_ws_tx.send(msg).await.is_err() {
|
||||
if app_config.enable_detailed_logs { log::debug!("Error sending to client, B->C loop breaking."); }
|
||||
break;
|
||||
}
|
||||
backend_to_client_msg_count += 1;
|
||||
}
|
||||
Err(e) => {
|
||||
log::warn!("Error reading from backend WebSocket: {}", e);
|
||||
// Use a closure to capture `e` by reference for the format macro.
|
||||
ws_stats_error.get_or_insert_with(|| { let e_ref = &e; format!("Backend read error: {}", e_ref) });
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Try to close the client sink gracefully if backend read loop ends
|
||||
if app_config.enable_detailed_logs { log::debug!("B->C proxy loop finished. Closing client_ws_tx.");}
|
||||
let _ = client_ws_tx.close().await;
|
||||
};
|
||||
|
||||
// Run both proxy tasks concurrently
|
||||
tokio::join!(client_to_backend_task, backend_to_client_task);
|
||||
|
||||
if app_config.enable_detailed_logs {
|
||||
log::info!("WebSocket proxying ended for {}. Client->Backend: {}, Backend->Client: {}. Error: {:?}",
|
||||
backend_name_for_stats, client_to_backend_msg_count, backend_to_client_msg_count, ws_stats_error);
|
||||
}
|
||||
|
||||
let final_session_duration = connect_to_primary_start_time.elapsed();
|
||||
|
||||
let final_stats = WebSocketStats {
|
||||
backend_name: backend_name_for_stats,
|
||||
error: ws_stats_error,
|
||||
connect_time: final_session_duration,
|
||||
is_active: false, // Session is now over
|
||||
client_to_backend_messages,
|
||||
backend_to_client_messages,
|
||||
};
|
||||
stats_collector.add_websocket_stats(final_stats);
|
||||
}
|
||||
1
berachain-bartio.yml
Symbolic link
1
berachain-bartio.yml
Symbolic link
@@ -0,0 +1 @@
|
||||
berachain/reth/berachain-bartio-reth-archive-trace.yml
|
||||
1
berachain-bepolia-archive.yml
Symbolic link
1
berachain-bepolia-archive.yml
Symbolic link
@@ -0,0 +1 @@
|
||||
berachain/reth/berachain-bepolia-reth-archive-trace.yml
|
||||
1
berachain-mainnet-archive.yml
Symbolic link
1
berachain-mainnet-archive.yml
Symbolic link
@@ -0,0 +1 @@
|
||||
berachain/reth/berachain-mainnet-reth-archive-trace.yml
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user