mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-10 05:47:59 -05:00
Compare commits
998 Commits
exclude-as
...
migrate-rp
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1f3056ac84 | ||
|
|
4ab86838b8 | ||
|
|
203ac12216 | ||
|
|
2e0d4ac184 | ||
|
|
9c598ea9aa | ||
|
|
2cfc204e9a | ||
|
|
e859fc4e09 | ||
|
|
c0021f91c2 | ||
|
|
877d9ee948 | ||
|
|
785fefa3f1 | ||
|
|
0c22d91a55 | ||
|
|
fb60456116 | ||
|
|
be56711892 | ||
|
|
370ae9a12c | ||
|
|
96f1ebf706 | ||
|
|
fb755c7f3b | ||
|
|
bdb12c7d2f | ||
|
|
83cf0f8658 | ||
|
|
762594a368 | ||
|
|
c1fc812a38 | ||
|
|
340935af9c | ||
|
|
17d0082c5c | ||
|
|
e998b5ec97 | ||
|
|
5d0eb3168c | ||
|
|
e0c2aa71d4 | ||
|
|
6eff474042 | ||
|
|
70c31949ba | ||
|
|
e38fdb09a4 | ||
|
|
a50e981c74 | ||
|
|
8be205cf3d | ||
|
|
1b65e00096 | ||
|
|
e3fb4e86ec | ||
|
|
70aaad1904 | ||
|
|
e42611ec72 | ||
|
|
a3e61275a3 | ||
|
|
e82f9ccca3 | ||
|
|
38a6a7a4ea | ||
|
|
1295c987e8 | ||
|
|
6a27c41aad | ||
|
|
98b13ea144 | ||
|
|
c735ed2e32 | ||
|
|
bd17779231 | ||
|
|
e08ed0d823 | ||
|
|
2b4d8a09ff | ||
|
|
21e1f7883b | ||
|
|
bfa24606c3 | ||
|
|
d7628bab37 | ||
|
|
8e2c9313e9 | ||
|
|
fea441d889 | ||
|
|
2351064e8d | ||
|
|
d2699761ed | ||
|
|
c73473b59d | ||
|
|
2aa52fb56a | ||
|
|
16d5abd21b | ||
|
|
08bfaca42d | ||
|
|
179cedd4a0 | ||
|
|
0f39857653 | ||
|
|
645328bb9e | ||
|
|
9d2273c514 | ||
|
|
34429368fe | ||
|
|
629568c796 | ||
|
|
5c24978702 | ||
|
|
4e44999207 | ||
|
|
15ae71c0da | ||
|
|
1caea86152 | ||
|
|
7cef3b0491 | ||
|
|
15462844f9 | ||
|
|
863eee7b40 | ||
|
|
6d89373583 | ||
|
|
9a421a2feb | ||
|
|
4e41d5c610 | ||
|
|
0b6bea43a8 | ||
|
|
f89afb0fbd | ||
|
|
3cd2973c92 | ||
|
|
d3e5710a63 | ||
|
|
f40b4f16c2 | ||
|
|
7fd4f746d6 | ||
|
|
2362d9f3c2 | ||
|
|
6b84f8c6b1 | ||
|
|
997a9112d1 | ||
|
|
d46ca97680 | ||
|
|
417bbf8a9e | ||
|
|
a7b016c954 | ||
|
|
6015493de9 | ||
|
|
c718bdbe2b | ||
|
|
0a8f947169 | ||
|
|
d7efccf6a5 | ||
|
|
334920bc9e | ||
|
|
6e00db433c | ||
|
|
c6344e7c3e | ||
|
|
2131254722 | ||
|
|
b6d1866deb | ||
|
|
e56f489d06 | ||
|
|
bf62afb27c | ||
|
|
8369056027 | ||
|
|
09499a732f | ||
|
|
2ee015452c | ||
|
|
ffc1bf8bbe | ||
|
|
014dbd5c3a | ||
|
|
9bceaa59d2 | ||
|
|
832ebb3f39 | ||
|
|
8345c271cc | ||
|
|
56208aa84d | ||
|
|
b866a2c744 | ||
|
|
a77234e637 | ||
|
|
e0e7354708 | ||
|
|
0f86a16915 | ||
|
|
972c22b02f | ||
|
|
93c27340e4 | ||
|
|
c3edb32558 | ||
|
|
3baaa732df | ||
|
|
8ceb7e76ea | ||
|
|
4d5dddd302 | ||
|
|
55efccb07f | ||
|
|
961d8e1481 | ||
|
|
d396a9931e | ||
|
|
e3f8f121f4 | ||
|
|
80f29e9eda | ||
|
|
8995d8133a | ||
|
|
31044206b8 | ||
|
|
3a1702e56f | ||
|
|
501ec74a48 | ||
|
|
c248fe0bb3 | ||
|
|
215fbcb2e4 | ||
|
|
e39f44b529 | ||
|
|
9eff6ae476 | ||
|
|
3eec5a5cb6 | ||
|
|
66878deb2c | ||
|
|
0b6e1711e4 | ||
|
|
15025837bb | ||
|
|
0229a2055e | ||
|
|
eb9af15c7a | ||
|
|
0584746815 | ||
|
|
8c4ea850ba | ||
|
|
4b43f13e65 | ||
|
|
26d35474e9 | ||
|
|
9fbe3564df | ||
|
|
bed5547890 | ||
|
|
47922fe7d8 | ||
|
|
dcd25d1d97 | ||
|
|
81a2a17c5f | ||
|
|
6b3f1de19d | ||
|
|
7c17af2a41 | ||
|
|
ecf5a368d7 | ||
|
|
557c5be433 | ||
|
|
49405c3afd | ||
|
|
3439122629 | ||
|
|
f6e5da6723 | ||
|
|
842f241cb9 | ||
|
|
41daac1b04 | ||
|
|
2a7fc84044 | ||
|
|
44ff0b1a14 | ||
|
|
91cdd318a8 | ||
|
|
3dc00816fb | ||
|
|
e331d5b371 | ||
|
|
8d5090ce54 | ||
|
|
25244d906d | ||
|
|
aa445713ac | ||
|
|
177769a1ce | ||
|
|
967e9255a2 | ||
|
|
910609a75f | ||
|
|
f9c202190a | ||
|
|
4a63a194b1 | ||
|
|
d887536eb7 | ||
|
|
1069da1cd2 | ||
|
|
4a487ba3bc | ||
|
|
bf81cd4449 | ||
|
|
00337fe005 | ||
|
|
bb3fba4d8e | ||
|
|
89967fe209 | ||
|
|
56712b5e49 | ||
|
|
0be9391e62 | ||
|
|
4a9c60f75f | ||
|
|
9cf6b93356 | ||
|
|
b4220e35c4 | ||
|
|
536cded4cc | ||
|
|
86fc64c917 | ||
|
|
5d6a406829 | ||
|
|
2c78e501b3 | ||
|
|
c8cb0f37b2 | ||
|
|
78722239da | ||
|
|
3ffef024c7 | ||
|
|
a1eef44492 | ||
|
|
2845ab9365 | ||
|
|
4f43c15ebb | ||
|
|
e473d7cc4d | ||
|
|
794a05af26 | ||
|
|
15df13c7e6 | ||
|
|
b76f7fed2f | ||
|
|
e263687ea5 | ||
|
|
0b16c79c35 | ||
|
|
dc002c2806 | ||
|
|
e7e48dcaf9 | ||
|
|
8f43f6cc84 | ||
|
|
e07341e1d5 | ||
|
|
ef293e52f8 | ||
|
|
72cc63a6a3 | ||
|
|
34ff4c3ea9 | ||
|
|
e8c968326a | ||
|
|
2000ef457b | ||
|
|
e36564c4d3 | ||
|
|
e5784d09f0 | ||
|
|
e577bb0dcf | ||
|
|
153d1872ae | ||
|
|
80aa811ab9 | ||
|
|
39cf2c8f06 | ||
|
|
e99df5e489 | ||
|
|
393e63e8e5 | ||
|
|
c48d40907c | ||
|
|
a21f544219 | ||
|
|
705a9e8dcd | ||
|
|
2dcb015470 | ||
|
|
211e1a4b7c | ||
|
|
1efca9c28d | ||
|
|
97d7ca828b | ||
|
|
31df250496 | ||
|
|
8a439a6f5d | ||
|
|
8cff9356f1 | ||
|
|
afeb05c9a1 | ||
|
|
fa16232924 | ||
|
|
1f720bdbf4 | ||
|
|
79ea77ff57 | ||
|
|
d35cd0788e | ||
|
|
093e3df80a | ||
|
|
699a3b07a7 | ||
|
|
937d441e2e | ||
|
|
ead08d56d0 | ||
|
|
f55e62287a | ||
|
|
c7b2838873 | ||
|
|
9e7c1d6af6 | ||
|
|
6ce6b869e5 | ||
|
|
dbd53bd70d | ||
|
|
d04b361cc3 | ||
|
|
96b31a9f64 | ||
|
|
a7c3004115 | ||
|
|
30d5749ef6 | ||
|
|
bc69ab8a44 | ||
|
|
ed7b511949 | ||
|
|
0b7c005d7d | ||
|
|
65e8c37b48 | ||
|
|
689015ff01 | ||
|
|
08c14f02f6 | ||
|
|
4bb0b44f16 | ||
|
|
29237cb0bc | ||
|
|
2b25ede641 | ||
|
|
b7de64a340 | ||
|
|
11aa51e033 | ||
|
|
fa0dc09ce0 | ||
|
|
d93a1b671c | ||
|
|
1d8ffadd4f | ||
|
|
ac1717f1e4 | ||
|
|
6e6012b12f | ||
|
|
008f157e17 | ||
|
|
7afb8c3c86 | ||
|
|
e925d35d55 | ||
|
|
1f2d8cfae9 | ||
|
|
63bc965ddc | ||
|
|
a0791d77eb | ||
|
|
0d810a1fd6 | ||
|
|
92bbf6344c | ||
|
|
df81fa3e9a | ||
|
|
30a136f1fb | ||
|
|
b23c562b67 | ||
|
|
ae36630ccd | ||
|
|
ac72fe2e0e | ||
|
|
d09885b7ce | ||
|
|
dc643c9f32 | ||
|
|
9fa49e7bc9 | ||
|
|
1139c90ab2 | ||
|
|
79d05a87bb | ||
|
|
1707cf3ec7 | ||
|
|
bdbb850250 | ||
|
|
b28b1ed6ce | ||
|
|
74bb0821a8 | ||
|
|
8025a483e2 | ||
|
|
0475631543 | ||
|
|
f27092fa91 | ||
|
|
67cef41cbf | ||
|
|
258908d50e | ||
|
|
415a42a4aa | ||
|
|
25eae3acda | ||
|
|
956d9d108c | ||
|
|
c285715f9f | ||
|
|
9382ae736d | ||
|
|
f16ff45a6b | ||
|
|
8d6577be84 | ||
|
|
9de75b5376 | ||
|
|
a7ba11df37 | ||
|
|
00aeea3656 | ||
|
|
9dbf979e77 | ||
|
|
be60504512 | ||
|
|
1857496159 | ||
|
|
ccf61e1700 | ||
|
|
4edbd2f9ef | ||
|
|
5179af1438 | ||
|
|
c0f9689e30 | ||
|
|
ff8240a04f | ||
|
|
847498c648 | ||
|
|
2633684339 | ||
|
|
ab3f1963e2 | ||
|
|
b87d02eeb3 | ||
|
|
bcb4155523 | ||
|
|
77f10b9e0e | ||
|
|
928b707ef1 | ||
|
|
91c15247e5 | ||
|
|
5ef5b65ffe | ||
|
|
9ae97786c5 | ||
|
|
66d1bb54f6 | ||
|
|
4d98049054 | ||
|
|
d5ff25b59d | ||
|
|
a265cf08fa | ||
|
|
f2ade3caff | ||
|
|
e6ffc0701e | ||
|
|
61c296e075 | ||
|
|
f264680739 | ||
|
|
8fe024f6a1 | ||
|
|
6b7dd833a3 | ||
|
|
060527032b | ||
|
|
a29ecb6bbe | ||
|
|
54656e172f | ||
|
|
97c8adb003 | ||
|
|
2fe8614115 | ||
|
|
09accc7132 | ||
|
|
53f1f11c6d | ||
|
|
48fe9d9c4d | ||
|
|
4386c244e1 | ||
|
|
7ac522d8ff | ||
|
|
52cf3a155d | ||
|
|
83ed320826 | ||
|
|
616cdc1e8b | ||
|
|
361712e886 | ||
|
|
9ec8c6c4b5 | ||
|
|
073cf19b69 | ||
|
|
6ac8090599 | ||
|
|
4aa54107e4 | ||
|
|
ffc443b5f2 | ||
|
|
d6c5692dc0 | ||
|
|
1086bdf2b3 | ||
|
|
2afa63b442 | ||
|
|
5a5193c59d | ||
|
|
c8d3ed02cb | ||
|
|
30fcf5366a | ||
|
|
f776b968ad | ||
|
|
de094b0078 | ||
|
|
0a4ed8279b | ||
|
|
f307a369a5 | ||
|
|
dc91c963b9 | ||
|
|
7238848d81 | ||
|
|
80cafaa6df | ||
|
|
8a0545c3d7 | ||
|
|
9c61117b71 | ||
|
|
6c22edeecc | ||
|
|
57cc4950c0 | ||
|
|
2c981d5564 | ||
|
|
492c8af83f | ||
|
|
e40d2cbd2c | ||
|
|
3fa6d3bd9d | ||
|
|
56f0eb1437 | ||
|
|
7fc5c714a1 | ||
|
|
cfbfccb203 | ||
|
|
884b663455 | ||
|
|
0f1d16c599 | ||
|
|
c11e3392d4 | ||
|
|
f498463843 | ||
|
|
cf4ffc97e2 | ||
|
|
3824e8a463 | ||
|
|
21ca4e008f | ||
|
|
6af44a1466 | ||
|
|
2e29164582 | ||
|
|
6d499bc9fc | ||
|
|
7786cb5684 | ||
|
|
003b70c34b | ||
|
|
71edf96c7d | ||
|
|
ddafedc268 | ||
|
|
7e5738bfcd | ||
|
|
315c05b351 | ||
|
|
3662cf6009 | ||
|
|
98d8b50b0e | ||
|
|
1a1cc25bd1 | ||
|
|
bc9c7193a9 | ||
|
|
7ac3c01b5b | ||
|
|
ed6f69e868 | ||
|
|
222b360c66 | ||
|
|
170a864239 | ||
|
|
b5cfd0d35d | ||
|
|
28181710b0 | ||
|
|
2f756b7ec4 | ||
|
|
df4ca54a76 | ||
|
|
875e3e5e7d | ||
|
|
a5317f8117 | ||
|
|
38b92c0171 | ||
|
|
a03b34af77 | ||
|
|
4c14bd8be2 | ||
|
|
62b8e63a0a | ||
|
|
eec3b0b7fe | ||
|
|
2bffb83a00 | ||
|
|
45fd3eb1bf | ||
|
|
963a1b4cb7 | ||
|
|
77c845043d | ||
|
|
342bb0fcef | ||
|
|
93e6bd7929 | ||
|
|
3015eea4e3 | ||
|
|
2f42f7e313 | ||
|
|
a7c86a6d1b | ||
|
|
2399451869 | ||
|
|
19d9a1915d | ||
|
|
261921ae4c | ||
|
|
6ad8a104dd | ||
|
|
50e53265a1 | ||
|
|
3392fdb21d | ||
|
|
dd3c9652c3 | ||
|
|
022a53f8f2 | ||
|
|
2fa3547644 | ||
|
|
7c213ce161 | ||
|
|
ed3d7d49ec | ||
|
|
068139a78a | ||
|
|
8dd7361b6a | ||
|
|
41ea1d230a | ||
|
|
9e25026519 | ||
|
|
9e9559df60 | ||
|
|
7a5a6c7e54 | ||
|
|
be317c439d | ||
|
|
f43383a3fb | ||
|
|
22f6f787e1 | ||
|
|
44b3986025 | ||
|
|
6cb845660a | ||
|
|
de2c866707 | ||
|
|
74ddb84e0a | ||
|
|
0c6a068fd5 | ||
|
|
fad92472d8 | ||
|
|
2a44e8e6ec | ||
|
|
e3d27f29c7 | ||
|
|
e011f05403 | ||
|
|
b8cd77945d | ||
|
|
9a7f521f8a | ||
|
|
102f94f914 | ||
|
|
0c0a497651 | ||
|
|
e0785a8939 | ||
|
|
af098e737e | ||
|
|
1e4ede5585 | ||
|
|
fb2620364a | ||
|
|
68b38b6666 | ||
|
|
ff3e0856a1 | ||
|
|
85f334b663 | ||
|
|
10f520accb | ||
|
|
836608537e | ||
|
|
13e09c58f6 | ||
|
|
600ca08aa8 | ||
|
|
0ed74b3c4a | ||
|
|
7c69a9aa1c | ||
|
|
c50cfb044a | ||
|
|
38d4e179ba | ||
|
|
be80728320 | ||
|
|
09028033c0 | ||
|
|
52c036c3ab | ||
|
|
2fc7cdeba7 | ||
|
|
6f7976766d | ||
|
|
5c369361b0 | ||
|
|
7d48b45152 | ||
|
|
345aabe996 | ||
|
|
5d04b36680 | ||
|
|
cd8907f76c | ||
|
|
b108d5bf54 | ||
|
|
4d823acf45 | ||
|
|
aa868e5e8c | ||
|
|
b1be6cd20b | ||
|
|
fd9321f6ba | ||
|
|
8364226b68 | ||
|
|
49055acf81 | ||
|
|
57ffc12f17 | ||
|
|
d066480a51 | ||
|
|
0e8f98b2a4 | ||
|
|
3a734f51e0 | ||
|
|
c7e2d709cf | ||
|
|
8b4b3a269b | ||
|
|
2f76ba542f | ||
|
|
637cbc88e8 | ||
|
|
fadff022a0 | ||
|
|
05784a6c28 | ||
|
|
5a48e002dd | ||
|
|
d6f86269a4 | ||
|
|
422438f515 | ||
|
|
e5b25071f9 | ||
|
|
498ee635e1 | ||
|
|
c238c00630 | ||
|
|
3eacc37831 | ||
|
|
5267b4b4d4 | ||
|
|
ec84a1b49c | ||
|
|
afb7383225 | ||
|
|
a00b40fa81 | ||
|
|
365c6252ba | ||
|
|
7c81c7da90 | ||
|
|
f8950c8c40 | ||
|
|
18be899aef | ||
|
|
9dc3b645c4 | ||
|
|
318561999d | ||
|
|
ae5b0b4391 | ||
|
|
74b5f6ecf2 | ||
|
|
aea2a469cc | ||
|
|
7a394062e1 | ||
|
|
8070fc8ece | ||
|
|
d6aeaf77b3 | ||
|
|
40434ac209 | ||
|
|
0aab919d7c | ||
|
|
a8ecf5d118 | ||
|
|
8c0d6b27d0 | ||
|
|
2e6f1de29a | ||
|
|
657750b803 | ||
|
|
af5eb82217 | ||
|
|
84e7f33fd9 | ||
|
|
ca83d29eef | ||
|
|
0d49f6c142 | ||
|
|
041e81aad2 | ||
|
|
028504ae9a | ||
|
|
91c55c6880 | ||
|
|
78cf75a0ed | ||
|
|
fa370724f1 | ||
|
|
5edc64d88c | ||
|
|
7898e65d4e | ||
|
|
6d63dbe1af | ||
|
|
eab9daf5f5 | ||
|
|
4becd7b375 | ||
|
|
f230a6af58 | ||
|
|
539b981ac3 | ||
|
|
aad29ff9fc | ||
|
|
4722446caf | ||
|
|
b8aad84285 | ||
|
|
5f0d6074d6 | ||
|
|
9d6a2f5390 | ||
|
|
490ddbf782 | ||
|
|
adc875b20d | ||
|
|
8cd249c1c8 | ||
|
|
305d5850e7 | ||
|
|
df3a9f218d | ||
|
|
ae451a3a02 | ||
|
|
17561a6576 | ||
|
|
b842b7ea01 | ||
|
|
9bbe12e28c | ||
|
|
0674cf64cc | ||
|
|
3413d05b34 | ||
|
|
070a765d24 | ||
|
|
8ac1647436 | ||
|
|
dfe31c9242 | ||
|
|
b7866be3a9 | ||
|
|
8413660d5f | ||
|
|
e037491756 | ||
|
|
ea2624b5ab | ||
|
|
1b40f941cf | ||
|
|
57830435d7 | ||
|
|
44d850de51 | ||
|
|
b08e691127 | ||
|
|
968e82b02d | ||
|
|
de04ce8329 | ||
|
|
5efecff631 | ||
|
|
3ab759e163 | ||
|
|
836d369c6c | ||
|
|
568273453b | ||
|
|
7a4ecb6060 | ||
|
|
82f0ea5b11 | ||
|
|
6fddd13cb2 | ||
|
|
43c7659d18 | ||
|
|
2d15e53dab | ||
|
|
2f2152e039 | ||
|
|
2542189efc | ||
|
|
8e6d39a44b | ||
|
|
c35889d4c6 | ||
|
|
10dedd5ced | ||
|
|
d2966a4c5b | ||
|
|
62b5c43d87 | ||
|
|
b04baa93cd | ||
|
|
2e84208169 | ||
|
|
2265af58ae | ||
|
|
4d190c41cc | ||
|
|
0fbb27d8e3 | ||
|
|
3df3e84270 | ||
|
|
30cc23c5de | ||
|
|
9befb6bd06 | ||
|
|
8a12b78684 | ||
|
|
46168607e8 | ||
|
|
1272b9e186 | ||
|
|
fcbe19445a | ||
|
|
2b4dffa87d | ||
|
|
49a6d02e12 | ||
|
|
2b06dfd4a3 | ||
|
|
6e81b4e84b | ||
|
|
0de1282e1c | ||
|
|
e3db52ca1f | ||
|
|
c5a36d4c70 | ||
|
|
e28b6695ba | ||
|
|
de177f74fb | ||
|
|
e4310aef73 | ||
|
|
d71079e1d8 | ||
|
|
c08d2f36b0 | ||
|
|
839a80e339 | ||
|
|
a35535043e | ||
|
|
323dd7b22d | ||
|
|
102128ca2e | ||
|
|
f3dd75a2c4 | ||
|
|
0869814a0e | ||
|
|
41edee9fe9 | ||
|
|
2fa3694746 | ||
|
|
e9606b3635 | ||
|
|
ed7c4bb6a7 | ||
|
|
c93fea4ec4 | ||
|
|
aa847991e0 | ||
|
|
5f1b903bdf | ||
|
|
49f3531aed | ||
|
|
9b2934f1f6 | ||
|
|
26355768a0 | ||
|
|
80bff0dc2d | ||
|
|
c312a88aa3 | ||
|
|
625818d556 | ||
|
|
2c5a2e8ec7 | ||
|
|
ae16d5f52c | ||
|
|
d69be8a766 | ||
|
|
8df62a537b | ||
|
|
bf5e667351 | ||
|
|
0e5c2bd18e | ||
|
|
3233e64ace | ||
|
|
751117a308 | ||
|
|
8d9024f01f | ||
|
|
a9862f32f3 | ||
|
|
c8d6f47749 | ||
|
|
a6f134e48e | ||
|
|
fdbb5136d9 | ||
|
|
2c66918594 | ||
|
|
a0dac292ff | ||
|
|
75857e7177 | ||
|
|
0369f70b0b | ||
|
|
276b97530f | ||
|
|
d5daf49a9a | ||
|
|
feb16ae4aa | ||
|
|
219301339c | ||
|
|
aec349f75a | ||
|
|
5f909caedf | ||
|
|
ba6dff3adb | ||
|
|
8cd05f098b | ||
|
|
425f5387fa | ||
|
|
f2ce115ade | ||
|
|
090a3e1ded | ||
|
|
c0acb7d352 | ||
|
|
0d6070e6fc | ||
|
|
bd00f851f0 | ||
|
|
1a0c07deec | ||
|
|
04f231a400 | ||
|
|
be1bfcce63 | ||
|
|
8cf5d79852 | ||
|
|
f7912e7c20 | ||
|
|
caa8be5dd1 | ||
|
|
0c15a30a34 | ||
|
|
7bce1c0714 | ||
|
|
d1084cbe48 | ||
|
|
2cc3f69a3f | ||
|
|
a861489a83 | ||
|
|
0e1c585f7d | ||
|
|
9df20e616c | ||
|
|
53fdd2d062 | ||
|
|
2b4bb5d890 | ||
|
|
38f208d70d | ||
|
|
65b90abdda | ||
|
|
f3b49d4eaf | ||
|
|
5b1da7353c | ||
|
|
9f17e65860 | ||
|
|
9b2d53b0d1 | ||
|
|
d6f9196707 | ||
|
|
1b0e09369e | ||
|
|
12482eeb40 | ||
|
|
acc307b959 | ||
|
|
c1d75c295a | ||
|
|
fad118cb04 | ||
|
|
cdd1d819df | ||
|
|
97edffaff5 | ||
|
|
6de7df6b9d | ||
|
|
14d7416c16 | ||
|
|
6782df917a | ||
|
|
3d2230223f | ||
|
|
b008a6422d | ||
|
|
d19365507f | ||
|
|
c05e39a668 | ||
|
|
63c2b3563a | ||
|
|
a6e86c6731 | ||
|
|
32fb183392 | ||
|
|
cade09ba0b | ||
|
|
f85ddfe265 | ||
|
|
3b97094ea4 | ||
|
|
acdbf7c491 | ||
|
|
1cc1effd75 | ||
|
|
f7f1d249f2 | ||
|
|
02abb3e3c0 | ||
|
|
2255c8b287 | ||
|
|
27ecf448a7 | ||
|
|
e243f04e44 | ||
|
|
fca1adbad7 | ||
|
|
b692722ddf | ||
|
|
c4f6020677 | ||
|
|
d779e65d4e | ||
|
|
357211b7d9 | ||
|
|
2dd48343a2 | ||
|
|
7f931bf65b | ||
|
|
fda4589251 | ||
|
|
34593d34d4 | ||
|
|
4d18e590ed | ||
|
|
ec8b67cb12 | ||
|
|
a817aa0a8d | ||
|
|
d76f55e97a | ||
|
|
2de21eb22f | ||
|
|
58b8c31c93 | ||
|
|
f343333880 | ||
|
|
8e0b1b7e1f | ||
|
|
65f71b3a48 | ||
|
|
9fcb9b86af | ||
|
|
aa63c4e7f2 | ||
|
|
d6ae838bbf | ||
|
|
d49afb370c | ||
|
|
4d3a6d84d2 | ||
|
|
9c5d16e161 | ||
|
|
4731304187 | ||
|
|
02cbcf8545 | ||
|
|
4e10734ae4 | ||
|
|
e19c99c3e2 | ||
|
|
697bcd418c | ||
|
|
ec7949fa4b | ||
|
|
cb8eb4e955 | ||
|
|
800f3b572f | ||
|
|
9d3af41acb | ||
|
|
07a0a95ee7 | ||
|
|
9e7352704c | ||
|
|
2616de1eb1 | ||
|
|
b2e3c29ab3 | ||
|
|
83538251aa | ||
|
|
2442280e37 | ||
|
|
4608569495 | ||
|
|
20d013a30b | ||
|
|
b0a2115a26 | ||
|
|
102518e106 | ||
|
|
e49ed4d554 | ||
|
|
21775eed52 | ||
|
|
ee9274a9bc | ||
|
|
ef21d3adf8 | ||
|
|
b6ce6c2eba | ||
|
|
b3caaa9acc | ||
|
|
d6fb8c29c9 | ||
|
|
3df7a1f067 | ||
|
|
4c3dbae3c0 | ||
|
|
68b78dd520 | ||
|
|
2e2ef4a179 | ||
|
|
b61d17731e | ||
|
|
6d3c6a6331 | ||
|
|
f1615c4c88 | ||
|
|
87b127365f | ||
|
|
5215ed03fd | ||
|
|
0453d18395 | ||
|
|
0132c1b17d | ||
|
|
d9d2ee75de | ||
|
|
ddb321e0ce | ||
|
|
5735379963 | ||
|
|
1d5a09c05d | ||
|
|
70e1b11aeb | ||
|
|
e100fb0c08 | ||
|
|
789c3f8078 | ||
|
|
0b261cba5e | ||
|
|
7a9608ea20 | ||
|
|
f795e09ecf | ||
|
|
e6a6365bdd | ||
|
|
4c66e4d060 | ||
|
|
daad29d0de | ||
|
|
9f67ad9496 | ||
|
|
0ee0653a15 | ||
|
|
4ff91bebf8 | ||
|
|
f85e027141 | ||
|
|
e09ae75c9f | ||
|
|
cb80d5ad32 | ||
|
|
24b029bbef | ||
|
|
04dd60d1bf | ||
|
|
92303b610d | ||
|
|
41d97a2a27 | ||
|
|
b842d8ce1d | ||
|
|
4030614df0 | ||
|
|
1ec745b88e | ||
|
|
05b2795844 | ||
|
|
2d0fe20917 | ||
|
|
3a2734f249 | ||
|
|
50d1961e52 | ||
|
|
0dfe19c3dd | ||
|
|
e5394fe081 | ||
|
|
f09fe4f038 | ||
|
|
6c5351c3a2 | ||
|
|
5a66807989 | ||
|
|
bb66201c2c | ||
|
|
5de22d22bc | ||
|
|
1eb373103a | ||
|
|
b18026fc00 | ||
|
|
8a89173937 | ||
|
|
3d13c69ef3 | ||
|
|
f2f10e7381 | ||
|
|
9aa55b47f3 | ||
|
|
c4c6b47d9b | ||
|
|
06a5548424 | ||
|
|
5e74c798d4 | ||
|
|
7b955c94ec | ||
|
|
256a05bfd5 | ||
|
|
03068ba781 | ||
|
|
5df8b83a05 | ||
|
|
db653b8863 | ||
|
|
af203efa0c | ||
|
|
5582c558c6 | ||
|
|
573d9739ea | ||
|
|
bb18fa3f71 | ||
|
|
6a605e6b6d | ||
|
|
a0787e2379 | ||
|
|
621bda068d | ||
|
|
91504eb95a | ||
|
|
5afb1255fe | ||
|
|
9d6160e112 | ||
|
|
1383546999 | ||
|
|
01116f7f82 | ||
|
|
692ebd313f | ||
|
|
6fa656c1ee | ||
|
|
55a29a4670 | ||
|
|
e2e7e84a96 | ||
|
|
91b0a93df7 | ||
|
|
8839015312 | ||
|
|
61ab4bf7ca | ||
|
|
e3ce1bde45 | ||
|
|
9d1189b222 | ||
|
|
74f5452a64 | ||
|
|
ea1204d3c7 | ||
|
|
d9ac69752b | ||
|
|
52af63f25a | ||
|
|
2dad245bc8 | ||
|
|
9a9990605c | ||
|
|
2cddb5ca86 | ||
|
|
73ce28c356 | ||
|
|
7a294e861e | ||
|
|
258123341e | ||
|
|
224b136737 | ||
|
|
3ed4866eec | ||
|
|
373c853d17 | ||
|
|
23b0718b5f | ||
|
|
3a9854145c | ||
|
|
1b70d2b566 | ||
|
|
59b310a221 | ||
|
|
22b6d1751d | ||
|
|
9c13d47f4c | ||
|
|
835dce5f6e | ||
|
|
c4c28e4825 | ||
|
|
c996109b3a | ||
|
|
e397f8a2bd | ||
|
|
6438060733 | ||
|
|
a2892b1ed5 | ||
|
|
f4ab2ca79f | ||
|
|
dbcf5c29cd | ||
|
|
c9fe53bc32 | ||
|
|
8522febd88 | ||
|
|
75a28310c2 | ||
|
|
1df173e701 | ||
|
|
3187a05a76 | ||
|
|
4e24102237 | ||
|
|
8dd5e96b29 | ||
|
|
4afb379f8d | ||
|
|
5a2453ac9c | ||
|
|
e610d2a5de | ||
|
|
233aaf2f9e | ||
|
|
a49bdcaa1f | ||
|
|
bdd7b2caa9 | ||
|
|
8de0e3804b | ||
|
|
bfb648067b | ||
|
|
852db1f3eb | ||
|
|
5d3663ef8d | ||
|
|
a608630727 | ||
|
|
37739b4193 | ||
|
|
4d2067dbae | ||
|
|
fc05e306dd | ||
|
|
204de13c86 | ||
|
|
f3ef1b64d6 | ||
|
|
c3dbfa66d0 | ||
|
|
93aba997f4 | ||
|
|
79bb7efbf8 | ||
|
|
87b53db3b4 | ||
|
|
fe431b9201 | ||
|
|
790a09f9b1 | ||
|
|
46387a903a | ||
|
|
6a65e07684 | ||
|
|
abef94d7ad | ||
|
|
99a8d0bac6 | ||
|
|
b585ff77f5 | ||
|
|
1ff5a43385 | ||
|
|
0cfbddc980 | ||
|
|
22a484c45e | ||
|
|
6ddafe1159 | ||
|
|
b8c5af665f | ||
|
|
2875ce6ee1 | ||
|
|
a883ae2a76 | ||
|
|
3a2b486bde | ||
|
|
283e09569d | ||
|
|
69723b4a77 | ||
|
|
4fe6834ba5 | ||
|
|
98e3f2b80f | ||
|
|
2aef7a3ec5 | ||
|
|
c41a54be9d | ||
|
|
7e65378f63 | ||
|
|
cf606e3766 | ||
|
|
703cfc5819 | ||
|
|
c6ebe157a6 | ||
|
|
a3cc81a048 | ||
|
|
75bbeb61cc | ||
|
|
5cea6bebb8 | ||
|
|
28596d669b | ||
|
|
0e043d55b4 | ||
|
|
8d092a1113 | ||
|
|
073c4edc5f | ||
|
|
d055db1c31 | ||
|
|
a974627258 | ||
|
|
67dccc5e43 | ||
|
|
ff06e08274 | ||
|
|
d3d25e3ae5 | ||
|
|
929e9ddf4c | ||
|
|
7c0e79d432 | ||
|
|
3c1c0b3c00 | ||
|
|
d439e6da74 | ||
|
|
e68b2821c1 | ||
|
|
cfef8f4676 | ||
|
|
9709412511 | ||
|
|
7781eb60f4 | ||
|
|
396b8bf970 | ||
|
|
d5107942a1 | ||
|
|
bd4a520013 | ||
|
|
a0ff1351a0 | ||
|
|
7e6fd5fd8b | ||
|
|
d984210baa | ||
|
|
31c72672d7 | ||
|
|
8c1e180dd1 | ||
|
|
886d76fe7c | ||
|
|
a602acf492 | ||
|
|
1b6547de6a | ||
|
|
88685bb3bd | ||
|
|
2319b7d4bd | ||
|
|
82b2840d68 | ||
|
|
cf221d0f4c | ||
|
|
0956e3a657 | ||
|
|
351ed1c511 | ||
|
|
9809f5ac77 | ||
|
|
cff5e2b5fe | ||
|
|
dd15f9e0cc | ||
|
|
1c9ded4684 | ||
|
|
d4cc6fcf4a | ||
|
|
49c16f1a71 | ||
|
|
e70b606e78 | ||
|
|
0e8b37c317 | ||
|
|
e80db9554d | ||
|
|
d0bf03e863 | ||
|
|
b7e0819f00 | ||
|
|
7d64104003 | ||
|
|
b1e8a9ea3d | ||
|
|
cc1028ca3c | ||
|
|
233f4d99a2 | ||
|
|
a068f3877e | ||
|
|
856907d760 | ||
|
|
c6801df05a | ||
|
|
bc7b15b04e | ||
|
|
eb713d1177 | ||
|
|
844b2c6602 | ||
|
|
9efaa832cd | ||
|
|
e9d26c61d7 | ||
|
|
374d77f437 | ||
|
|
1f6d1d1852 | ||
|
|
0eff83cb9d | ||
|
|
ffe2f6b732 | ||
|
|
d57bca97a5 | ||
|
|
b45a6664be | ||
|
|
c56abfb840 | ||
|
|
d70f477b1e | ||
|
|
db096488b0 | ||
|
|
344e68b81b | ||
|
|
1962cca69e | ||
|
|
4a374435c0 | ||
|
|
0fde4a22e1 | ||
|
|
62ecc0d177 | ||
|
|
97dfec84f6 | ||
|
|
53bc96844e | ||
|
|
ddcf0c18dc | ||
|
|
45a2746d0e | ||
|
|
09f3df309d | ||
|
|
96df81d5c5 | ||
|
|
c47c52152b | ||
|
|
4cbe144a6c | ||
|
|
52b9b65adb | ||
|
|
ea59b1ec71 | ||
|
|
175c484c44 | ||
|
|
8aaab86987 | ||
|
|
381116a3e8 | ||
|
|
3d61fd0436 | ||
|
|
b19d24c581 | ||
|
|
8387088a52 | ||
|
|
ce7452c97a | ||
|
|
5e56b5fdd7 | ||
|
|
bfaba378f6 | ||
|
|
3bd116db16 |
6
.bazelrc
6
.bazelrc
@@ -6,6 +6,12 @@ import %workspace%/build/bazelrc/debug.bazelrc
|
||||
import %workspace%/build/bazelrc/hermetic-cc.bazelrc
|
||||
import %workspace%/build/bazelrc/performance.bazelrc
|
||||
|
||||
# hermetic_cc_toolchain v3.0.1 required changes.
|
||||
common --enable_platform_specific_config
|
||||
build:linux --sandbox_add_mount_pair=/tmp
|
||||
build:macos --sandbox_add_mount_pair=/var/tmp
|
||||
build:windows --sandbox_add_mount_pair=C:\Temp
|
||||
|
||||
# E2E run with debug gotag
|
||||
test:e2e --define gotags=debug
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
6.4.0
|
||||
7.4.1
|
||||
|
||||
@@ -10,10 +10,9 @@
|
||||
|
||||
# Prysm specific remote-cache properties.
|
||||
build:remote-cache --remote_download_minimal
|
||||
build:remote-cache --experimental_remote_build_event_upload=minimal
|
||||
build:remote-cache --remote_build_event_upload=minimal
|
||||
build:remote-cache --remote_cache=grpc://bazel-remote-cache:9092
|
||||
# Does not work with rules_oci. See https://github.com/bazel-contrib/rules_oci/issues/292
|
||||
#build:remote-cache --experimental_remote_downloader=grpc://bazel-remote-cache:9092
|
||||
build:remote-cache --experimental_remote_downloader=grpc://bazel-remote-cache:9092
|
||||
build:remote-cache --remote_local_fallback
|
||||
build:remote-cache --experimental_remote_cache_async
|
||||
build:remote-cache --experimental_remote_merkle_tree_cache
|
||||
|
||||
@@ -11,7 +11,7 @@ name = "go"
|
||||
enabled = true
|
||||
|
||||
[analyzers.meta]
|
||||
import_paths = ["github.com/prysmaticlabs/prysm/v4"]
|
||||
import_paths = ["github.com/prysmaticlabs/prysm/v5"]
|
||||
|
||||
[[analyzers]]
|
||||
name = "test-coverage"
|
||||
|
||||
7
.github/PULL_REQUEST_TEMPLATE.md
vendored
7
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -10,6 +10,7 @@
|
||||
in review.
|
||||
4. Note that PRs updating dependencies and new Go versions are not accepted.
|
||||
Please file an issue instead.
|
||||
5. A changelog entry is required for user facing issues.
|
||||
-->
|
||||
|
||||
**What type of PR is this?**
|
||||
@@ -28,3 +29,9 @@
|
||||
Fixes #
|
||||
|
||||
**Other notes for review**
|
||||
|
||||
**Acknowledgements**
|
||||
|
||||
- [ ] I have read [CONTRIBUTING.md](https://github.com/prysmaticlabs/prysm/blob/develop/CONTRIBUTING.md).
|
||||
- [ ] I have included a uniquely named [changelog fragment file](https://github.com/prysmaticlabs/prysm/blob/develop/CONTRIBUTING.md#maintaining-changelogmd).
|
||||
- [ ] I have added a description to this PR with sufficient context for reviewers to understand this PR.
|
||||
|
||||
2
.github/actions/gomodtidy/Dockerfile
vendored
2
.github/actions/gomodtidy/Dockerfile
vendored
@@ -1,4 +1,4 @@
|
||||
FROM golang:1.20-alpine
|
||||
FROM golang:1.24-alpine
|
||||
|
||||
COPY entrypoint.sh /entrypoint.sh
|
||||
|
||||
|
||||
34
.github/workflows/changelog.yml
vendored
Normal file
34
.github/workflows/changelog.yml
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
# This workflow will build a golang project
|
||||
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-go
|
||||
|
||||
name: changelog
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches: [ "develop" ]
|
||||
|
||||
jobs:
|
||||
run-changelog-check:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout source code
|
||||
uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
|
||||
|
||||
- name: Download unclog binary
|
||||
uses: dsaltares/fetch-gh-release-asset@aa2ab1243d6e0d5b405b973c89fa4d06a2d0fff7 # 1.1.2
|
||||
with:
|
||||
repo: OffchainLabs/unclog
|
||||
version: "tags/v0.1.3"
|
||||
file: "unclog"
|
||||
|
||||
- name: Get new changelog files
|
||||
id: new-changelog-files
|
||||
uses: OffchainLabs/gh-action-changed-files@9200e69727eb73eb060652b19946b8a2fdfb654b # v4.0.8
|
||||
with:
|
||||
files: |
|
||||
changelog/**.md
|
||||
|
||||
- name: Run lint command
|
||||
env:
|
||||
ALL_ADDED_MARKDOWN: ${{ steps.new-changelog-files.outputs.added_files }}
|
||||
run: chmod +x unclog && ./unclog check -fragment-env=ALL_ADDED_MARKDOWN
|
||||
21
.github/workflows/clang-format.yml
vendored
Normal file
21
.github/workflows/clang-format.yml
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
name: Protobuf Format
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ '*' ]
|
||||
pull_request:
|
||||
branches: [ '*' ]
|
||||
merge_group:
|
||||
types: [checks_requested]
|
||||
|
||||
jobs:
|
||||
clang-format-checking:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
# Is this step failing for you?
|
||||
# Run: clang-format -i proto/**/*.proto
|
||||
# See: https://clang.llvm.org/docs/ClangFormat.html
|
||||
- uses: RafikFarhad/clang-format-github-action@v3
|
||||
with:
|
||||
sources: "proto/**/*.proto"
|
||||
4
.github/workflows/fuzz.yml
vendored
4
.github/workflows/fuzz.yml
vendored
@@ -16,7 +16,7 @@ jobs:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-go@v4
|
||||
with:
|
||||
go-version: '1.20'
|
||||
go-version: '1.23.5'
|
||||
- id: list
|
||||
uses: shogo82148/actions-go-fuzz/list@v0
|
||||
with:
|
||||
@@ -36,7 +36,7 @@ jobs:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-go@v4
|
||||
with:
|
||||
go-version: '1.20'
|
||||
go-version: '1.23.5'
|
||||
- uses: shogo82148/actions-go-fuzz/run@v0
|
||||
with:
|
||||
packages: ${{ matrix.package }}
|
||||
|
||||
34
.github/workflows/go.yml
vendored
34
.github/workflows/go.yml
vendored
@@ -5,7 +5,7 @@ on:
|
||||
branches: [ master ]
|
||||
pull_request:
|
||||
branches: [ '*' ]
|
||||
merge_group:
|
||||
merge_group:
|
||||
types: [checks_requested]
|
||||
|
||||
jobs:
|
||||
@@ -14,7 +14,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Go mod tidy checker
|
||||
id: gomodtidy
|
||||
@@ -27,34 +27,34 @@ jobs:
|
||||
GO111MODULE: on
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
- name: Set up Go 1.20
|
||||
uses: actions/setup-go@v3
|
||||
uses: actions/checkout@v4
|
||||
- name: Set up Go 1.24
|
||||
uses: actions/setup-go@v4
|
||||
with:
|
||||
go-version: '1.20'
|
||||
go-version: '1.24.0'
|
||||
- name: Run Gosec Security Scanner
|
||||
run: | # https://github.com/securego/gosec/issues/469
|
||||
export PATH=$PATH:$(go env GOPATH)/bin
|
||||
go install github.com/securego/gosec/v2/cmd/gosec@v2.15.0
|
||||
gosec -exclude-generated -exclude=G307 -exclude-dir=crypto/bls/herumi ./...
|
||||
go install github.com/securego/gosec/v2/cmd/gosec@v2.22.1
|
||||
gosec -exclude-generated -exclude=G307,G115 -exclude-dir=crypto/bls/herumi ./...
|
||||
|
||||
lint:
|
||||
name: Lint
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Go 1.20
|
||||
uses: actions/setup-go@v3
|
||||
- name: Set up Go 1.24
|
||||
uses: actions/setup-go@v4
|
||||
with:
|
||||
go-version: '1.20'
|
||||
go-version: '1.24.0'
|
||||
id: go
|
||||
|
||||
- name: Golangci-lint
|
||||
uses: golangci/golangci-lint-action@v3
|
||||
uses: golangci/golangci-lint-action@v5
|
||||
with:
|
||||
version: v1.52.2
|
||||
version: v1.64.5
|
||||
args: --config=.golangci.yml --out-${NO_FUTURE}format colored-line-number
|
||||
|
||||
build:
|
||||
@@ -62,13 +62,13 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Set up Go 1.x
|
||||
uses: actions/setup-go@v2
|
||||
uses: actions/setup-go@v4
|
||||
with:
|
||||
go-version: '1.20'
|
||||
go-version: '1.24.0'
|
||||
id: go
|
||||
|
||||
- name: Check out code into the Go module directory
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Get dependencies
|
||||
run: |
|
||||
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -41,3 +41,6 @@ jwt.hex
|
||||
|
||||
# manual testing
|
||||
tmp
|
||||
|
||||
# spectest coverage reports
|
||||
report.txt
|
||||
|
||||
@@ -1,26 +1,84 @@
|
||||
run:
|
||||
skip-files:
|
||||
timeout: 10m
|
||||
go: '1.23.5'
|
||||
|
||||
issues:
|
||||
exclude-files:
|
||||
- validator/web/site_data.go
|
||||
- .*_test.go
|
||||
skip-dirs:
|
||||
exclude-dirs:
|
||||
- proto
|
||||
- tools/analyzers
|
||||
timeout: 10m
|
||||
go: '1.19'
|
||||
|
||||
linters:
|
||||
disable-all: true
|
||||
enable:
|
||||
- gofmt
|
||||
- goimports
|
||||
- unused
|
||||
- errcheck
|
||||
- gosimple
|
||||
- gocognit
|
||||
- dupword
|
||||
- nilerr
|
||||
- whitespace
|
||||
- misspell
|
||||
enable-all: true
|
||||
disable:
|
||||
# Deprecated linters:
|
||||
- govet
|
||||
|
||||
# Disabled for now:
|
||||
- asasalint
|
||||
- bodyclose
|
||||
- containedctx
|
||||
- contextcheck
|
||||
- cyclop
|
||||
- depguard
|
||||
- dogsled
|
||||
- dupl
|
||||
- durationcheck
|
||||
- errname
|
||||
- err113
|
||||
- exhaustive
|
||||
- exhaustruct
|
||||
- forbidigo
|
||||
- forcetypeassert
|
||||
- funlen
|
||||
- gci
|
||||
- gochecknoglobals
|
||||
- gochecknoinits
|
||||
- goconst
|
||||
- gocritic
|
||||
- gocyclo
|
||||
- godot
|
||||
- godox
|
||||
- gofumpt
|
||||
- gomoddirectives
|
||||
- gosec
|
||||
- inamedparam
|
||||
- interfacebloat
|
||||
- intrange
|
||||
- ireturn
|
||||
- lll
|
||||
- maintidx
|
||||
- makezero
|
||||
- mnd
|
||||
- musttag
|
||||
- nakedret
|
||||
- nestif
|
||||
- nilnil
|
||||
- nlreturn
|
||||
- noctx
|
||||
- nolintlint
|
||||
- nonamedreturns
|
||||
- nosprintfhostport
|
||||
- perfsprint
|
||||
- prealloc
|
||||
- predeclared
|
||||
- promlinter
|
||||
- protogetter
|
||||
- recvcheck
|
||||
- revive
|
||||
- spancheck
|
||||
- staticcheck
|
||||
- stylecheck
|
||||
- tagalign
|
||||
- tagliatelle
|
||||
- thelper
|
||||
- unparam
|
||||
- usetesting
|
||||
- varnamelen
|
||||
- wrapcheck
|
||||
- wsl
|
||||
|
||||
linters-settings:
|
||||
gocognit:
|
||||
|
||||
@@ -26,7 +26,6 @@ approval_rules:
|
||||
only_changed_files:
|
||||
paths:
|
||||
- "*pb.go"
|
||||
- "*pb.gw.go"
|
||||
- "*.bazel"
|
||||
options:
|
||||
ignore_commits_by:
|
||||
@@ -69,7 +68,6 @@ approval_rules:
|
||||
changed_files:
|
||||
ignore:
|
||||
- "*pb.go"
|
||||
- "*pb.gw.go"
|
||||
- "*.bazel"
|
||||
options:
|
||||
ignore_commits_by:
|
||||
|
||||
89
BUILD.bazel
89
BUILD.bazel
@@ -12,7 +12,7 @@ exports_files([
|
||||
"LICENSE.md",
|
||||
])
|
||||
|
||||
# gazelle:prefix github.com/prysmaticlabs/prysm/v4
|
||||
# gazelle:prefix github.com/prysmaticlabs/prysm/v5
|
||||
# gazelle:map_kind go_library go_library @prysm//tools/go:def.bzl
|
||||
# gazelle:map_kind go_test go_test @prysm//tools/go:def.bzl
|
||||
# gazelle:map_kind go_repository go_repository @prysm//tools/go:def.bzl
|
||||
@@ -55,13 +55,6 @@ alias(
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
# Protobuf gRPC gateway compiler
|
||||
alias(
|
||||
name = "grpc_gateway_proto_compiler",
|
||||
actual = "@com_github_grpc_ecosystem_grpc_gateway_v2//protoc-gen-grpc-gateway:go_gen_grpc_gateway",
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
gometalinter(
|
||||
name = "gometalinter",
|
||||
config = "//:.gometalinter.json",
|
||||
@@ -126,7 +119,7 @@ STATICCHECK_ANALYZERS = [
|
||||
"sa4003",
|
||||
"sa4004",
|
||||
"sa4005",
|
||||
# "sa4006", # TODO: Fix violations of unused arguments.
|
||||
"sa4006",
|
||||
"sa4008",
|
||||
"sa4009",
|
||||
"sa4010",
|
||||
@@ -172,7 +165,7 @@ STATICCHECK_ANALYZERS = [
|
||||
"sa6006",
|
||||
"sa9001",
|
||||
"sa9002",
|
||||
#"sa9003", # Doesn't build
|
||||
"sa9003",
|
||||
"sa9004",
|
||||
"sa9005",
|
||||
"sa9006",
|
||||
@@ -194,33 +187,6 @@ nogo(
|
||||
config = ":nogo_config_with_excludes",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"@org_golang_x_tools//go/analysis/passes/unsafeptr:go_default_library",
|
||||
"@org_golang_x_tools//go/analysis/passes/unreachable:go_default_library",
|
||||
"@org_golang_x_tools//go/analysis/passes/unmarshal:go_default_library",
|
||||
"@org_golang_x_tools//go/analysis/passes/tests:go_default_library",
|
||||
"@org_golang_x_tools//go/analysis/passes/structtag:go_default_library",
|
||||
"@org_golang_x_tools//go/analysis/passes/stdmethods:go_default_library",
|
||||
"@org_golang_x_tools//go/analysis/passes/shift:go_default_library",
|
||||
# "@org_golang_x_tools//go/analysis/passes/shadow:go_default_library",
|
||||
"@org_golang_x_tools//go/analysis/passes/printf:go_default_library",
|
||||
"@org_golang_x_tools//go/analysis/passes/pkgfact:go_default_library",
|
||||
"@org_golang_x_tools//go/analysis/passes/nilness:go_default_library",
|
||||
"@org_golang_x_tools//go/analysis/passes/nilfunc:go_default_library",
|
||||
"@org_golang_x_tools//go/analysis/passes/loopclosure:go_default_library",
|
||||
"@org_golang_x_tools//go/analysis/passes/httpresponse:go_default_library",
|
||||
"@org_golang_x_tools//go/analysis/passes/findcall:go_default_library",
|
||||
"@org_golang_x_tools//go/analysis/passes/deepequalerrors:go_default_library",
|
||||
"@org_golang_x_tools//go/analysis/passes/ctrlflow:go_default_library",
|
||||
"@org_golang_x_tools//go/analysis/passes/copylock:go_default_library",
|
||||
# "@org_golang_x_tools//go/analysis/passes/cgocall:go_default_library",
|
||||
"@org_golang_x_tools//go/analysis/passes/buildtag:go_default_library",
|
||||
"@org_golang_x_tools//go/analysis/passes/buildssa:go_default_library",
|
||||
"@org_golang_x_tools//go/analysis/passes/bools:go_default_library",
|
||||
"@org_golang_x_tools//go/analysis/passes/atomicalign:go_default_library",
|
||||
"@org_golang_x_tools//go/analysis/passes/atomic:go_default_library",
|
||||
"@org_golang_x_tools//go/analysis/passes/assign:go_default_library",
|
||||
"@org_golang_x_tools//go/analysis/passes/inspect:go_default_library",
|
||||
"@org_golang_x_tools//go/analysis/passes/asmdecl:go_default_library",
|
||||
"//tools/analyzers/comparesame:go_default_library",
|
||||
"//tools/analyzers/cryptorand:go_default_library",
|
||||
"//tools/analyzers/errcheck:go_default_library",
|
||||
@@ -231,11 +197,60 @@ nogo(
|
||||
"//tools/analyzers/logruswitherror:go_default_library",
|
||||
"//tools/analyzers/maligned:go_default_library",
|
||||
"//tools/analyzers/nop:go_default_library",
|
||||
"//tools/analyzers/nopanic:go_default_library",
|
||||
"//tools/analyzers/properpermissions:go_default_library",
|
||||
"//tools/analyzers/recursivelock:go_default_library",
|
||||
"//tools/analyzers/shadowpredecl:go_default_library",
|
||||
"//tools/analyzers/slicedirect:go_default_library",
|
||||
"//tools/analyzers/uintcast:go_default_library",
|
||||
"@org_golang_x_tools//go/analysis/passes/appends:go_default_library",
|
||||
"@org_golang_x_tools//go/analysis/passes/asmdecl:go_default_library",
|
||||
"@org_golang_x_tools//go/analysis/passes/assign:go_default_library",
|
||||
"@org_golang_x_tools//go/analysis/passes/atomic:go_default_library",
|
||||
"@org_golang_x_tools//go/analysis/passes/atomicalign:go_default_library",
|
||||
"@org_golang_x_tools//go/analysis/passes/bools:go_default_library",
|
||||
"@org_golang_x_tools//go/analysis/passes/buildssa:go_default_library",
|
||||
"@org_golang_x_tools//go/analysis/passes/buildtag:go_default_library",
|
||||
# cgocall disabled
|
||||
#"@org_golang_x_tools//go/analysis/passes/cgocall:go_default_library",
|
||||
"@org_golang_x_tools//go/analysis/passes/copylock:go_default_library",
|
||||
"@org_golang_x_tools//go/analysis/passes/ctrlflow:go_default_library",
|
||||
"@org_golang_x_tools//go/analysis/passes/deepequalerrors:go_default_library",
|
||||
"@org_golang_x_tools//go/analysis/passes/defers:go_default_library",
|
||||
"@org_golang_x_tools//go/analysis/passes/directive:go_default_library",
|
||||
"@org_golang_x_tools//go/analysis/passes/errorsas:go_default_library",
|
||||
# fieldalignment disabled
|
||||
#"@org_golang_x_tools//go/analysis/passes/fieldalignment:go_default_library",
|
||||
"@org_golang_x_tools//go/analysis/passes/findcall:go_default_library",
|
||||
"@org_golang_x_tools//go/analysis/passes/framepointer:go_default_library",
|
||||
"@org_golang_x_tools//go/analysis/passes/httpmux:go_default_library",
|
||||
"@org_golang_x_tools//go/analysis/passes/httpresponse:go_default_library",
|
||||
"@org_golang_x_tools//go/analysis/passes/ifaceassert:go_default_library",
|
||||
"@org_golang_x_tools//go/analysis/passes/inspect:go_default_library",
|
||||
"@org_golang_x_tools//go/analysis/passes/loopclosure:go_default_library",
|
||||
"@org_golang_x_tools//go/analysis/passes/nilfunc:go_default_library",
|
||||
"@org_golang_x_tools//go/analysis/passes/nilness:go_default_library",
|
||||
"@org_golang_x_tools//go/analysis/passes/pkgfact:go_default_library",
|
||||
"@org_golang_x_tools//go/analysis/passes/printf:go_default_library",
|
||||
"@org_golang_x_tools//go/analysis/passes/reflectvaluecompare:go_default_library",
|
||||
# shadow disabled
|
||||
#"@org_golang_x_tools//go/analysis/passes/shadow:go_default_library",
|
||||
"@org_golang_x_tools//go/analysis/passes/shift:go_default_library",
|
||||
"@org_golang_x_tools//go/analysis/passes/sigchanyzer:go_default_library",
|
||||
"@org_golang_x_tools//go/analysis/passes/slog:go_default_library",
|
||||
"@org_golang_x_tools//go/analysis/passes/sortslice:go_default_library",
|
||||
"@org_golang_x_tools//go/analysis/passes/stdmethods:go_default_library",
|
||||
"@org_golang_x_tools//go/analysis/passes/stringintconv:go_default_library",
|
||||
"@org_golang_x_tools//go/analysis/passes/structtag:go_default_library",
|
||||
"@org_golang_x_tools//go/analysis/passes/testinggoroutine:go_default_library",
|
||||
"@org_golang_x_tools//go/analysis/passes/tests:go_default_library",
|
||||
"@org_golang_x_tools//go/analysis/passes/timeformat:go_default_library",
|
||||
"@org_golang_x_tools//go/analysis/passes/unmarshal:go_default_library",
|
||||
"@org_golang_x_tools//go/analysis/passes/unreachable:go_default_library",
|
||||
"@org_golang_x_tools//go/analysis/passes/unsafeptr:go_default_library",
|
||||
"@org_golang_x_tools//go/analysis/passes/unusedresult:go_default_library",
|
||||
"@org_golang_x_tools//go/analysis/passes/unusedwrite:go_default_library",
|
||||
"@org_golang_x_tools//go/analysis/passes/usesgenerics:go_default_library",
|
||||
] + select({
|
||||
# nogo checks that fail with coverage enabled.
|
||||
":coverage_enabled": [],
|
||||
|
||||
3258
CHANGELOG.md
Normal file
3258
CHANGELOG.md
Normal file
File diff suppressed because it is too large
Load Diff
@@ -6,6 +6,9 @@ Excited by our work and want to get involved in building out our sharding releas
|
||||
|
||||
You can explore our [Open Issues](https://github.com/prysmaticlabs/prysm/issues) in-the works for our different releases. Feel free to fork our repo and start creating PR’s after assigning yourself to an issue of interest. We are always chatting on [Discord](https://discord.gg/CTYGPUJ) drop us a line there if you want to get more involved or have any questions on our implementation!
|
||||
|
||||
> [!IMPORTANT]
|
||||
> Please, **do not send pull requests for trivial changes**, such as typos, these will be rejected. These types of pull requests incur a cost to reviewers and do not provide much value to the project. If you are unsure, please open an issue first to discuss the change.
|
||||
|
||||
## Contribution Steps
|
||||
|
||||
**1. Set up Prysm following the instructions in README.md.**
|
||||
@@ -120,15 +123,19 @@ $ git push myrepo feature-in-progress-branch
|
||||
|
||||
Navigate to your fork of the repo on GitHub. On the upper left where the current branch is listed, change the branch to your feature-in-progress-branch. Open the files that you have worked on and check to make sure they include your changes.
|
||||
|
||||
**16. Create a pull request.**
|
||||
**16. Add an entry to CHANGELOG.md.**
|
||||
|
||||
Navigate your browser to https://github.com/prysmaticlabs/prysm and click on the new pull request button. In the “base” box on the left, leave the default selection “base master”, the branch that you want your changes to be applied to. In the “compare” box on the right, select feature-in-progress-branch, the branch containing the changes you want to apply. You will then be asked to answer a few questions about your pull request. After you complete the questionnaire, the pull request will appear in the list of pull requests at https://github.com/prysmaticlabs/prysm/pulls.
|
||||
All PRs must must include a changelog fragment file in the `changelog` directory. If your change is not user-facing or should not be mentioned in the changelog for some other reason, you may use the `Ignored` changelog section in your fragment's header to satisfy this requirement without altering the final release changelog. See the [Maintaining CHANGELOG.md](#maintaining-changelogmd) section for more information.
|
||||
|
||||
**17. Respond to comments by Core Contributors.**
|
||||
**17. Create a pull request.**
|
||||
|
||||
Navigate your browser to https://github.com/prysmaticlabs/prysm and click on the new pull request button. In the “base” box on the left, leave the default selection “base develop”, the branch that you want your changes to be applied to. In the “compare” box on the right, select feature-in-progress-branch, the branch containing the changes you want to apply. You will then be asked to answer a few questions about your pull request. After you complete the questionnaire, the pull request will appear in the list of pull requests at https://github.com/prysmaticlabs/prysm/pulls. Ensure that you have added an entry to CHANGELOG.md if your PR is a user-facing change. See the [Maintaining CHANGELOG.md](#maintaining-changelogmd) section for more information.
|
||||
|
||||
**18. Respond to comments by Core Contributors.**
|
||||
|
||||
Core Contributors may ask questions and request that you make edits. If you set notifications at the top of the page to “not watching,” you will still be notified by email whenever someone comments on the page of a pull request you have created. If you are asked to modify your pull request, repeat steps 8 through 15, then leave a comment to notify the Core Contributors that the pull request is ready for further review.
|
||||
|
||||
**18. If the number of commits becomes excessive, you may be asked to squash your commits.**
|
||||
**19. If the number of commits becomes excessive, you may be asked to squash your commits.**
|
||||
|
||||
You can do this with an interactive rebase. Start by running the following command to determine the commit that is the base of your branch...
|
||||
|
||||
@@ -136,7 +143,7 @@ Core Contributors may ask questions and request that you make edits. If you set
|
||||
$ git merge-base feature-in-progress-branch prysm/master
|
||||
```
|
||||
|
||||
**19. The previous command will return a commit-hash that you should use in the following command.**
|
||||
**20. The previous command will return a commit-hash that you should use in the following command.**
|
||||
|
||||
```
|
||||
$ git rebase -i commit-hash
|
||||
@@ -160,13 +167,24 @@ squash hash add a feature
|
||||
|
||||
Save and close the file, then a commit command will appear in the terminal that squashes the smaller commits into one. Check to be sure the commit message accurately reflects your changes and then hit enter to execute it.
|
||||
|
||||
**20. Update your pull request with the following command.**
|
||||
**21. Update your pull request with the following command.**
|
||||
|
||||
```
|
||||
$ git push myrepo feature-in-progress-branch -f
|
||||
```
|
||||
|
||||
**21. Finally, again leave a comment to the Core Contributors on the pull request to let them know that the pull request has been updated.**
|
||||
**22. Finally, again leave a comment to the Core Contributors on the pull request to let them know that the pull request has been updated.**
|
||||
|
||||
## Maintaining CHANGELOG.md
|
||||
|
||||
This project follows the changelog guidelines from [keepachangelog.com](https://keepachangelog.com/en/1.1.0/). In order to minimize conflicts and workflow headaches, we chose to implement a changelog management
|
||||
strategy that uses changelog "fragment" files, managed by our changelog management tool called `unclog`. Each PR must include a new changelog fragment file in the `changelog` directory, as specified by unclog's
|
||||
[README.md](https://github.com/OffchainLabs/unclog?tab=readme-ov-file#what-is-a-changelog-fragment). As the `unclog` README suggests in the [Best Practices](https://github.com/OffchainLabs/unclog?tab=readme-ov-file#best-practices) section,
|
||||
the standard naming convention for your PR's fragment file, to avoid conflicting with another fragment file, is `changelog/<github user name>_<PR branch name>.md`.
|
||||
|
||||
### Releasing
|
||||
|
||||
When a new release is made, the "Unreleased" section should be moved to a new section with the release version and the current date. Then a new "Unreleased" section is made at the top of the file with the categories listed above.
|
||||
|
||||
## Contributor Responsibilities
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ bazel build //beacon-chain --config=release
|
||||
## Adding / updating dependencies
|
||||
|
||||
1. Add your dependency as you would with go modules. I.e. `go get ...`
|
||||
1. Run `gazelle update-repos -from_file=go.mod` to update the bazel managed dependencies.
|
||||
1. Run `bazel run //:gazelle -- update-repos -from_file=go.mod -to_macro=deps.bzl%prysm_deps -prune=true` to update the bazel managed dependencies.
|
||||
|
||||
Example:
|
||||
|
||||
|
||||
113
INTEROP.md
113
INTEROP.md
@@ -2,18 +2,21 @@
|
||||
|
||||
This README details how to setup Prysm for interop testing for usage with other Ethereum consensus clients.
|
||||
|
||||
> [!IMPORTANT]
|
||||
> This guide is likely to be outdated. The Prysm team does not have capacity to troubleshoot
|
||||
> outdated interop guides or instructions. If you experience issues with this guide, please file an
|
||||
> issue for visibility and propose fixes, if possible.
|
||||
|
||||
## Installation & Setup
|
||||
|
||||
1. Install [Bazel](https://docs.bazel.build/versions/master/install.html) **(Recommended)**
|
||||
2. `git clone https://github.com/prysmaticlabs/prysm && cd prysm`
|
||||
3. `bazel build //...`
|
||||
3. `bazel build //cmd/...`
|
||||
|
||||
## Starting from Genesis
|
||||
|
||||
Prysm supports a few ways to quickly launch a beacon node from basic configurations:
|
||||
|
||||
- `NumValidators + GenesisTime`: Launches a beacon node by deterministically generating a state from a num-validators flag along with a genesis time **(Recommended)**
|
||||
- `SSZ Genesis`: Launches a beacon node from a .ssz file containing a SSZ-encoded, genesis beacon state
|
||||
Prysm can be started from a built-in mainnet genesis state, or started with a provided genesis state by
|
||||
using the `--genesis-state` flag and providing a path to the genesis.ssz file.
|
||||
|
||||
## Generating a Genesis State
|
||||
|
||||
@@ -21,24 +24,34 @@ To setup the necessary files for these quick starts, Prysm provides a tool to ge
|
||||
a deterministically generated set of validator private keys following the official interop YAML format
|
||||
[here](https://github.com/ethereum/eth2.0-pm/blob/master/interop/mocked_start).
|
||||
|
||||
You can use `bazel run //tools/genesis-state-gen` to create a deterministic genesis state for interop.
|
||||
You can use `prysmctl` to create a deterministic genesis state for interop.
|
||||
|
||||
### Usage
|
||||
|
||||
- **--genesis-time** uint: Unix timestamp used as the genesis time in the generated genesis state (defaults to now)
|
||||
- **--num-validators** int: Number of validators to deterministically include in the generated genesis state
|
||||
- **--output-ssz** string: Output filename of the SSZ marshaling of the generated genesis state
|
||||
- **--config-name=interop** string: name of the beacon chain config to use when generating the state. ex mainnet|minimal|interop
|
||||
|
||||
**deprecated flag: use --config-name instead**
|
||||
- **--mainnet-config** bool: Select whether genesis state should be generated with mainnet or minimal (default) params
|
||||
|
||||
The example below creates 64 validator keys, instantiates a genesis state with those 64 validators and with genesis unix timestamp 1567542540,
|
||||
and finally writes a ssz encoded output to ~/Desktop/genesis.ssz. This file can be used to kickstart the beacon chain in the next section. When using the `--interop-*` flags, the beacon node will assume the `interop` config should be used, unless a different config is specified on the command line.
|
||||
```sh
|
||||
# Download (or create) a chain config file.
|
||||
curl https://raw.githubusercontent.com/ethereum/consensus-specs/refs/heads/dev/configs/minimal.yaml -o /tmp/minimal.yaml
|
||||
|
||||
# Run prysmctl to generate genesis with a 2 minute genesis delay and 256 validators.
|
||||
bazel run //cmd/prysmctl --config=minimal -- \
|
||||
testnet generate-genesis \
|
||||
--genesis-time-delay=120 \
|
||||
--num-validators=256 \
|
||||
--output-ssz=/tmp/genesis.ssz \
|
||||
--chain-config-file=/tmp/minimal.yaml
|
||||
```
|
||||
bazel run //tools/genesis-state-gen -- --config-name interop --output-ssz ~/Desktop/genesis.ssz --num-validators 64 --genesis-time 1567542540
|
||||
```
|
||||
|
||||
The flags are explained below:
|
||||
- `bazel run //cmd/prysmctl` is the bazel command to compile and run prysmctl.
|
||||
- `--config=minimal` is a bazel build time configuration flag to compile Prysm with minimal state constants.
|
||||
- `--` is an argument divider to tell bazel that everything after this divider should be passed as arguments to prysmctl. Without this divider, it isn't clear to bazel if the arguments are meant to be build time arguments or runtime arguments so the operation complains and fails to build without this divider.
|
||||
- `testnet` is the primary command argument for prysmctl.
|
||||
- `generate-genesis` is the subcommand to `testnet` in prysmctl.
|
||||
- `--genesis-time-delay` uint: The number of seconds in the future to define genesis. Example: a value of 60 will set the genesis time to 1 minute in the future. This should be sufficiently large enough to allow for you to start the beacon node before the genesis time.
|
||||
- `--num-validators` int: Number of validators to deterministically include in the generated genesis state
|
||||
- `--output-ssz` string: Output filename of the SSZ marshaling of the generated genesis state
|
||||
- `--chain-config-file` string: Filepath to a chain config yaml file.
|
||||
|
||||
Note: This guide saves items to the `/tmp/` directory which will not persist if your machine is
|
||||
restarted. Consider tweaking the arguments if persistence is needed.
|
||||
|
||||
## Launching a Beacon Node + Validator Client
|
||||
|
||||
@@ -47,45 +60,33 @@ bazel run //tools/genesis-state-gen -- --config-name interop --output-ssz ~/Desk
|
||||
Open up two terminal windows, run:
|
||||
|
||||
```
|
||||
bazel run //beacon-chain -- \
|
||||
--bootstrap-node= \
|
||||
--deposit-contract 0x8A04d14125D0FDCDc742F4A05C051De07232EDa4 \
|
||||
--datadir=/tmp/beacon-chain-interop \
|
||||
--force-clear-db \
|
||||
--min-sync-peers=0 \
|
||||
--interop-num-validators 64 \
|
||||
--interop-eth1data-votes
|
||||
bazel run //cmd/beacon-chain --config=minimal -- \
|
||||
--minimal-config \
|
||||
--bootstrap-node= \
|
||||
--deposit-contract 0x8A04d14125D0FDCDc742F4A05C051De07232EDa4 \
|
||||
--datadir=/tmp/beacon-chain-minimal-devnet \
|
||||
--force-clear-db \
|
||||
--min-sync-peers=0 \
|
||||
--genesis-state=/tmp/genesis.ssz \
|
||||
--chain-config-file=/tmp/minimal.yaml
|
||||
```
|
||||
|
||||
This will deterministically generate a beacon genesis state and start
|
||||
the system with 64 validators and the genesis time set to the current unix timestamp.
|
||||
Wait a bit until your beacon chain starts, and in the other window:
|
||||
This will start the system with 256 validators. The flags used can be explained as such:
|
||||
|
||||
- `bazel run //cmd/beacon-chain --config=minimal` builds and runs the beacon node in minimal build configuration.
|
||||
- `--` is a flag divider to distinguish between bazel flags and flags that should be passed to the application. All flags and arguments after this divider are passed to the beacon chain.
|
||||
- `--minimal-config` tells the beacon node to use minimal network configuration. This is different from the compile time state configuration flag `--config=minimal` and both are required.
|
||||
- `--bootstrap-node=` disables the default bootstrap nodes. This prevents the client from attempting to peer with mainnet nodes.
|
||||
- `--datadir=/tmp/beacon-chain-minimal-devnet` sets the data directory in a temporary location. Change this to your preferred destination.
|
||||
- `--force-clear-db` will delete the beaconchain.db file without confirming with the user. This is helpful for iteratively running local devnets without changing the datadir, but less helpful for one off runs where there was no database in the data directory.
|
||||
- `--min-sync-peers=0` allows the beacon node to skip initial sync without peers. This is essential because Prysm expects at least a few peers to start the blockchain.
|
||||
- `--genesis-state=/tmp/genesis.ssz` defines the path to the generated genesis ssz file. The beacon node will use this as the initial genesis state.
|
||||
- `--chain-config-file=/tmp/minimal.yaml` defines the path to the yaml file with the chain configuration.
|
||||
|
||||
As soon as the beacon node has started, start the validator in the other terminal window.
|
||||
|
||||
```
|
||||
bazel run //validator -- --keymanager=interop --keymanageropts='{"keys":64}'
|
||||
bazel run //cmd/validator --config=minimal -- --datadir=/tmp/validator --interop-num-validators=256 --minimal-config --suggested-fee-recipient=0x8A04d14125D0FDCDc742F4A05C051De07232EDa4
|
||||
```
|
||||
|
||||
This will launch and kickstart the system with your 64 validators performing their duties accordingly.
|
||||
|
||||
### Launching from `genesis.ssz`
|
||||
|
||||
Assuming you generated a `genesis.ssz` file with 64 validators, open up two terminal windows, run:
|
||||
|
||||
```
|
||||
bazel run //beacon-chain -- \
|
||||
--bootstrap-node= \
|
||||
--deposit-contract 0x8A04d14125D0FDCDc742F4A05C051De07232EDa4 \
|
||||
--datadir=/tmp/beacon-chain-interop \
|
||||
--force-clear-db \
|
||||
--min-sync-peers=0 \
|
||||
--interop-genesis-state /path/to/genesis.ssz \
|
||||
--interop-eth1data-votes
|
||||
```
|
||||
|
||||
Wait a bit until your beacon chain starts, and in the other window:
|
||||
|
||||
```
|
||||
bazel run //validator -- --keymanager=interop --keymanageropts='{"keys":64}'
|
||||
```
|
||||
|
||||
This will launch and kickstart the system with your 64 validators performing their duties accordingly.
|
||||
This will launch and kickstart the system with your 256 validators performing their duties accordingly.
|
||||
|
||||
6
MODULE.bazel
Normal file
6
MODULE.bazel
Normal file
@@ -0,0 +1,6 @@
|
||||
###############################################################################
|
||||
# Bazel now uses Bzlmod by default to manage external dependencies.
|
||||
# Please consider migrating your external dependencies from WORKSPACE to MODULE.bazel.
|
||||
#
|
||||
# For more details, please check https://github.com/bazelbuild/bazel/issues/18958
|
||||
###############################################################################
|
||||
110
MODULE.bazel.lock
generated
Normal file
110
MODULE.bazel.lock
generated
Normal file
@@ -0,0 +1,110 @@
|
||||
{
|
||||
"lockFileVersion": 11,
|
||||
"registryFileHashes": {
|
||||
"https://bcr.bazel.build/bazel_registry.json": "8a28e4aff06ee60aed2a8c281907fb8bcbf3b753c91fb5a5c57da3215d5b3497",
|
||||
"https://bcr.bazel.build/modules/abseil-cpp/20210324.2/MODULE.bazel": "7cd0312e064fde87c8d1cd79ba06c876bd23630c83466e9500321be55c96ace2",
|
||||
"https://bcr.bazel.build/modules/abseil-cpp/20211102.0/MODULE.bazel": "70390338f7a5106231d20620712f7cccb659cd0e9d073d1991c038eb9fc57589",
|
||||
"https://bcr.bazel.build/modules/abseil-cpp/20211102.0/source.json": "7e3a9adf473e9af076ae485ed649d5641ad50ec5c11718103f34de03170d94ad",
|
||||
"https://bcr.bazel.build/modules/apple_support/1.5.0/MODULE.bazel": "50341a62efbc483e8a2a6aec30994a58749bd7b885e18dd96aa8c33031e558ef",
|
||||
"https://bcr.bazel.build/modules/apple_support/1.5.0/source.json": "eb98a7627c0bc486b57f598ad8da50f6625d974c8f723e9ea71bd39f709c9862",
|
||||
"https://bcr.bazel.build/modules/bazel_features/1.11.0/MODULE.bazel": "f9382337dd5a474c3b7d334c2f83e50b6eaedc284253334cf823044a26de03e8",
|
||||
"https://bcr.bazel.build/modules/bazel_features/1.11.0/source.json": "c9320aa53cd1c441d24bd6b716da087ad7e4ff0d9742a9884587596edfe53015",
|
||||
"https://bcr.bazel.build/modules/bazel_skylib/1.0.3/MODULE.bazel": "bcb0fd896384802d1ad283b4e4eb4d718eebd8cb820b0a2c3a347fb971afd9d8",
|
||||
"https://bcr.bazel.build/modules/bazel_skylib/1.2.1/MODULE.bazel": "f35baf9da0efe45fa3da1696ae906eea3d615ad41e2e3def4aeb4e8bc0ef9a7a",
|
||||
"https://bcr.bazel.build/modules/bazel_skylib/1.3.0/MODULE.bazel": "20228b92868bf5cfc41bda7afc8a8ba2a543201851de39d990ec957b513579c5",
|
||||
"https://bcr.bazel.build/modules/bazel_skylib/1.6.1/MODULE.bazel": "8fdee2dbaace6c252131c00e1de4b165dc65af02ea278476187765e1a617b917",
|
||||
"https://bcr.bazel.build/modules/bazel_skylib/1.6.1/source.json": "082ed5f9837901fada8c68c2f3ddc958bb22b6d654f71dd73f3df30d45d4b749",
|
||||
"https://bcr.bazel.build/modules/buildozer/7.1.2/MODULE.bazel": "2e8dd40ede9c454042645fd8d8d0cd1527966aa5c919de86661e62953cd73d84",
|
||||
"https://bcr.bazel.build/modules/buildozer/7.1.2/source.json": "c9028a501d2db85793a6996205c8de120944f50a0d570438fcae0457a5f9d1f8",
|
||||
"https://bcr.bazel.build/modules/googletest/1.11.0/MODULE.bazel": "3a83f095183f66345ca86aa13c58b59f9f94a2f81999c093d4eeaa2d262d12f4",
|
||||
"https://bcr.bazel.build/modules/googletest/1.11.0/source.json": "c73d9ef4268c91bd0c1cd88f1f9dfa08e814b1dbe89b5f594a9f08ba0244d206",
|
||||
"https://bcr.bazel.build/modules/platforms/0.0.4/MODULE.bazel": "9b328e31ee156f53f3c416a64f8491f7eb731742655a47c9eec4703a71644aee",
|
||||
"https://bcr.bazel.build/modules/platforms/0.0.5/MODULE.bazel": "5733b54ea419d5eaf7997054bb55f6a1d0b5ff8aedf0176fef9eea44f3acda37",
|
||||
"https://bcr.bazel.build/modules/platforms/0.0.6/MODULE.bazel": "ad6eeef431dc52aefd2d77ed20a4b353f8ebf0f4ecdd26a807d2da5aa8cd0615",
|
||||
"https://bcr.bazel.build/modules/platforms/0.0.7/MODULE.bazel": "72fd4a0ede9ee5c021f6a8dd92b503e089f46c227ba2813ff183b71616034814",
|
||||
"https://bcr.bazel.build/modules/platforms/0.0.9/MODULE.bazel": "4a87a60c927b56ddd67db50c89acaa62f4ce2a1d2149ccb63ffd871d5ce29ebc",
|
||||
"https://bcr.bazel.build/modules/platforms/0.0.9/source.json": "cd74d854bf16a9e002fb2ca7b1a421f4403cda29f824a765acd3a8c56f8d43e6",
|
||||
"https://bcr.bazel.build/modules/protobuf/21.7/MODULE.bazel": "a5a29bb89544f9b97edce05642fac225a808b5b7be74038ea3640fae2f8e66a7",
|
||||
"https://bcr.bazel.build/modules/protobuf/21.7/source.json": "bbe500720421e582ff2d18b0802464205138c06056f443184de39fbb8187b09b",
|
||||
"https://bcr.bazel.build/modules/protobuf/3.19.0/MODULE.bazel": "6b5fbb433f760a99a22b18b6850ed5784ef0e9928a72668b66e4d7ccd47db9b0",
|
||||
"https://bcr.bazel.build/modules/protobuf/3.19.6/MODULE.bazel": "9233edc5e1f2ee276a60de3eaa47ac4132302ef9643238f23128fea53ea12858",
|
||||
"https://bcr.bazel.build/modules/rules_cc/0.0.1/MODULE.bazel": "cb2aa0747f84c6c3a78dad4e2049c154f08ab9d166b1273835a8174940365647",
|
||||
"https://bcr.bazel.build/modules/rules_cc/0.0.2/MODULE.bazel": "6915987c90970493ab97393024c156ea8fb9f3bea953b2f3ec05c34f19b5695c",
|
||||
"https://bcr.bazel.build/modules/rules_cc/0.0.8/MODULE.bazel": "964c85c82cfeb6f3855e6a07054fdb159aced38e99a5eecf7bce9d53990afa3e",
|
||||
"https://bcr.bazel.build/modules/rules_cc/0.0.9/MODULE.bazel": "836e76439f354b89afe6a911a7adf59a6b2518fafb174483ad78a2a2fde7b1c5",
|
||||
"https://bcr.bazel.build/modules/rules_cc/0.0.9/source.json": "1f1ba6fea244b616de4a554a0f4983c91a9301640c8fe0dd1d410254115c8430",
|
||||
"https://bcr.bazel.build/modules/rules_java/4.0.0/MODULE.bazel": "5a78a7ae82cd1a33cef56dc578c7d2a46ed0dca12643ee45edbb8417899e6f74",
|
||||
"https://bcr.bazel.build/modules/rules_java/7.6.5/MODULE.bazel": "481164be5e02e4cab6e77a36927683263be56b7e36fef918b458d7a8a1ebadb1",
|
||||
"https://bcr.bazel.build/modules/rules_java/7.6.5/source.json": "a805b889531d1690e3c72a7a7e47a870d00323186a9904b36af83aa3d053ee8d",
|
||||
"https://bcr.bazel.build/modules/rules_jvm_external/4.4.2/MODULE.bazel": "a56b85e418c83eb1839819f0b515c431010160383306d13ec21959ac412d2fe7",
|
||||
"https://bcr.bazel.build/modules/rules_jvm_external/4.4.2/source.json": "a075731e1b46bc8425098512d038d416e966ab19684a10a34f4741295642fc35",
|
||||
"https://bcr.bazel.build/modules/rules_license/0.0.3/MODULE.bazel": "627e9ab0247f7d1e05736b59dbb1b6871373de5ad31c3011880b4133cafd4bd0",
|
||||
"https://bcr.bazel.build/modules/rules_license/0.0.7/MODULE.bazel": "088fbeb0b6a419005b89cf93fe62d9517c0a2b8bb56af3244af65ecfe37e7d5d",
|
||||
"https://bcr.bazel.build/modules/rules_license/0.0.7/source.json": "355cc5737a0f294e560d52b1b7a6492d4fff2caf0bef1a315df5a298fca2d34a",
|
||||
"https://bcr.bazel.build/modules/rules_pkg/0.7.0/MODULE.bazel": "df99f03fc7934a4737122518bb87e667e62d780b610910f0447665a7e2be62dc",
|
||||
"https://bcr.bazel.build/modules/rules_pkg/0.7.0/source.json": "c2557066e0c0342223ba592510ad3d812d4963b9024831f7f66fd0584dd8c66c",
|
||||
"https://bcr.bazel.build/modules/rules_proto/4.0.0/MODULE.bazel": "a7a7b6ce9bee418c1a760b3d84f83a299ad6952f9903c67f19e4edd964894e06",
|
||||
"https://bcr.bazel.build/modules/rules_proto/5.3.0-21.7/MODULE.bazel": "e8dff86b0971688790ae75528fe1813f71809b5afd57facb44dad9e8eca631b7",
|
||||
"https://bcr.bazel.build/modules/rules_proto/5.3.0-21.7/source.json": "d57902c052424dfda0e71646cb12668d39c4620ee0544294d9d941e7d12bc3a9",
|
||||
"https://bcr.bazel.build/modules/rules_python/0.10.2/MODULE.bazel": "cc82bc96f2997baa545ab3ce73f196d040ffb8756fd2d66125a530031cd90e5f",
|
||||
"https://bcr.bazel.build/modules/rules_python/0.22.1/MODULE.bazel": "26114f0c0b5e93018c0c066d6673f1a2c3737c7e90af95eff30cfee38d0bbac7",
|
||||
"https://bcr.bazel.build/modules/rules_python/0.22.1/source.json": "57226905e783bae7c37c2dd662be078728e48fa28ee4324a7eabcafb5a43d014",
|
||||
"https://bcr.bazel.build/modules/rules_python/0.4.0/MODULE.bazel": "9208ee05fd48bf09ac60ed269791cf17fb343db56c8226a720fbb1cdf467166c",
|
||||
"https://bcr.bazel.build/modules/stardoc/0.5.1/MODULE.bazel": "1a05d92974d0c122f5ccf09291442580317cdd859f07a8655f1db9a60374f9f8",
|
||||
"https://bcr.bazel.build/modules/stardoc/0.5.1/source.json": "a96f95e02123320aa015b956f29c00cb818fa891ef823d55148e1a362caacf29",
|
||||
"https://bcr.bazel.build/modules/upb/0.0.0-20220923-a547704/MODULE.bazel": "7298990c00040a0e2f121f6c32544bab27d4452f80d9ce51349b1a28f3005c43",
|
||||
"https://bcr.bazel.build/modules/upb/0.0.0-20220923-a547704/source.json": "f1ef7d3f9e0e26d4b23d1c39b5f5de71f584dd7d1b4ef83d9bbba6ec7a6a6459",
|
||||
"https://bcr.bazel.build/modules/zlib/1.2.11/MODULE.bazel": "07b389abc85fdbca459b69e2ec656ae5622873af3f845e1c9d80fe179f3effa0",
|
||||
"https://bcr.bazel.build/modules/zlib/1.2.12/MODULE.bazel": "3b1a8834ada2a883674be8cbd36ede1b6ec481477ada359cd2d3ddc562340b27",
|
||||
"https://bcr.bazel.build/modules/zlib/1.3.1.bcr.3/MODULE.bazel": "af322bc08976524477c79d1e45e241b6efbeb918c497e8840b8ab116802dda79",
|
||||
"https://bcr.bazel.build/modules/zlib/1.3.1.bcr.3/source.json": "2be409ac3c7601245958cd4fcdff4288be79ed23bd690b4b951f500d54ee6e7d"
|
||||
},
|
||||
"selectedYankedVersions": {},
|
||||
"moduleExtensions": {
|
||||
"@@apple_support~//crosstool:setup.bzl%apple_cc_configure_extension": {
|
||||
"general": {
|
||||
"bzlTransitiveDigest": "PjIds3feoYE8SGbbIq2SFTZy3zmxeO2tQevJZNDo7iY=",
|
||||
"usagesDigest": "+hz7IHWN6A1oVJJWNDB6yZRG+RYhF76wAYItpAeIUIg=",
|
||||
"recordedFileInputs": {},
|
||||
"recordedDirentsInputs": {},
|
||||
"envVariables": {},
|
||||
"generatedRepoSpecs": {
|
||||
"local_config_apple_cc_toolchains": {
|
||||
"bzlFile": "@@apple_support~//crosstool:setup.bzl",
|
||||
"ruleClassName": "_apple_cc_autoconf_toolchains",
|
||||
"attributes": {}
|
||||
},
|
||||
"local_config_apple_cc": {
|
||||
"bzlFile": "@@apple_support~//crosstool:setup.bzl",
|
||||
"ruleClassName": "_apple_cc_autoconf",
|
||||
"attributes": {}
|
||||
}
|
||||
},
|
||||
"recordedRepoMappingEntries": [
|
||||
[
|
||||
"apple_support~",
|
||||
"bazel_tools",
|
||||
"bazel_tools"
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
"@@platforms//host:extension.bzl%host_platform": {
|
||||
"general": {
|
||||
"bzlTransitiveDigest": "xelQcPZH8+tmuOHVjL9vDxMnnQNMlwj0SlvgoqBkm4U=",
|
||||
"usagesDigest": "pCYpDQmqMbmiiPI1p2Kd3VLm5T48rRAht5WdW0X2GlA=",
|
||||
"recordedFileInputs": {},
|
||||
"recordedDirentsInputs": {},
|
||||
"envVariables": {},
|
||||
"generatedRepoSpecs": {
|
||||
"host_platform": {
|
||||
"bzlFile": "@@platforms//host:extension.bzl",
|
||||
"ruleClassName": "host_platform_repo",
|
||||
"attributes": {}
|
||||
}
|
||||
},
|
||||
"recordedRepoMappingEntries": []
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
65
README.md
65
README.md
@@ -1,37 +1,68 @@
|
||||
# Prysm: An Ethereum Consensus Implementation Written in Go
|
||||
<h1 align="left">Prysm: An Ethereum Consensus Implementation Written in Go</h1>
|
||||
|
||||
<div align="left">
|
||||
|
||||
[](https://buildkite.com/prysmatic-labs/prysm)
|
||||
[](https://goreportcard.com/report/github.com/prysmaticlabs/prysm)
|
||||
[](https://github.com/ethereum/consensus-specs/tree/v1.3.0)
|
||||
[](https://github.com/ethereum/consensus-specs/tree/v1.4.0)
|
||||
[](https://github.com/ethereum/execution-apis/tree/v1.0.0-beta.2/src/engine)
|
||||
[](https://discord.gg/prysmaticlabs)
|
||||
[](https://www.gitpoap.io/gh/prysmaticlabs/prysm)
|
||||
|
||||
This is the core repository for Prysm, a [Golang](https://golang.org/) implementation of the [Ethereum Consensus](https://ethereum.org/en/developers/docs/consensus-mechanisms/#proof-of-stake) [specification](https://github.com/ethereum/consensus-specs), developed by [Offchain Labs](https://www.offchainlabs.com). See the [Changelog](https://github.com/prysmaticlabs/prysm/releases) for details of the latest releases and upcoming breaking changes.
|
||||
</div>
|
||||
|
||||
### Getting Started
|
||||
---
|
||||
|
||||
A detailed set of installation and usage instructions as well as breakdowns of each individual component are available in the [official documentation portal](https://docs.prylabs.network). If you still have questions, feel free to stop by our [Discord](https://discord.gg/prysmaticlabs).
|
||||
## 📖 Overview
|
||||
|
||||
### Staking on Mainnet
|
||||
This is the core repository for Prysm, a [Golang](https://golang.org/) implementation of the [Ethereum Consensus](https://ethereum.org/en/developers/docs/consensus-mechanisms/#proof-of-stake) [specification](https://github.com/ethereum/consensus-specs), developed by [Offchain Labs](https://www.offchainlabs.com).
|
||||
|
||||
To participate in staking, you can join the [official eth2 launchpad](https://launchpad.ethereum.org). The launchpad is the only recommended way to become a validator on mainnet. You can explore validator rewards/penalties via Bitfly's block explorer: [beaconcha.in](https://beaconcha.in), and follow the latest blocks added to the chain on [beaconscan](https://beaconscan.com).
|
||||
See the [Changelog](https://github.com/prysmaticlabs/prysm/releases) for details of the latest releases and upcoming breaking changes.
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Getting Started
|
||||
|
||||
A detailed set of installation and usage instructions as well as breakdowns of each individual component are available in the **[official documentation portal](https://docs.prylabs.network)**.
|
||||
|
||||
💬 **Need help?** Join our **[Discord Community](https://discord.gg/prysmaticlabs)** for support.
|
||||
|
||||
---
|
||||
|
||||
## 🏆 Staking on Mainnet
|
||||
|
||||
To participate in staking, you can join the **[official Ethereum launchpad](https://launchpad.ethereum.org)**. The launchpad is the **only recommended** way to become a validator on mainnet.
|
||||
|
||||
🔍 Explore validator rewards/penalties:
|
||||
|
||||
- **[beaconcha.in](https://beaconcha.in)**
|
||||
- **[beaconscan](https://beaconscan.com)**
|
||||
|
||||
---
|
||||
|
||||
## 🤝 Contributing
|
||||
|
||||
### 🔥 Branches
|
||||
|
||||
## Contributing
|
||||
### Branches
|
||||
Prysm maintains two permanent branches:
|
||||
|
||||
* [master](https://github.com/prysmaticlabs/prysm/tree/master): This points to the latest stable release. It is ideal for most users.
|
||||
* [develop](https://github.com/prysmaticlabs/prysm/tree/develop): This is used for development, it contains the latest PRs. Developers should base their PRs on this branch.
|
||||
- **[`master`](https://github.com/prysmaticlabs/prysm/tree/master)** - This points to the latest stable release. It is ideal for most users.
|
||||
- **[`develop`](https://github.com/prysmaticlabs/prysm/tree/develop)** - This is used for development and contains the latest PRs. Developers should base their PRs on this branch.
|
||||
|
||||
### Guide
|
||||
Want to get involved? Check out our [Contribution Guide](https://docs.prylabs.network/docs/contribute/contribution-guidelines/) to learn more!
|
||||
### 🛠 Contribution Guide
|
||||
|
||||
## License
|
||||
Want to get involved? Check out our **[Contribution Guide](https://docs.prylabs.network/docs/contribute/contribution-guidelines/)** to learn more!
|
||||
|
||||
[GNU General Public License v3.0](https://www.gnu.org/licenses/gpl-3.0.en.html)
|
||||
---
|
||||
|
||||
## Legal Disclaimer
|
||||
## 📜 License
|
||||
|
||||
[Terms of Use](/TERMS_OF_SERVICE.md)
|
||||
[](https://www.gnu.org/licenses/gpl-3.0.en.html)
|
||||
|
||||
This project is licensed under the **GNU General Public License v3.0**.
|
||||
|
||||
---
|
||||
|
||||
## ⚖️ Legal Disclaimer
|
||||
|
||||
📜 [Terms of Use](/TERMS_OF_SERVICE.md)
|
||||
|
||||
248
WORKSPACE
248
WORKSPACE
@@ -16,34 +16,48 @@ load("@rules_pkg//:deps.bzl", "rules_pkg_dependencies")
|
||||
|
||||
rules_pkg_dependencies()
|
||||
|
||||
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
|
||||
|
||||
http_archive(
|
||||
name = "toolchains_protoc",
|
||||
sha256 = "abb1540f8a9e045422730670ebb2f25b41fa56ca5a7cf795175a110a0a68f4ad",
|
||||
strip_prefix = "toolchains_protoc-0.3.6",
|
||||
url = "https://github.com/aspect-build/toolchains_protoc/releases/download/v0.3.6/toolchains_protoc-v0.3.6.tar.gz",
|
||||
)
|
||||
|
||||
load("@toolchains_protoc//protoc:repositories.bzl", "rules_protoc_dependencies")
|
||||
|
||||
rules_protoc_dependencies()
|
||||
|
||||
load("@rules_proto//proto:repositories.bzl", "rules_proto_dependencies")
|
||||
|
||||
rules_proto_dependencies()
|
||||
|
||||
load("@bazel_features//:deps.bzl", "bazel_features_deps")
|
||||
|
||||
bazel_features_deps()
|
||||
|
||||
load("@toolchains_protoc//protoc:toolchain.bzl", "protoc_toolchains")
|
||||
|
||||
protoc_toolchains(
|
||||
name = "protoc_toolchains",
|
||||
version = "v25.3",
|
||||
)
|
||||
|
||||
HERMETIC_CC_TOOLCHAIN_VERSION = "v3.0.1"
|
||||
|
||||
http_archive(
|
||||
name = "hermetic_cc_toolchain",
|
||||
sha256 = "973ab22945b921ef45b8e1d6ce01ca7ce1b8a462167449a36e297438c4ec2755",
|
||||
strip_prefix = "hermetic_cc_toolchain-5098046bccc15d2962f3cc8e7e53d6a2a26072dc",
|
||||
sha256 = "3bc6ec127622fdceb4129cb06b6f7ab098c4d539124dde96a6318e7c32a53f7a",
|
||||
urls = [
|
||||
"https://github.com/uber/hermetic_cc_toolchain/archive/5098046bccc15d2962f3cc8e7e53d6a2a26072dc.tar.gz", # 2023-06-28
|
||||
"https://mirror.bazel.build/github.com/uber/hermetic_cc_toolchain/releases/download/{0}/hermetic_cc_toolchain-{0}.tar.gz".format(HERMETIC_CC_TOOLCHAIN_VERSION),
|
||||
"https://github.com/uber/hermetic_cc_toolchain/releases/download/{0}/hermetic_cc_toolchain-{0}.tar.gz".format(HERMETIC_CC_TOOLCHAIN_VERSION),
|
||||
],
|
||||
)
|
||||
|
||||
load("@hermetic_cc_toolchain//toolchain:defs.bzl", zig_toolchains = "toolchains")
|
||||
|
||||
# Temporarily use a nightly build until 0.12.0 is released.
|
||||
# See: https://github.com/prysmaticlabs/prysm/issues/13130
|
||||
zig_toolchains(
|
||||
host_platform_sha256 = {
|
||||
"linux-aarch64": "45afb8e32adde825165f4f293fcea9ecea503f7f9ec0e9bf4435afe70e67fb70",
|
||||
"linux-x86_64": "f136c6a8a0f6adcb057d73615fbcd6f88281b3593f7008d5f7ed514ff925c02e",
|
||||
"macos-aarch64": "05d995853c05243151deff47b60bdc2674f1e794a939eaeca0f42312da031cee",
|
||||
"macos-x86_64": "721754ba5a50f31e8a1f0e1a74cace26f8246576878ac4a8591b0ee7b6db1fc1",
|
||||
"windows-x86_64": "93f5248b2ea8c5ee8175e15b1384e133edc1cd49870b3ea259062a2e04164343",
|
||||
},
|
||||
url_formats = [
|
||||
"https://ziglang.org/builds/zig-{host_platform}-{version}.{_ext}",
|
||||
"https://mirror.bazel.build/ziglang.org/builds/zig-{host_platform}-{version}.{_ext}",
|
||||
"https://prysmaticlabs.com/mirror/ziglang.org/builds/zig-{host_platform}-{version}.{_ext}",
|
||||
],
|
||||
version = "0.12.0-dev.1349+fa022d1ec",
|
||||
)
|
||||
zig_toolchains()
|
||||
|
||||
# Register zig sdk toolchains with support for Ubuntu 20.04 (Focal Fossa) which has an EOL date of April, 2025.
|
||||
# For ubuntu glibc support, see https://launchpad.net/ubuntu/+source/glibc
|
||||
@@ -81,10 +95,10 @@ bazel_skylib_workspace()
|
||||
|
||||
http_archive(
|
||||
name = "bazel_gazelle",
|
||||
sha256 = "d3fa66a39028e97d76f9e2db8f1b0c11c099e8e01bf363a923074784e451f809",
|
||||
integrity = "sha256-MpOL2hbmcABjA1R5Bj2dJMYO2o15/Uc5Vj9Q0zHLMgk=",
|
||||
urls = [
|
||||
"https://mirror.bazel.build/github.com/bazelbuild/bazel-gazelle/releases/download/v0.33.0/bazel-gazelle-v0.33.0.tar.gz",
|
||||
"https://github.com/bazelbuild/bazel-gazelle/releases/download/v0.33.0/bazel-gazelle-v0.33.0.tar.gz",
|
||||
"https://mirror.bazel.build/github.com/bazelbuild/bazel-gazelle/releases/download/v0.35.0/bazel-gazelle-v0.35.0.tar.gz",
|
||||
"https://github.com/bazelbuild/bazel-gazelle/releases/download/v0.35.0/bazel-gazelle-v0.35.0.tar.gz",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -96,16 +110,41 @@ http_archive(
|
||||
)
|
||||
|
||||
http_archive(
|
||||
name = "io_bazel_rules_docker",
|
||||
sha256 = "b1e80761a8a8243d03ebca8845e9cc1ba6c82ce7c5179ce2b295cd36f7e394bf",
|
||||
urls = ["https://github.com/bazelbuild/rules_docker/releases/download/v0.25.0/rules_docker-v0.25.0.tar.gz"],
|
||||
name = "rules_distroless",
|
||||
sha256 = "e64f06e452cd153aeab81f752ccf4642955b3af319e64f7bc7a7c9252f76b10e",
|
||||
strip_prefix = "rules_distroless-f5e678217b57ce3ad2f1c0204bd4e9d416255773",
|
||||
url = "https://github.com/GoogleContainerTools/rules_distroless/archive/f5e678217b57ce3ad2f1c0204bd4e9d416255773.tar.gz",
|
||||
)
|
||||
|
||||
load("@rules_distroless//distroless:dependencies.bzl", "rules_distroless_dependencies")
|
||||
|
||||
rules_distroless_dependencies()
|
||||
|
||||
http_archive(
|
||||
name = "distroless",
|
||||
integrity = "sha256-Cf00kUp1NyXA3LzbdyYy4Kda27wbkB8+A9MliTxq4jE=",
|
||||
strip_prefix = "distroless-9dc924b9fe812eec2fa0061824dcad39eb09d0d6",
|
||||
url = "https://github.com/GoogleContainerTools/distroless/archive/9dc924b9fe812eec2fa0061824dcad39eb09d0d6.tar.gz", # 2024-01-24
|
||||
)
|
||||
|
||||
http_archive(
|
||||
name = "aspect_bazel_lib",
|
||||
sha256 = "a272d79bb0ac6b6965aa199b1f84333413452e87f043b53eca7f347a23a478e8",
|
||||
strip_prefix = "bazel-lib-2.9.3",
|
||||
url = "https://github.com/bazel-contrib/bazel-lib/releases/download/v2.9.3/bazel-lib-v2.9.3.tar.gz",
|
||||
)
|
||||
|
||||
load("@aspect_bazel_lib//lib:repositories.bzl", "aspect_bazel_lib_dependencies", "aspect_bazel_lib_register_toolchains")
|
||||
|
||||
aspect_bazel_lib_dependencies()
|
||||
|
||||
aspect_bazel_lib_register_toolchains()
|
||||
|
||||
http_archive(
|
||||
name = "rules_oci",
|
||||
sha256 = "c71c25ed333a4909d2dd77e0b16c39e9912525a98c7fa85144282be8d04ef54c",
|
||||
strip_prefix = "rules_oci-1.3.4",
|
||||
url = "https://github.com/bazel-contrib/rules_oci/releases/download/v1.3.4/rules_oci-v1.3.4.tar.gz",
|
||||
sha256 = "4a276e9566c03491649eef63f27c2816cc222f41ccdebd97d2c5159e84917c3b",
|
||||
strip_prefix = "rules_oci-1.7.4",
|
||||
url = "https://github.com/bazel-contrib/rules_oci/releases/download/v1.7.4/rules_oci-v1.7.4.tar.gz",
|
||||
)
|
||||
|
||||
load("@rules_oci//oci:dependencies.bzl", "rules_oci_dependencies")
|
||||
@@ -121,15 +160,15 @@ oci_register_toolchains(
|
||||
|
||||
http_archive(
|
||||
name = "io_bazel_rules_go",
|
||||
integrity = "sha256-JD8o94crTb2DFiJJR8nMAGdBAW95zIENB4cbI+JnrI4=",
|
||||
patch_args = ["-p1"],
|
||||
patches = [
|
||||
# Expose internals of go_test for custom build transitions.
|
||||
"//third_party:io_bazel_rules_go_test.patch",
|
||||
],
|
||||
sha256 = "d6ab6b57e48c09523e93050f13698f708428cfd5e619252e369d377af6597707",
|
||||
strip_prefix = "rules_go-cf3c3af34bd869b864f5f2b98e2f41c2b220d6c9",
|
||||
urls = [
|
||||
"https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.43.0/rules_go-v0.43.0.zip",
|
||||
"https://github.com/bazelbuild/rules_go/releases/download/v0.43.0/rules_go-v0.43.0.zip",
|
||||
"https://github.com/bazel-contrib/rules_go/archive/cf3c3af34bd869b864f5f2b98e2f41c2b220d6c9.tar.gz",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -148,67 +187,16 @@ git_repository(
|
||||
# gazelle args: -go_prefix github.com/gogo/protobuf -proto legacy
|
||||
)
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_docker//repositories:repositories.bzl",
|
||||
container_repositories = "repositories",
|
||||
)
|
||||
|
||||
container_repositories()
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_docker//container:container.bzl",
|
||||
"container_pull",
|
||||
)
|
||||
|
||||
# Pulled gcr.io/distroless/cc-debian11:latest on 2022-02-23
|
||||
container_pull(
|
||||
name = "cc_image_base_amd64",
|
||||
digest = "sha256:2a0daf90a7deb78465bfca3ef2eee6e91ce0a5706059f05d79d799a51d339523",
|
||||
registry = "gcr.io",
|
||||
repository = "distroless/cc-debian11",
|
||||
)
|
||||
|
||||
# Pulled gcr.io/distroless/cc-debian11:debug on 2022-02-23
|
||||
container_pull(
|
||||
name = "cc_debug_image_base_amd64",
|
||||
digest = "sha256:7bd596f5f200588f13a69c268eea6ce428b222b67cd7428d6a7fef95e75c052a",
|
||||
registry = "gcr.io",
|
||||
repository = "distroless/cc-debian11",
|
||||
)
|
||||
|
||||
# Pulled from gcr.io/distroless/base-debian11:latest on 2022-02-23
|
||||
container_pull(
|
||||
name = "go_image_base_amd64",
|
||||
digest = "sha256:34e682800774ecbd0954b1663d90238505f1ba5543692dbc75feef7dd4839e90",
|
||||
registry = "gcr.io",
|
||||
repository = "distroless/base-debian11",
|
||||
)
|
||||
|
||||
# Pulled from gcr.io/distroless/base-debian11:debug on 2022-02-23
|
||||
container_pull(
|
||||
name = "go_debug_image_base_amd64",
|
||||
digest = "sha256:0f503c6bfd207793bc416f20a35bf6b75d769a903c48f180ad73f60f7b60d7bd",
|
||||
registry = "gcr.io",
|
||||
repository = "distroless/base-debian11",
|
||||
)
|
||||
|
||||
container_pull(
|
||||
name = "alpine_cc_linux_amd64",
|
||||
digest = "sha256:752aa0c9a88461ffc50c5267bb7497ef03a303e38b2c8f7f2ded9bebe5f1f00e",
|
||||
registry = "index.docker.io",
|
||||
repository = "pinglamb/alpine-glibc",
|
||||
)
|
||||
|
||||
load("@rules_oci//oci:pull.bzl", "oci_pull")
|
||||
|
||||
# A multi-arch base image
|
||||
oci_pull(
|
||||
name = "linux_debian11_multiarch_base", # Debian bullseye
|
||||
digest = "sha256:9b8e0854865dcaf49470b4ec305df45957020fbcf17b71eeb50ffd3bc5bf885d", # 2023-05-17
|
||||
image = "gcr.io/distroless/cc-debian11",
|
||||
digest = "sha256:b82f113425c5b5c714151aaacd8039bc141821cdcd3c65202d42bdf9c43ae60b", # 2023-12-12
|
||||
image = "gcr.io/prysmaticlabs/distroless/cc-debian11",
|
||||
platforms = [
|
||||
"linux/amd64",
|
||||
"linux/arm64",
|
||||
"linux/arm64/v8",
|
||||
],
|
||||
reproducible = True,
|
||||
)
|
||||
@@ -222,10 +210,14 @@ load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_depe
|
||||
go_rules_dependencies()
|
||||
|
||||
go_register_toolchains(
|
||||
go_version = "1.20.10",
|
||||
go_version = "1.24.0",
|
||||
nogo = "@//:nogo",
|
||||
)
|
||||
|
||||
load("//:distroless_deps.bzl", "distroless_deps")
|
||||
|
||||
distroless_deps()
|
||||
|
||||
http_archive(
|
||||
name = "io_kubernetes_build",
|
||||
sha256 = "b84fbd1173acee9d02a7d3698ad269fdf4f7aa081e9cecd40e012ad0ad8cfa2a",
|
||||
@@ -263,7 +255,7 @@ filegroup(
|
||||
url = "https://github.com/ethereum/EIPs/archive/5480440fe51742ed23342b68cf106cefd427e39d.tar.gz",
|
||||
)
|
||||
|
||||
consensus_spec_version = "v1.4.0-beta.3"
|
||||
consensus_spec_version = "v1.5.0-beta.4"
|
||||
|
||||
bls_test_version = "v0.1.1"
|
||||
|
||||
@@ -279,7 +271,7 @@ filegroup(
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
""",
|
||||
sha256 = "67ae5b8fc368853da23d4297e480a4b7f4722fb970d1c7e2b6a5b7faef9cb907",
|
||||
integrity = "sha256-QG0NUqaCvP5lKaKKwF/fmeICZVjONMlb7EE+MtYl0C0=",
|
||||
url = "https://github.com/ethereum/consensus-spec-tests/releases/download/%s/general.tar.gz" % consensus_spec_version,
|
||||
)
|
||||
|
||||
@@ -295,7 +287,7 @@ filegroup(
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
""",
|
||||
sha256 = "82474f29fff4abd09fb1e71bafa98827e2573cf0ad02cf119610961831dc3bb5",
|
||||
integrity = "sha256-8NQngTSSqzW/j3tOUi3r5h+94ChRbLNWTt7BOGqr4+E=",
|
||||
url = "https://github.com/ethereum/consensus-spec-tests/releases/download/%s/minimal.tar.gz" % consensus_spec_version,
|
||||
)
|
||||
|
||||
@@ -311,7 +303,7 @@ filegroup(
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
""",
|
||||
sha256 = "60e4b6eb6c341daab7ee5614a8e3f28567247c504c593b951bfe919622c8ef8f",
|
||||
integrity = "sha256-gFqxbaBnJ7dtdoj0zFbVrtlHv/bLNuWjrTHkyCAjFjI=",
|
||||
url = "https://github.com/ethereum/consensus-spec-tests/releases/download/%s/mainnet.tar.gz" % consensus_spec_version,
|
||||
)
|
||||
|
||||
@@ -326,7 +318,7 @@ filegroup(
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
""",
|
||||
sha256 = "fdab9756c93a250219ff6a10d5a9faee1e2e6878a14508410409e307362c6991",
|
||||
integrity = "sha256-9paalF0POULpP2ga+4ouHSETKYrWNCUCZoJHPuFw06E=",
|
||||
strip_prefix = "consensus-specs-" + consensus_spec_version[1:],
|
||||
url = "https://github.com/ethereum/consensus-specs/archive/refs/tags/%s.tar.gz" % consensus_spec_version,
|
||||
)
|
||||
@@ -357,9 +349,9 @@ filegroup(
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
""",
|
||||
sha256 = "2701e1e1a3ec10c673fe7dbdbbe6f02c8ae8c922aebbf6e720d8c72d5458aafe",
|
||||
strip_prefix = "eth2-networks-7b4897888cebef23801540236f73123e21774954",
|
||||
url = "https://github.com/eth-clients/eth2-networks/archive/7b4897888cebef23801540236f73123e21774954.tar.gz",
|
||||
sha256 = "77e7e3ed65e33b7bb19d30131f4c2bb39e4dfeb188ab9ae84651c3cc7600131d",
|
||||
strip_prefix = "eth2-networks-934c948e69205dcf2deb87e4ae6cc140c335f94d",
|
||||
url = "https://github.com/eth-clients/eth2-networks/archive/934c948e69205dcf2deb87e4ae6cc140c335f94d.tar.gz",
|
||||
)
|
||||
|
||||
http_archive(
|
||||
@@ -368,22 +360,54 @@ http_archive(
|
||||
filegroup(
|
||||
name = "configs",
|
||||
srcs = [
|
||||
"custom_config_data/config.yaml",
|
||||
"metadata/config.yaml",
|
||||
],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
""",
|
||||
sha256 = "9f66d8d5644982d3d0d2e3d2b9ebe77a5f96638a5d7fcd715599c32818195cb3",
|
||||
strip_prefix = "holesky-ea39b9006210848e13f28d92e12a30548cecd41d",
|
||||
url = "https://github.com/eth-clients/holesky/archive/ea39b9006210848e13f28d92e12a30548cecd41d.tar.gz", # 2023-09-21
|
||||
integrity = "sha256-YVFFrCmjoGZ3fXMWpsCpSsYbANy1grnqYwOLKIg2SsA=",
|
||||
strip_prefix = "holesky-32a72e21c6e53c262f27d50dd540cb654517d03a",
|
||||
url = "https://github.com/eth-clients/holesky/archive/32a72e21c6e53c262f27d50dd540cb654517d03a.tar.gz", # 2025-03-17
|
||||
)
|
||||
|
||||
http_archive(
|
||||
name = "sepolia_testnet",
|
||||
build_file_content = """
|
||||
filegroup(
|
||||
name = "configs",
|
||||
srcs = [
|
||||
"metadata/config.yaml",
|
||||
],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
""",
|
||||
integrity = "sha256-b5F7Wg9LLMqGRIpP2uqb/YsSFVn2ynzlV7g/Nb1EFLk=",
|
||||
strip_prefix = "sepolia-562d9938f08675e9ba490a1dfba21fb05843f39f",
|
||||
url = "https://github.com/eth-clients/sepolia/archive/562d9938f08675e9ba490a1dfba21fb05843f39f.tar.gz", # 2025-03-17
|
||||
)
|
||||
|
||||
http_archive(
|
||||
name = "hoodi_testnet",
|
||||
build_file_content = """
|
||||
filegroup(
|
||||
name = "configs",
|
||||
srcs = [
|
||||
"metadata/config.yaml",
|
||||
],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
""",
|
||||
integrity = "sha256-dPiEWUd8QvbYGwGtIm0QtCekitVLOLsW5rpQIGzz8PU=",
|
||||
strip_prefix = "hoodi-828c2c940e1141092bd4bb979cef547ea926d272",
|
||||
url = "https://github.com/eth-clients/hoodi/archive/828c2c940e1141092bd4bb979cef547ea926d272.tar.gz",
|
||||
)
|
||||
|
||||
http_archive(
|
||||
name = "com_google_protobuf",
|
||||
sha256 = "4e176116949be52b0408dfd24f8925d1eb674a781ae242a75296b17a1c721395",
|
||||
strip_prefix = "protobuf-23.3",
|
||||
sha256 = "9bd87b8280ef720d3240514f884e56a712f2218f0d693b48050c836028940a42",
|
||||
strip_prefix = "protobuf-25.1",
|
||||
urls = [
|
||||
"https://github.com/protocolbuffers/protobuf/archive/v23.3.tar.gz",
|
||||
"https://github.com/protocolbuffers/protobuf/archive/v25.1.tar.gz",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -417,31 +441,13 @@ load("@prysm//testing/endtoend:deps.bzl", "e2e_deps")
|
||||
|
||||
e2e_deps()
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_docker//go:image.bzl",
|
||||
_go_image_repos = "repositories",
|
||||
)
|
||||
|
||||
# Golang images
|
||||
# This is using gcr.io/distroless/base
|
||||
_go_image_repos()
|
||||
|
||||
# CC images
|
||||
# This is using gcr.io/distroless/base
|
||||
load(
|
||||
"@io_bazel_rules_docker//cc:image.bzl",
|
||||
_cc_image_repos = "repositories",
|
||||
)
|
||||
|
||||
_cc_image_repos()
|
||||
|
||||
load("@com_github_atlassian_bazel_tools//gometalinter:deps.bzl", "gometalinter_dependencies")
|
||||
|
||||
gometalinter_dependencies()
|
||||
|
||||
load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies")
|
||||
|
||||
gazelle_dependencies()
|
||||
gazelle_dependencies(go_sdk = "go_sdk")
|
||||
|
||||
load("@com_google_protobuf//:protobuf_deps.bzl", "protobuf_deps")
|
||||
|
||||
|
||||
@@ -1,11 +1,24 @@
|
||||
load("@prysm//tools/go:def.bzl", "go_library")
|
||||
load("@prysm//tools/go:def.bzl", "go_library", "go_test")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"constants.go",
|
||||
"headers.go",
|
||||
"jwt.go",
|
||||
],
|
||||
importpath = "github.com/prysmaticlabs/prysm/v4/api",
|
||||
importpath = "github.com/prysmaticlabs/prysm/v5/api",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//crypto/rand:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//common/hexutil:go_default_library",
|
||||
"@com_github_pkg_errors//:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["jwt_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
deps = ["//testing/require:go_default_library"],
|
||||
)
|
||||
|
||||
9
api/apiutil/BUILD.bazel
Normal file
9
api/apiutil/BUILD.bazel
Normal file
@@ -0,0 +1,9 @@
|
||||
load("@prysm//tools/go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["common.go"],
|
||||
importpath = "github.com/prysmaticlabs/prysm/v5/api/client/apiutil",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = ["//consensus-types/primitives:go_default_library"],
|
||||
)
|
||||
30
api/apiutil/common.go
Normal file
30
api/apiutil/common.go
Normal file
@@ -0,0 +1,30 @@
|
||||
package apiutil
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
neturl "net/url"
|
||||
"regexp"
|
||||
"strconv"
|
||||
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
)
|
||||
|
||||
func ValidRoot(root string) bool {
|
||||
matchesRegex, err := regexp.MatchString("^0x[a-fA-F0-9]{64}$", root)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return matchesRegex
|
||||
}
|
||||
|
||||
func Uint64ToString[T uint64 | primitives.Slot | primitives.ValidatorIndex | primitives.CommitteeIndex | primitives.Epoch](val T) string {
|
||||
return strconv.FormatUint(uint64(val), 10)
|
||||
}
|
||||
|
||||
func BuildURL(path string, queryParams ...neturl.Values) string {
|
||||
if len(queryParams) == 0 {
|
||||
return path
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%s?%s", path, queryParams[0].Encode())
|
||||
}
|
||||
@@ -5,16 +5,31 @@ go_library(
|
||||
srcs = [
|
||||
"client.go",
|
||||
"errors.go",
|
||||
"json_rest_handler.go",
|
||||
"options.go",
|
||||
],
|
||||
importpath = "github.com/prysmaticlabs/prysm/v4/api/client",
|
||||
importpath = "github.com/prysmaticlabs/prysm/v5/api/client",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = ["@com_github_pkg_errors//:go_default_library"],
|
||||
deps = [
|
||||
"//api:go_default_library",
|
||||
"//network/httputil:go_default_library",
|
||||
"@com_github_pkg_errors//:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["client_test.go"],
|
||||
srcs = [
|
||||
"client_test.go",
|
||||
"json_rest_handler_test.go",
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
deps = ["//testing/require:go_default_library"],
|
||||
deps = [
|
||||
"//api:go_default_library",
|
||||
"//api/server/structs:go_default_library",
|
||||
"//network/httputil:go_default_library",
|
||||
"//testing/assert:go_default_library",
|
||||
"//testing/require:go_default_library",
|
||||
"@com_github_pkg_errors//:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -3,58 +3,34 @@ load("@prysm//tools/go:def.bzl", "go_library", "go_test")
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"checkpoint.go",
|
||||
"client.go",
|
||||
"doc.go",
|
||||
"log.go",
|
||||
"structs.go",
|
||||
"template.go",
|
||||
],
|
||||
importpath = "github.com/prysmaticlabs/prysm/v4/api/client/beacon",
|
||||
importpath = "github.com/prysmaticlabs/prysm/v5/api/client/beacon",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//api/client:go_default_library",
|
||||
"//api/server:go_default_library",
|
||||
"//beacon-chain/core/helpers:go_default_library",
|
||||
"//beacon-chain/rpc/eth/beacon:go_default_library",
|
||||
"//beacon-chain/rpc/eth/config:go_default_library",
|
||||
"//beacon-chain/rpc/eth/shared:go_default_library",
|
||||
"//beacon-chain/rpc/prysm/beacon:go_default_library",
|
||||
"//beacon-chain/state:go_default_library",
|
||||
"//consensus-types/interfaces:go_default_library",
|
||||
"//api/server/structs:go_default_library",
|
||||
"//consensus-types/primitives:go_default_library",
|
||||
"//encoding/bytesutil:go_default_library",
|
||||
"//encoding/ssz/detect:go_default_library",
|
||||
"//io/file:go_default_library",
|
||||
"//network/forks:go_default_library",
|
||||
"//proto/prysm/v1alpha1:go_default_library",
|
||||
"//runtime/version:go_default_library",
|
||||
"//time/slots:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//common/hexutil:go_default_library",
|
||||
"@com_github_pkg_errors//:go_default_library",
|
||||
"@com_github_sirupsen_logrus//:go_default_library",
|
||||
"@org_golang_x_mod//semver:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = [
|
||||
"checkpoint_test.go",
|
||||
"client_test.go",
|
||||
],
|
||||
srcs = ["client_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//api/client:go_default_library",
|
||||
"//beacon-chain/state:go_default_library",
|
||||
"//config/params:go_default_library",
|
||||
"//consensus-types/blocks:go_default_library",
|
||||
"//consensus-types/blocks/testing:go_default_library",
|
||||
"//consensus-types/primitives:go_default_library",
|
||||
"//encoding/ssz/detect:go_default_library",
|
||||
"//network/forks:go_default_library",
|
||||
"//proto/prysm/v1alpha1:go_default_library",
|
||||
"//runtime/version:go_default_library",
|
||||
"//testing/require:go_default_library",
|
||||
"//testing/util:go_default_library",
|
||||
"//time/slots:go_default_library",
|
||||
"@com_github_pkg_errors//:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
45
api/client/beacon/chain/BUILD.bazel
Normal file
45
api/client/beacon/chain/BUILD.bazel
Normal file
@@ -0,0 +1,45 @@
|
||||
load("@prysm//tools/go:def.bzl", "go_library", "go_test")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"client.go",
|
||||
"grpc_client.go",
|
||||
"interfaces.go",
|
||||
"rest_client.go",
|
||||
],
|
||||
importpath = "github.com/prysmaticlabs/prysm/v5/api/client/beacon/chain",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//api/client:go_default_library",
|
||||
"//api/client/beacon/shared_providers:go_default_library",
|
||||
"//api/server/structs:go_default_library",
|
||||
"//config/features:go_default_library",
|
||||
"//consensus-types/primitives:go_default_library",
|
||||
"//proto/prysm/v1alpha1:go_default_library",
|
||||
"//time/slots:go_default_library",
|
||||
"//validator/helpers:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//common/hexutil:go_default_library",
|
||||
"@com_github_golang_protobuf//ptypes/empty",
|
||||
"@com_github_pkg_errors//:go_default_library",
|
||||
"@org_golang_google_grpc//:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["rest_client_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//api/client/beacon/mock:go_default_library",
|
||||
"//api/server/structs:go_default_library",
|
||||
"//consensus-types/primitives:go_default_library",
|
||||
"//proto/prysm/v1alpha1:go_default_library",
|
||||
"//testing/assert:go_default_library",
|
||||
"//testing/require:go_default_library",
|
||||
"//time/slots:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//common/hexutil:go_default_library",
|
||||
"@org_golang_google_protobuf//types/known/emptypb:go_default_library",
|
||||
"@org_uber_go_mock//gomock:go_default_library",
|
||||
],
|
||||
)
|
||||
31
api/client/beacon/chain/client.go
Normal file
31
api/client/beacon/chain/client.go
Normal file
@@ -0,0 +1,31 @@
|
||||
package chain
|
||||
|
||||
import (
|
||||
"github.com/prysmaticlabs/prysm/v5/api/client"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/client/beacon/shared_providers"
|
||||
"github.com/prysmaticlabs/prysm/v5/config/features"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
validatorHelpers "github.com/prysmaticlabs/prysm/v5/validator/helpers"
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
func NewClient(validatorConn validatorHelpers.NodeConnection, jsonRestHandler client.JsonRestHandler) Client {
|
||||
grpcClient := NewGrpcChainClient(validatorConn.GetGrpcClientConn())
|
||||
if features.Get().EnableBeaconRESTApi {
|
||||
return NewBeaconApiChainClientWithFallback(jsonRestHandler, grpcClient)
|
||||
} else {
|
||||
return grpcClient
|
||||
}
|
||||
}
|
||||
|
||||
func NewGrpcChainClient(cc grpc.ClientConnInterface) Client {
|
||||
return &grpcChainClient{ethpb.NewBeaconChainClient(cc)}
|
||||
}
|
||||
|
||||
func NewBeaconApiChainClientWithFallback(jsonRestHandler client.JsonRestHandler, fallbackClient Client) Client {
|
||||
return &beaconApiChainClient{
|
||||
jsonRestHandler: jsonRestHandler,
|
||||
fallbackClient: fallbackClient,
|
||||
stateValidatorsProvider: shared_providers.NewStateValidators(jsonRestHandler),
|
||||
}
|
||||
}
|
||||
36
api/client/beacon/chain/grpc_client.go
Normal file
36
api/client/beacon/chain/grpc_client.go
Normal file
@@ -0,0 +1,36 @@
|
||||
package chain
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/golang/protobuf/ptypes/empty"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
)
|
||||
|
||||
type grpcChainClient struct {
|
||||
beaconChainClient ethpb.BeaconChainClient
|
||||
}
|
||||
|
||||
func (c *grpcChainClient) ChainHead(ctx context.Context, in *empty.Empty) (*ethpb.ChainHead, error) {
|
||||
return c.beaconChainClient.GetChainHead(ctx, in)
|
||||
}
|
||||
|
||||
func (c *grpcChainClient) ValidatorBalances(ctx context.Context, in *ethpb.ListValidatorBalancesRequest) (*ethpb.ValidatorBalances, error) {
|
||||
return c.beaconChainClient.ListValidatorBalances(ctx, in)
|
||||
}
|
||||
|
||||
func (c *grpcChainClient) Validators(ctx context.Context, in *ethpb.ListValidatorsRequest) (*ethpb.Validators, error) {
|
||||
return c.beaconChainClient.ListValidators(ctx, in)
|
||||
}
|
||||
|
||||
func (c *grpcChainClient) ValidatorQueue(ctx context.Context, in *empty.Empty) (*ethpb.ValidatorQueue, error) {
|
||||
return c.beaconChainClient.GetValidatorQueue(ctx, in)
|
||||
}
|
||||
|
||||
func (c *grpcChainClient) ValidatorPerformance(ctx context.Context, in *ethpb.ValidatorPerformanceRequest) (*ethpb.ValidatorPerformanceResponse, error) {
|
||||
return c.beaconChainClient.GetValidatorPerformance(ctx, in)
|
||||
}
|
||||
|
||||
func (c *grpcChainClient) ValidatorParticipation(ctx context.Context, in *ethpb.GetValidatorParticipationRequest) (*ethpb.ValidatorParticipationResponse, error) {
|
||||
return c.beaconChainClient.GetValidatorParticipation(ctx, in)
|
||||
}
|
||||
17
api/client/beacon/chain/interfaces.go
Normal file
17
api/client/beacon/chain/interfaces.go
Normal file
@@ -0,0 +1,17 @@
|
||||
package chain
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/golang/protobuf/ptypes/empty"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
)
|
||||
|
||||
type Client interface {
|
||||
ChainHead(ctx context.Context, in *empty.Empty) (*ethpb.ChainHead, error)
|
||||
ValidatorBalances(ctx context.Context, in *ethpb.ListValidatorBalancesRequest) (*ethpb.ValidatorBalances, error)
|
||||
Validators(ctx context.Context, in *ethpb.ListValidatorsRequest) (*ethpb.Validators, error)
|
||||
ValidatorQueue(ctx context.Context, in *empty.Empty) (*ethpb.ValidatorQueue, error)
|
||||
ValidatorParticipation(ctx context.Context, in *ethpb.GetValidatorParticipationRequest) (*ethpb.ValidatorParticipationResponse, error)
|
||||
ValidatorPerformance(context.Context, *ethpb.ValidatorPerformanceRequest) (*ethpb.ValidatorPerformanceResponse, error)
|
||||
}
|
||||
@@ -1,41 +1,32 @@
|
||||
package beacon_api
|
||||
package chain
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/golang/protobuf/ptypes/empty"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/beacon"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/prysm/validator"
|
||||
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v4/time/slots"
|
||||
"github.com/prysmaticlabs/prysm/v4/validator/client/iface"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/client"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/client/beacon/shared_providers"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/server/structs"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v5/time/slots"
|
||||
)
|
||||
|
||||
type beaconApiBeaconChainClient struct {
|
||||
fallbackClient iface.BeaconChainClient
|
||||
jsonRestHandler JsonRestHandler
|
||||
stateValidatorsProvider StateValidatorsProvider
|
||||
type beaconApiChainClient struct {
|
||||
fallbackClient Client
|
||||
jsonRestHandler client.JsonRestHandler
|
||||
stateValidatorsProvider shared_providers.StateValidators
|
||||
}
|
||||
|
||||
const getValidatorPerformanceEndpoint = "/prysm/validators/performance"
|
||||
|
||||
func (c beaconApiBeaconChainClient) getHeadBlockHeaders(ctx context.Context) (*beacon.GetBlockHeaderResponse, error) {
|
||||
blockHeader := beacon.GetBlockHeaderResponse{}
|
||||
errJson, err := c.jsonRestHandler.Get(ctx, "/eth/v1/beacon/headers/head", &blockHeader)
|
||||
func (c beaconApiChainClient) headBlockHeaders(ctx context.Context) (*structs.GetBlockHeaderResponse, error) {
|
||||
blockHeader := structs.GetBlockHeaderResponse{}
|
||||
err := c.jsonRestHandler.Get(ctx, "/eth/v1/beacon/headers/head", &blockHeader)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, msgUnexpectedError)
|
||||
}
|
||||
if errJson != nil {
|
||||
return nil, errJson
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if blockHeader.Data == nil || blockHeader.Data.Header == nil {
|
||||
@@ -49,16 +40,12 @@ func (c beaconApiBeaconChainClient) getHeadBlockHeaders(ctx context.Context) (*b
|
||||
return &blockHeader, nil
|
||||
}
|
||||
|
||||
func (c beaconApiBeaconChainClient) GetChainHead(ctx context.Context, _ *empty.Empty) (*ethpb.ChainHead, error) {
|
||||
func (c beaconApiChainClient) ChainHead(ctx context.Context, _ *empty.Empty) (*ethpb.ChainHead, error) {
|
||||
const endpoint = "/eth/v1/beacon/states/head/finality_checkpoints"
|
||||
|
||||
finalityCheckpoints := beacon.GetFinalityCheckpointsResponse{}
|
||||
errJson, err := c.jsonRestHandler.Get(ctx, endpoint, &finalityCheckpoints)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, msgUnexpectedError)
|
||||
}
|
||||
if errJson != nil {
|
||||
return nil, errJson
|
||||
finalityCheckpoints := structs.GetFinalityCheckpointsResponse{}
|
||||
if err := c.jsonRestHandler.Get(ctx, endpoint, &finalityCheckpoints); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if finalityCheckpoints.Data == nil {
|
||||
@@ -122,7 +109,7 @@ func (c beaconApiBeaconChainClient) GetChainHead(ctx context.Context, _ *empty.E
|
||||
return nil, errors.Wrapf(err, "failed to decode previous justified checkpoint root `%s`", finalityCheckpoints.Data.PreviousJustified.Root)
|
||||
}
|
||||
|
||||
blockHeader, err := c.getHeadBlockHeaders(ctx)
|
||||
blockHeader, err := c.headBlockHeaders(ctx)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to get head block headers")
|
||||
}
|
||||
@@ -156,16 +143,16 @@ func (c beaconApiBeaconChainClient) GetChainHead(ctx context.Context, _ *empty.E
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c beaconApiBeaconChainClient) ListValidatorBalances(ctx context.Context, in *ethpb.ListValidatorBalancesRequest) (*ethpb.ValidatorBalances, error) {
|
||||
func (c beaconApiChainClient) ValidatorBalances(ctx context.Context, in *ethpb.ListValidatorBalancesRequest) (*ethpb.ValidatorBalances, error) {
|
||||
if c.fallbackClient != nil {
|
||||
return c.fallbackClient.ListValidatorBalances(ctx, in)
|
||||
return c.fallbackClient.ValidatorBalances(ctx, in)
|
||||
}
|
||||
|
||||
// TODO: Implement me
|
||||
panic("beaconApiBeaconChainClient.ListValidatorBalances is not implemented. To use a fallback client, pass a fallback client as the last argument of NewBeaconApiBeaconChainClientWithFallback.")
|
||||
return nil, errors.New("beaconApiChainClient.ValidatorBalances is not implemented. To use a fallback client, pass a fallback client as the last argument of NewBeaconApiChainClientWithFallback.")
|
||||
}
|
||||
|
||||
func (c beaconApiBeaconChainClient) ListValidators(ctx context.Context, in *ethpb.ListValidatorsRequest) (*ethpb.Validators, error) {
|
||||
func (c beaconApiChainClient) Validators(ctx context.Context, in *ethpb.ListValidatorsRequest) (*ethpb.Validators, error) {
|
||||
pageSize := in.PageSize
|
||||
|
||||
// We follow the gRPC behavior here, which returns a maximum of 250 results when pageSize == 0
|
||||
@@ -192,7 +179,7 @@ func (c beaconApiBeaconChainClient) ListValidators(ctx context.Context, in *ethp
|
||||
pubkeys[idx] = hexutil.Encode(pubkey)
|
||||
}
|
||||
|
||||
var stateValidators *beacon.GetValidatorsResponse
|
||||
var stateValidators *structs.GetValidatorsResponse
|
||||
var epoch primitives.Epoch
|
||||
|
||||
switch queryFilter := in.QueryFilter.(type) {
|
||||
@@ -201,21 +188,21 @@ func (c beaconApiBeaconChainClient) ListValidators(ctx context.Context, in *ethp
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to get first slot for epoch `%d`", queryFilter.Epoch)
|
||||
}
|
||||
if stateValidators, err = c.stateValidatorsProvider.GetStateValidatorsForSlot(ctx, slot, pubkeys, in.Indices, statuses); err != nil {
|
||||
if stateValidators, err = c.stateValidatorsProvider.StateValidatorsForSlot(ctx, slot, pubkeys, in.Indices, statuses); err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to get state validators for slot `%d`", slot)
|
||||
}
|
||||
epoch = slots.ToEpoch(slot)
|
||||
case *ethpb.ListValidatorsRequest_Genesis:
|
||||
if stateValidators, err = c.stateValidatorsProvider.GetStateValidatorsForSlot(ctx, 0, pubkeys, in.Indices, statuses); err != nil {
|
||||
if stateValidators, err = c.stateValidatorsProvider.StateValidatorsForSlot(ctx, 0, pubkeys, in.Indices, statuses); err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to get genesis state validators")
|
||||
}
|
||||
epoch = 0
|
||||
case nil:
|
||||
if stateValidators, err = c.stateValidatorsProvider.GetStateValidatorsForHead(ctx, pubkeys, in.Indices, statuses); err != nil {
|
||||
if stateValidators, err = c.stateValidatorsProvider.StateValidatorsForHead(ctx, pubkeys, in.Indices, statuses); err != nil {
|
||||
return nil, errors.Wrap(err, "failed to get head state validators")
|
||||
}
|
||||
|
||||
blockHeader, err := c.getHeadBlockHeaders(ctx)
|
||||
blockHeader, err := c.headBlockHeaders(ctx)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to get head block headers")
|
||||
}
|
||||
@@ -320,63 +307,29 @@ func (c beaconApiBeaconChainClient) ListValidators(ctx context.Context, in *ethp
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c beaconApiBeaconChainClient) GetValidatorQueue(ctx context.Context, in *empty.Empty) (*ethpb.ValidatorQueue, error) {
|
||||
func (c beaconApiChainClient) ValidatorQueue(ctx context.Context, in *empty.Empty) (*ethpb.ValidatorQueue, error) {
|
||||
if c.fallbackClient != nil {
|
||||
return c.fallbackClient.GetValidatorQueue(ctx, in)
|
||||
return c.fallbackClient.ValidatorQueue(ctx, in)
|
||||
}
|
||||
|
||||
// TODO: Implement me
|
||||
panic("beaconApiBeaconChainClient.GetValidatorQueue is not implemented. To use a fallback client, pass a fallback client as the last argument of NewBeaconApiBeaconChainClientWithFallback.")
|
||||
return nil, errors.New("beaconApiChainClient.ValidatorQueue is not implemented. To use a fallback client, pass a fallback client as the last argument of NewBeaconApiChainClientWithFallback.")
|
||||
}
|
||||
|
||||
func (c beaconApiBeaconChainClient) GetValidatorPerformance(ctx context.Context, in *ethpb.ValidatorPerformanceRequest) (*ethpb.ValidatorPerformanceResponse, error) {
|
||||
request, err := json.Marshal(validator.PerformanceRequest{
|
||||
PublicKeys: in.PublicKeys,
|
||||
Indices: in.Indices,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to marshal request")
|
||||
}
|
||||
resp := &validator.PerformanceResponse{}
|
||||
errJson, err := c.jsonRestHandler.Post(ctx, getValidatorPerformanceEndpoint, nil, bytes.NewBuffer(request), resp)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, msgUnexpectedError)
|
||||
}
|
||||
if errJson != nil {
|
||||
return nil, errJson
|
||||
}
|
||||
|
||||
return ðpb.ValidatorPerformanceResponse{
|
||||
CurrentEffectiveBalances: resp.CurrentEffectiveBalances,
|
||||
CorrectlyVotedSource: resp.CorrectlyVotedSource,
|
||||
CorrectlyVotedTarget: resp.CorrectlyVotedTarget,
|
||||
CorrectlyVotedHead: resp.CorrectlyVotedHead,
|
||||
BalancesBeforeEpochTransition: resp.BalancesBeforeEpochTransition,
|
||||
BalancesAfterEpochTransition: resp.BalancesAfterEpochTransition,
|
||||
MissingValidators: resp.MissingValidators,
|
||||
PublicKeys: resp.PublicKeys,
|
||||
InactivityScores: resp.InactivityScores,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c beaconApiBeaconChainClient) GetValidatorParticipation(ctx context.Context, in *ethpb.GetValidatorParticipationRequest) (*ethpb.ValidatorParticipationResponse, error) {
|
||||
func (c beaconApiChainClient) ValidatorPerformance(ctx context.Context, in *ethpb.ValidatorPerformanceRequest) (*ethpb.ValidatorPerformanceResponse, error) {
|
||||
if c.fallbackClient != nil {
|
||||
return c.fallbackClient.GetValidatorParticipation(ctx, in)
|
||||
return c.fallbackClient.ValidatorPerformance(ctx, in)
|
||||
}
|
||||
|
||||
// TODO: Implement me
|
||||
panic("beaconApiBeaconChainClient.GetValidatorParticipation is not implemented. To use a fallback client, pass a fallback client as the last argument of NewBeaconApiBeaconChainClientWithFallback.")
|
||||
return nil, errors.New("beaconApiChainClient.ValidatorPerformance is not implemented. To use a fallback client, pass a fallback client as the last argument of NewBeaconApiChainClientWithFallback.")
|
||||
}
|
||||
|
||||
func NewBeaconApiBeaconChainClientWithFallback(host string, timeout time.Duration, fallbackClient iface.BeaconChainClient) iface.BeaconChainClient {
|
||||
jsonRestHandler := beaconApiJsonRestHandler{
|
||||
httpClient: http.Client{Timeout: timeout},
|
||||
host: host,
|
||||
func (c beaconApiChainClient) ValidatorParticipation(ctx context.Context, in *ethpb.GetValidatorParticipationRequest) (*ethpb.ValidatorParticipationResponse, error) {
|
||||
if c.fallbackClient != nil {
|
||||
return c.fallbackClient.ValidatorParticipation(ctx, in)
|
||||
}
|
||||
|
||||
return &beaconApiBeaconChainClient{
|
||||
jsonRestHandler: jsonRestHandler,
|
||||
fallbackClient: fallbackClient,
|
||||
stateValidatorsProvider: beaconApiStateValidatorsProvider{jsonRestHandler: jsonRestHandler},
|
||||
}
|
||||
// TODO: Implement me
|
||||
return nil, errors.New("beaconApiChainClient.ValidatorParticipation is not implemented. To use a fallback client, pass a fallback client as the last argument of NewBeaconApiChainClientWithFallback.")
|
||||
}
|
||||
@@ -1,9 +1,7 @@
|
||||
package beacon_api
|
||||
package chain
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
@@ -11,17 +9,14 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/golang/mock/gomock"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/beacon"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/shared"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/prysm/validator"
|
||||
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
|
||||
"github.com/prysmaticlabs/prysm/v4/encoding/bytesutil"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v4/testing/assert"
|
||||
"github.com/prysmaticlabs/prysm/v4/testing/require"
|
||||
"github.com/prysmaticlabs/prysm/v4/time/slots"
|
||||
"github.com/prysmaticlabs/prysm/v4/validator/client/beacon-api/mock"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/client/beacon/mock"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/server/structs"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v5/testing/assert"
|
||||
"github.com/prysmaticlabs/prysm/v5/testing/require"
|
||||
"github.com/prysmaticlabs/prysm/v5/time/slots"
|
||||
"go.uber.org/mock/gomock"
|
||||
"google.golang.org/protobuf/types/known/emptypb"
|
||||
)
|
||||
|
||||
@@ -33,8 +28,8 @@ func TestListValidators(t *testing.T) {
|
||||
defer ctrl.Finish()
|
||||
ctx := context.Background()
|
||||
|
||||
beaconChainClient := beaconApiBeaconChainClient{}
|
||||
_, err := beaconChainClient.ListValidators(ctx, ðpb.ListValidatorsRequest{
|
||||
beaconChainClient := beaconApiChainClient{}
|
||||
_, err := beaconChainClient.Validators(ctx, ðpb.ListValidatorsRequest{
|
||||
PageToken: "foo",
|
||||
})
|
||||
assert.ErrorContains(t, "failed to parse page token `foo`", err)
|
||||
@@ -45,8 +40,8 @@ func TestListValidators(t *testing.T) {
|
||||
defer ctrl.Finish()
|
||||
ctx := context.Background()
|
||||
|
||||
beaconChainClient := beaconApiBeaconChainClient{}
|
||||
_, err := beaconChainClient.ListValidators(ctx, ðpb.ListValidatorsRequest{
|
||||
beaconChainClient := beaconApiChainClient{}
|
||||
_, err := beaconChainClient.Validators(ctx, ðpb.ListValidatorsRequest{
|
||||
QueryFilter: ðpb.ListValidatorsRequest_Epoch{
|
||||
Epoch: math.MaxUint64,
|
||||
},
|
||||
@@ -60,13 +55,13 @@ func TestListValidators(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
stateValidatorsProvider := mock.NewMockStateValidatorsProvider(ctrl)
|
||||
stateValidatorsProvider.EXPECT().GetStateValidatorsForSlot(ctx, gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(
|
||||
stateValidatorsProvider.EXPECT().StateValidatorsForSlot(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(
|
||||
nil,
|
||||
errors.New("foo error"),
|
||||
)
|
||||
|
||||
beaconChainClient := beaconApiBeaconChainClient{stateValidatorsProvider: stateValidatorsProvider}
|
||||
_, err := beaconChainClient.ListValidators(ctx, ðpb.ListValidatorsRequest{
|
||||
beaconChainClient := beaconApiChainClient{stateValidatorsProvider: stateValidatorsProvider}
|
||||
_, err := beaconChainClient.Validators(ctx, ðpb.ListValidatorsRequest{
|
||||
QueryFilter: ðpb.ListValidatorsRequest_Epoch{
|
||||
Epoch: 0,
|
||||
},
|
||||
@@ -80,13 +75,13 @@ func TestListValidators(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
stateValidatorsProvider := mock.NewMockStateValidatorsProvider(ctrl)
|
||||
stateValidatorsProvider.EXPECT().GetStateValidatorsForSlot(ctx, gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(
|
||||
stateValidatorsProvider.EXPECT().StateValidatorsForSlot(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(
|
||||
nil,
|
||||
errors.New("bar error"),
|
||||
)
|
||||
|
||||
beaconChainClient := beaconApiBeaconChainClient{stateValidatorsProvider: stateValidatorsProvider}
|
||||
_, err := beaconChainClient.ListValidators(ctx, ðpb.ListValidatorsRequest{
|
||||
beaconChainClient := beaconApiChainClient{stateValidatorsProvider: stateValidatorsProvider}
|
||||
_, err := beaconChainClient.Validators(ctx, ðpb.ListValidatorsRequest{
|
||||
QueryFilter: ðpb.ListValidatorsRequest_Genesis{},
|
||||
})
|
||||
assert.ErrorContains(t, "failed to get genesis state validators: bar error", err)
|
||||
@@ -98,13 +93,13 @@ func TestListValidators(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
stateValidatorsProvider := mock.NewMockStateValidatorsProvider(ctrl)
|
||||
stateValidatorsProvider.EXPECT().GetStateValidatorsForHead(ctx, gomock.Any(), gomock.Any(), gomock.Any()).Return(
|
||||
stateValidatorsProvider.EXPECT().StateValidatorsForHead(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(
|
||||
nil,
|
||||
errors.New("foo error"),
|
||||
)
|
||||
|
||||
beaconChainClient := beaconApiBeaconChainClient{stateValidatorsProvider: stateValidatorsProvider}
|
||||
_, err := beaconChainClient.ListValidators(ctx, ðpb.ListValidatorsRequest{
|
||||
beaconChainClient := beaconApiChainClient{stateValidatorsProvider: stateValidatorsProvider}
|
||||
_, err := beaconChainClient.Validators(ctx, ðpb.ListValidatorsRequest{
|
||||
QueryFilter: nil,
|
||||
})
|
||||
assert.ErrorContains(t, "failed to get head state validators: foo error", err)
|
||||
@@ -116,22 +111,19 @@ func TestListValidators(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
stateValidatorsProvider := mock.NewMockStateValidatorsProvider(ctrl)
|
||||
stateValidatorsProvider.EXPECT().GetStateValidatorsForHead(ctx, gomock.Any(), gomock.Any(), gomock.Any()).Return(
|
||||
stateValidatorsProvider.EXPECT().StateValidatorsForHead(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
|
||||
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
|
||||
jsonRestHandler.EXPECT().Get(ctx, blockHeaderEndpoint, gomock.Any()).Return(
|
||||
nil,
|
||||
errors.New("bar error"),
|
||||
)
|
||||
jsonRestHandler.EXPECT().Get(gomock.Any(), blockHeaderEndpoint, gomock.Any()).Return(errors.New("bar error"))
|
||||
|
||||
beaconChainClient := beaconApiBeaconChainClient{
|
||||
beaconChainClient := beaconApiChainClient{
|
||||
stateValidatorsProvider: stateValidatorsProvider,
|
||||
jsonRestHandler: jsonRestHandler,
|
||||
}
|
||||
_, err := beaconChainClient.ListValidators(ctx, ðpb.ListValidatorsRequest{
|
||||
_, err := beaconChainClient.Validators(ctx, ðpb.ListValidatorsRequest{
|
||||
QueryFilter: nil,
|
||||
})
|
||||
assert.ErrorContains(t, "bar error", err)
|
||||
@@ -141,19 +133,19 @@ func TestListValidators(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
expectedError string
|
||||
blockHeaderResponse beacon.GetBlockHeaderResponse
|
||||
blockHeaderResponse structs.GetBlockHeaderResponse
|
||||
}{
|
||||
{
|
||||
name: "nil data",
|
||||
blockHeaderResponse: beacon.GetBlockHeaderResponse{
|
||||
blockHeaderResponse: structs.GetBlockHeaderResponse{
|
||||
Data: nil,
|
||||
},
|
||||
expectedError: "block header data is nil",
|
||||
},
|
||||
{
|
||||
name: "nil data header",
|
||||
blockHeaderResponse: beacon.GetBlockHeaderResponse{
|
||||
Data: &shared.SignedBeaconBlockHeaderContainer{
|
||||
blockHeaderResponse: structs.GetBlockHeaderResponse{
|
||||
Data: &structs.SignedBeaconBlockHeaderContainer{
|
||||
Header: nil,
|
||||
},
|
||||
},
|
||||
@@ -161,9 +153,9 @@ func TestListValidators(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "nil message",
|
||||
blockHeaderResponse: beacon.GetBlockHeaderResponse{
|
||||
Data: &shared.SignedBeaconBlockHeaderContainer{
|
||||
Header: &shared.SignedBeaconBlockHeader{
|
||||
blockHeaderResponse: structs.GetBlockHeaderResponse{
|
||||
Data: &structs.SignedBeaconBlockHeaderContainer{
|
||||
Header: &structs.SignedBeaconBlockHeader{
|
||||
Message: nil,
|
||||
},
|
||||
},
|
||||
@@ -172,10 +164,10 @@ func TestListValidators(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "invalid header slot",
|
||||
blockHeaderResponse: beacon.GetBlockHeaderResponse{
|
||||
Data: &shared.SignedBeaconBlockHeaderContainer{
|
||||
Header: &shared.SignedBeaconBlockHeader{
|
||||
Message: &shared.BeaconBlockHeader{
|
||||
blockHeaderResponse: structs.GetBlockHeaderResponse{
|
||||
Data: &structs.SignedBeaconBlockHeaderContainer{
|
||||
Header: &structs.SignedBeaconBlockHeader{
|
||||
Message: &structs.BeaconBlockHeader{
|
||||
Slot: "foo",
|
||||
},
|
||||
},
|
||||
@@ -192,25 +184,24 @@ func TestListValidators(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
stateValidatorsProvider := mock.NewMockStateValidatorsProvider(ctrl)
|
||||
stateValidatorsProvider.EXPECT().GetStateValidatorsForHead(ctx, gomock.Any(), gomock.Any(), gomock.Any()).Return(
|
||||
stateValidatorsProvider.EXPECT().StateValidatorsForHead(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
|
||||
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
|
||||
jsonRestHandler.EXPECT().Get(ctx, blockHeaderEndpoint, gomock.Any()).Return(
|
||||
nil,
|
||||
jsonRestHandler.EXPECT().Get(gomock.Any(), blockHeaderEndpoint, gomock.Any()).Return(
|
||||
nil,
|
||||
).SetArg(
|
||||
2,
|
||||
testCase.blockHeaderResponse,
|
||||
)
|
||||
|
||||
beaconChainClient := beaconApiBeaconChainClient{
|
||||
beaconChainClient := beaconApiChainClient{
|
||||
stateValidatorsProvider: stateValidatorsProvider,
|
||||
jsonRestHandler: jsonRestHandler,
|
||||
}
|
||||
_, err := beaconChainClient.ListValidators(ctx, ðpb.ListValidatorsRequest{
|
||||
_, err := beaconChainClient.Validators(ctx, ðpb.ListValidatorsRequest{
|
||||
QueryFilter: nil,
|
||||
})
|
||||
assert.ErrorContains(t, testCase.expectedError, err)
|
||||
@@ -219,12 +210,12 @@ func TestListValidators(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("fails to get validators for genesis filter", func(t *testing.T) {
|
||||
generateValidStateValidatorsResponse := func() *beacon.GetValidatorsResponse {
|
||||
return &beacon.GetValidatorsResponse{
|
||||
Data: []*beacon.ValidatorContainer{
|
||||
generateValidStateValidatorsResponse := func() *structs.GetValidatorsResponse {
|
||||
return &structs.GetValidatorsResponse{
|
||||
Data: []*structs.ValidatorContainer{
|
||||
{
|
||||
Index: "1",
|
||||
Validator: &beacon.Validator{
|
||||
Validator: &structs.Validator{
|
||||
Pubkey: hexutil.Encode([]byte{3}),
|
||||
WithdrawalCredentials: hexutil.Encode([]byte{4}),
|
||||
EffectiveBalance: "5",
|
||||
@@ -241,12 +232,12 @@ func TestListValidators(t *testing.T) {
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
generateStateValidatorsResponse func() *beacon.GetValidatorsResponse
|
||||
generateStateValidatorsResponse func() *structs.GetValidatorsResponse
|
||||
expectedError string
|
||||
}{
|
||||
{
|
||||
name: "nil validator",
|
||||
generateStateValidatorsResponse: func() *beacon.GetValidatorsResponse {
|
||||
generateStateValidatorsResponse: func() *structs.GetValidatorsResponse {
|
||||
validatorsResponse := generateValidStateValidatorsResponse()
|
||||
validatorsResponse.Data[0].Validator = nil
|
||||
return validatorsResponse
|
||||
@@ -255,7 +246,7 @@ func TestListValidators(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "invalid pubkey",
|
||||
generateStateValidatorsResponse: func() *beacon.GetValidatorsResponse {
|
||||
generateStateValidatorsResponse: func() *structs.GetValidatorsResponse {
|
||||
validatorsResponse := generateValidStateValidatorsResponse()
|
||||
validatorsResponse.Data[0].Validator.Pubkey = "foo"
|
||||
return validatorsResponse
|
||||
@@ -264,7 +255,7 @@ func TestListValidators(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "invalid withdrawal credentials",
|
||||
generateStateValidatorsResponse: func() *beacon.GetValidatorsResponse {
|
||||
generateStateValidatorsResponse: func() *structs.GetValidatorsResponse {
|
||||
validatorsResponse := generateValidStateValidatorsResponse()
|
||||
validatorsResponse.Data[0].Validator.WithdrawalCredentials = "bar"
|
||||
return validatorsResponse
|
||||
@@ -273,7 +264,7 @@ func TestListValidators(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "invalid effective balance",
|
||||
generateStateValidatorsResponse: func() *beacon.GetValidatorsResponse {
|
||||
generateStateValidatorsResponse: func() *structs.GetValidatorsResponse {
|
||||
validatorsResponse := generateValidStateValidatorsResponse()
|
||||
validatorsResponse.Data[0].Validator.EffectiveBalance = "foo"
|
||||
return validatorsResponse
|
||||
@@ -282,7 +273,7 @@ func TestListValidators(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "invalid validator index",
|
||||
generateStateValidatorsResponse: func() *beacon.GetValidatorsResponse {
|
||||
generateStateValidatorsResponse: func() *structs.GetValidatorsResponse {
|
||||
validatorsResponse := generateValidStateValidatorsResponse()
|
||||
validatorsResponse.Data[0].Index = "bar"
|
||||
return validatorsResponse
|
||||
@@ -291,7 +282,7 @@ func TestListValidators(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "invalid activation eligibility epoch",
|
||||
generateStateValidatorsResponse: func() *beacon.GetValidatorsResponse {
|
||||
generateStateValidatorsResponse: func() *structs.GetValidatorsResponse {
|
||||
validatorsResponse := generateValidStateValidatorsResponse()
|
||||
validatorsResponse.Data[0].Validator.ActivationEligibilityEpoch = "foo"
|
||||
return validatorsResponse
|
||||
@@ -300,7 +291,7 @@ func TestListValidators(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "invalid activation epoch",
|
||||
generateStateValidatorsResponse: func() *beacon.GetValidatorsResponse {
|
||||
generateStateValidatorsResponse: func() *structs.GetValidatorsResponse {
|
||||
validatorsResponse := generateValidStateValidatorsResponse()
|
||||
validatorsResponse.Data[0].Validator.ActivationEpoch = "bar"
|
||||
return validatorsResponse
|
||||
@@ -309,7 +300,7 @@ func TestListValidators(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "invalid exit epoch",
|
||||
generateStateValidatorsResponse: func() *beacon.GetValidatorsResponse {
|
||||
generateStateValidatorsResponse: func() *structs.GetValidatorsResponse {
|
||||
validatorsResponse := generateValidStateValidatorsResponse()
|
||||
validatorsResponse.Data[0].Validator.ExitEpoch = "foo"
|
||||
return validatorsResponse
|
||||
@@ -318,7 +309,7 @@ func TestListValidators(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "invalid withdrawable epoch",
|
||||
generateStateValidatorsResponse: func() *beacon.GetValidatorsResponse {
|
||||
generateStateValidatorsResponse: func() *structs.GetValidatorsResponse {
|
||||
validatorsResponse := generateValidStateValidatorsResponse()
|
||||
validatorsResponse.Data[0].Validator.WithdrawableEpoch = "bar"
|
||||
return validatorsResponse
|
||||
@@ -334,13 +325,13 @@ func TestListValidators(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
stateValidatorsProvider := mock.NewMockStateValidatorsProvider(ctrl)
|
||||
stateValidatorsProvider.EXPECT().GetStateValidatorsForSlot(ctx, gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(
|
||||
stateValidatorsProvider.EXPECT().StateValidatorsForSlot(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(
|
||||
testCase.generateStateValidatorsResponse(),
|
||||
nil,
|
||||
)
|
||||
|
||||
beaconChainClient := beaconApiBeaconChainClient{stateValidatorsProvider: stateValidatorsProvider}
|
||||
_, err := beaconChainClient.ListValidators(ctx, ðpb.ListValidatorsRequest{
|
||||
beaconChainClient := beaconApiChainClient{stateValidatorsProvider: stateValidatorsProvider}
|
||||
_, err := beaconChainClient.Validators(ctx, ðpb.ListValidatorsRequest{
|
||||
QueryFilter: ðpb.ListValidatorsRequest_Genesis{},
|
||||
})
|
||||
assert.ErrorContains(t, testCase.expectedError, err)
|
||||
@@ -349,12 +340,12 @@ func TestListValidators(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("correctly returns the expected validators", func(t *testing.T) {
|
||||
generateValidStateValidatorsResponse := func() *beacon.GetValidatorsResponse {
|
||||
return &beacon.GetValidatorsResponse{
|
||||
Data: []*beacon.ValidatorContainer{
|
||||
generateValidStateValidatorsResponse := func() *structs.GetValidatorsResponse {
|
||||
return &structs.GetValidatorsResponse{
|
||||
Data: []*structs.ValidatorContainer{
|
||||
{
|
||||
Index: "1",
|
||||
Validator: &beacon.Validator{
|
||||
Validator: &structs.Validator{
|
||||
Pubkey: hexutil.Encode([]byte{2}),
|
||||
WithdrawalCredentials: hexutil.Encode([]byte{3}),
|
||||
EffectiveBalance: "4",
|
||||
@@ -367,7 +358,7 @@ func TestListValidators(t *testing.T) {
|
||||
},
|
||||
{
|
||||
Index: "9",
|
||||
Validator: &beacon.Validator{
|
||||
Validator: &structs.Validator{
|
||||
Pubkey: hexutil.Encode([]byte{10}),
|
||||
WithdrawalCredentials: hexutil.Encode([]byte{11}),
|
||||
EffectiveBalance: "12",
|
||||
@@ -384,7 +375,7 @@ func TestListValidators(t *testing.T) {
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
generateJsonStateValidatorsResponse func() *beacon.GetValidatorsResponse
|
||||
generateJsonStateValidatorsResponse func() *structs.GetValidatorsResponse
|
||||
generateProtoValidatorsResponse func() *ethpb.Validators
|
||||
pubkeys [][]byte
|
||||
pubkeyStrings []string
|
||||
@@ -395,16 +386,16 @@ func TestListValidators(t *testing.T) {
|
||||
}{
|
||||
{
|
||||
name: "page size 0",
|
||||
generateJsonStateValidatorsResponse: func() *beacon.GetValidatorsResponse {
|
||||
generateJsonStateValidatorsResponse: func() *structs.GetValidatorsResponse {
|
||||
validValidatorsResponse := generateValidStateValidatorsResponse()
|
||||
|
||||
// Generate more than 250 validators, but expect only 250 to be returned
|
||||
validators := make([]*beacon.ValidatorContainer, 267)
|
||||
validators := make([]*structs.ValidatorContainer, 267)
|
||||
for idx := 0; idx < len(validators); idx++ {
|
||||
validators[idx] = validValidatorsResponse.Data[0]
|
||||
}
|
||||
|
||||
validatorsResponse := &beacon.GetValidatorsResponse{
|
||||
validatorsResponse := &structs.GetValidatorsResponse{
|
||||
Data: validators,
|
||||
}
|
||||
|
||||
@@ -562,13 +553,13 @@ func TestListValidators(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
stateValidatorsProvider := mock.NewMockStateValidatorsProvider(ctrl)
|
||||
stateValidatorsProvider.EXPECT().GetStateValidatorsForSlot(ctx, primitives.Slot(0), make([]string, 0), []primitives.ValidatorIndex{}, nil).Return(
|
||||
stateValidatorsProvider.EXPECT().StateValidatorsForSlot(gomock.Any(), primitives.Slot(0), make([]string, 0), []primitives.ValidatorIndex{}, nil).Return(
|
||||
testCase.generateJsonStateValidatorsResponse(),
|
||||
nil,
|
||||
)
|
||||
|
||||
beaconChainClient := beaconApiBeaconChainClient{stateValidatorsProvider: stateValidatorsProvider}
|
||||
validators, err := beaconChainClient.ListValidators(ctx, ðpb.ListValidatorsRequest{
|
||||
beaconChainClient := beaconApiChainClient{stateValidatorsProvider: stateValidatorsProvider}
|
||||
validators, err := beaconChainClient.Validators(ctx, ðpb.ListValidatorsRequest{
|
||||
QueryFilter: ðpb.ListValidatorsRequest_Genesis{},
|
||||
PublicKeys: [][]byte{},
|
||||
Indices: []primitives.ValidatorIndex{},
|
||||
@@ -590,18 +581,18 @@ func TestGetChainHead(t *testing.T) {
|
||||
const finalityCheckpointsEndpoint = "/eth/v1/beacon/states/head/finality_checkpoints"
|
||||
const headBlockHeadersEndpoint = "/eth/v1/beacon/headers/head"
|
||||
|
||||
generateValidFinalityCheckpointsResponse := func() beacon.GetFinalityCheckpointsResponse {
|
||||
return beacon.GetFinalityCheckpointsResponse{
|
||||
Data: &beacon.FinalityCheckpoints{
|
||||
PreviousJustified: &shared.Checkpoint{
|
||||
generateValidFinalityCheckpointsResponse := func() structs.GetFinalityCheckpointsResponse {
|
||||
return structs.GetFinalityCheckpointsResponse{
|
||||
Data: &structs.FinalityCheckpoints{
|
||||
PreviousJustified: &structs.Checkpoint{
|
||||
Epoch: "1",
|
||||
Root: hexutil.Encode([]byte{2}),
|
||||
},
|
||||
CurrentJustified: &shared.Checkpoint{
|
||||
CurrentJustified: &structs.Checkpoint{
|
||||
Epoch: "3",
|
||||
Root: hexutil.Encode([]byte{4}),
|
||||
},
|
||||
Finalized: &shared.Checkpoint{
|
||||
Finalized: &structs.Checkpoint{
|
||||
Epoch: "5",
|
||||
Root: hexutil.Encode([]byte{6}),
|
||||
},
|
||||
@@ -612,7 +603,7 @@ func TestGetChainHead(t *testing.T) {
|
||||
t.Run("fails to get finality checkpoints", func(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
generateFinalityCheckpointsResponse func() beacon.GetFinalityCheckpointsResponse
|
||||
generateFinalityCheckpointsResponse func() structs.GetFinalityCheckpointsResponse
|
||||
finalityCheckpointsError error
|
||||
expectedError string
|
||||
}{
|
||||
@@ -620,14 +611,14 @@ func TestGetChainHead(t *testing.T) {
|
||||
name: "query failed",
|
||||
finalityCheckpointsError: errors.New("foo error"),
|
||||
expectedError: "foo error",
|
||||
generateFinalityCheckpointsResponse: func() beacon.GetFinalityCheckpointsResponse {
|
||||
return beacon.GetFinalityCheckpointsResponse{}
|
||||
generateFinalityCheckpointsResponse: func() structs.GetFinalityCheckpointsResponse {
|
||||
return structs.GetFinalityCheckpointsResponse{}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "nil finality checkpoints data",
|
||||
expectedError: "finality checkpoints data is nil",
|
||||
generateFinalityCheckpointsResponse: func() beacon.GetFinalityCheckpointsResponse {
|
||||
generateFinalityCheckpointsResponse: func() structs.GetFinalityCheckpointsResponse {
|
||||
validResponse := generateValidFinalityCheckpointsResponse()
|
||||
validResponse.Data = nil
|
||||
return validResponse
|
||||
@@ -636,7 +627,7 @@ func TestGetChainHead(t *testing.T) {
|
||||
{
|
||||
name: "nil finalized checkpoint",
|
||||
expectedError: "finalized checkpoint is nil",
|
||||
generateFinalityCheckpointsResponse: func() beacon.GetFinalityCheckpointsResponse {
|
||||
generateFinalityCheckpointsResponse: func() structs.GetFinalityCheckpointsResponse {
|
||||
validResponse := generateValidFinalityCheckpointsResponse()
|
||||
validResponse.Data.Finalized = nil
|
||||
return validResponse
|
||||
@@ -645,7 +636,7 @@ func TestGetChainHead(t *testing.T) {
|
||||
{
|
||||
name: "invalid finalized epoch",
|
||||
expectedError: "failed to parse finalized epoch `foo`",
|
||||
generateFinalityCheckpointsResponse: func() beacon.GetFinalityCheckpointsResponse {
|
||||
generateFinalityCheckpointsResponse: func() structs.GetFinalityCheckpointsResponse {
|
||||
validResponse := generateValidFinalityCheckpointsResponse()
|
||||
validResponse.Data.Finalized.Epoch = "foo"
|
||||
return validResponse
|
||||
@@ -654,7 +645,7 @@ func TestGetChainHead(t *testing.T) {
|
||||
{
|
||||
name: "failed to get first slot of finalized epoch",
|
||||
expectedError: fmt.Sprintf("failed to get first slot for epoch `%d`", uint64(math.MaxUint64)),
|
||||
generateFinalityCheckpointsResponse: func() beacon.GetFinalityCheckpointsResponse {
|
||||
generateFinalityCheckpointsResponse: func() structs.GetFinalityCheckpointsResponse {
|
||||
validResponse := generateValidFinalityCheckpointsResponse()
|
||||
validResponse.Data.Finalized.Epoch = strconv.FormatUint(uint64(math.MaxUint64), 10)
|
||||
return validResponse
|
||||
@@ -663,7 +654,7 @@ func TestGetChainHead(t *testing.T) {
|
||||
{
|
||||
name: "invalid finalized root",
|
||||
expectedError: "failed to decode finalized checkpoint root `bar`",
|
||||
generateFinalityCheckpointsResponse: func() beacon.GetFinalityCheckpointsResponse {
|
||||
generateFinalityCheckpointsResponse: func() structs.GetFinalityCheckpointsResponse {
|
||||
validResponse := generateValidFinalityCheckpointsResponse()
|
||||
validResponse.Data.Finalized.Root = "bar"
|
||||
return validResponse
|
||||
@@ -672,7 +663,7 @@ func TestGetChainHead(t *testing.T) {
|
||||
{
|
||||
name: "nil current justified checkpoint",
|
||||
expectedError: "current justified checkpoint is nil",
|
||||
generateFinalityCheckpointsResponse: func() beacon.GetFinalityCheckpointsResponse {
|
||||
generateFinalityCheckpointsResponse: func() structs.GetFinalityCheckpointsResponse {
|
||||
validResponse := generateValidFinalityCheckpointsResponse()
|
||||
validResponse.Data.CurrentJustified = nil
|
||||
return validResponse
|
||||
@@ -681,7 +672,7 @@ func TestGetChainHead(t *testing.T) {
|
||||
{
|
||||
name: "nil current justified epoch",
|
||||
expectedError: "failed to parse current justified checkpoint epoch `foo`",
|
||||
generateFinalityCheckpointsResponse: func() beacon.GetFinalityCheckpointsResponse {
|
||||
generateFinalityCheckpointsResponse: func() structs.GetFinalityCheckpointsResponse {
|
||||
validResponse := generateValidFinalityCheckpointsResponse()
|
||||
validResponse.Data.CurrentJustified.Epoch = "foo"
|
||||
return validResponse
|
||||
@@ -690,7 +681,7 @@ func TestGetChainHead(t *testing.T) {
|
||||
{
|
||||
name: "failed to get first slot of current justified epoch",
|
||||
expectedError: fmt.Sprintf("failed to get first slot for epoch `%d`", uint64(math.MaxUint64)),
|
||||
generateFinalityCheckpointsResponse: func() beacon.GetFinalityCheckpointsResponse {
|
||||
generateFinalityCheckpointsResponse: func() structs.GetFinalityCheckpointsResponse {
|
||||
validResponse := generateValidFinalityCheckpointsResponse()
|
||||
validResponse.Data.CurrentJustified.Epoch = strconv.FormatUint(uint64(math.MaxUint64), 10)
|
||||
return validResponse
|
||||
@@ -699,7 +690,7 @@ func TestGetChainHead(t *testing.T) {
|
||||
{
|
||||
name: "invalid current justified root",
|
||||
expectedError: "failed to decode current justified checkpoint root `bar`",
|
||||
generateFinalityCheckpointsResponse: func() beacon.GetFinalityCheckpointsResponse {
|
||||
generateFinalityCheckpointsResponse: func() structs.GetFinalityCheckpointsResponse {
|
||||
validResponse := generateValidFinalityCheckpointsResponse()
|
||||
validResponse.Data.CurrentJustified.Root = "bar"
|
||||
return validResponse
|
||||
@@ -708,7 +699,7 @@ func TestGetChainHead(t *testing.T) {
|
||||
{
|
||||
name: "nil previous justified checkpoint",
|
||||
expectedError: "previous justified checkpoint is nil",
|
||||
generateFinalityCheckpointsResponse: func() beacon.GetFinalityCheckpointsResponse {
|
||||
generateFinalityCheckpointsResponse: func() structs.GetFinalityCheckpointsResponse {
|
||||
validResponse := generateValidFinalityCheckpointsResponse()
|
||||
validResponse.Data.PreviousJustified = nil
|
||||
return validResponse
|
||||
@@ -717,7 +708,7 @@ func TestGetChainHead(t *testing.T) {
|
||||
{
|
||||
name: "nil previous justified epoch",
|
||||
expectedError: "failed to parse previous justified checkpoint epoch `foo`",
|
||||
generateFinalityCheckpointsResponse: func() beacon.GetFinalityCheckpointsResponse {
|
||||
generateFinalityCheckpointsResponse: func() structs.GetFinalityCheckpointsResponse {
|
||||
validResponse := generateValidFinalityCheckpointsResponse()
|
||||
validResponse.Data.PreviousJustified.Epoch = "foo"
|
||||
return validResponse
|
||||
@@ -726,7 +717,7 @@ func TestGetChainHead(t *testing.T) {
|
||||
{
|
||||
name: "failed to get first slot of previous justified epoch",
|
||||
expectedError: fmt.Sprintf("failed to get first slot for epoch `%d`", uint64(math.MaxUint64)),
|
||||
generateFinalityCheckpointsResponse: func() beacon.GetFinalityCheckpointsResponse {
|
||||
generateFinalityCheckpointsResponse: func() structs.GetFinalityCheckpointsResponse {
|
||||
validResponse := generateValidFinalityCheckpointsResponse()
|
||||
validResponse.Data.PreviousJustified.Epoch = strconv.FormatUint(uint64(math.MaxUint64), 10)
|
||||
return validResponse
|
||||
@@ -735,7 +726,7 @@ func TestGetChainHead(t *testing.T) {
|
||||
{
|
||||
name: "invalid previous justified root",
|
||||
expectedError: "failed to decode previous justified checkpoint root `bar`",
|
||||
generateFinalityCheckpointsResponse: func() beacon.GetFinalityCheckpointsResponse {
|
||||
generateFinalityCheckpointsResponse: func() structs.GetFinalityCheckpointsResponse {
|
||||
validResponse := generateValidFinalityCheckpointsResponse()
|
||||
validResponse.Data.PreviousJustified.Root = "bar"
|
||||
return validResponse
|
||||
@@ -749,29 +740,28 @@ func TestGetChainHead(t *testing.T) {
|
||||
defer ctrl.Finish()
|
||||
ctx := context.Background()
|
||||
|
||||
finalityCheckpointsResponse := beacon.GetFinalityCheckpointsResponse{}
|
||||
finalityCheckpointsResponse := structs.GetFinalityCheckpointsResponse{}
|
||||
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
|
||||
jsonRestHandler.EXPECT().Get(ctx, finalityCheckpointsEndpoint, &finalityCheckpointsResponse).Return(
|
||||
nil,
|
||||
jsonRestHandler.EXPECT().Get(gomock.Any(), finalityCheckpointsEndpoint, &finalityCheckpointsResponse).Return(
|
||||
testCase.finalityCheckpointsError,
|
||||
).SetArg(
|
||||
2,
|
||||
testCase.generateFinalityCheckpointsResponse(),
|
||||
)
|
||||
|
||||
beaconChainClient := beaconApiBeaconChainClient{jsonRestHandler: jsonRestHandler}
|
||||
_, err := beaconChainClient.GetChainHead(ctx, &emptypb.Empty{})
|
||||
beaconChainClient := beaconApiChainClient{jsonRestHandler: jsonRestHandler}
|
||||
_, err := beaconChainClient.ChainHead(ctx, &emptypb.Empty{})
|
||||
assert.ErrorContains(t, testCase.expectedError, err)
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
generateValidBlockHeadersResponse := func() beacon.GetBlockHeaderResponse {
|
||||
return beacon.GetBlockHeaderResponse{
|
||||
Data: &shared.SignedBeaconBlockHeaderContainer{
|
||||
generateValidBlockHeadersResponse := func() structs.GetBlockHeaderResponse {
|
||||
return structs.GetBlockHeaderResponse{
|
||||
Data: &structs.SignedBeaconBlockHeaderContainer{
|
||||
Root: hexutil.Encode([]byte{7}),
|
||||
Header: &shared.SignedBeaconBlockHeader{
|
||||
Message: &shared.BeaconBlockHeader{
|
||||
Header: &structs.SignedBeaconBlockHeader{
|
||||
Message: &structs.BeaconBlockHeader{
|
||||
Slot: "8",
|
||||
},
|
||||
},
|
||||
@@ -782,7 +772,7 @@ func TestGetChainHead(t *testing.T) {
|
||||
t.Run("fails to get head block headers", func(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
generateHeadBlockHeadersResponse func() beacon.GetBlockHeaderResponse
|
||||
generateHeadBlockHeadersResponse func() structs.GetBlockHeaderResponse
|
||||
headBlockHeadersError error
|
||||
expectedError string
|
||||
}{
|
||||
@@ -790,14 +780,14 @@ func TestGetChainHead(t *testing.T) {
|
||||
name: "query failed",
|
||||
headBlockHeadersError: errors.New("foo error"),
|
||||
expectedError: "failed to get head block header",
|
||||
generateHeadBlockHeadersResponse: func() beacon.GetBlockHeaderResponse {
|
||||
return beacon.GetBlockHeaderResponse{}
|
||||
generateHeadBlockHeadersResponse: func() structs.GetBlockHeaderResponse {
|
||||
return structs.GetBlockHeaderResponse{}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "nil block header data",
|
||||
expectedError: "block header data is nil",
|
||||
generateHeadBlockHeadersResponse: func() beacon.GetBlockHeaderResponse {
|
||||
generateHeadBlockHeadersResponse: func() structs.GetBlockHeaderResponse {
|
||||
validResponse := generateValidBlockHeadersResponse()
|
||||
validResponse.Data = nil
|
||||
return validResponse
|
||||
@@ -806,7 +796,7 @@ func TestGetChainHead(t *testing.T) {
|
||||
{
|
||||
name: "nil block header data header",
|
||||
expectedError: "block header data is nil",
|
||||
generateHeadBlockHeadersResponse: func() beacon.GetBlockHeaderResponse {
|
||||
generateHeadBlockHeadersResponse: func() structs.GetBlockHeaderResponse {
|
||||
validResponse := generateValidBlockHeadersResponse()
|
||||
validResponse.Data.Header = nil
|
||||
return validResponse
|
||||
@@ -815,7 +805,7 @@ func TestGetChainHead(t *testing.T) {
|
||||
{
|
||||
name: "nil block header message",
|
||||
expectedError: "block header message is nil",
|
||||
generateHeadBlockHeadersResponse: func() beacon.GetBlockHeaderResponse {
|
||||
generateHeadBlockHeadersResponse: func() structs.GetBlockHeaderResponse {
|
||||
validResponse := generateValidBlockHeadersResponse()
|
||||
validResponse.Data.Header.Message = nil
|
||||
return validResponse
|
||||
@@ -824,7 +814,7 @@ func TestGetChainHead(t *testing.T) {
|
||||
{
|
||||
name: "invalid message slot",
|
||||
expectedError: "failed to parse head block slot `foo`",
|
||||
generateHeadBlockHeadersResponse: func() beacon.GetBlockHeaderResponse {
|
||||
generateHeadBlockHeadersResponse: func() structs.GetBlockHeaderResponse {
|
||||
validResponse := generateValidBlockHeadersResponse()
|
||||
validResponse.Data.Header.Message.Slot = "foo"
|
||||
return validResponse
|
||||
@@ -834,7 +824,7 @@ func TestGetChainHead(t *testing.T) {
|
||||
{
|
||||
name: "invalid root",
|
||||
expectedError: "failed to decode head block root `bar`",
|
||||
generateHeadBlockHeadersResponse: func() beacon.GetBlockHeaderResponse {
|
||||
generateHeadBlockHeadersResponse: func() structs.GetBlockHeaderResponse {
|
||||
validResponse := generateValidBlockHeadersResponse()
|
||||
validResponse.Data.Root = "bar"
|
||||
return validResponse
|
||||
@@ -850,26 +840,24 @@ func TestGetChainHead(t *testing.T) {
|
||||
|
||||
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
|
||||
|
||||
finalityCheckpointsResponse := beacon.GetFinalityCheckpointsResponse{}
|
||||
jsonRestHandler.EXPECT().Get(ctx, finalityCheckpointsEndpoint, &finalityCheckpointsResponse).Return(
|
||||
nil,
|
||||
finalityCheckpointsResponse := structs.GetFinalityCheckpointsResponse{}
|
||||
jsonRestHandler.EXPECT().Get(gomock.Any(), finalityCheckpointsEndpoint, &finalityCheckpointsResponse).Return(
|
||||
nil,
|
||||
).SetArg(
|
||||
2,
|
||||
generateValidFinalityCheckpointsResponse(),
|
||||
)
|
||||
|
||||
headBlockHeadersResponse := beacon.GetBlockHeaderResponse{}
|
||||
jsonRestHandler.EXPECT().Get(ctx, headBlockHeadersEndpoint, &headBlockHeadersResponse).Return(
|
||||
nil,
|
||||
headBlockHeadersResponse := structs.GetBlockHeaderResponse{}
|
||||
jsonRestHandler.EXPECT().Get(gomock.Any(), headBlockHeadersEndpoint, &headBlockHeadersResponse).Return(
|
||||
testCase.headBlockHeadersError,
|
||||
).SetArg(
|
||||
2,
|
||||
testCase.generateHeadBlockHeadersResponse(),
|
||||
)
|
||||
|
||||
beaconChainClient := beaconApiBeaconChainClient{jsonRestHandler: jsonRestHandler}
|
||||
_, err := beaconChainClient.GetChainHead(ctx, &emptypb.Empty{})
|
||||
beaconChainClient := beaconApiChainClient{jsonRestHandler: jsonRestHandler}
|
||||
_, err := beaconChainClient.ChainHead(ctx, &emptypb.Empty{})
|
||||
assert.ErrorContains(t, testCase.expectedError, err)
|
||||
})
|
||||
}
|
||||
@@ -882,18 +870,16 @@ func TestGetChainHead(t *testing.T) {
|
||||
|
||||
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
|
||||
|
||||
finalityCheckpointsResponse := beacon.GetFinalityCheckpointsResponse{}
|
||||
jsonRestHandler.EXPECT().Get(ctx, finalityCheckpointsEndpoint, &finalityCheckpointsResponse).Return(
|
||||
nil,
|
||||
finalityCheckpointsResponse := structs.GetFinalityCheckpointsResponse{}
|
||||
jsonRestHandler.EXPECT().Get(gomock.Any(), finalityCheckpointsEndpoint, &finalityCheckpointsResponse).Return(
|
||||
nil,
|
||||
).SetArg(
|
||||
2,
|
||||
generateValidFinalityCheckpointsResponse(),
|
||||
)
|
||||
|
||||
headBlockHeadersResponse := beacon.GetBlockHeaderResponse{}
|
||||
jsonRestHandler.EXPECT().Get(ctx, headBlockHeadersEndpoint, &headBlockHeadersResponse).Return(
|
||||
nil,
|
||||
headBlockHeadersResponse := structs.GetBlockHeaderResponse{}
|
||||
jsonRestHandler.EXPECT().Get(gomock.Any(), headBlockHeadersEndpoint, &headBlockHeadersResponse).Return(
|
||||
nil,
|
||||
).SetArg(
|
||||
2,
|
||||
@@ -924,50 +910,9 @@ func TestGetChainHead(t *testing.T) {
|
||||
HeadEpoch: slots.ToEpoch(8),
|
||||
}
|
||||
|
||||
beaconChainClient := beaconApiBeaconChainClient{jsonRestHandler: jsonRestHandler}
|
||||
chainHead, err := beaconChainClient.GetChainHead(ctx, &emptypb.Empty{})
|
||||
beaconChainClient := beaconApiChainClient{jsonRestHandler: jsonRestHandler}
|
||||
chainHead, err := beaconChainClient.ChainHead(ctx, &emptypb.Empty{})
|
||||
require.NoError(t, err)
|
||||
assert.DeepEqual(t, expectedChainHead, chainHead)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_beaconApiBeaconChainClient_GetValidatorPerformance(t *testing.T) {
|
||||
publicKeys := [][48]byte{
|
||||
bytesutil.ToBytes48([]byte{1}),
|
||||
bytesutil.ToBytes48([]byte{2}),
|
||||
bytesutil.ToBytes48([]byte{3}),
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
|
||||
request, err := json.Marshal(validator.PerformanceRequest{
|
||||
PublicKeys: [][]byte{publicKeys[0][:], publicKeys[2][:], publicKeys[1][:]},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
wantResponse := &validator.PerformanceResponse{}
|
||||
want := ðpb.ValidatorPerformanceResponse{}
|
||||
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
|
||||
jsonRestHandler.EXPECT().Post(
|
||||
ctx,
|
||||
getValidatorPerformanceEndpoint,
|
||||
nil,
|
||||
bytes.NewBuffer(request),
|
||||
wantResponse,
|
||||
).Return(
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
|
||||
c := beaconApiBeaconChainClient{
|
||||
jsonRestHandler: jsonRestHandler,
|
||||
}
|
||||
|
||||
got, err := c.GetValidatorPerformance(ctx, ðpb.ValidatorPerformanceRequest{
|
||||
PublicKeys: [][]byte{publicKeys[0][:], publicKeys[2][:], publicKeys[1][:]},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.DeepEqual(t, want.PublicKeys, got.PublicKeys)
|
||||
}
|
||||
@@ -1,271 +0,0 @@
|
||||
package beacon
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"path"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/pkg/errors"
|
||||
base "github.com/prysmaticlabs/prysm/v4/api/client"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/core/helpers"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/state"
|
||||
"github.com/prysmaticlabs/prysm/v4/consensus-types/interfaces"
|
||||
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
|
||||
"github.com/prysmaticlabs/prysm/v4/encoding/bytesutil"
|
||||
"github.com/prysmaticlabs/prysm/v4/encoding/ssz/detect"
|
||||
"github.com/prysmaticlabs/prysm/v4/io/file"
|
||||
"github.com/prysmaticlabs/prysm/v4/runtime/version"
|
||||
"github.com/prysmaticlabs/prysm/v4/time/slots"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"golang.org/x/mod/semver"
|
||||
)
|
||||
|
||||
var errCheckpointBlockMismatch = errors.New("mismatch between checkpoint sync state and block")
|
||||
|
||||
// OriginData represents the BeaconState and ReadOnlySignedBeaconBlock necessary to start an empty Beacon Node
|
||||
// using Checkpoint Sync.
|
||||
type OriginData struct {
|
||||
sb []byte
|
||||
bb []byte
|
||||
st state.BeaconState
|
||||
b interfaces.ReadOnlySignedBeaconBlock
|
||||
vu *detect.VersionedUnmarshaler
|
||||
br [32]byte
|
||||
sr [32]byte
|
||||
}
|
||||
|
||||
// SaveBlock saves the downloaded block to a unique file in the given path.
|
||||
// For readability and collision avoidance, the file name includes: type, config name, slot and root
|
||||
func (o *OriginData) SaveBlock(dir string) (string, error) {
|
||||
blockPath := path.Join(dir, fname("block", o.vu, o.b.Block().Slot(), o.br))
|
||||
return blockPath, file.WriteFile(blockPath, o.BlockBytes())
|
||||
}
|
||||
|
||||
// SaveState saves the downloaded state to a unique file in the given path.
|
||||
// For readability and collision avoidance, the file name includes: type, config name, slot and root
|
||||
func (o *OriginData) SaveState(dir string) (string, error) {
|
||||
statePath := path.Join(dir, fname("state", o.vu, o.st.Slot(), o.sr))
|
||||
return statePath, file.WriteFile(statePath, o.StateBytes())
|
||||
}
|
||||
|
||||
// StateBytes returns the ssz-encoded bytes of the downloaded BeaconState value.
|
||||
func (o *OriginData) StateBytes() []byte {
|
||||
return o.sb
|
||||
}
|
||||
|
||||
// BlockBytes returns the ssz-encoded bytes of the downloaded ReadOnlySignedBeaconBlock value.
|
||||
func (o *OriginData) BlockBytes() []byte {
|
||||
return o.bb
|
||||
}
|
||||
|
||||
func fname(prefix string, vu *detect.VersionedUnmarshaler, slot primitives.Slot, root [32]byte) string {
|
||||
return fmt.Sprintf("%s_%s_%s_%d-%#x.ssz", prefix, vu.Config.ConfigName, version.String(vu.Fork), slot, root)
|
||||
}
|
||||
|
||||
// DownloadFinalizedData downloads the most recently finalized state, and the block most recently applied to that state.
|
||||
// This pair can be used to initialize a new beacon node via checkpoint sync.
|
||||
func DownloadFinalizedData(ctx context.Context, client *Client) (*OriginData, error) {
|
||||
sb, err := client.GetState(ctx, IdFinalized)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
vu, err := detect.FromState(sb)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "error detecting chain config for finalized state")
|
||||
}
|
||||
log.Printf("detected supported config in remote finalized state, name=%s, fork=%s", vu.Config.ConfigName, version.String(vu.Fork))
|
||||
s, err := vu.UnmarshalBeaconState(sb)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "error unmarshaling finalized state to correct version")
|
||||
}
|
||||
|
||||
slot := s.LatestBlockHeader().Slot
|
||||
bb, err := client.GetBlock(ctx, IdFromSlot(slot))
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "error requesting block by slot = %d", slot)
|
||||
}
|
||||
b, err := vu.UnmarshalBeaconBlock(bb)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "unable to unmarshal block to a supported type using the detected fork schedule")
|
||||
}
|
||||
br, err := b.Block().HashTreeRoot()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "error computing hash_tree_root of retrieved block")
|
||||
}
|
||||
bodyRoot, err := b.Block().Body().HashTreeRoot()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "error computing hash_tree_root of retrieved block body")
|
||||
}
|
||||
|
||||
sbr := bytesutil.ToBytes32(s.LatestBlockHeader().BodyRoot)
|
||||
if sbr != bodyRoot {
|
||||
return nil, errors.Wrapf(errCheckpointBlockMismatch, "state body root = %#x, block body root = %#x", sbr, bodyRoot)
|
||||
}
|
||||
sr, err := s.HashTreeRoot(ctx)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to compute htr for finalized state at slot=%d", s.Slot())
|
||||
}
|
||||
|
||||
log.
|
||||
WithField("block_slot", b.Block().Slot()).
|
||||
WithField("state_slot", s.Slot()).
|
||||
WithField("state_root", hexutil.Encode(sr[:])).
|
||||
WithField("block_root", hexutil.Encode(br[:])).
|
||||
Info("Downloaded checkpoint sync state and block.")
|
||||
return &OriginData{
|
||||
st: s,
|
||||
b: b,
|
||||
sb: sb,
|
||||
bb: bb,
|
||||
vu: vu,
|
||||
br: br,
|
||||
sr: sr,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// WeakSubjectivityData represents the state root, block root and epoch of the BeaconState + ReadOnlySignedBeaconBlock
|
||||
// that falls at the beginning of the current weak subjectivity period. These values can be used to construct
|
||||
// a weak subjectivity checkpoint beacon node flag to be used for validation.
|
||||
type WeakSubjectivityData struct {
|
||||
BlockRoot [32]byte
|
||||
StateRoot [32]byte
|
||||
Epoch primitives.Epoch
|
||||
}
|
||||
|
||||
// CheckpointString returns the standard string representation of a Checkpoint.
|
||||
// The format is a hex-encoded block root, followed by the epoch of the block, separated by a colon. For example:
|
||||
// "0x1c35540cac127315fabb6bf29181f2ae0de1a3fc909d2e76ba771e61312cc49a:74888"
|
||||
func (wsd *WeakSubjectivityData) CheckpointString() string {
|
||||
return fmt.Sprintf("%#x:%d", wsd.BlockRoot, wsd.Epoch)
|
||||
}
|
||||
|
||||
// ComputeWeakSubjectivityCheckpoint attempts to use the prysm weak_subjectivity api
|
||||
// to obtain the current weak_subjectivity checkpoint.
|
||||
// For non-prysm nodes, the same computation will be performed with extra steps,
|
||||
// using the head state downloaded from the beacon node api.
|
||||
func ComputeWeakSubjectivityCheckpoint(ctx context.Context, client *Client) (*WeakSubjectivityData, error) {
|
||||
ws, err := client.GetWeakSubjectivity(ctx)
|
||||
if err != nil {
|
||||
// a 404/405 is expected if querying an endpoint that doesn't support the weak subjectivity checkpoint api
|
||||
if !errors.Is(err, base.ErrNotOK) {
|
||||
return nil, errors.Wrap(err, "unexpected API response for prysm-only weak subjectivity checkpoint API")
|
||||
}
|
||||
// fall back to vanilla Beacon Node API method
|
||||
return computeBackwardsCompatible(ctx, client)
|
||||
}
|
||||
log.Printf("server weak subjectivity checkpoint response - epoch=%d, block_root=%#x, state_root=%#x", ws.Epoch, ws.BlockRoot, ws.StateRoot)
|
||||
return ws, nil
|
||||
}
|
||||
|
||||
const (
|
||||
prysmMinimumVersion = "v2.0.7"
|
||||
prysmImplementationName = "Prysm"
|
||||
)
|
||||
|
||||
// errUnsupportedPrysmCheckpointVersion indicates remote beacon node can't be used for checkpoint retrieval.
|
||||
var errUnsupportedPrysmCheckpointVersion = errors.New("node does not meet minimum version requirements for checkpoint retrieval")
|
||||
|
||||
// for older endpoints or clients that do not support the weak_subjectivity api method
|
||||
// we gather the necessary data for a checkpoint sync by:
|
||||
// - inspecting the remote server's head state and computing the weak subjectivity epoch locally
|
||||
// - requesting the state at the first slot of the epoch
|
||||
// - using hash_tree_root(state.latest_block_header) to compute the block the state integrates
|
||||
// - requesting that block by its root
|
||||
func computeBackwardsCompatible(ctx context.Context, client *Client) (*WeakSubjectivityData, error) {
|
||||
log.Print("falling back to generic checkpoint derivation, weak_subjectivity API not supported by server")
|
||||
nv, err := client.GetNodeVersion(ctx)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "unable to proceed with fallback method without confirming node version")
|
||||
}
|
||||
if nv.implementation == prysmImplementationName && semver.Compare(nv.semver, prysmMinimumVersion) < 0 {
|
||||
return nil, errors.Wrapf(errUnsupportedPrysmCheckpointVersion, "%s < minimum (%s)", nv.semver, prysmMinimumVersion)
|
||||
}
|
||||
epoch, err := getWeakSubjectivityEpochFromHead(ctx, client)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "error computing weak subjectivity epoch via head state inspection")
|
||||
}
|
||||
|
||||
// use first slot of the epoch for the state slot
|
||||
slot, err := slots.EpochStart(epoch)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "error computing first slot of epoch=%d", epoch)
|
||||
}
|
||||
|
||||
log.Printf("requesting checkpoint state at slot %d", slot)
|
||||
// get the state at the first slot of the epoch
|
||||
sb, err := client.GetState(ctx, IdFromSlot(slot))
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to request state by slot from api, slot=%d", slot)
|
||||
}
|
||||
|
||||
// ConfigFork is used to unmarshal the BeaconState so we can read the block root in latest_block_header
|
||||
vu, err := detect.FromState(sb)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "error detecting chain config for beacon state")
|
||||
}
|
||||
log.Printf("detected supported config in checkpoint state, name=%s, fork=%s", vu.Config.ConfigName, version.String(vu.Fork))
|
||||
|
||||
s, err := vu.UnmarshalBeaconState(sb)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "error using detected config fork to unmarshal state bytes")
|
||||
}
|
||||
|
||||
// compute state and block roots
|
||||
sr, err := s.HashTreeRoot(ctx)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "error computing hash_tree_root of state")
|
||||
}
|
||||
|
||||
h := s.LatestBlockHeader()
|
||||
h.StateRoot = sr[:]
|
||||
br, err := h.HashTreeRoot()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "error while computing block root using state data")
|
||||
}
|
||||
|
||||
bb, err := client.GetBlock(ctx, IdFromRoot(br))
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "error requesting block by root = %d", br)
|
||||
}
|
||||
b, err := vu.UnmarshalBeaconBlock(bb)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "unable to unmarshal block to a supported type using the detected fork schedule")
|
||||
}
|
||||
br, err = b.Block().HashTreeRoot()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "error computing hash_tree_root for block obtained via root")
|
||||
}
|
||||
|
||||
return &WeakSubjectivityData{
|
||||
Epoch: epoch,
|
||||
BlockRoot: br,
|
||||
StateRoot: sr,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// this method downloads the head state, which can be used to find the correct chain config
|
||||
// and use prysm's helper methods to compute the latest weak subjectivity epoch.
|
||||
func getWeakSubjectivityEpochFromHead(ctx context.Context, client *Client) (primitives.Epoch, error) {
|
||||
headBytes, err := client.GetState(ctx, IdHead)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
vu, err := detect.FromState(headBytes)
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "error detecting chain config for beacon state")
|
||||
}
|
||||
log.Printf("detected supported config in remote head state, name=%s, fork=%s", vu.Config.ConfigName, version.String(vu.Fork))
|
||||
headState, err := vu.UnmarshalBeaconState(headBytes)
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "error unmarshaling state to correct version")
|
||||
}
|
||||
|
||||
epoch, err := helpers.LatestWeakSubjectivityEpoch(ctx, headState, vu.Config)
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "error computing the weak subjectivity epoch from head state")
|
||||
}
|
||||
|
||||
log.Printf("(computed client-side) weak subjectivity epoch = %d", epoch)
|
||||
return epoch, nil
|
||||
}
|
||||
@@ -11,33 +11,30 @@ import (
|
||||
"regexp"
|
||||
"sort"
|
||||
"strconv"
|
||||
"text/template"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/v4/api/client"
|
||||
"github.com/prysmaticlabs/prysm/v4/api/server"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/beacon"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/config"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/shared"
|
||||
apibeacon "github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/prysm/beacon"
|
||||
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
|
||||
"github.com/prysmaticlabs/prysm/v4/encoding/bytesutil"
|
||||
"github.com/prysmaticlabs/prysm/v4/network/forks"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/client"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/server"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/server/structs"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
"github.com/prysmaticlabs/prysm/v5/encoding/bytesutil"
|
||||
"github.com/prysmaticlabs/prysm/v5/network/forks"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
const (
|
||||
getSignedBlockPath = "/eth/v2/beacon/blocks"
|
||||
getBlockRootPath = "/eth/v1/beacon/blocks/{{.Id}}/root"
|
||||
getForkForStatePath = "/eth/v1/beacon/states/{{.Id}}/fork"
|
||||
getWeakSubjectivityPath = "/prysm/v1/beacon/weak_subjectivity"
|
||||
getForkSchedulePath = "/eth/v1/config/fork_schedule"
|
||||
getConfigSpecPath = "/eth/v1/config/spec"
|
||||
getStatePath = "/eth/v2/debug/beacon/states"
|
||||
getNodeVersionPath = "/eth/v1/node/version"
|
||||
changeBLStoExecutionPath = "/eth/v1/beacon/pool/bls_to_execution_changes"
|
||||
|
||||
GetNodeVersionPath = "/eth/v1/node/version"
|
||||
GetWeakSubjectivityPath = "/prysm/v1/beacon/weak_subjectivity"
|
||||
)
|
||||
|
||||
// StateOrBlockId represents the block_id / state_id parameters that several of the Eth Beacon API methods accept.
|
||||
@@ -66,24 +63,8 @@ func IdFromSlot(s primitives.Slot) StateOrBlockId {
|
||||
return StateOrBlockId(strconv.FormatUint(uint64(s), 10))
|
||||
}
|
||||
|
||||
// idTemplate is used to create template functions that can interpolate StateOrBlockId values.
|
||||
func idTemplate(ts string) func(StateOrBlockId) string {
|
||||
t := template.Must(template.New("").Parse(ts))
|
||||
f := func(id StateOrBlockId) string {
|
||||
b := bytes.NewBuffer(nil)
|
||||
err := t.Execute(b, struct{ Id string }{Id: string(id)})
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("invalid idTemplate: %s", ts))
|
||||
}
|
||||
return b.String()
|
||||
}
|
||||
// run the template to ensure that it is valid
|
||||
// this should happen load time (using package scoped vars) to ensure runtime errors aren't possible
|
||||
_ = f(IdGenesis)
|
||||
return f
|
||||
}
|
||||
|
||||
func renderGetBlockPath(id StateOrBlockId) string {
|
||||
// RenderGetBlockPath formats a block id into a path for the GetBlock API endpoint.
|
||||
func RenderGetBlockPath(id StateOrBlockId) string {
|
||||
return path.Join(getSignedBlockPath, string(id))
|
||||
}
|
||||
|
||||
@@ -107,7 +88,7 @@ func NewClient(host string, opts ...client.ClientOpt) (*Client, error) {
|
||||
// for the named identifiers.
|
||||
// The return value contains the ssz-encoded bytes.
|
||||
func (c *Client) GetBlock(ctx context.Context, blockId StateOrBlockId) ([]byte, error) {
|
||||
blockPath := renderGetBlockPath(blockId)
|
||||
blockPath := RenderGetBlockPath(blockId)
|
||||
b, err := c.Get(ctx, blockPath, client.WithSSZEncoding())
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "error requesting state by id = %s", blockId)
|
||||
@@ -115,8 +96,6 @@ func (c *Client) GetBlock(ctx context.Context, blockId StateOrBlockId) ([]byte,
|
||||
return b, nil
|
||||
}
|
||||
|
||||
var getBlockRootTpl = idTemplate(getBlockRootPath)
|
||||
|
||||
// GetBlockRoot retrieves the hash_tree_root of the BeaconBlock for the given block id.
|
||||
// Block identifier can be one of: "head" (canonical head in node's view), "genesis", "finalized",
|
||||
// <slot>, <hex encoded blockRoot with 0x prefix>. Variables of type StateOrBlockId are exported by this package
|
||||
@@ -139,8 +118,6 @@ func (c *Client) GetBlockRoot(ctx context.Context, blockId StateOrBlockId) ([32]
|
||||
return bytesutil.ToBytes32(rs), nil
|
||||
}
|
||||
|
||||
var getForkTpl = idTemplate(getForkForStatePath)
|
||||
|
||||
// GetFork queries the Beacon Node API for the Fork from the state identified by stateId.
|
||||
// Block identifier can be one of: "head" (canonical head in node's view), "genesis", "finalized",
|
||||
// <slot>, <hex encoded blockRoot with 0x prefix>. Variables of type StateOrBlockId are exported by this package
|
||||
@@ -150,8 +127,8 @@ func (c *Client) GetFork(ctx context.Context, stateId StateOrBlockId) (*ethpb.Fo
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "error requesting fork by state id = %s", stateId)
|
||||
}
|
||||
fr := &shared.Fork{}
|
||||
dataWrapper := &struct{ Data *shared.Fork }{Data: fr}
|
||||
fr := &structs.Fork{}
|
||||
dataWrapper := &struct{ Data *structs.Fork }{Data: fr}
|
||||
err = json.Unmarshal(body, dataWrapper)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "error decoding json response in GetFork")
|
||||
@@ -179,12 +156,12 @@ func (c *Client) GetForkSchedule(ctx context.Context) (forks.OrderedSchedule, er
|
||||
}
|
||||
|
||||
// GetConfigSpec retrieve the current configs of the network used by the beacon node.
|
||||
func (c *Client) GetConfigSpec(ctx context.Context) (*config.GetSpecResponse, error) {
|
||||
func (c *Client) GetConfigSpec(ctx context.Context) (*structs.GetSpecResponse, error) {
|
||||
body, err := c.Get(ctx, getConfigSpecPath)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "error requesting configSpecPath")
|
||||
}
|
||||
fsr := &config.GetSpecResponse{}
|
||||
fsr := &structs.GetSpecResponse{}
|
||||
err = json.Unmarshal(body, fsr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -198,6 +175,10 @@ type NodeVersion struct {
|
||||
systemInfo string
|
||||
}
|
||||
|
||||
func (nv *NodeVersion) SetImplementation(impl string) {
|
||||
nv.implementation = impl
|
||||
}
|
||||
|
||||
var versionRE = regexp.MustCompile(`^(\w+)/(v\d+\.\d+\.\d+[-a-zA-Z0-9]*)\s*/?(.*)$`)
|
||||
|
||||
func parseNodeVersion(v string) (*NodeVersion, error) {
|
||||
@@ -215,7 +196,7 @@ func parseNodeVersion(v string) (*NodeVersion, error) {
|
||||
// GetNodeVersion requests that the beacon node identify information about its implementation in a format
|
||||
// similar to a HTTP User-Agent field. ex: Lighthouse/v0.1.5 (Linux x86_64)
|
||||
func (c *Client) GetNodeVersion(ctx context.Context) (*NodeVersion, error) {
|
||||
b, err := c.Get(ctx, getNodeVersionPath)
|
||||
b, err := c.Get(ctx, GetNodeVersionPath)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "error requesting node version")
|
||||
}
|
||||
@@ -231,7 +212,8 @@ func (c *Client) GetNodeVersion(ctx context.Context) (*NodeVersion, error) {
|
||||
return parseNodeVersion(d.Data.Version)
|
||||
}
|
||||
|
||||
func renderGetStatePath(id StateOrBlockId) string {
|
||||
// RenderGetStatePath formats a state id into a path for the GetState API endpoint.
|
||||
func RenderGetStatePath(id StateOrBlockId) string {
|
||||
return path.Join(getStatePath, string(id))
|
||||
}
|
||||
|
||||
@@ -249,17 +231,33 @@ func (c *Client) GetState(ctx context.Context, stateId StateOrBlockId) ([]byte,
|
||||
return b, nil
|
||||
}
|
||||
|
||||
// WeakSubjectivityData represents the state root, block root and epoch of the BeaconState + ReadOnlySignedBeaconBlock
|
||||
// that falls at the beginning of the current weak subjectivity period. These values can be used to construct
|
||||
// a weak subjectivity checkpoint beacon node flag to be used for validation.
|
||||
type WeakSubjectivityData struct {
|
||||
BlockRoot [32]byte
|
||||
StateRoot [32]byte
|
||||
Epoch primitives.Epoch
|
||||
}
|
||||
|
||||
// CheckpointString returns the standard string representation of a Checkpoint.
|
||||
// The format is a hex-encoded block root, followed by the epoch of the block, separated by a colon. For example:
|
||||
// "0x1c35540cac127315fabb6bf29181f2ae0de1a3fc909d2e76ba771e61312cc49a:74888"
|
||||
func (wsd *WeakSubjectivityData) CheckpointString() string {
|
||||
return fmt.Sprintf("%#x:%d", wsd.BlockRoot, wsd.Epoch)
|
||||
}
|
||||
|
||||
// GetWeakSubjectivity calls a proposed API endpoint that is unique to prysm
|
||||
// This api method does the following:
|
||||
// - computes weak subjectivity epoch
|
||||
// - finds the highest non-skipped block preceding the epoch
|
||||
// - returns the htr of the found block and returns this + the value of state_root from the block
|
||||
func (c *Client) GetWeakSubjectivity(ctx context.Context) (*WeakSubjectivityData, error) {
|
||||
body, err := c.Get(ctx, getWeakSubjectivityPath)
|
||||
body, err := c.Get(ctx, GetWeakSubjectivityPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
v := &apibeacon.GetWeakSubjectivityResponse{}
|
||||
v := &structs.GetWeakSubjectivityResponse{}
|
||||
err = json.Unmarshal(body, v)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -285,7 +283,7 @@ func (c *Client) GetWeakSubjectivity(ctx context.Context) (*WeakSubjectivityData
|
||||
|
||||
// SubmitChangeBLStoExecution calls a beacon API endpoint to set the withdrawal addresses based on the given signed messages.
|
||||
// If the API responds with something other than OK there will be failure messages associated to the corresponding request message.
|
||||
func (c *Client) SubmitChangeBLStoExecution(ctx context.Context, request []*shared.SignedBLSToExecutionChange) error {
|
||||
func (c *Client) SubmitChangeBLStoExecution(ctx context.Context, request []*structs.SignedBLSToExecutionChange) error {
|
||||
u := c.BaseURL().ResolveReference(&url.URL{Path: changeBLStoExecutionPath})
|
||||
body, err := json.Marshal(request)
|
||||
if err != nil {
|
||||
@@ -312,9 +310,9 @@ func (c *Client) SubmitChangeBLStoExecution(ctx context.Context, request []*shar
|
||||
}
|
||||
for _, failure := range errorJson.Failures {
|
||||
w := request[failure.Index].Message
|
||||
log.WithFields(log.Fields{
|
||||
"validator_index": w.ValidatorIndex,
|
||||
"withdrawal_address": w.ToExecutionAddress,
|
||||
log.WithFields(logrus.Fields{
|
||||
"validatorIndex": w.ValidatorIndex,
|
||||
"withdrawalAddress": w.ToExecutionAddress,
|
||||
}).Error(failure.Message)
|
||||
}
|
||||
return errors.Errorf("POST error %d: %s", errorJson.Code, errorJson.Message)
|
||||
@@ -324,12 +322,12 @@ func (c *Client) SubmitChangeBLStoExecution(ctx context.Context, request []*shar
|
||||
|
||||
// GetBLStoExecutionChanges gets all the set withdrawal messages in the node's operation pool.
|
||||
// Returns a struct representation of json response.
|
||||
func (c *Client) GetBLStoExecutionChanges(ctx context.Context) (*beacon.BLSToExecutionChangesPoolResponse, error) {
|
||||
func (c *Client) GetBLStoExecutionChanges(ctx context.Context) (*structs.BLSToExecutionChangesPoolResponse, error) {
|
||||
body, err := c.Get(ctx, changeBLStoExecutionPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
poolResponse := &beacon.BLSToExecutionChangesPoolResponse{}
|
||||
poolResponse := &structs.BLSToExecutionChangesPoolResponse{}
|
||||
err = json.Unmarshal(body, poolResponse)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -338,15 +336,15 @@ func (c *Client) GetBLStoExecutionChanges(ctx context.Context) (*beacon.BLSToExe
|
||||
}
|
||||
|
||||
type forkScheduleResponse struct {
|
||||
Data []shared.Fork
|
||||
Data []structs.Fork
|
||||
}
|
||||
|
||||
func (fsr *forkScheduleResponse) OrderedForkSchedule() (forks.OrderedSchedule, error) {
|
||||
ofs := make(forks.OrderedSchedule, 0)
|
||||
for _, d := range fsr.Data {
|
||||
epoch, err := strconv.Atoi(d.Epoch)
|
||||
epoch, err := strconv.ParseUint(d.Epoch, 10, 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.Wrapf(err, "error parsing epoch %s", d.Epoch)
|
||||
}
|
||||
vSlice, err := hexutil.Decode(d.CurrentVersion)
|
||||
if err != nil {
|
||||
@@ -358,7 +356,7 @@ func (fsr *forkScheduleResponse) OrderedForkSchedule() (forks.OrderedSchedule, e
|
||||
version := bytesutil.ToBytes4(vSlice)
|
||||
ofs = append(ofs, forks.ForkScheduleEntry{
|
||||
Version: version,
|
||||
Epoch: primitives.Epoch(uint64(epoch)),
|
||||
Epoch: primitives.Epoch(epoch),
|
||||
})
|
||||
}
|
||||
sort.Sort(ofs)
|
||||
|
||||
@@ -4,8 +4,8 @@ import (
|
||||
"net/url"
|
||||
"testing"
|
||||
|
||||
"github.com/prysmaticlabs/prysm/v4/api/client"
|
||||
"github.com/prysmaticlabs/prysm/v4/testing/require"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/client"
|
||||
"github.com/prysmaticlabs/prysm/v5/testing/require"
|
||||
)
|
||||
|
||||
func TestParseNodeVersion(t *testing.T) {
|
||||
@@ -97,31 +97,31 @@ func TestValidHostname(t *testing.T) {
|
||||
{
|
||||
name: "hostname with port",
|
||||
hostArg: "mydomain.org:3500",
|
||||
path: getNodeVersionPath,
|
||||
path: GetNodeVersionPath,
|
||||
joined: "http://mydomain.org:3500/eth/v1/node/version",
|
||||
},
|
||||
{
|
||||
name: "https scheme, hostname with port",
|
||||
hostArg: "https://mydomain.org:3500",
|
||||
path: getNodeVersionPath,
|
||||
path: GetNodeVersionPath,
|
||||
joined: "https://mydomain.org:3500/eth/v1/node/version",
|
||||
},
|
||||
{
|
||||
name: "http scheme, hostname without port",
|
||||
hostArg: "http://mydomain.org",
|
||||
path: getNodeVersionPath,
|
||||
path: GetNodeVersionPath,
|
||||
joined: "http://mydomain.org/eth/v1/node/version",
|
||||
},
|
||||
{
|
||||
name: "http scheme, trailing slash, hostname without port",
|
||||
hostArg: "http://mydomain.org/",
|
||||
path: getNodeVersionPath,
|
||||
path: GetNodeVersionPath,
|
||||
joined: "http://mydomain.org/eth/v1/node/version",
|
||||
},
|
||||
{
|
||||
name: "http scheme, hostname with basic auth creds and no port",
|
||||
hostArg: "http://username:pass@mydomain.org/",
|
||||
path: getNodeVersionPath,
|
||||
path: GetNodeVersionPath,
|
||||
joined: "http://username:pass@mydomain.org/eth/v1/node/version",
|
||||
},
|
||||
}
|
||||
|
||||
20
api/client/beacon/health/BUILD.bazel
Normal file
20
api/client/beacon/health/BUILD.bazel
Normal file
@@ -0,0 +1,20 @@
|
||||
load("@prysm//tools/go:def.bzl", "go_library", "go_test")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"health_mock.go",
|
||||
"interfaces.go",
|
||||
"tracker.go",
|
||||
],
|
||||
importpath = "github.com/prysmaticlabs/prysm/v5/api/client/beacon/health",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = ["@org_uber_go_mock//gomock:go_default_library"],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["tracker_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
deps = ["@org_uber_go_mock//gomock:go_default_library"],
|
||||
)
|
||||
65
api/client/beacon/health/health_mock.go
generated
Normal file
65
api/client/beacon/health/health_mock.go
generated
Normal file
@@ -0,0 +1,65 @@
|
||||
package health
|
||||
|
||||
import (
|
||||
"context"
|
||||
"reflect"
|
||||
"sync"
|
||||
|
||||
"go.uber.org/mock/gomock"
|
||||
)
|
||||
|
||||
// NewMockHealthClient creates a new mock instance.
|
||||
func NewMockHealthClient(ctrl *gomock.Controller) *MockHealthClient {
|
||||
mock := &MockHealthClient{ctrl: ctrl}
|
||||
mock.recorder = &MockHealthClientMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// MockHealthClient is a mock of HealthClient interface.
|
||||
type MockHealthClient struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockHealthClientMockRecorder
|
||||
Health bool
|
||||
sync.Mutex
|
||||
}
|
||||
|
||||
// MockHealthClientMockRecorder is the mock recorder for MockHealthClient.
|
||||
type MockHealthClientMockRecorder struct {
|
||||
mock *MockHealthClient
|
||||
}
|
||||
|
||||
// IsHealthy mocks base method.
|
||||
func (m *MockHealthClient) IsHealthy(arg0 context.Context) bool {
|
||||
m.Lock()
|
||||
defer m.Unlock()
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "IsHealthy", arg0)
|
||||
ret0, ok := ret[0].(bool)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
return ret0
|
||||
}
|
||||
|
||||
func (m *MockHealthClient) HealthUpdates() <-chan bool {
|
||||
ch := make(chan bool, 2)
|
||||
ch <- m.Health
|
||||
return ch
|
||||
}
|
||||
|
||||
func (m *MockHealthClient) CheckHealth(_ context.Context) bool {
|
||||
return m.Health
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||
func (m *MockHealthClient) EXPECT() *MockHealthClientMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// IsHealthy indicates an expected call of IsHealthy.
|
||||
func (mr *MockHealthClientMockRecorder) IsHealthy(arg0 any) *gomock.Call {
|
||||
mr.mock.Lock()
|
||||
defer mr.mock.Unlock()
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsHealthy", reflect.TypeOf((*MockHealthClient)(nil).IsHealthy), arg0)
|
||||
}
|
||||
13
api/client/beacon/health/interfaces.go
Normal file
13
api/client/beacon/health/interfaces.go
Normal file
@@ -0,0 +1,13 @@
|
||||
package health
|
||||
|
||||
import "context"
|
||||
|
||||
type HealthTracker interface {
|
||||
HealthUpdates() <-chan bool
|
||||
IsHealthy(ctx context.Context) bool
|
||||
CheckHealth(ctx context.Context) bool
|
||||
}
|
||||
|
||||
type HealthNode interface {
|
||||
IsHealthy(ctx context.Context) bool
|
||||
}
|
||||
58
api/client/beacon/health/tracker.go
Normal file
58
api/client/beacon/health/tracker.go
Normal file
@@ -0,0 +1,58 @@
|
||||
package health
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type healthTracker struct {
|
||||
isHealthy *bool
|
||||
healthChan chan bool
|
||||
node HealthNode
|
||||
sync.RWMutex
|
||||
}
|
||||
|
||||
func NewTracker(node HealthNode) HealthTracker {
|
||||
return &healthTracker{
|
||||
node: node,
|
||||
healthChan: make(chan bool, 1),
|
||||
}
|
||||
}
|
||||
|
||||
// HealthUpdates provides a read-only channel for health updates.
|
||||
func (n *healthTracker) HealthUpdates() <-chan bool {
|
||||
return n.healthChan
|
||||
}
|
||||
|
||||
func (n *healthTracker) IsHealthy(_ context.Context) bool {
|
||||
n.RLock()
|
||||
defer n.RUnlock()
|
||||
if n.isHealthy == nil {
|
||||
return false
|
||||
}
|
||||
return *n.isHealthy
|
||||
}
|
||||
|
||||
func (n *healthTracker) CheckHealth(ctx context.Context) bool {
|
||||
n.Lock()
|
||||
defer n.Unlock()
|
||||
|
||||
newStatus := n.node.IsHealthy(ctx)
|
||||
if n.isHealthy == nil {
|
||||
n.isHealthy = &newStatus
|
||||
}
|
||||
|
||||
isStatusChanged := newStatus != *n.isHealthy
|
||||
if isStatusChanged {
|
||||
// Update the health status
|
||||
n.isHealthy = &newStatus
|
||||
// Send the new status to the health channel, potentially overwriting the existing value
|
||||
select {
|
||||
case <-n.healthChan:
|
||||
n.healthChan <- newStatus
|
||||
default:
|
||||
n.healthChan <- newStatus
|
||||
}
|
||||
}
|
||||
return newStatus
|
||||
}
|
||||
115
api/client/beacon/health/tracker_test.go
Normal file
115
api/client/beacon/health/tracker_test.go
Normal file
@@ -0,0 +1,115 @@
|
||||
package health
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
"testing"
|
||||
|
||||
"go.uber.org/mock/gomock"
|
||||
)
|
||||
|
||||
var (
|
||||
_ = HealthTracker(&MockHealthClient{})
|
||||
)
|
||||
|
||||
func TestNodeHealth_IsHealthy(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
isHealthy bool
|
||||
want bool
|
||||
}{
|
||||
{"initially healthy", true, true},
|
||||
{"initially unhealthy", false, false},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
n := &healthTracker{
|
||||
isHealthy: &tt.isHealthy,
|
||||
healthChan: make(chan bool, 1),
|
||||
}
|
||||
if got := n.IsHealthy(context.Background()); got != tt.want {
|
||||
t.Errorf("IsHealthy() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestNodeHealth_UpdateNodeHealth(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
initial bool // Initial health status
|
||||
newStatus bool // Status to update to
|
||||
shouldSend bool // Should a message be sent through the channel
|
||||
}{
|
||||
{"healthy to unhealthy", true, false, true},
|
||||
{"unhealthy to healthy", false, true, true},
|
||||
{"remain healthy", true, true, false},
|
||||
{"remain unhealthy", false, false, false},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
client := NewMockHealthClient(ctrl)
|
||||
client.EXPECT().IsHealthy(gomock.Any()).Return(tt.newStatus)
|
||||
n := &healthTracker{
|
||||
isHealthy: &tt.initial,
|
||||
node: client,
|
||||
healthChan: make(chan bool, 1),
|
||||
}
|
||||
|
||||
s := n.CheckHealth(context.Background())
|
||||
// Check if health status was updated
|
||||
if s != tt.newStatus {
|
||||
t.Errorf("UpdateNodeHealth() failed to update isHealthy from %v to %v", tt.initial, tt.newStatus)
|
||||
}
|
||||
|
||||
select {
|
||||
case status := <-n.HealthUpdates():
|
||||
if !tt.shouldSend {
|
||||
t.Errorf("UpdateNodeHealth() unexpectedly sent status %v to HealthCh", status)
|
||||
} else if status != tt.newStatus {
|
||||
t.Errorf("UpdateNodeHealth() sent wrong status %v, want %v", status, tt.newStatus)
|
||||
}
|
||||
default:
|
||||
if tt.shouldSend {
|
||||
t.Error("UpdateNodeHealth() did not send any status to HealthCh when expected")
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestNodeHealth_Concurrency(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
client := NewMockHealthClient(ctrl)
|
||||
n := NewTracker(client)
|
||||
var wg sync.WaitGroup
|
||||
|
||||
// Number of goroutines to spawn for both reading and writing
|
||||
numGoroutines := 6
|
||||
|
||||
wg.Add(numGoroutines * 2) // for readers and writers
|
||||
|
||||
// Concurrently update health status
|
||||
for i := 0; i < numGoroutines; i++ {
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
client.EXPECT().IsHealthy(gomock.Any()).Return(false).Times(1)
|
||||
n.CheckHealth(context.Background())
|
||||
client.EXPECT().IsHealthy(gomock.Any()).Return(true).Times(1)
|
||||
n.CheckHealth(context.Background())
|
||||
}()
|
||||
}
|
||||
|
||||
// Concurrently read health status
|
||||
for i := 0; i < numGoroutines; i++ {
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
_ = n.IsHealthy(context.Background()) // Just read the value
|
||||
}()
|
||||
}
|
||||
|
||||
wg.Wait() // Wait for all goroutines to finish
|
||||
}
|
||||
5
api/client/beacon/log.go
Normal file
5
api/client/beacon/log.go
Normal file
@@ -0,0 +1,5 @@
|
||||
package beacon
|
||||
|
||||
import "github.com/sirupsen/logrus"
|
||||
|
||||
var log = logrus.WithField("prefix", "beacon")
|
||||
29
api/client/beacon/mock/BUILD.bazel
Normal file
29
api/client/beacon/mock/BUILD.bazel
Normal file
@@ -0,0 +1,29 @@
|
||||
load("@prysm//tools/go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"beacon_block_converter_mock.go",
|
||||
"chain_client_mock.go",
|
||||
"duties_mock.go",
|
||||
"genesis_mock.go",
|
||||
"json_rest_handler_mock.go",
|
||||
"node_client_mock.go",
|
||||
"prysm_chain_client_mock.go",
|
||||
"state_validators_mock.go",
|
||||
"validator_client_mock.go",
|
||||
],
|
||||
importpath = "github.com/prysmaticlabs/prysm/v5/api/client/beacon/mock",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//api/client/beacon:go_default_library",
|
||||
"//api/client/beacon/health:go_default_library",
|
||||
"//api/client/event:go_default_library",
|
||||
"//api/server/structs:go_default_library",
|
||||
"//consensus-types/primitives:go_default_library",
|
||||
"//consensus-types/validator:go_default_library",
|
||||
"//proto/prysm/v1alpha1:go_default_library",
|
||||
"@org_golang_google_protobuf//types/known/emptypb:go_default_library",
|
||||
"@org_uber_go_mock//gomock:go_default_library",
|
||||
],
|
||||
)
|
||||
@@ -1,5 +1,10 @@
|
||||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: github.com/prysmaticlabs/prysm/v4/validator/client/beacon-api (interfaces: BeaconBlockConverter)
|
||||
// Source: validator/client/beacon-api/beacon_block_converter.go
|
||||
//
|
||||
// Generated by this command:
|
||||
//
|
||||
// mockgen -package=mock -source=validator/client/beacon-api/beacon_block_converter.go -destination=validator/client/beacon-api/mock/beacon_block_converter_mock.go
|
||||
//
|
||||
|
||||
// Package mock is a generated GoMock package.
|
||||
package mock
|
||||
@@ -7,9 +12,9 @@ package mock
|
||||
import (
|
||||
reflect "reflect"
|
||||
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
shared "github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/shared"
|
||||
eth "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
|
||||
structs "github.com/prysmaticlabs/prysm/v5/api/server/structs"
|
||||
eth "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
gomock "go.uber.org/mock/gomock"
|
||||
)
|
||||
|
||||
// MockBeaconBlockConverter is a mock of BeaconBlockConverter interface.
|
||||
@@ -36,61 +41,61 @@ func (m *MockBeaconBlockConverter) EXPECT() *MockBeaconBlockConverterMockRecorde
|
||||
}
|
||||
|
||||
// ConvertRESTAltairBlockToProto mocks base method.
|
||||
func (m *MockBeaconBlockConverter) ConvertRESTAltairBlockToProto(arg0 *shared.BeaconBlockAltair) (*eth.BeaconBlockAltair, error) {
|
||||
func (m *MockBeaconBlockConverter) ConvertRESTAltairBlockToProto(block *structs.BeaconBlockAltair) (*eth.BeaconBlockAltair, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "ConvertRESTAltairBlockToProto", arg0)
|
||||
ret := m.ctrl.Call(m, "ConvertRESTAltairBlockToProto", block)
|
||||
ret0, _ := ret[0].(*eth.BeaconBlockAltair)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// ConvertRESTAltairBlockToProto indicates an expected call of ConvertRESTAltairBlockToProto.
|
||||
func (mr *MockBeaconBlockConverterMockRecorder) ConvertRESTAltairBlockToProto(arg0 interface{}) *gomock.Call {
|
||||
func (mr *MockBeaconBlockConverterMockRecorder) ConvertRESTAltairBlockToProto(block any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ConvertRESTAltairBlockToProto", reflect.TypeOf((*MockBeaconBlockConverter)(nil).ConvertRESTAltairBlockToProto), arg0)
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ConvertRESTAltairBlockToProto", reflect.TypeOf((*MockBeaconBlockConverter)(nil).ConvertRESTAltairBlockToProto), block)
|
||||
}
|
||||
|
||||
// ConvertRESTBellatrixBlockToProto mocks base method.
|
||||
func (m *MockBeaconBlockConverter) ConvertRESTBellatrixBlockToProto(arg0 *shared.BeaconBlockBellatrix) (*eth.BeaconBlockBellatrix, error) {
|
||||
func (m *MockBeaconBlockConverter) ConvertRESTBellatrixBlockToProto(block *structs.BeaconBlockBellatrix) (*eth.BeaconBlockBellatrix, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "ConvertRESTBellatrixBlockToProto", arg0)
|
||||
ret := m.ctrl.Call(m, "ConvertRESTBellatrixBlockToProto", block)
|
||||
ret0, _ := ret[0].(*eth.BeaconBlockBellatrix)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// ConvertRESTBellatrixBlockToProto indicates an expected call of ConvertRESTBellatrixBlockToProto.
|
||||
func (mr *MockBeaconBlockConverterMockRecorder) ConvertRESTBellatrixBlockToProto(arg0 interface{}) *gomock.Call {
|
||||
func (mr *MockBeaconBlockConverterMockRecorder) ConvertRESTBellatrixBlockToProto(block any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ConvertRESTBellatrixBlockToProto", reflect.TypeOf((*MockBeaconBlockConverter)(nil).ConvertRESTBellatrixBlockToProto), arg0)
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ConvertRESTBellatrixBlockToProto", reflect.TypeOf((*MockBeaconBlockConverter)(nil).ConvertRESTBellatrixBlockToProto), block)
|
||||
}
|
||||
|
||||
// ConvertRESTCapellaBlockToProto mocks base method.
|
||||
func (m *MockBeaconBlockConverter) ConvertRESTCapellaBlockToProto(arg0 *shared.BeaconBlockCapella) (*eth.BeaconBlockCapella, error) {
|
||||
func (m *MockBeaconBlockConverter) ConvertRESTCapellaBlockToProto(block *structs.BeaconBlockCapella) (*eth.BeaconBlockCapella, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "ConvertRESTCapellaBlockToProto", arg0)
|
||||
ret := m.ctrl.Call(m, "ConvertRESTCapellaBlockToProto", block)
|
||||
ret0, _ := ret[0].(*eth.BeaconBlockCapella)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// ConvertRESTCapellaBlockToProto indicates an expected call of ConvertRESTCapellaBlockToProto.
|
||||
func (mr *MockBeaconBlockConverterMockRecorder) ConvertRESTCapellaBlockToProto(arg0 interface{}) *gomock.Call {
|
||||
func (mr *MockBeaconBlockConverterMockRecorder) ConvertRESTCapellaBlockToProto(block any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ConvertRESTCapellaBlockToProto", reflect.TypeOf((*MockBeaconBlockConverter)(nil).ConvertRESTCapellaBlockToProto), arg0)
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ConvertRESTCapellaBlockToProto", reflect.TypeOf((*MockBeaconBlockConverter)(nil).ConvertRESTCapellaBlockToProto), block)
|
||||
}
|
||||
|
||||
// ConvertRESTPhase0BlockToProto mocks base method.
|
||||
func (m *MockBeaconBlockConverter) ConvertRESTPhase0BlockToProto(arg0 *shared.BeaconBlock) (*eth.BeaconBlock, error) {
|
||||
func (m *MockBeaconBlockConverter) ConvertRESTPhase0BlockToProto(block *structs.BeaconBlock) (*eth.BeaconBlock, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "ConvertRESTPhase0BlockToProto", arg0)
|
||||
ret := m.ctrl.Call(m, "ConvertRESTPhase0BlockToProto", block)
|
||||
ret0, _ := ret[0].(*eth.BeaconBlock)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// ConvertRESTPhase0BlockToProto indicates an expected call of ConvertRESTPhase0BlockToProto.
|
||||
func (mr *MockBeaconBlockConverterMockRecorder) ConvertRESTPhase0BlockToProto(arg0 interface{}) *gomock.Call {
|
||||
func (mr *MockBeaconBlockConverterMockRecorder) ConvertRESTPhase0BlockToProto(block any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ConvertRESTPhase0BlockToProto", reflect.TypeOf((*MockBeaconBlockConverter)(nil).ConvertRESTPhase0BlockToProto), arg0)
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ConvertRESTPhase0BlockToProto", reflect.TypeOf((*MockBeaconBlockConverter)(nil).ConvertRESTPhase0BlockToProto), block)
|
||||
}
|
||||
132
api/client/beacon/mock/chain_client_mock.go
generated
Normal file
132
api/client/beacon/mock/chain_client_mock.go
generated
Normal file
@@ -0,0 +1,132 @@
|
||||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: github.com/prysmaticlabs/prysm/v5/validator/client/iface (interfaces: ChainClient)
|
||||
//
|
||||
// Generated by this command:
|
||||
//
|
||||
// mockgen -package=validator_mock -destination=testing/validator-mock/chain_client_mock.go github.com/prysmaticlabs/prysm/v5/validator/client/iface ChainClient
|
||||
//
|
||||
|
||||
// Package validator_mock is a generated GoMock package.
|
||||
package mock
|
||||
|
||||
import (
|
||||
context "context"
|
||||
reflect "reflect"
|
||||
|
||||
eth "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
gomock "go.uber.org/mock/gomock"
|
||||
emptypb "google.golang.org/protobuf/types/known/emptypb"
|
||||
)
|
||||
|
||||
// MockChainClient is a mock of ChainClient interface.
|
||||
type MockChainClient struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockChainClientMockRecorder
|
||||
}
|
||||
|
||||
// MockChainClientMockRecorder is the mock recorder for MockChainClient.
|
||||
type MockChainClientMockRecorder struct {
|
||||
mock *MockChainClient
|
||||
}
|
||||
|
||||
// NewMockChainClient creates a new mock instance.
|
||||
func NewMockChainClient(ctrl *gomock.Controller) *MockChainClient {
|
||||
mock := &MockChainClient{ctrl: ctrl}
|
||||
mock.recorder = &MockChainClientMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||
func (m *MockChainClient) EXPECT() *MockChainClientMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// ChainHead mocks base method.
|
||||
func (m *MockChainClient) ChainHead(arg0 context.Context, arg1 *emptypb.Empty) (*eth.ChainHead, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "ChainHead", arg0, arg1)
|
||||
ret0, _ := ret[0].(*eth.ChainHead)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// ChainHead indicates an expected call of ChainHead.
|
||||
func (mr *MockChainClientMockRecorder) ChainHead(arg0, arg1 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainHead", reflect.TypeOf((*MockChainClient)(nil).ChainHead), arg0, arg1)
|
||||
}
|
||||
|
||||
// ValidatorBalances mocks base method.
|
||||
func (m *MockChainClient) ValidatorBalances(arg0 context.Context, arg1 *eth.ListValidatorBalancesRequest) (*eth.ValidatorBalances, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "ValidatorBalances", arg0, arg1)
|
||||
ret0, _ := ret[0].(*eth.ValidatorBalances)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// ValidatorBalances indicates an expected call of ValidatorBalances.
|
||||
func (mr *MockChainClientMockRecorder) ValidatorBalances(arg0, arg1 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ValidatorBalances", reflect.TypeOf((*MockChainClient)(nil).ValidatorBalances), arg0, arg1)
|
||||
}
|
||||
|
||||
// ValidatorParticipation mocks base method.
|
||||
func (m *MockChainClient) ValidatorParticipation(arg0 context.Context, arg1 *eth.GetValidatorParticipationRequest) (*eth.ValidatorParticipationResponse, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "ValidatorParticipation", arg0, arg1)
|
||||
ret0, _ := ret[0].(*eth.ValidatorParticipationResponse)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// ValidatorParticipation indicates an expected call of ValidatorParticipation.
|
||||
func (mr *MockChainClientMockRecorder) ValidatorParticipation(arg0, arg1 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ValidatorParticipation", reflect.TypeOf((*MockChainClient)(nil).ValidatorParticipation), arg0, arg1)
|
||||
}
|
||||
|
||||
// ValidatorPerformance mocks base method.
|
||||
func (m *MockChainClient) ValidatorPerformance(arg0 context.Context, arg1 *eth.ValidatorPerformanceRequest) (*eth.ValidatorPerformanceResponse, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "ValidatorPerformance", arg0, arg1)
|
||||
ret0, _ := ret[0].(*eth.ValidatorPerformanceResponse)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// ValidatorPerformance indicates an expected call of ValidatorPerformance.
|
||||
func (mr *MockChainClientMockRecorder) ValidatorPerformance(arg0, arg1 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ValidatorPerformance", reflect.TypeOf((*MockChainClient)(nil).ValidatorPerformance), arg0, arg1)
|
||||
}
|
||||
|
||||
// ValidatorQueue mocks base method.
|
||||
func (m *MockChainClient) ValidatorQueue(arg0 context.Context, arg1 *emptypb.Empty) (*eth.ValidatorQueue, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "ValidatorQueue", arg0, arg1)
|
||||
ret0, _ := ret[0].(*eth.ValidatorQueue)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// ValidatorQueue indicates an expected call of ValidatorQueue.
|
||||
func (mr *MockChainClientMockRecorder) ValidatorQueue(arg0, arg1 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ValidatorQueue", reflect.TypeOf((*MockChainClient)(nil).ValidatorQueue), arg0, arg1)
|
||||
}
|
||||
|
||||
// Validators mocks base method.
|
||||
func (m *MockChainClient) Validators(arg0 context.Context, arg1 *eth.ListValidatorsRequest) (*eth.Validators, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Validators", arg0, arg1)
|
||||
ret0, _ := ret[0].(*eth.Validators)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// Validators indicates an expected call of Validators.
|
||||
func (mr *MockChainClientMockRecorder) Validators(arg0, arg1 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Validators", reflect.TypeOf((*MockChainClient)(nil).Validators), arg0, arg1)
|
||||
}
|
||||
102
api/client/beacon/mock/duties_mock.go
generated
Normal file
102
api/client/beacon/mock/duties_mock.go
generated
Normal file
@@ -0,0 +1,102 @@
|
||||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: validator/client/beacon-api/duties.go
|
||||
//
|
||||
// Generated by this command:
|
||||
//
|
||||
// mockgen -package=mock -source=validator/client/beacon-api/duties.go -destination=validator/client/beacon-api/mock/duties_mock.go
|
||||
//
|
||||
|
||||
// Package mock is a generated GoMock package.
|
||||
package mock
|
||||
|
||||
import (
|
||||
context "context"
|
||||
reflect "reflect"
|
||||
|
||||
structs "github.com/prysmaticlabs/prysm/v5/api/server/structs"
|
||||
primitives "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
gomock "go.uber.org/mock/gomock"
|
||||
)
|
||||
|
||||
// MockdutiesProvider is a mock of dutiesProvider interface.
|
||||
type MockdutiesProvider struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockdutiesProviderMockRecorder
|
||||
}
|
||||
|
||||
// MockdutiesProviderMockRecorder is the mock recorder for MockdutiesProvider.
|
||||
type MockdutiesProviderMockRecorder struct {
|
||||
mock *MockdutiesProvider
|
||||
}
|
||||
|
||||
// NewMockdutiesProvider creates a new mock instance.
|
||||
func NewMockdutiesProvider(ctrl *gomock.Controller) *MockdutiesProvider {
|
||||
mock := &MockdutiesProvider{ctrl: ctrl}
|
||||
mock.recorder = &MockdutiesProviderMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||
func (m *MockdutiesProvider) EXPECT() *MockdutiesProviderMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// AttesterDuties mocks base method.
|
||||
func (m *MockdutiesProvider) AttesterDuties(ctx context.Context, epoch primitives.Epoch, validatorIndices []primitives.ValidatorIndex) ([]*structs.AttesterDuty, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "AttesterDuties", ctx, epoch, validatorIndices)
|
||||
ret0, _ := ret[0].([]*structs.AttesterDuty)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// AttesterDuties indicates an expected call of AttesterDuties.
|
||||
func (mr *MockdutiesProviderMockRecorder) AttesterDuties(ctx, epoch, validatorIndices any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AttesterDuties", reflect.TypeOf((*MockdutiesProvider)(nil).AttesterDuties), ctx, epoch, validatorIndices)
|
||||
}
|
||||
|
||||
// Committees mocks base method.
|
||||
func (m *MockdutiesProvider) Committees(ctx context.Context, epoch primitives.Epoch) ([]*structs.Committee, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Committees", ctx, epoch)
|
||||
ret0, _ := ret[0].([]*structs.Committee)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// Committees indicates an expected call of Committees.
|
||||
func (mr *MockdutiesProviderMockRecorder) Committees(ctx, epoch any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Committees", reflect.TypeOf((*MockdutiesProvider)(nil).Committees), ctx, epoch)
|
||||
}
|
||||
|
||||
// ProposerDuties mocks base method.
|
||||
func (m *MockdutiesProvider) ProposerDuties(ctx context.Context, epoch primitives.Epoch) ([]*structs.ProposerDuty, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "ProposerDuties", ctx, epoch)
|
||||
ret0, _ := ret[0].([]*structs.ProposerDuty)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// ProposerDuties indicates an expected call of ProposerDuties.
|
||||
func (mr *MockdutiesProviderMockRecorder) ProposerDuties(ctx, epoch any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ProposerDuties", reflect.TypeOf((*MockdutiesProvider)(nil).ProposerDuties), ctx, epoch)
|
||||
}
|
||||
|
||||
// SyncDuties mocks base method.
|
||||
func (m *MockdutiesProvider) SyncDuties(ctx context.Context, epoch primitives.Epoch, validatorIndices []primitives.ValidatorIndex) ([]*structs.SyncCommitteeDuty, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "SyncDuties", ctx, epoch, validatorIndices)
|
||||
ret0, _ := ret[0].([]*structs.SyncCommitteeDuty)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// SyncDuties indicates an expected call of SyncDuties.
|
||||
func (mr *MockdutiesProviderMockRecorder) SyncDuties(ctx, epoch, validatorIndices any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SyncDuties", reflect.TypeOf((*MockdutiesProvider)(nil).SyncDuties), ctx, epoch, validatorIndices)
|
||||
}
|
||||
@@ -1,5 +1,10 @@
|
||||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: github.com/prysmaticlabs/prysm/v4/validator/client/beacon-api (interfaces: GenesisProvider)
|
||||
// Source: validator/client/beacon-api/genesis.go
|
||||
//
|
||||
// Generated by this command:
|
||||
//
|
||||
// mockgen -package=mock -source=validator/client/beacon-api/genesis.go -destination=validator/client/beacon-api/mock/genesis_mock.go
|
||||
//
|
||||
|
||||
// Package mock is a generated GoMock package.
|
||||
package mock
|
||||
@@ -8,9 +13,8 @@ import (
|
||||
context "context"
|
||||
reflect "reflect"
|
||||
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
beacon "github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/beacon"
|
||||
httputil "github.com/prysmaticlabs/prysm/v4/network/httputil"
|
||||
structs "github.com/prysmaticlabs/prysm/v5/api/server/structs"
|
||||
gomock "go.uber.org/mock/gomock"
|
||||
)
|
||||
|
||||
// MockGenesisProvider is a mock of GenesisProvider interface.
|
||||
@@ -36,18 +40,17 @@ func (m *MockGenesisProvider) EXPECT() *MockGenesisProviderMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// GetGenesis mocks base method.
|
||||
func (m *MockGenesisProvider) GetGenesis(arg0 context.Context) (*beacon.Genesis, *httputil.DefaultErrorJson, error) {
|
||||
// Genesis mocks base method.
|
||||
func (m *MockGenesisProvider) Genesis(ctx context.Context) (*structs.Genesis, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetGenesis", arg0)
|
||||
ret0, _ := ret[0].(*beacon.Genesis)
|
||||
ret1, _ := ret[1].(*httputil.DefaultErrorJson)
|
||||
ret2, _ := ret[2].(error)
|
||||
return ret0, ret1, ret2
|
||||
ret := m.ctrl.Call(m, "Genesis", ctx)
|
||||
ret0, _ := ret[0].(*structs.Genesis)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// GetGenesis indicates an expected call of GetGenesis.
|
||||
func (mr *MockGenesisProviderMockRecorder) GetGenesis(arg0 interface{}) *gomock.Call {
|
||||
// Genesis indicates an expected call of Genesis.
|
||||
func (mr *MockGenesisProviderMockRecorder) Genesis(ctx any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetGenesis", reflect.TypeOf((*MockGenesisProvider)(nil).GetGenesis), arg0)
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Genesis", reflect.TypeOf((*MockGenesisProvider)(nil).Genesis), ctx)
|
||||
}
|
||||
110
api/client/beacon/mock/json_rest_handler_mock.go
generated
Normal file
110
api/client/beacon/mock/json_rest_handler_mock.go
generated
Normal file
@@ -0,0 +1,110 @@
|
||||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: validator/client/beacon-api/json_rest_handler.go
|
||||
//
|
||||
// Generated by this command:
|
||||
//
|
||||
// mockgen -package=mock -source=validator/client/beacon-api/json_rest_handler.go -destination=validator/client/beacon-api/mock/json_rest_handler_mock.go
|
||||
//
|
||||
|
||||
// Package mock is a generated GoMock package.
|
||||
package mock
|
||||
|
||||
import (
|
||||
bytes "bytes"
|
||||
context "context"
|
||||
http "net/http"
|
||||
reflect "reflect"
|
||||
|
||||
gomock "go.uber.org/mock/gomock"
|
||||
)
|
||||
|
||||
// MockJsonRestHandler is a mock of JsonRestHandler interface.
|
||||
type MockJsonRestHandler struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockJsonRestHandlerMockRecorder
|
||||
}
|
||||
|
||||
// MockJsonRestHandlerMockRecorder is the mock recorder for MockJsonRestHandler.
|
||||
type MockJsonRestHandlerMockRecorder struct {
|
||||
mock *MockJsonRestHandler
|
||||
}
|
||||
|
||||
// NewMockJsonRestHandler creates a new mock instance.
|
||||
func NewMockJsonRestHandler(ctrl *gomock.Controller) *MockJsonRestHandler {
|
||||
mock := &MockJsonRestHandler{ctrl: ctrl}
|
||||
mock.recorder = &MockJsonRestHandlerMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||
func (m *MockJsonRestHandler) EXPECT() *MockJsonRestHandlerMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// Get mocks base method.
|
||||
func (m *MockJsonRestHandler) Get(ctx context.Context, endpoint string, resp any) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Get", ctx, endpoint, resp)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// Get indicates an expected call of Get.
|
||||
func (mr *MockJsonRestHandlerMockRecorder) Get(ctx, endpoint, resp any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockJsonRestHandler)(nil).Get), ctx, endpoint, resp)
|
||||
}
|
||||
|
||||
// Host mocks base method.
|
||||
func (m *MockJsonRestHandler) Host() string {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Host")
|
||||
ret0, _ := ret[0].(string)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// Host indicates an expected call of Host.
|
||||
func (mr *MockJsonRestHandlerMockRecorder) Host() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Host", reflect.TypeOf((*MockJsonRestHandler)(nil).Host))
|
||||
}
|
||||
|
||||
// HttpClient mocks base method.
|
||||
func (m *MockJsonRestHandler) HttpClient() *http.Client {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "HttpClient")
|
||||
ret0, _ := ret[0].(*http.Client)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// HttpClient indicates an expected call of HttpClient.
|
||||
func (mr *MockJsonRestHandlerMockRecorder) HttpClient() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HttpClient", reflect.TypeOf((*MockJsonRestHandler)(nil).HttpClient))
|
||||
}
|
||||
|
||||
// Post mocks base method.
|
||||
func (m *MockJsonRestHandler) Post(ctx context.Context, endpoint string, headers map[string]string, data *bytes.Buffer, resp any) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Post", ctx, endpoint, headers, data, resp)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// Post indicates an expected call of Post.
|
||||
func (mr *MockJsonRestHandlerMockRecorder) Post(ctx, endpoint, headers, data, resp any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Post", reflect.TypeOf((*MockJsonRestHandler)(nil).Post), ctx, endpoint, headers, data, resp)
|
||||
}
|
||||
|
||||
// SetHost mocks base method.
|
||||
func (m *MockJsonRestHandler) SetHost(host string) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "SetHost", host)
|
||||
}
|
||||
|
||||
// SetHost indicates an expected call of SetHost.
|
||||
func (mr *MockJsonRestHandlerMockRecorder) SetHost(host any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetHost", reflect.TypeOf((*MockJsonRestHandler)(nil).SetHost), host)
|
||||
}
|
||||
115
api/client/beacon/mock/node_client_mock.go
generated
Normal file
115
api/client/beacon/mock/node_client_mock.go
generated
Normal file
@@ -0,0 +1,115 @@
|
||||
//
|
||||
// Generated by this command:
|
||||
//
|
||||
// mockgen -package=validator_mock -destination=testing/validator-mock/node_client_mock.go github.com/prysmaticlabs/prysm/v5/validator/client/iface NodeClient
|
||||
//
|
||||
|
||||
// Package validator_mock is a generated GoMock package.
|
||||
package mock
|
||||
|
||||
import (
|
||||
context "context"
|
||||
reflect "reflect"
|
||||
|
||||
"github.com/prysmaticlabs/prysm/v5/api/client/beacon/health"
|
||||
eth "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
gomock "go.uber.org/mock/gomock"
|
||||
emptypb "google.golang.org/protobuf/types/known/emptypb"
|
||||
)
|
||||
|
||||
// MockNodeClient is a mock of NodeClient interface.
|
||||
type MockNodeClient struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockNodeClientMockRecorder
|
||||
}
|
||||
|
||||
// MockNodeClientMockRecorder is the mock recorder for MockNodeClient.
|
||||
type MockNodeClientMockRecorder struct {
|
||||
mock *MockNodeClient
|
||||
}
|
||||
|
||||
// NewMockNodeClient creates a new mock instance.
|
||||
func NewMockNodeClient(ctrl *gomock.Controller) *MockNodeClient {
|
||||
mock := &MockNodeClient{ctrl: ctrl}
|
||||
mock.recorder = &MockNodeClientMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||
func (m *MockNodeClient) EXPECT() *MockNodeClientMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// Genesis mocks base method.
|
||||
func (m *MockNodeClient) Genesis(arg0 context.Context, arg1 *emptypb.Empty) (*eth.Genesis, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Genesis", arg0, arg1)
|
||||
ret0, _ := ret[0].(*eth.Genesis)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// Genesis indicates an expected call of Genesis.
|
||||
func (mr *MockNodeClientMockRecorder) Genesis(arg0, arg1 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Genesis", reflect.TypeOf((*MockNodeClient)(nil).Genesis), arg0, arg1)
|
||||
}
|
||||
|
||||
// HealthTracker mocks base method.
|
||||
func (m *MockNodeClient) HealthTracker() health.HealthTracker {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "HealthTracker")
|
||||
ret0, _ := ret[0].(health.HealthTracker)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// HealthTracker indicates an expected call of HealthTracker.
|
||||
func (mr *MockNodeClientMockRecorder) HealthTracker() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HealthTracker", reflect.TypeOf((*MockNodeClient)(nil).HealthTracker))
|
||||
}
|
||||
|
||||
// Peers mocks base method.
|
||||
func (m *MockNodeClient) Peers(arg0 context.Context, arg1 *emptypb.Empty) (*eth.Peers, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Peers", arg0, arg1)
|
||||
ret0, _ := ret[0].(*eth.Peers)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// Peers indicates an expected call of Peers.
|
||||
func (mr *MockNodeClientMockRecorder) Peers(arg0, arg1 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Peers", reflect.TypeOf((*MockNodeClient)(nil).Peers), arg0, arg1)
|
||||
}
|
||||
|
||||
// SyncStatus mocks base method.
|
||||
func (m *MockNodeClient) SyncStatus(arg0 context.Context, arg1 *emptypb.Empty) (*eth.SyncStatus, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "SyncStatus", arg0, arg1)
|
||||
ret0, _ := ret[0].(*eth.SyncStatus)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// SyncStatus indicates an expected call of SyncStatus.
|
||||
func (mr *MockNodeClientMockRecorder) SyncStatus(arg0, arg1 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SyncStatus", reflect.TypeOf((*MockNodeClient)(nil).SyncStatus), arg0, arg1)
|
||||
}
|
||||
|
||||
// Version mocks base method.
|
||||
func (m *MockNodeClient) Version(arg0 context.Context, arg1 *emptypb.Empty) (*eth.Version, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Version", arg0, arg1)
|
||||
ret0, _ := ret[0].(*eth.Version)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// Version indicates an expected call of Version.
|
||||
func (mr *MockNodeClientMockRecorder) Version(arg0, arg1 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Version", reflect.TypeOf((*MockNodeClient)(nil).Version), arg0, arg1)
|
||||
}
|
||||
73
api/client/beacon/mock/prysm_chain_client_mock.go
generated
Normal file
73
api/client/beacon/mock/prysm_chain_client_mock.go
generated
Normal file
@@ -0,0 +1,73 @@
|
||||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: github.com/prysmaticlabs/prysm/v5/validator/client/iface (interfaces: PrysmChainClient)
|
||||
//
|
||||
// Generated by this command:
|
||||
//
|
||||
// mockgen -package=validator_mock -destination=testing/validator-mock/prysm_chain_client_mock.go github.com/prysmaticlabs/prysm/v5/validator/client/iface PrysmChainClient
|
||||
//
|
||||
|
||||
// Package validator_mock is a generated GoMock package.
|
||||
package mock
|
||||
|
||||
import (
|
||||
context "context"
|
||||
reflect "reflect"
|
||||
|
||||
"github.com/prysmaticlabs/prysm/v5/api/client/beacon"
|
||||
validator "github.com/prysmaticlabs/prysm/v5/consensus-types/validator"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
gomock "go.uber.org/mock/gomock"
|
||||
)
|
||||
|
||||
// MockPrysmChainClient is a mock of PrysmChainClient interface.
|
||||
type MockPrysmChainClient struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockPrysmChainClientMockRecorder
|
||||
}
|
||||
|
||||
// MockPrysmChainClientMockRecorder is the mock recorder for MockPrysmChainClient.
|
||||
type MockPrysmChainClientMockRecorder struct {
|
||||
mock *MockPrysmChainClient
|
||||
}
|
||||
|
||||
// NewMockPrysmChainClient creates a new mock instance.
|
||||
func NewMockPrysmChainClient(ctrl *gomock.Controller) *MockPrysmChainClient {
|
||||
mock := &MockPrysmChainClient{ctrl: ctrl}
|
||||
mock.recorder = &MockPrysmChainClientMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||
func (m *MockPrysmChainClient) EXPECT() *MockPrysmChainClientMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// ValidatorCount mocks base method.
|
||||
func (m *MockPrysmChainClient) ValidatorCount(arg0 context.Context, arg1 string, arg2 []validator.Status) ([]beacon.ValidatorCount, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "ValidatorCount", arg0, arg1, arg2)
|
||||
ret0, _ := ret[0].([]beacon.ValidatorCount)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// ValidatorCount indicates an expected call of ValidatorCount.
|
||||
func (mr *MockPrysmChainClientMockRecorder) ValidatorCount(arg0, arg1, arg2 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ValidatorCount", reflect.TypeOf((*MockPrysmChainClient)(nil).ValidatorCount), arg0, arg1, arg2)
|
||||
}
|
||||
|
||||
// ValidatorPerformance mocks base method.
|
||||
func (m *MockPrysmChainClient) ValidatorPerformance(arg0 context.Context, arg1 *ethpb.ValidatorPerformanceRequest) (*ethpb.ValidatorPerformanceResponse, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "ValidatorPerformance", arg0, arg1)
|
||||
ret0, _ := ret[0].(*ethpb.ValidatorPerformanceResponse)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// ValidatorPerformance indicates an expected call of ValidatorPerformance.
|
||||
func (mr *MockPrysmChainClientMockRecorder) ValidatorPerformance(arg0, arg1 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ValidatorCount", reflect.TypeOf((*MockPrysmChainClient)(nil).ValidatorPerformance), arg0, arg1)
|
||||
}
|
||||
87
api/client/beacon/mock/state_validators_mock.go
generated
Normal file
87
api/client/beacon/mock/state_validators_mock.go
generated
Normal file
@@ -0,0 +1,87 @@
|
||||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: validator/client/beacon-api/state_validators.go
|
||||
//
|
||||
// Generated by this command:
|
||||
//
|
||||
// mockgen -package=mock -source=validator/client/beacon-api/state_validators.go -destination=validator/client/beacon-api/mock/state_validators_mock.go
|
||||
//
|
||||
|
||||
// Package mock is a generated GoMock package.
|
||||
package mock
|
||||
|
||||
import (
|
||||
context "context"
|
||||
reflect "reflect"
|
||||
|
||||
structs "github.com/prysmaticlabs/prysm/v5/api/server/structs"
|
||||
primitives "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
gomock "go.uber.org/mock/gomock"
|
||||
)
|
||||
|
||||
// MockStateValidatorsProvider is a mock of StateValidatorsProvider interface.
|
||||
type MockStateValidatorsProvider struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockStateValidatorsProviderMockRecorder
|
||||
}
|
||||
|
||||
// MockStateValidatorsProviderMockRecorder is the mock recorder for MockStateValidatorsProvider.
|
||||
type MockStateValidatorsProviderMockRecorder struct {
|
||||
mock *MockStateValidatorsProvider
|
||||
}
|
||||
|
||||
// NewMockStateValidatorsProvider creates a new mock instance.
|
||||
func NewMockStateValidatorsProvider(ctrl *gomock.Controller) *MockStateValidatorsProvider {
|
||||
mock := &MockStateValidatorsProvider{ctrl: ctrl}
|
||||
mock.recorder = &MockStateValidatorsProviderMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||
func (m *MockStateValidatorsProvider) EXPECT() *MockStateValidatorsProviderMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// StateValidators mocks base method.
|
||||
func (m *MockStateValidatorsProvider) StateValidators(arg0 context.Context, arg1 []string, arg2 []primitives.ValidatorIndex, arg3 []string) (*structs.GetValidatorsResponse, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "StateValidators", arg0, arg1, arg2, arg3)
|
||||
ret0, _ := ret[0].(*structs.GetValidatorsResponse)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// StateValidators indicates an expected call of StateValidators.
|
||||
func (mr *MockStateValidatorsProviderMockRecorder) StateValidators(arg0, arg1, arg2, arg3 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateValidators", reflect.TypeOf((*MockStateValidatorsProvider)(nil).StateValidators), arg0, arg1, arg2, arg3)
|
||||
}
|
||||
|
||||
// StateValidatorsForHead mocks base method.
|
||||
func (m *MockStateValidatorsProvider) StateValidatorsForHead(arg0 context.Context, arg1 []string, arg2 []primitives.ValidatorIndex, arg3 []string) (*structs.GetValidatorsResponse, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "StateValidatorsForHead", arg0, arg1, arg2, arg3)
|
||||
ret0, _ := ret[0].(*structs.GetValidatorsResponse)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// StateValidatorsForHead indicates an expected call of StateValidatorsForHead.
|
||||
func (mr *MockStateValidatorsProviderMockRecorder) StateValidatorsForHead(arg0, arg1, arg2, arg3 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateValidatorsForHead", reflect.TypeOf((*MockStateValidatorsProvider)(nil).StateValidatorsForHead), arg0, arg1, arg2, arg3)
|
||||
}
|
||||
|
||||
// StateValidatorsForSlot mocks base method.
|
||||
func (m *MockStateValidatorsProvider) StateValidatorsForSlot(arg0 context.Context, arg1 primitives.Slot, arg2 []string, arg3 []primitives.ValidatorIndex, arg4 []string) (*structs.GetValidatorsResponse, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "StateValidatorsForSlot", arg0, arg1, arg2, arg3, arg4)
|
||||
ret0, _ := ret[0].(*structs.GetValidatorsResponse)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// StateValidatorsForSlot indicates an expected call of StateValidatorsForSlot.
|
||||
func (mr *MockStateValidatorsProviderMockRecorder) StateValidatorsForSlot(arg0, arg1, arg2, arg3, arg4 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateValidatorsForSlot", reflect.TypeOf((*MockStateValidatorsProvider)(nil).StateValidatorsForSlot), arg0, arg1, arg2, arg3, arg4)
|
||||
}
|
||||
@@ -1,16 +1,23 @@
|
||||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: github.com/prysmaticlabs/prysm/v4/validator/client/iface (interfaces: ValidatorClient)
|
||||
// Source: github.com/prysmaticlabs/prysm/v5/validator/client/iface (interfaces: ValidatorClient)
|
||||
//
|
||||
// Generated by this command:
|
||||
//
|
||||
// mockgen -package=validator_mock -destination=testing/validator-mock/validator_client_mock.go github.com/prysmaticlabs/prysm/v5/validator/client/iface ValidatorClient
|
||||
//
|
||||
|
||||
// Package validator_mock is a generated GoMock package.
|
||||
package validator_mock
|
||||
package mock
|
||||
|
||||
import (
|
||||
context "context"
|
||||
reflect "reflect"
|
||||
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
primitives "github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
|
||||
eth "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/client/beacon"
|
||||
event "github.com/prysmaticlabs/prysm/v5/api/client/event"
|
||||
primitives "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
eth "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
gomock "go.uber.org/mock/gomock"
|
||||
emptypb "google.golang.org/protobuf/types/known/emptypb"
|
||||
)
|
||||
|
||||
@@ -37,6 +44,66 @@ func (m *MockValidatorClient) EXPECT() *MockValidatorClientMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// AggregatedSelections mocks base method.
|
||||
func (m *MockValidatorClient) AggregatedSelections(arg0 context.Context, arg1 []beacon.BeaconCommitteeSelection) ([]beacon.BeaconCommitteeSelection, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "AggregatedSelections", arg0, arg1)
|
||||
ret0, _ := ret[0].([]beacon.BeaconCommitteeSelection)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// AggregatedSelections indicates an expected call of AggregatedSelections.
|
||||
func (mr *MockValidatorClientMockRecorder) AggregatedSelections(arg0, arg1 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AggregatedSelections", reflect.TypeOf((*MockValidatorClient)(nil).AggregatedSelections), arg0, arg1)
|
||||
}
|
||||
|
||||
// AggregatedSyncSelections mocks base method.
|
||||
func (m *MockValidatorClient) AggregatedSyncSelections(arg0 context.Context, arg1 []beacon.SyncCommitteeSelection) ([]beacon.SyncCommitteeSelection, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "AggregatedSyncSelections", arg0, arg1)
|
||||
ret0, _ := ret[0].([]beacon.SyncCommitteeSelection)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// AggregatedSyncSelections indicates an expected call of AggregatedSyncSelections.
|
||||
func (mr *MockValidatorClientMockRecorder) AggregatedSyncSelections(arg0, arg1 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AggregatedSyncSelections", reflect.TypeOf((*MockValidatorClient)(nil).AggregatedSyncSelections), arg0, arg1)
|
||||
}
|
||||
|
||||
// AttestationData mocks base method.
|
||||
func (m *MockValidatorClient) AttestationData(arg0 context.Context, arg1 *eth.AttestationDataRequest) (*eth.AttestationData, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "AttestationData", arg0, arg1)
|
||||
ret0, _ := ret[0].(*eth.AttestationData)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// AttestationData indicates an expected call of AttestationData.
|
||||
func (mr *MockValidatorClientMockRecorder) AttestationData(arg0, arg1 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AttestationData", reflect.TypeOf((*MockValidatorClient)(nil).AttestationData), arg0, arg1)
|
||||
}
|
||||
|
||||
// BeaconBlock mocks base method.
|
||||
func (m *MockValidatorClient) BeaconBlock(arg0 context.Context, arg1 *eth.BlockRequest) (*eth.GenericBeaconBlock, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "BeaconBlock", arg0, arg1)
|
||||
ret0, _ := ret[0].(*eth.GenericBeaconBlock)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// BeaconBlock indicates an expected call of BeaconBlock.
|
||||
func (mr *MockValidatorClientMockRecorder) BeaconBlock(arg0, arg1 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BeaconBlock", reflect.TypeOf((*MockValidatorClient)(nil).BeaconBlock), arg0, arg1)
|
||||
}
|
||||
|
||||
// CheckDoppelGanger mocks base method.
|
||||
func (m *MockValidatorClient) CheckDoppelGanger(arg0 context.Context, arg1 *eth.DoppelGangerRequest) (*eth.DoppelGangerResponse, error) {
|
||||
m.ctrl.T.Helper()
|
||||
@@ -47,7 +114,7 @@ func (m *MockValidatorClient) CheckDoppelGanger(arg0 context.Context, arg1 *eth.
|
||||
}
|
||||
|
||||
// CheckDoppelGanger indicates an expected call of CheckDoppelGanger.
|
||||
func (mr *MockValidatorClientMockRecorder) CheckDoppelGanger(arg0, arg1 interface{}) *gomock.Call {
|
||||
func (mr *MockValidatorClientMockRecorder) CheckDoppelGanger(arg0, arg1 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CheckDoppelGanger", reflect.TypeOf((*MockValidatorClient)(nil).CheckDoppelGanger), arg0, arg1)
|
||||
}
|
||||
@@ -62,114 +129,67 @@ func (m *MockValidatorClient) DomainData(arg0 context.Context, arg1 *eth.DomainR
|
||||
}
|
||||
|
||||
// DomainData indicates an expected call of DomainData.
|
||||
func (mr *MockValidatorClientMockRecorder) DomainData(arg0, arg1 interface{}) *gomock.Call {
|
||||
func (mr *MockValidatorClientMockRecorder) DomainData(arg0, arg1 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DomainData", reflect.TypeOf((*MockValidatorClient)(nil).DomainData), arg0, arg1)
|
||||
}
|
||||
|
||||
// GetAttestationData mocks base method.
|
||||
func (m *MockValidatorClient) GetAttestationData(arg0 context.Context, arg1 *eth.AttestationDataRequest) (*eth.AttestationData, error) {
|
||||
// Duties mocks base method.
|
||||
func (m *MockValidatorClient) Duties(arg0 context.Context, arg1 *eth.DutiesRequest) (*eth.ValidatorDutiesContainer, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetAttestationData", arg0, arg1)
|
||||
ret0, _ := ret[0].(*eth.AttestationData)
|
||||
ret := m.ctrl.Call(m, "Duties", arg0, arg1)
|
||||
ret0, _ := ret[0].(*eth.ValidatorDutiesContainer)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// GetAttestationData indicates an expected call of GetAttestationData.
|
||||
func (mr *MockValidatorClientMockRecorder) GetAttestationData(arg0, arg1 interface{}) *gomock.Call {
|
||||
// Duties indicates an expected call of Duties.
|
||||
func (mr *MockValidatorClientMockRecorder) Duties(arg0, arg1 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAttestationData", reflect.TypeOf((*MockValidatorClient)(nil).GetAttestationData), arg0, arg1)
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Duties", reflect.TypeOf((*MockValidatorClient)(nil).Duties), arg0, arg1)
|
||||
}
|
||||
|
||||
// GetBeaconBlock mocks base method.
|
||||
func (m *MockValidatorClient) GetBeaconBlock(arg0 context.Context, arg1 *eth.BlockRequest) (*eth.GenericBeaconBlock, error) {
|
||||
// EventStreamIsRunning mocks base method.
|
||||
func (m *MockValidatorClient) EventStreamIsRunning() bool {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetBeaconBlock", arg0, arg1)
|
||||
ret0, _ := ret[0].(*eth.GenericBeaconBlock)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
ret := m.ctrl.Call(m, "EventStreamIsRunning")
|
||||
ret0, _ := ret[0].(bool)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// GetBeaconBlock indicates an expected call of GetBeaconBlock.
|
||||
func (mr *MockValidatorClientMockRecorder) GetBeaconBlock(arg0, arg1 interface{}) *gomock.Call {
|
||||
// EventStreamIsRunning indicates an expected call of EventStreamIsRunning.
|
||||
func (mr *MockValidatorClientMockRecorder) EventStreamIsRunning() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBeaconBlock", reflect.TypeOf((*MockValidatorClient)(nil).GetBeaconBlock), arg0, arg1)
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EventStreamIsRunning", reflect.TypeOf((*MockValidatorClient)(nil).EventStreamIsRunning))
|
||||
}
|
||||
|
||||
// GetDuties mocks base method.
|
||||
func (m *MockValidatorClient) GetDuties(arg0 context.Context, arg1 *eth.DutiesRequest) (*eth.DutiesResponse, error) {
|
||||
// FeeRecipientByPubKey mocks base method.
|
||||
func (m *MockValidatorClient) FeeRecipientByPubKey(arg0 context.Context, arg1 *eth.FeeRecipientByPubKeyRequest) (*eth.FeeRecipientByPubKeyResponse, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetDuties", arg0, arg1)
|
||||
ret0, _ := ret[0].(*eth.DutiesResponse)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// GetDuties indicates an expected call of GetDuties.
|
||||
func (mr *MockValidatorClientMockRecorder) GetDuties(arg0, arg1 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDuties", reflect.TypeOf((*MockValidatorClient)(nil).GetDuties), arg0, arg1)
|
||||
}
|
||||
|
||||
// GetFeeRecipientByPubKey mocks base method.
|
||||
func (m *MockValidatorClient) GetFeeRecipientByPubKey(arg0 context.Context, arg1 *eth.FeeRecipientByPubKeyRequest) (*eth.FeeRecipientByPubKeyResponse, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetFeeRecipientByPubKey", arg0, arg1)
|
||||
ret := m.ctrl.Call(m, "FeeRecipientByPubKey", arg0, arg1)
|
||||
ret0, _ := ret[0].(*eth.FeeRecipientByPubKeyResponse)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// GetFeeRecipientByPubKey indicates an expected call of GetFeeRecipientByPubKey.
|
||||
func (mr *MockValidatorClientMockRecorder) GetFeeRecipientByPubKey(arg0, arg1 interface{}) *gomock.Call {
|
||||
// FeeRecipientByPubKey indicates an expected call of FeeRecipientByPubKey.
|
||||
func (mr *MockValidatorClientMockRecorder) FeeRecipientByPubKey(arg0, arg1 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetFeeRecipientByPubKey", reflect.TypeOf((*MockValidatorClient)(nil).GetFeeRecipientByPubKey), arg0, arg1)
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FeeRecipientByPubKey", reflect.TypeOf((*MockValidatorClient)(nil).FeeRecipientByPubKey), arg0, arg1)
|
||||
}
|
||||
|
||||
// GetSyncCommitteeContribution mocks base method.
|
||||
func (m *MockValidatorClient) GetSyncCommitteeContribution(arg0 context.Context, arg1 *eth.SyncCommitteeContributionRequest) (*eth.SyncCommitteeContribution, error) {
|
||||
// Host mocks base method.
|
||||
func (m *MockValidatorClient) Host() string {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetSyncCommitteeContribution", arg0, arg1)
|
||||
ret0, _ := ret[0].(*eth.SyncCommitteeContribution)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
ret := m.ctrl.Call(m, "Host")
|
||||
ret0, _ := ret[0].(string)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// GetSyncCommitteeContribution indicates an expected call of GetSyncCommitteeContribution.
|
||||
func (mr *MockValidatorClientMockRecorder) GetSyncCommitteeContribution(arg0, arg1 interface{}) *gomock.Call {
|
||||
// Host indicates an expected call of Host.
|
||||
func (mr *MockValidatorClientMockRecorder) Host() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSyncCommitteeContribution", reflect.TypeOf((*MockValidatorClient)(nil).GetSyncCommitteeContribution), arg0, arg1)
|
||||
}
|
||||
|
||||
// GetSyncMessageBlockRoot mocks base method.
|
||||
func (m *MockValidatorClient) GetSyncMessageBlockRoot(arg0 context.Context, arg1 *emptypb.Empty) (*eth.SyncMessageBlockRootResponse, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetSyncMessageBlockRoot", arg0, arg1)
|
||||
ret0, _ := ret[0].(*eth.SyncMessageBlockRootResponse)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// GetSyncMessageBlockRoot indicates an expected call of GetSyncMessageBlockRoot.
|
||||
func (mr *MockValidatorClientMockRecorder) GetSyncMessageBlockRoot(arg0, arg1 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSyncMessageBlockRoot", reflect.TypeOf((*MockValidatorClient)(nil).GetSyncMessageBlockRoot), arg0, arg1)
|
||||
}
|
||||
|
||||
// GetSyncSubcommitteeIndex mocks base method.
|
||||
func (m *MockValidatorClient) GetSyncSubcommitteeIndex(arg0 context.Context, arg1 *eth.SyncSubcommitteeIndexRequest) (*eth.SyncSubcommitteeIndexResponse, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetSyncSubcommitteeIndex", arg0, arg1)
|
||||
ret0, _ := ret[0].(*eth.SyncSubcommitteeIndexResponse)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// GetSyncSubcommitteeIndex indicates an expected call of GetSyncSubcommitteeIndex.
|
||||
func (mr *MockValidatorClientMockRecorder) GetSyncSubcommitteeIndex(arg0, arg1 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSyncSubcommitteeIndex", reflect.TypeOf((*MockValidatorClient)(nil).GetSyncSubcommitteeIndex), arg0, arg1)
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Host", reflect.TypeOf((*MockValidatorClient)(nil).Host))
|
||||
}
|
||||
|
||||
// MultipleValidatorStatus mocks base method.
|
||||
@@ -182,7 +202,7 @@ func (m *MockValidatorClient) MultipleValidatorStatus(arg0 context.Context, arg1
|
||||
}
|
||||
|
||||
// MultipleValidatorStatus indicates an expected call of MultipleValidatorStatus.
|
||||
func (mr *MockValidatorClientMockRecorder) MultipleValidatorStatus(arg0, arg1 interface{}) *gomock.Call {
|
||||
func (mr *MockValidatorClientMockRecorder) MultipleValidatorStatus(arg0, arg1 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MultipleValidatorStatus", reflect.TypeOf((*MockValidatorClient)(nil).MultipleValidatorStatus), arg0, arg1)
|
||||
}
|
||||
@@ -197,7 +217,7 @@ func (m *MockValidatorClient) PrepareBeaconProposer(arg0 context.Context, arg1 *
|
||||
}
|
||||
|
||||
// PrepareBeaconProposer indicates an expected call of PrepareBeaconProposer.
|
||||
func (mr *MockValidatorClientMockRecorder) PrepareBeaconProposer(arg0, arg1 interface{}) *gomock.Call {
|
||||
func (mr *MockValidatorClientMockRecorder) PrepareBeaconProposer(arg0, arg1 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PrepareBeaconProposer", reflect.TypeOf((*MockValidatorClient)(nil).PrepareBeaconProposer), arg0, arg1)
|
||||
}
|
||||
@@ -212,11 +232,26 @@ func (m *MockValidatorClient) ProposeAttestation(arg0 context.Context, arg1 *eth
|
||||
}
|
||||
|
||||
// ProposeAttestation indicates an expected call of ProposeAttestation.
|
||||
func (mr *MockValidatorClientMockRecorder) ProposeAttestation(arg0, arg1 interface{}) *gomock.Call {
|
||||
func (mr *MockValidatorClientMockRecorder) ProposeAttestation(arg0, arg1 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ProposeAttestation", reflect.TypeOf((*MockValidatorClient)(nil).ProposeAttestation), arg0, arg1)
|
||||
}
|
||||
|
||||
// ProposeAttestationElectra mocks base method.
|
||||
func (m *MockValidatorClient) ProposeAttestationElectra(arg0 context.Context, arg1 *eth.SingleAttestation) (*eth.AttestResponse, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "ProposeAttestationElectra", arg0, arg1)
|
||||
ret0, _ := ret[0].(*eth.AttestResponse)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// ProposeAttestationElectra indicates an expected call of ProposeAttestationElectra.
|
||||
func (mr *MockValidatorClientMockRecorder) ProposeAttestationElectra(arg0, arg1 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ProposeAttestationElectra", reflect.TypeOf((*MockValidatorClient)(nil).ProposeAttestationElectra), arg0, arg1)
|
||||
}
|
||||
|
||||
// ProposeBeaconBlock mocks base method.
|
||||
func (m *MockValidatorClient) ProposeBeaconBlock(arg0 context.Context, arg1 *eth.GenericSignedBeaconBlock) (*eth.ProposeResponse, error) {
|
||||
m.ctrl.T.Helper()
|
||||
@@ -227,7 +262,7 @@ func (m *MockValidatorClient) ProposeBeaconBlock(arg0 context.Context, arg1 *eth
|
||||
}
|
||||
|
||||
// ProposeBeaconBlock indicates an expected call of ProposeBeaconBlock.
|
||||
func (mr *MockValidatorClientMockRecorder) ProposeBeaconBlock(arg0, arg1 interface{}) *gomock.Call {
|
||||
func (mr *MockValidatorClientMockRecorder) ProposeBeaconBlock(arg0, arg1 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ProposeBeaconBlock", reflect.TypeOf((*MockValidatorClient)(nil).ProposeBeaconBlock), arg0, arg1)
|
||||
}
|
||||
@@ -242,39 +277,63 @@ func (m *MockValidatorClient) ProposeExit(arg0 context.Context, arg1 *eth.Signed
|
||||
}
|
||||
|
||||
// ProposeExit indicates an expected call of ProposeExit.
|
||||
func (mr *MockValidatorClientMockRecorder) ProposeExit(arg0, arg1 interface{}) *gomock.Call {
|
||||
func (mr *MockValidatorClientMockRecorder) ProposeExit(arg0, arg1 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ProposeExit", reflect.TypeOf((*MockValidatorClient)(nil).ProposeExit), arg0, arg1)
|
||||
}
|
||||
|
||||
// StreamBlocksAltair mocks base method.
|
||||
func (m *MockValidatorClient) StreamBlocksAltair(arg0 context.Context, arg1 *eth.StreamBlocksRequest) (eth.BeaconNodeValidator_StreamBlocksAltairClient, error) {
|
||||
// SetHost mocks base method.
|
||||
func (m *MockValidatorClient) SetHost(arg0 string) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "StreamBlocksAltair", arg0, arg1)
|
||||
ret0, _ := ret[0].(eth.BeaconNodeValidator_StreamBlocksAltairClient)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
m.ctrl.Call(m, "SetHost", arg0)
|
||||
}
|
||||
|
||||
// StreamBlocksAltair indicates an expected call of StreamBlocksAltair.
|
||||
func (mr *MockValidatorClientMockRecorder) StreamBlocksAltair(arg0, arg1 interface{}) *gomock.Call {
|
||||
// SetHost indicates an expected call of SetHost.
|
||||
func (mr *MockValidatorClientMockRecorder) SetHost(arg0 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StreamBlocksAltair", reflect.TypeOf((*MockValidatorClient)(nil).StreamBlocksAltair), arg0, arg1)
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetHost", reflect.TypeOf((*MockValidatorClient)(nil).SetHost), arg0)
|
||||
}
|
||||
|
||||
// StartEventStream mocks base method.
|
||||
func (m *MockValidatorClient) StartEventStream(arg0 context.Context, arg1 []string, arg2 chan<- *event.Event) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "StartEventStream", arg0, arg1, arg2)
|
||||
}
|
||||
|
||||
// StartEventStream indicates an expected call of StartEventStream.
|
||||
func (mr *MockValidatorClientMockRecorder) StartEventStream(arg0, arg1, arg2 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StartEventStream", reflect.TypeOf((*MockValidatorClient)(nil).StartEventStream), arg0, arg1, arg2)
|
||||
}
|
||||
|
||||
// SubmitAggregateSelectionProof mocks base method.
|
||||
func (m *MockValidatorClient) SubmitAggregateSelectionProof(arg0 context.Context, arg1 *eth.AggregateSelectionRequest) (*eth.AggregateSelectionResponse, error) {
|
||||
func (m *MockValidatorClient) SubmitAggregateSelectionProof(arg0 context.Context, arg1 *eth.AggregateSelectionRequest, arg2 primitives.ValidatorIndex, arg3 uint64) (*eth.AggregateSelectionResponse, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "SubmitAggregateSelectionProof", arg0, arg1)
|
||||
ret := m.ctrl.Call(m, "SubmitAggregateSelectionProof", arg0, arg1, arg2, arg3)
|
||||
ret0, _ := ret[0].(*eth.AggregateSelectionResponse)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// SubmitAggregateSelectionProof indicates an expected call of SubmitAggregateSelectionProof.
|
||||
func (mr *MockValidatorClientMockRecorder) SubmitAggregateSelectionProof(arg0, arg1 interface{}) *gomock.Call {
|
||||
func (mr *MockValidatorClientMockRecorder) SubmitAggregateSelectionProof(arg0, arg1, arg2, arg3 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SubmitAggregateSelectionProof", reflect.TypeOf((*MockValidatorClient)(nil).SubmitAggregateSelectionProof), arg0, arg1)
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SubmitAggregateSelectionProof", reflect.TypeOf((*MockValidatorClient)(nil).SubmitAggregateSelectionProof), arg0, arg1, arg2, arg3)
|
||||
}
|
||||
|
||||
// SubmitAggregateSelectionProofElectra mocks base method.
|
||||
func (m *MockValidatorClient) SubmitAggregateSelectionProofElectra(arg0 context.Context, arg1 *eth.AggregateSelectionRequest, arg2 primitives.ValidatorIndex, arg3 uint64) (*eth.AggregateSelectionElectraResponse, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "SubmitAggregateSelectionProofElectra", arg0, arg1, arg2, arg3)
|
||||
ret0, _ := ret[0].(*eth.AggregateSelectionElectraResponse)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// SubmitAggregateSelectionProofElectra indicates an expected call of SubmitAggregateSelectionProofElectra.
|
||||
func (mr *MockValidatorClientMockRecorder) SubmitAggregateSelectionProofElectra(arg0, arg1, arg2, arg3 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SubmitAggregateSelectionProofElectra", reflect.TypeOf((*MockValidatorClient)(nil).SubmitAggregateSelectionProofElectra), arg0, arg1, arg2, arg3)
|
||||
}
|
||||
|
||||
// SubmitSignedAggregateSelectionProof mocks base method.
|
||||
@@ -287,11 +346,26 @@ func (m *MockValidatorClient) SubmitSignedAggregateSelectionProof(arg0 context.C
|
||||
}
|
||||
|
||||
// SubmitSignedAggregateSelectionProof indicates an expected call of SubmitSignedAggregateSelectionProof.
|
||||
func (mr *MockValidatorClientMockRecorder) SubmitSignedAggregateSelectionProof(arg0, arg1 interface{}) *gomock.Call {
|
||||
func (mr *MockValidatorClientMockRecorder) SubmitSignedAggregateSelectionProof(arg0, arg1 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SubmitSignedAggregateSelectionProof", reflect.TypeOf((*MockValidatorClient)(nil).SubmitSignedAggregateSelectionProof), arg0, arg1)
|
||||
}
|
||||
|
||||
// SubmitSignedAggregateSelectionProofElectra mocks base method.
|
||||
func (m *MockValidatorClient) SubmitSignedAggregateSelectionProofElectra(arg0 context.Context, arg1 *eth.SignedAggregateSubmitElectraRequest) (*eth.SignedAggregateSubmitResponse, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "SubmitSignedAggregateSelectionProofElectra", arg0, arg1)
|
||||
ret0, _ := ret[0].(*eth.SignedAggregateSubmitResponse)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// SubmitSignedAggregateSelectionProofElectra indicates an expected call of SubmitSignedAggregateSelectionProofElectra.
|
||||
func (mr *MockValidatorClientMockRecorder) SubmitSignedAggregateSelectionProofElectra(arg0, arg1 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SubmitSignedAggregateSelectionProofElectra", reflect.TypeOf((*MockValidatorClient)(nil).SubmitSignedAggregateSelectionProofElectra), arg0, arg1)
|
||||
}
|
||||
|
||||
// SubmitSignedContributionAndProof mocks base method.
|
||||
func (m *MockValidatorClient) SubmitSignedContributionAndProof(arg0 context.Context, arg1 *eth.SignedContributionAndProof) (*emptypb.Empty, error) {
|
||||
m.ctrl.T.Helper()
|
||||
@@ -302,7 +376,7 @@ func (m *MockValidatorClient) SubmitSignedContributionAndProof(arg0 context.Cont
|
||||
}
|
||||
|
||||
// SubmitSignedContributionAndProof indicates an expected call of SubmitSignedContributionAndProof.
|
||||
func (mr *MockValidatorClientMockRecorder) SubmitSignedContributionAndProof(arg0, arg1 interface{}) *gomock.Call {
|
||||
func (mr *MockValidatorClientMockRecorder) SubmitSignedContributionAndProof(arg0, arg1 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SubmitSignedContributionAndProof", reflect.TypeOf((*MockValidatorClient)(nil).SubmitSignedContributionAndProof), arg0, arg1)
|
||||
}
|
||||
@@ -317,7 +391,7 @@ func (m *MockValidatorClient) SubmitSyncMessage(arg0 context.Context, arg1 *eth.
|
||||
}
|
||||
|
||||
// SubmitSyncMessage indicates an expected call of SubmitSyncMessage.
|
||||
func (mr *MockValidatorClientMockRecorder) SubmitSyncMessage(arg0, arg1 interface{}) *gomock.Call {
|
||||
func (mr *MockValidatorClientMockRecorder) SubmitSyncMessage(arg0, arg1 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SubmitSyncMessage", reflect.TypeOf((*MockValidatorClient)(nil).SubmitSyncMessage), arg0, arg1)
|
||||
}
|
||||
@@ -332,13 +406,13 @@ func (m *MockValidatorClient) SubmitValidatorRegistrations(arg0 context.Context,
|
||||
}
|
||||
|
||||
// SubmitValidatorRegistrations indicates an expected call of SubmitValidatorRegistrations.
|
||||
func (mr *MockValidatorClientMockRecorder) SubmitValidatorRegistrations(arg0, arg1 interface{}) *gomock.Call {
|
||||
func (mr *MockValidatorClientMockRecorder) SubmitValidatorRegistrations(arg0, arg1 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SubmitValidatorRegistrations", reflect.TypeOf((*MockValidatorClient)(nil).SubmitValidatorRegistrations), arg0, arg1)
|
||||
}
|
||||
|
||||
// SubscribeCommitteeSubnets mocks base method.
|
||||
func (m *MockValidatorClient) SubscribeCommitteeSubnets(arg0 context.Context, arg1 *eth.CommitteeSubnetsSubscribeRequest, arg2 []primitives.ValidatorIndex) (*emptypb.Empty, error) {
|
||||
func (m *MockValidatorClient) SubscribeCommitteeSubnets(arg0 context.Context, arg1 *eth.CommitteeSubnetsSubscribeRequest, arg2 []*eth.ValidatorDuty) (*emptypb.Empty, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "SubscribeCommitteeSubnets", arg0, arg1, arg2)
|
||||
ret0, _ := ret[0].(*emptypb.Empty)
|
||||
@@ -347,11 +421,56 @@ func (m *MockValidatorClient) SubscribeCommitteeSubnets(arg0 context.Context, ar
|
||||
}
|
||||
|
||||
// SubscribeCommitteeSubnets indicates an expected call of SubscribeCommitteeSubnets.
|
||||
func (mr *MockValidatorClientMockRecorder) SubscribeCommitteeSubnets(arg0, arg1, arg2 interface{}) *gomock.Call {
|
||||
func (mr *MockValidatorClientMockRecorder) SubscribeCommitteeSubnets(arg0, arg1, arg2 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SubscribeCommitteeSubnets", reflect.TypeOf((*MockValidatorClient)(nil).SubscribeCommitteeSubnets), arg0, arg1, arg2)
|
||||
}
|
||||
|
||||
// SyncCommitteeContribution mocks base method.
|
||||
func (m *MockValidatorClient) SyncCommitteeContribution(arg0 context.Context, arg1 *eth.SyncCommitteeContributionRequest) (*eth.SyncCommitteeContribution, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "SyncCommitteeContribution", arg0, arg1)
|
||||
ret0, _ := ret[0].(*eth.SyncCommitteeContribution)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// SyncCommitteeContribution indicates an expected call of SyncCommitteeContribution.
|
||||
func (mr *MockValidatorClientMockRecorder) SyncCommitteeContribution(arg0, arg1 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SyncCommitteeContribution", reflect.TypeOf((*MockValidatorClient)(nil).SyncCommitteeContribution), arg0, arg1)
|
||||
}
|
||||
|
||||
// SyncMessageBlockRoot mocks base method.
|
||||
func (m *MockValidatorClient) SyncMessageBlockRoot(arg0 context.Context, arg1 *emptypb.Empty) (*eth.SyncMessageBlockRootResponse, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "SyncMessageBlockRoot", arg0, arg1)
|
||||
ret0, _ := ret[0].(*eth.SyncMessageBlockRootResponse)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// SyncMessageBlockRoot indicates an expected call of SyncMessageBlockRoot.
|
||||
func (mr *MockValidatorClientMockRecorder) SyncMessageBlockRoot(arg0, arg1 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SyncMessageBlockRoot", reflect.TypeOf((*MockValidatorClient)(nil).SyncMessageBlockRoot), arg0, arg1)
|
||||
}
|
||||
|
||||
// SyncSubcommitteeIndex mocks base method.
|
||||
func (m *MockValidatorClient) SyncSubcommitteeIndex(arg0 context.Context, arg1 *eth.SyncSubcommitteeIndexRequest) (*eth.SyncSubcommitteeIndexResponse, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "SyncSubcommitteeIndex", arg0, arg1)
|
||||
ret0, _ := ret[0].(*eth.SyncSubcommitteeIndexResponse)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// SyncSubcommitteeIndex indicates an expected call of SyncSubcommitteeIndex.
|
||||
func (mr *MockValidatorClientMockRecorder) SyncSubcommitteeIndex(arg0, arg1 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SyncSubcommitteeIndex", reflect.TypeOf((*MockValidatorClient)(nil).SyncSubcommitteeIndex), arg0, arg1)
|
||||
}
|
||||
|
||||
// ValidatorIndex mocks base method.
|
||||
func (m *MockValidatorClient) ValidatorIndex(arg0 context.Context, arg1 *eth.ValidatorIndexRequest) (*eth.ValidatorIndexResponse, error) {
|
||||
m.ctrl.T.Helper()
|
||||
@@ -362,7 +481,7 @@ func (m *MockValidatorClient) ValidatorIndex(arg0 context.Context, arg1 *eth.Val
|
||||
}
|
||||
|
||||
// ValidatorIndex indicates an expected call of ValidatorIndex.
|
||||
func (mr *MockValidatorClientMockRecorder) ValidatorIndex(arg0, arg1 interface{}) *gomock.Call {
|
||||
func (mr *MockValidatorClientMockRecorder) ValidatorIndex(arg0, arg1 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ValidatorIndex", reflect.TypeOf((*MockValidatorClient)(nil).ValidatorIndex), arg0, arg1)
|
||||
}
|
||||
@@ -377,26 +496,11 @@ func (m *MockValidatorClient) ValidatorStatus(arg0 context.Context, arg1 *eth.Va
|
||||
}
|
||||
|
||||
// ValidatorStatus indicates an expected call of ValidatorStatus.
|
||||
func (mr *MockValidatorClientMockRecorder) ValidatorStatus(arg0, arg1 interface{}) *gomock.Call {
|
||||
func (mr *MockValidatorClientMockRecorder) ValidatorStatus(arg0, arg1 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ValidatorStatus", reflect.TypeOf((*MockValidatorClient)(nil).ValidatorStatus), arg0, arg1)
|
||||
}
|
||||
|
||||
// WaitForActivation mocks base method.
|
||||
func (m *MockValidatorClient) WaitForActivation(arg0 context.Context, arg1 *eth.ValidatorActivationRequest) (eth.BeaconNodeValidator_WaitForActivationClient, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "WaitForActivation", arg0, arg1)
|
||||
ret0, _ := ret[0].(eth.BeaconNodeValidator_WaitForActivationClient)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// WaitForActivation indicates an expected call of WaitForActivation.
|
||||
func (mr *MockValidatorClientMockRecorder) WaitForActivation(arg0, arg1 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WaitForActivation", reflect.TypeOf((*MockValidatorClient)(nil).WaitForActivation), arg0, arg1)
|
||||
}
|
||||
|
||||
// WaitForChainStart mocks base method.
|
||||
func (m *MockValidatorClient) WaitForChainStart(arg0 context.Context, arg1 *emptypb.Empty) (*eth.ChainStartResponse, error) {
|
||||
m.ctrl.T.Helper()
|
||||
@@ -407,7 +511,7 @@ func (m *MockValidatorClient) WaitForChainStart(arg0 context.Context, arg1 *empt
|
||||
}
|
||||
|
||||
// WaitForChainStart indicates an expected call of WaitForChainStart.
|
||||
func (mr *MockValidatorClientMockRecorder) WaitForChainStart(arg0, arg1 interface{}) *gomock.Call {
|
||||
func (mr *MockValidatorClientMockRecorder) WaitForChainStart(arg0, arg1 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WaitForChainStart", reflect.TypeOf((*MockValidatorClient)(nil).WaitForChainStart), arg0, arg1)
|
||||
}
|
||||
44
api/client/beacon/node/BUILD.bazel
Normal file
44
api/client/beacon/node/BUILD.bazel
Normal file
@@ -0,0 +1,44 @@
|
||||
load("@prysm//tools/go:def.bzl", "go_library", "go_test")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"client.go",
|
||||
"grpc_node_client.go",
|
||||
"interfaces.go",
|
||||
"rest_client.go",
|
||||
],
|
||||
importpath = "github.com/prysmaticlabs/prysm/v5/api/client/beacon/node",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//api/client:go_default_library",
|
||||
"//api/client/beacon/health:go_default_library",
|
||||
"//api/client/beacon/shared_providers:go_default_library",
|
||||
"//api/server/structs:go_default_library",
|
||||
"//config/features:go_default_library",
|
||||
"//proto/prysm/v1alpha1:go_default_library",
|
||||
"//validator/helpers:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//common/hexutil:go_default_library",
|
||||
"@com_github_golang_protobuf//ptypes/empty",
|
||||
"@com_github_pkg_errors//:go_default_library",
|
||||
"@com_github_sirupsen_logrus//:go_default_library",
|
||||
"@org_golang_google_grpc//:go_default_library",
|
||||
"@org_golang_google_protobuf//types/known/timestamppb:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["rest_client_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//api/client/beacon/mock:go_default_library",
|
||||
"//api/server/structs:go_default_library",
|
||||
"//proto/prysm/v1alpha1:go_default_library",
|
||||
"//testing/assert:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//common/hexutil:go_default_library",
|
||||
"@org_golang_google_protobuf//types/known/emptypb:go_default_library",
|
||||
"@org_golang_google_protobuf//types/known/timestamppb:go_default_library",
|
||||
"@org_uber_go_mock//gomock:go_default_library",
|
||||
],
|
||||
)
|
||||
28
api/client/beacon/node/client.go
Normal file
28
api/client/beacon/node/client.go
Normal file
@@ -0,0 +1,28 @@
|
||||
package node
|
||||
|
||||
import (
|
||||
"github.com/prysmaticlabs/prysm/v5/api/client"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/client/beacon/health"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/client/beacon/shared_providers"
|
||||
"github.com/prysmaticlabs/prysm/v5/config/features"
|
||||
validatorHelpers "github.com/prysmaticlabs/prysm/v5/validator/helpers"
|
||||
)
|
||||
|
||||
func NewClient(validatorConn validatorHelpers.NodeConnection, jsonRestHandler client.JsonRestHandler) Client {
|
||||
grpcClient := NewNodeClient(validatorConn.GetGrpcClientConn())
|
||||
if features.Get().EnableBeaconRESTApi {
|
||||
return NewNodeClientWithFallback(jsonRestHandler, grpcClient)
|
||||
} else {
|
||||
return grpcClient
|
||||
}
|
||||
}
|
||||
|
||||
func NewNodeClientWithFallback(jsonRestHandler client.JsonRestHandler, fallbackClient Client) Client {
|
||||
b := &beaconapiNodeClient{
|
||||
jsonRestHandler: jsonRestHandler,
|
||||
fallbackClient: fallbackClient,
|
||||
genesisProvider: shared_providers.NewGenesis(jsonRestHandler),
|
||||
}
|
||||
b.healthTracker = health.NewTracker(b)
|
||||
return b
|
||||
}
|
||||
55
api/client/beacon/node/grpc_node_client.go
Normal file
55
api/client/beacon/node/grpc_node_client.go
Normal file
@@ -0,0 +1,55 @@
|
||||
package node
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/golang/protobuf/ptypes/empty"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/client/beacon/health"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
var (
|
||||
_ = Client(&grpcNodeClient{})
|
||||
)
|
||||
|
||||
type grpcNodeClient struct {
|
||||
nodeClient ethpb.NodeClient
|
||||
healthTracker health.HealthTracker
|
||||
}
|
||||
|
||||
func (c *grpcNodeClient) SyncStatus(ctx context.Context, in *empty.Empty) (*ethpb.SyncStatus, error) {
|
||||
return c.nodeClient.GetSyncStatus(ctx, in)
|
||||
}
|
||||
|
||||
func (c *grpcNodeClient) Genesis(ctx context.Context, in *empty.Empty) (*ethpb.Genesis, error) {
|
||||
return c.nodeClient.GetGenesis(ctx, in)
|
||||
}
|
||||
|
||||
func (c *grpcNodeClient) Version(ctx context.Context, in *empty.Empty) (*ethpb.Version, error) {
|
||||
return c.nodeClient.GetVersion(ctx, in)
|
||||
}
|
||||
|
||||
func (c *grpcNodeClient) Peers(ctx context.Context, in *empty.Empty) (*ethpb.Peers, error) {
|
||||
return c.nodeClient.ListPeers(ctx, in)
|
||||
}
|
||||
|
||||
func (c *grpcNodeClient) IsHealthy(ctx context.Context) bool {
|
||||
_, err := c.nodeClient.GetHealth(ctx, ðpb.HealthRequest{})
|
||||
if err != nil {
|
||||
log.WithError(err).Debug("failed to get health of node")
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (c *grpcNodeClient) HealthTracker() health.HealthTracker {
|
||||
return c.healthTracker
|
||||
}
|
||||
|
||||
func NewNodeClient(cc grpc.ClientConnInterface) Client {
|
||||
g := &grpcNodeClient{nodeClient: ethpb.NewNodeClient(cc)}
|
||||
g.healthTracker = health.NewTracker(g)
|
||||
return g
|
||||
}
|
||||
17
api/client/beacon/node/interfaces.go
Normal file
17
api/client/beacon/node/interfaces.go
Normal file
@@ -0,0 +1,17 @@
|
||||
package node
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/golang/protobuf/ptypes/empty"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/client/beacon/health"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
)
|
||||
|
||||
type Client interface {
|
||||
SyncStatus(ctx context.Context, in *empty.Empty) (*ethpb.SyncStatus, error)
|
||||
Genesis(ctx context.Context, in *empty.Empty) (*ethpb.Genesis, error)
|
||||
Version(ctx context.Context, in *empty.Empty) (*ethpb.Version, error)
|
||||
Peers(ctx context.Context, in *empty.Empty) (*ethpb.Peers, error)
|
||||
HealthTracker() health.HealthTracker
|
||||
}
|
||||
113
api/client/beacon/node/rest_client.go
Normal file
113
api/client/beacon/node/rest_client.go
Normal file
@@ -0,0 +1,113 @@
|
||||
package node
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strconv"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/golang/protobuf/ptypes/empty"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/client"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/client/beacon/health"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/client/beacon/shared_providers"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/server/structs"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
"google.golang.org/protobuf/types/known/timestamppb"
|
||||
)
|
||||
|
||||
var (
|
||||
_ = Client(&beaconapiNodeClient{})
|
||||
)
|
||||
|
||||
type beaconapiNodeClient struct {
|
||||
fallbackClient Client
|
||||
jsonRestHandler client.JsonRestHandler
|
||||
genesisProvider shared_providers.Genesis
|
||||
healthTracker health.HealthTracker
|
||||
}
|
||||
|
||||
func (c *beaconapiNodeClient) SyncStatus(ctx context.Context, _ *empty.Empty) (*ethpb.SyncStatus, error) {
|
||||
syncingResponse := structs.SyncStatusResponse{}
|
||||
if err := c.jsonRestHandler.Get(ctx, "/eth/v1/node/syncing", &syncingResponse); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if syncingResponse.Data == nil {
|
||||
return nil, errors.New("syncing data is nil")
|
||||
}
|
||||
|
||||
return ðpb.SyncStatus{
|
||||
Syncing: syncingResponse.Data.IsSyncing,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *beaconapiNodeClient) Genesis(ctx context.Context, _ *empty.Empty) (*ethpb.Genesis, error) {
|
||||
genesisJson, err := c.genesisProvider.Genesis(ctx)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to get genesis")
|
||||
}
|
||||
|
||||
genesisValidatorRoot, err := hexutil.Decode(genesisJson.GenesisValidatorsRoot)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to decode genesis validator root `%s`", genesisJson.GenesisValidatorsRoot)
|
||||
}
|
||||
|
||||
genesisTime, err := strconv.ParseInt(genesisJson.GenesisTime, 10, 64)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to parse genesis time `%s`", genesisJson.GenesisTime)
|
||||
}
|
||||
|
||||
depositContractJson := structs.GetDepositContractResponse{}
|
||||
if err = c.jsonRestHandler.Get(ctx, "/eth/v1/config/deposit_contract", &depositContractJson); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if depositContractJson.Data == nil {
|
||||
return nil, errors.New("deposit contract data is nil")
|
||||
}
|
||||
|
||||
depositContactAddress, err := hexutil.Decode(depositContractJson.Data.Address)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to decode deposit contract address `%s`", depositContractJson.Data.Address)
|
||||
}
|
||||
|
||||
return ðpb.Genesis{
|
||||
GenesisTime: ×tamppb.Timestamp{
|
||||
Seconds: genesisTime,
|
||||
},
|
||||
DepositContractAddress: depositContactAddress,
|
||||
GenesisValidatorsRoot: genesisValidatorRoot,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *beaconapiNodeClient) Version(ctx context.Context, _ *empty.Empty) (*ethpb.Version, error) {
|
||||
var versionResponse structs.GetVersionResponse
|
||||
if err := c.jsonRestHandler.Get(ctx, "/eth/v1/node/version", &versionResponse); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if versionResponse.Data == nil || versionResponse.Data.Version == "" {
|
||||
return nil, errors.New("empty version response")
|
||||
}
|
||||
|
||||
return ðpb.Version{
|
||||
Version: versionResponse.Data.Version,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *beaconapiNodeClient) Peers(ctx context.Context, in *empty.Empty) (*ethpb.Peers, error) {
|
||||
if c.fallbackClient != nil {
|
||||
return c.fallbackClient.Peers(ctx, in)
|
||||
}
|
||||
|
||||
// TODO: Implement me
|
||||
return nil, errors.New("beaconapiNodeClient.Peers is not implemented. To use a fallback client, pass a fallback client as the last argument of NewBeaconApiNodeClientWithFallback.")
|
||||
}
|
||||
|
||||
func (c *beaconapiNodeClient) IsHealthy(ctx context.Context) bool {
|
||||
return c.jsonRestHandler.Get(ctx, "/eth/v1/node/health", nil) == nil
|
||||
}
|
||||
|
||||
func (c *beaconapiNodeClient) HealthTracker() health.HealthTracker {
|
||||
return c.healthTracker
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package beacon_api
|
||||
package node
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -6,13 +6,11 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/golang/mock/gomock"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/beacon"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/config"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/node"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v4/testing/assert"
|
||||
"github.com/prysmaticlabs/prysm/v4/validator/client/beacon-api/mock"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/client/beacon/mock"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/server/structs"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v5/testing/assert"
|
||||
"go.uber.org/mock/gomock"
|
||||
"google.golang.org/protobuf/types/known/emptypb"
|
||||
"google.golang.org/protobuf/types/known/timestamppb"
|
||||
)
|
||||
@@ -20,9 +18,9 @@ import (
|
||||
func TestGetGenesis(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
genesisResponse *beacon.Genesis
|
||||
genesisResponse *structs.Genesis
|
||||
genesisError error
|
||||
depositContractResponse config.GetDepositContractResponse
|
||||
depositContractResponse structs.GetDepositContractResponse
|
||||
depositContractError error
|
||||
queriesDepositContract bool
|
||||
expectedResponse *ethpb.Genesis
|
||||
@@ -35,7 +33,7 @@ func TestGetGenesis(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "fails to decode genesis validator root",
|
||||
genesisResponse: &beacon.Genesis{
|
||||
genesisResponse: &structs.Genesis{
|
||||
GenesisTime: "1",
|
||||
GenesisValidatorsRoot: "foo",
|
||||
},
|
||||
@@ -43,7 +41,7 @@ func TestGetGenesis(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "fails to parse genesis time",
|
||||
genesisResponse: &beacon.Genesis{
|
||||
genesisResponse: &structs.Genesis{
|
||||
GenesisTime: "foo",
|
||||
GenesisValidatorsRoot: hexutil.Encode([]byte{1}),
|
||||
},
|
||||
@@ -51,7 +49,7 @@ func TestGetGenesis(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "fails to query contract information",
|
||||
genesisResponse: &beacon.Genesis{
|
||||
genesisResponse: &structs.Genesis{
|
||||
GenesisTime: "1",
|
||||
GenesisValidatorsRoot: hexutil.Encode([]byte{2}),
|
||||
},
|
||||
@@ -61,25 +59,25 @@ func TestGetGenesis(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "fails to read nil deposit contract data",
|
||||
genesisResponse: &beacon.Genesis{
|
||||
genesisResponse: &structs.Genesis{
|
||||
GenesisTime: "1",
|
||||
GenesisValidatorsRoot: hexutil.Encode([]byte{2}),
|
||||
},
|
||||
queriesDepositContract: true,
|
||||
depositContractResponse: config.GetDepositContractResponse{
|
||||
depositContractResponse: structs.GetDepositContractResponse{
|
||||
Data: nil,
|
||||
},
|
||||
expectedError: "deposit contract data is nil",
|
||||
},
|
||||
{
|
||||
name: "fails to decode deposit contract address",
|
||||
genesisResponse: &beacon.Genesis{
|
||||
genesisResponse: &structs.Genesis{
|
||||
GenesisTime: "1",
|
||||
GenesisValidatorsRoot: hexutil.Encode([]byte{2}),
|
||||
},
|
||||
queriesDepositContract: true,
|
||||
depositContractResponse: config.GetDepositContractResponse{
|
||||
Data: &config.DepositContractData{
|
||||
depositContractResponse: structs.GetDepositContractResponse{
|
||||
Data: &structs.DepositContractData{
|
||||
Address: "foo",
|
||||
},
|
||||
},
|
||||
@@ -87,13 +85,13 @@ func TestGetGenesis(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "successfully retrieves genesis info",
|
||||
genesisResponse: &beacon.Genesis{
|
||||
genesisResponse: &structs.Genesis{
|
||||
GenesisTime: "654812",
|
||||
GenesisValidatorsRoot: hexutil.Encode([]byte{2}),
|
||||
},
|
||||
queriesDepositContract: true,
|
||||
depositContractResponse: config.GetDepositContractResponse{
|
||||
Data: &config.DepositContractData{
|
||||
depositContractResponse: structs.GetDepositContractResponse{
|
||||
Data: &structs.DepositContractData{
|
||||
Address: hexutil.Encode([]byte{3}),
|
||||
},
|
||||
},
|
||||
@@ -114,24 +112,22 @@ func TestGetGenesis(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
genesisProvider := mock.NewMockGenesisProvider(ctrl)
|
||||
genesisProvider.EXPECT().GetGenesis(
|
||||
ctx,
|
||||
genesisProvider.EXPECT().Genesis(
|
||||
gomock.Any(),
|
||||
).Return(
|
||||
testCase.genesisResponse,
|
||||
nil,
|
||||
testCase.genesisError,
|
||||
)
|
||||
|
||||
depositContractJson := config.GetDepositContractResponse{}
|
||||
depositContractJson := structs.GetDepositContractResponse{}
|
||||
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
|
||||
|
||||
if testCase.queriesDepositContract {
|
||||
jsonRestHandler.EXPECT().Get(
|
||||
ctx,
|
||||
gomock.Any(),
|
||||
"/eth/v1/config/deposit_contract",
|
||||
&depositContractJson,
|
||||
).Return(
|
||||
nil,
|
||||
testCase.depositContractError,
|
||||
).SetArg(
|
||||
2,
|
||||
@@ -139,11 +135,11 @@ func TestGetGenesis(t *testing.T) {
|
||||
)
|
||||
}
|
||||
|
||||
nodeClient := &beaconApiNodeClient{
|
||||
nodeClient := &beaconapiNodeClient{
|
||||
genesisProvider: genesisProvider,
|
||||
jsonRestHandler: jsonRestHandler,
|
||||
}
|
||||
response, err := nodeClient.GetGenesis(ctx, &emptypb.Empty{})
|
||||
response, err := nodeClient.Genesis(ctx, &emptypb.Empty{})
|
||||
|
||||
if testCase.expectedResponse == nil {
|
||||
assert.ErrorContains(t, testCase.expectedError, err)
|
||||
@@ -159,7 +155,7 @@ func TestGetSyncStatus(t *testing.T) {
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
restEndpointResponse node.SyncStatusResponse
|
||||
restEndpointResponse structs.SyncStatusResponse
|
||||
restEndpointError error
|
||||
expectedResponse *ethpb.SyncStatus
|
||||
expectedError string
|
||||
@@ -171,13 +167,13 @@ func TestGetSyncStatus(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "returns nil syncing data",
|
||||
restEndpointResponse: node.SyncStatusResponse{Data: nil},
|
||||
restEndpointResponse: structs.SyncStatusResponse{Data: nil},
|
||||
expectedError: "syncing data is nil",
|
||||
},
|
||||
{
|
||||
name: "returns false syncing status",
|
||||
restEndpointResponse: node.SyncStatusResponse{
|
||||
Data: &node.SyncStatusResponseData{
|
||||
restEndpointResponse: structs.SyncStatusResponse{
|
||||
Data: &structs.SyncStatusResponseData{
|
||||
IsSyncing: false,
|
||||
},
|
||||
},
|
||||
@@ -187,8 +183,8 @@ func TestGetSyncStatus(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "returns true syncing status",
|
||||
restEndpointResponse: node.SyncStatusResponse{
|
||||
Data: &node.SyncStatusResponseData{
|
||||
restEndpointResponse: structs.SyncStatusResponse{
|
||||
Data: &structs.SyncStatusResponseData{
|
||||
IsSyncing: true,
|
||||
},
|
||||
},
|
||||
@@ -204,22 +200,21 @@ func TestGetSyncStatus(t *testing.T) {
|
||||
defer ctrl.Finish()
|
||||
ctx := context.Background()
|
||||
|
||||
syncingResponse := node.SyncStatusResponse{}
|
||||
syncingResponse := structs.SyncStatusResponse{}
|
||||
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
|
||||
jsonRestHandler.EXPECT().Get(
|
||||
ctx,
|
||||
gomock.Any(),
|
||||
syncingEndpoint,
|
||||
&syncingResponse,
|
||||
).Return(
|
||||
nil,
|
||||
testCase.restEndpointError,
|
||||
).SetArg(
|
||||
2,
|
||||
testCase.restEndpointResponse,
|
||||
)
|
||||
|
||||
nodeClient := &beaconApiNodeClient{jsonRestHandler: jsonRestHandler}
|
||||
syncStatus, err := nodeClient.GetSyncStatus(ctx, &emptypb.Empty{})
|
||||
nodeClient := &beaconapiNodeClient{jsonRestHandler: jsonRestHandler}
|
||||
syncStatus, err := nodeClient.SyncStatus(ctx, &emptypb.Empty{})
|
||||
|
||||
if testCase.expectedResponse == nil {
|
||||
assert.ErrorContains(t, testCase.expectedError, err)
|
||||
@@ -235,7 +230,7 @@ func TestGetVersion(t *testing.T) {
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
restEndpointResponse node.GetVersionResponse
|
||||
restEndpointResponse structs.GetVersionResponse
|
||||
restEndpointError error
|
||||
expectedResponse *ethpb.Version
|
||||
expectedError string
|
||||
@@ -247,13 +242,13 @@ func TestGetVersion(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "returns nil version data",
|
||||
restEndpointResponse: node.GetVersionResponse{Data: nil},
|
||||
restEndpointResponse: structs.GetVersionResponse{Data: nil},
|
||||
expectedError: "empty version response",
|
||||
},
|
||||
{
|
||||
name: "returns proper version response",
|
||||
restEndpointResponse: node.GetVersionResponse{
|
||||
Data: &node.Version{
|
||||
restEndpointResponse: structs.GetVersionResponse{
|
||||
Data: &structs.Version{
|
||||
Version: "prysm/local",
|
||||
},
|
||||
},
|
||||
@@ -269,22 +264,21 @@ func TestGetVersion(t *testing.T) {
|
||||
defer ctrl.Finish()
|
||||
ctx := context.Background()
|
||||
|
||||
var versionResponse node.GetVersionResponse
|
||||
var versionResponse structs.GetVersionResponse
|
||||
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
|
||||
jsonRestHandler.EXPECT().Get(
|
||||
ctx,
|
||||
gomock.Any(),
|
||||
versionEndpoint,
|
||||
&versionResponse,
|
||||
).Return(
|
||||
nil,
|
||||
testCase.restEndpointError,
|
||||
).SetArg(
|
||||
2,
|
||||
testCase.restEndpointResponse,
|
||||
)
|
||||
|
||||
nodeClient := &beaconApiNodeClient{jsonRestHandler: jsonRestHandler}
|
||||
version, err := nodeClient.GetVersion(ctx, &emptypb.Empty{})
|
||||
nodeClient := &beaconapiNodeClient{jsonRestHandler: jsonRestHandler}
|
||||
version, err := nodeClient.Version(ctx, &emptypb.Empty{})
|
||||
|
||||
if testCase.expectedResponse == nil {
|
||||
assert.ErrorContains(t, testCase.expectedError, err)
|
||||
@@ -3,21 +3,28 @@ load("@prysm//tools/go:def.bzl", "go_library", "go_test")
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"grpc_beacon_chain_client.go",
|
||||
"grpc_node_client.go",
|
||||
"grpc_prysm_beacon_chain_client.go",
|
||||
"grpc_validator_client.go",
|
||||
"client.go",
|
||||
"grpc_client.go",
|
||||
"interfaces.go",
|
||||
"rest_client.go",
|
||||
],
|
||||
importpath = "github.com/prysmaticlabs/prysm/v4/validator/client/grpc-api",
|
||||
visibility = ["//validator:__subpackages__"],
|
||||
importpath = "github.com/prysmaticlabs/prysm/v5/api/client/beacon/prysm_api",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//api/client:go_default_library",
|
||||
"//api/client/apiutil:go_default_library",
|
||||
"//api/client/beacon:go_default_library",
|
||||
"//api/client/beacon/chain:go_default_library",
|
||||
"//api/client/beacon/node:go_default_library",
|
||||
"//api/server/structs:go_default_library",
|
||||
"//beacon-chain/rpc/eth/helpers:go_default_library",
|
||||
"//beacon-chain/state/state-native:go_default_library",
|
||||
"//config/features:go_default_library",
|
||||
"//consensus-types/primitives:go_default_library",
|
||||
"//consensus-types/validator:go_default_library",
|
||||
"//proto/eth/v1:go_default_library",
|
||||
"//proto/prysm/v1alpha1:go_default_library",
|
||||
"//validator/client/iface:go_default_library",
|
||||
"//validator/helpers:go_default_library",
|
||||
"@com_github_golang_protobuf//ptypes/empty",
|
||||
"@com_github_pkg_errors//:go_default_library",
|
||||
"@org_golang_google_grpc//:go_default_library",
|
||||
@@ -26,24 +33,23 @@ go_library(
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
size = "small",
|
||||
srcs = [
|
||||
"grpc_prysm_beacon_chain_client_test.go",
|
||||
"grpc_validator_client_test.go",
|
||||
"grpc_client_test.go",
|
||||
"rest_client_test.go",
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//api/client/beacon:go_default_library",
|
||||
"//api/client/beacon/mock:go_default_library",
|
||||
"//api/client/beacon/node:go_default_library",
|
||||
"//api/server/structs:go_default_library",
|
||||
"//config/params:go_default_library",
|
||||
"//consensus-types/primitives:go_default_library",
|
||||
"//consensus-types/validator:go_default_library",
|
||||
"//encoding/bytesutil:go_default_library",
|
||||
"//proto/prysm/v1alpha1:go_default_library",
|
||||
"//testing/assert:go_default_library",
|
||||
"//testing/mock:go_default_library",
|
||||
"//testing/require:go_default_library",
|
||||
"//testing/util:go_default_library",
|
||||
"//testing/validator-mock:go_default_library",
|
||||
"//validator/client/iface:go_default_library",
|
||||
"@com_github_golang_mock//gomock:go_default_library",
|
||||
"@org_golang_google_protobuf//types/known/emptypb:go_default_library",
|
||||
"@org_uber_go_mock//gomock:go_default_library",
|
||||
],
|
||||
)
|
||||
30
api/client/beacon/prysm_api/client.go
Normal file
30
api/client/beacon/prysm_api/client.go
Normal file
@@ -0,0 +1,30 @@
|
||||
package prysm_api
|
||||
|
||||
import (
|
||||
"github.com/prysmaticlabs/prysm/v5/api/client"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/client/beacon/chain"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/client/beacon/node"
|
||||
"github.com/prysmaticlabs/prysm/v5/config/features"
|
||||
validatorHelpers "github.com/prysmaticlabs/prysm/v5/validator/helpers"
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
func NewClient(validatorConn validatorHelpers.NodeConnection, jsonRestHandler client.JsonRestHandler) Client {
|
||||
if features.Get().EnableBeaconRESTApi {
|
||||
return NewPrysmChainRestClient(jsonRestHandler, node.NewClient(validatorConn, jsonRestHandler))
|
||||
} else {
|
||||
return NewGrpcPrysmChainClient(validatorConn.GetGrpcClientConn())
|
||||
}
|
||||
}
|
||||
|
||||
// NewPrysmChainClient returns implementation of Client.
|
||||
func NewPrysmChainRestClient(jsonRestHandler client.JsonRestHandler, nodeClient node.Client) Client {
|
||||
return prysmChainClient{
|
||||
jsonRestHandler: jsonRestHandler,
|
||||
nodeClient: nodeClient,
|
||||
}
|
||||
}
|
||||
|
||||
func NewGrpcPrysmChainClient(cc grpc.ClientConnInterface) Client {
|
||||
return &grpcPrysmChainClient{chainClient: chain.NewGrpcChainClient(cc)}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package grpc_api
|
||||
package prysm_api
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -6,24 +6,23 @@ import (
|
||||
"sort"
|
||||
|
||||
"github.com/golang/protobuf/ptypes/empty"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/helpers"
|
||||
statenative "github.com/prysmaticlabs/prysm/v4/beacon-chain/state/state-native"
|
||||
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
|
||||
"github.com/prysmaticlabs/prysm/v4/consensus-types/validator"
|
||||
eth "github.com/prysmaticlabs/prysm/v4/proto/eth/v1"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v4/validator/client/iface"
|
||||
"google.golang.org/grpc"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/client/beacon"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/client/beacon/chain"
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/rpc/eth/helpers"
|
||||
statenative "github.com/prysmaticlabs/prysm/v5/beacon-chain/state/state-native"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/validator"
|
||||
eth "github.com/prysmaticlabs/prysm/v5/proto/eth/v1"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
)
|
||||
|
||||
type grpcPrysmBeaconChainClient struct {
|
||||
beaconChainClient iface.BeaconChainClient
|
||||
type grpcPrysmChainClient struct {
|
||||
chainClient chain.Client
|
||||
}
|
||||
|
||||
func (g grpcPrysmBeaconChainClient) GetValidatorCount(ctx context.Context, _ string, statuses []validator.Status) ([]iface.ValidatorCount, error) {
|
||||
resp, err := g.beaconChainClient.ListValidators(ctx, ðpb.ListValidatorsRequest{PageSize: 0})
|
||||
func (g grpcPrysmChainClient) ValidatorCount(ctx context.Context, _ string, statuses []validator.Status) ([]beacon.ValidatorCount, error) {
|
||||
resp, err := g.chainClient.Validators(ctx, ðpb.ListValidatorsRequest{PageSize: 0})
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "list validators failed")
|
||||
}
|
||||
@@ -33,7 +32,7 @@ func (g grpcPrysmBeaconChainClient) GetValidatorCount(ctx context.Context, _ str
|
||||
vals = append(vals, val.Validator)
|
||||
}
|
||||
|
||||
head, err := g.beaconChainClient.GetChainHead(ctx, &empty.Empty{})
|
||||
head, err := g.chainClient.ChainHead(ctx, &empty.Empty{})
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "get chain head")
|
||||
}
|
||||
@@ -53,20 +52,20 @@ func (g grpcPrysmBeaconChainClient) GetValidatorCount(ctx context.Context, _ str
|
||||
}
|
||||
|
||||
// validatorCountByStatus returns a slice of validator count for each status in the given epoch.
|
||||
func validatorCountByStatus(validators []*ethpb.Validator, statuses []validator.Status, epoch primitives.Epoch) ([]iface.ValidatorCount, error) {
|
||||
func validatorCountByStatus(validators []*ethpb.Validator, statuses []validator.Status, epoch primitives.Epoch) ([]beacon.ValidatorCount, error) {
|
||||
countByStatus := make(map[validator.Status]uint64)
|
||||
for _, val := range validators {
|
||||
readOnlyVal, err := statenative.NewValidator(val)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not convert validator: %v", err)
|
||||
return nil, fmt.Errorf("could not convert validator: %w", err)
|
||||
}
|
||||
valStatus, err := helpers.ValidatorStatus(readOnlyVal, epoch)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not get validator status: %v", err)
|
||||
return nil, fmt.Errorf("could not get validator status: %w", err)
|
||||
}
|
||||
valSubStatus, err := helpers.ValidatorSubStatus(readOnlyVal, epoch)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not get validator sub status: %v", err)
|
||||
return nil, fmt.Errorf("could not get validator sub status: %w", err)
|
||||
}
|
||||
|
||||
for _, status := range statuses {
|
||||
@@ -76,9 +75,9 @@ func validatorCountByStatus(validators []*ethpb.Validator, statuses []validator.
|
||||
}
|
||||
}
|
||||
|
||||
var resp []iface.ValidatorCount
|
||||
var resp []beacon.ValidatorCount
|
||||
for status, count := range countByStatus {
|
||||
resp = append(resp, iface.ValidatorCount{
|
||||
resp = append(resp, beacon.ValidatorCount{
|
||||
Status: status.String(),
|
||||
Count: count,
|
||||
})
|
||||
@@ -92,6 +91,6 @@ func validatorCountByStatus(validators []*ethpb.Validator, statuses []validator.
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func NewGrpcPrysmBeaconChainClient(cc grpc.ClientConnInterface) iface.PrysmBeaconChainClient {
|
||||
return &grpcPrysmBeaconChainClient{beaconChainClient: &grpcBeaconChainClient{ethpb.NewBeaconChainClient(cc)}}
|
||||
func (c *grpcPrysmChainClient) ValidatorPerformance(ctx context.Context, in *ethpb.ValidatorPerformanceRequest) (*ethpb.ValidatorPerformanceResponse, error) {
|
||||
return c.chainClient.ValidatorPerformance(ctx, in)
|
||||
}
|
||||
@@ -1,21 +1,21 @@
|
||||
package grpc_api
|
||||
package prysm_api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/golang/mock/gomock"
|
||||
"github.com/prysmaticlabs/prysm/v4/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
|
||||
"github.com/prysmaticlabs/prysm/v4/consensus-types/validator"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v4/testing/require"
|
||||
"github.com/prysmaticlabs/prysm/v4/testing/util"
|
||||
mock "github.com/prysmaticlabs/prysm/v4/testing/validator-mock"
|
||||
"github.com/prysmaticlabs/prysm/v4/validator/client/iface"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/client/beacon"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/client/beacon/mock"
|
||||
"github.com/prysmaticlabs/prysm/v5/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/validator"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v5/testing/require"
|
||||
"github.com/prysmaticlabs/prysm/v5/testing/util"
|
||||
"go.uber.org/mock/gomock"
|
||||
)
|
||||
|
||||
func TestGetValidatorCount(t *testing.T) {
|
||||
func TestGRPC_GetValidatorCount(t *testing.T) {
|
||||
st, _ := util.DeterministicGenesisState(t, 10)
|
||||
farFutureEpoch := params.BeaconConfig().FarFutureEpoch
|
||||
validators := []*ethpb.Validator{
|
||||
@@ -83,8 +83,8 @@ func TestGetValidatorCount(t *testing.T) {
|
||||
Slashed: false,
|
||||
},
|
||||
}
|
||||
for _, validator := range validators {
|
||||
require.NoError(t, st.AppendValidator(validator))
|
||||
for _, v := range validators {
|
||||
require.NoError(t, st.AppendValidator(v))
|
||||
require.NoError(t, st.AppendBalance(params.BeaconConfig().MaxEffectiveBalance))
|
||||
}
|
||||
|
||||
@@ -92,12 +92,12 @@ func TestGetValidatorCount(t *testing.T) {
|
||||
name string
|
||||
statuses []string
|
||||
currentEpoch int
|
||||
expectedResponse []iface.ValidatorCount
|
||||
expectedResponse []beacon.ValidatorCount
|
||||
}{
|
||||
{
|
||||
name: "Head count active validators",
|
||||
statuses: []string{"active"},
|
||||
expectedResponse: []iface.ValidatorCount{
|
||||
expectedResponse: []beacon.ValidatorCount{
|
||||
{
|
||||
Status: "active",
|
||||
Count: 13,
|
||||
@@ -107,7 +107,7 @@ func TestGetValidatorCount(t *testing.T) {
|
||||
{
|
||||
name: "Head count active ongoing validators",
|
||||
statuses: []string{"active_ongoing"},
|
||||
expectedResponse: []iface.ValidatorCount{
|
||||
expectedResponse: []beacon.ValidatorCount{
|
||||
{
|
||||
Status: "active_ongoing",
|
||||
Count: 11,
|
||||
@@ -117,7 +117,7 @@ func TestGetValidatorCount(t *testing.T) {
|
||||
{
|
||||
name: "Head count active exiting validators",
|
||||
statuses: []string{"active_exiting"},
|
||||
expectedResponse: []iface.ValidatorCount{
|
||||
expectedResponse: []beacon.ValidatorCount{
|
||||
{
|
||||
Status: "active_exiting",
|
||||
Count: 1,
|
||||
@@ -127,7 +127,7 @@ func TestGetValidatorCount(t *testing.T) {
|
||||
{
|
||||
name: "Head count active slashed validators",
|
||||
statuses: []string{"active_slashed"},
|
||||
expectedResponse: []iface.ValidatorCount{
|
||||
expectedResponse: []beacon.ValidatorCount{
|
||||
{
|
||||
Status: "active_slashed",
|
||||
Count: 1,
|
||||
@@ -137,7 +137,7 @@ func TestGetValidatorCount(t *testing.T) {
|
||||
{
|
||||
name: "Head count pending validators",
|
||||
statuses: []string{"pending"},
|
||||
expectedResponse: []iface.ValidatorCount{
|
||||
expectedResponse: []beacon.ValidatorCount{
|
||||
{
|
||||
Status: "pending",
|
||||
Count: 6,
|
||||
@@ -147,7 +147,7 @@ func TestGetValidatorCount(t *testing.T) {
|
||||
{
|
||||
name: "Head count pending initialized validators",
|
||||
statuses: []string{"pending_initialized"},
|
||||
expectedResponse: []iface.ValidatorCount{
|
||||
expectedResponse: []beacon.ValidatorCount{
|
||||
{
|
||||
Status: "pending_initialized",
|
||||
Count: 1,
|
||||
@@ -157,7 +157,7 @@ func TestGetValidatorCount(t *testing.T) {
|
||||
{
|
||||
name: "Head count pending queued validators",
|
||||
statuses: []string{"pending_queued"},
|
||||
expectedResponse: []iface.ValidatorCount{
|
||||
expectedResponse: []beacon.ValidatorCount{
|
||||
{
|
||||
Status: "pending_queued",
|
||||
Count: 5,
|
||||
@@ -168,7 +168,7 @@ func TestGetValidatorCount(t *testing.T) {
|
||||
name: "Head count exited validators",
|
||||
statuses: []string{"exited"},
|
||||
currentEpoch: 35,
|
||||
expectedResponse: []iface.ValidatorCount{
|
||||
expectedResponse: []beacon.ValidatorCount{
|
||||
{
|
||||
Status: "exited",
|
||||
Count: 6,
|
||||
@@ -179,7 +179,7 @@ func TestGetValidatorCount(t *testing.T) {
|
||||
name: "Head count exited slashed validators",
|
||||
statuses: []string{"exited_slashed"},
|
||||
currentEpoch: 35,
|
||||
expectedResponse: []iface.ValidatorCount{
|
||||
expectedResponse: []beacon.ValidatorCount{
|
||||
{
|
||||
Status: "exited_slashed",
|
||||
Count: 2,
|
||||
@@ -190,7 +190,7 @@ func TestGetValidatorCount(t *testing.T) {
|
||||
name: "Head count exited unslashed validators",
|
||||
statuses: []string{"exited_unslashed"},
|
||||
currentEpoch: 35,
|
||||
expectedResponse: []iface.ValidatorCount{
|
||||
expectedResponse: []beacon.ValidatorCount{
|
||||
{
|
||||
Status: "exited_unslashed",
|
||||
Count: 4,
|
||||
@@ -201,7 +201,7 @@ func TestGetValidatorCount(t *testing.T) {
|
||||
name: "Head count withdrawal validators",
|
||||
statuses: []string{"withdrawal"},
|
||||
currentEpoch: 45,
|
||||
expectedResponse: []iface.ValidatorCount{
|
||||
expectedResponse: []beacon.ValidatorCount{
|
||||
{
|
||||
Status: "withdrawal",
|
||||
Count: 2,
|
||||
@@ -212,7 +212,7 @@ func TestGetValidatorCount(t *testing.T) {
|
||||
name: "Head count withdrawal possible validators",
|
||||
statuses: []string{"withdrawal_possible"},
|
||||
currentEpoch: 45,
|
||||
expectedResponse: []iface.ValidatorCount{
|
||||
expectedResponse: []beacon.ValidatorCount{
|
||||
{
|
||||
Status: "withdrawal_possible",
|
||||
Count: 1,
|
||||
@@ -223,7 +223,7 @@ func TestGetValidatorCount(t *testing.T) {
|
||||
name: "Head count withdrawal done validators",
|
||||
statuses: []string{"withdrawal_done"},
|
||||
currentEpoch: 45,
|
||||
expectedResponse: []iface.ValidatorCount{
|
||||
expectedResponse: []beacon.ValidatorCount{
|
||||
{
|
||||
Status: "withdrawal_done",
|
||||
Count: 1,
|
||||
@@ -233,7 +233,7 @@ func TestGetValidatorCount(t *testing.T) {
|
||||
{
|
||||
name: "Head count active and pending validators",
|
||||
statuses: []string{"active", "pending"},
|
||||
expectedResponse: []iface.ValidatorCount{
|
||||
expectedResponse: []beacon.ValidatorCount{
|
||||
{
|
||||
Status: "active",
|
||||
Count: 13,
|
||||
@@ -246,7 +246,7 @@ func TestGetValidatorCount(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "Head count of ALL validators",
|
||||
expectedResponse: []iface.ValidatorCount{
|
||||
expectedResponse: []beacon.ValidatorCount{
|
||||
{
|
||||
Status: "active",
|
||||
Count: 13,
|
||||
@@ -291,8 +291,8 @@ func TestGetValidatorCount(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
beaconChainClient := mock.NewMockBeaconChainClient(ctrl)
|
||||
beaconChainClient.EXPECT().ListValidators(
|
||||
chainClient := mock.NewMockChainClient(ctrl)
|
||||
chainClient.EXPECT().Validators(
|
||||
gomock.Any(),
|
||||
gomock.Any(),
|
||||
).Return(
|
||||
@@ -300,7 +300,7 @@ func TestGetValidatorCount(t *testing.T) {
|
||||
nil,
|
||||
)
|
||||
|
||||
beaconChainClient.EXPECT().GetChainHead(
|
||||
chainClient.EXPECT().ChainHead(
|
||||
gomock.Any(),
|
||||
gomock.Any(),
|
||||
).Return(
|
||||
@@ -308,8 +308,8 @@ func TestGetValidatorCount(t *testing.T) {
|
||||
nil,
|
||||
)
|
||||
|
||||
prysmBeaconChainClient := &grpcPrysmBeaconChainClient{
|
||||
beaconChainClient: beaconChainClient,
|
||||
prysmBeaconChainClient := &grpcPrysmChainClient{
|
||||
chainClient: chainClient,
|
||||
}
|
||||
|
||||
var statuses []validator.Status
|
||||
@@ -318,7 +318,7 @@ func TestGetValidatorCount(t *testing.T) {
|
||||
require.Equal(t, true, ok)
|
||||
statuses = append(statuses, valStatus)
|
||||
}
|
||||
vcCountResp, err := prysmBeaconChainClient.GetValidatorCount(context.Background(), "", statuses)
|
||||
vcCountResp, err := prysmBeaconChainClient.ValidatorCount(context.Background(), "", statuses)
|
||||
require.NoError(t, err)
|
||||
require.DeepEqual(t, test.expectedResponse, vcCountResp)
|
||||
})
|
||||
15
api/client/beacon/prysm_api/interfaces.go
Normal file
15
api/client/beacon/prysm_api/interfaces.go
Normal file
@@ -0,0 +1,15 @@
|
||||
package prysm_api
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/prysmaticlabs/prysm/v5/api/client/beacon"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/validator"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
)
|
||||
|
||||
// Client defines an interface required to implement all the prysm specific custom endpoints.
|
||||
type Client interface {
|
||||
ValidatorCount(context.Context, string, []validator.Status) ([]beacon.ValidatorCount, error)
|
||||
ValidatorPerformance(context.Context, *ethpb.ValidatorPerformanceRequest) (*ethpb.ValidatorPerformanceResponse, error)
|
||||
}
|
||||
108
api/client/beacon/prysm_api/rest_client.go
Normal file
108
api/client/beacon/prysm_api/rest_client.go
Normal file
@@ -0,0 +1,108 @@
|
||||
package prysm_api
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
neturl "net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/apiutil"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/client"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/client/beacon"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/client/beacon/node"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/server/structs"
|
||||
validator2 "github.com/prysmaticlabs/prysm/v5/consensus-types/validator"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
)
|
||||
|
||||
type prysmChainClient struct {
|
||||
jsonRestHandler client.JsonRestHandler
|
||||
nodeClient node.Client
|
||||
}
|
||||
|
||||
func (c prysmChainClient) ValidatorCount(ctx context.Context, stateID string, statuses []validator2.Status) ([]beacon.ValidatorCount, error) {
|
||||
// Check node version for prysm beacon node as it is a custom endpoint for prysm beacon node.
|
||||
nodeVersion, err := c.nodeClient.Version(ctx, nil)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to get node version")
|
||||
}
|
||||
|
||||
if !strings.Contains(strings.ToLower(nodeVersion.Version), "prysm") {
|
||||
return nil, client.ErrNotSupported
|
||||
}
|
||||
|
||||
queryParams := neturl.Values{}
|
||||
for _, status := range statuses {
|
||||
queryParams.Add("status", status.String())
|
||||
}
|
||||
|
||||
queryUrl := apiutil.BuildURL(fmt.Sprintf("/eth/v1/beacon/states/%s/validator_count", stateID), queryParams)
|
||||
|
||||
var validatorCountResponse structs.GetValidatorCountResponse
|
||||
if err = c.jsonRestHandler.Get(ctx, queryUrl, &validatorCountResponse); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if validatorCountResponse.Data == nil {
|
||||
return nil, errors.New("validator count data is nil")
|
||||
}
|
||||
|
||||
if len(statuses) != 0 && len(statuses) != len(validatorCountResponse.Data) {
|
||||
return nil, errors.New("mismatch between validator count data and the number of statuses provided")
|
||||
}
|
||||
|
||||
var resp []beacon.ValidatorCount
|
||||
for _, vc := range validatorCountResponse.Data {
|
||||
count, err := strconv.ParseUint(vc.Count, 10, 64)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to parse validator count %s", vc.Count)
|
||||
}
|
||||
|
||||
resp = append(resp, beacon.ValidatorCount{
|
||||
Status: vc.Status,
|
||||
Count: count,
|
||||
})
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func (c prysmChainClient) ValidatorPerformance(ctx context.Context, in *ethpb.ValidatorPerformanceRequest) (*ethpb.ValidatorPerformanceResponse, error) {
|
||||
// Check node version for prysm beacon node as it is a custom endpoint for prysm beacon node.
|
||||
nodeVersion, err := c.nodeClient.Version(ctx, nil)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to get node version")
|
||||
}
|
||||
|
||||
if !strings.Contains(strings.ToLower(nodeVersion.Version), "prysm") {
|
||||
return nil, client.ErrNotSupported
|
||||
}
|
||||
|
||||
request, err := json.Marshal(structs.GetValidatorPerformanceRequest{
|
||||
PublicKeys: in.PublicKeys,
|
||||
Indices: in.Indices,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to marshal request")
|
||||
}
|
||||
resp := &structs.GetValidatorPerformanceResponse{}
|
||||
if err = c.jsonRestHandler.Post(ctx, "/prysm/validators/performance", nil, bytes.NewBuffer(request), resp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return ðpb.ValidatorPerformanceResponse{
|
||||
CurrentEffectiveBalances: resp.CurrentEffectiveBalances,
|
||||
CorrectlyVotedSource: resp.CorrectlyVotedSource,
|
||||
CorrectlyVotedTarget: resp.CorrectlyVotedTarget,
|
||||
CorrectlyVotedHead: resp.CorrectlyVotedHead,
|
||||
BalancesBeforeEpochTransition: resp.BalancesBeforeEpochTransition,
|
||||
BalancesAfterEpochTransition: resp.BalancesAfterEpochTransition,
|
||||
MissingValidators: resp.MissingValidators,
|
||||
PublicKeys: resp.PublicKeys,
|
||||
InactivityScores: resp.InactivityScores,
|
||||
}, nil
|
||||
}
|
||||
221
api/client/beacon/prysm_api/rest_client_test.go
Normal file
221
api/client/beacon/prysm_api/rest_client_test.go
Normal file
@@ -0,0 +1,221 @@
|
||||
package prysm_api
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
"github.com/prysmaticlabs/prysm/v5/api/client/beacon"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/client/beacon/mock"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/client/beacon/node"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/server/structs"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/validator"
|
||||
"github.com/prysmaticlabs/prysm/v5/encoding/bytesutil"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v5/testing/require"
|
||||
"go.uber.org/mock/gomock"
|
||||
)
|
||||
|
||||
func TestGetValidatorCount(t *testing.T) {
|
||||
const nodeVersion = "prysm/v0.0.1"
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
versionEndpointError error
|
||||
validatorCountEndpointError error
|
||||
versionResponse structs.GetVersionResponse
|
||||
validatorCountResponse structs.GetValidatorCountResponse
|
||||
validatorCountCalled int
|
||||
expectedResponse []beacon.ValidatorCount
|
||||
expectedError string
|
||||
}{
|
||||
{
|
||||
name: "success",
|
||||
versionResponse: structs.GetVersionResponse{
|
||||
Data: &structs.Version{Version: nodeVersion},
|
||||
},
|
||||
validatorCountResponse: structs.GetValidatorCountResponse{
|
||||
ExecutionOptimistic: "false",
|
||||
Finalized: "true",
|
||||
Data: []*structs.ValidatorCount{
|
||||
{
|
||||
Status: "active",
|
||||
Count: "10",
|
||||
},
|
||||
},
|
||||
},
|
||||
validatorCountCalled: 1,
|
||||
expectedResponse: []beacon.ValidatorCount{
|
||||
{
|
||||
Status: "active",
|
||||
Count: 10,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "not supported beacon node",
|
||||
versionResponse: structs.GetVersionResponse{
|
||||
Data: &structs.Version{Version: "lighthouse/v0.0.1"},
|
||||
},
|
||||
expectedError: "endpoint not supported",
|
||||
},
|
||||
{
|
||||
name: "fails to get version",
|
||||
versionEndpointError: errors.New("foo error"),
|
||||
expectedError: "failed to get node version",
|
||||
},
|
||||
{
|
||||
name: "fails to get validator count",
|
||||
versionResponse: structs.GetVersionResponse{
|
||||
Data: &structs.Version{Version: nodeVersion},
|
||||
},
|
||||
validatorCountEndpointError: errors.New("foo error"),
|
||||
validatorCountCalled: 1,
|
||||
expectedError: "foo error",
|
||||
},
|
||||
{
|
||||
name: "nil validator count data",
|
||||
versionResponse: structs.GetVersionResponse{
|
||||
Data: &structs.Version{Version: nodeVersion},
|
||||
},
|
||||
validatorCountResponse: structs.GetValidatorCountResponse{
|
||||
ExecutionOptimistic: "false",
|
||||
Finalized: "true",
|
||||
Data: nil,
|
||||
},
|
||||
validatorCountCalled: 1,
|
||||
expectedError: "validator count data is nil",
|
||||
},
|
||||
{
|
||||
name: "invalid validator count",
|
||||
versionResponse: structs.GetVersionResponse{
|
||||
Data: &structs.Version{Version: nodeVersion},
|
||||
},
|
||||
validatorCountResponse: structs.GetValidatorCountResponse{
|
||||
ExecutionOptimistic: "false",
|
||||
Finalized: "true",
|
||||
Data: []*structs.ValidatorCount{
|
||||
{
|
||||
Status: "active",
|
||||
Count: "10",
|
||||
},
|
||||
{
|
||||
Status: "exited",
|
||||
Count: "10",
|
||||
},
|
||||
},
|
||||
},
|
||||
validatorCountCalled: 1,
|
||||
expectedError: "mismatch between validator count data and the number of statuses provided",
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range testCases {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
|
||||
ctx := context.Background()
|
||||
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
|
||||
|
||||
// Expect node version endpoint call.
|
||||
var nodeVersionResponse structs.GetVersionResponse
|
||||
jsonRestHandler.EXPECT().Get(
|
||||
gomock.Any(),
|
||||
"/eth/v1/node/version",
|
||||
&nodeVersionResponse,
|
||||
).Return(
|
||||
test.versionEndpointError,
|
||||
).SetArg(
|
||||
2,
|
||||
test.versionResponse,
|
||||
)
|
||||
|
||||
var validatorCountResponse structs.GetValidatorCountResponse
|
||||
jsonRestHandler.EXPECT().Get(
|
||||
gomock.Any(),
|
||||
"/eth/v1/beacon/states/head/validator_count?status=active",
|
||||
&validatorCountResponse,
|
||||
).Return(
|
||||
test.validatorCountEndpointError,
|
||||
).SetArg(
|
||||
2,
|
||||
test.validatorCountResponse,
|
||||
).Times(test.validatorCountCalled)
|
||||
|
||||
// Type assertion.
|
||||
var client Client = &prysmChainClient{
|
||||
nodeClient: node.NewNodeClientWithFallback(jsonRestHandler, nil),
|
||||
jsonRestHandler: jsonRestHandler,
|
||||
}
|
||||
|
||||
countResponse, err := client.ValidatorCount(ctx, "head", []validator.Status{validator.Active})
|
||||
|
||||
if len(test.expectedResponse) == 0 {
|
||||
require.ErrorContains(t, test.expectedError, err)
|
||||
} else {
|
||||
require.NoError(t, err)
|
||||
require.DeepEqual(t, test.expectedResponse, countResponse)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_beaconApiBeaconChainClient_GetValidatorPerformance(t *testing.T) {
|
||||
const nodeVersion = "prysm/v0.0.1"
|
||||
publicKeys := [][48]byte{
|
||||
bytesutil.ToBytes48([]byte{1}),
|
||||
bytesutil.ToBytes48([]byte{2}),
|
||||
bytesutil.ToBytes48([]byte{3}),
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
|
||||
request, err := json.Marshal(structs.GetValidatorPerformanceRequest{
|
||||
PublicKeys: [][]byte{publicKeys[0][:], publicKeys[2][:], publicKeys[1][:]},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
|
||||
// Expect node version endpoint call.
|
||||
var nodeVersionResponse structs.GetVersionResponse
|
||||
jsonRestHandler.EXPECT().Get(
|
||||
gomock.Any(),
|
||||
"/eth/v1/node/version",
|
||||
&nodeVersionResponse,
|
||||
).Return(
|
||||
nil,
|
||||
).SetArg(
|
||||
2,
|
||||
structs.GetVersionResponse{
|
||||
Data: &structs.Version{Version: nodeVersion},
|
||||
},
|
||||
)
|
||||
|
||||
wantResponse := &structs.GetValidatorPerformanceResponse{}
|
||||
want := ðpb.ValidatorPerformanceResponse{}
|
||||
|
||||
jsonRestHandler.EXPECT().Post(
|
||||
gomock.Any(),
|
||||
"/prysm/validators/performance",
|
||||
nil,
|
||||
bytes.NewBuffer(request),
|
||||
wantResponse,
|
||||
).Return(
|
||||
nil,
|
||||
)
|
||||
|
||||
var client Client = &prysmChainClient{
|
||||
nodeClient: node.NewNodeClientWithFallback(jsonRestHandler, nil),
|
||||
jsonRestHandler: jsonRestHandler,
|
||||
}
|
||||
|
||||
got, err := client.ValidatorPerformance(ctx, ðpb.ValidatorPerformanceRequest{
|
||||
PublicKeys: [][]byte{publicKeys[0][:], publicKeys[2][:], publicKeys[1][:]},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.DeepEqual(t, want.PublicKeys, got.PublicKeys)
|
||||
}
|
||||
42
api/client/beacon/shared_providers/BUILD.bazel
Normal file
42
api/client/beacon/shared_providers/BUILD.bazel
Normal file
@@ -0,0 +1,42 @@
|
||||
load("@prysm//tools/go:def.bzl", "go_library", "go_test")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"duties.go",
|
||||
"genesis.go",
|
||||
"interfaces.go",
|
||||
"providers.go",
|
||||
"state_validators.go",
|
||||
],
|
||||
importpath = "github.com/prysmaticlabs/prysm/v5/api/client/beacon/shared_providers",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//api/client:go_default_library",
|
||||
"//api/client/apiutil:go_default_library",
|
||||
"//api/server/structs:go_default_library",
|
||||
"//consensus-types/primitives:go_default_library",
|
||||
"@com_github_pkg_errors//:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = [
|
||||
"duties_test.go",
|
||||
"genesis_test.go",
|
||||
"state_validators_test.go",
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//api/client/apiutil:go_default_library",
|
||||
"//api/client/beacon/mock:go_default_library",
|
||||
"//api/server/structs:go_default_library",
|
||||
"//consensus-types/primitives:go_default_library",
|
||||
"//testing/assert:go_default_library",
|
||||
"//testing/require:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//common/hexutil:go_default_library",
|
||||
"@com_github_pkg_errors//:go_default_library",
|
||||
"@org_uber_go_mock//gomock:go_default_library",
|
||||
],
|
||||
)
|
||||
132
api/client/beacon/shared_providers/duties.go
Normal file
132
api/client/beacon/shared_providers/duties.go
Normal file
@@ -0,0 +1,132 @@
|
||||
package shared_providers
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/apiutil"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/client"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/server/structs"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
)
|
||||
|
||||
type dutiesProvider struct {
|
||||
jsonRestHandler client.JsonRestHandler
|
||||
}
|
||||
|
||||
// Committees retrieves the committees for the given epoch
|
||||
func (c dutiesProvider) Committees(ctx context.Context, epoch primitives.Epoch) ([]*structs.Committee, error) {
|
||||
committeeParams := url.Values{}
|
||||
committeeParams.Add("epoch", strconv.FormatUint(uint64(epoch), 10))
|
||||
committeesRequest := apiutil.BuildURL("/eth/v1/beacon/states/head/committees", committeeParams)
|
||||
|
||||
var stateCommittees structs.GetCommitteesResponse
|
||||
if err := c.jsonRestHandler.Get(ctx, committeesRequest, &stateCommittees); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if stateCommittees.Data == nil {
|
||||
return nil, errors.New("state committees data is nil")
|
||||
}
|
||||
|
||||
for index, committee := range stateCommittees.Data {
|
||||
if committee == nil {
|
||||
return nil, errors.Errorf("committee at index `%d` is nil", index)
|
||||
}
|
||||
}
|
||||
|
||||
return stateCommittees.Data, nil
|
||||
}
|
||||
|
||||
// AttesterDuties retrieves the attester duties for the given epoch and validatorIndices
|
||||
func (c dutiesProvider) AttesterDuties(ctx context.Context, epoch primitives.Epoch, validatorIndices []primitives.ValidatorIndex) ([]*structs.AttesterDuty, error) {
|
||||
jsonValidatorIndices := make([]string, len(validatorIndices))
|
||||
for index, validatorIndex := range validatorIndices {
|
||||
jsonValidatorIndices[index] = strconv.FormatUint(uint64(validatorIndex), 10)
|
||||
}
|
||||
|
||||
validatorIndicesBytes, err := json.Marshal(jsonValidatorIndices)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to marshal validator indices")
|
||||
}
|
||||
|
||||
attesterDuties := &structs.GetAttesterDutiesResponse{}
|
||||
if err = c.jsonRestHandler.Post(
|
||||
ctx,
|
||||
fmt.Sprintf("/eth/v1/validator/duties/attester/%d", epoch),
|
||||
nil,
|
||||
bytes.NewBuffer(validatorIndicesBytes),
|
||||
attesterDuties,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for index, attesterDuty := range attesterDuties.Data {
|
||||
if attesterDuty == nil {
|
||||
return nil, errors.Errorf("attester duty at index `%d` is nil", index)
|
||||
}
|
||||
}
|
||||
|
||||
return attesterDuties.Data, nil
|
||||
}
|
||||
|
||||
// ProposerDuties retrieves the proposer duties for the given epoch
|
||||
func (c dutiesProvider) ProposerDuties(ctx context.Context, epoch primitives.Epoch) ([]*structs.ProposerDuty, error) {
|
||||
proposerDuties := structs.GetProposerDutiesResponse{}
|
||||
if err := c.jsonRestHandler.Get(ctx, fmt.Sprintf("/eth/v1/validator/duties/proposer/%d", epoch), &proposerDuties); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if proposerDuties.Data == nil {
|
||||
return nil, errors.New("proposer duties data is nil")
|
||||
}
|
||||
|
||||
for index, proposerDuty := range proposerDuties.Data {
|
||||
if proposerDuty == nil {
|
||||
return nil, errors.Errorf("proposer duty at index `%d` is nil", index)
|
||||
}
|
||||
}
|
||||
|
||||
return proposerDuties.Data, nil
|
||||
}
|
||||
|
||||
// SyncDuties retrieves the sync committee duties for the given epoch and validatorIndices
|
||||
func (c dutiesProvider) SyncDuties(ctx context.Context, epoch primitives.Epoch, validatorIndices []primitives.ValidatorIndex) ([]*structs.SyncCommitteeDuty, error) {
|
||||
jsonValidatorIndices := make([]string, len(validatorIndices))
|
||||
for index, validatorIndex := range validatorIndices {
|
||||
jsonValidatorIndices[index] = strconv.FormatUint(uint64(validatorIndex), 10)
|
||||
}
|
||||
|
||||
validatorIndicesBytes, err := json.Marshal(jsonValidatorIndices)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to marshal validator indices")
|
||||
}
|
||||
|
||||
syncDuties := structs.GetSyncCommitteeDutiesResponse{}
|
||||
if err = c.jsonRestHandler.Post(
|
||||
ctx,
|
||||
fmt.Sprintf("/eth/v1/validator/duties/sync/%d", epoch),
|
||||
nil,
|
||||
bytes.NewBuffer(validatorIndicesBytes),
|
||||
&syncDuties,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if syncDuties.Data == nil {
|
||||
return nil, errors.New("sync duties data is nil")
|
||||
}
|
||||
|
||||
for index, syncDuty := range syncDuties.Data {
|
||||
if syncDuty == nil {
|
||||
return nil, errors.Errorf("sync duty at index `%d` is nil", index)
|
||||
}
|
||||
}
|
||||
|
||||
return syncDuties.Data, nil
|
||||
}
|
||||
508
api/client/beacon/shared_providers/duties_test.go
Normal file
508
api/client/beacon/shared_providers/duties_test.go
Normal file
@@ -0,0 +1,508 @@
|
||||
package shared_providers
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/client/beacon/mock"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/server/structs"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
"github.com/prysmaticlabs/prysm/v5/testing/assert"
|
||||
"github.com/prysmaticlabs/prysm/v5/testing/require"
|
||||
"go.uber.org/mock/gomock"
|
||||
)
|
||||
|
||||
const getAttesterDutiesTestEndpoint = "/eth/v1/validator/duties/attester"
|
||||
const getProposerDutiesTestEndpoint = "/eth/v1/validator/duties/proposer"
|
||||
const getSyncDutiesTestEndpoint = "/eth/v1/validator/duties/sync"
|
||||
const getCommitteesTestEndpoint = "/eth/v1/beacon/states/head/committees"
|
||||
|
||||
func TestGetAttesterDuties_Valid(t *testing.T) {
|
||||
stringValidatorIndices := []string{"2", "9"}
|
||||
const epoch = primitives.Epoch(1)
|
||||
|
||||
validatorIndicesBytes, err := json.Marshal(stringValidatorIndices)
|
||||
require.NoError(t, err)
|
||||
|
||||
expectedAttesterDuties := structs.GetAttesterDutiesResponse{
|
||||
Data: []*structs.AttesterDuty{
|
||||
{
|
||||
Pubkey: hexutil.Encode([]byte{1}),
|
||||
ValidatorIndex: "2",
|
||||
CommitteeIndex: "3",
|
||||
CommitteeLength: "4",
|
||||
CommitteesAtSlot: "5",
|
||||
ValidatorCommitteeIndex: "6",
|
||||
Slot: "7",
|
||||
},
|
||||
{
|
||||
Pubkey: hexutil.Encode([]byte{8}),
|
||||
ValidatorIndex: "9",
|
||||
CommitteeIndex: "10",
|
||||
CommitteeLength: "11",
|
||||
CommitteesAtSlot: "12",
|
||||
ValidatorCommitteeIndex: "13",
|
||||
Slot: "14",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
validatorIndices := []primitives.ValidatorIndex{2, 9}
|
||||
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
|
||||
jsonRestHandler.EXPECT().Post(
|
||||
gomock.Any(),
|
||||
fmt.Sprintf("%s/%d", getAttesterDutiesTestEndpoint, epoch),
|
||||
nil,
|
||||
bytes.NewBuffer(validatorIndicesBytes),
|
||||
&structs.GetAttesterDutiesResponse{},
|
||||
).Return(
|
||||
nil,
|
||||
).SetArg(
|
||||
4,
|
||||
expectedAttesterDuties,
|
||||
).Times(1)
|
||||
|
||||
dutiesProvider := &dutiesProvider{jsonRestHandler: jsonRestHandler}
|
||||
attesterDuties, err := dutiesProvider.AttesterDuties(ctx, epoch, validatorIndices)
|
||||
require.NoError(t, err)
|
||||
assert.DeepEqual(t, expectedAttesterDuties.Data, attesterDuties)
|
||||
}
|
||||
|
||||
func TestGetAttesterDuties_HttpError(t *testing.T) {
|
||||
const epoch = primitives.Epoch(1)
|
||||
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
|
||||
jsonRestHandler.EXPECT().Post(
|
||||
gomock.Any(),
|
||||
fmt.Sprintf("%s/%d", getAttesterDutiesTestEndpoint, epoch),
|
||||
gomock.Any(),
|
||||
gomock.Any(),
|
||||
gomock.Any(),
|
||||
).Return(
|
||||
errors.New("foo error"),
|
||||
).Times(1)
|
||||
|
||||
dutiesProvider := &dutiesProvider{jsonRestHandler: jsonRestHandler}
|
||||
_, err := dutiesProvider.AttesterDuties(ctx, epoch, nil)
|
||||
assert.ErrorContains(t, "foo error", err)
|
||||
}
|
||||
|
||||
func TestGetAttesterDuties_NilAttesterDuty(t *testing.T) {
|
||||
const epoch = primitives.Epoch(1)
|
||||
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
|
||||
jsonRestHandler.EXPECT().Post(
|
||||
gomock.Any(),
|
||||
fmt.Sprintf("%s/%d", getAttesterDutiesTestEndpoint, epoch),
|
||||
gomock.Any(),
|
||||
gomock.Any(),
|
||||
gomock.Any(),
|
||||
).Return(
|
||||
nil,
|
||||
).SetArg(
|
||||
4,
|
||||
structs.GetAttesterDutiesResponse{
|
||||
Data: []*structs.AttesterDuty{nil},
|
||||
},
|
||||
).Times(1)
|
||||
|
||||
dutiesProvider := &dutiesProvider{jsonRestHandler: jsonRestHandler}
|
||||
_, err := dutiesProvider.AttesterDuties(ctx, epoch, nil)
|
||||
assert.ErrorContains(t, "attester duty at index `0` is nil", err)
|
||||
}
|
||||
|
||||
func TestGetProposerDuties_Valid(t *testing.T) {
|
||||
const epoch = primitives.Epoch(1)
|
||||
|
||||
expectedProposerDuties := structs.GetProposerDutiesResponse{
|
||||
Data: []*structs.ProposerDuty{
|
||||
{
|
||||
Pubkey: hexutil.Encode([]byte{1}),
|
||||
ValidatorIndex: "2",
|
||||
Slot: "3",
|
||||
},
|
||||
{
|
||||
Pubkey: hexutil.Encode([]byte{4}),
|
||||
ValidatorIndex: "5",
|
||||
Slot: "6",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
|
||||
jsonRestHandler.EXPECT().Get(
|
||||
gomock.Any(),
|
||||
fmt.Sprintf("%s/%d", getProposerDutiesTestEndpoint, epoch),
|
||||
&structs.GetProposerDutiesResponse{},
|
||||
).Return(
|
||||
nil,
|
||||
).SetArg(
|
||||
2,
|
||||
expectedProposerDuties,
|
||||
).Times(1)
|
||||
|
||||
dutiesProvider := &dutiesProvider{jsonRestHandler: jsonRestHandler}
|
||||
proposerDuties, err := dutiesProvider.ProposerDuties(ctx, epoch)
|
||||
require.NoError(t, err)
|
||||
assert.DeepEqual(t, expectedProposerDuties.Data, proposerDuties)
|
||||
}
|
||||
|
||||
func TestGetProposerDuties_HttpError(t *testing.T) {
|
||||
const epoch = primitives.Epoch(1)
|
||||
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
|
||||
jsonRestHandler.EXPECT().Get(
|
||||
gomock.Any(),
|
||||
fmt.Sprintf("%s/%d", getProposerDutiesTestEndpoint, epoch),
|
||||
gomock.Any(),
|
||||
).Return(
|
||||
errors.New("foo error"),
|
||||
).Times(1)
|
||||
|
||||
dutiesProvider := &dutiesProvider{jsonRestHandler: jsonRestHandler}
|
||||
_, err := dutiesProvider.ProposerDuties(ctx, epoch)
|
||||
assert.ErrorContains(t, "foo error", err)
|
||||
}
|
||||
|
||||
func TestGetProposerDuties_NilData(t *testing.T) {
|
||||
const epoch = primitives.Epoch(1)
|
||||
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
|
||||
jsonRestHandler.EXPECT().Get(
|
||||
gomock.Any(),
|
||||
fmt.Sprintf("%s/%d", getProposerDutiesTestEndpoint, epoch),
|
||||
gomock.Any(),
|
||||
).Return(
|
||||
nil,
|
||||
).SetArg(
|
||||
2,
|
||||
structs.GetProposerDutiesResponse{
|
||||
Data: nil,
|
||||
},
|
||||
).Times(1)
|
||||
|
||||
dutiesProvider := &dutiesProvider{jsonRestHandler: jsonRestHandler}
|
||||
_, err := dutiesProvider.ProposerDuties(ctx, epoch)
|
||||
assert.ErrorContains(t, "proposer duties data is nil", err)
|
||||
}
|
||||
|
||||
func TestGetProposerDuties_NilProposerDuty(t *testing.T) {
|
||||
const epoch = primitives.Epoch(1)
|
||||
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
|
||||
jsonRestHandler.EXPECT().Get(
|
||||
gomock.Any(),
|
||||
fmt.Sprintf("%s/%d", getProposerDutiesTestEndpoint, epoch),
|
||||
gomock.Any(),
|
||||
).Return(
|
||||
nil,
|
||||
).SetArg(
|
||||
2,
|
||||
structs.GetProposerDutiesResponse{
|
||||
Data: []*structs.ProposerDuty{nil},
|
||||
},
|
||||
).Times(1)
|
||||
|
||||
dutiesProvider := &dutiesProvider{jsonRestHandler: jsonRestHandler}
|
||||
_, err := dutiesProvider.ProposerDuties(ctx, epoch)
|
||||
assert.ErrorContains(t, "proposer duty at index `0` is nil", err)
|
||||
}
|
||||
|
||||
func TestGetSyncDuties_Valid(t *testing.T) {
|
||||
stringValidatorIndices := []string{"2", "6"}
|
||||
const epoch = primitives.Epoch(1)
|
||||
|
||||
validatorIndicesBytes, err := json.Marshal(stringValidatorIndices)
|
||||
require.NoError(t, err)
|
||||
|
||||
expectedSyncDuties := structs.GetSyncCommitteeDutiesResponse{
|
||||
Data: []*structs.SyncCommitteeDuty{
|
||||
{
|
||||
Pubkey: hexutil.Encode([]byte{1}),
|
||||
ValidatorIndex: "2",
|
||||
ValidatorSyncCommitteeIndices: []string{
|
||||
"3",
|
||||
"4",
|
||||
},
|
||||
},
|
||||
{
|
||||
Pubkey: hexutil.Encode([]byte{5}),
|
||||
ValidatorIndex: "6",
|
||||
ValidatorSyncCommitteeIndices: []string{
|
||||
"7",
|
||||
"8",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
validatorIndices := []primitives.ValidatorIndex{2, 6}
|
||||
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
|
||||
jsonRestHandler.EXPECT().Post(
|
||||
gomock.Any(),
|
||||
fmt.Sprintf("%s/%d", getSyncDutiesTestEndpoint, epoch),
|
||||
nil,
|
||||
bytes.NewBuffer(validatorIndicesBytes),
|
||||
&structs.GetSyncCommitteeDutiesResponse{},
|
||||
).Return(
|
||||
nil,
|
||||
).SetArg(
|
||||
4,
|
||||
expectedSyncDuties,
|
||||
).Times(1)
|
||||
|
||||
dutiesProvider := &dutiesProvider{jsonRestHandler: jsonRestHandler}
|
||||
syncDuties, err := dutiesProvider.SyncDuties(ctx, epoch, validatorIndices)
|
||||
require.NoError(t, err)
|
||||
assert.DeepEqual(t, expectedSyncDuties.Data, syncDuties)
|
||||
}
|
||||
|
||||
func TestGetSyncDuties_HttpError(t *testing.T) {
|
||||
const epoch = primitives.Epoch(1)
|
||||
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
|
||||
jsonRestHandler.EXPECT().Post(
|
||||
gomock.Any(),
|
||||
fmt.Sprintf("%s/%d", getSyncDutiesTestEndpoint, epoch),
|
||||
gomock.Any(),
|
||||
gomock.Any(),
|
||||
gomock.Any(),
|
||||
).Return(
|
||||
errors.New("foo error"),
|
||||
).Times(1)
|
||||
|
||||
dutiesProvider := &dutiesProvider{jsonRestHandler: jsonRestHandler}
|
||||
_, err := dutiesProvider.SyncDuties(ctx, epoch, nil)
|
||||
assert.ErrorContains(t, "foo error", err)
|
||||
}
|
||||
|
||||
func TestGetSyncDuties_NilData(t *testing.T) {
|
||||
const epoch = primitives.Epoch(1)
|
||||
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
|
||||
jsonRestHandler.EXPECT().Post(
|
||||
gomock.Any(),
|
||||
fmt.Sprintf("%s/%d", getSyncDutiesTestEndpoint, epoch),
|
||||
gomock.Any(),
|
||||
gomock.Any(),
|
||||
gomock.Any(),
|
||||
).Return(
|
||||
nil,
|
||||
).SetArg(
|
||||
4,
|
||||
structs.GetSyncCommitteeDutiesResponse{
|
||||
Data: nil,
|
||||
},
|
||||
).Times(1)
|
||||
|
||||
dutiesProvider := &dutiesProvider{jsonRestHandler: jsonRestHandler}
|
||||
_, err := dutiesProvider.SyncDuties(ctx, epoch, nil)
|
||||
assert.ErrorContains(t, "sync duties data is nil", err)
|
||||
}
|
||||
|
||||
func TestGetSyncDuties_NilSyncDuty(t *testing.T) {
|
||||
const epoch = primitives.Epoch(1)
|
||||
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
|
||||
jsonRestHandler.EXPECT().Post(
|
||||
gomock.Any(),
|
||||
fmt.Sprintf("%s/%d", getSyncDutiesTestEndpoint, epoch),
|
||||
gomock.Any(),
|
||||
gomock.Any(),
|
||||
gomock.Any(),
|
||||
).Return(
|
||||
nil,
|
||||
).SetArg(
|
||||
4,
|
||||
structs.GetSyncCommitteeDutiesResponse{
|
||||
Data: []*structs.SyncCommitteeDuty{nil},
|
||||
},
|
||||
).Times(1)
|
||||
|
||||
dutiesProvider := &dutiesProvider{jsonRestHandler: jsonRestHandler}
|
||||
_, err := dutiesProvider.SyncDuties(ctx, epoch, nil)
|
||||
assert.ErrorContains(t, "sync duty at index `0` is nil", err)
|
||||
}
|
||||
|
||||
func TestGetCommittees_Valid(t *testing.T) {
|
||||
const epoch = primitives.Epoch(1)
|
||||
|
||||
expectedCommittees := structs.GetCommitteesResponse{
|
||||
Data: []*structs.Committee{
|
||||
{
|
||||
Index: "1",
|
||||
Slot: "2",
|
||||
Validators: []string{
|
||||
"3",
|
||||
"4",
|
||||
},
|
||||
},
|
||||
{
|
||||
Index: "5",
|
||||
Slot: "6",
|
||||
Validators: []string{
|
||||
"7",
|
||||
"8",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
|
||||
jsonRestHandler.EXPECT().Get(
|
||||
gomock.Any(),
|
||||
fmt.Sprintf("%s?epoch=%d", getCommitteesTestEndpoint, epoch),
|
||||
&structs.GetCommitteesResponse{},
|
||||
).Return(
|
||||
nil,
|
||||
).SetArg(
|
||||
2,
|
||||
expectedCommittees,
|
||||
).Times(1)
|
||||
|
||||
dutiesProvider := &dutiesProvider{jsonRestHandler: jsonRestHandler}
|
||||
committees, err := dutiesProvider.Committees(ctx, epoch)
|
||||
require.NoError(t, err)
|
||||
assert.DeepEqual(t, expectedCommittees.Data, committees)
|
||||
}
|
||||
|
||||
func TestGetCommittees_HttpError(t *testing.T) {
|
||||
const epoch = primitives.Epoch(1)
|
||||
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
|
||||
jsonRestHandler.EXPECT().Get(
|
||||
gomock.Any(),
|
||||
fmt.Sprintf("%s?epoch=%d", getCommitteesTestEndpoint, epoch),
|
||||
gomock.Any(),
|
||||
).Return(
|
||||
errors.New("foo error"),
|
||||
).Times(1)
|
||||
|
||||
dutiesProvider := &dutiesProvider{jsonRestHandler: jsonRestHandler}
|
||||
_, err := dutiesProvider.Committees(ctx, epoch)
|
||||
assert.ErrorContains(t, "foo error", err)
|
||||
}
|
||||
|
||||
func TestGetCommittees_NilData(t *testing.T) {
|
||||
const epoch = primitives.Epoch(1)
|
||||
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
|
||||
jsonRestHandler.EXPECT().Get(
|
||||
gomock.Any(),
|
||||
fmt.Sprintf("%s?epoch=%d", getCommitteesTestEndpoint, epoch),
|
||||
gomock.Any(),
|
||||
).Return(
|
||||
nil,
|
||||
).SetArg(
|
||||
2,
|
||||
structs.GetCommitteesResponse{
|
||||
Data: nil,
|
||||
},
|
||||
).Times(1)
|
||||
|
||||
dutiesProvider := &dutiesProvider{jsonRestHandler: jsonRestHandler}
|
||||
_, err := dutiesProvider.Committees(ctx, epoch)
|
||||
assert.ErrorContains(t, "state committees data is nil", err)
|
||||
}
|
||||
|
||||
func TestGetCommittees_NilCommittee(t *testing.T) {
|
||||
const epoch = primitives.Epoch(1)
|
||||
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
|
||||
jsonRestHandler.EXPECT().Get(
|
||||
gomock.Any(),
|
||||
fmt.Sprintf("%s?epoch=%d", getCommitteesTestEndpoint, epoch),
|
||||
gomock.Any(),
|
||||
).Return(
|
||||
nil,
|
||||
).SetArg(
|
||||
2,
|
||||
structs.GetCommitteesResponse{
|
||||
Data: []*structs.Committee{nil},
|
||||
},
|
||||
).Times(1)
|
||||
|
||||
dutiesProvider := &dutiesProvider{jsonRestHandler: jsonRestHandler}
|
||||
_, err := dutiesProvider.Committees(ctx, epoch)
|
||||
assert.ErrorContains(t, "committee at index `0` is nil", err)
|
||||
}
|
||||
38
api/client/beacon/shared_providers/genesis.go
Normal file
38
api/client/beacon/shared_providers/genesis.go
Normal file
@@ -0,0 +1,38 @@
|
||||
package shared_providers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/client"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/server/structs"
|
||||
)
|
||||
|
||||
type genesisProvider struct {
|
||||
jsonRestHandler client.JsonRestHandler
|
||||
genesis *structs.Genesis
|
||||
once sync.Once
|
||||
}
|
||||
|
||||
// GetGenesis gets the genesis information from the beacon node via the /eth/v1/beacon/genesis endpoint
|
||||
func (c *genesisProvider) Genesis(ctx context.Context) (*structs.Genesis, error) {
|
||||
genesisJson := &structs.GetGenesisResponse{}
|
||||
var doErr error
|
||||
c.once.Do(func() {
|
||||
if err := c.jsonRestHandler.Get(ctx, "/eth/v1/beacon/genesis", genesisJson); err != nil {
|
||||
doErr = err
|
||||
return
|
||||
}
|
||||
if genesisJson.Data == nil {
|
||||
doErr = errors.New("genesis data is nil")
|
||||
return
|
||||
}
|
||||
c.genesis = genesisJson.Data
|
||||
})
|
||||
if doErr != nil {
|
||||
// Allow another call because the current one returned an error
|
||||
c.once = sync.Once{}
|
||||
}
|
||||
return c.genesis, doErr
|
||||
}
|
||||
144
api/client/beacon/shared_providers/genesis_test.go
Normal file
144
api/client/beacon/shared_providers/genesis_test.go
Normal file
@@ -0,0 +1,144 @@
|
||||
package shared_providers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/client/beacon/mock"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/server/structs"
|
||||
"github.com/prysmaticlabs/prysm/v5/testing/assert"
|
||||
"github.com/prysmaticlabs/prysm/v5/testing/require"
|
||||
"go.uber.org/mock/gomock"
|
||||
)
|
||||
|
||||
func TestGetGenesis_ValidGenesis(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
genesisResponseJson := structs.GetGenesisResponse{}
|
||||
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
|
||||
jsonRestHandler.EXPECT().Get(
|
||||
gomock.Any(),
|
||||
"/eth/v1/beacon/genesis",
|
||||
&genesisResponseJson,
|
||||
).Return(
|
||||
nil,
|
||||
).SetArg(
|
||||
2,
|
||||
structs.GetGenesisResponse{
|
||||
Data: &structs.Genesis{
|
||||
GenesisTime: "1234",
|
||||
GenesisValidatorsRoot: "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2",
|
||||
},
|
||||
},
|
||||
).Times(1)
|
||||
|
||||
genesisProvider := &genesisProvider{jsonRestHandler: jsonRestHandler}
|
||||
resp, err := genesisProvider.Genesis(ctx)
|
||||
assert.NoError(t, err)
|
||||
require.NotNil(t, resp)
|
||||
assert.Equal(t, "1234", resp.GenesisTime)
|
||||
assert.Equal(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", resp.GenesisValidatorsRoot)
|
||||
}
|
||||
|
||||
func TestGetGenesis_NilData(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
genesisResponseJson := structs.GetGenesisResponse{}
|
||||
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
|
||||
jsonRestHandler.EXPECT().Get(
|
||||
gomock.Any(),
|
||||
"/eth/v1/beacon/genesis",
|
||||
&genesisResponseJson,
|
||||
).Return(
|
||||
nil,
|
||||
).SetArg(
|
||||
2,
|
||||
structs.GetGenesisResponse{Data: nil},
|
||||
).Times(1)
|
||||
|
||||
genesisProvider := &genesisProvider{jsonRestHandler: jsonRestHandler}
|
||||
_, err := genesisProvider.Genesis(ctx)
|
||||
assert.ErrorContains(t, "genesis data is nil", err)
|
||||
}
|
||||
|
||||
func TestGetGenesis_EndpointCalledOnlyOnce(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
genesisResponseJson := structs.GetGenesisResponse{}
|
||||
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
|
||||
jsonRestHandler.EXPECT().Get(
|
||||
gomock.Any(),
|
||||
"/eth/v1/beacon/genesis",
|
||||
&genesisResponseJson,
|
||||
).Return(
|
||||
nil,
|
||||
).SetArg(
|
||||
2,
|
||||
structs.GetGenesisResponse{
|
||||
Data: &structs.Genesis{
|
||||
GenesisTime: "1234",
|
||||
GenesisValidatorsRoot: "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2",
|
||||
},
|
||||
},
|
||||
).Times(1)
|
||||
|
||||
genesisProvider := &genesisProvider{jsonRestHandler: jsonRestHandler}
|
||||
_, err := genesisProvider.Genesis(ctx)
|
||||
assert.NoError(t, err)
|
||||
resp, err := genesisProvider.Genesis(ctx)
|
||||
assert.NoError(t, err)
|
||||
require.NotNil(t, resp)
|
||||
assert.Equal(t, "1234", resp.GenesisTime)
|
||||
assert.Equal(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", resp.GenesisValidatorsRoot)
|
||||
}
|
||||
|
||||
func TestGetGenesis_EndpointCanBeCalledAgainAfterError(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
genesisResponseJson := structs.GetGenesisResponse{}
|
||||
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
|
||||
jsonRestHandler.EXPECT().Get(
|
||||
gomock.Any(),
|
||||
"/eth/v1/beacon/genesis",
|
||||
&genesisResponseJson,
|
||||
).Return(
|
||||
errors.New("foo"),
|
||||
).Times(1)
|
||||
jsonRestHandler.EXPECT().Get(
|
||||
gomock.Any(),
|
||||
"/eth/v1/beacon/genesis",
|
||||
&genesisResponseJson,
|
||||
).Return(
|
||||
nil,
|
||||
).SetArg(
|
||||
2,
|
||||
structs.GetGenesisResponse{
|
||||
Data: &structs.Genesis{
|
||||
GenesisTime: "1234",
|
||||
GenesisValidatorsRoot: "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2",
|
||||
},
|
||||
},
|
||||
).Times(1)
|
||||
|
||||
genesisProvider := &genesisProvider{jsonRestHandler: jsonRestHandler}
|
||||
_, err := genesisProvider.Genesis(ctx)
|
||||
require.ErrorContains(t, "foo", err)
|
||||
resp, err := genesisProvider.Genesis(ctx)
|
||||
assert.NoError(t, err)
|
||||
require.NotNil(t, resp)
|
||||
assert.Equal(t, "1234", resp.GenesisTime)
|
||||
assert.Equal(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", resp.GenesisValidatorsRoot)
|
||||
}
|
||||
25
api/client/beacon/shared_providers/interfaces.go
Normal file
25
api/client/beacon/shared_providers/interfaces.go
Normal file
@@ -0,0 +1,25 @@
|
||||
package shared_providers
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/prysmaticlabs/prysm/v5/api/server/structs"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
)
|
||||
|
||||
type Genesis interface {
|
||||
Genesis(ctx context.Context) (*structs.Genesis, error)
|
||||
}
|
||||
|
||||
type StateValidators interface {
|
||||
StateValidators(context.Context, []string, []primitives.ValidatorIndex, []string) (*structs.GetValidatorsResponse, error)
|
||||
StateValidatorsForSlot(context.Context, primitives.Slot, []string, []primitives.ValidatorIndex, []string) (*structs.GetValidatorsResponse, error)
|
||||
StateValidatorsForHead(context.Context, []string, []primitives.ValidatorIndex, []string) (*structs.GetValidatorsResponse, error)
|
||||
}
|
||||
|
||||
type Duties interface {
|
||||
AttesterDuties(ctx context.Context, epoch primitives.Epoch, validatorIndices []primitives.ValidatorIndex) ([]*structs.AttesterDuty, error)
|
||||
ProposerDuties(ctx context.Context, epoch primitives.Epoch) ([]*structs.ProposerDuty, error)
|
||||
SyncDuties(ctx context.Context, epoch primitives.Epoch, validatorIndices []primitives.ValidatorIndex) ([]*structs.SyncCommitteeDuty, error)
|
||||
Committees(ctx context.Context, epoch primitives.Epoch) ([]*structs.Committee, error)
|
||||
}
|
||||
17
api/client/beacon/shared_providers/providers.go
Normal file
17
api/client/beacon/shared_providers/providers.go
Normal file
@@ -0,0 +1,17 @@
|
||||
package shared_providers
|
||||
|
||||
import (
|
||||
"github.com/prysmaticlabs/prysm/v5/api/client"
|
||||
)
|
||||
|
||||
func NewStateValidators(jsonRestHandler client.JsonRestHandler) StateValidators {
|
||||
return &stateValidatorsProvider{jsonRestHandler: jsonRestHandler}
|
||||
}
|
||||
|
||||
func NewDuties(jsonRestHandler client.JsonRestHandler) Duties {
|
||||
return &dutiesProvider{jsonRestHandler: jsonRestHandler}
|
||||
}
|
||||
|
||||
func NewGenesis(jsonRestHandler client.JsonRestHandler) Genesis {
|
||||
return &genesisProvider{jsonRestHandler: jsonRestHandler}
|
||||
}
|
||||
@@ -1,55 +1,51 @@
|
||||
package beacon_api
|
||||
package shared_providers
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/beacon"
|
||||
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/apiutil"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/client"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/server/structs"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
)
|
||||
|
||||
type StateValidatorsProvider interface {
|
||||
GetStateValidators(context.Context, []string, []primitives.ValidatorIndex, []string) (*beacon.GetValidatorsResponse, error)
|
||||
GetStateValidatorsForSlot(context.Context, primitives.Slot, []string, []primitives.ValidatorIndex, []string) (*beacon.GetValidatorsResponse, error)
|
||||
GetStateValidatorsForHead(context.Context, []string, []primitives.ValidatorIndex, []string) (*beacon.GetValidatorsResponse, error)
|
||||
type stateValidatorsProvider struct {
|
||||
jsonRestHandler client.JsonRestHandler
|
||||
}
|
||||
|
||||
type beaconApiStateValidatorsProvider struct {
|
||||
jsonRestHandler JsonRestHandler
|
||||
}
|
||||
|
||||
func (c beaconApiStateValidatorsProvider) GetStateValidators(
|
||||
func (c stateValidatorsProvider) StateValidators(
|
||||
ctx context.Context,
|
||||
stringPubkeys []string,
|
||||
indexes []primitives.ValidatorIndex,
|
||||
statuses []string,
|
||||
) (*beacon.GetValidatorsResponse, error) {
|
||||
) (*structs.GetValidatorsResponse, error) {
|
||||
stringIndices := convertValidatorIndicesToStrings(indexes)
|
||||
return c.getStateValidatorsHelper(ctx, "/eth/v1/beacon/states/head/validators", append(stringIndices, stringPubkeys...), statuses)
|
||||
}
|
||||
|
||||
func (c beaconApiStateValidatorsProvider) GetStateValidatorsForSlot(
|
||||
func (c stateValidatorsProvider) StateValidatorsForSlot(
|
||||
ctx context.Context,
|
||||
slot primitives.Slot,
|
||||
stringPubkeys []string,
|
||||
indices []primitives.ValidatorIndex,
|
||||
statuses []string,
|
||||
) (*beacon.GetValidatorsResponse, error) {
|
||||
) (*structs.GetValidatorsResponse, error) {
|
||||
stringIndices := convertValidatorIndicesToStrings(indices)
|
||||
url := fmt.Sprintf("/eth/v1/beacon/states/%d/validators", slot)
|
||||
return c.getStateValidatorsHelper(ctx, url, append(stringIndices, stringPubkeys...), statuses)
|
||||
return c.getStateValidatorsHelper(ctx, fmt.Sprintf("/eth/v1/beacon/states/%d/validators", slot), append(stringIndices, stringPubkeys...), statuses)
|
||||
}
|
||||
|
||||
func (c beaconApiStateValidatorsProvider) GetStateValidatorsForHead(
|
||||
func (c stateValidatorsProvider) StateValidatorsForHead(
|
||||
ctx context.Context,
|
||||
stringPubkeys []string,
|
||||
indices []primitives.ValidatorIndex,
|
||||
statuses []string,
|
||||
) (*beacon.GetValidatorsResponse, error) {
|
||||
) (*structs.GetValidatorsResponse, error) {
|
||||
stringIndices := convertValidatorIndicesToStrings(indices)
|
||||
return c.getStateValidatorsHelper(ctx, "/eth/v1/beacon/states/head/validators", append(stringIndices, stringPubkeys...), statuses)
|
||||
}
|
||||
@@ -66,13 +62,13 @@ func convertValidatorIndicesToStrings(indices []primitives.ValidatorIndex) []str
|
||||
return result
|
||||
}
|
||||
|
||||
func (c beaconApiStateValidatorsProvider) getStateValidatorsHelper(
|
||||
func (c stateValidatorsProvider) getStateValidatorsHelper(
|
||||
ctx context.Context,
|
||||
endpoint string,
|
||||
vals []string,
|
||||
statuses []string,
|
||||
) (*beacon.GetValidatorsResponse, error) {
|
||||
req := beacon.GetValidatorsRequest{
|
||||
) (*structs.GetValidatorsResponse, error) {
|
||||
req := structs.GetValidatorsRequest{
|
||||
Ids: []string{},
|
||||
Statuses: []string{},
|
||||
}
|
||||
@@ -90,13 +86,33 @@ func (c beaconApiStateValidatorsProvider) getStateValidatorsHelper(
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to marshal request into JSON")
|
||||
}
|
||||
stateValidatorsJson := &beacon.GetValidatorsResponse{}
|
||||
errJson, err := c.jsonRestHandler.Post(ctx, endpoint, nil, bytes.NewBuffer(reqBytes), stateValidatorsJson)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, msgUnexpectedError)
|
||||
stateValidatorsJson := &structs.GetValidatorsResponse{}
|
||||
// First try POST endpoint to check whether it is supported by the beacon node.
|
||||
if err = c.jsonRestHandler.Post(ctx, endpoint, nil, bytes.NewBuffer(reqBytes), stateValidatorsJson); err == nil {
|
||||
if stateValidatorsJson.Data == nil {
|
||||
return nil, errors.New("stateValidatorsJson.Data is nil")
|
||||
}
|
||||
|
||||
return stateValidatorsJson, nil
|
||||
}
|
||||
if errJson != nil {
|
||||
return nil, errJson
|
||||
|
||||
// Re-initialise the response just in case.
|
||||
stateValidatorsJson = &structs.GetValidatorsResponse{}
|
||||
|
||||
// Seems like POST isn't supported by the beacon node, let's try the GET one.
|
||||
queryParams := url.Values{}
|
||||
for _, id := range req.Ids {
|
||||
queryParams.Add("id", id)
|
||||
}
|
||||
for _, st := range req.Statuses {
|
||||
queryParams.Add("status", st)
|
||||
}
|
||||
|
||||
query := apiutil.BuildURL(endpoint, queryParams)
|
||||
|
||||
err = c.jsonRestHandler.Get(ctx, query, stateValidatorsJson)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if stateValidatorsJson.Data == nil {
|
||||
365
api/client/beacon/shared_providers/state_validators_test.go
Normal file
365
api/client/beacon/shared_providers/state_validators_test.go
Normal file
@@ -0,0 +1,365 @@
|
||||
package shared_providers
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/url"
|
||||
"testing"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/apiutil"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/client/beacon/mock"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/server/structs"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
"github.com/prysmaticlabs/prysm/v5/testing/assert"
|
||||
"github.com/prysmaticlabs/prysm/v5/testing/require"
|
||||
"go.uber.org/mock/gomock"
|
||||
)
|
||||
|
||||
func TestGetStateValidators_Nominal_POST(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
|
||||
req := &structs.GetValidatorsRequest{
|
||||
Ids: []string{
|
||||
"12345",
|
||||
"0x8000091c2ae64ee414a54c1cc1fc67dec663408bc636cb86756e0200e41a75c8f86603f104f02c856983d2783116be13",
|
||||
"0x80000e851c0f53c3246ff726d7ff7766661ca5e12a07c45c114d208d54f0f8233d4380b2e9aff759d69795d1df905526",
|
||||
"0x424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242",
|
||||
"0x800015473bdc3a7f45ef8eb8abc598bc20021e55ad6e6ad1d745aaef9730dd2c28ec08bf42df18451de94dd4a6d24ec5",
|
||||
},
|
||||
Statuses: []string{"active_ongoing", "active_exiting", "exited_slashed", "exited_unslashed"},
|
||||
}
|
||||
reqBytes, err := json.Marshal(req)
|
||||
require.NoError(t, err)
|
||||
|
||||
stateValidatorsResponseJson := structs.GetValidatorsResponse{}
|
||||
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
|
||||
|
||||
wanted := []*structs.ValidatorContainer{
|
||||
{
|
||||
Index: "12345",
|
||||
Status: "active_ongoing",
|
||||
Validator: &structs.Validator{
|
||||
Pubkey: "0x8000091c2ae64ee414a54c1cc1fc67dec663408bc636cb86756e0200e41a75c8f86603f104f02c856983d2783116be19",
|
||||
},
|
||||
},
|
||||
{
|
||||
Index: "55293",
|
||||
Status: "active_ongoing",
|
||||
Validator: &structs.Validator{
|
||||
Pubkey: "0x8000091c2ae64ee414a54c1cc1fc67dec663408bc636cb86756e0200e41a75c8f86603f104f02c856983d2783116be13",
|
||||
},
|
||||
},
|
||||
{
|
||||
Index: "55294",
|
||||
Status: "active_exiting",
|
||||
Validator: &structs.Validator{
|
||||
Pubkey: "0x80000e851c0f53c3246ff726d7ff7766661ca5e12a07c45c114d208d54f0f8233d4380b2e9aff759d69795d1df905526",
|
||||
},
|
||||
},
|
||||
{
|
||||
Index: "55295",
|
||||
Status: "exited_slashed",
|
||||
Validator: &structs.Validator{
|
||||
Pubkey: "0x800015473bdc3a7f45ef8eb8abc598bc20021e55ad6e6ad1d745aaef9730dd2c28ec08bf42df18451de94dd4a6d24ec5",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
jsonRestHandler.EXPECT().Post(
|
||||
gomock.Any(),
|
||||
"/eth/v1/beacon/states/head/validators",
|
||||
nil,
|
||||
bytes.NewBuffer(reqBytes),
|
||||
&stateValidatorsResponseJson,
|
||||
).Return(
|
||||
nil,
|
||||
).SetArg(
|
||||
4,
|
||||
structs.GetValidatorsResponse{
|
||||
Data: wanted,
|
||||
},
|
||||
).Times(1)
|
||||
|
||||
stateValidatorsProvider := stateValidatorsProvider{jsonRestHandler: jsonRestHandler}
|
||||
actual, err := stateValidatorsProvider.StateValidators(ctx, []string{
|
||||
"0x8000091c2ae64ee414a54c1cc1fc67dec663408bc636cb86756e0200e41a75c8f86603f104f02c856983d2783116be13", // active_ongoing
|
||||
"0x80000e851c0f53c3246ff726d7ff7766661ca5e12a07c45c114d208d54f0f8233d4380b2e9aff759d69795d1df905526", // active_exiting
|
||||
"0x424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242", // does not exist
|
||||
"0x8000091c2ae64ee414a54c1cc1fc67dec663408bc636cb86756e0200e41a75c8f86603f104f02c856983d2783116be13", // active_ongoing - duplicate
|
||||
"0x800015473bdc3a7f45ef8eb8abc598bc20021e55ad6e6ad1d745aaef9730dd2c28ec08bf42df18451de94dd4a6d24ec5", // exited_slashed
|
||||
},
|
||||
[]primitives.ValidatorIndex{
|
||||
12345, // active_ongoing
|
||||
12345, // active_ongoing - duplicate
|
||||
},
|
||||
[]string{"active_ongoing", "active_exiting", "exited_slashed", "exited_unslashed"},
|
||||
)
|
||||
require.NoError(t, err)
|
||||
assert.DeepEqual(t, wanted, actual.Data)
|
||||
}
|
||||
|
||||
func TestGetStateValidators_Nominal_GET(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
|
||||
req := &structs.GetValidatorsRequest{
|
||||
Ids: []string{
|
||||
"12345",
|
||||
"0x8000091c2ae64ee414a54c1cc1fc67dec663408bc636cb86756e0200e41a75c8f86603f104f02c856983d2783116be13",
|
||||
"0x80000e851c0f53c3246ff726d7ff7766661ca5e12a07c45c114d208d54f0f8233d4380b2e9aff759d69795d1df905526",
|
||||
"0x424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242",
|
||||
"0x800015473bdc3a7f45ef8eb8abc598bc20021e55ad6e6ad1d745aaef9730dd2c28ec08bf42df18451de94dd4a6d24ec5",
|
||||
},
|
||||
Statuses: []string{"active_ongoing", "active_exiting", "exited_slashed", "exited_unslashed"},
|
||||
}
|
||||
reqBytes, err := json.Marshal(req)
|
||||
require.NoError(t, err)
|
||||
|
||||
stateValidatorsResponseJson := structs.GetValidatorsResponse{}
|
||||
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
|
||||
|
||||
wanted := []*structs.ValidatorContainer{
|
||||
{
|
||||
Index: "12345",
|
||||
Status: "active_ongoing",
|
||||
Validator: &structs.Validator{
|
||||
Pubkey: "0x8000091c2ae64ee414a54c1cc1fc67dec663408bc636cb86756e0200e41a75c8f86603f104f02c856983d2783116be19",
|
||||
},
|
||||
},
|
||||
{
|
||||
Index: "55293",
|
||||
Status: "active_ongoing",
|
||||
Validator: &structs.Validator{
|
||||
Pubkey: "0x8000091c2ae64ee414a54c1cc1fc67dec663408bc636cb86756e0200e41a75c8f86603f104f02c856983d2783116be13",
|
||||
},
|
||||
},
|
||||
{
|
||||
Index: "55294",
|
||||
Status: "active_exiting",
|
||||
Validator: &structs.Validator{
|
||||
Pubkey: "0x80000e851c0f53c3246ff726d7ff7766661ca5e12a07c45c114d208d54f0f8233d4380b2e9aff759d69795d1df905526",
|
||||
},
|
||||
},
|
||||
{
|
||||
Index: "55295",
|
||||
Status: "exited_slashed",
|
||||
Validator: &structs.Validator{
|
||||
Pubkey: "0x800015473bdc3a7f45ef8eb8abc598bc20021e55ad6e6ad1d745aaef9730dd2c28ec08bf42df18451de94dd4a6d24ec5",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
// First return an error from POST call.
|
||||
jsonRestHandler.EXPECT().Post(
|
||||
gomock.Any(),
|
||||
"/eth/v1/beacon/states/head/validators",
|
||||
nil,
|
||||
bytes.NewBuffer(reqBytes),
|
||||
&stateValidatorsResponseJson,
|
||||
).Return(
|
||||
errors.New("an error"),
|
||||
).Times(1)
|
||||
|
||||
// Then try the GET call which will be successful.
|
||||
queryParams := url.Values{}
|
||||
for _, id := range req.Ids {
|
||||
queryParams.Add("id", id)
|
||||
}
|
||||
for _, st := range req.Statuses {
|
||||
queryParams.Add("status", st)
|
||||
}
|
||||
|
||||
query := apiutil.BuildURL("/eth/v1/beacon/states/head/validators", queryParams)
|
||||
|
||||
jsonRestHandler.EXPECT().Get(
|
||||
gomock.Any(),
|
||||
query,
|
||||
&stateValidatorsResponseJson,
|
||||
).Return(
|
||||
nil,
|
||||
).SetArg(
|
||||
2,
|
||||
structs.GetValidatorsResponse{
|
||||
Data: wanted,
|
||||
},
|
||||
).Times(1)
|
||||
|
||||
stateValidatorsProvider := stateValidatorsProvider{jsonRestHandler: jsonRestHandler}
|
||||
actual, err := stateValidatorsProvider.StateValidators(ctx, []string{
|
||||
"0x8000091c2ae64ee414a54c1cc1fc67dec663408bc636cb86756e0200e41a75c8f86603f104f02c856983d2783116be13", // active_ongoing
|
||||
"0x80000e851c0f53c3246ff726d7ff7766661ca5e12a07c45c114d208d54f0f8233d4380b2e9aff759d69795d1df905526", // active_exiting
|
||||
"0x424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242", // does not exist
|
||||
"0x8000091c2ae64ee414a54c1cc1fc67dec663408bc636cb86756e0200e41a75c8f86603f104f02c856983d2783116be13", // active_ongoing - duplicate
|
||||
"0x800015473bdc3a7f45ef8eb8abc598bc20021e55ad6e6ad1d745aaef9730dd2c28ec08bf42df18451de94dd4a6d24ec5", // exited_slashed
|
||||
},
|
||||
[]primitives.ValidatorIndex{
|
||||
12345, // active_ongoing
|
||||
12345, // active_ongoing - duplicate
|
||||
},
|
||||
[]string{"active_ongoing", "active_exiting", "exited_slashed", "exited_unslashed"},
|
||||
)
|
||||
require.NoError(t, err)
|
||||
assert.DeepEqual(t, wanted, actual.Data)
|
||||
}
|
||||
|
||||
func TestGetStateValidators_GetRestJsonResponseOnError(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
|
||||
req := &structs.GetValidatorsRequest{
|
||||
Ids: []string{"0x8000091c2ae64ee414a54c1cc1fc67dec663408bc636cb86756e0200e41a75c8f86603f104f02c856983d2783116be13"},
|
||||
Statuses: []string{},
|
||||
}
|
||||
reqBytes, err := json.Marshal(req)
|
||||
require.NoError(t, err)
|
||||
|
||||
stateValidatorsResponseJson := structs.GetValidatorsResponse{}
|
||||
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
// First call POST.
|
||||
jsonRestHandler.EXPECT().Post(
|
||||
gomock.Any(),
|
||||
"/eth/v1/beacon/states/head/validators",
|
||||
nil,
|
||||
bytes.NewBuffer(reqBytes),
|
||||
&stateValidatorsResponseJson,
|
||||
).Return(
|
||||
errors.New("an error"),
|
||||
).Times(1)
|
||||
|
||||
// Call to GET endpoint upon receiving error from POST call.
|
||||
queryParams := url.Values{}
|
||||
for _, id := range req.Ids {
|
||||
queryParams.Add("id", id)
|
||||
}
|
||||
for _, st := range req.Statuses {
|
||||
queryParams.Add("status", st)
|
||||
}
|
||||
|
||||
query := apiutil.BuildURL("/eth/v1/beacon/states/head/validators", queryParams)
|
||||
|
||||
jsonRestHandler.EXPECT().Get(
|
||||
gomock.Any(),
|
||||
query,
|
||||
&stateValidatorsResponseJson,
|
||||
).Return(
|
||||
errors.New("an error"),
|
||||
).Times(1)
|
||||
|
||||
stateValidatorsProvider := stateValidatorsProvider{jsonRestHandler: jsonRestHandler}
|
||||
_, err = stateValidatorsProvider.StateValidators(ctx, []string{
|
||||
"0x8000091c2ae64ee414a54c1cc1fc67dec663408bc636cb86756e0200e41a75c8f86603f104f02c856983d2783116be13", // active_ongoing
|
||||
},
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
assert.ErrorContains(t, "an error", err)
|
||||
}
|
||||
|
||||
func TestGetStateValidators_DataIsNil_POST(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
|
||||
req := &structs.GetValidatorsRequest{
|
||||
Ids: []string{"0x8000091c2ae64ee414a54c1cc1fc67dec663408bc636cb86756e0200e41a75c8f86603f104f02c856983d2783116be13"},
|
||||
Statuses: []string{},
|
||||
}
|
||||
reqBytes, err := json.Marshal(req)
|
||||
require.NoError(t, err)
|
||||
|
||||
ctx := context.Background()
|
||||
stateValidatorsResponseJson := structs.GetValidatorsResponse{}
|
||||
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
|
||||
|
||||
jsonRestHandler.EXPECT().Post(
|
||||
gomock.Any(),
|
||||
"/eth/v1/beacon/states/head/validators",
|
||||
nil, bytes.NewBuffer(reqBytes),
|
||||
&stateValidatorsResponseJson,
|
||||
).Return(
|
||||
nil,
|
||||
).SetArg(
|
||||
4,
|
||||
structs.GetValidatorsResponse{
|
||||
Data: nil,
|
||||
},
|
||||
).Times(1)
|
||||
|
||||
stateValidatorsProvider := stateValidatorsProvider{jsonRestHandler: jsonRestHandler}
|
||||
_, err = stateValidatorsProvider.StateValidators(ctx, []string{
|
||||
"0x8000091c2ae64ee414a54c1cc1fc67dec663408bc636cb86756e0200e41a75c8f86603f104f02c856983d2783116be13", // active_ongoing
|
||||
},
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
assert.ErrorContains(t, "stateValidatorsJson.Data is nil", err)
|
||||
}
|
||||
|
||||
func TestGetStateValidators_DataIsNil_GET(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
|
||||
req := &structs.GetValidatorsRequest{
|
||||
Ids: []string{"0x8000091c2ae64ee414a54c1cc1fc67dec663408bc636cb86756e0200e41a75c8f86603f104f02c856983d2783116be13"},
|
||||
Statuses: []string{},
|
||||
}
|
||||
reqBytes, err := json.Marshal(req)
|
||||
require.NoError(t, err)
|
||||
|
||||
ctx := context.Background()
|
||||
stateValidatorsResponseJson := structs.GetValidatorsResponse{}
|
||||
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
|
||||
|
||||
// First call POST which will return an error.
|
||||
jsonRestHandler.EXPECT().Post(
|
||||
gomock.Any(),
|
||||
"/eth/v1/beacon/states/head/validators",
|
||||
nil,
|
||||
bytes.NewBuffer(reqBytes),
|
||||
&stateValidatorsResponseJson,
|
||||
).Return(
|
||||
errors.New("an error"),
|
||||
).Times(1)
|
||||
|
||||
// Then call GET which returns nil Data.
|
||||
queryParams := url.Values{}
|
||||
for _, id := range req.Ids {
|
||||
queryParams.Add("id", id)
|
||||
}
|
||||
for _, st := range req.Statuses {
|
||||
queryParams.Add("status", st)
|
||||
}
|
||||
|
||||
query := apiutil.BuildURL("/eth/v1/beacon/states/head/validators", queryParams)
|
||||
|
||||
jsonRestHandler.EXPECT().Get(
|
||||
gomock.Any(),
|
||||
query,
|
||||
&stateValidatorsResponseJson,
|
||||
).Return(
|
||||
nil,
|
||||
).SetArg(
|
||||
2,
|
||||
structs.GetValidatorsResponse{
|
||||
Data: nil,
|
||||
},
|
||||
).Times(1)
|
||||
|
||||
stateValidatorsProvider := stateValidatorsProvider{jsonRestHandler: jsonRestHandler}
|
||||
_, err = stateValidatorsProvider.StateValidators(ctx, []string{
|
||||
"0x8000091c2ae64ee414a54c1cc1fc67dec663408bc636cb86756e0200e41a75c8f86603f104f02c856983d2783116be13", // active_ongoing
|
||||
},
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
assert.ErrorContains(t, "stateValidatorsJson.Data is nil", err)
|
||||
}
|
||||
145
api/client/beacon/structs.go
Normal file
145
api/client/beacon/structs.go
Normal file
@@ -0,0 +1,145 @@
|
||||
package beacon
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strconv"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
)
|
||||
|
||||
type BeaconCommitteeSelection struct {
|
||||
SelectionProof []byte
|
||||
Slot primitives.Slot
|
||||
ValidatorIndex primitives.ValidatorIndex
|
||||
}
|
||||
|
||||
type beaconCommitteeSelectionJson struct {
|
||||
SelectionProof string `json:"selection_proof"`
|
||||
Slot string `json:"slot"`
|
||||
ValidatorIndex string `json:"validator_index"`
|
||||
}
|
||||
|
||||
func (b *BeaconCommitteeSelection) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(beaconCommitteeSelectionJson{
|
||||
SelectionProof: hexutil.Encode(b.SelectionProof),
|
||||
Slot: strconv.FormatUint(uint64(b.Slot), 10),
|
||||
ValidatorIndex: strconv.FormatUint(uint64(b.ValidatorIndex), 10),
|
||||
})
|
||||
}
|
||||
|
||||
func (b *BeaconCommitteeSelection) UnmarshalJSON(input []byte) error {
|
||||
var bjson beaconCommitteeSelectionJson
|
||||
err := json.Unmarshal(input, &bjson)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to unmarshal beacon committee selection")
|
||||
}
|
||||
|
||||
slot, err := strconv.ParseUint(bjson.Slot, 10, 64)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to parse slot")
|
||||
}
|
||||
|
||||
vIdx, err := strconv.ParseUint(bjson.ValidatorIndex, 10, 64)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to parse validator index")
|
||||
}
|
||||
|
||||
selectionProof, err := hexutil.Decode(bjson.SelectionProof)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to parse selection proof")
|
||||
}
|
||||
|
||||
b.Slot = primitives.Slot(slot)
|
||||
b.SelectionProof = selectionProof
|
||||
b.ValidatorIndex = primitives.ValidatorIndex(vIdx)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type SyncCommitteeSelection struct {
|
||||
SelectionProof []byte
|
||||
Slot primitives.Slot
|
||||
SubcommitteeIndex primitives.CommitteeIndex
|
||||
ValidatorIndex primitives.ValidatorIndex
|
||||
}
|
||||
|
||||
type syncCommitteeSelectionJson struct {
|
||||
SelectionProof string `json:"selection_proof"`
|
||||
Slot string `json:"slot"`
|
||||
SubcommitteeIndex string `json:"subcommittee_index"`
|
||||
ValidatorIndex string `json:"validator_index"`
|
||||
}
|
||||
|
||||
func (s *SyncCommitteeSelection) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(syncCommitteeSelectionJson{
|
||||
SelectionProof: hexutil.Encode(s.SelectionProof),
|
||||
Slot: strconv.FormatUint(uint64(s.Slot), 10),
|
||||
SubcommitteeIndex: strconv.FormatUint(uint64(s.SubcommitteeIndex), 10),
|
||||
ValidatorIndex: strconv.FormatUint(uint64(s.ValidatorIndex), 10),
|
||||
})
|
||||
}
|
||||
|
||||
func (s *SyncCommitteeSelection) UnmarshalJSON(input []byte) error {
|
||||
var resJson syncCommitteeSelectionJson
|
||||
err := json.Unmarshal(input, &resJson)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to unmarshal sync committee selection")
|
||||
}
|
||||
|
||||
slot, err := strconv.ParseUint(resJson.Slot, 10, 64)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to parse slot")
|
||||
}
|
||||
|
||||
vIdx, err := strconv.ParseUint(resJson.ValidatorIndex, 10, 64)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to parse validator index")
|
||||
}
|
||||
|
||||
subcommIdx, err := strconv.ParseUint(resJson.SubcommitteeIndex, 10, 64)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to parse subcommittee index")
|
||||
}
|
||||
|
||||
selectionProof, err := hexutil.Decode(resJson.SelectionProof)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to parse selection proof")
|
||||
}
|
||||
|
||||
s.Slot = primitives.Slot(slot)
|
||||
s.SelectionProof = selectionProof
|
||||
s.ValidatorIndex = primitives.ValidatorIndex(vIdx)
|
||||
s.SubcommitteeIndex = primitives.CommitteeIndex(subcommIdx)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type AggregatedSelectionResponse struct {
|
||||
Data []BeaconCommitteeSelection `json:"data"`
|
||||
}
|
||||
|
||||
type AggregatedSyncSelectionResponse struct {
|
||||
Data []SyncCommitteeSelection `json:"data"`
|
||||
}
|
||||
|
||||
type AttesterDuty struct {
|
||||
CommitteeIndex primitives.CommitteeIndex
|
||||
Slot primitives.Slot
|
||||
CommitteeLength uint64
|
||||
ValidatorCommitteeIndex uint64
|
||||
CommitteesAtSlot uint64
|
||||
}
|
||||
|
||||
type ValidatorForDuty struct {
|
||||
Pubkey []byte
|
||||
Index primitives.ValidatorIndex
|
||||
Status ethpb.ValidatorStatus
|
||||
}
|
||||
|
||||
type ValidatorCount struct {
|
||||
Status string
|
||||
Count uint64
|
||||
}
|
||||
34
api/client/beacon/template.go
Normal file
34
api/client/beacon/template.go
Normal file
@@ -0,0 +1,34 @@
|
||||
package beacon
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"text/template"
|
||||
)
|
||||
|
||||
type templateFn func(StateOrBlockId) string
|
||||
|
||||
var getBlockRootTpl templateFn
|
||||
var getForkTpl templateFn
|
||||
|
||||
func init() {
|
||||
// idTemplate is used to create template functions that can interpolate StateOrBlockId values.
|
||||
idTemplate := func(ts string) func(StateOrBlockId) string {
|
||||
t := template.Must(template.New("").Parse(ts))
|
||||
f := func(id StateOrBlockId) string {
|
||||
b := bytes.NewBuffer(nil)
|
||||
err := t.Execute(b, struct{ Id string }{Id: string(id)})
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("invalid idTemplate: %s", ts))
|
||||
}
|
||||
return b.String()
|
||||
}
|
||||
// run the template to ensure that it is valid
|
||||
// this should happen load time (using package scoped vars) to ensure runtime errors aren't possible
|
||||
_ = f(IdGenesis)
|
||||
return f
|
||||
}
|
||||
|
||||
getBlockRootTpl = idTemplate(getBlockRootPath)
|
||||
getForkTpl = idTemplate(getForkForStatePath)
|
||||
}
|
||||
@@ -3,31 +3,27 @@ load("@prysm//tools/go:def.bzl", "go_library", "go_test")
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"activation.go",
|
||||
"attestation_data.go",
|
||||
"beacon_api_beacon_chain_client.go",
|
||||
"beacon_api_helpers.go",
|
||||
"beacon_api_node_client.go",
|
||||
"beacon_api_validator_client.go",
|
||||
"beacon_block_converter.go",
|
||||
"beacon_block_json_helpers.go",
|
||||
"beacon_block_proto_helpers.go",
|
||||
"client.go",
|
||||
"domain_data.go",
|
||||
"doppelganger.go",
|
||||
"duties.go",
|
||||
"errors.go",
|
||||
"genesis.go",
|
||||
"get_beacon_block.go",
|
||||
"grpc_client.go",
|
||||
"index.go",
|
||||
"json_rest_handler.go",
|
||||
"interfaces.go",
|
||||
"log.go",
|
||||
"metrics.go",
|
||||
"prepare_beacon_proposer.go",
|
||||
"propose_attestation.go",
|
||||
"propose_beacon_block.go",
|
||||
"propose_exit.go",
|
||||
"prysm_beacon_chain_client.go",
|
||||
"registration.go",
|
||||
"state_validators.go",
|
||||
"rest_client.go",
|
||||
"status.go",
|
||||
"stream_blocks.go",
|
||||
"submit_aggregate_selection_proof.go",
|
||||
@@ -35,112 +31,116 @@ go_library(
|
||||
"submit_signed_contribution_and_proof.go",
|
||||
"subscribe_committee_subnets.go",
|
||||
"sync_committee.go",
|
||||
"sync_committee_selections.go",
|
||||
],
|
||||
importpath = "github.com/prysmaticlabs/prysm/v4/validator/client/beacon-api",
|
||||
visibility = ["//validator:__subpackages__"],
|
||||
importpath = "github.com/prysmaticlabs/prysm/v5/api/client/beacon/validator_api",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//api:go_default_library",
|
||||
"//api/client:go_default_library",
|
||||
"//api/client/apiutil:go_default_library",
|
||||
"//api/client/beacon:go_default_library",
|
||||
"//api/client/beacon/node:go_default_library",
|
||||
"//api/client/beacon/prysm_api:go_default_library",
|
||||
"//api/client/beacon/shared_providers:go_default_library",
|
||||
"//api/client/event:go_default_library",
|
||||
"//api/server/structs:go_default_library",
|
||||
"//beacon-chain/core/helpers:go_default_library",
|
||||
"//beacon-chain/core/signing:go_default_library",
|
||||
"//beacon-chain/rpc/eth/beacon:go_default_library",
|
||||
"//beacon-chain/rpc/eth/config:go_default_library",
|
||||
"//beacon-chain/rpc/eth/node:go_default_library",
|
||||
"//beacon-chain/rpc/eth/shared:go_default_library",
|
||||
"//beacon-chain/rpc/eth/validator:go_default_library",
|
||||
"//beacon-chain/rpc/prysm/validator:go_default_library",
|
||||
"//config/features:go_default_library",
|
||||
"//config/params:go_default_library",
|
||||
"//consensus-types/primitives:go_default_library",
|
||||
"//consensus-types/validator:go_default_library",
|
||||
"//encoding/bytesutil:go_default_library",
|
||||
"//monitoring/tracing/trace:go_default_library",
|
||||
"//network/forks:go_default_library",
|
||||
"//network/httputil:go_default_library",
|
||||
"//proto/engine/v1:go_default_library",
|
||||
"//proto/prysm/v1alpha1:go_default_library",
|
||||
"//runtime/version:go_default_library",
|
||||
"//time/slots:go_default_library",
|
||||
"//validator/client/iface:go_default_library",
|
||||
"//validator/helpers:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//common/hexutil:go_default_library",
|
||||
"@com_github_golang_protobuf//ptypes/empty",
|
||||
"@com_github_pkg_errors//:go_default_library",
|
||||
"@com_github_prometheus_client_golang//prometheus:go_default_library",
|
||||
"@com_github_prometheus_client_golang//prometheus/promauto:go_default_library",
|
||||
"@com_github_sirupsen_logrus//:go_default_library",
|
||||
"@org_golang_google_grpc//:go_default_library",
|
||||
"@org_golang_google_protobuf//types/known/timestamppb:go_default_library",
|
||||
"@org_golang_x_sync//errgroup:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
size = "small",
|
||||
srcs = [
|
||||
"activation_test.go",
|
||||
"attestation_data_test.go",
|
||||
"beacon_api_beacon_chain_client_test.go",
|
||||
"beacon_api_helpers_test.go",
|
||||
"beacon_api_node_client_test.go",
|
||||
"beacon_api_validator_client_test.go",
|
||||
"beacon_block_converter_test.go",
|
||||
"beacon_block_json_helpers_test.go",
|
||||
"beacon_block_proto_helpers_test.go",
|
||||
"domain_data_test.go",
|
||||
"doppelganger_test.go",
|
||||
"duties_test.go",
|
||||
"genesis_test.go",
|
||||
"get_beacon_block_test.go",
|
||||
"grpc_client_test.go",
|
||||
"index_test.go",
|
||||
"json_rest_handler_test.go",
|
||||
"prepare_beacon_proposer_test.go",
|
||||
"propose_attestation_test.go",
|
||||
"propose_beacon_block_altair_test.go",
|
||||
"propose_beacon_block_bellatrix_test.go",
|
||||
"propose_beacon_block_blinded_bellatrix_test.go",
|
||||
"propose_beacon_block_blinded_capella_test.go",
|
||||
"propose_beacon_block_blinded_deneb_test.go",
|
||||
"propose_beacon_block_blinded_electra_test.go",
|
||||
"propose_beacon_block_blinded_fulu_test.go",
|
||||
"propose_beacon_block_capella_test.go",
|
||||
"propose_beacon_block_deneb_test.go",
|
||||
"propose_beacon_block_electra_test.go",
|
||||
"propose_beacon_block_fulu_test.go",
|
||||
"propose_beacon_block_phase0_test.go",
|
||||
"propose_beacon_block_test.go",
|
||||
"propose_exit_test.go",
|
||||
"registration_test.go",
|
||||
"state_validators_test.go",
|
||||
"rest_client_test.go",
|
||||
"status_test.go",
|
||||
"stream_blocks_test.go",
|
||||
"submit_aggregate_selection_proof_test.go",
|
||||
"submit_signed_aggregate_proof_test.go",
|
||||
"submit_signed_contribution_and_proof_test.go",
|
||||
"subscribe_committee_subnets_test.go",
|
||||
"sync_committee_selections_test.go",
|
||||
"sync_committee_test.go",
|
||||
"validator_count_test.go",
|
||||
"wait_for_chain_start_test.go",
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//api:go_default_library",
|
||||
"//beacon-chain/rpc/eth/beacon:go_default_library",
|
||||
"//beacon-chain/rpc/eth/config:go_default_library",
|
||||
"//beacon-chain/rpc/eth/node:go_default_library",
|
||||
"//beacon-chain/rpc/eth/shared:go_default_library",
|
||||
"//api/client:go_default_library",
|
||||
"//api/client/apiutil:go_default_library",
|
||||
"//api/client/beacon:go_default_library",
|
||||
"//api/client/beacon/mock:go_default_library",
|
||||
"//api/client/beacon/node:go_default_library",
|
||||
"//api/client/beacon/prysm_api:go_default_library",
|
||||
"//api/client/beacon/shared_providers:go_default_library",
|
||||
"//api/client/beacon/validator_api/test_helpers:go_default_library",
|
||||
"//api/client/event:go_default_library",
|
||||
"//api/server/structs:go_default_library",
|
||||
"//beacon-chain/core/helpers:go_default_library",
|
||||
"//beacon-chain/rpc/eth/shared/testing:go_default_library",
|
||||
"//beacon-chain/rpc/eth/validator:go_default_library",
|
||||
"//beacon-chain/rpc/prysm/validator:go_default_library",
|
||||
"//config/params:go_default_library",
|
||||
"//consensus-types/primitives:go_default_library",
|
||||
"//consensus-types/validator:go_default_library",
|
||||
"//encoding/bytesutil:go_default_library",
|
||||
"//network/httputil:go_default_library",
|
||||
"//proto/engine/v1:go_default_library",
|
||||
"//proto/prysm/v1alpha1:go_default_library",
|
||||
"//runtime/version:go_default_library",
|
||||
"//testing/assert:go_default_library",
|
||||
"//testing/mock:go_default_library",
|
||||
"//testing/require:go_default_library",
|
||||
"//testing/validator-mock:go_default_library",
|
||||
"//time/slots:go_default_library",
|
||||
"//validator/client/beacon-api/mock:go_default_library",
|
||||
"//validator/client/beacon-api/test-helpers:go_default_library",
|
||||
"//validator/client/iface:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//common/hexutil:go_default_library",
|
||||
"@com_github_golang_mock//gomock:go_default_library",
|
||||
"@com_github_golang_protobuf//ptypes/empty",
|
||||
"@com_github_pkg_errors//:go_default_library",
|
||||
"@com_github_sirupsen_logrus//hooks/test:go_default_library",
|
||||
"@org_golang_google_protobuf//types/known/emptypb:go_default_library",
|
||||
"@org_golang_google_protobuf//types/known/timestamppb:go_default_library",
|
||||
"@org_uber_go_mock//gomock:go_default_library",
|
||||
],
|
||||
)
|
||||
@@ -1,4 +1,4 @@
|
||||
package beacon_api
|
||||
package validator_api
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -7,12 +7,13 @@ import (
|
||||
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/validator"
|
||||
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/apiutil"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/server/structs"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
)
|
||||
|
||||
func (c beaconApiValidatorClient) getAttestationData(
|
||||
func (c *beaconApiValidatorClient) attestationData(
|
||||
ctx context.Context,
|
||||
reqSlot primitives.Slot,
|
||||
reqCommitteeIndex primitives.CommitteeIndex,
|
||||
@@ -21,15 +22,11 @@ func (c beaconApiValidatorClient) getAttestationData(
|
||||
params.Add("slot", strconv.FormatUint(uint64(reqSlot), 10))
|
||||
params.Add("committee_index", strconv.FormatUint(uint64(reqCommitteeIndex), 10))
|
||||
|
||||
query := buildURL("/eth/v1/validator/attestation_data", params)
|
||||
produceAttestationDataResponseJson := validator.GetAttestationDataResponse{}
|
||||
query := apiutil.BuildURL("/eth/v1/validator/attestation_data", params)
|
||||
produceAttestationDataResponseJson := structs.GetAttestationDataResponse{}
|
||||
|
||||
errJson, err := c.jsonRestHandler.Get(ctx, query, &produceAttestationDataResponseJson)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, msgUnexpectedError)
|
||||
}
|
||||
if errJson != nil {
|
||||
return nil, errJson
|
||||
if err := c.jsonRestHandler.Get(ctx, query, &produceAttestationDataResponseJson); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if produceAttestationDataResponseJson.Data == nil {
|
||||
@@ -42,7 +39,7 @@ func (c beaconApiValidatorClient) getAttestationData(
|
||||
return nil, errors.Wrapf(err, "failed to parse attestation committee index: %s", attestationData.CommitteeIndex)
|
||||
}
|
||||
|
||||
if !validRoot(attestationData.BeaconBlockRoot) {
|
||||
if !apiutil.ValidRoot(attestationData.BeaconBlockRoot) {
|
||||
return nil, errors.Errorf("invalid beacon block root: %s", attestationData.BeaconBlockRoot)
|
||||
}
|
||||
|
||||
@@ -65,7 +62,7 @@ func (c beaconApiValidatorClient) getAttestationData(
|
||||
return nil, errors.Wrapf(err, "failed to parse attestation source epoch: %s", attestationData.Source.Epoch)
|
||||
}
|
||||
|
||||
if !validRoot(attestationData.Source.Root) {
|
||||
if !apiutil.ValidRoot(attestationData.Source.Root) {
|
||||
return nil, errors.Errorf("invalid attestation source root: %s", attestationData.Source.Root)
|
||||
}
|
||||
|
||||
@@ -83,7 +80,7 @@ func (c beaconApiValidatorClient) getAttestationData(
|
||||
return nil, errors.Wrapf(err, "failed to parse attestation target epoch: %s", attestationData.Target.Epoch)
|
||||
}
|
||||
|
||||
if !validRoot(attestationData.Target.Root) {
|
||||
if !apiutil.ValidRoot(attestationData.Target.Root) {
|
||||
return nil, errors.Errorf("invalid attestation target root: %s", attestationData.Target.Root)
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package beacon_api
|
||||
package validator_api
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -8,13 +8,12 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/golang/mock/gomock"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/shared"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/validator"
|
||||
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
|
||||
"github.com/prysmaticlabs/prysm/v4/testing/assert"
|
||||
"github.com/prysmaticlabs/prysm/v4/testing/require"
|
||||
"github.com/prysmaticlabs/prysm/v4/validator/client/beacon-api/mock"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/client/beacon/mock"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/server/structs"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
"github.com/prysmaticlabs/prysm/v5/testing/assert"
|
||||
"github.com/prysmaticlabs/prysm/v5/testing/require"
|
||||
"go.uber.org/mock/gomock"
|
||||
)
|
||||
|
||||
func TestGetAttestationData_ValidAttestation(t *testing.T) {
|
||||
@@ -31,27 +30,26 @@ func TestGetAttestationData_ValidAttestation(t *testing.T) {
|
||||
defer ctrl.Finish()
|
||||
|
||||
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
|
||||
produceAttestationDataResponseJson := validator.GetAttestationDataResponse{}
|
||||
produceAttestationDataResponseJson := structs.GetAttestationDataResponse{}
|
||||
|
||||
jsonRestHandler.EXPECT().Get(
|
||||
ctx,
|
||||
gomock.Any(),
|
||||
fmt.Sprintf("/eth/v1/validator/attestation_data?committee_index=%d&slot=%d", expectedCommitteeIndex, expectedSlot),
|
||||
&produceAttestationDataResponseJson,
|
||||
).Return(
|
||||
nil,
|
||||
nil,
|
||||
).SetArg(
|
||||
2,
|
||||
validator.GetAttestationDataResponse{
|
||||
Data: &shared.AttestationData{
|
||||
structs.GetAttestationDataResponse{
|
||||
Data: &structs.AttestationData{
|
||||
Slot: strconv.FormatUint(expectedSlot, 10),
|
||||
CommitteeIndex: strconv.FormatUint(expectedCommitteeIndex, 10),
|
||||
BeaconBlockRoot: expectedBeaconBlockRoot,
|
||||
Source: &shared.Checkpoint{
|
||||
Source: &structs.Checkpoint{
|
||||
Epoch: strconv.FormatUint(expectedSourceEpoch, 10),
|
||||
Root: expectedSourceRoot,
|
||||
},
|
||||
Target: &shared.Checkpoint{
|
||||
Target: &structs.Checkpoint{
|
||||
Epoch: strconv.FormatUint(expectedTargetEpoch, 10),
|
||||
Root: expectedTargetRoot,
|
||||
},
|
||||
@@ -60,7 +58,7 @@ func TestGetAttestationData_ValidAttestation(t *testing.T) {
|
||||
).Times(1)
|
||||
|
||||
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
|
||||
resp, err := validatorClient.getAttestationData(ctx, primitives.Slot(expectedSlot), primitives.CommitteeIndex(expectedCommitteeIndex))
|
||||
resp, err := validatorClient.attestationData(ctx, primitives.Slot(expectedSlot), primitives.CommitteeIndex(expectedCommitteeIndex))
|
||||
assert.NoError(t, err)
|
||||
|
||||
require.NotNil(t, resp)
|
||||
@@ -82,13 +80,13 @@ func TestGetAttestationData_InvalidData(t *testing.T) {
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
generateData func() validator.GetAttestationDataResponse
|
||||
generateData func() structs.GetAttestationDataResponse
|
||||
expectedErrorMessage string
|
||||
}{
|
||||
{
|
||||
name: "nil attestation data",
|
||||
generateData: func() validator.GetAttestationDataResponse {
|
||||
return validator.GetAttestationDataResponse{
|
||||
generateData: func() structs.GetAttestationDataResponse {
|
||||
return structs.GetAttestationDataResponse{
|
||||
Data: nil,
|
||||
}
|
||||
},
|
||||
@@ -96,7 +94,7 @@ func TestGetAttestationData_InvalidData(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "invalid committee index",
|
||||
generateData: func() validator.GetAttestationDataResponse {
|
||||
generateData: func() structs.GetAttestationDataResponse {
|
||||
attestation := generateValidAttestation(1, 2)
|
||||
attestation.Data.CommitteeIndex = "foo"
|
||||
return attestation
|
||||
@@ -105,7 +103,7 @@ func TestGetAttestationData_InvalidData(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "invalid block root",
|
||||
generateData: func() validator.GetAttestationDataResponse {
|
||||
generateData: func() structs.GetAttestationDataResponse {
|
||||
attestation := generateValidAttestation(1, 2)
|
||||
attestation.Data.BeaconBlockRoot = "foo"
|
||||
return attestation
|
||||
@@ -114,7 +112,7 @@ func TestGetAttestationData_InvalidData(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "invalid slot",
|
||||
generateData: func() validator.GetAttestationDataResponse {
|
||||
generateData: func() structs.GetAttestationDataResponse {
|
||||
attestation := generateValidAttestation(1, 2)
|
||||
attestation.Data.Slot = "foo"
|
||||
return attestation
|
||||
@@ -123,7 +121,7 @@ func TestGetAttestationData_InvalidData(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "nil source",
|
||||
generateData: func() validator.GetAttestationDataResponse {
|
||||
generateData: func() structs.GetAttestationDataResponse {
|
||||
attestation := generateValidAttestation(1, 2)
|
||||
attestation.Data.Source = nil
|
||||
return attestation
|
||||
@@ -132,7 +130,7 @@ func TestGetAttestationData_InvalidData(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "invalid source epoch",
|
||||
generateData: func() validator.GetAttestationDataResponse {
|
||||
generateData: func() structs.GetAttestationDataResponse {
|
||||
attestation := generateValidAttestation(1, 2)
|
||||
attestation.Data.Source.Epoch = "foo"
|
||||
return attestation
|
||||
@@ -141,7 +139,7 @@ func TestGetAttestationData_InvalidData(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "invalid source root",
|
||||
generateData: func() validator.GetAttestationDataResponse {
|
||||
generateData: func() structs.GetAttestationDataResponse {
|
||||
attestation := generateValidAttestation(1, 2)
|
||||
attestation.Data.Source.Root = "foo"
|
||||
return attestation
|
||||
@@ -150,7 +148,7 @@ func TestGetAttestationData_InvalidData(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "nil target",
|
||||
generateData: func() validator.GetAttestationDataResponse {
|
||||
generateData: func() structs.GetAttestationDataResponse {
|
||||
attestation := generateValidAttestation(1, 2)
|
||||
attestation.Data.Target = nil
|
||||
return attestation
|
||||
@@ -159,7 +157,7 @@ func TestGetAttestationData_InvalidData(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "invalid target epoch",
|
||||
generateData: func() validator.GetAttestationDataResponse {
|
||||
generateData: func() structs.GetAttestationDataResponse {
|
||||
attestation := generateValidAttestation(1, 2)
|
||||
attestation.Data.Target.Epoch = "foo"
|
||||
return attestation
|
||||
@@ -168,7 +166,7 @@ func TestGetAttestationData_InvalidData(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "invalid target root",
|
||||
generateData: func() validator.GetAttestationDataResponse {
|
||||
generateData: func() structs.GetAttestationDataResponse {
|
||||
attestation := generateValidAttestation(1, 2)
|
||||
attestation.Data.Target.Root = "foo"
|
||||
return attestation
|
||||
@@ -182,22 +180,21 @@ func TestGetAttestationData_InvalidData(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
|
||||
produceAttestationDataResponseJson := validator.GetAttestationDataResponse{}
|
||||
produceAttestationDataResponseJson := structs.GetAttestationDataResponse{}
|
||||
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
|
||||
jsonRestHandler.EXPECT().Get(
|
||||
ctx,
|
||||
gomock.Any(),
|
||||
"/eth/v1/validator/attestation_data?committee_index=2&slot=1",
|
||||
&produceAttestationDataResponseJson,
|
||||
).Return(
|
||||
nil,
|
||||
nil,
|
||||
).SetArg(
|
||||
2,
|
||||
testCase.generateData(),
|
||||
).Times(1)
|
||||
|
||||
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
|
||||
_, err := validatorClient.getAttestationData(ctx, 1, 2)
|
||||
_, err := validatorClient.attestationData(ctx, 1, 2)
|
||||
assert.ErrorContains(t, testCase.expectedErrorMessage, err)
|
||||
})
|
||||
}
|
||||
@@ -213,32 +210,31 @@ func TestGetAttestationData_JsonResponseError(t *testing.T) {
|
||||
defer ctrl.Finish()
|
||||
|
||||
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
|
||||
produceAttestationDataResponseJson := validator.GetAttestationDataResponse{}
|
||||
produceAttestationDataResponseJson := structs.GetAttestationDataResponse{}
|
||||
jsonRestHandler.EXPECT().Get(
|
||||
ctx,
|
||||
gomock.Any(),
|
||||
fmt.Sprintf("/eth/v1/validator/attestation_data?committee_index=%d&slot=%d", committeeIndex, slot),
|
||||
&produceAttestationDataResponseJson,
|
||||
).Return(
|
||||
nil,
|
||||
errors.New("some specific json response error"),
|
||||
).Times(1)
|
||||
|
||||
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
|
||||
_, err := validatorClient.getAttestationData(ctx, slot, committeeIndex)
|
||||
_, err := validatorClient.attestationData(ctx, slot, committeeIndex)
|
||||
assert.ErrorContains(t, "some specific json response error", err)
|
||||
}
|
||||
|
||||
func generateValidAttestation(slot uint64, committeeIndex uint64) validator.GetAttestationDataResponse {
|
||||
return validator.GetAttestationDataResponse{
|
||||
Data: &shared.AttestationData{
|
||||
func generateValidAttestation(slot, committeeIndex uint64) structs.GetAttestationDataResponse {
|
||||
return structs.GetAttestationDataResponse{
|
||||
Data: &structs.AttestationData{
|
||||
Slot: strconv.FormatUint(slot, 10),
|
||||
CommitteeIndex: strconv.FormatUint(committeeIndex, 10),
|
||||
BeaconBlockRoot: "0x5ecf3bff35e39d5f75476d42950d549f81fa93038c46b6652ae89ae1f7ad834f",
|
||||
Source: &shared.Checkpoint{
|
||||
Source: &structs.Checkpoint{
|
||||
Epoch: "3",
|
||||
Root: "0x9023c9e64f23c1d451d5073c641f5f69597c2ad7d82f6f16e67d703e0ce5db8b",
|
||||
},
|
||||
Target: &shared.Checkpoint{
|
||||
Target: &structs.Checkpoint{
|
||||
Epoch: "4",
|
||||
Root: "0xb154d46803b15b458ca822466547b054bc124338c6ee1d9c433dcde8c4457cca",
|
||||
},
|
||||
97
api/client/beacon/validator_api/beacon_api_helpers.go
Normal file
97
api/client/beacon/validator_api/beacon_api_helpers.go
Normal file
@@ -0,0 +1,97 @@
|
||||
package validator_api
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"strconv"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/server/structs"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
)
|
||||
|
||||
var beaconAPITogRPCValidatorStatus = map[string]ethpb.ValidatorStatus{
|
||||
"pending_initialized": ethpb.ValidatorStatus_DEPOSITED,
|
||||
"pending_queued": ethpb.ValidatorStatus_PENDING,
|
||||
"active_ongoing": ethpb.ValidatorStatus_ACTIVE,
|
||||
"active_exiting": ethpb.ValidatorStatus_EXITING,
|
||||
"active_slashed": ethpb.ValidatorStatus_SLASHING,
|
||||
"exited_unslashed": ethpb.ValidatorStatus_EXITED,
|
||||
"exited_slashed": ethpb.ValidatorStatus_EXITED,
|
||||
"withdrawal_possible": ethpb.ValidatorStatus_EXITED,
|
||||
"withdrawal_done": ethpb.ValidatorStatus_EXITED,
|
||||
}
|
||||
|
||||
func (c *beaconApiValidatorClient) fork(ctx context.Context) (*structs.GetStateForkResponse, error) {
|
||||
const endpoint = "/eth/v1/beacon/states/head/fork"
|
||||
|
||||
stateForkResponseJson := &structs.GetStateForkResponse{}
|
||||
|
||||
if err := c.jsonRestHandler.Get(ctx, endpoint, stateForkResponseJson); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return stateForkResponseJson, nil
|
||||
}
|
||||
|
||||
func (c *beaconApiValidatorClient) headers(ctx context.Context) (*structs.GetBlockHeadersResponse, error) {
|
||||
const endpoint = "/eth/v1/beacon/headers"
|
||||
|
||||
blockHeadersResponseJson := &structs.GetBlockHeadersResponse{}
|
||||
|
||||
if err := c.jsonRestHandler.Get(ctx, endpoint, blockHeadersResponseJson); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return blockHeadersResponseJson, nil
|
||||
}
|
||||
|
||||
func (c *beaconApiValidatorClient) liveness(ctx context.Context, epoch primitives.Epoch, validatorIndexes []string) (*structs.GetLivenessResponse, error) {
|
||||
const endpoint = "/eth/v1/validator/liveness/"
|
||||
url := endpoint + strconv.FormatUint(uint64(epoch), 10)
|
||||
|
||||
livenessResponseJson := &structs.GetLivenessResponse{}
|
||||
|
||||
marshalledJsonValidatorIndexes, err := json.Marshal(validatorIndexes)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to marshal validator indexes")
|
||||
}
|
||||
|
||||
if err = c.jsonRestHandler.Post(ctx, url, nil, bytes.NewBuffer(marshalledJsonValidatorIndexes), livenessResponseJson); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return livenessResponseJson, nil
|
||||
}
|
||||
|
||||
func (c *beaconApiValidatorClient) syncing(ctx context.Context) (*structs.SyncStatusResponse, error) {
|
||||
const endpoint = "/eth/v1/node/syncing"
|
||||
|
||||
syncingResponseJson := &structs.SyncStatusResponse{}
|
||||
|
||||
if err := c.jsonRestHandler.Get(ctx, endpoint, syncingResponseJson); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return syncingResponseJson, nil
|
||||
}
|
||||
|
||||
func (c *beaconApiValidatorClient) isSyncing(ctx context.Context) (bool, error) {
|
||||
response, err := c.syncing(ctx)
|
||||
if err != nil || response == nil || response.Data == nil {
|
||||
return true, errors.Wrapf(err, "failed to get syncing status")
|
||||
}
|
||||
|
||||
return response.Data.IsSyncing, err
|
||||
}
|
||||
|
||||
func (c *beaconApiValidatorClient) isOptimistic(ctx context.Context) (bool, error) {
|
||||
response, err := c.syncing(ctx)
|
||||
if err != nil || response == nil || response.Data == nil {
|
||||
return true, errors.Wrapf(err, "failed to get syncing status")
|
||||
}
|
||||
|
||||
return response.Data.IsOptimistic, err
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package beacon_api
|
||||
package validator_api
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
@@ -8,15 +8,13 @@ import (
|
||||
"net/url"
|
||||
"testing"
|
||||
|
||||
"github.com/golang/mock/gomock"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/beacon"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/node"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/shared"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/validator"
|
||||
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
|
||||
"github.com/prysmaticlabs/prysm/v4/testing/assert"
|
||||
"github.com/prysmaticlabs/prysm/v4/testing/require"
|
||||
"github.com/prysmaticlabs/prysm/v4/validator/client/beacon-api/mock"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/apiutil"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/client/beacon/mock"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/server/structs"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
"github.com/prysmaticlabs/prysm/v5/testing/assert"
|
||||
"github.com/prysmaticlabs/prysm/v5/testing/require"
|
||||
"go.uber.org/mock/gomock"
|
||||
)
|
||||
|
||||
func TestBeaconApiHelpers(t *testing.T) {
|
||||
@@ -59,7 +57,7 @@ func TestBeaconApiHelpers(t *testing.T) {
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
assert.Equal(t, tt.valid, validRoot(tt.input))
|
||||
assert.Equal(t, tt.valid, apiutil.ValidRoot(tt.input))
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -68,16 +66,16 @@ func TestBeaconApiHelpers_TestUint64ToString(t *testing.T) {
|
||||
const expectedResult = "1234"
|
||||
const val = uint64(1234)
|
||||
|
||||
assert.Equal(t, expectedResult, uint64ToString(val))
|
||||
assert.Equal(t, expectedResult, uint64ToString(primitives.Slot(val)))
|
||||
assert.Equal(t, expectedResult, uint64ToString(primitives.ValidatorIndex(val)))
|
||||
assert.Equal(t, expectedResult, uint64ToString(primitives.CommitteeIndex(val)))
|
||||
assert.Equal(t, expectedResult, uint64ToString(primitives.Epoch(val)))
|
||||
assert.Equal(t, expectedResult, apiutil.Uint64ToString(val))
|
||||
assert.Equal(t, expectedResult, apiutil.Uint64ToString(primitives.Slot(val)))
|
||||
assert.Equal(t, expectedResult, apiutil.Uint64ToString(primitives.ValidatorIndex(val)))
|
||||
assert.Equal(t, expectedResult, apiutil.Uint64ToString(primitives.CommitteeIndex(val)))
|
||||
assert.Equal(t, expectedResult, apiutil.Uint64ToString(primitives.Epoch(val)))
|
||||
}
|
||||
|
||||
func TestBuildURL_NoParams(t *testing.T) {
|
||||
wanted := "/aaa/bbb/ccc"
|
||||
actual := buildURL("/aaa/bbb/ccc")
|
||||
actual := apiutil.BuildURL("/aaa/bbb/ccc")
|
||||
assert.Equal(t, wanted, actual)
|
||||
}
|
||||
|
||||
@@ -88,7 +86,7 @@ func TestBuildURL_WithParams(t *testing.T) {
|
||||
params.Add("zzzz", "3")
|
||||
|
||||
wanted := "/aaa/bbb/ccc?xxxx=1&yyyy=2&zzzz=3"
|
||||
actual := buildURL("/aaa/bbb/ccc", params)
|
||||
actual := apiutil.BuildURL("/aaa/bbb/ccc", params)
|
||||
assert.Equal(t, wanted, actual)
|
||||
}
|
||||
|
||||
@@ -98,11 +96,11 @@ func TestGetFork_Nominal(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
|
||||
stateForkResponseJson := beacon.GetStateForkResponse{}
|
||||
stateForkResponseJson := structs.GetStateForkResponse{}
|
||||
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
|
||||
|
||||
expected := beacon.GetStateForkResponse{
|
||||
Data: &shared.Fork{
|
||||
expected := structs.GetStateForkResponse{
|
||||
Data: &structs.Fork{
|
||||
PreviousVersion: "0x1",
|
||||
CurrentVersion: "0x2",
|
||||
Epoch: "3",
|
||||
@@ -112,12 +110,11 @@ func TestGetFork_Nominal(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
jsonRestHandler.EXPECT().Get(
|
||||
ctx,
|
||||
gomock.Any(),
|
||||
forkEndpoint,
|
||||
&stateForkResponseJson,
|
||||
).Return(
|
||||
nil,
|
||||
nil,
|
||||
).SetArg(
|
||||
2,
|
||||
expected,
|
||||
@@ -127,7 +124,7 @@ func TestGetFork_Nominal(t *testing.T) {
|
||||
jsonRestHandler: jsonRestHandler,
|
||||
}
|
||||
|
||||
fork, err := validatorClient.getFork(ctx)
|
||||
fork, err := validatorClient.fork(ctx)
|
||||
require.NoError(t, err)
|
||||
assert.DeepEqual(t, &expected, fork)
|
||||
}
|
||||
@@ -141,11 +138,10 @@ func TestGetFork_Invalid(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
jsonRestHandler.EXPECT().Get(
|
||||
ctx,
|
||||
gomock.Any(),
|
||||
forkEndpoint,
|
||||
gomock.Any(),
|
||||
).Return(
|
||||
nil,
|
||||
errors.New("custom error"),
|
||||
).Times(1)
|
||||
|
||||
@@ -153,7 +149,7 @@ func TestGetFork_Invalid(t *testing.T) {
|
||||
jsonRestHandler: jsonRestHandler,
|
||||
}
|
||||
|
||||
_, err := validatorClient.getFork(ctx)
|
||||
_, err := validatorClient.fork(ctx)
|
||||
require.ErrorContains(t, "custom error", err)
|
||||
}
|
||||
|
||||
@@ -163,14 +159,14 @@ func TestGetHeaders_Nominal(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
|
||||
blockHeadersResponseJson := beacon.GetBlockHeadersResponse{}
|
||||
blockHeadersResponseJson := structs.GetBlockHeadersResponse{}
|
||||
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
|
||||
|
||||
expected := beacon.GetBlockHeadersResponse{
|
||||
Data: []*shared.SignedBeaconBlockHeaderContainer{
|
||||
expected := structs.GetBlockHeadersResponse{
|
||||
Data: []*structs.SignedBeaconBlockHeaderContainer{
|
||||
{
|
||||
Header: &shared.SignedBeaconBlockHeader{
|
||||
Message: &shared.BeaconBlockHeader{
|
||||
Header: &structs.SignedBeaconBlockHeader{
|
||||
Message: &structs.BeaconBlockHeader{
|
||||
Slot: "42",
|
||||
},
|
||||
},
|
||||
@@ -181,12 +177,11 @@ func TestGetHeaders_Nominal(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
jsonRestHandler.EXPECT().Get(
|
||||
ctx,
|
||||
gomock.Any(),
|
||||
headersEndpoint,
|
||||
&blockHeadersResponseJson,
|
||||
).Return(
|
||||
nil,
|
||||
nil,
|
||||
).SetArg(
|
||||
2,
|
||||
expected,
|
||||
@@ -196,7 +191,7 @@ func TestGetHeaders_Nominal(t *testing.T) {
|
||||
jsonRestHandler: jsonRestHandler,
|
||||
}
|
||||
|
||||
headers, err := validatorClient.getHeaders(ctx)
|
||||
headers, err := validatorClient.headers(ctx)
|
||||
require.NoError(t, err)
|
||||
assert.DeepEqual(t, &expected, headers)
|
||||
}
|
||||
@@ -210,11 +205,10 @@ func TestGetHeaders_Invalid(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
jsonRestHandler.EXPECT().Get(
|
||||
ctx,
|
||||
gomock.Any(),
|
||||
headersEndpoint,
|
||||
gomock.Any(),
|
||||
).Return(
|
||||
nil,
|
||||
errors.New("custom error"),
|
||||
).Times(1)
|
||||
|
||||
@@ -222,7 +216,7 @@ func TestGetHeaders_Invalid(t *testing.T) {
|
||||
jsonRestHandler: jsonRestHandler,
|
||||
}
|
||||
|
||||
_, err := validatorClient.getHeaders(ctx)
|
||||
_, err := validatorClient.headers(ctx)
|
||||
require.ErrorContains(t, "custom error", err)
|
||||
}
|
||||
|
||||
@@ -232,14 +226,14 @@ func TestGetLiveness_Nominal(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
|
||||
livenessResponseJson := validator.GetLivenessResponse{}
|
||||
livenessResponseJson := structs.GetLivenessResponse{}
|
||||
|
||||
indexes := []string{"1", "2"}
|
||||
marshalledIndexes, err := json.Marshal(indexes)
|
||||
require.NoError(t, err)
|
||||
|
||||
expected := validator.GetLivenessResponse{
|
||||
Data: []*validator.Liveness{
|
||||
expected := structs.GetLivenessResponse{
|
||||
Data: []*structs.Liveness{
|
||||
{
|
||||
Index: "1",
|
||||
IsLive: true,
|
||||
@@ -255,7 +249,7 @@ func TestGetLiveness_Nominal(t *testing.T) {
|
||||
|
||||
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
|
||||
jsonRestHandler.EXPECT().Post(
|
||||
ctx,
|
||||
gomock.Any(),
|
||||
livenessEndpoint,
|
||||
nil,
|
||||
bytes.NewBuffer(marshalledIndexes),
|
||||
@@ -265,11 +259,10 @@ func TestGetLiveness_Nominal(t *testing.T) {
|
||||
expected,
|
||||
).Return(
|
||||
nil,
|
||||
nil,
|
||||
).Times(1)
|
||||
|
||||
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
|
||||
liveness, err := validatorClient.getLiveness(ctx, 42, indexes)
|
||||
liveness, err := validatorClient.liveness(ctx, 42, indexes)
|
||||
|
||||
require.NoError(t, err)
|
||||
assert.DeepEqual(t, &expected, liveness)
|
||||
@@ -283,23 +276,22 @@ func TestGetLiveness_Invalid(t *testing.T) {
|
||||
|
||||
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
|
||||
jsonRestHandler.EXPECT().Post(
|
||||
ctx,
|
||||
gomock.Any(),
|
||||
livenessEndpoint,
|
||||
nil,
|
||||
gomock.Any(),
|
||||
gomock.Any(),
|
||||
).Return(
|
||||
nil,
|
||||
errors.New("custom error"),
|
||||
).Times(1)
|
||||
|
||||
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
|
||||
_, err := validatorClient.getLiveness(ctx, 42, nil)
|
||||
_, err := validatorClient.liveness(ctx, 42, nil)
|
||||
|
||||
require.ErrorContains(t, "custom error", err)
|
||||
}
|
||||
|
||||
const syncingEnpoint = "/eth/v1/node/syncing"
|
||||
const syncingEndpoint = "/eth/v1/node/syncing"
|
||||
|
||||
func TestGetIsSyncing_Nominal(t *testing.T) {
|
||||
testCases := []struct {
|
||||
@@ -321,11 +313,11 @@ func TestGetIsSyncing_Nominal(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
|
||||
syncingResponseJson := node.SyncStatusResponse{}
|
||||
syncingResponseJson := structs.SyncStatusResponse{}
|
||||
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
|
||||
|
||||
expected := node.SyncStatusResponse{
|
||||
Data: &node.SyncStatusResponseData{
|
||||
expected := structs.SyncStatusResponse{
|
||||
Data: &structs.SyncStatusResponseData{
|
||||
IsSyncing: testCase.isSyncing,
|
||||
},
|
||||
}
|
||||
@@ -333,12 +325,11 @@ func TestGetIsSyncing_Nominal(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
jsonRestHandler.EXPECT().Get(
|
||||
ctx,
|
||||
syncingEnpoint,
|
||||
gomock.Any(),
|
||||
syncingEndpoint,
|
||||
&syncingResponseJson,
|
||||
).Return(
|
||||
nil,
|
||||
nil,
|
||||
).SetArg(
|
||||
2,
|
||||
expected,
|
||||
@@ -359,17 +350,16 @@ func TestGetIsSyncing_Invalid(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
|
||||
syncingResponseJson := node.SyncStatusResponse{}
|
||||
syncingResponseJson := structs.SyncStatusResponse{}
|
||||
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
jsonRestHandler.EXPECT().Get(
|
||||
ctx,
|
||||
syncingEnpoint,
|
||||
gomock.Any(),
|
||||
syncingEndpoint,
|
||||
&syncingResponseJson,
|
||||
).Return(
|
||||
nil,
|
||||
errors.New("custom error"),
|
||||
).Times(1)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package beacon_api
|
||||
package validator_api
|
||||
|
||||
import (
|
||||
"math/big"
|
||||
@@ -6,24 +6,24 @@ import (
|
||||
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/shared"
|
||||
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
|
||||
"github.com/prysmaticlabs/prysm/v4/encoding/bytesutil"
|
||||
enginev1 "github.com/prysmaticlabs/prysm/v4/proto/engine/v1"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/server/structs"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
"github.com/prysmaticlabs/prysm/v5/encoding/bytesutil"
|
||||
enginev1 "github.com/prysmaticlabs/prysm/v5/proto/engine/v1"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
)
|
||||
|
||||
type BeaconBlockConverter interface {
|
||||
ConvertRESTPhase0BlockToProto(block *shared.BeaconBlock) (*ethpb.BeaconBlock, error)
|
||||
ConvertRESTAltairBlockToProto(block *shared.BeaconBlockAltair) (*ethpb.BeaconBlockAltair, error)
|
||||
ConvertRESTBellatrixBlockToProto(block *shared.BeaconBlockBellatrix) (*ethpb.BeaconBlockBellatrix, error)
|
||||
ConvertRESTCapellaBlockToProto(block *shared.BeaconBlockCapella) (*ethpb.BeaconBlockCapella, error)
|
||||
ConvertRESTPhase0BlockToProto(block *structs.BeaconBlock) (*ethpb.BeaconBlock, error)
|
||||
ConvertRESTAltairBlockToProto(block *structs.BeaconBlockAltair) (*ethpb.BeaconBlockAltair, error)
|
||||
ConvertRESTBellatrixBlockToProto(block *structs.BeaconBlockBellatrix) (*ethpb.BeaconBlockBellatrix, error)
|
||||
ConvertRESTCapellaBlockToProto(block *structs.BeaconBlockCapella) (*ethpb.BeaconBlockCapella, error)
|
||||
}
|
||||
|
||||
type beaconApiBeaconBlockConverter struct{}
|
||||
|
||||
// ConvertRESTPhase0BlockToProto converts a Phase0 JSON beacon block to its protobuf equivalent
|
||||
func (c beaconApiBeaconBlockConverter) ConvertRESTPhase0BlockToProto(block *shared.BeaconBlock) (*ethpb.BeaconBlock, error) {
|
||||
func (c beaconApiBeaconBlockConverter) ConvertRESTPhase0BlockToProto(block *structs.BeaconBlock) (*ethpb.BeaconBlock, error) {
|
||||
blockSlot, err := strconv.ParseUint(block.Slot, 10, 64)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to parse slot `%s`", block.Slot)
|
||||
@@ -125,19 +125,19 @@ func (c beaconApiBeaconBlockConverter) ConvertRESTPhase0BlockToProto(block *shar
|
||||
}
|
||||
|
||||
// ConvertRESTAltairBlockToProto converts an Altair JSON beacon block to its protobuf equivalent
|
||||
func (c beaconApiBeaconBlockConverter) ConvertRESTAltairBlockToProto(block *shared.BeaconBlockAltair) (*ethpb.BeaconBlockAltair, error) {
|
||||
func (c beaconApiBeaconBlockConverter) ConvertRESTAltairBlockToProto(block *structs.BeaconBlockAltair) (*ethpb.BeaconBlockAltair, error) {
|
||||
if block.Body == nil {
|
||||
return nil, errors.New("block body is nil")
|
||||
}
|
||||
|
||||
// Call convertRESTPhase0BlockToProto to set the phase0 fields because all the error handling and the heavy lifting
|
||||
// has already been done
|
||||
phase0Block, err := c.ConvertRESTPhase0BlockToProto(&shared.BeaconBlock{
|
||||
phase0Block, err := c.ConvertRESTPhase0BlockToProto(&structs.BeaconBlock{
|
||||
Slot: block.Slot,
|
||||
ProposerIndex: block.ProposerIndex,
|
||||
ParentRoot: block.ParentRoot,
|
||||
StateRoot: block.StateRoot,
|
||||
Body: &shared.BeaconBlockBody{
|
||||
Body: &structs.BeaconBlockBody{
|
||||
RandaoReveal: block.Body.RandaoReveal,
|
||||
Eth1Data: block.Body.Eth1Data,
|
||||
Graffiti: block.Body.Graffiti,
|
||||
@@ -189,19 +189,19 @@ func (c beaconApiBeaconBlockConverter) ConvertRESTAltairBlockToProto(block *shar
|
||||
}
|
||||
|
||||
// ConvertRESTBellatrixBlockToProto converts a Bellatrix JSON beacon block to its protobuf equivalent
|
||||
func (c beaconApiBeaconBlockConverter) ConvertRESTBellatrixBlockToProto(block *shared.BeaconBlockBellatrix) (*ethpb.BeaconBlockBellatrix, error) {
|
||||
func (c beaconApiBeaconBlockConverter) ConvertRESTBellatrixBlockToProto(block *structs.BeaconBlockBellatrix) (*ethpb.BeaconBlockBellatrix, error) {
|
||||
if block.Body == nil {
|
||||
return nil, errors.New("block body is nil")
|
||||
}
|
||||
|
||||
// Call convertRESTAltairBlockToProto to set the altair fields because all the error handling and the heavy lifting
|
||||
// has already been done
|
||||
altairBlock, err := c.ConvertRESTAltairBlockToProto(&shared.BeaconBlockAltair{
|
||||
altairBlock, err := c.ConvertRESTAltairBlockToProto(&structs.BeaconBlockAltair{
|
||||
Slot: block.Slot,
|
||||
ProposerIndex: block.ProposerIndex,
|
||||
ParentRoot: block.ParentRoot,
|
||||
StateRoot: block.StateRoot,
|
||||
Body: &shared.BeaconBlockBodyAltair{
|
||||
Body: &structs.BeaconBlockBodyAltair{
|
||||
RandaoReveal: block.Body.RandaoReveal,
|
||||
Eth1Data: block.Body.Eth1Data,
|
||||
Graffiti: block.Body.Graffiti,
|
||||
@@ -327,7 +327,7 @@ func (c beaconApiBeaconBlockConverter) ConvertRESTBellatrixBlockToProto(block *s
|
||||
}
|
||||
|
||||
// ConvertRESTCapellaBlockToProto converts a Capella JSON beacon block to its protobuf equivalent
|
||||
func (c beaconApiBeaconBlockConverter) ConvertRESTCapellaBlockToProto(block *shared.BeaconBlockCapella) (*ethpb.BeaconBlockCapella, error) {
|
||||
func (c beaconApiBeaconBlockConverter) ConvertRESTCapellaBlockToProto(block *structs.BeaconBlockCapella) (*ethpb.BeaconBlockCapella, error) {
|
||||
if block.Body == nil {
|
||||
return nil, errors.New("block body is nil")
|
||||
}
|
||||
@@ -338,12 +338,12 @@ func (c beaconApiBeaconBlockConverter) ConvertRESTCapellaBlockToProto(block *sha
|
||||
|
||||
// Call convertRESTBellatrixBlockToProto to set the bellatrix fields because all the error handling and the heavy
|
||||
// lifting has already been done
|
||||
bellatrixBlock, err := c.ConvertRESTBellatrixBlockToProto(&shared.BeaconBlockBellatrix{
|
||||
bellatrixBlock, err := c.ConvertRESTBellatrixBlockToProto(&structs.BeaconBlockBellatrix{
|
||||
Slot: block.Slot,
|
||||
ProposerIndex: block.ProposerIndex,
|
||||
ParentRoot: block.ParentRoot,
|
||||
StateRoot: block.StateRoot,
|
||||
Body: &shared.BeaconBlockBodyBellatrix{
|
||||
Body: &structs.BeaconBlockBodyBellatrix{
|
||||
RandaoReveal: block.Body.RandaoReveal,
|
||||
Eth1Data: block.Body.Eth1Data,
|
||||
Graffiti: block.Body.Graffiti,
|
||||
@@ -353,7 +353,7 @@ func (c beaconApiBeaconBlockConverter) ConvertRESTCapellaBlockToProto(block *sha
|
||||
Deposits: block.Body.Deposits,
|
||||
VoluntaryExits: block.Body.VoluntaryExits,
|
||||
SyncAggregate: block.Body.SyncAggregate,
|
||||
ExecutionPayload: &shared.ExecutionPayload{
|
||||
ExecutionPayload: &structs.ExecutionPayload{
|
||||
ParentHash: block.Body.ExecutionPayload.ParentHash,
|
||||
FeeRecipient: block.Body.ExecutionPayload.FeeRecipient,
|
||||
StateRoot: block.Body.ExecutionPayload.StateRoot,
|
||||
@@ -1,12 +1,12 @@
|
||||
package beacon_api
|
||||
package validator_api
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/shared"
|
||||
"github.com/prysmaticlabs/prysm/v4/testing/assert"
|
||||
"github.com/prysmaticlabs/prysm/v4/testing/require"
|
||||
test_helpers "github.com/prysmaticlabs/prysm/v4/validator/client/beacon-api/test-helpers"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/client/beacon/validator_api/test_helpers"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/server/structs"
|
||||
"github.com/prysmaticlabs/prysm/v5/testing/assert"
|
||||
"github.com/prysmaticlabs/prysm/v5/testing/require"
|
||||
)
|
||||
|
||||
func TestGetBeaconBlockConverter_Phase0Valid(t *testing.T) {
|
||||
@@ -21,12 +21,12 @@ func TestGetBeaconBlockConverter_Phase0Error(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
expectedErrorMessage string
|
||||
generateData func() *shared.BeaconBlock
|
||||
generateData func() *structs.BeaconBlock
|
||||
}{
|
||||
{
|
||||
name: "nil body",
|
||||
expectedErrorMessage: "block body is nil",
|
||||
generateData: func() *shared.BeaconBlock {
|
||||
generateData: func() *structs.BeaconBlock {
|
||||
beaconBlock := test_helpers.GenerateJsonPhase0BeaconBlock()
|
||||
beaconBlock.Body = nil
|
||||
return beaconBlock
|
||||
@@ -35,7 +35,7 @@ func TestGetBeaconBlockConverter_Phase0Error(t *testing.T) {
|
||||
{
|
||||
name: "nil eth1 data",
|
||||
expectedErrorMessage: "eth1 data is nil",
|
||||
generateData: func() *shared.BeaconBlock {
|
||||
generateData: func() *structs.BeaconBlock {
|
||||
beaconBlock := test_helpers.GenerateJsonPhase0BeaconBlock()
|
||||
beaconBlock.Body.Eth1Data = nil
|
||||
return beaconBlock
|
||||
@@ -44,7 +44,7 @@ func TestGetBeaconBlockConverter_Phase0Error(t *testing.T) {
|
||||
{
|
||||
name: "bad slot",
|
||||
expectedErrorMessage: "failed to parse slot `foo`",
|
||||
generateData: func() *shared.BeaconBlock {
|
||||
generateData: func() *structs.BeaconBlock {
|
||||
beaconBlock := test_helpers.GenerateJsonPhase0BeaconBlock()
|
||||
beaconBlock.Slot = "foo"
|
||||
return beaconBlock
|
||||
@@ -53,7 +53,7 @@ func TestGetBeaconBlockConverter_Phase0Error(t *testing.T) {
|
||||
{
|
||||
name: "bad proposer index",
|
||||
expectedErrorMessage: "failed to parse proposer index `bar`",
|
||||
generateData: func() *shared.BeaconBlock {
|
||||
generateData: func() *structs.BeaconBlock {
|
||||
beaconBlock := test_helpers.GenerateJsonPhase0BeaconBlock()
|
||||
beaconBlock.ProposerIndex = "bar"
|
||||
return beaconBlock
|
||||
@@ -62,7 +62,7 @@ func TestGetBeaconBlockConverter_Phase0Error(t *testing.T) {
|
||||
{
|
||||
name: "bad parent root",
|
||||
expectedErrorMessage: "failed to decode parent root `foo`",
|
||||
generateData: func() *shared.BeaconBlock {
|
||||
generateData: func() *structs.BeaconBlock {
|
||||
beaconBlock := test_helpers.GenerateJsonPhase0BeaconBlock()
|
||||
beaconBlock.ParentRoot = "foo"
|
||||
return beaconBlock
|
||||
@@ -71,7 +71,7 @@ func TestGetBeaconBlockConverter_Phase0Error(t *testing.T) {
|
||||
{
|
||||
name: "bad state root",
|
||||
expectedErrorMessage: "failed to decode state root `bar`",
|
||||
generateData: func() *shared.BeaconBlock {
|
||||
generateData: func() *structs.BeaconBlock {
|
||||
beaconBlock := test_helpers.GenerateJsonPhase0BeaconBlock()
|
||||
beaconBlock.StateRoot = "bar"
|
||||
return beaconBlock
|
||||
@@ -80,7 +80,7 @@ func TestGetBeaconBlockConverter_Phase0Error(t *testing.T) {
|
||||
{
|
||||
name: "bad randao reveal",
|
||||
expectedErrorMessage: "failed to decode randao reveal `foo`",
|
||||
generateData: func() *shared.BeaconBlock {
|
||||
generateData: func() *structs.BeaconBlock {
|
||||
beaconBlock := test_helpers.GenerateJsonPhase0BeaconBlock()
|
||||
beaconBlock.Body.RandaoReveal = "foo"
|
||||
return beaconBlock
|
||||
@@ -89,7 +89,7 @@ func TestGetBeaconBlockConverter_Phase0Error(t *testing.T) {
|
||||
{
|
||||
name: "bad deposit root",
|
||||
expectedErrorMessage: "failed to decode deposit root `bar`",
|
||||
generateData: func() *shared.BeaconBlock {
|
||||
generateData: func() *structs.BeaconBlock {
|
||||
beaconBlock := test_helpers.GenerateJsonPhase0BeaconBlock()
|
||||
beaconBlock.Body.Eth1Data.DepositRoot = "bar"
|
||||
return beaconBlock
|
||||
@@ -98,7 +98,7 @@ func TestGetBeaconBlockConverter_Phase0Error(t *testing.T) {
|
||||
{
|
||||
name: "bad deposit count",
|
||||
expectedErrorMessage: "failed to parse deposit count `foo`",
|
||||
generateData: func() *shared.BeaconBlock {
|
||||
generateData: func() *structs.BeaconBlock {
|
||||
beaconBlock := test_helpers.GenerateJsonPhase0BeaconBlock()
|
||||
beaconBlock.Body.Eth1Data.DepositCount = "foo"
|
||||
return beaconBlock
|
||||
@@ -107,7 +107,7 @@ func TestGetBeaconBlockConverter_Phase0Error(t *testing.T) {
|
||||
{
|
||||
name: "bad block hash",
|
||||
expectedErrorMessage: "failed to decode block hash `bar`",
|
||||
generateData: func() *shared.BeaconBlock {
|
||||
generateData: func() *structs.BeaconBlock {
|
||||
beaconBlock := test_helpers.GenerateJsonPhase0BeaconBlock()
|
||||
beaconBlock.Body.Eth1Data.BlockHash = "bar"
|
||||
return beaconBlock
|
||||
@@ -116,7 +116,7 @@ func TestGetBeaconBlockConverter_Phase0Error(t *testing.T) {
|
||||
{
|
||||
name: "bad graffiti",
|
||||
expectedErrorMessage: "failed to decode graffiti `foo`",
|
||||
generateData: func() *shared.BeaconBlock {
|
||||
generateData: func() *structs.BeaconBlock {
|
||||
beaconBlock := test_helpers.GenerateJsonPhase0BeaconBlock()
|
||||
beaconBlock.Body.Graffiti = "foo"
|
||||
return beaconBlock
|
||||
@@ -125,7 +125,7 @@ func TestGetBeaconBlockConverter_Phase0Error(t *testing.T) {
|
||||
{
|
||||
name: "bad proposer slashings",
|
||||
expectedErrorMessage: "failed to get proposer slashings",
|
||||
generateData: func() *shared.BeaconBlock {
|
||||
generateData: func() *structs.BeaconBlock {
|
||||
beaconBlock := test_helpers.GenerateJsonPhase0BeaconBlock()
|
||||
beaconBlock.Body.ProposerSlashings[0] = nil
|
||||
return beaconBlock
|
||||
@@ -134,7 +134,7 @@ func TestGetBeaconBlockConverter_Phase0Error(t *testing.T) {
|
||||
{
|
||||
name: "bad attester slashings",
|
||||
expectedErrorMessage: "failed to get attester slashings",
|
||||
generateData: func() *shared.BeaconBlock {
|
||||
generateData: func() *structs.BeaconBlock {
|
||||
beaconBlock := test_helpers.GenerateJsonPhase0BeaconBlock()
|
||||
beaconBlock.Body.AttesterSlashings[0] = nil
|
||||
return beaconBlock
|
||||
@@ -143,7 +143,7 @@ func TestGetBeaconBlockConverter_Phase0Error(t *testing.T) {
|
||||
{
|
||||
name: "bad attestations",
|
||||
expectedErrorMessage: "failed to get attestations",
|
||||
generateData: func() *shared.BeaconBlock {
|
||||
generateData: func() *structs.BeaconBlock {
|
||||
beaconBlock := test_helpers.GenerateJsonPhase0BeaconBlock()
|
||||
beaconBlock.Body.Attestations[0] = nil
|
||||
return beaconBlock
|
||||
@@ -152,7 +152,7 @@ func TestGetBeaconBlockConverter_Phase0Error(t *testing.T) {
|
||||
{
|
||||
name: "bad deposits",
|
||||
expectedErrorMessage: "failed to get deposits",
|
||||
generateData: func() *shared.BeaconBlock {
|
||||
generateData: func() *structs.BeaconBlock {
|
||||
beaconBlock := test_helpers.GenerateJsonPhase0BeaconBlock()
|
||||
beaconBlock.Body.Deposits[0] = nil
|
||||
return beaconBlock
|
||||
@@ -161,7 +161,7 @@ func TestGetBeaconBlockConverter_Phase0Error(t *testing.T) {
|
||||
{
|
||||
name: "bad voluntary exits",
|
||||
expectedErrorMessage: "failed to get voluntary exits",
|
||||
generateData: func() *shared.BeaconBlock {
|
||||
generateData: func() *structs.BeaconBlock {
|
||||
beaconBlock := test_helpers.GenerateJsonPhase0BeaconBlock()
|
||||
beaconBlock.Body.VoluntaryExits[0] = nil
|
||||
return beaconBlock
|
||||
@@ -192,12 +192,12 @@ func TestGetBeaconBlockConverter_AltairError(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
expectedErrorMessage string
|
||||
generateData func() *shared.BeaconBlockAltair
|
||||
generateData func() *structs.BeaconBlockAltair
|
||||
}{
|
||||
{
|
||||
name: "nil body",
|
||||
expectedErrorMessage: "block body is nil",
|
||||
generateData: func() *shared.BeaconBlockAltair {
|
||||
generateData: func() *structs.BeaconBlockAltair {
|
||||
beaconBlock := test_helpers.GenerateJsonAltairBeaconBlock()
|
||||
beaconBlock.Body = nil
|
||||
return beaconBlock
|
||||
@@ -206,7 +206,7 @@ func TestGetBeaconBlockConverter_AltairError(t *testing.T) {
|
||||
{
|
||||
name: "nil sync aggregate",
|
||||
expectedErrorMessage: "sync aggregate is nil",
|
||||
generateData: func() *shared.BeaconBlockAltair {
|
||||
generateData: func() *structs.BeaconBlockAltair {
|
||||
beaconBlock := test_helpers.GenerateJsonAltairBeaconBlock()
|
||||
beaconBlock.Body.SyncAggregate = nil
|
||||
return beaconBlock
|
||||
@@ -215,7 +215,7 @@ func TestGetBeaconBlockConverter_AltairError(t *testing.T) {
|
||||
{
|
||||
name: "bad phase0 fields",
|
||||
expectedErrorMessage: "failed to get the phase0 fields of the altair block",
|
||||
generateData: func() *shared.BeaconBlockAltair {
|
||||
generateData: func() *structs.BeaconBlockAltair {
|
||||
beaconBlock := test_helpers.GenerateJsonAltairBeaconBlock()
|
||||
beaconBlock.Body.Eth1Data = nil
|
||||
return beaconBlock
|
||||
@@ -224,7 +224,7 @@ func TestGetBeaconBlockConverter_AltairError(t *testing.T) {
|
||||
{
|
||||
name: "bad sync committee bits",
|
||||
expectedErrorMessage: "failed to decode sync committee bits `foo`",
|
||||
generateData: func() *shared.BeaconBlockAltair {
|
||||
generateData: func() *structs.BeaconBlockAltair {
|
||||
beaconBlock := test_helpers.GenerateJsonAltairBeaconBlock()
|
||||
beaconBlock.Body.SyncAggregate.SyncCommitteeBits = "foo"
|
||||
return beaconBlock
|
||||
@@ -233,7 +233,7 @@ func TestGetBeaconBlockConverter_AltairError(t *testing.T) {
|
||||
{
|
||||
name: "bad sync committee signature",
|
||||
expectedErrorMessage: "failed to decode sync committee signature `bar`",
|
||||
generateData: func() *shared.BeaconBlockAltair {
|
||||
generateData: func() *structs.BeaconBlockAltair {
|
||||
beaconBlock := test_helpers.GenerateJsonAltairBeaconBlock()
|
||||
beaconBlock.Body.SyncAggregate.SyncCommitteeSignature = "bar"
|
||||
return beaconBlock
|
||||
@@ -264,12 +264,12 @@ func TestGetBeaconBlockConverter_BellatrixError(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
expectedErrorMessage string
|
||||
generateData func() *shared.BeaconBlockBellatrix
|
||||
generateData func() *structs.BeaconBlockBellatrix
|
||||
}{
|
||||
{
|
||||
name: "nil body",
|
||||
expectedErrorMessage: "block body is nil",
|
||||
generateData: func() *shared.BeaconBlockBellatrix {
|
||||
generateData: func() *structs.BeaconBlockBellatrix {
|
||||
beaconBlock := test_helpers.GenerateJsonBellatrixBeaconBlock()
|
||||
beaconBlock.Body = nil
|
||||
return beaconBlock
|
||||
@@ -278,7 +278,7 @@ func TestGetBeaconBlockConverter_BellatrixError(t *testing.T) {
|
||||
{
|
||||
name: "nil execution payload",
|
||||
expectedErrorMessage: "execution payload is nil",
|
||||
generateData: func() *shared.BeaconBlockBellatrix {
|
||||
generateData: func() *structs.BeaconBlockBellatrix {
|
||||
beaconBlock := test_helpers.GenerateJsonBellatrixBeaconBlock()
|
||||
beaconBlock.Body.ExecutionPayload = nil
|
||||
return beaconBlock
|
||||
@@ -287,7 +287,7 @@ func TestGetBeaconBlockConverter_BellatrixError(t *testing.T) {
|
||||
{
|
||||
name: "bad altair fields",
|
||||
expectedErrorMessage: "failed to get the altair fields of the bellatrix block",
|
||||
generateData: func() *shared.BeaconBlockBellatrix {
|
||||
generateData: func() *structs.BeaconBlockBellatrix {
|
||||
beaconBlock := test_helpers.GenerateJsonBellatrixBeaconBlock()
|
||||
beaconBlock.Body.Eth1Data = nil
|
||||
return beaconBlock
|
||||
@@ -296,7 +296,7 @@ func TestGetBeaconBlockConverter_BellatrixError(t *testing.T) {
|
||||
{
|
||||
name: "bad parent hash",
|
||||
expectedErrorMessage: "failed to decode execution payload parent hash `foo`",
|
||||
generateData: func() *shared.BeaconBlockBellatrix {
|
||||
generateData: func() *structs.BeaconBlockBellatrix {
|
||||
beaconBlock := test_helpers.GenerateJsonBellatrixBeaconBlock()
|
||||
beaconBlock.Body.ExecutionPayload.ParentHash = "foo"
|
||||
return beaconBlock
|
||||
@@ -305,7 +305,7 @@ func TestGetBeaconBlockConverter_BellatrixError(t *testing.T) {
|
||||
{
|
||||
name: "bad fee recipient",
|
||||
expectedErrorMessage: "failed to decode execution payload fee recipient `bar`",
|
||||
generateData: func() *shared.BeaconBlockBellatrix {
|
||||
generateData: func() *structs.BeaconBlockBellatrix {
|
||||
beaconBlock := test_helpers.GenerateJsonBellatrixBeaconBlock()
|
||||
beaconBlock.Body.ExecutionPayload.FeeRecipient = "bar"
|
||||
return beaconBlock
|
||||
@@ -314,7 +314,7 @@ func TestGetBeaconBlockConverter_BellatrixError(t *testing.T) {
|
||||
{
|
||||
name: "bad state root",
|
||||
expectedErrorMessage: "failed to decode execution payload state root `foo`",
|
||||
generateData: func() *shared.BeaconBlockBellatrix {
|
||||
generateData: func() *structs.BeaconBlockBellatrix {
|
||||
beaconBlock := test_helpers.GenerateJsonBellatrixBeaconBlock()
|
||||
beaconBlock.Body.ExecutionPayload.StateRoot = "foo"
|
||||
return beaconBlock
|
||||
@@ -323,7 +323,7 @@ func TestGetBeaconBlockConverter_BellatrixError(t *testing.T) {
|
||||
{
|
||||
name: "bad receipts root",
|
||||
expectedErrorMessage: "failed to decode execution payload receipts root `bar`",
|
||||
generateData: func() *shared.BeaconBlockBellatrix {
|
||||
generateData: func() *structs.BeaconBlockBellatrix {
|
||||
beaconBlock := test_helpers.GenerateJsonBellatrixBeaconBlock()
|
||||
beaconBlock.Body.ExecutionPayload.ReceiptsRoot = "bar"
|
||||
return beaconBlock
|
||||
@@ -332,7 +332,7 @@ func TestGetBeaconBlockConverter_BellatrixError(t *testing.T) {
|
||||
{
|
||||
name: "bad logs bloom",
|
||||
expectedErrorMessage: "failed to decode execution payload logs bloom `foo`",
|
||||
generateData: func() *shared.BeaconBlockBellatrix {
|
||||
generateData: func() *structs.BeaconBlockBellatrix {
|
||||
beaconBlock := test_helpers.GenerateJsonBellatrixBeaconBlock()
|
||||
beaconBlock.Body.ExecutionPayload.LogsBloom = "foo"
|
||||
return beaconBlock
|
||||
@@ -341,7 +341,7 @@ func TestGetBeaconBlockConverter_BellatrixError(t *testing.T) {
|
||||
{
|
||||
name: "bad prev randao",
|
||||
expectedErrorMessage: "failed to decode execution payload prev randao `bar`",
|
||||
generateData: func() *shared.BeaconBlockBellatrix {
|
||||
generateData: func() *structs.BeaconBlockBellatrix {
|
||||
beaconBlock := test_helpers.GenerateJsonBellatrixBeaconBlock()
|
||||
beaconBlock.Body.ExecutionPayload.PrevRandao = "bar"
|
||||
return beaconBlock
|
||||
@@ -350,7 +350,7 @@ func TestGetBeaconBlockConverter_BellatrixError(t *testing.T) {
|
||||
{
|
||||
name: "bad block number",
|
||||
expectedErrorMessage: "failed to parse execution payload block number `foo`",
|
||||
generateData: func() *shared.BeaconBlockBellatrix {
|
||||
generateData: func() *structs.BeaconBlockBellatrix {
|
||||
beaconBlock := test_helpers.GenerateJsonBellatrixBeaconBlock()
|
||||
beaconBlock.Body.ExecutionPayload.BlockNumber = "foo"
|
||||
return beaconBlock
|
||||
@@ -359,7 +359,7 @@ func TestGetBeaconBlockConverter_BellatrixError(t *testing.T) {
|
||||
{
|
||||
name: "bad gas limit",
|
||||
expectedErrorMessage: "failed to parse execution payload gas limit `bar`",
|
||||
generateData: func() *shared.BeaconBlockBellatrix {
|
||||
generateData: func() *structs.BeaconBlockBellatrix {
|
||||
beaconBlock := test_helpers.GenerateJsonBellatrixBeaconBlock()
|
||||
beaconBlock.Body.ExecutionPayload.GasLimit = "bar"
|
||||
return beaconBlock
|
||||
@@ -368,7 +368,7 @@ func TestGetBeaconBlockConverter_BellatrixError(t *testing.T) {
|
||||
{
|
||||
name: "bad gas used",
|
||||
expectedErrorMessage: "failed to parse execution payload gas used `foo`",
|
||||
generateData: func() *shared.BeaconBlockBellatrix {
|
||||
generateData: func() *structs.BeaconBlockBellatrix {
|
||||
beaconBlock := test_helpers.GenerateJsonBellatrixBeaconBlock()
|
||||
beaconBlock.Body.ExecutionPayload.GasUsed = "foo"
|
||||
return beaconBlock
|
||||
@@ -377,7 +377,7 @@ func TestGetBeaconBlockConverter_BellatrixError(t *testing.T) {
|
||||
{
|
||||
name: "bad timestamp",
|
||||
expectedErrorMessage: "failed to parse execution payload timestamp `bar`",
|
||||
generateData: func() *shared.BeaconBlockBellatrix {
|
||||
generateData: func() *structs.BeaconBlockBellatrix {
|
||||
beaconBlock := test_helpers.GenerateJsonBellatrixBeaconBlock()
|
||||
beaconBlock.Body.ExecutionPayload.Timestamp = "bar"
|
||||
return beaconBlock
|
||||
@@ -386,7 +386,7 @@ func TestGetBeaconBlockConverter_BellatrixError(t *testing.T) {
|
||||
{
|
||||
name: "bad extra data",
|
||||
expectedErrorMessage: "failed to decode execution payload extra data `foo`",
|
||||
generateData: func() *shared.BeaconBlockBellatrix {
|
||||
generateData: func() *structs.BeaconBlockBellatrix {
|
||||
beaconBlock := test_helpers.GenerateJsonBellatrixBeaconBlock()
|
||||
beaconBlock.Body.ExecutionPayload.ExtraData = "foo"
|
||||
return beaconBlock
|
||||
@@ -395,7 +395,7 @@ func TestGetBeaconBlockConverter_BellatrixError(t *testing.T) {
|
||||
{
|
||||
name: "bad base fee per gas",
|
||||
expectedErrorMessage: "failed to parse execution payload base fee per gas `bar`",
|
||||
generateData: func() *shared.BeaconBlockBellatrix {
|
||||
generateData: func() *structs.BeaconBlockBellatrix {
|
||||
beaconBlock := test_helpers.GenerateJsonBellatrixBeaconBlock()
|
||||
beaconBlock.Body.ExecutionPayload.BaseFeePerGas = "bar"
|
||||
return beaconBlock
|
||||
@@ -404,7 +404,7 @@ func TestGetBeaconBlockConverter_BellatrixError(t *testing.T) {
|
||||
{
|
||||
name: "bad block hash",
|
||||
expectedErrorMessage: "failed to decode execution payload block hash `foo`",
|
||||
generateData: func() *shared.BeaconBlockBellatrix {
|
||||
generateData: func() *structs.BeaconBlockBellatrix {
|
||||
beaconBlock := test_helpers.GenerateJsonBellatrixBeaconBlock()
|
||||
beaconBlock.Body.ExecutionPayload.BlockHash = "foo"
|
||||
return beaconBlock
|
||||
@@ -413,7 +413,7 @@ func TestGetBeaconBlockConverter_BellatrixError(t *testing.T) {
|
||||
{
|
||||
name: "bad transactions",
|
||||
expectedErrorMessage: "failed to get execution payload transactions",
|
||||
generateData: func() *shared.BeaconBlockBellatrix {
|
||||
generateData: func() *structs.BeaconBlockBellatrix {
|
||||
beaconBlock := test_helpers.GenerateJsonBellatrixBeaconBlock()
|
||||
beaconBlock.Body.ExecutionPayload.Transactions[0] = "bar"
|
||||
return beaconBlock
|
||||
@@ -444,12 +444,12 @@ func TestGetBeaconBlockConverter_CapellaError(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
expectedErrorMessage string
|
||||
generateData func() *shared.BeaconBlockCapella
|
||||
generateData func() *structs.BeaconBlockCapella
|
||||
}{
|
||||
{
|
||||
name: "nil body",
|
||||
expectedErrorMessage: "block body is nil",
|
||||
generateData: func() *shared.BeaconBlockCapella {
|
||||
generateData: func() *structs.BeaconBlockCapella {
|
||||
beaconBlock := test_helpers.GenerateJsonCapellaBeaconBlock()
|
||||
beaconBlock.Body = nil
|
||||
return beaconBlock
|
||||
@@ -458,7 +458,7 @@ func TestGetBeaconBlockConverter_CapellaError(t *testing.T) {
|
||||
{
|
||||
name: "nil execution payload",
|
||||
expectedErrorMessage: "execution payload is nil",
|
||||
generateData: func() *shared.BeaconBlockCapella {
|
||||
generateData: func() *structs.BeaconBlockCapella {
|
||||
beaconBlock := test_helpers.GenerateJsonCapellaBeaconBlock()
|
||||
beaconBlock.Body.ExecutionPayload = nil
|
||||
return beaconBlock
|
||||
@@ -467,7 +467,7 @@ func TestGetBeaconBlockConverter_CapellaError(t *testing.T) {
|
||||
{
|
||||
name: "bad bellatrix fields",
|
||||
expectedErrorMessage: "failed to get the bellatrix fields of the capella block",
|
||||
generateData: func() *shared.BeaconBlockCapella {
|
||||
generateData: func() *structs.BeaconBlockCapella {
|
||||
beaconBlock := test_helpers.GenerateJsonCapellaBeaconBlock()
|
||||
beaconBlock.Body.Eth1Data = nil
|
||||
return beaconBlock
|
||||
@@ -476,7 +476,7 @@ func TestGetBeaconBlockConverter_CapellaError(t *testing.T) {
|
||||
{
|
||||
name: "bad withdrawals",
|
||||
expectedErrorMessage: "failed to get withdrawals",
|
||||
generateData: func() *shared.BeaconBlockCapella {
|
||||
generateData: func() *structs.BeaconBlockCapella {
|
||||
beaconBlock := test_helpers.GenerateJsonCapellaBeaconBlock()
|
||||
beaconBlock.Body.ExecutionPayload.Withdrawals[0] = nil
|
||||
return beaconBlock
|
||||
@@ -485,7 +485,7 @@ func TestGetBeaconBlockConverter_CapellaError(t *testing.T) {
|
||||
{
|
||||
name: "bad bls execution changes",
|
||||
expectedErrorMessage: "failed to get bls to execution changes",
|
||||
generateData: func() *shared.BeaconBlockCapella {
|
||||
generateData: func() *structs.BeaconBlockCapella {
|
||||
beaconBlock := test_helpers.GenerateJsonCapellaBeaconBlock()
|
||||
beaconBlock.Body.BLSToExecutionChanges[0] = nil
|
||||
return beaconBlock
|
||||
227
api/client/beacon/validator_api/beacon_block_json_helpers.go
Normal file
227
api/client/beacon/validator_api/beacon_block_json_helpers.go
Normal file
@@ -0,0 +1,227 @@
|
||||
package validator_api
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/apiutil"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/server/structs"
|
||||
enginev1 "github.com/prysmaticlabs/prysm/v5/proto/engine/v1"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
)
|
||||
|
||||
func jsonifyTransactions(transactions [][]byte) []string {
|
||||
jsonTransactions := make([]string, len(transactions))
|
||||
for index, transaction := range transactions {
|
||||
jsonTransaction := hexutil.Encode(transaction)
|
||||
jsonTransactions[index] = jsonTransaction
|
||||
}
|
||||
return jsonTransactions
|
||||
}
|
||||
|
||||
func jsonifyBlsToExecutionChanges(blsToExecutionChanges []*ethpb.SignedBLSToExecutionChange) []*structs.SignedBLSToExecutionChange {
|
||||
jsonBlsToExecutionChanges := make([]*structs.SignedBLSToExecutionChange, len(blsToExecutionChanges))
|
||||
for index, signedBlsToExecutionChange := range blsToExecutionChanges {
|
||||
blsToExecutionChangeJson := &structs.BLSToExecutionChange{
|
||||
ValidatorIndex: apiutil.Uint64ToString(signedBlsToExecutionChange.Message.ValidatorIndex),
|
||||
FromBLSPubkey: hexutil.Encode(signedBlsToExecutionChange.Message.FromBlsPubkey),
|
||||
ToExecutionAddress: hexutil.Encode(signedBlsToExecutionChange.Message.ToExecutionAddress),
|
||||
}
|
||||
signedJson := &structs.SignedBLSToExecutionChange{
|
||||
Message: blsToExecutionChangeJson,
|
||||
Signature: hexutil.Encode(signedBlsToExecutionChange.Signature),
|
||||
}
|
||||
jsonBlsToExecutionChanges[index] = signedJson
|
||||
}
|
||||
return jsonBlsToExecutionChanges
|
||||
}
|
||||
|
||||
func jsonifyEth1Data(eth1Data *ethpb.Eth1Data) *structs.Eth1Data {
|
||||
return &structs.Eth1Data{
|
||||
BlockHash: hexutil.Encode(eth1Data.BlockHash),
|
||||
DepositCount: apiutil.Uint64ToString(eth1Data.DepositCount),
|
||||
DepositRoot: hexutil.Encode(eth1Data.DepositRoot),
|
||||
}
|
||||
}
|
||||
|
||||
func jsonifyAttestations(attestations []*ethpb.Attestation) []*structs.Attestation {
|
||||
jsonAttestations := make([]*structs.Attestation, len(attestations))
|
||||
for index, attestation := range attestations {
|
||||
jsonAttestations[index] = jsonifyAttestation(attestation)
|
||||
}
|
||||
return jsonAttestations
|
||||
}
|
||||
|
||||
func jsonifySingleAttestations(attestations []*ethpb.SingleAttestation) []*structs.SingleAttestation {
|
||||
jsonAttestations := make([]*structs.SingleAttestation, len(attestations))
|
||||
for index, attestation := range attestations {
|
||||
jsonAttestations[index] = jsonifySingleAttestation(attestation)
|
||||
}
|
||||
return jsonAttestations
|
||||
}
|
||||
|
||||
func jsonifyAttesterSlashings(attesterSlashings []*ethpb.AttesterSlashing) []*structs.AttesterSlashing {
|
||||
jsonAttesterSlashings := make([]*structs.AttesterSlashing, len(attesterSlashings))
|
||||
for index, attesterSlashing := range attesterSlashings {
|
||||
jsonAttesterSlashing := &structs.AttesterSlashing{
|
||||
Attestation1: jsonifyIndexedAttestation(attesterSlashing.Attestation_1),
|
||||
Attestation2: jsonifyIndexedAttestation(attesterSlashing.Attestation_2),
|
||||
}
|
||||
jsonAttesterSlashings[index] = jsonAttesterSlashing
|
||||
}
|
||||
return jsonAttesterSlashings
|
||||
}
|
||||
|
||||
func jsonifyDeposits(deposits []*ethpb.Deposit) []*structs.Deposit {
|
||||
jsonDeposits := make([]*structs.Deposit, len(deposits))
|
||||
for depositIndex, deposit := range deposits {
|
||||
proofs := make([]string, len(deposit.Proof))
|
||||
for proofIndex, proof := range deposit.Proof {
|
||||
proofs[proofIndex] = hexutil.Encode(proof)
|
||||
}
|
||||
|
||||
jsonDeposit := &structs.Deposit{
|
||||
Data: &structs.DepositData{
|
||||
Amount: apiutil.Uint64ToString(deposit.Data.Amount),
|
||||
Pubkey: hexutil.Encode(deposit.Data.PublicKey),
|
||||
Signature: hexutil.Encode(deposit.Data.Signature),
|
||||
WithdrawalCredentials: hexutil.Encode(deposit.Data.WithdrawalCredentials),
|
||||
},
|
||||
Proof: proofs,
|
||||
}
|
||||
jsonDeposits[depositIndex] = jsonDeposit
|
||||
}
|
||||
return jsonDeposits
|
||||
}
|
||||
|
||||
func jsonifyProposerSlashings(proposerSlashings []*ethpb.ProposerSlashing) []*structs.ProposerSlashing {
|
||||
jsonProposerSlashings := make([]*structs.ProposerSlashing, len(proposerSlashings))
|
||||
for index, proposerSlashing := range proposerSlashings {
|
||||
jsonProposerSlashing := &structs.ProposerSlashing{
|
||||
SignedHeader1: jsonifySignedBeaconBlockHeader(proposerSlashing.Header_1),
|
||||
SignedHeader2: jsonifySignedBeaconBlockHeader(proposerSlashing.Header_2),
|
||||
}
|
||||
jsonProposerSlashings[index] = jsonProposerSlashing
|
||||
}
|
||||
return jsonProposerSlashings
|
||||
}
|
||||
|
||||
// JsonifySignedVoluntaryExits converts an array of voluntary exit structs to a JSON hex string compatible format.
|
||||
func JsonifySignedVoluntaryExits(voluntaryExits []*ethpb.SignedVoluntaryExit) []*structs.SignedVoluntaryExit {
|
||||
jsonSignedVoluntaryExits := make([]*structs.SignedVoluntaryExit, len(voluntaryExits))
|
||||
for index, signedVoluntaryExit := range voluntaryExits {
|
||||
jsonSignedVoluntaryExit := &structs.SignedVoluntaryExit{
|
||||
Message: &structs.VoluntaryExit{
|
||||
Epoch: apiutil.Uint64ToString(signedVoluntaryExit.Exit.Epoch),
|
||||
ValidatorIndex: apiutil.Uint64ToString(signedVoluntaryExit.Exit.ValidatorIndex),
|
||||
},
|
||||
Signature: hexutil.Encode(signedVoluntaryExit.Signature),
|
||||
}
|
||||
jsonSignedVoluntaryExits[index] = jsonSignedVoluntaryExit
|
||||
}
|
||||
return jsonSignedVoluntaryExits
|
||||
}
|
||||
|
||||
func jsonifySignedBeaconBlockHeader(signedBeaconBlockHeader *ethpb.SignedBeaconBlockHeader) *structs.SignedBeaconBlockHeader {
|
||||
return &structs.SignedBeaconBlockHeader{
|
||||
Message: &structs.BeaconBlockHeader{
|
||||
BodyRoot: hexutil.Encode(signedBeaconBlockHeader.Header.BodyRoot),
|
||||
ParentRoot: hexutil.Encode(signedBeaconBlockHeader.Header.ParentRoot),
|
||||
ProposerIndex: apiutil.Uint64ToString(signedBeaconBlockHeader.Header.ProposerIndex),
|
||||
Slot: apiutil.Uint64ToString(signedBeaconBlockHeader.Header.Slot),
|
||||
StateRoot: hexutil.Encode(signedBeaconBlockHeader.Header.StateRoot),
|
||||
},
|
||||
Signature: hexutil.Encode(signedBeaconBlockHeader.Signature),
|
||||
}
|
||||
}
|
||||
|
||||
func jsonifyIndexedAttestation(indexedAttestation *ethpb.IndexedAttestation) *structs.IndexedAttestation {
|
||||
attestingIndices := make([]string, len(indexedAttestation.AttestingIndices))
|
||||
for index, attestingIndex := range indexedAttestation.AttestingIndices {
|
||||
attestingIndex := apiutil.Uint64ToString(attestingIndex)
|
||||
attestingIndices[index] = attestingIndex
|
||||
}
|
||||
|
||||
return &structs.IndexedAttestation{
|
||||
AttestingIndices: attestingIndices,
|
||||
Data: jsonifyAttestationData(indexedAttestation.Data),
|
||||
Signature: hexutil.Encode(indexedAttestation.Signature),
|
||||
}
|
||||
}
|
||||
|
||||
func jsonifyAttestationData(attestationData *ethpb.AttestationData) *structs.AttestationData {
|
||||
return &structs.AttestationData{
|
||||
BeaconBlockRoot: hexutil.Encode(attestationData.BeaconBlockRoot),
|
||||
CommitteeIndex: apiutil.Uint64ToString(attestationData.CommitteeIndex),
|
||||
Slot: apiutil.Uint64ToString(attestationData.Slot),
|
||||
Source: &structs.Checkpoint{
|
||||
Epoch: apiutil.Uint64ToString(attestationData.Source.Epoch),
|
||||
Root: hexutil.Encode(attestationData.Source.Root),
|
||||
},
|
||||
Target: &structs.Checkpoint{
|
||||
Epoch: apiutil.Uint64ToString(attestationData.Target.Epoch),
|
||||
Root: hexutil.Encode(attestationData.Target.Root),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func jsonifyAttestation(attestation *ethpb.Attestation) *structs.Attestation {
|
||||
return &structs.Attestation{
|
||||
AggregationBits: hexutil.Encode(attestation.AggregationBits),
|
||||
Data: jsonifyAttestationData(attestation.Data),
|
||||
Signature: hexutil.Encode(attestation.Signature),
|
||||
}
|
||||
}
|
||||
|
||||
func jsonifyAttestationElectra(attestation *ethpb.AttestationElectra) *structs.AttestationElectra {
|
||||
return &structs.AttestationElectra{
|
||||
AggregationBits: hexutil.Encode(attestation.AggregationBits),
|
||||
Data: jsonifyAttestationData(attestation.Data),
|
||||
Signature: hexutil.Encode(attestation.Signature),
|
||||
CommitteeBits: hexutil.Encode(attestation.CommitteeBits),
|
||||
}
|
||||
}
|
||||
|
||||
func jsonifySingleAttestation(attestation *ethpb.SingleAttestation) *structs.SingleAttestation {
|
||||
return &structs.SingleAttestation{
|
||||
CommitteeIndex: apiutil.Uint64ToString(attestation.CommitteeId),
|
||||
AttesterIndex: apiutil.Uint64ToString(attestation.AttesterIndex),
|
||||
Data: jsonifyAttestationData(attestation.Data),
|
||||
Signature: hexutil.Encode(attestation.Signature),
|
||||
}
|
||||
}
|
||||
|
||||
func jsonifySignedAggregateAndProof(signedAggregateAndProof *ethpb.SignedAggregateAttestationAndProof) *structs.SignedAggregateAttestationAndProof {
|
||||
return &structs.SignedAggregateAttestationAndProof{
|
||||
Message: &structs.AggregateAttestationAndProof{
|
||||
AggregatorIndex: apiutil.Uint64ToString(signedAggregateAndProof.Message.AggregatorIndex),
|
||||
Aggregate: jsonifyAttestation(signedAggregateAndProof.Message.Aggregate),
|
||||
SelectionProof: hexutil.Encode(signedAggregateAndProof.Message.SelectionProof),
|
||||
},
|
||||
Signature: hexutil.Encode(signedAggregateAndProof.Signature),
|
||||
}
|
||||
}
|
||||
|
||||
func jsonifySignedAggregateAndProofElectra(signedAggregateAndProof *ethpb.SignedAggregateAttestationAndProofElectra) *structs.SignedAggregateAttestationAndProofElectra {
|
||||
return &structs.SignedAggregateAttestationAndProofElectra{
|
||||
Message: &structs.AggregateAttestationAndProofElectra{
|
||||
AggregatorIndex: apiutil.Uint64ToString(signedAggregateAndProof.Message.AggregatorIndex),
|
||||
Aggregate: jsonifyAttestationElectra(signedAggregateAndProof.Message.Aggregate),
|
||||
SelectionProof: hexutil.Encode(signedAggregateAndProof.Message.SelectionProof),
|
||||
},
|
||||
Signature: hexutil.Encode(signedAggregateAndProof.Signature),
|
||||
}
|
||||
}
|
||||
|
||||
func jsonifyWithdrawals(withdrawals []*enginev1.Withdrawal) []*structs.Withdrawal {
|
||||
jsonWithdrawals := make([]*structs.Withdrawal, len(withdrawals))
|
||||
for index, withdrawal := range withdrawals {
|
||||
jsonWithdrawals[index] = &structs.Withdrawal{
|
||||
WithdrawalIndex: strconv.FormatUint(withdrawal.Index, 10),
|
||||
ValidatorIndex: strconv.FormatUint(uint64(withdrawal.ValidatorIndex), 10),
|
||||
ExecutionAddress: hexutil.Encode(withdrawal.Address),
|
||||
Amount: strconv.FormatUint(withdrawal.Amount, 10),
|
||||
}
|
||||
}
|
||||
return jsonWithdrawals
|
||||
}
|
||||
@@ -1,13 +1,13 @@
|
||||
package beacon_api
|
||||
package validator_api
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/shared"
|
||||
enginev1 "github.com/prysmaticlabs/prysm/v4/proto/engine/v1"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v4/testing/assert"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/server/structs"
|
||||
enginev1 "github.com/prysmaticlabs/prysm/v5/proto/engine/v1"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v5/testing/assert"
|
||||
)
|
||||
|
||||
func TestBeaconBlockJsonHelpers_JsonifyTransactions(t *testing.T) {
|
||||
@@ -44,9 +44,9 @@ func TestBeaconBlockJsonHelpers_JsonifyBlsToExecutionChanges(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
expectedResult := []*shared.SignedBLSToExecutionChange{
|
||||
expectedResult := []*structs.SignedBLSToExecutionChange{
|
||||
{
|
||||
Message: &shared.BLSToExecutionChange{
|
||||
Message: &structs.BLSToExecutionChange{
|
||||
ValidatorIndex: "1",
|
||||
FromBLSPubkey: hexutil.Encode([]byte{2}),
|
||||
ToExecutionAddress: hexutil.Encode([]byte{3}),
|
||||
@@ -54,7 +54,7 @@ func TestBeaconBlockJsonHelpers_JsonifyBlsToExecutionChanges(t *testing.T) {
|
||||
Signature: hexutil.Encode([]byte{7}),
|
||||
},
|
||||
{
|
||||
Message: &shared.BLSToExecutionChange{
|
||||
Message: &structs.BLSToExecutionChange{
|
||||
ValidatorIndex: "4",
|
||||
FromBLSPubkey: hexutil.Encode([]byte{5}),
|
||||
ToExecutionAddress: hexutil.Encode([]byte{6}),
|
||||
@@ -63,7 +63,7 @@ func TestBeaconBlockJsonHelpers_JsonifyBlsToExecutionChanges(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
assert.DeepEqual(t, expectedResult, shared.SignedBLSChangesFromConsensus(input))
|
||||
assert.DeepEqual(t, expectedResult, structs.SignedBLSChangesFromConsensus(input))
|
||||
}
|
||||
|
||||
func TestBeaconBlockJsonHelpers_JsonifyEth1Data(t *testing.T) {
|
||||
@@ -73,7 +73,7 @@ func TestBeaconBlockJsonHelpers_JsonifyEth1Data(t *testing.T) {
|
||||
BlockHash: []byte{3},
|
||||
}
|
||||
|
||||
expectedResult := &shared.Eth1Data{
|
||||
expectedResult := &structs.Eth1Data{
|
||||
DepositRoot: hexutil.Encode([]byte{1}),
|
||||
DepositCount: "2",
|
||||
BlockHash: hexutil.Encode([]byte{3}),
|
||||
@@ -121,18 +121,18 @@ func TestBeaconBlockJsonHelpers_JsonifyAttestations(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
expectedResult := []*shared.Attestation{
|
||||
expectedResult := []*structs.Attestation{
|
||||
{
|
||||
AggregationBits: hexutil.Encode([]byte{1}),
|
||||
Data: &shared.AttestationData{
|
||||
Data: &structs.AttestationData{
|
||||
Slot: "2",
|
||||
CommitteeIndex: "3",
|
||||
BeaconBlockRoot: hexutil.Encode([]byte{4}),
|
||||
Source: &shared.Checkpoint{
|
||||
Source: &structs.Checkpoint{
|
||||
Epoch: "5",
|
||||
Root: hexutil.Encode([]byte{6}),
|
||||
},
|
||||
Target: &shared.Checkpoint{
|
||||
Target: &structs.Checkpoint{
|
||||
Epoch: "7",
|
||||
Root: hexutil.Encode([]byte{8}),
|
||||
},
|
||||
@@ -141,15 +141,15 @@ func TestBeaconBlockJsonHelpers_JsonifyAttestations(t *testing.T) {
|
||||
},
|
||||
{
|
||||
AggregationBits: hexutil.Encode([]byte{10}),
|
||||
Data: &shared.AttestationData{
|
||||
Data: &structs.AttestationData{
|
||||
Slot: "11",
|
||||
CommitteeIndex: "12",
|
||||
BeaconBlockRoot: hexutil.Encode([]byte{13}),
|
||||
Source: &shared.Checkpoint{
|
||||
Source: &structs.Checkpoint{
|
||||
Epoch: "14",
|
||||
Root: hexutil.Encode([]byte{15}),
|
||||
},
|
||||
Target: &shared.Checkpoint{
|
||||
Target: &structs.Checkpoint{
|
||||
Epoch: "16",
|
||||
Root: hexutil.Encode([]byte{17}),
|
||||
},
|
||||
@@ -238,36 +238,36 @@ func TestBeaconBlockJsonHelpers_JsonifyAttesterSlashings(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
expectedResult := []*shared.AttesterSlashing{
|
||||
expectedResult := []*structs.AttesterSlashing{
|
||||
{
|
||||
Attestation1: &shared.IndexedAttestation{
|
||||
Attestation1: &structs.IndexedAttestation{
|
||||
AttestingIndices: []string{"1", "2"},
|
||||
Data: &shared.AttestationData{
|
||||
Data: &structs.AttestationData{
|
||||
Slot: "3",
|
||||
CommitteeIndex: "4",
|
||||
BeaconBlockRoot: hexutil.Encode([]byte{5}),
|
||||
Source: &shared.Checkpoint{
|
||||
Source: &structs.Checkpoint{
|
||||
Epoch: "6",
|
||||
Root: hexutil.Encode([]byte{7}),
|
||||
},
|
||||
Target: &shared.Checkpoint{
|
||||
Target: &structs.Checkpoint{
|
||||
Epoch: "8",
|
||||
Root: hexutil.Encode([]byte{9}),
|
||||
},
|
||||
},
|
||||
Signature: hexutil.Encode([]byte{10}),
|
||||
},
|
||||
Attestation2: &shared.IndexedAttestation{
|
||||
Attestation2: &structs.IndexedAttestation{
|
||||
AttestingIndices: []string{"11", "12"},
|
||||
Data: &shared.AttestationData{
|
||||
Data: &structs.AttestationData{
|
||||
Slot: "13",
|
||||
CommitteeIndex: "14",
|
||||
BeaconBlockRoot: hexutil.Encode([]byte{15}),
|
||||
Source: &shared.Checkpoint{
|
||||
Source: &structs.Checkpoint{
|
||||
Epoch: "16",
|
||||
Root: hexutil.Encode([]byte{17}),
|
||||
},
|
||||
Target: &shared.Checkpoint{
|
||||
Target: &structs.Checkpoint{
|
||||
Epoch: "18",
|
||||
Root: hexutil.Encode([]byte{19}),
|
||||
},
|
||||
@@ -276,34 +276,34 @@ func TestBeaconBlockJsonHelpers_JsonifyAttesterSlashings(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
Attestation1: &shared.IndexedAttestation{
|
||||
Attestation1: &structs.IndexedAttestation{
|
||||
AttestingIndices: []string{"21", "22"},
|
||||
Data: &shared.AttestationData{
|
||||
Data: &structs.AttestationData{
|
||||
Slot: "23",
|
||||
CommitteeIndex: "24",
|
||||
BeaconBlockRoot: hexutil.Encode([]byte{25}),
|
||||
Source: &shared.Checkpoint{
|
||||
Source: &structs.Checkpoint{
|
||||
Epoch: "26",
|
||||
Root: hexutil.Encode([]byte{27}),
|
||||
},
|
||||
Target: &shared.Checkpoint{
|
||||
Target: &structs.Checkpoint{
|
||||
Epoch: "28",
|
||||
Root: hexutil.Encode([]byte{29}),
|
||||
},
|
||||
},
|
||||
Signature: hexutil.Encode([]byte{30}),
|
||||
},
|
||||
Attestation2: &shared.IndexedAttestation{
|
||||
Attestation2: &structs.IndexedAttestation{
|
||||
AttestingIndices: []string{"31", "32"},
|
||||
Data: &shared.AttestationData{
|
||||
Data: &structs.AttestationData{
|
||||
Slot: "33",
|
||||
CommitteeIndex: "34",
|
||||
BeaconBlockRoot: hexutil.Encode([]byte{35}),
|
||||
Source: &shared.Checkpoint{
|
||||
Source: &structs.Checkpoint{
|
||||
Epoch: "36",
|
||||
Root: hexutil.Encode([]byte{37}),
|
||||
},
|
||||
Target: &shared.Checkpoint{
|
||||
Target: &structs.Checkpoint{
|
||||
Epoch: "38",
|
||||
Root: hexutil.Encode([]byte{39}),
|
||||
},
|
||||
@@ -342,13 +342,13 @@ func TestBeaconBlockJsonHelpers_JsonifyDeposits(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
expectedResult := []*shared.Deposit{
|
||||
expectedResult := []*structs.Deposit{
|
||||
{
|
||||
Proof: []string{
|
||||
hexutil.Encode([]byte{1}),
|
||||
hexutil.Encode([]byte{2}),
|
||||
},
|
||||
Data: &shared.DepositData{
|
||||
Data: &structs.DepositData{
|
||||
Pubkey: hexutil.Encode([]byte{3}),
|
||||
WithdrawalCredentials: hexutil.Encode([]byte{4}),
|
||||
Amount: "5",
|
||||
@@ -360,7 +360,7 @@ func TestBeaconBlockJsonHelpers_JsonifyDeposits(t *testing.T) {
|
||||
hexutil.Encode([]byte{7}),
|
||||
hexutil.Encode([]byte{8}),
|
||||
},
|
||||
Data: &shared.DepositData{
|
||||
Data: &structs.DepositData{
|
||||
Pubkey: hexutil.Encode([]byte{9}),
|
||||
WithdrawalCredentials: hexutil.Encode([]byte{10}),
|
||||
Amount: "11",
|
||||
@@ -421,10 +421,10 @@ func TestBeaconBlockJsonHelpers_JsonifyProposerSlashings(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
expectedResult := []*shared.ProposerSlashing{
|
||||
expectedResult := []*structs.ProposerSlashing{
|
||||
{
|
||||
SignedHeader1: &shared.SignedBeaconBlockHeader{
|
||||
Message: &shared.BeaconBlockHeader{
|
||||
SignedHeader1: &structs.SignedBeaconBlockHeader{
|
||||
Message: &structs.BeaconBlockHeader{
|
||||
Slot: "1",
|
||||
ProposerIndex: "2",
|
||||
ParentRoot: hexutil.Encode([]byte{3}),
|
||||
@@ -433,8 +433,8 @@ func TestBeaconBlockJsonHelpers_JsonifyProposerSlashings(t *testing.T) {
|
||||
},
|
||||
Signature: hexutil.Encode([]byte{6}),
|
||||
},
|
||||
SignedHeader2: &shared.SignedBeaconBlockHeader{
|
||||
Message: &shared.BeaconBlockHeader{
|
||||
SignedHeader2: &structs.SignedBeaconBlockHeader{
|
||||
Message: &structs.BeaconBlockHeader{
|
||||
Slot: "7",
|
||||
ProposerIndex: "8",
|
||||
ParentRoot: hexutil.Encode([]byte{9}),
|
||||
@@ -445,8 +445,8 @@ func TestBeaconBlockJsonHelpers_JsonifyProposerSlashings(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
SignedHeader1: &shared.SignedBeaconBlockHeader{
|
||||
Message: &shared.BeaconBlockHeader{
|
||||
SignedHeader1: &structs.SignedBeaconBlockHeader{
|
||||
Message: &structs.BeaconBlockHeader{
|
||||
Slot: "13",
|
||||
ProposerIndex: "14",
|
||||
ParentRoot: hexutil.Encode([]byte{15}),
|
||||
@@ -455,8 +455,8 @@ func TestBeaconBlockJsonHelpers_JsonifyProposerSlashings(t *testing.T) {
|
||||
},
|
||||
Signature: hexutil.Encode([]byte{18}),
|
||||
},
|
||||
SignedHeader2: &shared.SignedBeaconBlockHeader{
|
||||
Message: &shared.BeaconBlockHeader{
|
||||
SignedHeader2: &structs.SignedBeaconBlockHeader{
|
||||
Message: &structs.BeaconBlockHeader{
|
||||
Slot: "19",
|
||||
ProposerIndex: "20",
|
||||
ParentRoot: hexutil.Encode([]byte{21}),
|
||||
@@ -490,16 +490,16 @@ func TestBeaconBlockJsonHelpers_JsonifySignedVoluntaryExits(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
expectedResult := []*shared.SignedVoluntaryExit{
|
||||
expectedResult := []*structs.SignedVoluntaryExit{
|
||||
{
|
||||
Message: &shared.VoluntaryExit{
|
||||
Message: &structs.VoluntaryExit{
|
||||
Epoch: "1",
|
||||
ValidatorIndex: "2",
|
||||
},
|
||||
Signature: hexutil.Encode([]byte{3}),
|
||||
},
|
||||
{
|
||||
Message: &shared.VoluntaryExit{
|
||||
Message: &structs.VoluntaryExit{
|
||||
Epoch: "4",
|
||||
ValidatorIndex: "5",
|
||||
},
|
||||
@@ -523,8 +523,8 @@ func TestBeaconBlockJsonHelpers_JsonifySignedBeaconBlockHeader(t *testing.T) {
|
||||
Signature: []byte{6},
|
||||
}
|
||||
|
||||
expectedResult := &shared.SignedBeaconBlockHeader{
|
||||
Message: &shared.BeaconBlockHeader{
|
||||
expectedResult := &structs.SignedBeaconBlockHeader{
|
||||
Message: &structs.BeaconBlockHeader{
|
||||
Slot: "1",
|
||||
ProposerIndex: "2",
|
||||
ParentRoot: hexutil.Encode([]byte{3}),
|
||||
@@ -557,17 +557,17 @@ func TestBeaconBlockJsonHelpers_JsonifyIndexedAttestation(t *testing.T) {
|
||||
Signature: []byte{10},
|
||||
}
|
||||
|
||||
expectedResult := &shared.IndexedAttestation{
|
||||
expectedResult := &structs.IndexedAttestation{
|
||||
AttestingIndices: []string{"1", "2"},
|
||||
Data: &shared.AttestationData{
|
||||
Data: &structs.AttestationData{
|
||||
Slot: "3",
|
||||
CommitteeIndex: "4",
|
||||
BeaconBlockRoot: hexutil.Encode([]byte{5}),
|
||||
Source: &shared.Checkpoint{
|
||||
Source: &structs.Checkpoint{
|
||||
Epoch: "6",
|
||||
Root: hexutil.Encode([]byte{7}),
|
||||
},
|
||||
Target: &shared.Checkpoint{
|
||||
Target: &structs.Checkpoint{
|
||||
Epoch: "8",
|
||||
Root: hexutil.Encode([]byte{9}),
|
||||
},
|
||||
@@ -594,15 +594,15 @@ func TestBeaconBlockJsonHelpers_JsonifyAttestationData(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
expectedResult := &shared.AttestationData{
|
||||
expectedResult := &structs.AttestationData{
|
||||
Slot: "1",
|
||||
CommitteeIndex: "2",
|
||||
BeaconBlockRoot: hexutil.Encode([]byte{3}),
|
||||
Source: &shared.Checkpoint{
|
||||
Source: &structs.Checkpoint{
|
||||
Epoch: "4",
|
||||
Root: hexutil.Encode([]byte{5}),
|
||||
},
|
||||
Target: &shared.Checkpoint{
|
||||
Target: &structs.Checkpoint{
|
||||
Epoch: "6",
|
||||
Root: hexutil.Encode([]byte{7}),
|
||||
},
|
||||
@@ -628,7 +628,7 @@ func TestBeaconBlockJsonHelpers_JsonifyWithdrawals(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
expectedResult := []*shared.Withdrawal{
|
||||
expectedResult := []*structs.Withdrawal{
|
||||
{
|
||||
WithdrawalIndex: "1",
|
||||
ValidatorIndex: "2",
|
||||
@@ -1,17 +1,17 @@
|
||||
package beacon_api
|
||||
package validator_api
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/shared"
|
||||
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
|
||||
enginev1 "github.com/prysmaticlabs/prysm/v4/proto/engine/v1"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/server/structs"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
enginev1 "github.com/prysmaticlabs/prysm/v5/proto/engine/v1"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
)
|
||||
|
||||
func convertProposerSlashingsToProto(jsonProposerSlashings []*shared.ProposerSlashing) ([]*ethpb.ProposerSlashing, error) {
|
||||
func convertProposerSlashingsToProto(jsonProposerSlashings []*structs.ProposerSlashing) ([]*ethpb.ProposerSlashing, error) {
|
||||
proposerSlashings := make([]*ethpb.ProposerSlashing, len(jsonProposerSlashings))
|
||||
|
||||
for index, jsonProposerSlashing := range jsonProposerSlashings {
|
||||
@@ -38,7 +38,7 @@ func convertProposerSlashingsToProto(jsonProposerSlashings []*shared.ProposerSla
|
||||
return proposerSlashings, nil
|
||||
}
|
||||
|
||||
func convertProposerSlashingSignedHeaderToProto(signedHeader *shared.SignedBeaconBlockHeader) (*ethpb.SignedBeaconBlockHeader, error) {
|
||||
func convertProposerSlashingSignedHeaderToProto(signedHeader *structs.SignedBeaconBlockHeader) (*ethpb.SignedBeaconBlockHeader, error) {
|
||||
if signedHeader == nil {
|
||||
return nil, errors.New("signed header is nil")
|
||||
}
|
||||
@@ -89,7 +89,7 @@ func convertProposerSlashingSignedHeaderToProto(signedHeader *shared.SignedBeaco
|
||||
}, nil
|
||||
}
|
||||
|
||||
func convertAttesterSlashingsToProto(jsonAttesterSlashings []*shared.AttesterSlashing) ([]*ethpb.AttesterSlashing, error) {
|
||||
func convertAttesterSlashingsToProto(jsonAttesterSlashings []*structs.AttesterSlashing) ([]*ethpb.AttesterSlashing, error) {
|
||||
attesterSlashings := make([]*ethpb.AttesterSlashing, len(jsonAttesterSlashings))
|
||||
|
||||
for index, jsonAttesterSlashing := range jsonAttesterSlashings {
|
||||
@@ -116,7 +116,7 @@ func convertAttesterSlashingsToProto(jsonAttesterSlashings []*shared.AttesterSla
|
||||
return attesterSlashings, nil
|
||||
}
|
||||
|
||||
func convertIndexedAttestationToProto(jsonAttestation *shared.IndexedAttestation) (*ethpb.IndexedAttestation, error) {
|
||||
func convertIndexedAttestationToProto(jsonAttestation *structs.IndexedAttestation) (*ethpb.IndexedAttestation, error) {
|
||||
if jsonAttestation == nil {
|
||||
return nil, errors.New("indexed attestation is nil")
|
||||
}
|
||||
@@ -149,7 +149,7 @@ func convertIndexedAttestationToProto(jsonAttestation *shared.IndexedAttestation
|
||||
}, nil
|
||||
}
|
||||
|
||||
func convertCheckpointToProto(jsonCheckpoint *shared.Checkpoint) (*ethpb.Checkpoint, error) {
|
||||
func convertCheckpointToProto(jsonCheckpoint *structs.Checkpoint) (*ethpb.Checkpoint, error) {
|
||||
if jsonCheckpoint == nil {
|
||||
return nil, errors.New("checkpoint is nil")
|
||||
}
|
||||
@@ -170,7 +170,7 @@ func convertCheckpointToProto(jsonCheckpoint *shared.Checkpoint) (*ethpb.Checkpo
|
||||
}, nil
|
||||
}
|
||||
|
||||
func convertAttestationToProto(jsonAttestation *shared.Attestation) (*ethpb.Attestation, error) {
|
||||
func convertAttestationToProto(jsonAttestation *structs.Attestation) (*ethpb.Attestation, error) {
|
||||
if jsonAttestation == nil {
|
||||
return nil, errors.New("json attestation is nil")
|
||||
}
|
||||
@@ -197,7 +197,40 @@ func convertAttestationToProto(jsonAttestation *shared.Attestation) (*ethpb.Atte
|
||||
}, nil
|
||||
}
|
||||
|
||||
func convertAttestationsToProto(jsonAttestations []*shared.Attestation) ([]*ethpb.Attestation, error) {
|
||||
func convertAttestationElectraToProto(jsonAttestation *structs.AttestationElectra) (*ethpb.AttestationElectra, error) {
|
||||
if jsonAttestation == nil {
|
||||
return nil, errors.New("json attestation is nil")
|
||||
}
|
||||
|
||||
aggregationBits, err := hexutil.Decode(jsonAttestation.AggregationBits)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to decode aggregation bits `%s`", jsonAttestation.AggregationBits)
|
||||
}
|
||||
|
||||
attestationData, err := convertAttestationDataToProto(jsonAttestation.Data)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to get attestation data")
|
||||
}
|
||||
|
||||
signature, err := hexutil.Decode(jsonAttestation.Signature)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to decode attestation signature `%s`", jsonAttestation.Signature)
|
||||
}
|
||||
|
||||
committeeBits, err := hexutil.Decode(jsonAttestation.CommitteeBits)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to decode committee bits `%s`", jsonAttestation.CommitteeBits)
|
||||
}
|
||||
|
||||
return ðpb.AttestationElectra{
|
||||
AggregationBits: aggregationBits,
|
||||
Data: attestationData,
|
||||
Signature: signature,
|
||||
CommitteeBits: committeeBits,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func convertAttestationsToProto(jsonAttestations []*structs.Attestation) ([]*ethpb.Attestation, error) {
|
||||
var attestations []*ethpb.Attestation
|
||||
for index, jsonAttestation := range jsonAttestations {
|
||||
if jsonAttestation == nil {
|
||||
@@ -215,7 +248,7 @@ func convertAttestationsToProto(jsonAttestations []*shared.Attestation) ([]*ethp
|
||||
return attestations, nil
|
||||
}
|
||||
|
||||
func convertAttestationDataToProto(jsonAttestationData *shared.AttestationData) (*ethpb.AttestationData, error) {
|
||||
func convertAttestationDataToProto(jsonAttestationData *structs.AttestationData) (*ethpb.AttestationData, error) {
|
||||
if jsonAttestationData == nil {
|
||||
return nil, errors.New("attestation data is nil")
|
||||
}
|
||||
@@ -254,7 +287,7 @@ func convertAttestationDataToProto(jsonAttestationData *shared.AttestationData)
|
||||
}, nil
|
||||
}
|
||||
|
||||
func convertDepositsToProto(jsonDeposits []*shared.Deposit) ([]*ethpb.Deposit, error) {
|
||||
func convertDepositsToProto(jsonDeposits []*structs.Deposit) ([]*ethpb.Deposit, error) {
|
||||
deposits := make([]*ethpb.Deposit, len(jsonDeposits))
|
||||
|
||||
for depositIndex, jsonDeposit := range jsonDeposits {
|
||||
@@ -310,7 +343,7 @@ func convertDepositsToProto(jsonDeposits []*shared.Deposit) ([]*ethpb.Deposit, e
|
||||
return deposits, nil
|
||||
}
|
||||
|
||||
func convertVoluntaryExitsToProto(jsonVoluntaryExits []*shared.SignedVoluntaryExit) ([]*ethpb.SignedVoluntaryExit, error) {
|
||||
func convertVoluntaryExitsToProto(jsonVoluntaryExits []*structs.SignedVoluntaryExit) ([]*ethpb.SignedVoluntaryExit, error) {
|
||||
attestingIndices := make([]*ethpb.SignedVoluntaryExit, len(jsonVoluntaryExits))
|
||||
|
||||
for index, jsonVoluntaryExit := range jsonVoluntaryExits {
|
||||
@@ -364,7 +397,7 @@ func convertTransactionsToProto(jsonTransactions []string) ([][]byte, error) {
|
||||
return transactions, nil
|
||||
}
|
||||
|
||||
func convertWithdrawalsToProto(jsonWithdrawals []*shared.Withdrawal) ([]*enginev1.Withdrawal, error) {
|
||||
func convertWithdrawalsToProto(jsonWithdrawals []*structs.Withdrawal) ([]*enginev1.Withdrawal, error) {
|
||||
withdrawals := make([]*enginev1.Withdrawal, len(jsonWithdrawals))
|
||||
|
||||
for index, jsonWithdrawal := range jsonWithdrawals {
|
||||
@@ -403,7 +436,7 @@ func convertWithdrawalsToProto(jsonWithdrawals []*shared.Withdrawal) ([]*enginev
|
||||
return withdrawals, nil
|
||||
}
|
||||
|
||||
func convertBlsToExecutionChangesToProto(jsonSignedBlsToExecutionChanges []*shared.SignedBLSToExecutionChange) ([]*ethpb.SignedBLSToExecutionChange, error) {
|
||||
func convertBlsToExecutionChangesToProto(jsonSignedBlsToExecutionChanges []*structs.SignedBLSToExecutionChange) ([]*ethpb.SignedBLSToExecutionChange, error) {
|
||||
signedBlsToExecutionChanges := make([]*ethpb.SignedBLSToExecutionChange, len(jsonSignedBlsToExecutionChanges))
|
||||
|
||||
for index, jsonBlsToExecutionChange := range jsonSignedBlsToExecutionChanges {
|
||||
@@ -1,28 +1,28 @@
|
||||
package beacon_api
|
||||
package validator_api
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/shared"
|
||||
enginev1 "github.com/prysmaticlabs/prysm/v4/proto/engine/v1"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v4/testing/assert"
|
||||
"github.com/prysmaticlabs/prysm/v4/testing/require"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/server/structs"
|
||||
enginev1 "github.com/prysmaticlabs/prysm/v5/proto/engine/v1"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v5/testing/assert"
|
||||
"github.com/prysmaticlabs/prysm/v5/testing/require"
|
||||
)
|
||||
|
||||
func TestBeaconBlockProtoHelpers_ConvertProposerSlashingsToProto(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
generateInput func() []*shared.ProposerSlashing
|
||||
generateInput func() []*structs.ProposerSlashing
|
||||
expectedResult []*ethpb.ProposerSlashing
|
||||
expectedErrorMessage string
|
||||
}{
|
||||
{
|
||||
name: "nil proposer slashing",
|
||||
expectedErrorMessage: "proposer slashing at index `0` is nil",
|
||||
generateInput: func() []*shared.ProposerSlashing {
|
||||
return []*shared.ProposerSlashing{
|
||||
generateInput: func() []*structs.ProposerSlashing {
|
||||
return []*structs.ProposerSlashing{
|
||||
nil,
|
||||
}
|
||||
},
|
||||
@@ -30,7 +30,7 @@ func TestBeaconBlockProtoHelpers_ConvertProposerSlashingsToProto(t *testing.T) {
|
||||
{
|
||||
name: "bad header 1",
|
||||
expectedErrorMessage: "failed to get proposer header 1",
|
||||
generateInput: func() []*shared.ProposerSlashing {
|
||||
generateInput: func() []*structs.ProposerSlashing {
|
||||
input := generateProposerSlashings()
|
||||
input[0].SignedHeader1 = nil
|
||||
return input
|
||||
@@ -39,7 +39,7 @@ func TestBeaconBlockProtoHelpers_ConvertProposerSlashingsToProto(t *testing.T) {
|
||||
{
|
||||
name: "bad header 2",
|
||||
expectedErrorMessage: "failed to get proposer header 2",
|
||||
generateInput: func() []*shared.ProposerSlashing {
|
||||
generateInput: func() []*structs.ProposerSlashing {
|
||||
input := generateProposerSlashings()
|
||||
input[0].SignedHeader2 = nil
|
||||
return input
|
||||
@@ -114,19 +114,19 @@ func TestBeaconBlockProtoHelpers_ConvertProposerSlashingsToProto(t *testing.T) {
|
||||
func TestBeaconBlockProtoHelpers_ConvertProposerSlashingSignedHeaderToProto(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
generateInput func() *shared.SignedBeaconBlockHeader
|
||||
generateInput func() *structs.SignedBeaconBlockHeader
|
||||
expectedResult *ethpb.SignedBeaconBlockHeader
|
||||
expectedErrorMessage string
|
||||
}{
|
||||
{
|
||||
name: "nil signed header",
|
||||
expectedErrorMessage: "signed header is nil",
|
||||
generateInput: func() *shared.SignedBeaconBlockHeader { return nil },
|
||||
generateInput: func() *structs.SignedBeaconBlockHeader { return nil },
|
||||
},
|
||||
{
|
||||
name: "nil header",
|
||||
expectedErrorMessage: "header is nil",
|
||||
generateInput: func() *shared.SignedBeaconBlockHeader {
|
||||
generateInput: func() *structs.SignedBeaconBlockHeader {
|
||||
input := generateSignedBeaconBlockHeader()
|
||||
input.Message = nil
|
||||
return input
|
||||
@@ -135,7 +135,7 @@ func TestBeaconBlockProtoHelpers_ConvertProposerSlashingSignedHeaderToProto(t *t
|
||||
{
|
||||
name: "bad slot",
|
||||
expectedErrorMessage: "failed to parse header slot `foo`",
|
||||
generateInput: func() *shared.SignedBeaconBlockHeader {
|
||||
generateInput: func() *structs.SignedBeaconBlockHeader {
|
||||
input := generateSignedBeaconBlockHeader()
|
||||
input.Message.Slot = "foo"
|
||||
return input
|
||||
@@ -144,7 +144,7 @@ func TestBeaconBlockProtoHelpers_ConvertProposerSlashingSignedHeaderToProto(t *t
|
||||
{
|
||||
name: "bad proposer index",
|
||||
expectedErrorMessage: "failed to parse header proposer index `bar`",
|
||||
generateInput: func() *shared.SignedBeaconBlockHeader {
|
||||
generateInput: func() *structs.SignedBeaconBlockHeader {
|
||||
input := generateSignedBeaconBlockHeader()
|
||||
input.Message.ProposerIndex = "bar"
|
||||
return input
|
||||
@@ -153,7 +153,7 @@ func TestBeaconBlockProtoHelpers_ConvertProposerSlashingSignedHeaderToProto(t *t
|
||||
{
|
||||
name: "bad parent root",
|
||||
expectedErrorMessage: "failed to decode header parent root `foo`",
|
||||
generateInput: func() *shared.SignedBeaconBlockHeader {
|
||||
generateInput: func() *structs.SignedBeaconBlockHeader {
|
||||
input := generateSignedBeaconBlockHeader()
|
||||
input.Message.ParentRoot = "foo"
|
||||
return input
|
||||
@@ -162,7 +162,7 @@ func TestBeaconBlockProtoHelpers_ConvertProposerSlashingSignedHeaderToProto(t *t
|
||||
{
|
||||
name: "bad state root",
|
||||
expectedErrorMessage: "failed to decode header state root `bar`",
|
||||
generateInput: func() *shared.SignedBeaconBlockHeader {
|
||||
generateInput: func() *structs.SignedBeaconBlockHeader {
|
||||
input := generateSignedBeaconBlockHeader()
|
||||
input.Message.StateRoot = "bar"
|
||||
return input
|
||||
@@ -171,7 +171,7 @@ func TestBeaconBlockProtoHelpers_ConvertProposerSlashingSignedHeaderToProto(t *t
|
||||
{
|
||||
name: "bad body root",
|
||||
expectedErrorMessage: "failed to decode header body root `foo`",
|
||||
generateInput: func() *shared.SignedBeaconBlockHeader {
|
||||
generateInput: func() *structs.SignedBeaconBlockHeader {
|
||||
input := generateSignedBeaconBlockHeader()
|
||||
input.Message.BodyRoot = "foo"
|
||||
return input
|
||||
@@ -180,7 +180,7 @@ func TestBeaconBlockProtoHelpers_ConvertProposerSlashingSignedHeaderToProto(t *t
|
||||
{
|
||||
name: "bad parent root",
|
||||
expectedErrorMessage: "failed to decode signature `bar`",
|
||||
generateInput: func() *shared.SignedBeaconBlockHeader {
|
||||
generateInput: func() *structs.SignedBeaconBlockHeader {
|
||||
input := generateSignedBeaconBlockHeader()
|
||||
input.Signature = "bar"
|
||||
return input
|
||||
@@ -219,15 +219,15 @@ func TestBeaconBlockProtoHelpers_ConvertProposerSlashingSignedHeaderToProto(t *t
|
||||
func TestBeaconBlockProtoHelpers_ConvertAttesterSlashingsToProto(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
generateInput func() []*shared.AttesterSlashing
|
||||
generateInput func() []*structs.AttesterSlashing
|
||||
expectedResult []*ethpb.AttesterSlashing
|
||||
expectedErrorMessage string
|
||||
}{
|
||||
{
|
||||
name: "nil attester slashing",
|
||||
expectedErrorMessage: "attester slashing at index `0` is nil",
|
||||
generateInput: func() []*shared.AttesterSlashing {
|
||||
return []*shared.AttesterSlashing{
|
||||
generateInput: func() []*structs.AttesterSlashing {
|
||||
return []*structs.AttesterSlashing{
|
||||
nil,
|
||||
}
|
||||
},
|
||||
@@ -235,8 +235,8 @@ func TestBeaconBlockProtoHelpers_ConvertAttesterSlashingsToProto(t *testing.T) {
|
||||
{
|
||||
name: "bad attestation 1",
|
||||
expectedErrorMessage: "failed to get attestation 1",
|
||||
generateInput: func() []*shared.AttesterSlashing {
|
||||
return []*shared.AttesterSlashing{
|
||||
generateInput: func() []*structs.AttesterSlashing {
|
||||
return []*structs.AttesterSlashing{
|
||||
{
|
||||
Attestation1: nil,
|
||||
Attestation2: nil,
|
||||
@@ -247,7 +247,7 @@ func TestBeaconBlockProtoHelpers_ConvertAttesterSlashingsToProto(t *testing.T) {
|
||||
{
|
||||
name: "bad attestation 2",
|
||||
expectedErrorMessage: "failed to get attestation 2",
|
||||
generateInput: func() []*shared.AttesterSlashing {
|
||||
generateInput: func() []*structs.AttesterSlashing {
|
||||
input := generateAttesterSlashings()
|
||||
input[0].Attestation2 = nil
|
||||
return input
|
||||
@@ -350,19 +350,19 @@ func TestBeaconBlockProtoHelpers_ConvertAttesterSlashingsToProto(t *testing.T) {
|
||||
func TestBeaconBlockProtoHelpers_ConvertAttestationToProto(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
generateInput func() *shared.IndexedAttestation
|
||||
generateInput func() *structs.IndexedAttestation
|
||||
expectedResult *ethpb.IndexedAttestation
|
||||
expectedErrorMessage string
|
||||
}{
|
||||
{
|
||||
name: "nil indexed attestation",
|
||||
expectedErrorMessage: "indexed attestation is nil",
|
||||
generateInput: func() *shared.IndexedAttestation { return nil },
|
||||
generateInput: func() *structs.IndexedAttestation { return nil },
|
||||
},
|
||||
{
|
||||
name: "bad attesting index",
|
||||
expectedErrorMessage: "failed to parse attesting index `foo`",
|
||||
generateInput: func() *shared.IndexedAttestation {
|
||||
generateInput: func() *structs.IndexedAttestation {
|
||||
input := generateIndexedAttestation()
|
||||
input.AttestingIndices[0] = "foo"
|
||||
return input
|
||||
@@ -371,7 +371,7 @@ func TestBeaconBlockProtoHelpers_ConvertAttestationToProto(t *testing.T) {
|
||||
{
|
||||
name: "bad signature",
|
||||
expectedErrorMessage: "failed to decode attestation signature `bar`",
|
||||
generateInput: func() *shared.IndexedAttestation {
|
||||
generateInput: func() *structs.IndexedAttestation {
|
||||
input := generateIndexedAttestation()
|
||||
input.Signature = "bar"
|
||||
return input
|
||||
@@ -380,7 +380,7 @@ func TestBeaconBlockProtoHelpers_ConvertAttestationToProto(t *testing.T) {
|
||||
{
|
||||
name: "bad data",
|
||||
expectedErrorMessage: "failed to get attestation data",
|
||||
generateInput: func() *shared.IndexedAttestation {
|
||||
generateInput: func() *structs.IndexedAttestation {
|
||||
input := generateIndexedAttestation()
|
||||
input.Data = nil
|
||||
return input
|
||||
@@ -426,19 +426,19 @@ func TestBeaconBlockProtoHelpers_ConvertAttestationToProto(t *testing.T) {
|
||||
func TestBeaconBlockProtoHelpers_ConvertCheckpointToProto(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
generateInput func() *shared.Checkpoint
|
||||
generateInput func() *structs.Checkpoint
|
||||
expectedResult *ethpb.Checkpoint
|
||||
expectedErrorMessage string
|
||||
}{
|
||||
{
|
||||
name: "nil checkpoint",
|
||||
expectedErrorMessage: "checkpoint is nil",
|
||||
generateInput: func() *shared.Checkpoint { return nil },
|
||||
generateInput: func() *structs.Checkpoint { return nil },
|
||||
},
|
||||
{
|
||||
name: "bad epoch",
|
||||
expectedErrorMessage: "failed to parse checkpoint epoch `foo`",
|
||||
generateInput: func() *shared.Checkpoint {
|
||||
generateInput: func() *structs.Checkpoint {
|
||||
input := generateCheckpoint()
|
||||
input.Epoch = "foo"
|
||||
return input
|
||||
@@ -447,7 +447,7 @@ func TestBeaconBlockProtoHelpers_ConvertCheckpointToProto(t *testing.T) {
|
||||
{
|
||||
name: "bad root",
|
||||
expectedErrorMessage: "failed to decode checkpoint root `bar`",
|
||||
generateInput: func() *shared.Checkpoint {
|
||||
generateInput: func() *structs.Checkpoint {
|
||||
input := generateCheckpoint()
|
||||
input.Root = "bar"
|
||||
return input
|
||||
@@ -480,15 +480,15 @@ func TestBeaconBlockProtoHelpers_ConvertCheckpointToProto(t *testing.T) {
|
||||
func TestBeaconBlockProtoHelpers_ConvertAttestationsToProto(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
generateInput func() []*shared.Attestation
|
||||
generateInput func() []*structs.Attestation
|
||||
expectedResult []*ethpb.Attestation
|
||||
expectedErrorMessage string
|
||||
}{
|
||||
{
|
||||
name: "nil attestation",
|
||||
expectedErrorMessage: "attestation at index `0` is nil",
|
||||
generateInput: func() []*shared.Attestation {
|
||||
return []*shared.Attestation{
|
||||
generateInput: func() []*structs.Attestation {
|
||||
return []*structs.Attestation{
|
||||
nil,
|
||||
}
|
||||
},
|
||||
@@ -496,7 +496,7 @@ func TestBeaconBlockProtoHelpers_ConvertAttestationsToProto(t *testing.T) {
|
||||
{
|
||||
name: "bad aggregation bits",
|
||||
expectedErrorMessage: "failed to decode aggregation bits `foo`",
|
||||
generateInput: func() []*shared.Attestation {
|
||||
generateInput: func() []*structs.Attestation {
|
||||
input := generateAttestations()
|
||||
input[0].AggregationBits = "foo"
|
||||
return input
|
||||
@@ -505,7 +505,7 @@ func TestBeaconBlockProtoHelpers_ConvertAttestationsToProto(t *testing.T) {
|
||||
{
|
||||
name: "bad data",
|
||||
expectedErrorMessage: "failed to get attestation data",
|
||||
generateInput: func() []*shared.Attestation {
|
||||
generateInput: func() []*structs.Attestation {
|
||||
input := generateAttestations()
|
||||
input[0].Data = nil
|
||||
return input
|
||||
@@ -514,7 +514,7 @@ func TestBeaconBlockProtoHelpers_ConvertAttestationsToProto(t *testing.T) {
|
||||
{
|
||||
name: "bad signature",
|
||||
expectedErrorMessage: "failed to decode attestation signature `bar`",
|
||||
generateInput: func() []*shared.Attestation {
|
||||
generateInput: func() []*structs.Attestation {
|
||||
input := generateAttestations()
|
||||
input[0].Signature = "bar"
|
||||
return input
|
||||
@@ -579,19 +579,19 @@ func TestBeaconBlockProtoHelpers_ConvertAttestationsToProto(t *testing.T) {
|
||||
func TestBeaconBlockProtoHelpers_ConvertAttestationDataToProto(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
generateInput func() *shared.AttestationData
|
||||
generateInput func() *structs.AttestationData
|
||||
expectedResult *ethpb.AttestationData
|
||||
expectedErrorMessage string
|
||||
}{
|
||||
{
|
||||
name: "nil attestation data",
|
||||
expectedErrorMessage: "attestation data is nil",
|
||||
generateInput: func() *shared.AttestationData { return nil },
|
||||
generateInput: func() *structs.AttestationData { return nil },
|
||||
},
|
||||
{
|
||||
name: "bad slot",
|
||||
expectedErrorMessage: "failed to parse attestation slot `foo`",
|
||||
generateInput: func() *shared.AttestationData {
|
||||
generateInput: func() *structs.AttestationData {
|
||||
input := generateAttestationData()
|
||||
input.Slot = "foo"
|
||||
return input
|
||||
@@ -600,7 +600,7 @@ func TestBeaconBlockProtoHelpers_ConvertAttestationDataToProto(t *testing.T) {
|
||||
{
|
||||
name: "bad committee index",
|
||||
expectedErrorMessage: "failed to parse attestation committee index `bar`",
|
||||
generateInput: func() *shared.AttestationData {
|
||||
generateInput: func() *structs.AttestationData {
|
||||
input := generateAttestationData()
|
||||
input.CommitteeIndex = "bar"
|
||||
return input
|
||||
@@ -609,7 +609,7 @@ func TestBeaconBlockProtoHelpers_ConvertAttestationDataToProto(t *testing.T) {
|
||||
{
|
||||
name: "bad beacon block root",
|
||||
expectedErrorMessage: "failed to decode attestation beacon block root `foo`",
|
||||
generateInput: func() *shared.AttestationData {
|
||||
generateInput: func() *structs.AttestationData {
|
||||
input := generateAttestationData()
|
||||
input.BeaconBlockRoot = "foo"
|
||||
return input
|
||||
@@ -618,7 +618,7 @@ func TestBeaconBlockProtoHelpers_ConvertAttestationDataToProto(t *testing.T) {
|
||||
{
|
||||
name: "bad source checkpoint",
|
||||
expectedErrorMessage: "failed to get attestation source checkpoint",
|
||||
generateInput: func() *shared.AttestationData {
|
||||
generateInput: func() *structs.AttestationData {
|
||||
input := generateAttestationData()
|
||||
input.Source = nil
|
||||
return input
|
||||
@@ -627,7 +627,7 @@ func TestBeaconBlockProtoHelpers_ConvertAttestationDataToProto(t *testing.T) {
|
||||
{
|
||||
name: "bad target checkpoint",
|
||||
expectedErrorMessage: "failed to get attestation target checkpoint",
|
||||
generateInput: func() *shared.AttestationData {
|
||||
generateInput: func() *structs.AttestationData {
|
||||
input := generateAttestationData()
|
||||
input.Target = nil
|
||||
return input
|
||||
@@ -669,15 +669,15 @@ func TestBeaconBlockProtoHelpers_ConvertAttestationDataToProto(t *testing.T) {
|
||||
func TestBeaconBlockProtoHelpers_ConvertDepositsToProto(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
generateInput func() []*shared.Deposit
|
||||
generateInput func() []*structs.Deposit
|
||||
expectedResult []*ethpb.Deposit
|
||||
expectedErrorMessage string
|
||||
}{
|
||||
{
|
||||
name: "nil deposit",
|
||||
expectedErrorMessage: "deposit at index `0` is nil",
|
||||
generateInput: func() []*shared.Deposit {
|
||||
return []*shared.Deposit{
|
||||
generateInput: func() []*structs.Deposit {
|
||||
return []*structs.Deposit{
|
||||
nil,
|
||||
}
|
||||
},
|
||||
@@ -685,7 +685,7 @@ func TestBeaconBlockProtoHelpers_ConvertDepositsToProto(t *testing.T) {
|
||||
{
|
||||
name: "bad proof",
|
||||
expectedErrorMessage: "failed to decode deposit proof `foo`",
|
||||
generateInput: func() []*shared.Deposit {
|
||||
generateInput: func() []*structs.Deposit {
|
||||
input := generateDeposits()
|
||||
input[0].Proof[0] = "foo"
|
||||
return input
|
||||
@@ -694,7 +694,7 @@ func TestBeaconBlockProtoHelpers_ConvertDepositsToProto(t *testing.T) {
|
||||
{
|
||||
name: "nil data",
|
||||
expectedErrorMessage: "deposit data at index `0` is nil",
|
||||
generateInput: func() []*shared.Deposit {
|
||||
generateInput: func() []*structs.Deposit {
|
||||
input := generateDeposits()
|
||||
input[0].Data = nil
|
||||
return input
|
||||
@@ -703,7 +703,7 @@ func TestBeaconBlockProtoHelpers_ConvertDepositsToProto(t *testing.T) {
|
||||
{
|
||||
name: "bad public key",
|
||||
expectedErrorMessage: "failed to decode deposit public key `bar`",
|
||||
generateInput: func() []*shared.Deposit {
|
||||
generateInput: func() []*structs.Deposit {
|
||||
input := generateDeposits()
|
||||
input[0].Data.Pubkey = "bar"
|
||||
return input
|
||||
@@ -712,7 +712,7 @@ func TestBeaconBlockProtoHelpers_ConvertDepositsToProto(t *testing.T) {
|
||||
{
|
||||
name: "bad withdrawal credentials",
|
||||
expectedErrorMessage: "failed to decode deposit withdrawal credentials `foo`",
|
||||
generateInput: func() []*shared.Deposit {
|
||||
generateInput: func() []*structs.Deposit {
|
||||
input := generateDeposits()
|
||||
input[0].Data.WithdrawalCredentials = "foo"
|
||||
return input
|
||||
@@ -721,7 +721,7 @@ func TestBeaconBlockProtoHelpers_ConvertDepositsToProto(t *testing.T) {
|
||||
{
|
||||
name: "bad amount",
|
||||
expectedErrorMessage: "failed to parse deposit amount `bar`",
|
||||
generateInput: func() []*shared.Deposit {
|
||||
generateInput: func() []*structs.Deposit {
|
||||
input := generateDeposits()
|
||||
input[0].Data.Amount = "bar"
|
||||
return input
|
||||
@@ -730,7 +730,7 @@ func TestBeaconBlockProtoHelpers_ConvertDepositsToProto(t *testing.T) {
|
||||
{
|
||||
name: "bad signature",
|
||||
expectedErrorMessage: "failed to decode signature `foo`",
|
||||
generateInput: func() []*shared.Deposit {
|
||||
generateInput: func() []*structs.Deposit {
|
||||
input := generateDeposits()
|
||||
input[0].Data.Signature = "foo"
|
||||
return input
|
||||
@@ -785,15 +785,15 @@ func TestBeaconBlockProtoHelpers_ConvertDepositsToProto(t *testing.T) {
|
||||
func TestBeaconBlockProtoHelpers_ConvertVoluntaryExitsToProto(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
generateInput func() []*shared.SignedVoluntaryExit
|
||||
generateInput func() []*structs.SignedVoluntaryExit
|
||||
expectedResult []*ethpb.SignedVoluntaryExit
|
||||
expectedErrorMessage string
|
||||
}{
|
||||
{
|
||||
name: "nil voluntary exit",
|
||||
expectedErrorMessage: "signed voluntary exit at index `0` is nil",
|
||||
generateInput: func() []*shared.SignedVoluntaryExit {
|
||||
return []*shared.SignedVoluntaryExit{
|
||||
generateInput: func() []*structs.SignedVoluntaryExit {
|
||||
return []*structs.SignedVoluntaryExit{
|
||||
nil,
|
||||
}
|
||||
},
|
||||
@@ -801,7 +801,7 @@ func TestBeaconBlockProtoHelpers_ConvertVoluntaryExitsToProto(t *testing.T) {
|
||||
{
|
||||
name: "nil data",
|
||||
expectedErrorMessage: "voluntary exit at index `0` is nil",
|
||||
generateInput: func() []*shared.SignedVoluntaryExit {
|
||||
generateInput: func() []*structs.SignedVoluntaryExit {
|
||||
input := generateSignedVoluntaryExits()
|
||||
input[0].Message = nil
|
||||
return input
|
||||
@@ -810,7 +810,7 @@ func TestBeaconBlockProtoHelpers_ConvertVoluntaryExitsToProto(t *testing.T) {
|
||||
{
|
||||
name: "bad epoch",
|
||||
expectedErrorMessage: "failed to parse voluntary exit epoch `foo`",
|
||||
generateInput: func() []*shared.SignedVoluntaryExit {
|
||||
generateInput: func() []*structs.SignedVoluntaryExit {
|
||||
input := generateSignedVoluntaryExits()
|
||||
input[0].Message.Epoch = "foo"
|
||||
return input
|
||||
@@ -819,7 +819,7 @@ func TestBeaconBlockProtoHelpers_ConvertVoluntaryExitsToProto(t *testing.T) {
|
||||
{
|
||||
name: "bad validator index",
|
||||
expectedErrorMessage: "failed to parse voluntary exit validator index `bar`",
|
||||
generateInput: func() []*shared.SignedVoluntaryExit {
|
||||
generateInput: func() []*structs.SignedVoluntaryExit {
|
||||
input := generateSignedVoluntaryExits()
|
||||
input[0].Message.ValidatorIndex = "bar"
|
||||
return input
|
||||
@@ -828,7 +828,7 @@ func TestBeaconBlockProtoHelpers_ConvertVoluntaryExitsToProto(t *testing.T) {
|
||||
{
|
||||
name: "bad signature",
|
||||
expectedErrorMessage: "failed to decode signature `foo`",
|
||||
generateInput: func() []*shared.SignedVoluntaryExit {
|
||||
generateInput: func() []*structs.SignedVoluntaryExit {
|
||||
input := generateSignedVoluntaryExits()
|
||||
input[0].Signature = "foo"
|
||||
return input
|
||||
@@ -918,14 +918,14 @@ func TestBeaconBlockProtoHelpers_ConvertTransactionsToProto(t *testing.T) {
|
||||
func TestBeaconBlockProtoHelpers_ConvertWithdrawalsToProto(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
generateInput func() []*shared.Withdrawal
|
||||
generateInput func() []*structs.Withdrawal
|
||||
expectedResult []*enginev1.Withdrawal
|
||||
expectedErrorMessage string
|
||||
}{
|
||||
{
|
||||
name: "nil withdrawal",
|
||||
expectedErrorMessage: "withdrawal at index `0` is nil",
|
||||
generateInput: func() []*shared.Withdrawal {
|
||||
generateInput: func() []*structs.Withdrawal {
|
||||
input := generateWithdrawals()
|
||||
input[0] = nil
|
||||
return input
|
||||
@@ -934,7 +934,7 @@ func TestBeaconBlockProtoHelpers_ConvertWithdrawalsToProto(t *testing.T) {
|
||||
{
|
||||
name: "bad withdrawal index",
|
||||
expectedErrorMessage: "failed to parse withdrawal index `foo`",
|
||||
generateInput: func() []*shared.Withdrawal {
|
||||
generateInput: func() []*structs.Withdrawal {
|
||||
input := generateWithdrawals()
|
||||
input[0].WithdrawalIndex = "foo"
|
||||
return input
|
||||
@@ -943,7 +943,7 @@ func TestBeaconBlockProtoHelpers_ConvertWithdrawalsToProto(t *testing.T) {
|
||||
{
|
||||
name: "bad validator index",
|
||||
expectedErrorMessage: "failed to parse validator index `bar`",
|
||||
generateInput: func() []*shared.Withdrawal {
|
||||
generateInput: func() []*structs.Withdrawal {
|
||||
input := generateWithdrawals()
|
||||
input[0].ValidatorIndex = "bar"
|
||||
return input
|
||||
@@ -952,7 +952,7 @@ func TestBeaconBlockProtoHelpers_ConvertWithdrawalsToProto(t *testing.T) {
|
||||
{
|
||||
name: "bad execution address",
|
||||
expectedErrorMessage: "failed to decode execution address `foo`",
|
||||
generateInput: func() []*shared.Withdrawal {
|
||||
generateInput: func() []*structs.Withdrawal {
|
||||
input := generateWithdrawals()
|
||||
input[0].ExecutionAddress = "foo"
|
||||
return input
|
||||
@@ -961,7 +961,7 @@ func TestBeaconBlockProtoHelpers_ConvertWithdrawalsToProto(t *testing.T) {
|
||||
{
|
||||
name: "bad amount",
|
||||
expectedErrorMessage: "failed to parse withdrawal amount `bar`",
|
||||
generateInput: func() []*shared.Withdrawal {
|
||||
generateInput: func() []*structs.Withdrawal {
|
||||
input := generateWithdrawals()
|
||||
input[0].Amount = "bar"
|
||||
return input
|
||||
@@ -1004,14 +1004,14 @@ func TestBeaconBlockProtoHelpers_ConvertWithdrawalsToProto(t *testing.T) {
|
||||
func TestBeaconBlockProtoHelpers_ConvertBlsToExecutionChangesToProto(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
generateInput func() []*shared.SignedBLSToExecutionChange
|
||||
generateInput func() []*structs.SignedBLSToExecutionChange
|
||||
expectedResult []*ethpb.SignedBLSToExecutionChange
|
||||
expectedErrorMessage string
|
||||
}{
|
||||
{
|
||||
name: "nil bls to execution change",
|
||||
expectedErrorMessage: "bls to execution change at index `0` is nil",
|
||||
generateInput: func() []*shared.SignedBLSToExecutionChange {
|
||||
generateInput: func() []*structs.SignedBLSToExecutionChange {
|
||||
input := generateBlsToExecutionChanges()
|
||||
input[0] = nil
|
||||
return input
|
||||
@@ -1020,7 +1020,7 @@ func TestBeaconBlockProtoHelpers_ConvertBlsToExecutionChangesToProto(t *testing.
|
||||
{
|
||||
name: "nil bls to execution change message",
|
||||
expectedErrorMessage: "bls to execution change message at index `0` is nil",
|
||||
generateInput: func() []*shared.SignedBLSToExecutionChange {
|
||||
generateInput: func() []*structs.SignedBLSToExecutionChange {
|
||||
input := generateBlsToExecutionChanges()
|
||||
input[0].Message = nil
|
||||
return input
|
||||
@@ -1029,7 +1029,7 @@ func TestBeaconBlockProtoHelpers_ConvertBlsToExecutionChangesToProto(t *testing.
|
||||
{
|
||||
name: "bad validator index",
|
||||
expectedErrorMessage: "failed to decode validator index `foo`",
|
||||
generateInput: func() []*shared.SignedBLSToExecutionChange {
|
||||
generateInput: func() []*structs.SignedBLSToExecutionChange {
|
||||
input := generateBlsToExecutionChanges()
|
||||
input[0].Message.ValidatorIndex = "foo"
|
||||
return input
|
||||
@@ -1038,7 +1038,7 @@ func TestBeaconBlockProtoHelpers_ConvertBlsToExecutionChangesToProto(t *testing.
|
||||
{
|
||||
name: "bad from bls pubkey",
|
||||
expectedErrorMessage: "failed to decode bls pubkey `bar`",
|
||||
generateInput: func() []*shared.SignedBLSToExecutionChange {
|
||||
generateInput: func() []*structs.SignedBLSToExecutionChange {
|
||||
input := generateBlsToExecutionChanges()
|
||||
input[0].Message.FromBLSPubkey = "bar"
|
||||
return input
|
||||
@@ -1047,7 +1047,7 @@ func TestBeaconBlockProtoHelpers_ConvertBlsToExecutionChangesToProto(t *testing.
|
||||
{
|
||||
name: "bad to execution address",
|
||||
expectedErrorMessage: "failed to decode execution address `foo`",
|
||||
generateInput: func() []*shared.SignedBLSToExecutionChange {
|
||||
generateInput: func() []*structs.SignedBLSToExecutionChange {
|
||||
input := generateBlsToExecutionChanges()
|
||||
input[0].Message.ToExecutionAddress = "foo"
|
||||
return input
|
||||
@@ -1056,7 +1056,7 @@ func TestBeaconBlockProtoHelpers_ConvertBlsToExecutionChangesToProto(t *testing.
|
||||
{
|
||||
name: "bad signature",
|
||||
expectedErrorMessage: "failed to decode signature `bar`",
|
||||
generateInput: func() []*shared.SignedBLSToExecutionChange {
|
||||
generateInput: func() []*structs.SignedBLSToExecutionChange {
|
||||
input := generateBlsToExecutionChanges()
|
||||
input[0].Signature = "bar"
|
||||
return input
|
||||
@@ -1078,11 +1078,11 @@ func TestBeaconBlockProtoHelpers_ConvertBlsToExecutionChangesToProto(t *testing.
|
||||
}
|
||||
}
|
||||
|
||||
func generateProposerSlashings() []*shared.ProposerSlashing {
|
||||
return []*shared.ProposerSlashing{
|
||||
func generateProposerSlashings() []*structs.ProposerSlashing {
|
||||
return []*structs.ProposerSlashing{
|
||||
{
|
||||
SignedHeader1: &shared.SignedBeaconBlockHeader{
|
||||
Message: &shared.BeaconBlockHeader{
|
||||
SignedHeader1: &structs.SignedBeaconBlockHeader{
|
||||
Message: &structs.BeaconBlockHeader{
|
||||
Slot: "1",
|
||||
ProposerIndex: "2",
|
||||
ParentRoot: hexutil.Encode([]byte{3}),
|
||||
@@ -1091,8 +1091,8 @@ func generateProposerSlashings() []*shared.ProposerSlashing {
|
||||
},
|
||||
Signature: hexutil.Encode([]byte{6}),
|
||||
},
|
||||
SignedHeader2: &shared.SignedBeaconBlockHeader{
|
||||
Message: &shared.BeaconBlockHeader{
|
||||
SignedHeader2: &structs.SignedBeaconBlockHeader{
|
||||
Message: &structs.BeaconBlockHeader{
|
||||
Slot: "7",
|
||||
ProposerIndex: "8",
|
||||
ParentRoot: hexutil.Encode([]byte{9}),
|
||||
@@ -1103,8 +1103,8 @@ func generateProposerSlashings() []*shared.ProposerSlashing {
|
||||
},
|
||||
},
|
||||
{
|
||||
SignedHeader1: &shared.SignedBeaconBlockHeader{
|
||||
Message: &shared.BeaconBlockHeader{
|
||||
SignedHeader1: &structs.SignedBeaconBlockHeader{
|
||||
Message: &structs.BeaconBlockHeader{
|
||||
Slot: "13",
|
||||
ProposerIndex: "14",
|
||||
ParentRoot: hexutil.Encode([]byte{15}),
|
||||
@@ -1113,8 +1113,8 @@ func generateProposerSlashings() []*shared.ProposerSlashing {
|
||||
},
|
||||
Signature: hexutil.Encode([]byte{18}),
|
||||
},
|
||||
SignedHeader2: &shared.SignedBeaconBlockHeader{
|
||||
Message: &shared.BeaconBlockHeader{
|
||||
SignedHeader2: &structs.SignedBeaconBlockHeader{
|
||||
Message: &structs.BeaconBlockHeader{
|
||||
Slot: "19",
|
||||
ProposerIndex: "20",
|
||||
ParentRoot: hexutil.Encode([]byte{21}),
|
||||
@@ -1127,9 +1127,9 @@ func generateProposerSlashings() []*shared.ProposerSlashing {
|
||||
}
|
||||
}
|
||||
|
||||
func generateSignedBeaconBlockHeader() *shared.SignedBeaconBlockHeader {
|
||||
return &shared.SignedBeaconBlockHeader{
|
||||
Message: &shared.BeaconBlockHeader{
|
||||
func generateSignedBeaconBlockHeader() *structs.SignedBeaconBlockHeader {
|
||||
return &structs.SignedBeaconBlockHeader{
|
||||
Message: &structs.BeaconBlockHeader{
|
||||
Slot: "1",
|
||||
ProposerIndex: "2",
|
||||
ParentRoot: hexutil.Encode([]byte{3}),
|
||||
@@ -1140,37 +1140,37 @@ func generateSignedBeaconBlockHeader() *shared.SignedBeaconBlockHeader {
|
||||
}
|
||||
}
|
||||
|
||||
func generateAttesterSlashings() []*shared.AttesterSlashing {
|
||||
return []*shared.AttesterSlashing{
|
||||
func generateAttesterSlashings() []*structs.AttesterSlashing {
|
||||
return []*structs.AttesterSlashing{
|
||||
{
|
||||
Attestation1: &shared.IndexedAttestation{
|
||||
Attestation1: &structs.IndexedAttestation{
|
||||
AttestingIndices: []string{"1", "2"},
|
||||
Data: &shared.AttestationData{
|
||||
Data: &structs.AttestationData{
|
||||
Slot: "3",
|
||||
CommitteeIndex: "4",
|
||||
BeaconBlockRoot: hexutil.Encode([]byte{5}),
|
||||
Source: &shared.Checkpoint{
|
||||
Source: &structs.Checkpoint{
|
||||
Epoch: "6",
|
||||
Root: hexutil.Encode([]byte{7}),
|
||||
},
|
||||
Target: &shared.Checkpoint{
|
||||
Target: &structs.Checkpoint{
|
||||
Epoch: "8",
|
||||
Root: hexutil.Encode([]byte{9}),
|
||||
},
|
||||
},
|
||||
Signature: hexutil.Encode([]byte{10}),
|
||||
},
|
||||
Attestation2: &shared.IndexedAttestation{
|
||||
Attestation2: &structs.IndexedAttestation{
|
||||
AttestingIndices: []string{"11", "12"},
|
||||
Data: &shared.AttestationData{
|
||||
Data: &structs.AttestationData{
|
||||
Slot: "13",
|
||||
CommitteeIndex: "14",
|
||||
BeaconBlockRoot: hexutil.Encode([]byte{15}),
|
||||
Source: &shared.Checkpoint{
|
||||
Source: &structs.Checkpoint{
|
||||
Epoch: "16",
|
||||
Root: hexutil.Encode([]byte{17}),
|
||||
},
|
||||
Target: &shared.Checkpoint{
|
||||
Target: &structs.Checkpoint{
|
||||
Epoch: "18",
|
||||
Root: hexutil.Encode([]byte{19}),
|
||||
},
|
||||
@@ -1179,34 +1179,34 @@ func generateAttesterSlashings() []*shared.AttesterSlashing {
|
||||
},
|
||||
},
|
||||
{
|
||||
Attestation1: &shared.IndexedAttestation{
|
||||
Attestation1: &structs.IndexedAttestation{
|
||||
AttestingIndices: []string{"21", "22"},
|
||||
Data: &shared.AttestationData{
|
||||
Data: &structs.AttestationData{
|
||||
Slot: "23",
|
||||
CommitteeIndex: "24",
|
||||
BeaconBlockRoot: hexutil.Encode([]byte{25}),
|
||||
Source: &shared.Checkpoint{
|
||||
Source: &structs.Checkpoint{
|
||||
Epoch: "26",
|
||||
Root: hexutil.Encode([]byte{27}),
|
||||
},
|
||||
Target: &shared.Checkpoint{
|
||||
Target: &structs.Checkpoint{
|
||||
Epoch: "28",
|
||||
Root: hexutil.Encode([]byte{29}),
|
||||
},
|
||||
},
|
||||
Signature: hexutil.Encode([]byte{30}),
|
||||
},
|
||||
Attestation2: &shared.IndexedAttestation{
|
||||
Attestation2: &structs.IndexedAttestation{
|
||||
AttestingIndices: []string{"31", "32"},
|
||||
Data: &shared.AttestationData{
|
||||
Data: &structs.AttestationData{
|
||||
Slot: "33",
|
||||
CommitteeIndex: "34",
|
||||
BeaconBlockRoot: hexutil.Encode([]byte{35}),
|
||||
Source: &shared.Checkpoint{
|
||||
Source: &structs.Checkpoint{
|
||||
Epoch: "36",
|
||||
Root: hexutil.Encode([]byte{37}),
|
||||
},
|
||||
Target: &shared.Checkpoint{
|
||||
Target: &structs.Checkpoint{
|
||||
Epoch: "38",
|
||||
Root: hexutil.Encode([]byte{39}),
|
||||
},
|
||||
@@ -1217,18 +1217,18 @@ func generateAttesterSlashings() []*shared.AttesterSlashing {
|
||||
}
|
||||
}
|
||||
|
||||
func generateIndexedAttestation() *shared.IndexedAttestation {
|
||||
return &shared.IndexedAttestation{
|
||||
func generateIndexedAttestation() *structs.IndexedAttestation {
|
||||
return &structs.IndexedAttestation{
|
||||
AttestingIndices: []string{"1", "2"},
|
||||
Data: &shared.AttestationData{
|
||||
Data: &structs.AttestationData{
|
||||
Slot: "3",
|
||||
CommitteeIndex: "4",
|
||||
BeaconBlockRoot: hexutil.Encode([]byte{5}),
|
||||
Source: &shared.Checkpoint{
|
||||
Source: &structs.Checkpoint{
|
||||
Epoch: "6",
|
||||
Root: hexutil.Encode([]byte{7}),
|
||||
},
|
||||
Target: &shared.Checkpoint{
|
||||
Target: &structs.Checkpoint{
|
||||
Epoch: "8",
|
||||
Root: hexutil.Encode([]byte{9}),
|
||||
},
|
||||
@@ -1237,26 +1237,26 @@ func generateIndexedAttestation() *shared.IndexedAttestation {
|
||||
}
|
||||
}
|
||||
|
||||
func generateCheckpoint() *shared.Checkpoint {
|
||||
return &shared.Checkpoint{
|
||||
func generateCheckpoint() *structs.Checkpoint {
|
||||
return &structs.Checkpoint{
|
||||
Epoch: "1",
|
||||
Root: hexutil.Encode([]byte{2}),
|
||||
}
|
||||
}
|
||||
|
||||
func generateAttestations() []*shared.Attestation {
|
||||
return []*shared.Attestation{
|
||||
func generateAttestations() []*structs.Attestation {
|
||||
return []*structs.Attestation{
|
||||
{
|
||||
AggregationBits: hexutil.Encode([]byte{1}),
|
||||
Data: &shared.AttestationData{
|
||||
Data: &structs.AttestationData{
|
||||
Slot: "2",
|
||||
CommitteeIndex: "3",
|
||||
BeaconBlockRoot: hexutil.Encode([]byte{4}),
|
||||
Source: &shared.Checkpoint{
|
||||
Source: &structs.Checkpoint{
|
||||
Epoch: "5",
|
||||
Root: hexutil.Encode([]byte{6}),
|
||||
},
|
||||
Target: &shared.Checkpoint{
|
||||
Target: &structs.Checkpoint{
|
||||
Epoch: "7",
|
||||
Root: hexutil.Encode([]byte{8}),
|
||||
},
|
||||
@@ -1265,15 +1265,15 @@ func generateAttestations() []*shared.Attestation {
|
||||
},
|
||||
{
|
||||
AggregationBits: hexutil.Encode([]byte{10}),
|
||||
Data: &shared.AttestationData{
|
||||
Data: &structs.AttestationData{
|
||||
Slot: "11",
|
||||
CommitteeIndex: "12",
|
||||
BeaconBlockRoot: hexutil.Encode([]byte{13}),
|
||||
Source: &shared.Checkpoint{
|
||||
Source: &structs.Checkpoint{
|
||||
Epoch: "14",
|
||||
Root: hexutil.Encode([]byte{15}),
|
||||
},
|
||||
Target: &shared.Checkpoint{
|
||||
Target: &structs.Checkpoint{
|
||||
Epoch: "16",
|
||||
Root: hexutil.Encode([]byte{17}),
|
||||
},
|
||||
@@ -1283,30 +1283,30 @@ func generateAttestations() []*shared.Attestation {
|
||||
}
|
||||
}
|
||||
|
||||
func generateAttestationData() *shared.AttestationData {
|
||||
return &shared.AttestationData{
|
||||
func generateAttestationData() *structs.AttestationData {
|
||||
return &structs.AttestationData{
|
||||
Slot: "1",
|
||||
CommitteeIndex: "2",
|
||||
BeaconBlockRoot: hexutil.Encode([]byte{3}),
|
||||
Source: &shared.Checkpoint{
|
||||
Source: &structs.Checkpoint{
|
||||
Epoch: "4",
|
||||
Root: hexutil.Encode([]byte{5}),
|
||||
},
|
||||
Target: &shared.Checkpoint{
|
||||
Target: &structs.Checkpoint{
|
||||
Epoch: "6",
|
||||
Root: hexutil.Encode([]byte{7}),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func generateDeposits() []*shared.Deposit {
|
||||
return []*shared.Deposit{
|
||||
func generateDeposits() []*structs.Deposit {
|
||||
return []*structs.Deposit{
|
||||
{
|
||||
Proof: []string{
|
||||
hexutil.Encode([]byte{1}),
|
||||
hexutil.Encode([]byte{2}),
|
||||
},
|
||||
Data: &shared.DepositData{
|
||||
Data: &structs.DepositData{
|
||||
Pubkey: hexutil.Encode([]byte{3}),
|
||||
WithdrawalCredentials: hexutil.Encode([]byte{4}),
|
||||
Amount: "5",
|
||||
@@ -1318,7 +1318,7 @@ func generateDeposits() []*shared.Deposit {
|
||||
hexutil.Encode([]byte{7}),
|
||||
hexutil.Encode([]byte{8}),
|
||||
},
|
||||
Data: &shared.DepositData{
|
||||
Data: &structs.DepositData{
|
||||
Pubkey: hexutil.Encode([]byte{9}),
|
||||
WithdrawalCredentials: hexutil.Encode([]byte{10}),
|
||||
Amount: "11",
|
||||
@@ -1328,17 +1328,17 @@ func generateDeposits() []*shared.Deposit {
|
||||
}
|
||||
}
|
||||
|
||||
func generateSignedVoluntaryExits() []*shared.SignedVoluntaryExit {
|
||||
return []*shared.SignedVoluntaryExit{
|
||||
func generateSignedVoluntaryExits() []*structs.SignedVoluntaryExit {
|
||||
return []*structs.SignedVoluntaryExit{
|
||||
{
|
||||
Message: &shared.VoluntaryExit{
|
||||
Message: &structs.VoluntaryExit{
|
||||
Epoch: "1",
|
||||
ValidatorIndex: "2",
|
||||
},
|
||||
Signature: hexutil.Encode([]byte{3}),
|
||||
},
|
||||
{
|
||||
Message: &shared.VoluntaryExit{
|
||||
Message: &structs.VoluntaryExit{
|
||||
Epoch: "4",
|
||||
ValidatorIndex: "5",
|
||||
},
|
||||
@@ -1347,8 +1347,8 @@ func generateSignedVoluntaryExits() []*shared.SignedVoluntaryExit {
|
||||
}
|
||||
}
|
||||
|
||||
func generateWithdrawals() []*shared.Withdrawal {
|
||||
return []*shared.Withdrawal{
|
||||
func generateWithdrawals() []*structs.Withdrawal {
|
||||
return []*structs.Withdrawal{
|
||||
{
|
||||
WithdrawalIndex: "1",
|
||||
ValidatorIndex: "2",
|
||||
@@ -1364,10 +1364,10 @@ func generateWithdrawals() []*shared.Withdrawal {
|
||||
}
|
||||
}
|
||||
|
||||
func generateBlsToExecutionChanges() []*shared.SignedBLSToExecutionChange {
|
||||
return []*shared.SignedBLSToExecutionChange{
|
||||
func generateBlsToExecutionChanges() []*structs.SignedBLSToExecutionChange {
|
||||
return []*structs.SignedBLSToExecutionChange{
|
||||
{
|
||||
Message: &shared.BLSToExecutionChange{
|
||||
Message: &structs.BLSToExecutionChange{
|
||||
ValidatorIndex: "1",
|
||||
FromBLSPubkey: hexutil.Encode([]byte{2}),
|
||||
ToExecutionAddress: hexutil.Encode([]byte{3}),
|
||||
@@ -1375,7 +1375,7 @@ func generateBlsToExecutionChanges() []*shared.SignedBLSToExecutionChange {
|
||||
Signature: hexutil.Encode([]byte{4}),
|
||||
},
|
||||
{
|
||||
Message: &shared.BLSToExecutionChange{
|
||||
Message: &structs.BLSToExecutionChange{
|
||||
ValidatorIndex: "5",
|
||||
FromBLSPubkey: hexutil.Encode([]byte{6}),
|
||||
ToExecutionAddress: hexutil.Encode([]byte{7}),
|
||||
38
api/client/beacon/validator_api/client.go
Normal file
38
api/client/beacon/validator_api/client.go
Normal file
@@ -0,0 +1,38 @@
|
||||
package validator_api
|
||||
|
||||
import (
|
||||
"github.com/prysmaticlabs/prysm/v5/api/client"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/client/beacon/node"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/client/beacon/prysm_api"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/client/beacon/shared_providers"
|
||||
"github.com/prysmaticlabs/prysm/v5/config/features"
|
||||
validatorHelpers "github.com/prysmaticlabs/prysm/v5/validator/helpers"
|
||||
)
|
||||
|
||||
func NewClient(
|
||||
validatorConn validatorHelpers.NodeConnection,
|
||||
jsonRestHandler client.JsonRestHandler,
|
||||
opt ...ValidatorClientOpt,
|
||||
) Client {
|
||||
if features.Get().EnableBeaconRESTApi {
|
||||
return NewBeaconApiValidatorClient(jsonRestHandler, opt...)
|
||||
} else {
|
||||
return NewGrpcValidatorClient(validatorConn.GetGrpcClientConn())
|
||||
}
|
||||
}
|
||||
|
||||
func NewBeaconApiValidatorClient(jsonRestHandler client.JsonRestHandler, opts ...ValidatorClientOpt) Client {
|
||||
c := &beaconApiValidatorClient{
|
||||
genesisProvider: shared_providers.NewGenesis(jsonRestHandler),
|
||||
dutiesProvider: shared_providers.NewDuties(jsonRestHandler),
|
||||
stateValidatorsProvider: shared_providers.NewStateValidators(jsonRestHandler),
|
||||
jsonRestHandler: jsonRestHandler,
|
||||
beaconBlockConverter: beaconApiBeaconBlockConverter{},
|
||||
prysmChainClient: prysm_api.NewPrysmChainRestClient(jsonRestHandler, node.NewNodeClientWithFallback(jsonRestHandler, nil)), //TODO: this is really bad design...
|
||||
isEventStreamRunning: false,
|
||||
}
|
||||
for _, o := range opts {
|
||||
o(c)
|
||||
}
|
||||
return c
|
||||
}
|
||||
@@ -1,17 +1,18 @@
|
||||
package beacon_api
|
||||
package validator_api
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/core/signing"
|
||||
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
|
||||
"github.com/prysmaticlabs/prysm/v4/network/forks"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/apiutil"
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/signing"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
"github.com/prysmaticlabs/prysm/v5/network/forks"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
)
|
||||
|
||||
func (c beaconApiValidatorClient) getDomainData(ctx context.Context, epoch primitives.Epoch, domainType [4]byte) (*ethpb.DomainResponse, error) {
|
||||
func (c *beaconApiValidatorClient) domainData(ctx context.Context, epoch primitives.Epoch, domainType [4]byte) (*ethpb.DomainResponse, error) {
|
||||
// Get the fork version from the given epoch
|
||||
fork, err := forks.Fork(epoch)
|
||||
if err != nil {
|
||||
@@ -19,15 +20,12 @@ func (c beaconApiValidatorClient) getDomainData(ctx context.Context, epoch primi
|
||||
}
|
||||
|
||||
// Get the genesis validator root
|
||||
genesis, errJson, err := c.genesisProvider.GetGenesis(ctx)
|
||||
genesis, err := c.genesisProvider.Genesis(ctx)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to get genesis info")
|
||||
}
|
||||
if errJson != nil {
|
||||
return nil, errJson
|
||||
}
|
||||
|
||||
if !validRoot(genesis.GenesisValidatorsRoot) {
|
||||
if !apiutil.ValidRoot(genesis.GenesisValidatorsRoot) {
|
||||
return nil, errors.Errorf("invalid genesis validators root: %s", genesis.GenesisValidatorsRoot)
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package beacon_api
|
||||
package validator_api
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -6,13 +6,13 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/golang/mock/gomock"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/beacon"
|
||||
"github.com/prysmaticlabs/prysm/v4/config/params"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v4/testing/assert"
|
||||
"github.com/prysmaticlabs/prysm/v4/testing/require"
|
||||
"github.com/prysmaticlabs/prysm/v4/validator/client/beacon-api/mock"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/client/beacon/mock"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/server/structs"
|
||||
"github.com/prysmaticlabs/prysm/v5/config/params"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v5/testing/assert"
|
||||
"github.com/prysmaticlabs/prysm/v5/testing/require"
|
||||
"go.uber.org/mock/gomock"
|
||||
)
|
||||
|
||||
func TestGetDomainData_ValidDomainData(t *testing.T) {
|
||||
@@ -35,16 +35,15 @@ func TestGetDomainData_ValidDomainData(t *testing.T) {
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
// Make sure that GetGenesis() is called exactly once
|
||||
// Make sure that Genesis() is called exactly once
|
||||
genesisProvider := mock.NewMockGenesisProvider(ctrl)
|
||||
genesisProvider.EXPECT().GetGenesis(ctx).Return(
|
||||
&beacon.Genesis{GenesisValidatorsRoot: genesisValidatorRoot},
|
||||
nil,
|
||||
genesisProvider.EXPECT().Genesis(gomock.Any()).Return(
|
||||
&structs.Genesis{GenesisValidatorsRoot: genesisValidatorRoot},
|
||||
nil,
|
||||
).Times(1)
|
||||
|
||||
validatorClient := &beaconApiValidatorClient{genesisProvider: genesisProvider}
|
||||
resp, err := validatorClient.getDomainData(ctx, epoch, domainType)
|
||||
resp, err := validatorClient.domainData(ctx, epoch, domainType)
|
||||
assert.NoError(t, err)
|
||||
require.NotNil(t, resp)
|
||||
|
||||
@@ -65,12 +64,12 @@ func TestGetDomainData_GenesisError(t *testing.T) {
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
// Make sure that GetGenesis() is called exactly once
|
||||
// Make sure that Genesis() is called exactly once
|
||||
genesisProvider := mock.NewMockGenesisProvider(ctrl)
|
||||
genesisProvider.EXPECT().GetGenesis(ctx).Return(nil, nil, errors.New("foo error")).Times(1)
|
||||
genesisProvider.EXPECT().Genesis(gomock.Any()).Return(nil, errors.New("foo error")).Times(1)
|
||||
|
||||
validatorClient := &beaconApiValidatorClient{genesisProvider: genesisProvider}
|
||||
_, err := validatorClient.getDomainData(ctx, epoch, domainType)
|
||||
_, err := validatorClient.domainData(ctx, epoch, domainType)
|
||||
assert.ErrorContains(t, "failed to get genesis info", err)
|
||||
assert.ErrorContains(t, "foo error", err)
|
||||
}
|
||||
@@ -84,15 +83,14 @@ func TestGetDomainData_InvalidGenesisRoot(t *testing.T) {
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
// Make sure that GetGenesis() is called exactly once
|
||||
// Make sure that Genesis() is called exactly once
|
||||
genesisProvider := mock.NewMockGenesisProvider(ctrl)
|
||||
genesisProvider.EXPECT().GetGenesis(ctx).Return(
|
||||
&beacon.Genesis{GenesisValidatorsRoot: "foo"},
|
||||
nil,
|
||||
genesisProvider.EXPECT().Genesis(gomock.Any()).Return(
|
||||
&structs.Genesis{GenesisValidatorsRoot: "foo"},
|
||||
nil,
|
||||
).Times(1)
|
||||
|
||||
validatorClient := &beaconApiValidatorClient{genesisProvider: genesisProvider}
|
||||
_, err := validatorClient.getDomainData(ctx, epoch, domainType)
|
||||
_, err := validatorClient.domainData(ctx, epoch, domainType)
|
||||
assert.ErrorContains(t, "invalid genesis validators root: foo", err)
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package beacon_api
|
||||
package validator_api
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -6,13 +6,12 @@ import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v4/runtime/version"
|
||||
"github.com/prysmaticlabs/prysm/v4/time/slots"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v5/runtime/version"
|
||||
"github.com/prysmaticlabs/prysm/v5/time/slots"
|
||||
)
|
||||
|
||||
type DoppelGangerInfo struct {
|
||||
@@ -73,7 +72,7 @@ func (c *beaconApiValidatorClient) checkDoppelGanger(ctx context.Context, in *et
|
||||
}
|
||||
|
||||
// Retrieve fork version -- Return early if we are in phase0.
|
||||
forkResponse, err := c.getFork(ctx)
|
||||
forkResponse, err := c.fork(ctx)
|
||||
if err != nil || forkResponse == nil || forkResponse.Data == nil {
|
||||
return nil, errors.Wrapf(err, "failed to get fork")
|
||||
}
|
||||
@@ -91,7 +90,7 @@ func (c *beaconApiValidatorClient) checkDoppelGanger(ctx context.Context, in *et
|
||||
}
|
||||
|
||||
// Retrieve current epoch.
|
||||
headers, err := c.getHeaders(ctx)
|
||||
headers, err := c.headers(ctx)
|
||||
if err != nil || headers == nil || headers.Data == nil || len(headers.Data) == 0 ||
|
||||
headers.Data[0].Header == nil || headers.Data[0].Header.Message == nil {
|
||||
return nil, errors.Wrapf(err, "failed to get headers")
|
||||
@@ -127,7 +126,7 @@ func (c *beaconApiValidatorClient) checkDoppelGanger(ctx context.Context, in *et
|
||||
}
|
||||
|
||||
// Retrieve correspondence between validator pubkey and index.
|
||||
stateValidators, err := c.stateValidatorsProvider.GetStateValidators(ctx, notRecentStringPubKeys, nil, nil)
|
||||
stateValidators, err := c.stateValidatorsProvider.StateValidators(ctx, notRecentStringPubKeys, nil, nil)
|
||||
if err != nil || stateValidators == nil || stateValidators.Data == nil {
|
||||
return nil, errors.Wrapf(err, "failed to get state validators")
|
||||
}
|
||||
@@ -156,13 +155,13 @@ func (c *beaconApiValidatorClient) checkDoppelGanger(ctx context.Context, in *et
|
||||
// since we assume that we are not in phase0.
|
||||
previousEpoch := currentEpoch - 1
|
||||
|
||||
indexToPreviousLiveness, err := c.getIndexToLiveness(ctx, previousEpoch, indexes)
|
||||
indexToPreviousLiveness, err := c.indexToLiveness(ctx, previousEpoch, indexes)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to get map from validator index to liveness for previous epoch %d", previousEpoch)
|
||||
}
|
||||
|
||||
// Get validators liveness for the current epoch.
|
||||
indexToCurrentLiveness, err := c.getIndexToLiveness(ctx, currentEpoch, indexes)
|
||||
indexToCurrentLiveness, err := c.indexToLiveness(ctx, currentEpoch, indexes)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to get map from validator index to liveness for current epoch %d", currentEpoch)
|
||||
}
|
||||
@@ -218,10 +217,10 @@ func buildResponse(
|
||||
}
|
||||
}
|
||||
|
||||
func (c *beaconApiValidatorClient) getIndexToLiveness(ctx context.Context, epoch primitives.Epoch, indexes []string) (map[string]bool, error) {
|
||||
livenessResponse, err := c.getLiveness(ctx, epoch, indexes)
|
||||
func (c *beaconApiValidatorClient) indexToLiveness(ctx context.Context, epoch primitives.Epoch, indexes []string) (map[string]bool, error) {
|
||||
livenessResponse, err := c.liveness(ctx, epoch, indexes)
|
||||
if err != nil || livenessResponse.Data == nil {
|
||||
return nil, errors.Wrapf(err, fmt.Sprintf("failed to get liveness for epoch %d", epoch))
|
||||
return nil, errors.Wrapf(err, "failed to get liveness for epoch %d", epoch)
|
||||
}
|
||||
|
||||
indexToLiveness := make(map[string]bool, len(livenessResponse.Data))
|
||||
@@ -1,4 +1,4 @@
|
||||
package beacon_api
|
||||
package validator_api
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
@@ -7,16 +7,13 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/golang/mock/gomock"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/beacon"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/node"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/shared"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/validator"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v4/testing/assert"
|
||||
"github.com/prysmaticlabs/prysm/v4/testing/require"
|
||||
"github.com/prysmaticlabs/prysm/v4/validator/client/beacon-api/mock"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/client/beacon/mock"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/server/structs"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v5/testing/assert"
|
||||
"github.com/prysmaticlabs/prysm/v5/testing/require"
|
||||
"go.uber.org/mock/gomock"
|
||||
)
|
||||
|
||||
func TestCheckDoppelGanger_Nominal(t *testing.T) {
|
||||
@@ -49,17 +46,17 @@ func TestCheckDoppelGanger_Nominal(t *testing.T) {
|
||||
name string
|
||||
doppelGangerInput *ethpb.DoppelGangerRequest
|
||||
doppelGangerExpectedOutput *ethpb.DoppelGangerResponse
|
||||
getSyncingOutput *node.SyncStatusResponse
|
||||
getForkOutput *beacon.GetStateForkResponse
|
||||
getHeadersOutput *beacon.GetBlockHeadersResponse
|
||||
getSyncingOutput *structs.SyncStatusResponse
|
||||
getForkOutput *structs.GetStateForkResponse
|
||||
getHeadersOutput *structs.GetBlockHeadersResponse
|
||||
getStateValidatorsInterface *struct {
|
||||
input []string
|
||||
output *beacon.GetValidatorsResponse
|
||||
output *structs.GetValidatorsResponse
|
||||
}
|
||||
getLivelinessInterfaces []struct {
|
||||
inputUrl string
|
||||
inputStringIndexes []string
|
||||
output *validator.GetLivenessResponse
|
||||
output *structs.GetLivenessResponse
|
||||
}
|
||||
}{
|
||||
{
|
||||
@@ -109,13 +106,13 @@ func TestCheckDoppelGanger_Nominal(t *testing.T) {
|
||||
{PublicKey: pubKey6, DuplicateExists: false},
|
||||
},
|
||||
},
|
||||
getSyncingOutput: &node.SyncStatusResponse{
|
||||
Data: &node.SyncStatusResponseData{
|
||||
getSyncingOutput: &structs.SyncStatusResponse{
|
||||
Data: &structs.SyncStatusResponseData{
|
||||
IsSyncing: false,
|
||||
},
|
||||
},
|
||||
getForkOutput: &beacon.GetStateForkResponse{
|
||||
Data: &shared.Fork{
|
||||
getForkOutput: &structs.GetStateForkResponse{
|
||||
Data: &structs.Fork{
|
||||
PreviousVersion: "0x00000000",
|
||||
CurrentVersion: "0x00000000",
|
||||
Epoch: "42",
|
||||
@@ -144,23 +141,23 @@ func TestCheckDoppelGanger_Nominal(t *testing.T) {
|
||||
{PublicKey: pubKey6, DuplicateExists: false},
|
||||
},
|
||||
},
|
||||
getSyncingOutput: &node.SyncStatusResponse{
|
||||
Data: &node.SyncStatusResponseData{
|
||||
getSyncingOutput: &structs.SyncStatusResponse{
|
||||
Data: &structs.SyncStatusResponseData{
|
||||
IsSyncing: false,
|
||||
},
|
||||
},
|
||||
getForkOutput: &beacon.GetStateForkResponse{
|
||||
Data: &shared.Fork{
|
||||
getForkOutput: &structs.GetStateForkResponse{
|
||||
Data: &structs.Fork{
|
||||
PreviousVersion: "0x01000000",
|
||||
CurrentVersion: "0x02000000",
|
||||
Epoch: "2",
|
||||
},
|
||||
},
|
||||
getHeadersOutput: &beacon.GetBlockHeadersResponse{
|
||||
Data: []*shared.SignedBeaconBlockHeaderContainer{
|
||||
getHeadersOutput: &structs.GetBlockHeadersResponse{
|
||||
Data: []*structs.SignedBeaconBlockHeaderContainer{
|
||||
{
|
||||
Header: &shared.SignedBeaconBlockHeader{
|
||||
Message: &shared.BeaconBlockHeader{
|
||||
Header: &structs.SignedBeaconBlockHeader{
|
||||
Message: &structs.BeaconBlockHeader{
|
||||
Slot: "99",
|
||||
},
|
||||
},
|
||||
@@ -190,23 +187,23 @@ func TestCheckDoppelGanger_Nominal(t *testing.T) {
|
||||
{PublicKey: pubKey6, DuplicateExists: false}, // not recent - not duplicate
|
||||
},
|
||||
},
|
||||
getSyncingOutput: &node.SyncStatusResponse{
|
||||
Data: &node.SyncStatusResponseData{
|
||||
getSyncingOutput: &structs.SyncStatusResponse{
|
||||
Data: &structs.SyncStatusResponseData{
|
||||
IsSyncing: false,
|
||||
},
|
||||
},
|
||||
getForkOutput: &beacon.GetStateForkResponse{
|
||||
Data: &shared.Fork{
|
||||
getForkOutput: &structs.GetStateForkResponse{
|
||||
Data: &structs.Fork{
|
||||
PreviousVersion: "0x01000000",
|
||||
CurrentVersion: "0x02000000",
|
||||
Epoch: "2",
|
||||
},
|
||||
},
|
||||
getHeadersOutput: &beacon.GetBlockHeadersResponse{
|
||||
Data: []*shared.SignedBeaconBlockHeaderContainer{
|
||||
getHeadersOutput: &structs.GetBlockHeadersResponse{
|
||||
Data: []*structs.SignedBeaconBlockHeaderContainer{
|
||||
{
|
||||
Header: &shared.SignedBeaconBlockHeader{
|
||||
Message: &shared.BeaconBlockHeader{
|
||||
Header: &structs.SignedBeaconBlockHeader{
|
||||
Message: &structs.BeaconBlockHeader{
|
||||
Slot: "3201",
|
||||
},
|
||||
},
|
||||
@@ -215,7 +212,7 @@ func TestCheckDoppelGanger_Nominal(t *testing.T) {
|
||||
},
|
||||
getStateValidatorsInterface: &struct {
|
||||
input []string
|
||||
output *beacon.GetValidatorsResponse
|
||||
output *structs.GetValidatorsResponse
|
||||
}{
|
||||
input: []string{
|
||||
// no stringPubKey1 since recent
|
||||
@@ -225,21 +222,21 @@ func TestCheckDoppelGanger_Nominal(t *testing.T) {
|
||||
stringPubKey5, // non existing validator
|
||||
stringPubKey6, // not recent - not duplicate
|
||||
},
|
||||
output: &beacon.GetValidatorsResponse{
|
||||
Data: []*beacon.ValidatorContainer{
|
||||
output: &structs.GetValidatorsResponse{
|
||||
Data: []*structs.ValidatorContainer{
|
||||
// No "11111" since corresponding validator is recent
|
||||
{Index: "22222", Validator: &beacon.Validator{Pubkey: stringPubKey2}}, // not recent - duplicate on previous epoch
|
||||
{Index: "33333", Validator: &beacon.Validator{Pubkey: stringPubKey3}}, // not recent - duplicate on current epoch
|
||||
{Index: "44444", Validator: &beacon.Validator{Pubkey: stringPubKey4}}, // not recent - duplicate on both previous and current epoch
|
||||
// No "55555" sicee corresponding validator does not exist
|
||||
{Index: "66666", Validator: &beacon.Validator{Pubkey: stringPubKey6}}, // not recent - not duplicate
|
||||
{Index: "22222", Validator: &structs.Validator{Pubkey: stringPubKey2}}, // not recent - duplicate on previous epoch
|
||||
{Index: "33333", Validator: &structs.Validator{Pubkey: stringPubKey3}}, // not recent - duplicate on current epoch
|
||||
{Index: "44444", Validator: &structs.Validator{Pubkey: stringPubKey4}}, // not recent - duplicate on both previous and current epoch
|
||||
// No "55555" since corresponding validator does not exist
|
||||
{Index: "66666", Validator: &structs.Validator{Pubkey: stringPubKey6}}, // not recent - not duplicate
|
||||
},
|
||||
},
|
||||
},
|
||||
getLivelinessInterfaces: []struct {
|
||||
inputUrl string
|
||||
inputStringIndexes []string
|
||||
output *validator.GetLivenessResponse
|
||||
output *structs.GetLivenessResponse
|
||||
}{
|
||||
{
|
||||
inputUrl: "/eth/v1/validator/liveness/99", // previous epoch
|
||||
@@ -251,8 +248,8 @@ func TestCheckDoppelGanger_Nominal(t *testing.T) {
|
||||
// No "55555" since corresponding validator it does not exist
|
||||
"66666", // not recent - not duplicate
|
||||
},
|
||||
output: &validator.GetLivenessResponse{
|
||||
Data: []*validator.Liveness{
|
||||
output: &structs.GetLivenessResponse{
|
||||
Data: []*structs.Liveness{
|
||||
// No "11111" since corresponding validator is recent
|
||||
{Index: "22222", IsLive: true}, // not recent - duplicate on previous epoch
|
||||
{Index: "33333", IsLive: false}, // not recent - duplicate on current epoch
|
||||
@@ -272,8 +269,8 @@ func TestCheckDoppelGanger_Nominal(t *testing.T) {
|
||||
// No "55555" since corresponding validator it does not exist
|
||||
"66666", // not recent - not duplicate
|
||||
},
|
||||
output: &validator.GetLivenessResponse{
|
||||
Data: []*validator.Liveness{
|
||||
output: &structs.GetLivenessResponse{
|
||||
Data: []*structs.Liveness{
|
||||
// No "11111" since corresponding validator is recent
|
||||
{Index: "22222", IsLive: false}, // not recent - duplicate on previous epoch
|
||||
{Index: "33333", IsLive: true}, // not recent - duplicate on current epoch
|
||||
@@ -294,18 +291,15 @@ func TestCheckDoppelGanger_Nominal(t *testing.T) {
|
||||
|
||||
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
if testCase.getSyncingOutput != nil {
|
||||
syncingResponseJson := node.SyncStatusResponse{}
|
||||
syncingResponseJson := structs.SyncStatusResponse{}
|
||||
|
||||
jsonRestHandler.EXPECT().Get(
|
||||
ctx,
|
||||
syncingEnpoint,
|
||||
gomock.Any(),
|
||||
syncingEndpoint,
|
||||
&syncingResponseJson,
|
||||
).Return(
|
||||
nil,
|
||||
nil,
|
||||
).SetArg(
|
||||
2,
|
||||
*testCase.getSyncingOutput,
|
||||
@@ -313,15 +307,14 @@ func TestCheckDoppelGanger_Nominal(t *testing.T) {
|
||||
}
|
||||
|
||||
if testCase.getForkOutput != nil {
|
||||
stateForkResponseJson := beacon.GetStateForkResponse{}
|
||||
stateForkResponseJson := structs.GetStateForkResponse{}
|
||||
|
||||
jsonRestHandler.EXPECT().Get(
|
||||
ctx,
|
||||
gomock.Any(),
|
||||
forkEndpoint,
|
||||
&stateForkResponseJson,
|
||||
).Return(
|
||||
nil,
|
||||
nil,
|
||||
).SetArg(
|
||||
2,
|
||||
*testCase.getForkOutput,
|
||||
@@ -329,15 +322,14 @@ func TestCheckDoppelGanger_Nominal(t *testing.T) {
|
||||
}
|
||||
|
||||
if testCase.getHeadersOutput != nil {
|
||||
blockHeadersResponseJson := beacon.GetBlockHeadersResponse{}
|
||||
blockHeadersResponseJson := structs.GetBlockHeadersResponse{}
|
||||
|
||||
jsonRestHandler.EXPECT().Get(
|
||||
ctx,
|
||||
gomock.Any(),
|
||||
headersEndpoint,
|
||||
&blockHeadersResponseJson,
|
||||
).Return(
|
||||
nil,
|
||||
nil,
|
||||
).SetArg(
|
||||
2,
|
||||
*testCase.getHeadersOutput,
|
||||
@@ -346,13 +338,13 @@ func TestCheckDoppelGanger_Nominal(t *testing.T) {
|
||||
|
||||
if testCase.getLivelinessInterfaces != nil {
|
||||
for _, iface := range testCase.getLivelinessInterfaces {
|
||||
livenessResponseJson := validator.GetLivenessResponse{}
|
||||
livenessResponseJson := structs.GetLivenessResponse{}
|
||||
|
||||
marshalledIndexes, err := json.Marshal(iface.inputStringIndexes)
|
||||
require.NoError(t, err)
|
||||
|
||||
jsonRestHandler.EXPECT().Post(
|
||||
ctx,
|
||||
gomock.Any(),
|
||||
iface.inputUrl,
|
||||
nil,
|
||||
bytes.NewBuffer(marshalledIndexes),
|
||||
@@ -362,7 +354,6 @@ func TestCheckDoppelGanger_Nominal(t *testing.T) {
|
||||
*iface.output,
|
||||
).Return(
|
||||
nil,
|
||||
nil,
|
||||
).Times(1)
|
||||
}
|
||||
}
|
||||
@@ -370,8 +361,8 @@ func TestCheckDoppelGanger_Nominal(t *testing.T) {
|
||||
stateValidatorsProvider := mock.NewMockStateValidatorsProvider(ctrl)
|
||||
|
||||
if testCase.getStateValidatorsInterface != nil {
|
||||
stateValidatorsProvider.EXPECT().GetStateValidators(
|
||||
ctx,
|
||||
stateValidatorsProvider.EXPECT().StateValidators(
|
||||
gomock.Any(),
|
||||
testCase.getStateValidatorsInterface.input,
|
||||
nil,
|
||||
nil,
|
||||
@@ -409,23 +400,23 @@ func TestCheckDoppelGanger_Errors(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
standardGetSyncingOutput := &node.SyncStatusResponse{
|
||||
Data: &node.SyncStatusResponseData{
|
||||
standardGetSyncingOutput := &structs.SyncStatusResponse{
|
||||
Data: &structs.SyncStatusResponseData{
|
||||
IsSyncing: false,
|
||||
},
|
||||
}
|
||||
|
||||
standardGetForkOutput := &beacon.GetStateForkResponse{
|
||||
Data: &shared.Fork{
|
||||
standardGetForkOutput := &structs.GetStateForkResponse{
|
||||
Data: &structs.Fork{
|
||||
CurrentVersion: "0x02000000",
|
||||
},
|
||||
}
|
||||
|
||||
standardGetHeadersOutput := &beacon.GetBlockHeadersResponse{
|
||||
Data: []*shared.SignedBeaconBlockHeaderContainer{
|
||||
standardGetHeadersOutput := &structs.GetBlockHeadersResponse{
|
||||
Data: []*structs.SignedBeaconBlockHeaderContainer{
|
||||
{
|
||||
Header: &shared.SignedBeaconBlockHeader{
|
||||
Message: &shared.BeaconBlockHeader{
|
||||
Header: &structs.SignedBeaconBlockHeader{
|
||||
Message: &structs.BeaconBlockHeader{
|
||||
Slot: "1000",
|
||||
},
|
||||
},
|
||||
@@ -435,15 +426,15 @@ func TestCheckDoppelGanger_Errors(t *testing.T) {
|
||||
|
||||
standardGetStateValidatorsInterface := &struct {
|
||||
input []string
|
||||
output *beacon.GetValidatorsResponse
|
||||
output *structs.GetValidatorsResponse
|
||||
err error
|
||||
}{
|
||||
input: []string{stringPubKey},
|
||||
output: &beacon.GetValidatorsResponse{
|
||||
Data: []*beacon.ValidatorContainer{
|
||||
output: &structs.GetValidatorsResponse{
|
||||
Data: []*structs.ValidatorContainer{
|
||||
{
|
||||
Index: "42",
|
||||
Validator: &beacon.Validator{
|
||||
Validator: &structs.Validator{
|
||||
Pubkey: stringPubKey,
|
||||
},
|
||||
},
|
||||
@@ -455,21 +446,21 @@ func TestCheckDoppelGanger_Errors(t *testing.T) {
|
||||
name string
|
||||
expectedErrorMessage string
|
||||
inputValidatorRequests []*ethpb.DoppelGangerRequest_ValidatorRequest
|
||||
getSyncingOutput *node.SyncStatusResponse
|
||||
getSyncingOutput *structs.SyncStatusResponse
|
||||
getSyncingError error
|
||||
getForkOutput *beacon.GetStateForkResponse
|
||||
getForkOutput *structs.GetStateForkResponse
|
||||
getForkError error
|
||||
getHeadersOutput *beacon.GetBlockHeadersResponse
|
||||
getHeadersOutput *structs.GetBlockHeadersResponse
|
||||
getHeadersError error
|
||||
getStateValidatorsInterface *struct {
|
||||
input []string
|
||||
output *beacon.GetValidatorsResponse
|
||||
output *structs.GetValidatorsResponse
|
||||
err error
|
||||
}
|
||||
getLivenessInterfaces []struct {
|
||||
inputUrl string
|
||||
inputStringIndexes []string
|
||||
output *validator.GetLivenessResponse
|
||||
output *structs.GetLivenessResponse
|
||||
err error
|
||||
}
|
||||
}{
|
||||
@@ -489,18 +480,18 @@ func TestCheckDoppelGanger_Errors(t *testing.T) {
|
||||
name: "beacon node not synced",
|
||||
expectedErrorMessage: "beacon node not synced",
|
||||
inputValidatorRequests: standardInputValidatorRequests,
|
||||
getSyncingOutput: &node.SyncStatusResponse{
|
||||
Data: &node.SyncStatusResponseData{
|
||||
getSyncingOutput: &structs.SyncStatusResponse{
|
||||
Data: &structs.SyncStatusResponseData{
|
||||
IsSyncing: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "getFork on error",
|
||||
name: "fork on error",
|
||||
expectedErrorMessage: "failed to get fork",
|
||||
inputValidatorRequests: standardInputValidatorRequests,
|
||||
getSyncingOutput: standardGetSyncingOutput,
|
||||
getForkOutput: &beacon.GetStateForkResponse{},
|
||||
getForkOutput: &structs.GetStateForkResponse{},
|
||||
getForkError: errors.New("custom error"),
|
||||
},
|
||||
{
|
||||
@@ -508,8 +499,8 @@ func TestCheckDoppelGanger_Errors(t *testing.T) {
|
||||
expectedErrorMessage: "failed to decode fork version",
|
||||
inputValidatorRequests: standardInputValidatorRequests,
|
||||
getSyncingOutput: standardGetSyncingOutput,
|
||||
getForkOutput: &beacon.GetStateForkResponse{
|
||||
Data: &shared.Fork{CurrentVersion: "not a version"},
|
||||
getForkOutput: &structs.GetStateForkResponse{
|
||||
Data: &structs.Fork{CurrentVersion: "not a version"},
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -518,7 +509,7 @@ func TestCheckDoppelGanger_Errors(t *testing.T) {
|
||||
inputValidatorRequests: standardInputValidatorRequests,
|
||||
getSyncingOutput: standardGetSyncingOutput,
|
||||
getForkOutput: standardGetForkOutput,
|
||||
getHeadersOutput: &beacon.GetBlockHeadersResponse{},
|
||||
getHeadersOutput: &structs.GetBlockHeadersResponse{},
|
||||
getHeadersError: errors.New("custom error"),
|
||||
},
|
||||
{
|
||||
@@ -527,11 +518,11 @@ func TestCheckDoppelGanger_Errors(t *testing.T) {
|
||||
inputValidatorRequests: standardInputValidatorRequests,
|
||||
getSyncingOutput: standardGetSyncingOutput,
|
||||
getForkOutput: standardGetForkOutput,
|
||||
getHeadersOutput: &beacon.GetBlockHeadersResponse{
|
||||
Data: []*shared.SignedBeaconBlockHeaderContainer{
|
||||
getHeadersOutput: &structs.GetBlockHeadersResponse{
|
||||
Data: []*structs.SignedBeaconBlockHeaderContainer{
|
||||
{
|
||||
Header: &shared.SignedBeaconBlockHeader{
|
||||
Message: &shared.BeaconBlockHeader{
|
||||
Header: &structs.SignedBeaconBlockHeader{
|
||||
Message: &structs.BeaconBlockHeader{
|
||||
Slot: "not a slot",
|
||||
},
|
||||
},
|
||||
@@ -548,7 +539,7 @@ func TestCheckDoppelGanger_Errors(t *testing.T) {
|
||||
getHeadersOutput: standardGetHeadersOutput,
|
||||
getStateValidatorsInterface: &struct {
|
||||
input []string
|
||||
output *beacon.GetValidatorsResponse
|
||||
output *structs.GetValidatorsResponse
|
||||
err error
|
||||
}{
|
||||
input: []string{stringPubKey},
|
||||
@@ -564,11 +555,11 @@ func TestCheckDoppelGanger_Errors(t *testing.T) {
|
||||
getHeadersOutput: standardGetHeadersOutput,
|
||||
getStateValidatorsInterface: &struct {
|
||||
input []string
|
||||
output *beacon.GetValidatorsResponse
|
||||
output *structs.GetValidatorsResponse
|
||||
err error
|
||||
}{
|
||||
input: []string{stringPubKey},
|
||||
output: &beacon.GetValidatorsResponse{Data: []*beacon.ValidatorContainer{nil}},
|
||||
output: &structs.GetValidatorsResponse{Data: []*structs.ValidatorContainer{nil}},
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -580,11 +571,11 @@ func TestCheckDoppelGanger_Errors(t *testing.T) {
|
||||
getHeadersOutput: standardGetHeadersOutput,
|
||||
getStateValidatorsInterface: &struct {
|
||||
input []string
|
||||
output *beacon.GetValidatorsResponse
|
||||
output *structs.GetValidatorsResponse
|
||||
err error
|
||||
}{
|
||||
input: []string{stringPubKey},
|
||||
output: &beacon.GetValidatorsResponse{Data: []*beacon.ValidatorContainer{{Validator: nil}}},
|
||||
output: &structs.GetValidatorsResponse{Data: []*structs.ValidatorContainer{{Validator: nil}}},
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -598,13 +589,13 @@ func TestCheckDoppelGanger_Errors(t *testing.T) {
|
||||
getLivenessInterfaces: []struct {
|
||||
inputUrl string
|
||||
inputStringIndexes []string
|
||||
output *validator.GetLivenessResponse
|
||||
output *structs.GetLivenessResponse
|
||||
err error
|
||||
}{
|
||||
{
|
||||
inputUrl: "/eth/v1/validator/liveness/30",
|
||||
inputStringIndexes: []string{"42"},
|
||||
output: &validator.GetLivenessResponse{},
|
||||
output: &structs.GetLivenessResponse{},
|
||||
err: errors.New("custom error"),
|
||||
},
|
||||
},
|
||||
@@ -620,14 +611,14 @@ func TestCheckDoppelGanger_Errors(t *testing.T) {
|
||||
getLivenessInterfaces: []struct {
|
||||
inputUrl string
|
||||
inputStringIndexes []string
|
||||
output *validator.GetLivenessResponse
|
||||
output *structs.GetLivenessResponse
|
||||
err error
|
||||
}{
|
||||
{
|
||||
inputUrl: "/eth/v1/validator/liveness/30",
|
||||
inputStringIndexes: []string{"42"},
|
||||
output: &validator.GetLivenessResponse{
|
||||
Data: []*validator.Liveness{nil},
|
||||
output: &structs.GetLivenessResponse{
|
||||
Data: []*structs.Liveness{nil},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -643,20 +634,20 @@ func TestCheckDoppelGanger_Errors(t *testing.T) {
|
||||
getLivenessInterfaces: []struct {
|
||||
inputUrl string
|
||||
inputStringIndexes []string
|
||||
output *validator.GetLivenessResponse
|
||||
output *structs.GetLivenessResponse
|
||||
err error
|
||||
}{
|
||||
{
|
||||
inputUrl: "/eth/v1/validator/liveness/30",
|
||||
inputStringIndexes: []string{"42"},
|
||||
output: &validator.GetLivenessResponse{
|
||||
Data: []*validator.Liveness{},
|
||||
output: &structs.GetLivenessResponse{
|
||||
Data: []*structs.Liveness{},
|
||||
},
|
||||
},
|
||||
{
|
||||
inputUrl: "/eth/v1/validator/liveness/31",
|
||||
inputStringIndexes: []string{"42"},
|
||||
output: &validator.GetLivenessResponse{},
|
||||
output: &structs.GetLivenessResponse{},
|
||||
err: errors.New("custom error"),
|
||||
},
|
||||
},
|
||||
@@ -672,21 +663,21 @@ func TestCheckDoppelGanger_Errors(t *testing.T) {
|
||||
getLivenessInterfaces: []struct {
|
||||
inputUrl string
|
||||
inputStringIndexes []string
|
||||
output *validator.GetLivenessResponse
|
||||
output *structs.GetLivenessResponse
|
||||
err error
|
||||
}{
|
||||
{
|
||||
inputUrl: "/eth/v1/validator/liveness/30",
|
||||
inputStringIndexes: []string{"42"},
|
||||
output: &validator.GetLivenessResponse{
|
||||
Data: []*validator.Liveness{},
|
||||
output: &structs.GetLivenessResponse{
|
||||
Data: []*structs.Liveness{},
|
||||
},
|
||||
},
|
||||
{
|
||||
inputUrl: "/eth/v1/validator/liveness/31",
|
||||
inputStringIndexes: []string{"42"},
|
||||
output: &validator.GetLivenessResponse{
|
||||
Data: []*validator.Liveness{},
|
||||
output: &structs.GetLivenessResponse{
|
||||
Data: []*structs.Liveness{},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -702,14 +693,14 @@ func TestCheckDoppelGanger_Errors(t *testing.T) {
|
||||
getLivenessInterfaces: []struct {
|
||||
inputUrl string
|
||||
inputStringIndexes []string
|
||||
output *validator.GetLivenessResponse
|
||||
output *structs.GetLivenessResponse
|
||||
err error
|
||||
}{
|
||||
{
|
||||
inputUrl: "/eth/v1/validator/liveness/30",
|
||||
inputStringIndexes: []string{"42"},
|
||||
output: &validator.GetLivenessResponse{
|
||||
Data: []*validator.Liveness{
|
||||
output: &structs.GetLivenessResponse{
|
||||
Data: []*structs.Liveness{
|
||||
{
|
||||
Index: "42",
|
||||
},
|
||||
@@ -719,8 +710,8 @@ func TestCheckDoppelGanger_Errors(t *testing.T) {
|
||||
{
|
||||
inputUrl: "/eth/v1/validator/liveness/31",
|
||||
inputStringIndexes: []string{"42"},
|
||||
output: &validator.GetLivenessResponse{
|
||||
Data: []*validator.Liveness{},
|
||||
output: &structs.GetLivenessResponse{
|
||||
Data: []*structs.Liveness{},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -734,17 +725,14 @@ func TestCheckDoppelGanger_Errors(t *testing.T) {
|
||||
|
||||
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
if testCase.getSyncingOutput != nil {
|
||||
syncingResponseJson := node.SyncStatusResponse{}
|
||||
syncingResponseJson := structs.SyncStatusResponse{}
|
||||
|
||||
jsonRestHandler.EXPECT().Get(
|
||||
ctx,
|
||||
syncingEnpoint,
|
||||
gomock.Any(),
|
||||
syncingEndpoint,
|
||||
&syncingResponseJson,
|
||||
).Return(
|
||||
nil,
|
||||
testCase.getSyncingError,
|
||||
).SetArg(
|
||||
2,
|
||||
@@ -753,14 +741,13 @@ func TestCheckDoppelGanger_Errors(t *testing.T) {
|
||||
}
|
||||
|
||||
if testCase.getForkOutput != nil {
|
||||
stateForkResponseJson := beacon.GetStateForkResponse{}
|
||||
stateForkResponseJson := structs.GetStateForkResponse{}
|
||||
|
||||
jsonRestHandler.EXPECT().Get(
|
||||
ctx,
|
||||
gomock.Any(),
|
||||
forkEndpoint,
|
||||
&stateForkResponseJson,
|
||||
).Return(
|
||||
nil,
|
||||
testCase.getForkError,
|
||||
).SetArg(
|
||||
2,
|
||||
@@ -769,14 +756,13 @@ func TestCheckDoppelGanger_Errors(t *testing.T) {
|
||||
}
|
||||
|
||||
if testCase.getHeadersOutput != nil {
|
||||
blockHeadersResponseJson := beacon.GetBlockHeadersResponse{}
|
||||
blockHeadersResponseJson := structs.GetBlockHeadersResponse{}
|
||||
|
||||
jsonRestHandler.EXPECT().Get(
|
||||
ctx,
|
||||
gomock.Any(),
|
||||
headersEndpoint,
|
||||
&blockHeadersResponseJson,
|
||||
).Return(
|
||||
nil,
|
||||
testCase.getHeadersError,
|
||||
).SetArg(
|
||||
2,
|
||||
@@ -787,8 +773,8 @@ func TestCheckDoppelGanger_Errors(t *testing.T) {
|
||||
stateValidatorsProvider := mock.NewMockStateValidatorsProvider(ctrl)
|
||||
|
||||
if testCase.getStateValidatorsInterface != nil {
|
||||
stateValidatorsProvider.EXPECT().GetStateValidators(
|
||||
ctx,
|
||||
stateValidatorsProvider.EXPECT().StateValidators(
|
||||
gomock.Any(),
|
||||
testCase.getStateValidatorsInterface.input,
|
||||
nil,
|
||||
nil,
|
||||
@@ -800,13 +786,13 @@ func TestCheckDoppelGanger_Errors(t *testing.T) {
|
||||
|
||||
if testCase.getLivenessInterfaces != nil {
|
||||
for _, iface := range testCase.getLivenessInterfaces {
|
||||
livenessResponseJson := validator.GetLivenessResponse{}
|
||||
livenessResponseJson := structs.GetLivenessResponse{}
|
||||
|
||||
marshalledIndexes, err := json.Marshal(iface.inputStringIndexes)
|
||||
require.NoError(t, err)
|
||||
|
||||
jsonRestHandler.EXPECT().Post(
|
||||
ctx,
|
||||
gomock.Any(),
|
||||
iface.inputUrl,
|
||||
nil,
|
||||
bytes.NewBuffer(marshalledIndexes),
|
||||
@@ -815,7 +801,6 @@ func TestCheckDoppelGanger_Errors(t *testing.T) {
|
||||
4,
|
||||
*iface.output,
|
||||
).Return(
|
||||
nil,
|
||||
iface.err,
|
||||
).Times(1)
|
||||
}
|
||||
228
api/client/beacon/validator_api/duties.go
Normal file
228
api/client/beacon/validator_api/duties.go
Normal file
@@ -0,0 +1,228 @@
|
||||
package validator_api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strconv"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/client/beacon"
|
||||
"github.com/prysmaticlabs/prysm/v5/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/validator"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
"golang.org/x/sync/errgroup"
|
||||
)
|
||||
|
||||
func (c *beaconApiValidatorClient) duties(ctx context.Context, in *ethpb.DutiesRequest) (*ethpb.ValidatorDutiesContainer, error) {
|
||||
vals, err := c.validatorsForDuties(ctx, in.PublicKeys)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to get validators for duties")
|
||||
}
|
||||
|
||||
// Sync committees are an Altair feature
|
||||
fetchSyncDuties := in.Epoch >= params.BeaconConfig().AltairForkEpoch
|
||||
|
||||
errCh := make(chan error, 1)
|
||||
|
||||
var currentEpochDuties []*ethpb.ValidatorDuty
|
||||
go func() {
|
||||
currentEpochDuties, err = c.dutiesForEpoch(ctx, in.Epoch, vals, fetchSyncDuties)
|
||||
if err != nil {
|
||||
errCh <- errors.Wrapf(err, "failed to get duties for current epoch `%d`", in.Epoch)
|
||||
return
|
||||
}
|
||||
errCh <- nil
|
||||
}()
|
||||
|
||||
nextEpochDuties, err := c.dutiesForEpoch(ctx, in.Epoch+1, vals, fetchSyncDuties)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to get duties for next epoch `%d`", in.Epoch+1)
|
||||
}
|
||||
|
||||
if err = <-errCh; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return ðpb.ValidatorDutiesContainer{
|
||||
CurrentEpochDuties: currentEpochDuties,
|
||||
NextEpochDuties: nextEpochDuties,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *beaconApiValidatorClient) dutiesForEpoch(
|
||||
ctx context.Context,
|
||||
epoch primitives.Epoch,
|
||||
vals []beacon.ValidatorForDuty,
|
||||
fetchSyncDuties bool,
|
||||
) ([]*ethpb.ValidatorDuty, error) {
|
||||
indices := make([]primitives.ValidatorIndex, len(vals))
|
||||
for i, v := range vals {
|
||||
indices[i] = v.Index
|
||||
}
|
||||
|
||||
// Below variables MUST NOT be used in the main function before wg.Wait().
|
||||
// This is because they are populated in goroutines and wg.Wait()
|
||||
// will return only once all goroutines finish their execution.
|
||||
|
||||
// Mapping from a validator index to its attesting committee's index and slot
|
||||
attesterDutiesMapping := make(map[primitives.ValidatorIndex]beacon.AttesterDuty)
|
||||
// Set containing all validator indices that are part of a sync committee for this epoch
|
||||
syncDutiesMapping := make(map[primitives.ValidatorIndex]bool)
|
||||
// Mapping from a validator index to its proposal slot
|
||||
proposerDutySlots := make(map[primitives.ValidatorIndex][]primitives.Slot)
|
||||
|
||||
var wg errgroup.Group
|
||||
|
||||
wg.Go(func() error {
|
||||
attesterDuties, err := c.dutiesProvider.AttesterDuties(ctx, epoch, indices)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to get attester duties for epoch `%d`", epoch)
|
||||
}
|
||||
|
||||
for _, duty := range attesterDuties {
|
||||
validatorIndex, err := strconv.ParseUint(duty.ValidatorIndex, 10, 64)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to parse attester validator index `%s`", duty.ValidatorIndex)
|
||||
}
|
||||
slot, err := strconv.ParseUint(duty.Slot, 10, 64)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to parse attester slot `%s`", duty.Slot)
|
||||
}
|
||||
committeeIndex, err := strconv.ParseUint(duty.CommitteeIndex, 10, 64)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to parse attester committee index `%s`", duty.CommitteeIndex)
|
||||
}
|
||||
committeeLength, err := strconv.ParseUint(duty.CommitteeLength, 10, 64)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to parse attester committee length `%s`", duty.CommitteeLength)
|
||||
}
|
||||
validatorCommitteeIndex, err := strconv.ParseUint(duty.ValidatorCommitteeIndex, 10, 64)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to parse attester validator committee index `%s`", duty.ValidatorCommitteeIndex)
|
||||
}
|
||||
committeesAtSlot, err := strconv.ParseUint(duty.CommitteesAtSlot, 10, 64)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to parse attester committees at slot `%s`", duty.CommitteesAtSlot)
|
||||
}
|
||||
attesterDutiesMapping[primitives.ValidatorIndex(validatorIndex)] = beacon.AttesterDuty{
|
||||
Slot: primitives.Slot(slot),
|
||||
CommitteeIndex: primitives.CommitteeIndex(committeeIndex),
|
||||
CommitteeLength: committeeLength,
|
||||
ValidatorCommitteeIndex: validatorCommitteeIndex,
|
||||
CommitteesAtSlot: committeesAtSlot,
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
if fetchSyncDuties {
|
||||
wg.Go(func() error {
|
||||
syncDuties, err := c.dutiesProvider.SyncDuties(ctx, epoch, indices)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to get sync duties for epoch `%d`", epoch)
|
||||
}
|
||||
for _, syncDuty := range syncDuties {
|
||||
validatorIndex, err := strconv.ParseUint(syncDuty.ValidatorIndex, 10, 64)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to parse sync validator index `%s`", syncDuty.ValidatorIndex)
|
||||
}
|
||||
syncDutiesMapping[primitives.ValidatorIndex(validatorIndex)] = true
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
wg.Go(func() error {
|
||||
proposerDuties, err := c.dutiesProvider.ProposerDuties(ctx, epoch)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to get proposer duties for epoch `%d`", epoch)
|
||||
}
|
||||
|
||||
for _, proposerDuty := range proposerDuties {
|
||||
validatorIndex, err := strconv.ParseUint(proposerDuty.ValidatorIndex, 10, 64)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to parse proposer validator index `%s`", proposerDuty.ValidatorIndex)
|
||||
}
|
||||
slot, err := strconv.ParseUint(proposerDuty.Slot, 10, 64)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to parse proposer slot `%s`", proposerDuty.Slot)
|
||||
}
|
||||
proposerDutySlots[primitives.ValidatorIndex(validatorIndex)] =
|
||||
append(proposerDutySlots[primitives.ValidatorIndex(validatorIndex)], primitives.Slot(slot))
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
if err := wg.Wait(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
duties := make([]*ethpb.ValidatorDuty, len(vals))
|
||||
for i, v := range vals {
|
||||
att, ok := attesterDutiesMapping[v.Index]
|
||||
if !ok {
|
||||
log.Debugf("failed to find attester duty for validator `%d`", v.Index)
|
||||
}
|
||||
|
||||
duties[i] = ðpb.ValidatorDuty{
|
||||
ValidatorCommitteeIndex: att.ValidatorCommitteeIndex,
|
||||
CommitteeLength: att.CommitteeLength,
|
||||
CommitteeIndex: att.CommitteeIndex,
|
||||
AttesterSlot: att.Slot,
|
||||
CommitteesAtSlot: att.CommitteesAtSlot,
|
||||
ProposerSlots: proposerDutySlots[v.Index],
|
||||
PublicKey: v.Pubkey,
|
||||
Status: v.Status,
|
||||
ValidatorIndex: v.Index,
|
||||
IsSyncCommittee: syncDutiesMapping[v.Index],
|
||||
}
|
||||
}
|
||||
|
||||
return duties, nil
|
||||
}
|
||||
|
||||
func (c *beaconApiValidatorClient) validatorsForDuties(ctx context.Context, pubkeys [][]byte) ([]beacon.ValidatorForDuty, error) {
|
||||
vals := make([]beacon.ValidatorForDuty, 0, len(pubkeys))
|
||||
stringPubkeysToPubkeys := make(map[string][]byte, len(pubkeys))
|
||||
stringPubkeys := make([]string, len(pubkeys))
|
||||
|
||||
for i, pk := range pubkeys {
|
||||
stringPk := hexutil.Encode(pk)
|
||||
stringPubkeysToPubkeys[stringPk] = pk
|
||||
stringPubkeys[i] = stringPk
|
||||
}
|
||||
|
||||
statusesWithDuties := []string{validator.ActiveOngoing.String(), validator.ActiveExiting.String()}
|
||||
stateValidatorsResponse, err := c.stateValidatorsProvider.StateValidators(ctx, stringPubkeys, nil, statusesWithDuties)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to get state validators")
|
||||
}
|
||||
|
||||
for _, validatorContainer := range stateValidatorsResponse.Data {
|
||||
val := beacon.ValidatorForDuty{}
|
||||
|
||||
validatorIndex, err := strconv.ParseUint(validatorContainer.Index, 10, 64)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to parse validator index %s", validatorContainer.Index)
|
||||
}
|
||||
val.Index = primitives.ValidatorIndex(validatorIndex)
|
||||
|
||||
stringPubkey := validatorContainer.Validator.Pubkey
|
||||
pubkey, ok := stringPubkeysToPubkeys[stringPubkey]
|
||||
if !ok {
|
||||
return nil, errors.Wrapf(err, "returned public key %s not requested", stringPubkey)
|
||||
}
|
||||
val.Pubkey = pubkey
|
||||
|
||||
status, ok := beaconAPITogRPCValidatorStatus[validatorContainer.Status]
|
||||
if !ok {
|
||||
return nil, errors.New("invalid validator status " + validatorContainer.Status)
|
||||
}
|
||||
val.Status = status
|
||||
|
||||
vals = append(vals, val)
|
||||
}
|
||||
|
||||
return vals, nil
|
||||
}
|
||||
884
api/client/beacon/validator_api/duties_test.go
Normal file
884
api/client/beacon/validator_api/duties_test.go
Normal file
@@ -0,0 +1,884 @@
|
||||
package validator_api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"testing"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/client/beacon"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/client/beacon/mock"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/server/structs"
|
||||
"github.com/prysmaticlabs/prysm/v5/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v5/testing/assert"
|
||||
"github.com/prysmaticlabs/prysm/v5/testing/require"
|
||||
"go.uber.org/mock/gomock"
|
||||
)
|
||||
|
||||
func TestGetDutiesForEpoch_Error(t *testing.T) {
|
||||
const epoch = primitives.Epoch(1)
|
||||
pubkeys := [][]byte{{1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}, {9}, {10}, {11}, {12}}
|
||||
validatorIndices := []primitives.ValidatorIndex{13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24}
|
||||
committeeIndices := []primitives.CommitteeIndex{25, 26, 27}
|
||||
committeeSlots := []primitives.Slot{28, 29, 30}
|
||||
proposerSlots := []primitives.Slot{31, 32, 33, 34, 35, 36, 37, 38}
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
expectedError string
|
||||
generateAttesterDuties func() []*structs.AttesterDuty
|
||||
fetchAttesterDutiesError error
|
||||
generateProposerDuties func() []*structs.ProposerDuty
|
||||
fetchProposerDutiesError error
|
||||
generateSyncDuties func() []*structs.SyncCommitteeDuty
|
||||
fetchSyncDutiesError error
|
||||
}{
|
||||
{
|
||||
name: "get attester duties failed",
|
||||
expectedError: "failed to get attester duties for epoch `1`: foo error",
|
||||
fetchAttesterDutiesError: errors.New("foo error"),
|
||||
},
|
||||
{
|
||||
name: "get proposer duties failed",
|
||||
expectedError: "failed to get proposer duties for epoch `1`: foo error",
|
||||
fetchProposerDutiesError: errors.New("foo error"),
|
||||
},
|
||||
{
|
||||
name: "get sync duties failed",
|
||||
expectedError: "failed to get sync duties for epoch `1`: foo error",
|
||||
fetchSyncDutiesError: errors.New("foo error"),
|
||||
},
|
||||
{
|
||||
name: "bad attester validator index",
|
||||
expectedError: "failed to parse attester validator index `foo`",
|
||||
generateAttesterDuties: func() []*structs.AttesterDuty {
|
||||
attesterDuties := generateValidAttesterDuties(pubkeys, validatorIndices, committeeIndices, committeeSlots)
|
||||
attesterDuties[0].ValidatorIndex = "foo"
|
||||
return attesterDuties
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "bad attester slot",
|
||||
expectedError: "failed to parse attester slot `foo`",
|
||||
generateAttesterDuties: func() []*structs.AttesterDuty {
|
||||
attesterDuties := generateValidAttesterDuties(pubkeys, validatorIndices, committeeIndices, committeeSlots)
|
||||
attesterDuties[0].Slot = "foo"
|
||||
return attesterDuties
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "bad attester committee index",
|
||||
expectedError: "failed to parse attester committee index `foo`",
|
||||
generateAttesterDuties: func() []*structs.AttesterDuty {
|
||||
attesterDuties := generateValidAttesterDuties(pubkeys, validatorIndices, committeeIndices, committeeSlots)
|
||||
attesterDuties[0].CommitteeIndex = "foo"
|
||||
return attesterDuties
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "bad proposer validator index",
|
||||
expectedError: "failed to parse proposer validator index `foo`",
|
||||
generateProposerDuties: func() []*structs.ProposerDuty {
|
||||
proposerDuties := generateValidProposerDuties(pubkeys, validatorIndices, proposerSlots)
|
||||
proposerDuties[0].ValidatorIndex = "foo"
|
||||
return proposerDuties
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "bad proposer slot",
|
||||
expectedError: "failed to parse proposer slot `foo`",
|
||||
generateProposerDuties: func() []*structs.ProposerDuty {
|
||||
proposerDuties := generateValidProposerDuties(pubkeys, validatorIndices, proposerSlots)
|
||||
proposerDuties[0].Slot = "foo"
|
||||
return proposerDuties
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "bad sync validator index",
|
||||
expectedError: "failed to parse sync validator index `foo`",
|
||||
generateSyncDuties: func() []*structs.SyncCommitteeDuty {
|
||||
syncDuties := generateValidSyncDuties(pubkeys, validatorIndices)
|
||||
syncDuties[0].ValidatorIndex = "foo"
|
||||
return syncDuties
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, testCase := range testCases {
|
||||
t.Run(testCase.name, func(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
var attesterDuties []*structs.AttesterDuty
|
||||
if testCase.generateAttesterDuties == nil {
|
||||
attesterDuties = generateValidAttesterDuties(pubkeys, validatorIndices, committeeIndices, committeeSlots)
|
||||
} else {
|
||||
attesterDuties = testCase.generateAttesterDuties()
|
||||
}
|
||||
|
||||
var proposerDuties []*structs.ProposerDuty
|
||||
if testCase.generateProposerDuties == nil {
|
||||
proposerDuties = generateValidProposerDuties(pubkeys, validatorIndices, proposerSlots)
|
||||
} else {
|
||||
proposerDuties = testCase.generateProposerDuties()
|
||||
}
|
||||
|
||||
var syncDuties []*structs.SyncCommitteeDuty
|
||||
if testCase.generateSyncDuties == nil {
|
||||
syncDuties = generateValidSyncDuties(pubkeys, validatorIndices)
|
||||
} else {
|
||||
syncDuties = testCase.generateSyncDuties()
|
||||
}
|
||||
|
||||
dutiesProvider := mock.NewMockdutiesProvider(ctrl)
|
||||
dutiesProvider.EXPECT().AttesterDuties(
|
||||
ctx,
|
||||
epoch,
|
||||
gomock.Any(),
|
||||
).Return(
|
||||
attesterDuties,
|
||||
testCase.fetchAttesterDutiesError,
|
||||
).AnyTimes()
|
||||
|
||||
dutiesProvider.EXPECT().ProposerDuties(
|
||||
ctx,
|
||||
epoch,
|
||||
).Return(
|
||||
proposerDuties,
|
||||
testCase.fetchProposerDutiesError,
|
||||
).AnyTimes()
|
||||
|
||||
dutiesProvider.EXPECT().SyncDuties(
|
||||
ctx,
|
||||
epoch,
|
||||
gomock.Any(),
|
||||
).Return(
|
||||
syncDuties,
|
||||
testCase.fetchSyncDutiesError,
|
||||
).AnyTimes()
|
||||
|
||||
vals := make([]beacon.ValidatorForDuty, len(pubkeys))
|
||||
for i := 0; i < len(pubkeys); i++ {
|
||||
vals[i] = beacon.ValidatorForDuty{
|
||||
Pubkey: pubkeys[i],
|
||||
Index: validatorIndices[i],
|
||||
Status: ethpb.ValidatorStatus_ACTIVE,
|
||||
}
|
||||
}
|
||||
|
||||
validatorClient := &beaconApiValidatorClient{dutiesProvider: dutiesProvider}
|
||||
_, err := validatorClient.dutiesForEpoch(
|
||||
ctx,
|
||||
epoch,
|
||||
vals,
|
||||
true,
|
||||
)
|
||||
assert.ErrorContains(t, testCase.expectedError, err)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetDutiesForEpoch_Valid(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
fetchSyncDuties bool
|
||||
}{
|
||||
{
|
||||
name: "fetch attester and proposer duties",
|
||||
fetchSyncDuties: false,
|
||||
},
|
||||
{
|
||||
name: "fetch attester and sync and proposer duties",
|
||||
fetchSyncDuties: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, testCase := range testCases {
|
||||
t.Run(testCase.name, func(t *testing.T) {
|
||||
const epoch = primitives.Epoch(1)
|
||||
pubkeys := [][]byte{{1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}, {9}, {10}, {11}, {12}}
|
||||
validatorIndices := []primitives.ValidatorIndex{13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24}
|
||||
committeeIndices := []primitives.CommitteeIndex{25, 26, 27}
|
||||
committeeSlots := []primitives.Slot{28, 29, 30}
|
||||
proposerSlots := []primitives.Slot{31, 32, 33, 34, 35, 36, 37, 38}
|
||||
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
dutiesProvider := mock.NewMockdutiesProvider(ctrl)
|
||||
|
||||
dutiesProvider.EXPECT().AttesterDuties(
|
||||
ctx,
|
||||
epoch,
|
||||
validatorIndices,
|
||||
).Return(
|
||||
generateValidAttesterDuties(pubkeys, validatorIndices, committeeIndices, committeeSlots),
|
||||
nil,
|
||||
).Times(1)
|
||||
|
||||
dutiesProvider.EXPECT().ProposerDuties(
|
||||
ctx,
|
||||
epoch,
|
||||
).Return(
|
||||
generateValidProposerDuties(pubkeys, validatorIndices, proposerSlots),
|
||||
nil,
|
||||
).Times(1)
|
||||
|
||||
if testCase.fetchSyncDuties {
|
||||
dutiesProvider.EXPECT().SyncDuties(
|
||||
ctx,
|
||||
epoch,
|
||||
validatorIndices,
|
||||
).Return(
|
||||
generateValidSyncDuties(pubkeys, validatorIndices),
|
||||
nil,
|
||||
).Times(1)
|
||||
}
|
||||
|
||||
var expectedProposerSlots1 []primitives.Slot
|
||||
var expectedProposerSlots2 []primitives.Slot
|
||||
var expectedProposerSlots3 []primitives.Slot
|
||||
var expectedProposerSlots4 []primitives.Slot
|
||||
|
||||
expectedProposerSlots1 = []primitives.Slot{
|
||||
proposerSlots[0],
|
||||
proposerSlots[1],
|
||||
}
|
||||
|
||||
expectedProposerSlots2 = []primitives.Slot{
|
||||
proposerSlots[2],
|
||||
proposerSlots[3],
|
||||
}
|
||||
|
||||
expectedProposerSlots3 = []primitives.Slot{
|
||||
proposerSlots[4],
|
||||
proposerSlots[5],
|
||||
}
|
||||
|
||||
expectedProposerSlots4 = []primitives.Slot{
|
||||
proposerSlots[6],
|
||||
proposerSlots[7],
|
||||
}
|
||||
|
||||
expectedDuties := []*ethpb.DutiesResponse_Duty{
|
||||
{
|
||||
Committee: []primitives.ValidatorIndex{
|
||||
validatorIndices[0],
|
||||
validatorIndices[1],
|
||||
},
|
||||
CommitteeIndex: committeeIndices[0],
|
||||
AttesterSlot: committeeSlots[0],
|
||||
PublicKey: pubkeys[0],
|
||||
Status: ethpb.ValidatorStatus_ACTIVE,
|
||||
ValidatorIndex: validatorIndices[0],
|
||||
CommitteesAtSlot: 1,
|
||||
},
|
||||
{
|
||||
Committee: []primitives.ValidatorIndex{
|
||||
validatorIndices[0],
|
||||
validatorIndices[1],
|
||||
},
|
||||
CommitteeIndex: committeeIndices[0],
|
||||
AttesterSlot: committeeSlots[0],
|
||||
PublicKey: pubkeys[1],
|
||||
Status: ethpb.ValidatorStatus_ACTIVE,
|
||||
ValidatorIndex: validatorIndices[1],
|
||||
CommitteesAtSlot: 1,
|
||||
},
|
||||
{
|
||||
Committee: []primitives.ValidatorIndex{
|
||||
validatorIndices[2],
|
||||
validatorIndices[3],
|
||||
},
|
||||
CommitteeIndex: committeeIndices[1],
|
||||
AttesterSlot: committeeSlots[1],
|
||||
PublicKey: pubkeys[2],
|
||||
Status: ethpb.ValidatorStatus_ACTIVE,
|
||||
ValidatorIndex: validatorIndices[2],
|
||||
CommitteesAtSlot: 1,
|
||||
},
|
||||
{
|
||||
Committee: []primitives.ValidatorIndex{
|
||||
validatorIndices[2],
|
||||
validatorIndices[3],
|
||||
},
|
||||
CommitteeIndex: committeeIndices[1],
|
||||
AttesterSlot: committeeSlots[1],
|
||||
PublicKey: pubkeys[3],
|
||||
Status: ethpb.ValidatorStatus_ACTIVE,
|
||||
ValidatorIndex: validatorIndices[3],
|
||||
CommitteesAtSlot: 1,
|
||||
},
|
||||
{
|
||||
Committee: []primitives.ValidatorIndex{
|
||||
validatorIndices[4],
|
||||
validatorIndices[5],
|
||||
},
|
||||
CommitteeIndex: committeeIndices[2],
|
||||
AttesterSlot: committeeSlots[2],
|
||||
PublicKey: pubkeys[4],
|
||||
Status: ethpb.ValidatorStatus_ACTIVE,
|
||||
ValidatorIndex: validatorIndices[4],
|
||||
ProposerSlots: expectedProposerSlots1,
|
||||
CommitteesAtSlot: 1,
|
||||
},
|
||||
{
|
||||
Committee: []primitives.ValidatorIndex{
|
||||
validatorIndices[4],
|
||||
validatorIndices[5],
|
||||
},
|
||||
CommitteeIndex: committeeIndices[2],
|
||||
AttesterSlot: committeeSlots[2],
|
||||
PublicKey: pubkeys[5],
|
||||
Status: ethpb.ValidatorStatus_ACTIVE,
|
||||
ValidatorIndex: validatorIndices[5],
|
||||
ProposerSlots: expectedProposerSlots2,
|
||||
IsSyncCommittee: testCase.fetchSyncDuties,
|
||||
CommitteesAtSlot: 1,
|
||||
},
|
||||
{
|
||||
PublicKey: pubkeys[6],
|
||||
Status: ethpb.ValidatorStatus_ACTIVE,
|
||||
ValidatorIndex: validatorIndices[6],
|
||||
ProposerSlots: expectedProposerSlots3,
|
||||
IsSyncCommittee: testCase.fetchSyncDuties,
|
||||
},
|
||||
{
|
||||
PublicKey: pubkeys[7],
|
||||
Status: ethpb.ValidatorStatus_ACTIVE,
|
||||
ValidatorIndex: validatorIndices[7],
|
||||
ProposerSlots: expectedProposerSlots4,
|
||||
IsSyncCommittee: testCase.fetchSyncDuties,
|
||||
},
|
||||
{
|
||||
PublicKey: pubkeys[8],
|
||||
Status: ethpb.ValidatorStatus_ACTIVE,
|
||||
ValidatorIndex: validatorIndices[8],
|
||||
IsSyncCommittee: testCase.fetchSyncDuties,
|
||||
},
|
||||
{
|
||||
PublicKey: pubkeys[9],
|
||||
Status: ethpb.ValidatorStatus_ACTIVE,
|
||||
ValidatorIndex: validatorIndices[9],
|
||||
IsSyncCommittee: testCase.fetchSyncDuties,
|
||||
},
|
||||
{
|
||||
PublicKey: pubkeys[10],
|
||||
Status: ethpb.ValidatorStatus_ACTIVE,
|
||||
ValidatorIndex: validatorIndices[10],
|
||||
},
|
||||
{
|
||||
PublicKey: pubkeys[11],
|
||||
Status: ethpb.ValidatorStatus_ACTIVE,
|
||||
ValidatorIndex: validatorIndices[11],
|
||||
},
|
||||
}
|
||||
|
||||
validatorClient := &beaconApiValidatorClient{dutiesProvider: dutiesProvider}
|
||||
vals := make([]beacon.ValidatorForDuty, len(pubkeys))
|
||||
for i := 0; i < len(pubkeys); i++ {
|
||||
vals[i] = beacon.ValidatorForDuty{
|
||||
Pubkey: pubkeys[i],
|
||||
Index: validatorIndices[i],
|
||||
Status: ethpb.ValidatorStatus_ACTIVE,
|
||||
}
|
||||
}
|
||||
duties, err := validatorClient.dutiesForEpoch(
|
||||
ctx,
|
||||
epoch,
|
||||
vals,
|
||||
testCase.fetchSyncDuties,
|
||||
)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, len(expectedDuties), len(duties))
|
||||
for i, duty := range expectedDuties {
|
||||
assert.Equal(t, duty.CommitteeIndex, duties[i].CommitteeIndex)
|
||||
assert.DeepEqual(t, duty.ProposerSlots, duties[i].ProposerSlots)
|
||||
assert.Equal(t, duty.ValidatorIndex, duties[i].ValidatorIndex)
|
||||
assert.Equal(t, duty.IsSyncCommittee, duties[i].IsSyncCommittee)
|
||||
assert.Equal(t, duty.Status, duties[i].Status)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetDuties_Valid(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
epoch primitives.Epoch
|
||||
}{
|
||||
{
|
||||
name: "genesis epoch",
|
||||
epoch: params.BeaconConfig().GenesisEpoch,
|
||||
},
|
||||
{
|
||||
name: "altair epoch",
|
||||
epoch: params.BeaconConfig().AltairForkEpoch,
|
||||
},
|
||||
}
|
||||
|
||||
for _, testCase := range testCases {
|
||||
t.Run(testCase.name, func(t *testing.T) {
|
||||
valCount := 12
|
||||
pubkeys := make([][]byte, valCount)
|
||||
validatorIndices := make([]primitives.ValidatorIndex, valCount)
|
||||
vals := make([]beacon.ValidatorForDuty, valCount)
|
||||
for i := 0; i < valCount; i++ {
|
||||
pubkeys[i] = []byte(strconv.Itoa(i))
|
||||
validatorIndices[i] = primitives.ValidatorIndex(i)
|
||||
vals[i] = beacon.ValidatorForDuty{
|
||||
Pubkey: pubkeys[i],
|
||||
Index: validatorIndices[i],
|
||||
Status: ethpb.ValidatorStatus_ACTIVE,
|
||||
}
|
||||
}
|
||||
|
||||
committeeIndices := []primitives.CommitteeIndex{25, 26, 27}
|
||||
committeeSlots := []primitives.Slot{28, 29, 30}
|
||||
proposerSlots := []primitives.Slot{31, 32, 33, 34, 35, 36, 37, 38}
|
||||
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
dutiesProvider := mock.NewMockdutiesProvider(ctrl)
|
||||
|
||||
dutiesProvider.EXPECT().AttesterDuties(
|
||||
ctx,
|
||||
testCase.epoch,
|
||||
validatorIndices,
|
||||
).Return(
|
||||
generateValidAttesterDuties(pubkeys, validatorIndices, committeeIndices, committeeSlots),
|
||||
nil,
|
||||
).Times(2)
|
||||
|
||||
dutiesProvider.EXPECT().ProposerDuties(
|
||||
ctx,
|
||||
testCase.epoch,
|
||||
).Return(
|
||||
generateValidProposerDuties(pubkeys, validatorIndices, proposerSlots),
|
||||
nil,
|
||||
).Times(2)
|
||||
|
||||
fetchSyncDuties := testCase.epoch >= params.BeaconConfig().AltairForkEpoch
|
||||
if fetchSyncDuties {
|
||||
dutiesProvider.EXPECT().SyncDuties(
|
||||
ctx,
|
||||
testCase.epoch,
|
||||
validatorIndices,
|
||||
).Return(
|
||||
generateValidSyncDuties(pubkeys, validatorIndices),
|
||||
nil,
|
||||
).Times(2)
|
||||
}
|
||||
|
||||
dutiesProvider.EXPECT().AttesterDuties(
|
||||
ctx,
|
||||
testCase.epoch+1,
|
||||
validatorIndices,
|
||||
).Return(
|
||||
reverseSlice(generateValidAttesterDuties(pubkeys, validatorIndices, committeeIndices, committeeSlots)),
|
||||
nil,
|
||||
).Times(2)
|
||||
|
||||
dutiesProvider.EXPECT().ProposerDuties(
|
||||
ctx,
|
||||
testCase.epoch+1,
|
||||
).Return(
|
||||
generateValidProposerDuties(pubkeys, validatorIndices, proposerSlots),
|
||||
nil,
|
||||
).Times(2)
|
||||
|
||||
if fetchSyncDuties {
|
||||
dutiesProvider.EXPECT().SyncDuties(
|
||||
ctx,
|
||||
testCase.epoch+1,
|
||||
validatorIndices,
|
||||
).Return(
|
||||
reverseSlice(generateValidSyncDuties(pubkeys, validatorIndices)),
|
||||
nil,
|
||||
).Times(2)
|
||||
}
|
||||
|
||||
stateValidatorsProvider := mock.NewMockStateValidatorsProvider(ctrl)
|
||||
stateValidatorsProvider.EXPECT().StateValidators(
|
||||
gomock.Any(),
|
||||
gomock.Any(),
|
||||
gomock.Any(),
|
||||
gomock.Any(),
|
||||
).Return(
|
||||
&structs.GetValidatorsResponse{
|
||||
Data: []*structs.ValidatorContainer{
|
||||
{
|
||||
Index: strconv.FormatUint(uint64(validatorIndices[0]), 10),
|
||||
Status: "active_ongoing",
|
||||
Validator: &structs.Validator{
|
||||
Pubkey: hexutil.Encode(pubkeys[0]),
|
||||
ActivationEpoch: strconv.FormatUint(uint64(testCase.epoch), 10),
|
||||
},
|
||||
},
|
||||
{
|
||||
Index: strconv.FormatUint(uint64(validatorIndices[1]), 10),
|
||||
Status: "active_ongoing",
|
||||
Validator: &structs.Validator{
|
||||
Pubkey: hexutil.Encode(pubkeys[1]),
|
||||
ActivationEpoch: strconv.FormatUint(uint64(testCase.epoch), 10),
|
||||
},
|
||||
},
|
||||
{
|
||||
Index: strconv.FormatUint(uint64(validatorIndices[2]), 10),
|
||||
Status: "active_ongoing",
|
||||
Validator: &structs.Validator{
|
||||
Pubkey: hexutil.Encode(pubkeys[2]),
|
||||
ActivationEpoch: strconv.FormatUint(uint64(testCase.epoch), 10),
|
||||
},
|
||||
},
|
||||
{
|
||||
Index: strconv.FormatUint(uint64(validatorIndices[3]), 10),
|
||||
Status: "active_ongoing",
|
||||
Validator: &structs.Validator{
|
||||
Pubkey: hexutil.Encode(pubkeys[3]),
|
||||
ActivationEpoch: strconv.FormatUint(uint64(testCase.epoch), 10),
|
||||
},
|
||||
},
|
||||
{
|
||||
Index: strconv.FormatUint(uint64(validatorIndices[4]), 10),
|
||||
Status: "active_ongoing",
|
||||
Validator: &structs.Validator{
|
||||
Pubkey: hexutil.Encode(pubkeys[4]),
|
||||
ActivationEpoch: strconv.FormatUint(uint64(testCase.epoch), 10),
|
||||
},
|
||||
},
|
||||
{
|
||||
Index: strconv.FormatUint(uint64(validatorIndices[5]), 10),
|
||||
Status: "active_ongoing",
|
||||
Validator: &structs.Validator{
|
||||
Pubkey: hexutil.Encode(pubkeys[5]),
|
||||
ActivationEpoch: strconv.FormatUint(uint64(testCase.epoch), 10),
|
||||
},
|
||||
},
|
||||
{
|
||||
Index: strconv.FormatUint(uint64(validatorIndices[6]), 10),
|
||||
Status: "active_ongoing",
|
||||
Validator: &structs.Validator{
|
||||
Pubkey: hexutil.Encode(pubkeys[6]),
|
||||
ActivationEpoch: strconv.FormatUint(uint64(testCase.epoch), 10),
|
||||
},
|
||||
},
|
||||
{
|
||||
Index: strconv.FormatUint(uint64(validatorIndices[7]), 10),
|
||||
Status: "active_ongoing",
|
||||
Validator: &structs.Validator{
|
||||
Pubkey: hexutil.Encode(pubkeys[7]),
|
||||
ActivationEpoch: strconv.FormatUint(uint64(testCase.epoch), 10),
|
||||
},
|
||||
},
|
||||
{
|
||||
Index: strconv.FormatUint(uint64(validatorIndices[8]), 10),
|
||||
Status: "active_ongoing",
|
||||
Validator: &structs.Validator{
|
||||
Pubkey: hexutil.Encode(pubkeys[8]),
|
||||
ActivationEpoch: strconv.FormatUint(uint64(testCase.epoch), 10),
|
||||
},
|
||||
},
|
||||
{
|
||||
Index: strconv.FormatUint(uint64(validatorIndices[9]), 10),
|
||||
Status: "active_ongoing",
|
||||
Validator: &structs.Validator{
|
||||
Pubkey: hexutil.Encode(pubkeys[9]),
|
||||
ActivationEpoch: strconv.FormatUint(uint64(testCase.epoch), 10),
|
||||
},
|
||||
},
|
||||
{
|
||||
Index: strconv.FormatUint(uint64(validatorIndices[10]), 10),
|
||||
Status: "active_ongoing",
|
||||
Validator: &structs.Validator{
|
||||
Pubkey: hexutil.Encode(pubkeys[10]),
|
||||
ActivationEpoch: strconv.FormatUint(uint64(testCase.epoch), 10),
|
||||
},
|
||||
},
|
||||
{
|
||||
Index: strconv.FormatUint(uint64(validatorIndices[11]), 10),
|
||||
Status: "active_ongoing",
|
||||
Validator: &structs.Validator{
|
||||
Pubkey: hexutil.Encode(pubkeys[11]),
|
||||
ActivationEpoch: strconv.FormatUint(uint64(testCase.epoch), 10),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
nil,
|
||||
).MinTimes(1)
|
||||
|
||||
// Make sure that our values are equal to what would be returned by calling dutiesForEpoch individually
|
||||
validatorClient := &beaconApiValidatorClient{
|
||||
dutiesProvider: dutiesProvider,
|
||||
stateValidatorsProvider: stateValidatorsProvider,
|
||||
}
|
||||
|
||||
expectedCurrentEpochDuties, err := validatorClient.dutiesForEpoch(
|
||||
ctx,
|
||||
testCase.epoch,
|
||||
vals,
|
||||
fetchSyncDuties,
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
expectedNextEpochDuties, err := validatorClient.dutiesForEpoch(
|
||||
ctx,
|
||||
testCase.epoch+1,
|
||||
vals,
|
||||
fetchSyncDuties,
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
expectedDuties := ðpb.ValidatorDutiesContainer{
|
||||
CurrentEpochDuties: expectedCurrentEpochDuties,
|
||||
NextEpochDuties: expectedNextEpochDuties,
|
||||
}
|
||||
|
||||
duties, err := validatorClient.duties(ctx, ðpb.DutiesRequest{
|
||||
Epoch: testCase.epoch,
|
||||
PublicKeys: append(pubkeys, []byte("0xunknown")),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.DeepEqual(t, expectedDuties, duties)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetDuties_GetStateValidatorsFailed(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
stateValidatorsProvider := mock.NewMockStateValidatorsProvider(ctrl)
|
||||
stateValidatorsProvider.EXPECT().StateValidators(
|
||||
gomock.Any(),
|
||||
gomock.Any(),
|
||||
gomock.Any(),
|
||||
gomock.Any(),
|
||||
).Return(
|
||||
nil,
|
||||
errors.New("foo error"),
|
||||
).Times(1)
|
||||
|
||||
validatorClient := &beaconApiValidatorClient{
|
||||
stateValidatorsProvider: stateValidatorsProvider,
|
||||
}
|
||||
|
||||
_, err := validatorClient.duties(ctx, ðpb.DutiesRequest{
|
||||
Epoch: 1,
|
||||
PublicKeys: [][]byte{},
|
||||
})
|
||||
assert.ErrorContains(t, "failed to get state validators", err)
|
||||
assert.ErrorContains(t, "foo error", err)
|
||||
}
|
||||
|
||||
func TestGetDuties_GetDutiesForEpochFailed(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
|
||||
ctx := context.Background()
|
||||
pubkey := []byte{1, 2, 3}
|
||||
|
||||
stateValidatorsProvider := mock.NewMockStateValidatorsProvider(ctrl)
|
||||
stateValidatorsProvider.EXPECT().StateValidators(
|
||||
gomock.Any(),
|
||||
gomock.Any(),
|
||||
gomock.Any(),
|
||||
gomock.Any(),
|
||||
).Return(
|
||||
&structs.GetValidatorsResponse{
|
||||
Data: []*structs.ValidatorContainer{{
|
||||
Index: "0",
|
||||
Status: "active_ongoing",
|
||||
Validator: &structs.Validator{
|
||||
Pubkey: hexutil.Encode(pubkey),
|
||||
},
|
||||
}},
|
||||
},
|
||||
nil,
|
||||
).Times(1)
|
||||
|
||||
dutiesProvider := mock.NewMockdutiesProvider(ctrl)
|
||||
dutiesProvider.EXPECT().AttesterDuties(
|
||||
ctx,
|
||||
primitives.Epoch(1),
|
||||
gomock.Any(),
|
||||
).Return(
|
||||
nil,
|
||||
errors.New("foo error"),
|
||||
).Times(1)
|
||||
dutiesProvider.EXPECT().AttesterDuties(
|
||||
ctx,
|
||||
primitives.Epoch(2),
|
||||
gomock.Any(),
|
||||
).Times(1)
|
||||
dutiesProvider.EXPECT().ProposerDuties(
|
||||
ctx,
|
||||
gomock.Any(),
|
||||
).Times(2)
|
||||
|
||||
validatorClient := &beaconApiValidatorClient{
|
||||
stateValidatorsProvider: stateValidatorsProvider,
|
||||
dutiesProvider: dutiesProvider,
|
||||
}
|
||||
|
||||
_, err := validatorClient.duties(ctx, ðpb.DutiesRequest{
|
||||
Epoch: 1,
|
||||
PublicKeys: [][]byte{pubkey},
|
||||
})
|
||||
assert.ErrorContains(t, "failed to get duties for current epoch `1`", err)
|
||||
assert.ErrorContains(t, "foo error", err)
|
||||
}
|
||||
|
||||
func generateValidAttesterDuties(pubkeys [][]byte, validatorIndices []primitives.ValidatorIndex, committeeIndices []primitives.CommitteeIndex, slots []primitives.Slot) []*structs.AttesterDuty {
|
||||
return []*structs.AttesterDuty{
|
||||
{
|
||||
Pubkey: hexutil.Encode(pubkeys[0]),
|
||||
ValidatorIndex: strconv.FormatUint(uint64(validatorIndices[0]), 10),
|
||||
CommitteeIndex: strconv.FormatUint(uint64(committeeIndices[0]), 10),
|
||||
CommitteeLength: fmt.Sprintf("%d", len(committeeIndices)),
|
||||
ValidatorCommitteeIndex: strconv.FormatUint(uint64(0), 10),
|
||||
CommitteesAtSlot: strconv.FormatUint(uint64(10), 10),
|
||||
Slot: strconv.FormatUint(uint64(slots[0]), 10),
|
||||
},
|
||||
{
|
||||
Pubkey: hexutil.Encode(pubkeys[1]),
|
||||
ValidatorIndex: strconv.FormatUint(uint64(validatorIndices[1]), 10),
|
||||
CommitteeIndex: strconv.FormatUint(uint64(committeeIndices[0]), 10),
|
||||
CommitteeLength: fmt.Sprintf("%d", len(committeeIndices)),
|
||||
ValidatorCommitteeIndex: strconv.FormatUint(uint64(0), 10),
|
||||
CommitteesAtSlot: strconv.FormatUint(uint64(10), 10),
|
||||
Slot: strconv.FormatUint(uint64(slots[0]), 10),
|
||||
},
|
||||
{
|
||||
Pubkey: hexutil.Encode(pubkeys[2]),
|
||||
ValidatorIndex: strconv.FormatUint(uint64(validatorIndices[2]), 10),
|
||||
CommitteeIndex: strconv.FormatUint(uint64(committeeIndices[1]), 10),
|
||||
CommitteeLength: fmt.Sprintf("%d", len(committeeIndices)),
|
||||
ValidatorCommitteeIndex: strconv.FormatUint(uint64(0), 10),
|
||||
CommitteesAtSlot: strconv.FormatUint(uint64(10), 10),
|
||||
Slot: strconv.FormatUint(uint64(slots[1]), 10),
|
||||
},
|
||||
{
|
||||
Pubkey: hexutil.Encode(pubkeys[3]),
|
||||
ValidatorIndex: strconv.FormatUint(uint64(validatorIndices[3]), 10),
|
||||
CommitteeIndex: strconv.FormatUint(uint64(committeeIndices[1]), 10),
|
||||
CommitteeLength: fmt.Sprintf("%d", len(committeeIndices)),
|
||||
ValidatorCommitteeIndex: strconv.FormatUint(uint64(0), 10),
|
||||
CommitteesAtSlot: strconv.FormatUint(uint64(10), 10),
|
||||
Slot: strconv.FormatUint(uint64(slots[1]), 10),
|
||||
},
|
||||
{
|
||||
Pubkey: hexutil.Encode(pubkeys[4]),
|
||||
ValidatorIndex: strconv.FormatUint(uint64(validatorIndices[4]), 10),
|
||||
CommitteeIndex: strconv.FormatUint(uint64(committeeIndices[2]), 10),
|
||||
CommitteeLength: fmt.Sprintf("%d", len(committeeIndices)),
|
||||
ValidatorCommitteeIndex: strconv.FormatUint(uint64(0), 10),
|
||||
CommitteesAtSlot: strconv.FormatUint(uint64(10), 10),
|
||||
Slot: strconv.FormatUint(uint64(slots[2]), 10),
|
||||
},
|
||||
{
|
||||
Pubkey: hexutil.Encode(pubkeys[5]),
|
||||
ValidatorIndex: strconv.FormatUint(uint64(validatorIndices[5]), 10),
|
||||
CommitteeIndex: strconv.FormatUint(uint64(committeeIndices[2]), 10),
|
||||
CommitteeLength: fmt.Sprintf("%d", len(committeeIndices)),
|
||||
ValidatorCommitteeIndex: strconv.FormatUint(uint64(0), 10),
|
||||
CommitteesAtSlot: strconv.FormatUint(uint64(10), 10),
|
||||
Slot: strconv.FormatUint(uint64(slots[2]), 10),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func generateValidProposerDuties(pubkeys [][]byte, validatorIndices []primitives.ValidatorIndex, slots []primitives.Slot) []*structs.ProposerDuty {
|
||||
return []*structs.ProposerDuty{
|
||||
{
|
||||
Pubkey: hexutil.Encode(pubkeys[4]),
|
||||
ValidatorIndex: strconv.FormatUint(uint64(validatorIndices[4]), 10),
|
||||
Slot: strconv.FormatUint(uint64(slots[0]), 10),
|
||||
},
|
||||
{
|
||||
Pubkey: hexutil.Encode(pubkeys[4]),
|
||||
ValidatorIndex: strconv.FormatUint(uint64(validatorIndices[4]), 10),
|
||||
Slot: strconv.FormatUint(uint64(slots[1]), 10),
|
||||
},
|
||||
{
|
||||
Pubkey: hexutil.Encode(pubkeys[5]),
|
||||
ValidatorIndex: strconv.FormatUint(uint64(validatorIndices[5]), 10),
|
||||
Slot: strconv.FormatUint(uint64(slots[2]), 10),
|
||||
},
|
||||
{
|
||||
Pubkey: hexutil.Encode(pubkeys[5]),
|
||||
ValidatorIndex: strconv.FormatUint(uint64(validatorIndices[5]), 10),
|
||||
Slot: strconv.FormatUint(uint64(slots[3]), 10),
|
||||
},
|
||||
{
|
||||
Pubkey: hexutil.Encode(pubkeys[6]),
|
||||
ValidatorIndex: strconv.FormatUint(uint64(validatorIndices[6]), 10),
|
||||
Slot: strconv.FormatUint(uint64(slots[4]), 10),
|
||||
},
|
||||
{
|
||||
Pubkey: hexutil.Encode(pubkeys[6]),
|
||||
ValidatorIndex: strconv.FormatUint(uint64(validatorIndices[6]), 10),
|
||||
Slot: strconv.FormatUint(uint64(slots[5]), 10),
|
||||
},
|
||||
{
|
||||
Pubkey: hexutil.Encode(pubkeys[7]),
|
||||
ValidatorIndex: strconv.FormatUint(uint64(validatorIndices[7]), 10),
|
||||
Slot: strconv.FormatUint(uint64(slots[6]), 10),
|
||||
},
|
||||
{
|
||||
Pubkey: hexutil.Encode(pubkeys[7]),
|
||||
ValidatorIndex: strconv.FormatUint(uint64(validatorIndices[7]), 10),
|
||||
Slot: strconv.FormatUint(uint64(slots[7]), 10),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func generateValidSyncDuties(pubkeys [][]byte, validatorIndices []primitives.ValidatorIndex) []*structs.SyncCommitteeDuty {
|
||||
return []*structs.SyncCommitteeDuty{
|
||||
{
|
||||
Pubkey: hexutil.Encode(pubkeys[5]),
|
||||
ValidatorIndex: strconv.FormatUint(uint64(validatorIndices[5]), 10),
|
||||
},
|
||||
{
|
||||
Pubkey: hexutil.Encode(pubkeys[6]),
|
||||
ValidatorIndex: strconv.FormatUint(uint64(validatorIndices[6]), 10),
|
||||
},
|
||||
{
|
||||
Pubkey: hexutil.Encode(pubkeys[7]),
|
||||
ValidatorIndex: strconv.FormatUint(uint64(validatorIndices[7]), 10),
|
||||
},
|
||||
{
|
||||
Pubkey: hexutil.Encode(pubkeys[8]),
|
||||
ValidatorIndex: strconv.FormatUint(uint64(validatorIndices[8]), 10),
|
||||
},
|
||||
{
|
||||
Pubkey: hexutil.Encode(pubkeys[9]),
|
||||
ValidatorIndex: strconv.FormatUint(uint64(validatorIndices[9]), 10),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// We will use a reverse function to easily make sure that the current epoch and next epoch data returned by dutiesForEpoch
|
||||
// are not the same
|
||||
func reverseSlice[T interface{}](slice []T) []T {
|
||||
reversedSlice := make([]T, len(slice))
|
||||
for i := range slice {
|
||||
reversedSlice[len(reversedSlice)-1-i] = slice[i]
|
||||
}
|
||||
return reversedSlice
|
||||
}
|
||||
243
api/client/beacon/validator_api/get_beacon_block.go
Normal file
243
api/client/beacon/validator_api/get_beacon_block.go
Normal file
@@ -0,0 +1,243 @@
|
||||
package validator_api
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
neturl "net/url"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/apiutil"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/server/structs"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
"github.com/prysmaticlabs/prysm/v5/network/httputil"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v5/runtime/version"
|
||||
)
|
||||
|
||||
type abstractProduceBlockResponseJson struct {
|
||||
Version string `json:"version"`
|
||||
Data json.RawMessage `json:"data"`
|
||||
}
|
||||
|
||||
func (c *beaconApiValidatorClient) beaconBlock(ctx context.Context, slot primitives.Slot, randaoReveal, graffiti []byte) (*ethpb.GenericBeaconBlock, error) {
|
||||
queryParams := neturl.Values{}
|
||||
queryParams.Add("randao_reveal", hexutil.Encode(randaoReveal))
|
||||
if len(graffiti) > 0 {
|
||||
queryParams.Add("graffiti", hexutil.Encode(graffiti))
|
||||
}
|
||||
|
||||
var ver string
|
||||
var blinded bool
|
||||
var decoder *json.Decoder
|
||||
|
||||
// Try v3 endpoint first. If it's not supported, then we fall back to older endpoints.
|
||||
// We try the blinded block endpoint first. If it fails, we assume that we got a full block and try the full block endpoint.
|
||||
queryUrl := apiutil.BuildURL(fmt.Sprintf("/eth/v3/validator/blocks/%d", slot), queryParams)
|
||||
produceBlockV3ResponseJson := structs.ProduceBlockV3Response{}
|
||||
err := c.jsonRestHandler.Get(ctx, queryUrl, &produceBlockV3ResponseJson)
|
||||
errJson := &httputil.DefaultJsonError{}
|
||||
if err != nil {
|
||||
if !errors.As(err, &errJson) {
|
||||
return nil, err
|
||||
}
|
||||
if errJson.Code != http.StatusNotFound {
|
||||
return nil, errJson
|
||||
}
|
||||
log.Debug("Endpoint /eth/v3/validator/blocks is not supported, falling back to older endpoints for block proposal.")
|
||||
fallbackResp, err := c.fallBackToBlinded(ctx, slot, queryParams)
|
||||
errJson = &httputil.DefaultJsonError{}
|
||||
if err != nil {
|
||||
if !errors.As(err, &errJson) {
|
||||
return nil, err
|
||||
}
|
||||
log.Debug("Endpoint /eth/v1/validator/blinded_blocks failed to produce a blinded block, trying /eth/v2/validator/blocks.")
|
||||
fallbackResp, err = c.fallBackToFull(ctx, slot, queryParams)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
blinded = false
|
||||
} else {
|
||||
blinded = true
|
||||
}
|
||||
ver = fallbackResp.Version
|
||||
decoder = json.NewDecoder(bytes.NewReader(fallbackResp.Data))
|
||||
} else {
|
||||
ver = produceBlockV3ResponseJson.Version
|
||||
blinded = produceBlockV3ResponseJson.ExecutionPayloadBlinded
|
||||
decoder = json.NewDecoder(bytes.NewReader(produceBlockV3ResponseJson.Data))
|
||||
}
|
||||
return processBlockResponse(ver, blinded, decoder)
|
||||
}
|
||||
|
||||
// nolint: gocognit
|
||||
func processBlockResponse(ver string, isBlinded bool, decoder *json.Decoder) (*ethpb.GenericBeaconBlock, error) {
|
||||
var response *ethpb.GenericBeaconBlock
|
||||
if decoder == nil {
|
||||
return nil, errors.New("no produce block json decoder found")
|
||||
}
|
||||
switch ver {
|
||||
case version.String(version.Phase0):
|
||||
jsonPhase0Block := structs.BeaconBlock{}
|
||||
if err := decoder.Decode(&jsonPhase0Block); err != nil {
|
||||
return nil, errors.Wrap(err, "failed to decode phase0 block response json")
|
||||
}
|
||||
genericBlock, err := jsonPhase0Block.ToGeneric()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to get phase0 block")
|
||||
}
|
||||
response = genericBlock
|
||||
case version.String(version.Altair):
|
||||
jsonAltairBlock := structs.BeaconBlockAltair{}
|
||||
if err := decoder.Decode(&jsonAltairBlock); err != nil {
|
||||
return nil, errors.Wrap(err, "failed to decode altair block response json")
|
||||
}
|
||||
genericBlock, err := jsonAltairBlock.ToGeneric()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to get altair block")
|
||||
}
|
||||
response = genericBlock
|
||||
case version.String(version.Bellatrix):
|
||||
if isBlinded {
|
||||
jsonBellatrixBlock := structs.BlindedBeaconBlockBellatrix{}
|
||||
if err := decoder.Decode(&jsonBellatrixBlock); err != nil {
|
||||
return nil, errors.Wrap(err, "failed to decode blinded bellatrix block response json")
|
||||
}
|
||||
genericBlock, err := jsonBellatrixBlock.ToGeneric()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to get blinded bellatrix block")
|
||||
}
|
||||
response = genericBlock
|
||||
} else {
|
||||
jsonBellatrixBlock := structs.BeaconBlockBellatrix{}
|
||||
if err := decoder.Decode(&jsonBellatrixBlock); err != nil {
|
||||
return nil, errors.Wrap(err, "failed to decode bellatrix block response json")
|
||||
}
|
||||
genericBlock, err := jsonBellatrixBlock.ToGeneric()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to get bellatrix block")
|
||||
}
|
||||
response = genericBlock
|
||||
}
|
||||
case version.String(version.Capella):
|
||||
if isBlinded {
|
||||
jsonCapellaBlock := structs.BlindedBeaconBlockCapella{}
|
||||
if err := decoder.Decode(&jsonCapellaBlock); err != nil {
|
||||
return nil, errors.Wrap(err, "failed to decode blinded capella block response json")
|
||||
}
|
||||
genericBlock, err := jsonCapellaBlock.ToGeneric()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to get blinded capella block")
|
||||
}
|
||||
response = genericBlock
|
||||
} else {
|
||||
jsonCapellaBlock := structs.BeaconBlockCapella{}
|
||||
if err := decoder.Decode(&jsonCapellaBlock); err != nil {
|
||||
return nil, errors.Wrap(err, "failed to decode capella block response json")
|
||||
}
|
||||
genericBlock, err := jsonCapellaBlock.ToGeneric()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to get capella block")
|
||||
}
|
||||
response = genericBlock
|
||||
}
|
||||
case version.String(version.Deneb):
|
||||
if isBlinded {
|
||||
jsonDenebBlock := structs.BlindedBeaconBlockDeneb{}
|
||||
if err := decoder.Decode(&jsonDenebBlock); err != nil {
|
||||
return nil, errors.Wrap(err, "failed to decode blinded deneb block response json")
|
||||
}
|
||||
genericBlock, err := jsonDenebBlock.ToGeneric()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to get blinded deneb block")
|
||||
}
|
||||
response = genericBlock
|
||||
} else {
|
||||
jsonDenebBlockContents := structs.BeaconBlockContentsDeneb{}
|
||||
if err := decoder.Decode(&jsonDenebBlockContents); err != nil {
|
||||
return nil, errors.Wrap(err, "failed to decode deneb block response json")
|
||||
}
|
||||
genericBlock, err := jsonDenebBlockContents.ToGeneric()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to get deneb block")
|
||||
}
|
||||
response = genericBlock
|
||||
}
|
||||
case version.String(version.Electra):
|
||||
if isBlinded {
|
||||
jsonElectraBlock := structs.BlindedBeaconBlockElectra{}
|
||||
if err := decoder.Decode(&jsonElectraBlock); err != nil {
|
||||
return nil, errors.Wrap(err, "failed to decode blinded electra block response json")
|
||||
}
|
||||
genericBlock, err := jsonElectraBlock.ToGeneric()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to get blinded electra block")
|
||||
}
|
||||
response = genericBlock
|
||||
} else {
|
||||
jsonElectraBlockContents := structs.BeaconBlockContentsElectra{}
|
||||
if err := decoder.Decode(&jsonElectraBlockContents); err != nil {
|
||||
return nil, errors.Wrap(err, "failed to decode electra block response json")
|
||||
}
|
||||
genericBlock, err := jsonElectraBlockContents.ToGeneric()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to get electra block")
|
||||
}
|
||||
response = genericBlock
|
||||
}
|
||||
case version.String(version.Fulu):
|
||||
if isBlinded {
|
||||
jsonFuluBlock := structs.BlindedBeaconBlockFulu{}
|
||||
if err := decoder.Decode(&jsonFuluBlock); err != nil {
|
||||
return nil, errors.Wrap(err, "failed to decode blinded fulu block response json")
|
||||
}
|
||||
genericBlock, err := jsonFuluBlock.ToGeneric()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to get blinded fulu block")
|
||||
}
|
||||
response = genericBlock
|
||||
} else {
|
||||
jsonFuluBlockContents := structs.BeaconBlockContentsFulu{}
|
||||
if err := decoder.Decode(&jsonFuluBlockContents); err != nil {
|
||||
return nil, errors.Wrap(err, "failed to decode fulu block response json")
|
||||
}
|
||||
genericBlock, err := jsonFuluBlockContents.ToGeneric()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to get fulu block")
|
||||
}
|
||||
response = genericBlock
|
||||
}
|
||||
default:
|
||||
return nil, errors.Errorf("unsupported consensus version `%s`", ver)
|
||||
}
|
||||
return response, nil
|
||||
}
|
||||
|
||||
func (c *beaconApiValidatorClient) fallBackToBlinded(
|
||||
ctx context.Context,
|
||||
slot primitives.Slot,
|
||||
queryParams neturl.Values,
|
||||
) (*abstractProduceBlockResponseJson, error) {
|
||||
resp := &abstractProduceBlockResponseJson{}
|
||||
url := apiutil.BuildURL(fmt.Sprintf("/eth/v1/validator/blinded_blocks/%d", slot), queryParams)
|
||||
if err := c.jsonRestHandler.Get(ctx, url, resp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func (c *beaconApiValidatorClient) fallBackToFull(
|
||||
ctx context.Context,
|
||||
slot primitives.Slot,
|
||||
queryParams neturl.Values,
|
||||
) (*abstractProduceBlockResponseJson, error) {
|
||||
resp := &abstractProduceBlockResponseJson{}
|
||||
url := apiutil.BuildURL(fmt.Sprintf("/eth/v2/validator/blocks/%d", slot), queryParams)
|
||||
if err := c.jsonRestHandler.Get(ctx, url, resp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return resp, nil
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package beacon_api
|
||||
package validator_api
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -9,15 +9,15 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/golang/mock/gomock"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/validator"
|
||||
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
|
||||
"github.com/prysmaticlabs/prysm/v4/network/httputil"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v4/testing/assert"
|
||||
"github.com/prysmaticlabs/prysm/v4/testing/require"
|
||||
"github.com/prysmaticlabs/prysm/v4/validator/client/beacon-api/mock"
|
||||
test_helpers "github.com/prysmaticlabs/prysm/v4/validator/client/beacon-api/test-helpers"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/client/beacon/mock"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/client/beacon/validator_api/test_helpers"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/server/structs"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
"github.com/prysmaticlabs/prysm/v5/network/httputil"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v5/testing/assert"
|
||||
"github.com/prysmaticlabs/prysm/v5/testing/require"
|
||||
"go.uber.org/mock/gomock"
|
||||
)
|
||||
|
||||
func TestGetBeaconBlock_RequestFailed(t *testing.T) {
|
||||
@@ -28,17 +28,15 @@ func TestGetBeaconBlock_RequestFailed(t *testing.T) {
|
||||
|
||||
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
|
||||
jsonRestHandler.EXPECT().Get(
|
||||
ctx,
|
||||
gomock.Any(),
|
||||
gomock.Any(),
|
||||
gomock.Any(),
|
||||
).Return(
|
||||
nil,
|
||||
errors.New("foo error"),
|
||||
).Times(1)
|
||||
|
||||
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
|
||||
_, err := validatorClient.getBeaconBlock(ctx, 1, []byte{1}, []byte{2})
|
||||
assert.ErrorContains(t, "failed to query GET REST endpoint", err)
|
||||
_, err := validatorClient.beaconBlock(ctx, 1, []byte{1}, []byte{2})
|
||||
assert.ErrorContains(t, "foo error", err)
|
||||
}
|
||||
|
||||
@@ -127,22 +125,21 @@ func TestGetBeaconBlock_Error(t *testing.T) {
|
||||
|
||||
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
|
||||
jsonRestHandler.EXPECT().Get(
|
||||
ctx,
|
||||
gomock.Any(),
|
||||
&validator.ProduceBlockV3Response{},
|
||||
gomock.Any(),
|
||||
&structs.ProduceBlockV3Response{},
|
||||
).SetArg(
|
||||
2,
|
||||
validator.ProduceBlockV3Response{
|
||||
structs.ProduceBlockV3Response{
|
||||
Version: testCase.consensusVersion,
|
||||
Data: testCase.data,
|
||||
},
|
||||
).Return(
|
||||
nil,
|
||||
nil,
|
||||
).Times(1)
|
||||
|
||||
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
|
||||
_, err := validatorClient.getBeaconBlock(ctx, 1, []byte{1}, []byte{2})
|
||||
_, err := validatorClient.beaconBlock(ctx, 1, []byte{1}, []byte{2})
|
||||
assert.ErrorContains(t, testCase.expectedErrorMessage, err)
|
||||
})
|
||||
}
|
||||
@@ -164,22 +161,21 @@ func TestGetBeaconBlock_Phase0Valid(t *testing.T) {
|
||||
|
||||
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
|
||||
jsonRestHandler.EXPECT().Get(
|
||||
ctx,
|
||||
gomock.Any(),
|
||||
fmt.Sprintf("/eth/v3/validator/blocks/%d?graffiti=%s&randao_reveal=%s", slot, hexutil.Encode(graffiti), hexutil.Encode(randaoReveal)),
|
||||
&validator.ProduceBlockV3Response{},
|
||||
&structs.ProduceBlockV3Response{},
|
||||
).SetArg(
|
||||
2,
|
||||
validator.ProduceBlockV3Response{
|
||||
structs.ProduceBlockV3Response{
|
||||
Version: "phase0",
|
||||
Data: bytes,
|
||||
},
|
||||
).Return(
|
||||
nil,
|
||||
nil,
|
||||
).Times(1)
|
||||
|
||||
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
|
||||
beaconBlock, err := validatorClient.getBeaconBlock(ctx, slot, randaoReveal, graffiti)
|
||||
beaconBlock, err := validatorClient.beaconBlock(ctx, slot, randaoReveal, graffiti)
|
||||
require.NoError(t, err)
|
||||
|
||||
expectedBeaconBlock := ðpb.GenericBeaconBlock{
|
||||
@@ -208,22 +204,21 @@ func TestGetBeaconBlock_AltairValid(t *testing.T) {
|
||||
|
||||
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
|
||||
jsonRestHandler.EXPECT().Get(
|
||||
ctx,
|
||||
gomock.Any(),
|
||||
fmt.Sprintf("/eth/v3/validator/blocks/%d?graffiti=%s&randao_reveal=%s", slot, hexutil.Encode(graffiti), hexutil.Encode(randaoReveal)),
|
||||
&validator.ProduceBlockV3Response{},
|
||||
&structs.ProduceBlockV3Response{},
|
||||
).SetArg(
|
||||
2,
|
||||
validator.ProduceBlockV3Response{
|
||||
structs.ProduceBlockV3Response{
|
||||
Version: "altair",
|
||||
Data: bytes,
|
||||
},
|
||||
).Return(
|
||||
nil,
|
||||
nil,
|
||||
).Times(1)
|
||||
|
||||
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
|
||||
beaconBlock, err := validatorClient.getBeaconBlock(ctx, slot, randaoReveal, graffiti)
|
||||
beaconBlock, err := validatorClient.beaconBlock(ctx, slot, randaoReveal, graffiti)
|
||||
require.NoError(t, err)
|
||||
|
||||
expectedBeaconBlock := ðpb.GenericBeaconBlock{
|
||||
@@ -252,23 +247,22 @@ func TestGetBeaconBlock_BellatrixValid(t *testing.T) {
|
||||
|
||||
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
|
||||
jsonRestHandler.EXPECT().Get(
|
||||
ctx,
|
||||
gomock.Any(),
|
||||
fmt.Sprintf("/eth/v3/validator/blocks/%d?graffiti=%s&randao_reveal=%s", slot, hexutil.Encode(graffiti), hexutil.Encode(randaoReveal)),
|
||||
&validator.ProduceBlockV3Response{},
|
||||
&structs.ProduceBlockV3Response{},
|
||||
).SetArg(
|
||||
2,
|
||||
validator.ProduceBlockV3Response{
|
||||
structs.ProduceBlockV3Response{
|
||||
Version: "bellatrix",
|
||||
ExecutionPayloadBlinded: false,
|
||||
Data: bytes,
|
||||
},
|
||||
).Return(
|
||||
nil,
|
||||
nil,
|
||||
).Times(1)
|
||||
|
||||
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
|
||||
beaconBlock, err := validatorClient.getBeaconBlock(ctx, slot, randaoReveal, graffiti)
|
||||
beaconBlock, err := validatorClient.beaconBlock(ctx, slot, randaoReveal, graffiti)
|
||||
require.NoError(t, err)
|
||||
|
||||
expectedBeaconBlock := ðpb.GenericBeaconBlock{
|
||||
@@ -298,23 +292,22 @@ func TestGetBeaconBlock_BlindedBellatrixValid(t *testing.T) {
|
||||
|
||||
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
|
||||
jsonRestHandler.EXPECT().Get(
|
||||
ctx,
|
||||
gomock.Any(),
|
||||
fmt.Sprintf("/eth/v3/validator/blocks/%d?graffiti=%s&randao_reveal=%s", slot, hexutil.Encode(graffiti), hexutil.Encode(randaoReveal)),
|
||||
&validator.ProduceBlockV3Response{},
|
||||
&structs.ProduceBlockV3Response{},
|
||||
).SetArg(
|
||||
2,
|
||||
validator.ProduceBlockV3Response{
|
||||
structs.ProduceBlockV3Response{
|
||||
Version: "bellatrix",
|
||||
ExecutionPayloadBlinded: true,
|
||||
Data: bytes,
|
||||
},
|
||||
).Return(
|
||||
nil,
|
||||
nil,
|
||||
).Times(1)
|
||||
|
||||
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
|
||||
beaconBlock, err := validatorClient.getBeaconBlock(ctx, slot, randaoReveal, graffiti)
|
||||
beaconBlock, err := validatorClient.beaconBlock(ctx, slot, randaoReveal, graffiti)
|
||||
require.NoError(t, err)
|
||||
|
||||
expectedBeaconBlock := ðpb.GenericBeaconBlock{
|
||||
@@ -344,23 +337,22 @@ func TestGetBeaconBlock_CapellaValid(t *testing.T) {
|
||||
|
||||
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
|
||||
jsonRestHandler.EXPECT().Get(
|
||||
ctx,
|
||||
gomock.Any(),
|
||||
fmt.Sprintf("/eth/v3/validator/blocks/%d?graffiti=%s&randao_reveal=%s", slot, hexutil.Encode(graffiti), hexutil.Encode(randaoReveal)),
|
||||
&validator.ProduceBlockV3Response{},
|
||||
&structs.ProduceBlockV3Response{},
|
||||
).SetArg(
|
||||
2,
|
||||
validator.ProduceBlockV3Response{
|
||||
structs.ProduceBlockV3Response{
|
||||
Version: "capella",
|
||||
ExecutionPayloadBlinded: false,
|
||||
Data: bytes,
|
||||
},
|
||||
).Return(
|
||||
nil,
|
||||
nil,
|
||||
).Times(1)
|
||||
|
||||
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
|
||||
beaconBlock, err := validatorClient.getBeaconBlock(ctx, slot, randaoReveal, graffiti)
|
||||
beaconBlock, err := validatorClient.beaconBlock(ctx, slot, randaoReveal, graffiti)
|
||||
require.NoError(t, err)
|
||||
|
||||
expectedBeaconBlock := ðpb.GenericBeaconBlock{
|
||||
@@ -390,23 +382,22 @@ func TestGetBeaconBlock_BlindedCapellaValid(t *testing.T) {
|
||||
|
||||
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
|
||||
jsonRestHandler.EXPECT().Get(
|
||||
ctx,
|
||||
gomock.Any(),
|
||||
fmt.Sprintf("/eth/v3/validator/blocks/%d?graffiti=%s&randao_reveal=%s", slot, hexutil.Encode(graffiti), hexutil.Encode(randaoReveal)),
|
||||
&validator.ProduceBlockV3Response{},
|
||||
&structs.ProduceBlockV3Response{},
|
||||
).SetArg(
|
||||
2,
|
||||
validator.ProduceBlockV3Response{
|
||||
structs.ProduceBlockV3Response{
|
||||
Version: "capella",
|
||||
ExecutionPayloadBlinded: true,
|
||||
Data: bytes,
|
||||
},
|
||||
).Return(
|
||||
nil,
|
||||
nil,
|
||||
).Times(1)
|
||||
|
||||
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
|
||||
beaconBlock, err := validatorClient.getBeaconBlock(ctx, slot, randaoReveal, graffiti)
|
||||
beaconBlock, err := validatorClient.beaconBlock(ctx, slot, randaoReveal, graffiti)
|
||||
require.NoError(t, err)
|
||||
|
||||
expectedBeaconBlock := ðpb.GenericBeaconBlock{
|
||||
@@ -436,23 +427,22 @@ func TestGetBeaconBlock_DenebValid(t *testing.T) {
|
||||
|
||||
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
|
||||
jsonRestHandler.EXPECT().Get(
|
||||
ctx,
|
||||
gomock.Any(),
|
||||
fmt.Sprintf("/eth/v3/validator/blocks/%d?graffiti=%s&randao_reveal=%s", slot, hexutil.Encode(graffiti), hexutil.Encode(randaoReveal)),
|
||||
&validator.ProduceBlockV3Response{},
|
||||
&structs.ProduceBlockV3Response{},
|
||||
).SetArg(
|
||||
2,
|
||||
validator.ProduceBlockV3Response{
|
||||
structs.ProduceBlockV3Response{
|
||||
Version: "deneb",
|
||||
ExecutionPayloadBlinded: false,
|
||||
Data: bytes,
|
||||
},
|
||||
).Return(
|
||||
nil,
|
||||
nil,
|
||||
).Times(1)
|
||||
|
||||
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
|
||||
beaconBlock, err := validatorClient.getBeaconBlock(ctx, slot, randaoReveal, graffiti)
|
||||
beaconBlock, err := validatorClient.beaconBlock(ctx, slot, randaoReveal, graffiti)
|
||||
require.NoError(t, err)
|
||||
|
||||
expectedBeaconBlock := ðpb.GenericBeaconBlock{
|
||||
@@ -482,23 +472,22 @@ func TestGetBeaconBlock_BlindedDenebValid(t *testing.T) {
|
||||
|
||||
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
|
||||
jsonRestHandler.EXPECT().Get(
|
||||
ctx,
|
||||
gomock.Any(),
|
||||
fmt.Sprintf("/eth/v3/validator/blocks/%d?graffiti=%s&randao_reveal=%s", slot, hexutil.Encode(graffiti), hexutil.Encode(randaoReveal)),
|
||||
&validator.ProduceBlockV3Response{},
|
||||
&structs.ProduceBlockV3Response{},
|
||||
).SetArg(
|
||||
2,
|
||||
validator.ProduceBlockV3Response{
|
||||
structs.ProduceBlockV3Response{
|
||||
Version: "deneb",
|
||||
ExecutionPayloadBlinded: true,
|
||||
Data: bytes,
|
||||
},
|
||||
).Return(
|
||||
nil,
|
||||
nil,
|
||||
).Times(1)
|
||||
|
||||
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
|
||||
beaconBlock, err := validatorClient.getBeaconBlock(ctx, slot, randaoReveal, graffiti)
|
||||
beaconBlock, err := validatorClient.beaconBlock(ctx, slot, randaoReveal, graffiti)
|
||||
require.NoError(t, err)
|
||||
|
||||
expectedBeaconBlock := ðpb.GenericBeaconBlock{
|
||||
@@ -511,6 +500,96 @@ func TestGetBeaconBlock_BlindedDenebValid(t *testing.T) {
|
||||
assert.DeepEqual(t, expectedBeaconBlock, beaconBlock)
|
||||
}
|
||||
|
||||
func TestGetBeaconBlock_ElectraValid(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
|
||||
proto := test_helpers.GenerateProtoElectraBeaconBlockContents()
|
||||
block := test_helpers.GenerateJsonElectraBeaconBlockContents()
|
||||
bytes, err := json.Marshal(block)
|
||||
require.NoError(t, err)
|
||||
|
||||
const slot = primitives.Slot(1)
|
||||
randaoReveal := []byte{2}
|
||||
graffiti := []byte{3}
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
|
||||
jsonRestHandler.EXPECT().Get(
|
||||
gomock.Any(),
|
||||
fmt.Sprintf("/eth/v3/validator/blocks/%d?graffiti=%s&randao_reveal=%s", slot, hexutil.Encode(graffiti), hexutil.Encode(randaoReveal)),
|
||||
&structs.ProduceBlockV3Response{},
|
||||
).SetArg(
|
||||
2,
|
||||
structs.ProduceBlockV3Response{
|
||||
Version: "electra",
|
||||
ExecutionPayloadBlinded: false,
|
||||
Data: bytes,
|
||||
},
|
||||
).Return(
|
||||
nil,
|
||||
).Times(1)
|
||||
|
||||
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
|
||||
beaconBlock, err := validatorClient.beaconBlock(ctx, slot, randaoReveal, graffiti)
|
||||
require.NoError(t, err)
|
||||
|
||||
expectedBeaconBlock := ðpb.GenericBeaconBlock{
|
||||
Block: ðpb.GenericBeaconBlock_Electra{
|
||||
Electra: proto,
|
||||
},
|
||||
IsBlinded: false,
|
||||
}
|
||||
|
||||
assert.DeepEqual(t, expectedBeaconBlock, beaconBlock)
|
||||
}
|
||||
|
||||
func TestGetBeaconBlock_BlindedElectraValid(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
|
||||
proto := test_helpers.GenerateProtoBlindedElectraBeaconBlock()
|
||||
block := test_helpers.GenerateJsonBlindedElectraBeaconBlock()
|
||||
bytes, err := json.Marshal(block)
|
||||
require.NoError(t, err)
|
||||
|
||||
const slot = primitives.Slot(1)
|
||||
randaoReveal := []byte{2}
|
||||
graffiti := []byte{3}
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
|
||||
jsonRestHandler.EXPECT().Get(
|
||||
gomock.Any(),
|
||||
fmt.Sprintf("/eth/v3/validator/blocks/%d?graffiti=%s&randao_reveal=%s", slot, hexutil.Encode(graffiti), hexutil.Encode(randaoReveal)),
|
||||
&structs.ProduceBlockV3Response{},
|
||||
).SetArg(
|
||||
2,
|
||||
structs.ProduceBlockV3Response{
|
||||
Version: "electra",
|
||||
ExecutionPayloadBlinded: true,
|
||||
Data: bytes,
|
||||
},
|
||||
).Return(
|
||||
nil,
|
||||
).Times(1)
|
||||
|
||||
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
|
||||
beaconBlock, err := validatorClient.beaconBlock(ctx, slot, randaoReveal, graffiti)
|
||||
require.NoError(t, err)
|
||||
|
||||
expectedBeaconBlock := ðpb.GenericBeaconBlock{
|
||||
Block: ðpb.GenericBeaconBlock_BlindedElectra{
|
||||
BlindedElectra: proto,
|
||||
},
|
||||
IsBlinded: true,
|
||||
}
|
||||
|
||||
assert.DeepEqual(t, expectedBeaconBlock, beaconBlock)
|
||||
}
|
||||
|
||||
func TestGetBeaconBlock_FallbackToBlindedBlock(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
@@ -528,15 +607,14 @@ func TestGetBeaconBlock_FallbackToBlindedBlock(t *testing.T) {
|
||||
|
||||
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
|
||||
jsonRestHandler.EXPECT().Get(
|
||||
ctx,
|
||||
gomock.Any(),
|
||||
fmt.Sprintf("/eth/v3/validator/blocks/%d?graffiti=%s&randao_reveal=%s", slot, hexutil.Encode(graffiti), hexutil.Encode(randaoReveal)),
|
||||
&validator.ProduceBlockV3Response{},
|
||||
&structs.ProduceBlockV3Response{},
|
||||
).Return(
|
||||
&httputil.DefaultErrorJson{Code: http.StatusNotFound},
|
||||
errors.New("foo"),
|
||||
&httputil.DefaultJsonError{Code: http.StatusNotFound},
|
||||
).Times(1)
|
||||
jsonRestHandler.EXPECT().Get(
|
||||
ctx,
|
||||
gomock.Any(),
|
||||
fmt.Sprintf("/eth/v1/validator/blinded_blocks/%d?graffiti=%s&randao_reveal=%s", slot, hexutil.Encode(graffiti), hexutil.Encode(randaoReveal)),
|
||||
&abstractProduceBlockResponseJson{},
|
||||
).SetArg(
|
||||
@@ -547,11 +625,10 @@ func TestGetBeaconBlock_FallbackToBlindedBlock(t *testing.T) {
|
||||
},
|
||||
).Return(
|
||||
nil,
|
||||
nil,
|
||||
).Times(1)
|
||||
|
||||
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
|
||||
beaconBlock, err := validatorClient.getBeaconBlock(ctx, slot, randaoReveal, graffiti)
|
||||
beaconBlock, err := validatorClient.beaconBlock(ctx, slot, randaoReveal, graffiti)
|
||||
require.NoError(t, err)
|
||||
|
||||
expectedBeaconBlock := ðpb.GenericBeaconBlock{
|
||||
@@ -581,20 +658,18 @@ func TestGetBeaconBlock_FallbackToFullBlock(t *testing.T) {
|
||||
|
||||
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
|
||||
jsonRestHandler.EXPECT().Get(
|
||||
ctx,
|
||||
gomock.Any(),
|
||||
fmt.Sprintf("/eth/v3/validator/blocks/%d?graffiti=%s&randao_reveal=%s", slot, hexutil.Encode(graffiti), hexutil.Encode(randaoReveal)),
|
||||
&validator.ProduceBlockV3Response{},
|
||||
&structs.ProduceBlockV3Response{},
|
||||
).Return(
|
||||
&httputil.DefaultErrorJson{Code: http.StatusNotFound},
|
||||
errors.New("foo"),
|
||||
&httputil.DefaultJsonError{Code: http.StatusNotFound},
|
||||
).Times(1)
|
||||
jsonRestHandler.EXPECT().Get(
|
||||
ctx,
|
||||
gomock.Any(),
|
||||
fmt.Sprintf("/eth/v1/validator/blinded_blocks/%d?graffiti=%s&randao_reveal=%s", slot, hexutil.Encode(graffiti), hexutil.Encode(randaoReveal)),
|
||||
&abstractProduceBlockResponseJson{},
|
||||
).Return(
|
||||
&httputil.DefaultErrorJson{Code: http.StatusInternalServerError},
|
||||
errors.New("foo"),
|
||||
&httputil.DefaultJsonError{Code: http.StatusInternalServerError},
|
||||
).Times(1)
|
||||
jsonRestHandler.EXPECT().Get(
|
||||
ctx,
|
||||
@@ -608,11 +683,10 @@ func TestGetBeaconBlock_FallbackToFullBlock(t *testing.T) {
|
||||
},
|
||||
).Return(
|
||||
nil,
|
||||
nil,
|
||||
).Times(1)
|
||||
|
||||
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
|
||||
beaconBlock, err := validatorClient.getBeaconBlock(ctx, slot, randaoReveal, graffiti)
|
||||
beaconBlock, err := validatorClient.beaconBlock(ctx, slot, randaoReveal, graffiti)
|
||||
require.NoError(t, err)
|
||||
|
||||
expectedBeaconBlock := ðpb.GenericBeaconBlock{
|
||||
315
api/client/beacon/validator_api/grpc_client.go
Normal file
315
api/client/beacon/validator_api/grpc_client.go
Normal file
@@ -0,0 +1,315 @@
|
||||
package validator_api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"strconv"
|
||||
|
||||
"github.com/golang/protobuf/ptypes/empty"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/client"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/client/beacon"
|
||||
eventClient "github.com/prysmaticlabs/prysm/v5/api/client/event"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/server/structs"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
"github.com/prysmaticlabs/prysm/v5/encoding/bytesutil"
|
||||
"github.com/prysmaticlabs/prysm/v5/monitoring/tracing/trace"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
type grpcValidatorClient struct {
|
||||
beaconNodeValidatorClient ethpb.BeaconNodeValidatorClient
|
||||
isEventStreamRunning bool
|
||||
}
|
||||
|
||||
func (c *grpcValidatorClient) Duties(ctx context.Context, in *ethpb.DutiesRequest) (*ethpb.ValidatorDutiesContainer, error) {
|
||||
dutiesResponse, err := c.beaconNodeValidatorClient.GetDuties(ctx, in)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return toValidatorDutiesContainer(dutiesResponse)
|
||||
}
|
||||
|
||||
func toValidatorDutiesContainer(dutiesResponse *ethpb.DutiesResponse) (*ethpb.ValidatorDutiesContainer, error) {
|
||||
currentDuties := make([]*ethpb.ValidatorDuty, len(dutiesResponse.CurrentEpochDuties))
|
||||
for i, cd := range dutiesResponse.CurrentEpochDuties {
|
||||
duty, err := toValidatorDuty(cd)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
currentDuties[i] = duty
|
||||
}
|
||||
nextDuties := make([]*ethpb.ValidatorDuty, len(dutiesResponse.NextEpochDuties))
|
||||
for i, nd := range dutiesResponse.NextEpochDuties {
|
||||
duty, err := toValidatorDuty(nd)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
nextDuties[i] = duty
|
||||
}
|
||||
return ðpb.ValidatorDutiesContainer{
|
||||
CurrentEpochDuties: currentDuties,
|
||||
NextEpochDuties: nextDuties,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func toValidatorDuty(duty *ethpb.DutiesResponse_Duty) (*ethpb.ValidatorDuty, error) {
|
||||
var valIndexInCommittee uint64
|
||||
// valIndexInCommittee will be 0 in case we don't get a match. This is a potential false positive,
|
||||
// however it's an impossible condition because every validator must be assigned to a committee.
|
||||
for cIndex, vIndex := range duty.Committee {
|
||||
if vIndex == duty.ValidatorIndex {
|
||||
valIndexInCommittee = uint64(cIndex)
|
||||
break
|
||||
}
|
||||
}
|
||||
return ðpb.ValidatorDuty{
|
||||
CommitteeLength: uint64(len(duty.Committee)),
|
||||
CommitteeIndex: duty.CommitteeIndex,
|
||||
CommitteesAtSlot: duty.CommitteesAtSlot, // GRPC doesn't use this value though
|
||||
ValidatorCommitteeIndex: valIndexInCommittee,
|
||||
AttesterSlot: duty.AttesterSlot,
|
||||
ProposerSlots: duty.ProposerSlots,
|
||||
PublicKey: bytesutil.SafeCopyBytes(duty.PublicKey),
|
||||
Status: duty.Status,
|
||||
ValidatorIndex: duty.ValidatorIndex,
|
||||
IsSyncCommittee: duty.IsSyncCommittee,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *grpcValidatorClient) CheckDoppelGanger(ctx context.Context, in *ethpb.DoppelGangerRequest) (*ethpb.DoppelGangerResponse, error) {
|
||||
return c.beaconNodeValidatorClient.CheckDoppelGanger(ctx, in)
|
||||
}
|
||||
|
||||
func (c *grpcValidatorClient) DomainData(ctx context.Context, in *ethpb.DomainRequest) (*ethpb.DomainResponse, error) {
|
||||
return c.beaconNodeValidatorClient.DomainData(ctx, in)
|
||||
}
|
||||
|
||||
func (c *grpcValidatorClient) AttestationData(ctx context.Context, in *ethpb.AttestationDataRequest) (*ethpb.AttestationData, error) {
|
||||
return c.beaconNodeValidatorClient.GetAttestationData(ctx, in)
|
||||
}
|
||||
|
||||
func (c *grpcValidatorClient) BeaconBlock(ctx context.Context, in *ethpb.BlockRequest) (*ethpb.GenericBeaconBlock, error) {
|
||||
return c.beaconNodeValidatorClient.GetBeaconBlock(ctx, in)
|
||||
}
|
||||
|
||||
func (c *grpcValidatorClient) FeeRecipientByPubKey(ctx context.Context, in *ethpb.FeeRecipientByPubKeyRequest) (*ethpb.FeeRecipientByPubKeyResponse, error) {
|
||||
return c.beaconNodeValidatorClient.GetFeeRecipientByPubKey(ctx, in)
|
||||
}
|
||||
|
||||
func (c *grpcValidatorClient) SyncCommitteeContribution(ctx context.Context, in *ethpb.SyncCommitteeContributionRequest) (*ethpb.SyncCommitteeContribution, error) {
|
||||
return c.beaconNodeValidatorClient.GetSyncCommitteeContribution(ctx, in)
|
||||
}
|
||||
|
||||
func (c *grpcValidatorClient) SyncMessageBlockRoot(ctx context.Context, in *empty.Empty) (*ethpb.SyncMessageBlockRootResponse, error) {
|
||||
return c.beaconNodeValidatorClient.GetSyncMessageBlockRoot(ctx, in)
|
||||
}
|
||||
|
||||
func (c *grpcValidatorClient) SyncSubcommitteeIndex(ctx context.Context, in *ethpb.SyncSubcommitteeIndexRequest) (*ethpb.SyncSubcommitteeIndexResponse, error) {
|
||||
return c.beaconNodeValidatorClient.GetSyncSubcommitteeIndex(ctx, in)
|
||||
}
|
||||
|
||||
func (c *grpcValidatorClient) MultipleValidatorStatus(ctx context.Context, in *ethpb.MultipleValidatorStatusRequest) (*ethpb.MultipleValidatorStatusResponse, error) {
|
||||
return c.beaconNodeValidatorClient.MultipleValidatorStatus(ctx, in)
|
||||
}
|
||||
|
||||
func (c *grpcValidatorClient) PrepareBeaconProposer(ctx context.Context, in *ethpb.PrepareBeaconProposerRequest) (*empty.Empty, error) {
|
||||
return c.beaconNodeValidatorClient.PrepareBeaconProposer(ctx, in)
|
||||
}
|
||||
|
||||
func (c *grpcValidatorClient) ProposeAttestation(ctx context.Context, in *ethpb.Attestation) (*ethpb.AttestResponse, error) {
|
||||
return c.beaconNodeValidatorClient.ProposeAttestation(ctx, in)
|
||||
}
|
||||
|
||||
func (c *grpcValidatorClient) ProposeAttestationElectra(ctx context.Context, in *ethpb.SingleAttestation) (*ethpb.AttestResponse, error) {
|
||||
return c.beaconNodeValidatorClient.ProposeAttestationElectra(ctx, in)
|
||||
}
|
||||
|
||||
func (c *grpcValidatorClient) ProposeBeaconBlock(ctx context.Context, in *ethpb.GenericSignedBeaconBlock) (*ethpb.ProposeResponse, error) {
|
||||
return c.beaconNodeValidatorClient.ProposeBeaconBlock(ctx, in)
|
||||
}
|
||||
|
||||
func (c *grpcValidatorClient) ProposeExit(ctx context.Context, in *ethpb.SignedVoluntaryExit) (*ethpb.ProposeExitResponse, error) {
|
||||
return c.beaconNodeValidatorClient.ProposeExit(ctx, in)
|
||||
}
|
||||
|
||||
func (c *grpcValidatorClient) StreamBlocksAltair(ctx context.Context, in *ethpb.StreamBlocksRequest) (ethpb.BeaconNodeValidator_StreamBlocksAltairClient, error) {
|
||||
return c.beaconNodeValidatorClient.StreamBlocksAltair(ctx, in)
|
||||
}
|
||||
|
||||
func (c *grpcValidatorClient) SubmitAggregateSelectionProof(ctx context.Context, in *ethpb.AggregateSelectionRequest, _ primitives.ValidatorIndex, _ uint64) (*ethpb.AggregateSelectionResponse, error) {
|
||||
return c.beaconNodeValidatorClient.SubmitAggregateSelectionProof(ctx, in)
|
||||
}
|
||||
|
||||
func (c *grpcValidatorClient) SubmitAggregateSelectionProofElectra(ctx context.Context, in *ethpb.AggregateSelectionRequest, _ primitives.ValidatorIndex, _ uint64) (*ethpb.AggregateSelectionElectraResponse, error) {
|
||||
return c.beaconNodeValidatorClient.SubmitAggregateSelectionProofElectra(ctx, in)
|
||||
}
|
||||
|
||||
func (c *grpcValidatorClient) SubmitSignedAggregateSelectionProof(ctx context.Context, in *ethpb.SignedAggregateSubmitRequest) (*ethpb.SignedAggregateSubmitResponse, error) {
|
||||
return c.beaconNodeValidatorClient.SubmitSignedAggregateSelectionProof(ctx, in)
|
||||
}
|
||||
|
||||
func (c *grpcValidatorClient) SubmitSignedAggregateSelectionProofElectra(ctx context.Context, in *ethpb.SignedAggregateSubmitElectraRequest) (*ethpb.SignedAggregateSubmitResponse, error) {
|
||||
return c.beaconNodeValidatorClient.SubmitSignedAggregateSelectionProofElectra(ctx, in)
|
||||
}
|
||||
|
||||
func (c *grpcValidatorClient) SubmitSignedContributionAndProof(ctx context.Context, in *ethpb.SignedContributionAndProof) (*empty.Empty, error) {
|
||||
return c.beaconNodeValidatorClient.SubmitSignedContributionAndProof(ctx, in)
|
||||
}
|
||||
|
||||
func (c *grpcValidatorClient) SubmitSyncMessage(ctx context.Context, in *ethpb.SyncCommitteeMessage) (*empty.Empty, error) {
|
||||
return c.beaconNodeValidatorClient.SubmitSyncMessage(ctx, in)
|
||||
}
|
||||
|
||||
func (c *grpcValidatorClient) SubmitValidatorRegistrations(ctx context.Context, in *ethpb.SignedValidatorRegistrationsV1) (*empty.Empty, error) {
|
||||
return c.beaconNodeValidatorClient.SubmitValidatorRegistrations(ctx, in)
|
||||
}
|
||||
|
||||
func (c *grpcValidatorClient) SubscribeCommitteeSubnets(ctx context.Context, in *ethpb.CommitteeSubnetsSubscribeRequest, _ []*ethpb.ValidatorDuty) (*empty.Empty, error) {
|
||||
return c.beaconNodeValidatorClient.SubscribeCommitteeSubnets(ctx, in)
|
||||
}
|
||||
|
||||
func (c *grpcValidatorClient) ValidatorIndex(ctx context.Context, in *ethpb.ValidatorIndexRequest) (*ethpb.ValidatorIndexResponse, error) {
|
||||
return c.beaconNodeValidatorClient.ValidatorIndex(ctx, in)
|
||||
}
|
||||
|
||||
func (c *grpcValidatorClient) ValidatorStatus(ctx context.Context, in *ethpb.ValidatorStatusRequest) (*ethpb.ValidatorStatusResponse, error) {
|
||||
return c.beaconNodeValidatorClient.ValidatorStatus(ctx, in)
|
||||
}
|
||||
|
||||
// Deprecated: Do not use.
|
||||
func (c *grpcValidatorClient) WaitForChainStart(ctx context.Context, in *empty.Empty) (*ethpb.ChainStartResponse, error) {
|
||||
stream, err := c.beaconNodeValidatorClient.WaitForChainStart(ctx, in)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(
|
||||
client.ErrConnectionIssue,
|
||||
errors.Wrap(err, "could not setup beacon chain ChainStart streaming client").Error(),
|
||||
)
|
||||
}
|
||||
|
||||
return stream.Recv()
|
||||
}
|
||||
|
||||
func (c *grpcValidatorClient) AssignValidatorToSubnet(ctx context.Context, in *ethpb.AssignValidatorToSubnetRequest) (*empty.Empty, error) {
|
||||
return c.beaconNodeValidatorClient.AssignValidatorToSubnet(ctx, in)
|
||||
}
|
||||
func (c *grpcValidatorClient) AggregatedSigAndAggregationBits(
|
||||
ctx context.Context,
|
||||
in *ethpb.AggregatedSigAndAggregationBitsRequest,
|
||||
) (*ethpb.AggregatedSigAndAggregationBitsResponse, error) {
|
||||
return c.beaconNodeValidatorClient.AggregatedSigAndAggregationBits(ctx, in)
|
||||
}
|
||||
|
||||
func (*grpcValidatorClient) AggregatedSelections(context.Context, []beacon.BeaconCommitteeSelection) ([]beacon.BeaconCommitteeSelection, error) {
|
||||
return nil, client.ErrNotSupported
|
||||
}
|
||||
|
||||
func (*grpcValidatorClient) AggregatedSyncSelections(context.Context, []beacon.SyncCommitteeSelection) ([]beacon.SyncCommitteeSelection, error) {
|
||||
return nil, client.ErrNotSupported
|
||||
}
|
||||
|
||||
func NewGrpcValidatorClient(cc grpc.ClientConnInterface) Client {
|
||||
return &grpcValidatorClient{ethpb.NewBeaconNodeValidatorClient(cc), false}
|
||||
}
|
||||
|
||||
func (c *grpcValidatorClient) StartEventStream(ctx context.Context, topics []string, eventsChannel chan<- *eventClient.Event) {
|
||||
ctx, span := trace.StartSpan(ctx, "validator.gRPCClient.StartEventStream")
|
||||
defer span.End()
|
||||
if len(topics) == 0 {
|
||||
eventsChannel <- &eventClient.Event{
|
||||
EventType: eventClient.EventError,
|
||||
Data: []byte(errors.New("no topics were added").Error()),
|
||||
}
|
||||
return
|
||||
}
|
||||
// TODO(13563): ONLY WORKS WITH HEAD TOPIC RIGHT NOW/ONLY PROVIDES THE SLOT
|
||||
containsHead := false
|
||||
for i := range topics {
|
||||
if topics[i] == eventClient.EventHead {
|
||||
containsHead = true
|
||||
}
|
||||
}
|
||||
if !containsHead {
|
||||
eventsChannel <- &eventClient.Event{
|
||||
EventType: eventClient.EventConnectionError,
|
||||
Data: []byte(errors.Wrap(client.ErrConnectionIssue, "gRPC only supports the head topic, and head topic was not passed").Error()),
|
||||
}
|
||||
}
|
||||
if containsHead && len(topics) > 1 {
|
||||
log.Warn("gRPC only supports the head topic, other topics will be ignored")
|
||||
}
|
||||
|
||||
stream, err := c.beaconNodeValidatorClient.StreamSlots(ctx, ðpb.StreamSlotsRequest{VerifiedOnly: true})
|
||||
if err != nil {
|
||||
eventsChannel <- &eventClient.Event{
|
||||
EventType: eventClient.EventConnectionError,
|
||||
Data: []byte(errors.Wrap(client.ErrConnectionIssue, err.Error()).Error()),
|
||||
}
|
||||
return
|
||||
}
|
||||
c.isEventStreamRunning = true
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
log.Info("Context canceled, stopping event stream")
|
||||
close(eventsChannel)
|
||||
c.isEventStreamRunning = false
|
||||
return
|
||||
default:
|
||||
if ctx.Err() != nil {
|
||||
c.isEventStreamRunning = false
|
||||
if errors.Is(ctx.Err(), context.Canceled) {
|
||||
eventsChannel <- &eventClient.Event{
|
||||
EventType: eventClient.EventConnectionError,
|
||||
Data: []byte(errors.Wrap(client.ErrConnectionIssue, ctx.Err().Error()).Error()),
|
||||
}
|
||||
return
|
||||
}
|
||||
eventsChannel <- &eventClient.Event{
|
||||
EventType: eventClient.EventError,
|
||||
Data: []byte(ctx.Err().Error()),
|
||||
}
|
||||
return
|
||||
}
|
||||
res, err := stream.Recv()
|
||||
if err != nil {
|
||||
c.isEventStreamRunning = false
|
||||
eventsChannel <- &eventClient.Event{
|
||||
EventType: eventClient.EventConnectionError,
|
||||
Data: []byte(errors.Wrap(client.ErrConnectionIssue, err.Error()).Error()),
|
||||
}
|
||||
return
|
||||
}
|
||||
if res == nil {
|
||||
continue
|
||||
}
|
||||
b, err := json.Marshal(structs.HeadEvent{
|
||||
Slot: strconv.FormatUint(uint64(res.Slot), 10),
|
||||
})
|
||||
if err != nil {
|
||||
eventsChannel <- &eventClient.Event{
|
||||
EventType: eventClient.EventError,
|
||||
Data: []byte(errors.Wrap(err, "failed to marshal Head Event").Error()),
|
||||
}
|
||||
}
|
||||
eventsChannel <- &eventClient.Event{
|
||||
EventType: eventClient.EventHead,
|
||||
Data: b,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (c *grpcValidatorClient) EventStreamIsRunning() bool {
|
||||
return c.isEventStreamRunning
|
||||
}
|
||||
|
||||
func (*grpcValidatorClient) Host() string {
|
||||
log.Warn(client.ErrNotSupported)
|
||||
return ""
|
||||
}
|
||||
|
||||
func (*grpcValidatorClient) SetHost(_ string) {
|
||||
log.Warn(client.ErrNotSupported)
|
||||
}
|
||||
185
api/client/beacon/validator_api/grpc_client_test.go
Normal file
185
api/client/beacon/validator_api/grpc_client_test.go
Normal file
@@ -0,0 +1,185 @@
|
||||
package validator_api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
eventClient "github.com/prysmaticlabs/prysm/v5/api/client/event"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/server/structs"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
eth "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v5/testing/assert"
|
||||
mock2 "github.com/prysmaticlabs/prysm/v5/testing/mock"
|
||||
"github.com/prysmaticlabs/prysm/v5/testing/require"
|
||||
logTest "github.com/sirupsen/logrus/hooks/test"
|
||||
"go.uber.org/mock/gomock"
|
||||
"google.golang.org/protobuf/types/known/emptypb"
|
||||
)
|
||||
|
||||
// toValidatorDutiesContainer is assumed to be available from your package, returning a *v1alpha1.ValidatorDutiesContainer.
|
||||
func TestToValidatorDutiesContainer_HappyPath(t *testing.T) {
|
||||
// Create a mock DutiesResponse with current and next duties.
|
||||
dutiesResp := ð.DutiesResponse{
|
||||
CurrentEpochDuties: []*eth.DutiesResponse_Duty{
|
||||
{
|
||||
Committee: []primitives.ValidatorIndex{100, 101},
|
||||
CommitteeIndex: 4,
|
||||
AttesterSlot: 200,
|
||||
ProposerSlots: []primitives.Slot{400},
|
||||
PublicKey: []byte{0xAA, 0xBB},
|
||||
Status: eth.ValidatorStatus_ACTIVE,
|
||||
ValidatorIndex: 101,
|
||||
IsSyncCommittee: false,
|
||||
CommitteesAtSlot: 2,
|
||||
},
|
||||
},
|
||||
NextEpochDuties: []*eth.DutiesResponse_Duty{
|
||||
{
|
||||
Committee: []primitives.ValidatorIndex{300, 301},
|
||||
CommitteeIndex: 8,
|
||||
AttesterSlot: 600,
|
||||
ProposerSlots: []primitives.Slot{700, 701},
|
||||
PublicKey: []byte{0xCC, 0xDD},
|
||||
Status: eth.ValidatorStatus_ACTIVE,
|
||||
ValidatorIndex: 301,
|
||||
IsSyncCommittee: true,
|
||||
CommitteesAtSlot: 3,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
gotContainer, err := toValidatorDutiesContainer(dutiesResp)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Validate we have the correct number of duties in current and next epochs.
|
||||
assert.Equal(t, len(gotContainer.CurrentEpochDuties), len(dutiesResp.CurrentEpochDuties))
|
||||
assert.Equal(t, len(gotContainer.NextEpochDuties), len(dutiesResp.NextEpochDuties))
|
||||
|
||||
firstCurrentDuty := gotContainer.CurrentEpochDuties[0]
|
||||
expectedCurrentDuty := dutiesResp.CurrentEpochDuties[0]
|
||||
assert.DeepEqual(t, firstCurrentDuty.PublicKey, expectedCurrentDuty.PublicKey)
|
||||
assert.Equal(t, firstCurrentDuty.ValidatorIndex, expectedCurrentDuty.ValidatorIndex)
|
||||
assert.DeepEqual(t, firstCurrentDuty.ProposerSlots, expectedCurrentDuty.ProposerSlots)
|
||||
|
||||
firstNextDuty := gotContainer.NextEpochDuties[0]
|
||||
expectedNextDuty := dutiesResp.NextEpochDuties[0]
|
||||
assert.DeepEqual(t, firstNextDuty.PublicKey, expectedNextDuty.PublicKey)
|
||||
assert.Equal(t, firstNextDuty.ValidatorIndex, expectedNextDuty.ValidatorIndex)
|
||||
assert.DeepEqual(t, firstNextDuty.ProposerSlots, expectedNextDuty.ProposerSlots)
|
||||
}
|
||||
|
||||
func TestWaitForChainStart_StreamSetupFails(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
|
||||
beaconNodeValidatorClient := mock2.NewMockBeaconNodeValidatorClient(ctrl)
|
||||
beaconNodeValidatorClient.EXPECT().WaitForChainStart(
|
||||
gomock.Any(),
|
||||
gomock.Any(),
|
||||
).Return(nil, errors.New("failed stream"))
|
||||
|
||||
validatorClient := &grpcValidatorClient{beaconNodeValidatorClient, true}
|
||||
_, err := validatorClient.WaitForChainStart(context.Background(), &emptypb.Empty{})
|
||||
want := "could not setup beacon chain ChainStart streaming client"
|
||||
assert.ErrorContains(t, want, err)
|
||||
}
|
||||
|
||||
func TestStartEventStream(t *testing.T) {
|
||||
hook := logTest.NewGlobal()
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
beaconNodeValidatorClient := mock2.NewMockBeaconNodeValidatorClient(ctrl)
|
||||
grpcClient := &grpcValidatorClient{beaconNodeValidatorClient, true}
|
||||
tests := []struct {
|
||||
name string
|
||||
topics []string
|
||||
prepare func()
|
||||
verify func(t *testing.T, event *eventClient.Event)
|
||||
}{
|
||||
{
|
||||
name: "Happy path Head topic",
|
||||
topics: []string{"head"},
|
||||
prepare: func() {
|
||||
stream := mock2.NewMockBeaconNodeValidator_StreamSlotsClient(ctrl)
|
||||
beaconNodeValidatorClient.EXPECT().StreamSlots(gomock.Any(),
|
||||
ð.StreamSlotsRequest{VerifiedOnly: true}).Return(stream, nil)
|
||||
stream.EXPECT().Context().Return(ctx).AnyTimes()
|
||||
stream.EXPECT().Recv().Return(
|
||||
ð.StreamSlotsResponse{Slot: 123},
|
||||
nil,
|
||||
).AnyTimes()
|
||||
},
|
||||
verify: func(t *testing.T, event *eventClient.Event) {
|
||||
require.Equal(t, event.EventType, eventClient.EventHead)
|
||||
head := structs.HeadEvent{}
|
||||
require.NoError(t, json.Unmarshal(event.Data, &head))
|
||||
require.Equal(t, head.Slot, "123")
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "no head produces error",
|
||||
topics: []string{"unsupportedTopic"},
|
||||
prepare: func() {
|
||||
stream := mock2.NewMockBeaconNodeValidator_StreamSlotsClient(ctrl)
|
||||
beaconNodeValidatorClient.EXPECT().StreamSlots(gomock.Any(),
|
||||
ð.StreamSlotsRequest{VerifiedOnly: true}).Return(stream, nil)
|
||||
stream.EXPECT().Context().Return(ctx).AnyTimes()
|
||||
stream.EXPECT().Recv().Return(
|
||||
ð.StreamSlotsResponse{Slot: 123},
|
||||
nil,
|
||||
).AnyTimes()
|
||||
},
|
||||
verify: func(t *testing.T, event *eventClient.Event) {
|
||||
require.Equal(t, event.EventType, eventClient.EventConnectionError)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Unsupported topics warning",
|
||||
topics: []string{"head", "unsupportedTopic"},
|
||||
prepare: func() {
|
||||
stream := mock2.NewMockBeaconNodeValidator_StreamSlotsClient(ctrl)
|
||||
beaconNodeValidatorClient.EXPECT().StreamSlots(gomock.Any(),
|
||||
ð.StreamSlotsRequest{VerifiedOnly: true}).Return(stream, nil)
|
||||
stream.EXPECT().Context().Return(ctx).AnyTimes()
|
||||
stream.EXPECT().Recv().Return(
|
||||
ð.StreamSlotsResponse{Slot: 123},
|
||||
nil,
|
||||
).AnyTimes()
|
||||
},
|
||||
verify: func(t *testing.T, event *eventClient.Event) {
|
||||
require.Equal(t, event.EventType, eventClient.EventHead)
|
||||
head := structs.HeadEvent{}
|
||||
require.NoError(t, json.Unmarshal(event.Data, &head))
|
||||
require.Equal(t, head.Slot, "123")
|
||||
assert.LogsContain(t, hook, "gRPC only supports the head topic")
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "No topics error",
|
||||
topics: []string{},
|
||||
prepare: func() {},
|
||||
verify: func(t *testing.T, event *eventClient.Event) {
|
||||
require.Equal(t, event.EventType, eventClient.EventError)
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
eventsChannel := make(chan *eventClient.Event, 1) // Buffer to prevent blocking
|
||||
tc.prepare() // Setup mock expectations
|
||||
|
||||
go grpcClient.StartEventStream(ctx, tc.topics, eventsChannel)
|
||||
|
||||
event := <-eventsChannel
|
||||
// Depending on what you're testing, you may need a timeout or a specific number of events to read
|
||||
time.AfterFunc(1*time.Second, cancel) // Prevents hanging forever
|
||||
tc.verify(t, event)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package beacon_api
|
||||
package validator_api
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -7,8 +7,8 @@ import (
|
||||
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
)
|
||||
|
||||
// IndexNotFoundError represents an error scenario where no validator index matches a pubkey.
|
||||
@@ -28,10 +28,10 @@ func (e *IndexNotFoundError) Error() string {
|
||||
return e.message
|
||||
}
|
||||
|
||||
func (c beaconApiValidatorClient) validatorIndex(ctx context.Context, in *ethpb.ValidatorIndexRequest) (*ethpb.ValidatorIndexResponse, error) {
|
||||
func (c *beaconApiValidatorClient) validatorIndex(ctx context.Context, in *ethpb.ValidatorIndexRequest) (*ethpb.ValidatorIndexResponse, error) {
|
||||
stringPubKey := hexutil.Encode(in.PublicKey)
|
||||
|
||||
stateValidator, err := c.stateValidatorsProvider.GetStateValidators(ctx, []string{stringPubKey}, nil, nil)
|
||||
stateValidator, err := c.stateValidatorsProvider.StateValidators(ctx, []string{stringPubKey}, nil, nil)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to get state validator")
|
||||
}
|
||||
@@ -1,20 +1,23 @@
|
||||
package beacon_api
|
||||
package validator_api
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/url"
|
||||
"testing"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/golang/mock/gomock"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/beacon"
|
||||
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v4/testing/assert"
|
||||
"github.com/prysmaticlabs/prysm/v4/testing/require"
|
||||
"github.com/prysmaticlabs/prysm/v4/validator/client/beacon-api/mock"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/apiutil"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/client/beacon/mock"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/client/beacon/shared_providers"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/server/structs"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v5/testing/assert"
|
||||
"github.com/prysmaticlabs/prysm/v5/testing/require"
|
||||
"go.uber.org/mock/gomock"
|
||||
)
|
||||
|
||||
const stringPubKey = "0x8000091c2ae64ee414a54c1cc1fc67dec663408bc636cb86756e0200e41a75c8f86603f104f02c856983d2783116be13"
|
||||
@@ -22,10 +25,11 @@ const stringPubKey = "0x8000091c2ae64ee414a54c1cc1fc67dec663408bc636cb86756e0200
|
||||
func getPubKeyAndReqBuffer(t *testing.T) ([]byte, *bytes.Buffer) {
|
||||
pubKey, err := hexutil.Decode(stringPubKey)
|
||||
require.NoError(t, err)
|
||||
req := beacon.GetValidatorsRequest{
|
||||
req := structs.GetValidatorsRequest{
|
||||
Ids: []string{stringPubKey},
|
||||
Statuses: []string{},
|
||||
}
|
||||
|
||||
reqBytes, err := json.Marshal(req)
|
||||
require.NoError(t, err)
|
||||
return pubKey, bytes.NewBuffer(reqBytes)
|
||||
@@ -38,26 +42,25 @@ func TestIndex_Nominal(t *testing.T) {
|
||||
pubKey, reqBuffer := getPubKeyAndReqBuffer(t)
|
||||
ctx := context.Background()
|
||||
|
||||
stateValidatorsResponseJson := beacon.GetValidatorsResponse{}
|
||||
stateValidatorsResponseJson := structs.GetValidatorsResponse{}
|
||||
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
|
||||
|
||||
jsonRestHandler.EXPECT().Post(
|
||||
ctx,
|
||||
gomock.Any(),
|
||||
"/eth/v1/beacon/states/head/validators",
|
||||
nil,
|
||||
reqBuffer,
|
||||
&stateValidatorsResponseJson,
|
||||
).Return(
|
||||
nil,
|
||||
nil,
|
||||
).SetArg(
|
||||
4,
|
||||
beacon.GetValidatorsResponse{
|
||||
Data: []*beacon.ValidatorContainer{
|
||||
structs.GetValidatorsResponse{
|
||||
Data: []*structs.ValidatorContainer{
|
||||
{
|
||||
Index: "55293",
|
||||
Status: "active_ongoing",
|
||||
Validator: &beacon.Validator{
|
||||
Validator: &structs.Validator{
|
||||
Pubkey: stringPubKey,
|
||||
},
|
||||
},
|
||||
@@ -66,9 +69,7 @@ func TestIndex_Nominal(t *testing.T) {
|
||||
).Times(1)
|
||||
|
||||
validatorClient := beaconApiValidatorClient{
|
||||
stateValidatorsProvider: beaconApiStateValidatorsProvider{
|
||||
jsonRestHandler: jsonRestHandler,
|
||||
},
|
||||
stateValidatorsProvider: shared_providers.NewStateValidators(jsonRestHandler),
|
||||
}
|
||||
|
||||
validatorIndex, err := validatorClient.ValidatorIndex(
|
||||
@@ -89,29 +90,26 @@ func TestIndex_UnexistingValidator(t *testing.T) {
|
||||
pubKey, reqBuffer := getPubKeyAndReqBuffer(t)
|
||||
ctx := context.Background()
|
||||
|
||||
stateValidatorsResponseJson := beacon.GetValidatorsResponse{}
|
||||
stateValidatorsResponseJson := structs.GetValidatorsResponse{}
|
||||
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
|
||||
|
||||
jsonRestHandler.EXPECT().Post(
|
||||
ctx,
|
||||
gomock.Any(),
|
||||
"/eth/v1/beacon/states/head/validators",
|
||||
nil,
|
||||
reqBuffer,
|
||||
&stateValidatorsResponseJson,
|
||||
).Return(
|
||||
nil,
|
||||
nil,
|
||||
).SetArg(
|
||||
4,
|
||||
beacon.GetValidatorsResponse{
|
||||
Data: []*beacon.ValidatorContainer{},
|
||||
structs.GetValidatorsResponse{
|
||||
Data: []*structs.ValidatorContainer{},
|
||||
},
|
||||
).Times(1)
|
||||
|
||||
validatorClient := beaconApiValidatorClient{
|
||||
stateValidatorsProvider: beaconApiStateValidatorsProvider{
|
||||
jsonRestHandler: jsonRestHandler,
|
||||
},
|
||||
stateValidatorsProvider: shared_providers.NewStateValidators(jsonRestHandler),
|
||||
}
|
||||
|
||||
_, err := validatorClient.ValidatorIndex(
|
||||
@@ -132,26 +130,25 @@ func TestIndex_BadIndexError(t *testing.T) {
|
||||
pubKey, reqBuffer := getPubKeyAndReqBuffer(t)
|
||||
ctx := context.Background()
|
||||
|
||||
stateValidatorsResponseJson := beacon.GetValidatorsResponse{}
|
||||
stateValidatorsResponseJson := structs.GetValidatorsResponse{}
|
||||
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
|
||||
|
||||
jsonRestHandler.EXPECT().Post(
|
||||
ctx,
|
||||
gomock.Any(),
|
||||
"/eth/v1/beacon/states/head/validators",
|
||||
nil,
|
||||
reqBuffer,
|
||||
&stateValidatorsResponseJson,
|
||||
).Return(
|
||||
nil,
|
||||
nil,
|
||||
).SetArg(
|
||||
4,
|
||||
beacon.GetValidatorsResponse{
|
||||
Data: []*beacon.ValidatorContainer{
|
||||
structs.GetValidatorsResponse{
|
||||
Data: []*structs.ValidatorContainer{
|
||||
{
|
||||
Index: "This is not an index",
|
||||
Status: "active_ongoing",
|
||||
Validator: &beacon.Validator{
|
||||
Validator: &structs.Validator{
|
||||
Pubkey: stringPubKey,
|
||||
},
|
||||
},
|
||||
@@ -160,9 +157,7 @@ func TestIndex_BadIndexError(t *testing.T) {
|
||||
).Times(1)
|
||||
|
||||
validatorClient := beaconApiValidatorClient{
|
||||
stateValidatorsProvider: beaconApiStateValidatorsProvider{
|
||||
jsonRestHandler: jsonRestHandler,
|
||||
},
|
||||
stateValidatorsProvider: shared_providers.NewStateValidators(jsonRestHandler),
|
||||
}
|
||||
|
||||
_, err := validatorClient.ValidatorIndex(
|
||||
@@ -182,24 +177,42 @@ func TestIndex_JsonResponseError(t *testing.T) {
|
||||
pubKey, reqBuffer := getPubKeyAndReqBuffer(t)
|
||||
ctx := context.Background()
|
||||
|
||||
stateValidatorsResponseJson := beacon.GetValidatorsResponse{}
|
||||
stateValidatorsResponseJson := structs.GetValidatorsResponse{}
|
||||
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
|
||||
|
||||
jsonRestHandler.EXPECT().Post(
|
||||
ctx,
|
||||
gomock.Any(),
|
||||
"/eth/v1/beacon/states/head/validators",
|
||||
nil,
|
||||
reqBuffer,
|
||||
&stateValidatorsResponseJson,
|
||||
).Return(
|
||||
nil,
|
||||
errors.New("some specific json error"),
|
||||
).Times(1)
|
||||
|
||||
req := structs.GetValidatorsRequest{
|
||||
Ids: []string{stringPubKey},
|
||||
Statuses: []string{},
|
||||
}
|
||||
|
||||
queryParams := url.Values{}
|
||||
for _, id := range req.Ids {
|
||||
queryParams.Add("id", id)
|
||||
}
|
||||
for _, st := range req.Statuses {
|
||||
queryParams.Add("status", st)
|
||||
}
|
||||
|
||||
jsonRestHandler.EXPECT().Get(
|
||||
gomock.Any(),
|
||||
apiutil.BuildURL("/eth/v1/beacon/states/head/validators", queryParams),
|
||||
&stateValidatorsResponseJson,
|
||||
).Return(
|
||||
errors.New("some specific json error"),
|
||||
).Times(1)
|
||||
|
||||
validatorClient := beaconApiValidatorClient{
|
||||
stateValidatorsProvider: beaconApiStateValidatorsProvider{
|
||||
jsonRestHandler: jsonRestHandler,
|
||||
},
|
||||
stateValidatorsProvider: shared_providers.NewStateValidators(jsonRestHandler),
|
||||
}
|
||||
|
||||
_, err := validatorClient.ValidatorIndex(
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user