Compare commits

...

329 Commits

Author SHA1 Message Date
james-prysm
1f3056ac84 move api util outside the client package 2025-04-03 10:07:23 -05:00
james-prysm
4ab86838b8 gaz 2025-04-02 17:36:23 -05:00
james-prysm
203ac12216 linting 2025-04-02 17:20:58 -05:00
james-prysm
2e0d4ac184 remove unused import 2025-04-02 17:12:03 -05:00
james-prysm
9c598ea9aa Merge branch 'develop' into migrate-rpc-clients 2025-04-02 16:54:32 -05:00
james-prysm
2cfc204e9a removed redundant mock validator and replaced with test util one (#15111) 2025-04-02 21:17:20 +00:00
james-prysm
e859fc4e09 Merge branch 'develop' into migrate-rpc-clients 2025-04-02 15:48:45 -05:00
james-prysm
c0021f91c2 updating lots of tests and finally getting the build to work successfully 2025-04-02 15:48:04 -05:00
Nishant Das
877d9ee948 Revert Execution Requests in E2E (#15119)
* Revert "Disable Execution Request Testing On Mainnet (#15115)"

This reverts commit 70c31949ba.

* Revert "Trigger Execution Requests In E2E (#14971)"

This reverts commit e38fdb09a4.

* Changelog
2025-04-02 16:12:35 +00:00
Kaloyan Tanev
785fefa3f1 Do not cache slot committee aggregations for DVs (#15110)
* Do not cache slot committee for DV agggregations

* Add changelog

---------

Co-authored-by: Radosław Kapka <rkapka@wp.pl>
2025-04-02 15:54:47 +00:00
kevincatty
0c22d91a55 fix: remove duplicate WithBlobStorage in options initialization (#15036)
Signed-off-by: kevincatty <zhanshanmao@outlook.com>
Co-authored-by: Radosław Kapka <rkapka@wp.pl>
2025-04-02 15:25:00 +00:00
NikolaiKryshnev
fb60456116 Improved README structure and visual presentation (#14860)
Co-authored-by: Radosław Kapka <rkapka@wp.pl>
2025-04-02 15:23:10 +00:00
jinjiadu
be56711892 fix: fix slice init length (#14407)
Signed-off-by: jinjiadu <jinjiadu@aliyun.com>
Co-authored-by: Radosław Kapka <rkapka@wp.pl>
2025-04-02 15:21:26 +00:00
james-prysm
370ae9a12c more wip 2025-04-01 15:56:35 -05:00
kasey
96f1ebf706 more efficient ancestry db queries, stategen (#15063)
Co-authored-by: Kasey <kasey@users.noreply.github.com>
2025-04-01 20:16:58 +00:00
james-prysm
fb755c7f3b more wip 2025-04-01 15:07:43 -05:00
John
bdb12c7d2f fix: use io.ReadFull instead of stream.Read (#15089) 2025-04-01 19:23:04 +00:00
LesCyber
83cf0f8658 refactor: use errors.New to replace fmt.Errorf with no parameters (#15007)
Signed-off-by: LesCyber <andi4cing@gmail.com>
2025-04-01 19:03:16 +00:00
VolodymyrBg
762594a368 feat(proposer): add gas limit range warnings (#15078)
* feat(proposer): add gas limit range warnings

* Update config/proposer/loader/loader.go

Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>

* Update config/proposer/loader/loader.go

Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>

* Create volodymyrbg_gas_limit_warnings.md

---------

Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
2025-04-01 19:00:21 +00:00
kilavvy
c1fc812a38 Fix typos in test code (#14991)
* Update keymanager_test.go

* Update fork_test.go

* Update README.md

* Update README.md
2025-04-01 18:31:59 +00:00
riyueguang
340935af9c refactor: use the built-in min to simplify the code (#15091)
Signed-off-by: riyueguang <rustruby@outlook.com>
2025-04-01 17:57:22 +00:00
kasey
17d0082c5c cleanup block indices for missing blocks (#15040)
Co-authored-by: Kasey Kirkham <kasey@users.noreply.github.com>
2025-04-01 17:54:35 +00:00
terence
e998b5ec97 Use latest state to pack attestation (#15113)
* Use latest state to pack attestation

* Add a test to make sure it would have failed when using head state instead of latest state
2025-04-01 15:31:45 +00:00
james-prysm
5d0eb3168c small optimization (#15116) 2025-04-01 14:55:29 +00:00
terence
e0c2aa71d4 Update spec tests to beta 4 (#15114)
* Update spec tests to beta 4

* Change log to ignored
2025-04-01 14:32:57 +00:00
james-prysm
6eff474042 WIP 2025-04-01 09:05:42 -05:00
Nishant Das
70c31949ba Disable Execution Request Testing On Mainnet (#15115)
* DisableOnMainnet

* Changelog
2025-04-01 10:38:05 +00:00
Nishant Das
e38fdb09a4 Trigger Execution Requests In E2E (#14971)
* Trigger Consolidation

* Finally have it working

* Fix Build

* Revert Change

* Fix Context

* Finally have consolidations working

* Get Evaluator Working

* Get Withdrawals Working

* Changelog

* Finally Passes

* New line

* Try again

* fmt

* fmt

* Fix Test
2025-04-01 06:49:51 +00:00
james-prysm
a50e981c74 removing redundant loop in computeOnChainAggregate (#15108)
* removing redundant loop

* Update beacon-chain/rpc/prysm/v1alpha1/validator/proposer_attestations_electra.go

Co-authored-by: Radosław Kapka <rkapka@wp.pl>

* removing unused import

* replacing with more used function

* resolving Unsafe cast from uint64 to int error

---------

Co-authored-by: Radosław Kapka <rkapka@wp.pl>
2025-03-31 21:22:47 +00:00
Bastin
8be205cf3d Use fieldparams.RootLength instead of local variable in p2p types.go (#15106)
* use fieldparams.RootLength instead of local var

* gazelle fix
2025-03-31 12:42:07 +00:00
kasey
1b65e00096 refactor state-by-root test to table-driven (#15087)
Co-authored-by: Kasey Kirkham <kasey@users.noreply.github.com>
2025-03-28 23:34:34 +00:00
james-prysm
e3fb4e86ec validator client initialization cleanup (#15080)
* cleanup

* fixing optimal sort order for struct

* reverting clictx change based on kasey's feedback

* adding in fix for old trace file flag

* more cleanup for clarity

* optimizing if statement check and fixing wallet open on web enable

* optimizing if statement check and fixing wallet open on web enable

* some more cleanup and bug fix on open wallet

* reverting debug.go changes will handle in a separate PR

* removing useless comment

* changing useWeb to enableAPI

* fixing tests and linting

* manu feedback and one optimization removing auth token check

* gaz
2025-03-28 14:03:42 +00:00
terence
70aaad1904 Add more tests to process pending deposits (#15099) 2025-03-27 14:16:41 +00:00
Radosław Kapka
e42611ec72 Allow hex strings in /eth/v1/beacon/states/{state_id}/root endpoint (#15098)
* Allow hex strings in `/eth/v1/beacon/states/{state_id}/root` endpoint

* changelog <3

* remove redundant conversion

* use `bytesutil.IsHex`
2025-03-27 14:13:57 +00:00
Bastin
a3e61275a3 Add light client types to spectest (#15097)
* add light client types to spectest

* changelog entry

* remove lightclientSnapshot from tests
2025-03-26 17:44:30 +00:00
terence
e82f9ccca3 Proposer: change attestation sorting to reward numerator (#15093)
* Change proposer block's sorting algo to proposer reward numerator

* Feedback

* Comments

* Add a cache for attestation reward numerator
2025-03-26 16:21:41 +00:00
Bastin
38a6a7a4ea Add SSZ support for light client updates by range API (#15082)
* create ssz payload

* remove unused function

* remove access to state

* gazelle fix

* fix ssz size for electra finality update

* fix fork digest version problem

* fix chunk size

* fix fork version

* fix fork version

* add tests

* add changelog entry

* add PR link in changelog entry

* fix lint error

* Update beacon-chain/rpc/eth/light-client/handlers.go

Co-authored-by: Preston Van Loon <pvanloon@offchainlabs.com>

* check for context error

* send response in chunks

* remove content disposition header

---------

Co-authored-by: Preston Van Loon <pvanloon@offchainlabs.com>
2025-03-26 15:06:03 +00:00
Bastin
1295c987e8 Remove content disposition header from httputil.WriteSSZ (#15092)
* remove content disposition header from httputil.WriteSSZ

* fix changelog

* fix newly added calls to WriteSSZ
2025-03-26 14:17:19 +00:00
Radosław Kapka
6a27c41aad Implement validator identities Beacon API endpoint (#15086)
* implementation

* tests

* changelog <3

* linter fix

* test fix
2025-03-25 16:49:35 +00:00
Radosław Kapka
98b13ea144 Update changelog for v5.3.2 release (#15096)
* Changelog for v5.3.2

* add header section

* fragment file
2025-03-25 16:38:29 +00:00
james-prysm
c735ed2e32 Remove use of committee list from validator client (#15039)
* wip

* fixing unit tests

* changing is aggregator function

* wip

* fully removing the use of committee from validator client, adding a wrapper type for duties

* fixing tests

* fixing linting

* fixing more tests

* changelog

* adding some more tests

* Update proto/prysm/v1alpha1/validator.go

Co-authored-by: Radosław Kapka <rkapka@wp.pl>

* radek's feedback

* removing accidently checked in

---------

Co-authored-by: Radosław Kapka <rkapka@wp.pl>
2025-03-25 16:25:42 +00:00
Potuz
bd17779231 Use headstate to validate canonical attestations for old targets (#15095)
* Use headstate to validate canonical attestations for old targets

* Update beacon-chain/blockchain/process_attestation_helpers.go

Co-authored-by: Radosław Kapka <rkapka@wp.pl>

---------

Co-authored-by: Radosław Kapka <rkapka@wp.pl>
2025-03-25 13:36:47 +00:00
james-prysm
e08ed0d823 Deprecate broken and unused debug flags in favor of --pprof (#15083)
* deprecating the trace and cpuprofile flags in favor of pprof

* gaz

* fixing change log title

* added hidden tags
2025-03-24 19:30:32 +00:00
xinhangzhou
2b4d8a09ff refactor: use maps.Copy for cleaner map handling (#15090)
Signed-off-by: xinhangzhou <shuangcui@aliyun.com>
2025-03-24 19:23:10 +00:00
Potuz
21e1f7883b Add feature flag to blacklist blocks (#15030)
* Add feature flag to blacklist blocks

* review and add tests

* add test

* review

* Kasey's review

---------

Co-authored-by: Radosław Kapka <rkapka@wp.pl>
2025-03-21 22:20:39 +00:00
Julian Yap
bfa24606c3 refactor: Remove redundant string conversion in BeaconDbStater.State (#15081) 2025-03-21 16:23:16 +00:00
Potuz
d7628bab37 Fix genesis block proposal (#15084)
* Fix genesis block proposal

* fix test

* fix test 2
2025-03-21 15:34:22 +00:00
Radosław Kapka
8e2c9313e9 Save orphaned Electra attestations properly (#15060)
* Deal with block attestations post_electra

* changelog <3

* Revert "Deal with block attestations post_electra"

This reverts commit 3d9a40a5a8369e863c37cebec0a53f4bbcf79fe2.
2025-03-21 12:54:19 +00:00
terence
fea441d889 Clean up batch process new pending deposits (#15085) 2025-03-21 05:45:52 +00:00
Radosław Kapka
2351064e8d Improve blobs Beacon API endpoint (#14845)
* Improve blobs API endpoint

* changelog <3

* use summary

* Kasey's review

* one more
2025-03-20 19:06:37 +00:00
Manu NALEPA
d2699761ed subscribeToSubnets: Remove unused parameter. (#15079)
* `subscribeToSubnets`: Remove unused parameter.

* Changelog: Change `Fixed` to `Ignored`.
2025-03-20 15:57:55 +00:00
Manu NALEPA
c73473b59d Tracked validator cache: Make sure no to loose the reference. (#15077) 2025-03-20 10:00:40 +00:00
Preston Van Loon
2aa52fb56a Add static analyzer to discourage use of panic() (#15075)
* Implement static analysis to prevent panics

* Add nopanic to nogo

* Fix violations and add exclusions

Fix violations and add exclusions for all

* Changelog fragment

* Use pass.Report instead of pass.Reportf

* Remove strings.ToLower for checking init method name

* Add exclusion for herumi init

* Move api/client/beacon template function to init and its own file

* Fix nopanic testcase
2025-03-19 18:04:15 +00:00
Preston Van Loon
16d5abd21b Update changelog for v5.3.1 release (#15045)
* Update changelog for v5.3.1 release.

* Add description for v5.3.1

* Changelog fragment
2025-03-19 15:10:30 +00:00
james-prysm
08bfaca42d panic to error changes and changelog (#15074) 2025-03-19 14:31:29 +00:00
Sam Calder-Mason
179cedd4a0 feat(event-stream): Support block_gossip topic (#15038)
* feat(event-stream): Add block_gossip topic support

* feat(event-stream): Add block_gossip topic support

* feat(event-stream): Add block_gossip topic support

* feat: add block gossip topic support to beacon api event stream

* fix: sync_fuzz_test panic

* fix: check for nil operationNotifier before sending block gossip

The operationNotifier was not being checked for nil before being used,
which could lead to a panic if it was not initialized. This commit adds
a nil check to prevent the panic.

---------

Co-authored-by: james-prysm <90280386+james-prysm@users.noreply.github.com>
2025-03-18 19:27:27 +00:00
terence
0f39857653 Clean up infinity signature usages (#15072) 2025-03-18 19:27:06 +00:00
terence
645328bb9e Clarify infinity signature deposit tests (#15071) 2025-03-18 19:25:56 +00:00
james-prysm
9d2273c514 Move prysm specific performance endpoint (#15062)
* adding in check for non prysm node and moving the prysm endpoint to the prysm beacon client

* fixing a bug connecting to a non prysm client and moving the prysm api call to the prysm beacon client

* changelog

* fixing linting

* Update validator/client/metrics.go

Co-authored-by: Radosław Kapka <rkapka@wp.pl>

---------

Co-authored-by: Radosław Kapka <rkapka@wp.pl>
2025-03-18 15:02:54 +00:00
Radosław Kapka
34429368fe Update seen unaggregated att cache to Electra (#15034)
* Update seen unaggregated att cache to Electra

* changelog <3

* pass full att

* revert extracting length check

* check if 1 bit set

* test fix

* adding end to end unit test saving unaggregated electra att and then verifying that it's already seen in the cache

* Terence's feedback

* return false on errors

---------

Co-authored-by: james-prysm <james@prysmaticlabs.com>
2025-03-17 16:34:34 +00:00
Nishant Das
629568c796 Handle Networking Message Limits Better (#14799)
* Handle Message Limits

* Changelog

* Ignore them for now

* Sort fields

* Update to Latest Versions
2025-03-17 14:15:20 +00:00
terence
5c24978702 Add hoodi testnet flag (#15057)
* Add hoodi testnet flag

* Add upstream test

* Fix test
2025-03-17 05:49:27 +00:00
kasey
4e44999207 OCL forked changed-files pin; pin others (#15056)
* OCL forked changed-files pin; pin others

* changelog :)

---------

Co-authored-by: Kasey Kirkham <kasey@users.noreply.github.com>
2025-03-15 19:56:25 +00:00
james-prysm
15ae71c0da Builder ssz (#14976)
* wip

* refactoring functions for easier readability

* allow ssz for register validator

* changelog

* adding in blinded block submission tests

* adding in tests for header ssz

* fixing linting and tests

* adding in custom errors and fixing ssz validator registration

* Update api/client/builder/client.go

Co-authored-by: Manu NALEPA <enalepa@offchainlabs.com>

* Update api/client/builder/client.go

Co-authored-by: Manu NALEPA <enalepa@offchainlabs.com>

* manu's feedback

* linting

* adding in info log to notify that this setting was turned on

* fixing linting

* manu's feedback

* fixing import

---------

Co-authored-by: Manu NALEPA <enalepa@offchainlabs.com>
2025-03-14 17:23:00 +00:00
terence
1caea86152 Update spec test to v1.5.0-beta.3 (#15050) 2025-03-14 10:47:16 +00:00
james-prysm
7cef3b0491 adding omitempty to request object (#15031) 2025-03-11 13:43:00 +00:00
Radosław Kapka
15462844f9 Remove error from signatures of UnaggregatedAttestations and pruneAttsFromPool (#15028) 2025-03-10 22:28:51 +00:00
Potuz
863eee7b40 Add feature flag to start from any beacon block in db (#15000)
* Add feature flag to start from any beacon block in db

The new feature flag called --sync-from takes a string that can take
values:

- `head` or
- a 0x-prefixed hex encoded beacon block root.

The beacon block root or the head block root has to be known in db and
has to be a descendant of the current justified checkpoint.

* Fix Bugs In Sync From Head (#15006)

* Fix Bugs

* Remove log

* missing save

* add tests

* Kasey review #1

* Kasey's review #2

* Kasey's review #3

---------

Co-authored-by: Nishant Das <nishdas93@gmail.com>
2025-03-10 15:51:25 +00:00
Radosław Kapka
6d89373583 Handle unaggregated attestations when decomposing (#15027) 2025-03-10 13:48:43 +00:00
kasey
9a421a2feb payload attribute computations in event handler (#14963)
* payload attribute computations in event handler

* Skip executing nil lazyReaders

* adding in clarifying comments, uncommenting needs fill, adding in happy path unit test for code coverage

* gaz

* fixing ineffectual assignment

* nil check the Reader coming from the lazyReader

* Apply suggestions from code review

Radek's PR suggestion to fix error/log capitalization.

Co-authored-by: Radosław Kapka <rkapka@wp.pl>

* Radek feedback

* Move fire payload attribute event to after save head

* set mock statenotifier in testServiceOptsWithDB

---------

Co-authored-by: Kasey Kirkham <kasey@users.noreply.github.com>
Co-authored-by: james-prysm <james@prysmaticlabs.com>
Co-authored-by: Radosław Kapka <rkapka@wp.pl>
Co-authored-by: terence tsao <terence@prysmaticlabs.com>
2025-03-07 23:25:12 +00:00
james-prysm
4e41d5c610 fixing e2e builder gas limit (#15025)
* fixing e2e

* linting
2025-03-07 19:00:16 +00:00
james-prysm
0b6bea43a8 adding optimistic check to /eth/v1/validator/sync_committee_contribution rest endpoint (#15022) 2025-03-06 22:29:11 +00:00
Radosław Kapka
f89afb0fbd Handle some errors from hasSeenBit and insertSeenBit differently (#15018)
* Ignore errors from `hasSeenBit` and don't pack unaggregated attestations

* changelog <3

* Revert "Ignore errors from `hasSeenBit` and don't pack unaggregated attestations"

This reverts commit dc86cb63204d6ff735d9302142068de95a8188fd.
2025-03-06 22:26:20 +00:00
Potuz
3cd2973c92 Return the genesis block root from last validated checkpoint if zero (#15021)
* Return the genesis block root from last validated checkpoint if zero
When starting a node we load the last validated checkpoint. On tests or a new node this checkpoint can have the zero blockroot (it returns the finalized checkpoint). This PR ensures that it returns the genesis block root instead.

It can't affect runnning code since the root is only used at startup in `setup_forkchoice`. But it may affect tests because now `OptimisticForRoot` will error out if there is no genesis block root set on db.

* Terence review

* fix test
2025-03-06 21:42:11 +00:00
james-prysm
d3e5710a63 updated gas limit (#14858) 2025-03-06 16:37:14 +00:00
Preston Van Loon
f40b4f16c2 Beacon API: Broadcasting BLS to execution changes should not use the request context in a go routine (#15019)
* Broadcasting BLS to execution changes should not use the request context in a go routine

* Changelog fragment
2025-03-06 15:25:48 +00:00
kasey
7fd4f746d6 Clean up block-slot-indices on block deletion (#15011)
* clean up block-slot-indices on block deletion

* also remove parent root index entry

* treat parent root index as packed key (like slot idx)

* fix bug where input slice is modified, with test

---------

Co-authored-by: Kasey Kirkham <kasey@users.noreply.github.com>
2025-03-06 14:43:23 +00:00
james-prysm
2362d9f3c2 blob_sidecar_subnet configs missing from /eth/v1/config/spec endpoint (#15016)
* fixing config display

* fixing test
2025-03-06 14:25:53 +00:00
Jun Song
6b84f8c6b1 Add p2p address format for CLI users (#14886)
* Add address format for CLI users

* Add changelog
2025-03-05 18:21:22 +00:00
terence
997a9112d1 Validate blob sidecar: check bad parent first (#15013) 2025-03-05 17:54:44 +00:00
Preston Van Loon
d46ca97680 Update go to 1.24.0 (#14969)
* Update rules_go to v0.53.0

* Update staticcheck to v0.6.0

* Update to go 1.24.0

* Update github.com/trailofbits/go-mutexasserts to latest

* Use rules_go @ cf3c3af34bd869b864f5f2b98e2f41c2b220d6c9

* Provide the go binary to SszGen. 
https://github.com/bazel-contrib/rules_go/pull/4173

* Unskip SA9003

* Update github ci checks to go1.24.0

* CI: Update gosec to v2.22.1 and golangci to v1..64.5

* Temporarily disable usetesting lint check for go1.24

* gosec: Disable G115 - integer overflow conversion

* gosec: Ignore G407 for "hardcoded" IV. It's not hardcoded.

* Fix uses of rand.Seed. This is a no-op in go1.24 and deprecated since go1.20.

* Changelog fragment
2025-03-05 17:46:39 +00:00
Radosław Kapka
417bbf8a9e Decompose Electra block attestations (#14896)
* Decompose Electra block attestations

* comments

* changelog <3

* remove redundant comparison

* typo in comment

* fix changelog section name

* review from James and Sammy

* continue pruning on error

* only prune when committees are cached

* fix bad assignments in test
2025-03-05 10:01:33 +00:00
Potuz
a7b016c954 Add Target root to forkchoice dump (#15009)
* Add Target root to forkchoice dump

* review
2025-03-05 04:49:44 +00:00
Manu NALEPA
6015493de9 --validators-registration-batch-size: Change default value from 0 to 200. (#14981) 2025-03-04 16:32:24 +00:00
Dhruv Bodani
c718bdbe2b fix pruner timing issue with batch pruning (#14929)
* fix pruner timing issue with batch pruning

* add changelog entry

* add batchSize and number of slots deleted to debug logs

* fix lint

* prune in small batches in one prune cycle

* remove noisy logs

* fix number of batches to prune and return early if there's nothing to delete

* use context with timeout

* fix lint by ignoring nil err return
2025-03-04 16:31:17 +00:00
Preston Van Loon
0a8f947169 beacon-chain: Reorganize flags in help text (#14959)
* Beacon flags: Comment on deprecated section

* Beacon flags: Organize flags relevant to logging, comment on logging section

* Beacon flags: Organize flags relevant to p2p, comment on p2p section

* Beacon flags: Introduce db flag section, organize flags relevant to db, comment on db section

* Beacon flags: Introduce builder flag section, organize flags relevant to builder, comment on builder section

* Beacon flags: Introduce sync flag section, organize flags relevant to sync, comment on sync section

* Beacon flags: Introduce execution layer flag section, organize flags relevant to execution layer, comment on execution layer section

* Beacon flags: Introduce monitoring flag section, organize flags relevant to monitoring, comment on monitoring section

* Beacon flags: Organizing remaining flags in cmd and beacon-chain sections

* Beacon flags: Introduce slasher flag section, organize flags relevant to slasher, comment on slasher section

* Move slasher flag from features to the slasher section

* Changelog fragment

* Beacon flags: Reorganize sections

* Move MaxGoroutines to debug section
2025-03-04 16:17:29 +00:00
james-prysm
d7efccf6a5 single attestation cleanup (#14984)
* some cleanup and minor bug fix

* adding some comments back in

* Update beacon-chain/sync/pending_attestations_queue.go

Co-authored-by: Radosław Kapka <rkapka@wp.pl>

* Update beacon-chain/sync/pending_attestations_queue.go

Co-authored-by: Radosław Kapka <rkapka@wp.pl>

* Update beacon-chain/sync/validate_beacon_attestation.go

Co-authored-by: Radosław Kapka <rkapka@wp.pl>

* Update beacon-chain/sync/validate_beacon_attestation.go

Co-authored-by: Radosław Kapka <rkapka@wp.pl>

* Update beacon-chain/sync/validate_beacon_attestation.go

Co-authored-by: Radosław Kapka <rkapka@wp.pl>

* Update beacon-chain/sync/validate_beacon_attestation.go

Co-authored-by: Radosław Kapka <rkapka@wp.pl>

* Update beacon-chain/sync/validate_beacon_attestation.go

Co-authored-by: Radosław Kapka <rkapka@wp.pl>

* Update beacon-chain/sync/pending_attestations_queue.go

Co-authored-by: Radosław Kapka <rkapka@wp.pl>

* adding comment back in

* linting

* fixing committeeIndiciesSLot

* fixing changelog

---------

Co-authored-by: Radosław Kapka <rkapka@wp.pl>
2025-03-04 14:50:59 +00:00
Nishant Das
334920bc9e Fix Block Decoding During State Deletion (#15008)
* Fix Block Decoding

* Changelog
2025-03-04 11:55:32 +00:00
james-prysm
6e00db433c cache uses wrong seen committee index for electra (#14998)
* adding fix and unit tests

* removing unneeded test for now, will handle in separate PR
2025-03-03 16:53:42 +00:00
james-prysm
c6344e7c3e fixing electra committee logs (#14992)
* fixing logs

* fixing tests

* addressing feedback

* fixing tests based on feedback
2025-03-03 15:35:45 +00:00
Potuz
2131254722 Populate pubkey cache at genesis (#14995)
When starting with a zero root finalized checkpoint instead of returning
early also populate the pubkey cache.
2025-02-28 11:12:52 +00:00
Potuz
b6d1866deb Split out forkchoice setup from service start (#14997) 2025-02-27 20:38:29 +00:00
james-prysm
e56f489d06 add log for committee index on electra attesation (#14993)
* adding log in the case of debugging

* gaz
2025-02-27 18:11:27 +00:00
Nishant Das
bf62afb27c Fix Gossip Validation of Electra Attester Slashings (#14985)
* Fix Attester Slashing Validation In Electra

* Changelog
2025-02-27 08:50:24 +00:00
Bastin
8369056027 SSZ Support for LC finality and optimistic update APIs (#14836)
* bundle handlers test

* ssz support for optimistic and finality updates APIs

* changelog PR link

* delete helpers

---------

Co-authored-by: Radosław Kapka <rkapka@wp.pl>
2025-02-25 13:09:28 +00:00
Preston Van Loon
09499a732f gosec: Fix violations of G301 (#14980)
* gosec: Fix violations of G301

* Changelog fragment
2025-02-24 15:13:53 +00:00
Preston Van Loon
2ee015452c Use go-cmp and protocmp for assertion diff printing (#14978)
Fix assertion tests after switching to cmp

Changelog fragment
2025-02-23 21:06:07 +00:00
terence
ffc1bf8bbe Add more verbosity to validate range message (#14975) 2025-02-21 19:54:40 +00:00
Preston Van Loon
014dbd5c3a Lint: Fix violations of non-constant format string in call (#14974)
* Fix violations of non-constant format string in call

* Changelog fragment
2025-02-21 19:46:19 +00:00
Preston Van Loon
9bceaa59d2 tracing: Add otel tracer transport to all http clients (#14972)
* Fixed otelhttp client setups.

Note: This may not be the best solution as the http client is defined in many places. There should be a canoncial http client with the proper setup.

* Changelog fragment

* go mod tidy and gazelle
2025-02-21 19:39:53 +00:00
Preston Van Loon
832ebb3f39 Lint: Fix violations of S1009: should omit nil check; len() for nil slices is defined as zero (#14973)
* Fix violations of S1009: should omit nil check; len() for nil slices is defined as zero

* Changelog fragment
2025-02-21 19:39:33 +00:00
james-prysm
8345c271cc Code Cleanup: payload conversions and fixing gocognit ignores (#14953)
* created new converstions_execution files moving the from and to consensus functions for execution related items, also created a placeholder for block_execution with the intent of adding execution types there

* moving execution types from block.go to block_execution.go

* migrating more types and logic

* adding all the to consensus functions for payloads

* changelog

* linting

* updating unit tests for conversions

* fixing linting

* forgot to fix test

* updating name based on feedback
2025-02-21 16:12:01 +00:00
terence
56208aa84d Add more verbosity to fork digest mismatch (#14968) 2025-02-21 03:36:31 +00:00
james-prysm
b866a2c744 setting rest endpoints as deprecated for electra (#14967) 2025-02-20 18:20:51 +00:00
Nishant Das
a77234e637 Test Execution Deposit Requests in E2E (#14964)
* Test Deposit Requests

* Remove extra epochs

* Clean up Panic

* Fix Slashing Config

* Fix Slashing Test

---------

Co-authored-by: james-prysm <90280386+james-prysm@users.noreply.github.com>
2025-02-20 14:54:45 +00:00
james-prysm
e0e7354708 improving the error messages for execution request deserialization (#14962)
* improving the error messages for execution request deserialization

* changelog
2025-02-20 14:31:02 +00:00
james-prysm
0f86a16915 builder: api calls should have appropriate headers (#14961)
* adding correct headers when posting for validator registration on builder api

* changelog
2025-02-20 14:27:14 +00:00
Radosław Kapka
972c22b02f SingleAttestation support in the monitor service (#14965)
* `SingleAttestation` support in the monitor service

* changelog <3
2025-02-20 11:26:51 +00:00
Manu NALEPA
93c27340e4 Tracked validator TTL (#14957)
* `TrackedValidatorsCache`: Implement a 1-hour TTL by uding `go-cache`.

* `TrackedValidatorsCache`: Add the `ItemCount` method.

* `TrackedValidatorsCache`: Add the `Indices` method.

* Add changelog.

* `TrackedValidatorsCache`: Add prometheus metrics.

* Update beacon-chain/cache/tracked_validators.go

Co-authored-by: Preston Van Loon <pvanloon@offchainlabs.com>

---------

Co-authored-by: Preston Van Loon <pvanloon@offchainlabs.com>
2025-02-19 18:04:13 +00:00
Manu NALEPA
c3edb32558 ServiceRegistry.StartAll: Remove redundant log. (#14958) 2025-02-19 17:12:32 +00:00
Sammy Rosso
3baaa732df Add get pending partial withdrawals (#14949)
* add pending partial withdrawals endpoint

* changelog

* missing new line

* fix changelog

* removing unneeded header

* using generic instead of redundant functions

---------

Co-authored-by: james-prysm <james@prysmaticlabs.com>
2025-02-19 12:34:48 +00:00
Nishant Das
8ceb7e76ea Log execution requests (#14956) 2025-02-19 10:19:04 +00:00
terence
4d5dddd302 Add request hash to header for builder: executable data to block (#14955)
* Add request hash to header for builder: executable data to block

* go fmt
2025-02-19 05:18:18 +00:00
Sammy Rosso
55efccb07f Add get pending deposits endpoint (#14941)
* Add GetPendingDeposits endpoint

* add comment

* add changelog

* gaz

* Radek' review

* move JSON object params

* gaz

* Radek' nits xD

* James' review
2025-02-18 16:16:20 +00:00
Radosław Kapka
961d8e1481 Don't use MaxCover for Electra on-chain aggregates (#14925)
* Don't use MaxCover for Electra on-chain aggregates

* changelog <3
2025-02-18 14:44:18 +00:00
Nishant Das
d396a9931e Add in Multiclient E2E For Electra (#14946)
* Add in Multiclient E2E

* Fix Execution Engine

* Update testing/endtoend/endtoend_test.go

Co-authored-by: Radosław Kapka <rkapka@wp.pl>

* Update testing/endtoend/endtoend_test.go

Co-authored-by: Radosław Kapka <rkapka@wp.pl>

---------

Co-authored-by: Radosław Kapka <rkapka@wp.pl>
2025-02-18 10:32:58 +00:00
james-prysm
e3f8f121f4 web3signer electra for e2e (#14936)
* changes needed to support web3signer running on electra for e2e

* updating web3signer version and fixing missed configs and test alignment
2025-02-18 01:36:19 +00:00
fuyangpengqi
80f29e9eda refactor: use a more straightforward return value (#14942)
Signed-off-by: fuyangpengqi <995764973@qq.com>
2025-02-17 19:18:15 +00:00
Nishant Das
8995d8133a Fix Deposit Activation Evaluator (#14938)
* Fix evaluator

* fix deposit activation
2025-02-17 13:43:23 +00:00
Preston Van Loon
31044206b8 tracing: Replace deprecated jaeger exporter with otelhttp exporter (#14928)
* Update go.opentelemetry.io/otel to v1.34.0

* Update otel exporter to replace deprecated jaeger exporter

* Changelog

* Use WithEndpointURL

* Clarify potential breaking change
2025-02-15 17:26:57 +00:00
Manu NALEPA
3a1702e56f Fixed the bazel run //:gazelle command in DEPENDENCIES.md. (#14934) 2025-02-14 15:00:10 +00:00
Nishant Das
501ec74a48 Fix Deposit Evaluator in E2E (#14933)
* fix evaluator in electra

* remove function

* Fix evaluator

---------

Co-authored-by: james-prysm <90280386+james-prysm@users.noreply.github.com>
2025-02-14 14:59:51 +00:00
Potuz
c248fe0bb3 Add logs for RPC handlers registered/removed at forks (#14932) 2025-02-14 13:01:01 +00:00
Manu NALEPA
215fbcb2e4 Remove Fulu block and state. (#14905)
* Remove Fulu block and state.

* Add missing tests.

* Alias `ProtobufBeaconStateFulu` to `ProtobufBeaconStateElectra`
2025-02-14 10:48:24 +00:00
kasey
e39f44b529 fix path parsing bug on windows (#14931)
Co-authored-by: Kasey Kirkham <kasey@users.noreply.github.com>
2025-02-14 06:10:58 +00:00
Nishant Das
9eff6ae476 Update Blst to v3.14.0 (#14921)
* updateBlst

* changelog
2025-02-13 14:31:19 +00:00
Nishant Das
3eec5a5cb6 Fix Engine Capabilites Check (#14924)
* Fix Capabilities Check

* Changelog
2025-02-13 13:37:05 +00:00
Preston Van Loon
66878deb2c Update changelog for v5.3.0 release (#14918)
* Prysm v5.3.0 changelog update

* Add v5.3.0 preamble

* Remove experimental feature from suggestions

* Changelog fragment
2025-02-12 22:36:34 +00:00
james-prysm
0b6e1711e4 Electra e2e minimal (updates geth to 1.15.0) (#14842)
* wip electra e2e

* add Deneb state to `validatorsParticipating`

* Run bazel

* add Electra state to `validatorsParticipating`

* fixing some e2e issues

* more evaluator fixes and changelog

* adding in special condition to pass electra epoch participation

* fixing typo

* missed updating forks for e2e tests

* reverting change current release fork

* missed updating e2e config for test

* updating to latest devnet 5 to fix unit tests

* go mod tidy

* fixing branch, temporary will need to update geth version later

* update to goethereum v1.15.0

* changing changelog to reflect update in geth dependency

* fixing test failures

* adding fix for range request limit during transition period between forks

* enabling validator rest for Electra

* rolling back error message

* adding fixed change logs

* fixing dependencies based on nishant's comments, deps.bzl should be updated not workspace

* partially reverting incorrect change

* removing fixes from change log, handled in separate prs

* removing comment

* updating update fraction field to the corrected spec value from prague

* Update testing/endtoend/evaluators/fork.go

Co-authored-by: Preston Van Loon <pvanloon@offchainlabs.com>

---------

Co-authored-by: rkapka <radoslaw.kapka@gmail.com>
Co-authored-by: terence tsao <terence@prysmaticlabs.com>
Co-authored-by: Nishant Das <nishdas93@gmail.com>
Co-authored-by: Preston Van Loon <pvanloon@offchainlabs.com>
2025-02-12 15:58:06 +00:00
james-prysm
15025837bb fix: gocognit on publish block and fixing publish blinded block header check (#14913)
* refactored code and added in checks for blinded endpoints

* changelog

* cleaning up some comments and error messages

* fixing linting

* adding clarifying comment
2025-02-11 21:34:37 +00:00
Radosław Kapka
0229a2055e Rename files in beacon-chain/operations/slashings (#14904)
* pool

* service

* changelog <3
2025-02-11 16:13:23 +00:00
terence
eb9af15c7a Add blobs by range electra test (#14912) 2025-02-11 15:34:44 +00:00
james-prysm
0584746815 Dynamic max blobs config (#14911)
* fixing max config helpers to use dynamic values instead of static ones

* changelog
2025-02-11 15:04:22 +00:00
Nishant Das
8c4ea850ba Fix Blobs By Range RPC Handler (#14910)
* Add tests for TestSendBlobsByRangeRequest. Currently not working with sequential blob validation.

* Copy Root First

* Allow Test For Maximum Amount of Blobs

* Fails with the Same error

* Fix Last Test Assertion

* Add in Fix

* Changelog

---------

Co-authored-by: Preston Van Loon <preston@pvl.dev>
2025-02-11 14:11:12 +00:00
Nishant Das
4b43f13e65 Fix Blob Reconstruction (#14909)
* Fix Mutating Blob Mask

* Changelog

* Typo
2025-02-11 13:44:00 +00:00
james-prysm
26d35474e9 fix: /eth/v2/beacon/blocks post api to handle electra and fulu blocks correctly (#14897)
* adding fix and changelog

* adding no lint gocognit for now

* fixing linting

* Update beacon-chain/rpc/eth/beacon/handlers.go

Co-authored-by: Radosław Kapka <rkapka@wp.pl>

* Update beacon-chain/rpc/eth/beacon/handlers.go

Co-authored-by: Radosław Kapka <rkapka@wp.pl>

* Update beacon-chain/rpc/eth/beacon/handlers.go

Co-authored-by: Radosław Kapka <rkapka@wp.pl>

* updating based on kasey's suggestions

* preston's comments

---------

Co-authored-by: Radosław Kapka <rkapka@wp.pl>
2025-02-10 23:50:09 +00:00
terence
9fbe3564df Update spec tests to v1.5.0-beta.2 (#14901) 2025-02-10 15:12:57 +00:00
terence
bed5547890 Add pectra testnet dates (#14884) 2025-02-10 15:09:42 +00:00
Nishant Das
47922fe7d8 Remove Unused assignment (#14906)
* Remove unused boolean assignment

* Changelog

* Remove debug line
2025-02-10 15:01:23 +00:00
Radosław Kapka
dcd25d1d97 Add missing config values from the spec (#14903)
* Add missing config values from the spec

* remove placeholders

* add some more values
2025-02-10 14:17:13 +00:00
terence
81a2a17c5f Fix electra state to safe share references on pending fields when append (#14895)
* Fix electra state to safe share references on pending fields when append

* Feedback
2025-02-08 03:04:02 +00:00
Rupam Dey
6b3f1de19d change lc flag name from enable-lightclient to enable-light-client (#14887)
* change flag name from `enable-lightclient` to `enable-light-client`

* changelog
2025-02-07 17:35:12 +00:00
Bastin
7c17af2a41 bundle handlers test (#14834)
Co-authored-by: Radosław Kapka <rkapka@wp.pl>
2025-02-07 16:00:22 +00:00
Nishant Das
ecf5a368d7 Update it (#14890) 2025-02-07 08:31:36 +00:00
Jun Song
557c5be433 Prune pending deposits from the deposit cache post-Electra (#14829)
* Add metrics for pruned proofs & pending deposits

* Add PruneAllProofs & PruneAllPendingDeposits

* Add simple unit tests

* Add DepositPruner interface

* Add pruning logic at post finalization task

* Move pruner logic into new file(deposit_pruner.go)

Rationale:
As deposit_fetcher.go contains all pruning logics, it would be better to separate its interest into fetcher/inserter/pruner.

* Gofmt

* Add reference link for deprecating eth1 polling

* Add changelog

* Apply reviews from nisdas and james

* add pre and post deposit request tests

* nishant's comment

---------

Co-authored-by: james-prysm <90280386+james-prysm@users.noreply.github.com>
Co-authored-by: james-prysm <james@prysmaticlabs.com>
2025-02-07 04:31:01 +00:00
Radosław Kapka
49405c3afd Notify about attestations from the pending att queue (#14862)
* Notify about attestations from the pending att queue

* changelog <3

* fix tests

* adding to existing tests to track appropriate event feed sends

---------

Co-authored-by: james-prysm <james@prysmaticlabs.com>
Co-authored-by: james-prysm <90280386+james-prysm@users.noreply.github.com>
2025-02-06 22:07:42 +00:00
Nishant Das
3439122629 Set New Blob Limits For Electra (#14883)
* Set New Blob Limits For Electra

* Add Changelog

* Bump up blob limit
2025-02-06 16:53:39 +00:00
Potuz
f6e5da6723 Do not error on overflow when converting slashings (#14882) 2025-02-05 21:01:27 +00:00
kasey
842f241cb9 Reduce size of api/client import graph (#14871)
* relocate DownloadFinalizedData from api to sync

* unexpected go mod changes

---------

Co-authored-by: Kasey Kirkham <kasey@users.noreply.github.com>
2025-02-05 20:40:13 +00:00
kasey
41daac1b04 Organize blobs on disk by epoch (#14023)
* organize blob directories by period and epoch

* changelog

* remove Indices and replace with Summary

* old PR feedback

* log to advise about the speed of blob migration

* rename level->layer (hoping term is more clear)

* assert path in tests for increased legibility

* lint

* lint

* remove test covering a newly impossible error

* improve feedback from flag validation failure

* Try to clean dangling dirs epoch->flat migration

* lint

* Preston feedback

* try all layouts and short-circuit if base not found

---------

Co-authored-by: Kasey Kirkham <kasey@users.noreply.github.com>
2025-02-05 20:09:38 +00:00
Potuz
2a7fc84044 Fix startup log for config file values (#14865) 2025-02-05 16:01:25 +00:00
Rupam Dey
44ff0b1a14 add missing Electra tests for light client (#14783)
* add Electra tests for finality update

* override beacon config

* add Electra tests to

* fix setupTestElectra

* changelog

* cleanup test config

* Update beacon-chain/core/light-client/lightclient_test.go

Co-authored-by: Radosław Kapka <radoslaw.kapka@gmail.com>

* changelog

* move config to top

---------

Co-authored-by: Bastin <bastin.m@proton.me>
Co-authored-by: Bastin <43618253+Inspector-Butters@users.noreply.github.com>
Co-authored-by: Radosław Kapka <radoslaw.kapka@gmail.com>
Co-authored-by: Radosław Kapka <rkapka@wp.pl>
2025-02-05 15:16:53 +00:00
Dhruv Bodani
91cdd318a8 Add process slot span to slotCtx (#14874)
* attach process slot span to slotCtx

* add changelog

* fix build

* fix build

* Update changelog/dB2510_processslotspan.md

Co-authored-by: Radosław Kapka <rkapka@wp.pl>

---------

Co-authored-by: Radosław Kapka <rkapka@wp.pl>
2025-02-05 15:00:27 +00:00
james-prysm
3dc00816fb nil checks on ToConsensus() functions (#14867)
* adding more safety checks and associated tests

* changelog

* Update api/server/structs/conversions.go

Co-authored-by: Radosław Kapka <rkapka@wp.pl>

* radek's feedback

* fixing tests

* gaz

* Update api/server/structs/conversions.go

* Update api/server/structs/conversions.go

* Update api/server/structs/conversions.go

* Update api/server/structs/conversions.go

---------

Co-authored-by: Radosław Kapka <rkapka@wp.pl>
2025-02-05 14:59:57 +00:00
james-prysm
e331d5b371 improving proposer settings loader readability (#14868)
* updating loader code and adding change log

* updating variable names to reduce confusion

* exporting loader type

* Update config/proposer/loader/loader.go

Co-authored-by: Sammy Rosso <15244892+saolyn@users.noreply.github.com>

* Update config/proposer/loader/loader.go

Co-authored-by: Sammy Rosso <15244892+saolyn@users.noreply.github.com>

* Update config/proposer/loader/loader.go

Co-authored-by: Sammy Rosso <15244892+saolyn@users.noreply.github.com>

* gofmt

---------

Co-authored-by: Sammy Rosso <15244892+saolyn@users.noreply.github.com>
2025-02-04 23:18:50 +00:00
Taranpreet26311
8d5090ce54 Update go-ethereum to v1.14.13 (#14872)
* Update geth dependency in go

* Updated geth

* Add changelog update

* Remove change log line

* Modify changelog line
2025-02-04 16:11:18 +00:00
Radosław Kapka
25244d906d Modify comment in recomputeFieldTrie (#14873) 2025-02-04 12:20:40 +00:00
Preston Van Loon
aa445713ac Remove validator.SignValidatorRegistrationRequest span (#14864) 2025-02-03 17:07:49 +00:00
Radosław Kapka
177769a1ce Update Beacon API events to Electra (#14855)
* Update Beacon API events to Electra

* changelog <3

* fix issues

* send notifications from pending att queue

* Revert "send notifications from pending att queue"

This reverts commit 545408f6cf.
2025-02-03 16:16:38 +00:00
Radosław Kapka
967e9255a2 Fix monitor service for Electra (#14853)
* Fix monitor service for Electra

* changelog <3
2025-02-03 15:12:14 +00:00
terence
910609a75f Handle errors as no-op for execution requests (#14826)
* Update electra core processing error handling

* Add test for IsExecutionRequestError

* Add TestProcessOperationsWithNilRequests

* gazelle

---------

Co-authored-by: Preston Van Loon <preston@pvl.dev>
2025-01-31 22:17:27 +00:00
kasey
f9c202190a warnings for flags due for deprecation (#14856)
Co-authored-by: Kasey Kirkham <kasey@users.noreply.github.com>
2025-01-31 21:30:27 +00:00
Radosław Kapka
4a63a194b1 Address @jtraglia's comments regarding Electra code (#14833)
* change field IDs in `AggregateAttestationAndProofElectra`

* fix typo in `validator.proto`

* correct slashing indices length and shashings length

* check length in indexed attestation's `ToConsensus` method

* use `fieldparams.BLSSignatureLength`

* Add length checks for execution request

* fix typo in `beacon_state.proto`

* fix typo in `ssz_proto_library.bzl`

* fix error messages about incorrect types in block factory

* add Electra case to `BeaconBlockContainerToSignedBeaconBlock`

* move PeerDAS config items to PeerDAS section

* remove redundant params

* rename `PendingDepositLimit` to `PendingDepositsLimit`

* improve requests unmarshaling errors

* rename `get_validator_max_effective_balance` to `get_max_effective_balance`

* fix typo in `consolidations.go`

* rename `index` to `validator_index` in `PendingPartialWithdrawal`

* rename `randomByte` to `randomBytes` in `validators.go`

* fix for version in a comment in `validator.go`

* changelog <3

* Revert "rename `index` to `validator_index` in `PendingPartialWithdrawal`"

This reverts commit 87e4da0ea2.
2025-01-31 15:41:52 +00:00
james-prysm
d887536eb7 skip eth1data voting after electra (#14835)
* wip skip eth1data voting after electra

* updating technique

* adding fix for electra eth1 voting

* fixing linting on test

* seeing if reversing genesis state fixes problem

* increasing safety of legacy check

* review feedback

* forgot to fix tests

* nishant's feedback

* nishant's feedback

* rename function a little

* Update beacon-chain/core/helpers/legacy.go

Co-authored-by: Jun Song <87601811+syjn99@users.noreply.github.com>

* fixing naming

---------

Co-authored-by: Jun Song <87601811+syjn99@users.noreply.github.com>
2025-01-31 15:19:28 +00:00
Radosław Kapka
1069da1cd2 Convert Phase0 slashing to Electra slashings at the fork (#14844)
* EIP-7549: slasher

* update chunks and detection

* update tests

* encode+decode

* timer

* test fixes

* testing the timer

* Decouple pool from service

* update mock

* cleanup

* make review easier

* comments and changelog
2025-01-31 03:17:52 +00:00
Potuz
4a487ba3bc Don't mark blocks as invalid on context deadlines (#14838)
* Don't mark blocks as invalid on context deadlines

When processing state transition, if the error is because of a context
deadline, do not mark it as invalid.

* review

* fix changelog
2025-01-31 03:16:16 +00:00
james-prysm
bf81cd4449 Electra blob sidecar API update (#14852)
* adding in versioned header and unit tests

* changelog

* handling case

* changelog
2025-01-31 02:39:27 +00:00
terence
00337fe005 Add nil consolidation check for core processing (#14851) 2025-01-30 22:24:23 +00:00
terence
bb3fba4d8e Add a test for nil withdrawal requeset (#14850) 2025-01-30 21:24:40 +00:00
terence
89967fe209 Move deposit request nil check for all (#14849) 2025-01-30 21:24:31 +00:00
terence
56712b5e49 Update electra spec tests to beta.1 (#14841) 2025-01-29 18:19:07 +00:00
Preston Van Loon
0be9391e62 electra: Improve test coverage for beacon-chain/core/electra/churn.go (#14837)
* Fixed mutants in beacon-chain/core/electra/churn.go

┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╍┅
┃ 🧬 Mutant survived: beacon-chain/core/electra/churn.go → Arithmetic
┠┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
┃ --- beacon-chain/core/electra/churn.go (original)
┃ +++ beacon-chain/core/electra/churn.go (mutated with 'Arithmetic')
┃ @@ -64,7 +64,7 @@
┃       if consolidationBalance > consolidationBalanceToConsume {
┃               balanceToProcess := consolidationBalance - consolidationBalanceToConsume
┃               // additional_epochs = (balance_to_process - 1) // per_epoch_consolidation_churn + 1
┃ -             additionalEpochs, err := math.Div64(uint64(balanceToProcess-1), uint64(perEpochConsolidationChurn))
┃ +             additionalEpochs, err := math.Div64(uint64(balanceToProcess+1), uint64(perEpochConsolidationChurn))
┃               if err != nil {
┃                       return 0, err
┃               }
┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╍┅

┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╍┅
┃ 🧬 Mutant survived: beacon-chain/core/electra/churn.go → Comparison
┠┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
┃ --- beacon-chain/core/electra/churn.go (original)
┃ +++ beacon-chain/core/electra/churn.go (mutated with 'Comparison')
┃ @@ -61,7 +61,7 @@
┃       }
┃
┃       // Consolidation doesn't fit in the current earliest epoch.
┃ -     if consolidationBalance > consolidationBalanceToConsume {
┃ +     if consolidationBalance >= consolidationBalanceToConsume {
┃               balanceToProcess := consolidationBalance - consolidationBalanceToConsume
┃               // additional_epochs = (balance_to_process - 1) // per_epoch_consolidation_churn + 1
┃               additionalEpochs, err := math.Div64(uint64(balanceToProcess-1), uint64(perEpochConsolidationChurn))
┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╍┅

┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╍┅
┃ 🧬 Mutant survived: beacon-chain/core/electra/churn.go → Integer Decrement
┠┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
┃ --- beacon-chain/core/electra/churn.go (original)
┃ +++ beacon-chain/core/electra/churn.go (mutated with 'Integer Decrement')
┃ @@ -64,7 +64,7 @@
┃       if consolidationBalance > consolidationBalanceToConsume {
┃               balanceToProcess := consolidationBalance - consolidationBalanceToConsume
┃               // additional_epochs = (balance_to_process - 1) // per_epoch_consolidation_churn + 1
┃ -             additionalEpochs, err := math.Div64(uint64(balanceToProcess-1), uint64(perEpochConsolidationChurn))
┃ +             additionalEpochs, err := math.Div64(uint64(balanceToProcess-0), uint64(perEpochConsolidationChurn))
┃               if err != nil {
┃                       return 0, err
┃               }
┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╍┅

┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╍┅                                                                                                                                                      
┃ 🧬 Mutant survived: beacon-chain/core/electra/churn.go → Integer Increment                                                                                                                  
┠┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄                                                                                                                                                      
┃ --- beacon-chain/core/electra/churn.go (original)                                                                                                                                           
┃ +++ beacon-chain/core/electra/churn.go (mutated with 'Integer Increment')                                                                                                                   
┃ @@ -64,7 +64,7 @@                                                                                                                                                                           
┃       if consolidationBalance > consolidationBalanceToConsume {                                                                                                                             
┃               balanceToProcess := consolidationBalance - consolidationBalanceToConsume                                                                                                      
┃               // additional_epochs = (balance_to_process - 1) // per_epoch_consolidation_churn + 1                                                                                          
┃ -             additionalEpochs, err := math.Div64(uint64(balanceToProcess-1), uint64(perEpochConsolidationChurn))                                                                           
┃ +             additionalEpochs, err := math.Div64(uint64(balanceToProcess-2), uint64(perEpochConsolidationChurn))                                                                           
┃               if err != nil {                                                                                                                                                               
┃                       return 0, err                                                                                                                                                         
┃               }                                                                                                                                                                             
┃                                                                                                                                                                                             
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╍┅

* Changelog fragment
2025-01-29 02:15:43 +00:00
Dhruv Bodani
4a9c60f75f Implement beacon db pruner (#14687)
* implement weak subjectivity pruner

* fix goimports

* add delete before slot method to database

* add method to interface

* update changelog

* add flags

* wire pruner

* align pruner with backfill service

* rename db method

* fix imports

* delete block slot indices

* check for backfill and initial sync

* add tests

* fix imports

* Update beacon-chain/db/kv/blocks.go

Co-authored-by: Radosław Kapka <rkapka@wp.pl>

* Update cmd/beacon-chain/flags/base.go

Co-authored-by: Preston Van Loon <pvanloon@offchainlabs.com>

* Update beacon-chain/db/pruner/pruner.go

Co-authored-by: Radosław Kapka <rkapka@wp.pl>

* cleanup

* fix buildkite

* initialise atomic bool

* delete data from remaining buckets

* fix build

* fix build

* address review comments

* add test for blockParentRootIndicesBucket

* fix changelog

* fix build

* address kasey's comments

* fix build

* add trace span to blockRootsBySlotRange

---------

Co-authored-by: Radosław Kapka <rkapka@wp.pl>
Co-authored-by: Preston Van Loon <pvanloon@offchainlabs.com>
2025-01-28 16:55:50 +00:00
Radosław Kapka
9cf6b93356 Handle AttesterSlashingElectra everywhere in the codebase (#14823)
* Handle `AttesterSlashingElectra` everywhere in the codebase

* simplify `TestProcessAttesterSlashings_AppliesCorrectStatus`
2025-01-28 15:06:37 +00:00
Preston Van Loon
b4220e35c4 CI: Add clang-formatter lint workflow for proto files (#14831)
* Enforce clang-format for proto files in proto/

* Update pb files after #14818

* Changelog fragment
2025-01-27 20:01:21 +00:00
terence
536cded4cc Fix batch deposit processing by retrieving validators from state (#14827)
* Fix batch process new pending deposits by getting validators from state

* Update tt_fix_pending_deposits.md
2025-01-27 18:11:06 +00:00
Bastin
86fc64c917 Lightclient Bootstrap API SSZ support tests (#14824)
* add bootstrap ssz tests

* add changelog entry

---------

Co-authored-by: Radosław Kapka <rkapka@wp.pl>
2025-01-27 12:20:48 +00:00
Nishant Das
5d6a406829 Update to Go 1.23 (#14818)
* Update to Go 1.23

* Update bazel version

* Update rules_go

* Use toolchains_protoc

* Update go_honnef_go_tools

* Update golang.org/x/tools

* Fix violations of SA3000

* Update errcheck by re-exporting the upstream repo

* Remove problematic ginkgo and gomega test helpers. Rewrote tests without these test libraries.

* Update go to 1.23.5

* gofmt with go1.23.5

* Revert Patch

* Unclog

* Update for go 1.23 support

* Fix Lint Issues

* Gazelle

* Fix Build

* Fix Lint

* no lint

* Fix lint

* Fix lint

* Disable intrange

* Preston's review

---------

Co-authored-by: Preston Van Loon <preston@pvl.dev>
2025-01-24 04:53:23 +00:00
james-prysm
2c78e501b3 Builder: Electra (#14344)
* removing skip from test

* builder wip

* removing todo, it's probably ok

* adding more TODOs

* adding fromProtoElectra

* using lightclient
s branch and updating values

* minor fixes

* rolling back dependency changes

* go mod tidy

* adding space back in

* updating builder changes based on execution request changes

* update ssz

* changelog

* updating based on execution request changes

* fixing validation

* adding builder test for electra

* gaz

* attempting to fix test

* fixing ssz

* fixing build and handling develop changes

* gaz

* fixing unfinished function

* fixing test

* fixing important missed regression

* removing unneeded validations

* missed linting

* gofmt

* fixing fulu test

* fixing changelog

* Update bid.go

Co-authored-by: Radosław Kapka <rkapka@wp.pl>

* Update bid.go

Co-authored-by: Radosław Kapka <rkapka@wp.pl>

* Update types.go

Co-authored-by: Radosław Kapka <rkapka@wp.pl>

* Update types.go

Co-authored-by: Radosław Kapka <rkapka@wp.pl>

* Update james-prysm_builder-electra.md

Co-authored-by: Radosław Kapka <rkapka@wp.pl>

* Update testing/middleware/builder/builder.go

Co-authored-by: Radosław Kapka <rkapka@wp.pl>

* addressing review feedback and updating e2e

* fixing parsing bid version

* reversing incorrect check

* improving tests and updating more code based on review feedback

* gofmt

* fixing unit tests

* more feedback from terence

* gofmt

* Update api/client/builder/types.go

Co-authored-by: Radosław Kapka <rkapka@wp.pl>

* Update beacon-chain/rpc/prysm/v1alpha1/validator/proposer_bellatrix.go

Co-authored-by: Radosław Kapka <rkapka@wp.pl>

* Update beacon-chain/rpc/prysm/v1alpha1/validator/proposer_bellatrix.go

Co-authored-by: Radosław Kapka <rkapka@wp.pl>

* Update beacon-chain/rpc/prysm/v1alpha1/validator/proposer_bellatrix.go

Co-authored-by: Radosław Kapka <rkapka@wp.pl>

* Update beacon-chain/rpc/prysm/v1alpha1/validator/proposer_bellatrix.go

Co-authored-by: Radosław Kapka <rkapka@wp.pl>

* Update api/client/builder/types.go

Co-authored-by: Radosław Kapka <rkapka@wp.pl>

* addressing nitpicks

* gofmt

* radek feedback

* improves error

---------

Co-authored-by: Radosław Kapka <rkapka@wp.pl>
2025-01-23 17:48:19 +00:00
Jun Song
c8cb0f37b2 fix: early return for packing local deposits when EIP-6110 is applied (#14697)
* fix: early return for gathering local deposits when EIP-6110 is applied

* Add an entry on CHANGELOG.md

* Fix weird indent at CHANGELOG.md

* Add changelog

* Fix CHANGELOG.md

---------

Co-authored-by: james-prysm <90280386+james-prysm@users.noreply.github.com>
2025-01-23 16:21:57 +00:00
Manu NALEPA
78722239da nodeFilter: Add GossipBlobSidecarMessage case. (#14822)
Before this commit, this kind of logs were possible:

```
[2025-01-22 17:18:48]  DEBUG sync: Could not search for peers error=node filter: no subnet exists for provided topic: /eth2/d1f05cae/blob_sidecar_0/ssz_snappy
[2025-01-22 17:18:48]  DEBUG sync: Could not search for peers error=node filter: no subnet exists for provided topic: /eth2/d1f05cae/blob_sidecar_1/ssz_snappy
[2025-01-22 17:18:48]  DEBUG sync: Could not search for peers error=node filter: no subnet exists for provided topic: /eth2/d1f05cae/blob_sidecar_2/ssz_snappy
[2025-01-22 17:18:48]  DEBUG sync: Could not search for peers error=node filter: no subnet exists for provided topic: /eth2/d1f05cae/blob_sidecar_3/ssz_snappy
[2025-01-22 17:18:48]  DEBUG sync: Could not search for peers error=node filter: no subnet exists for provided topic: /eth2/d1f05cae/blob_sidecar_4/ssz_snappy
[2025-01-22 17:18:48]  DEBUG sync: Could not search for peers error=node filter: no subnet exists for provided topic: /eth2/d1f05cae/blob_sidecar_5/ssz_snappy
[2025-01-22 17:18:48]  DEBUG sync: Could not search for peers error=node filter: no subnet exists for provided topic: /eth2/d1f05cae/blob_sidecar_6/ssz_snappy
[2025-01-22 17:18:48]  DEBUG sync: Could not search for peers error=node filter: no subnet exists for provided topic: /eth2/d1f05cae/blob_sidecar_7/ssz_snappy
[2025-01-22 17:18:48]  DEBUG sync: Could not search for peers error=node filter: no subnet exists for provided topic: /eth2/d1f05cae/blob_sidecar_8/ssz_snappy
```

Note this bug has no real other impact than logging these errors: Since all nodes are subscribed to these subnets, as soon as some peers are found, there is no more issue.

Why not using `s.subscribe` instead of `s.subscribeWithParameters`?
Blobs subnets were before considered as static subnets. But since Electra, the number of subnets is a function of the epoch.
So it's better to use `s.subscribeWithParameters` than 2 specific but almost identic functions in `s.subscribe`.

Why `filterPeerForBlobSubnet` is the only one returning always `true`?
Because blobs subnets are actually the only subnets which are both dynamic AND which have to be subscribed by all the nodes.
So, `filterPeerForBlobSubnet` does not filter out any node.
2025-01-22 19:56:55 +00:00
Manu NALEPA
3ffef024c7 UpgradeToFulu: Respect the specification. (#14821)
188a2ff818/specs/fulu/fork.md (upgrading-the-state)

Before this commit, the `UpgradeToFulu` did not really respect the specification. This commit fixes that.

How can we be sure now the specification is really respected?

As long as the equivalent of https://github.com/ethereum/consensus-spec-tests/tree/master/tests/mainnet/electra/fork/fork/pyspec_tests are not released, we cannot be sure.

However, with this commit, Prysm and Lighthouse do agree with the post state after the Fulu fork (which is not the case without this commit).

So either both Prysm and Lighthouse are both right,
either the are both wrong (but in the exact same way, which has a pretty low likelyhood).
2025-01-22 18:39:12 +00:00
Radosław Kapka
a1eef44492 Update slasher service to Electra (#14812)
* Update slasher service to Electra

* Update beacon-chain/slasher/chunks.go

Co-authored-by: Manu NALEPA <enalepa@offchainlabs.com>

* Update beacon-chain/slasher/chunks_test.go

Co-authored-by: Manu NALEPA <enalepa@offchainlabs.com>

* Manu's review

* Manu's review again

---------

Co-authored-by: Manu NALEPA <enalepa@offchainlabs.com>
2025-01-22 17:32:19 +00:00
Radosław Kapka
2845ab9365 Update proto_test.go to Electra (#14817) 2025-01-21 20:30:52 +00:00
Radosław Kapka
4f43c15ebb Update rewards API to Electra (#14816) 2025-01-21 20:13:36 +00:00
Radosław Kapka
e473d7cc4d Use SingleAttestation for Fulu in p2p attestation map (#14809)
* Use `SingleAttestation` for Fulu in p2p attestation map.

* Fix `TestExtractDataType`.

---------

Co-authored-by: Manu NALEPA <enalepa@offchainlabs.com>
2025-01-20 10:35:52 +00:00
Potuz
794a05af26 Remove unused Copy() from the ReadOnlyBeaconBlock interface (#14811) 2025-01-19 19:56:14 +00:00
hidewrong
15df13c7e6 Signed-off-by: hidewrong <hidewrong@outlook.com> (#14792)
Signed-off-by: hidewrong <hidewrong@outlook.com>
2025-01-17 15:59:29 +00:00
Potuz
b76f7fed2f move credential helpers to ReadOnlyValidator methods (#14808)
* move credential helpers to ReadOnlyValidator methods

* Changelog + Gazelle

* Fix nil tests

* Fix more nil tests

* Fix another nil test
2025-01-17 12:37:08 +00:00
james-prysm
e263687ea5 Remote Signer: Electra (#14477)
* updating blockv2 to handle electra blocks

* adding aggregate attesation and proof electra

* gaz

* changelogs

* updating web3signer dependency

* test mock was flipped

* fixing hex value

* accidently checked in dependency changes

* preston feedback

* readding old metrics to not break linting

* review feedback and changelog

* gaz
2025-01-16 17:51:59 +00:00
james-prysm
0b16c79c35 fix e2e scenario evaluators (#14798)
* make fork evaluators conditional on fork for scenario tests

* changelog
2025-01-16 04:38:26 +00:00
terence
dc002c2806 Truncate ExtraData to 32 bytes for to satisfy SSZ marshal (#14803) 2025-01-16 00:14:56 +00:00
kasey
e7e48dcaf9 version pin unclog release (#14802)
Co-authored-by: Kasey Kirkham <kasey@users.noreply.github.com>
2025-01-15 23:50:10 +00:00
james-prysm
8f43f6cc84 adding in error for generic check (#14801) 2025-01-15 21:36:09 +00:00
Manu NALEPA
e07341e1d5 ToBlinded: Use Fulu. (#14797)
* `ToBlinded`: Use Fulu.

* Fix Sammy's comment.

* `unmarshalState`: Use `hasFuluKey`.
2025-01-15 19:50:48 +00:00
Preston Van Loon
ef293e52f8 Use ip.addr.tools for DNS resolution test in p2p (#14800)
* Use ip.addr.tools for DNS resolution test in p2p

* Changelog fragment
2025-01-15 18:07:00 +00:00
Jun Song
72cc63a6a3 Clean TestCanUpgrade* tests (#14791)
* Clean TestCanUpgrade* tests

* Add new changelog file
2025-01-15 15:42:21 +00:00
Jun Song
34ff4c3ea9 Replace new exampleIP for example.org (#14795)
* Replace new exampleIP for example.org

* Add changelog
2025-01-15 06:14:25 +00:00
kasey
e8c968326a switch to unclog latest release instead of run artifact (#14793)
* use latest unclog release instead of run artifact

* add missing changelog entries to pre-unclog starter pack

---------

Co-authored-by: Kasey Kirkham <kasey@users.noreply.github.com>
2025-01-14 21:47:20 +00:00
kasey
2000ef457b Move prysm to unclog for changelog management (#14782)
Co-authored-by: Kasey Kirkham <kasey@users.noreply.github.com>
2025-01-14 18:22:38 +00:00
james-prysm
e36564c4d3 goethereum dependency to v1.14~ (#14351)
* updating the goethereum dependency

* fixing dependencies

* reverting workspace

* more fixes, work in progress

* trying with upgraded geth version

* fixing deprecated functions except for the time related ones on eth1 distance due to time issues

* fixing time issues

* gaz

* fixing test and upgrading some dependencies and reverting others

* Disable cgo in hid, delete old vendored usb library

* changelog

* rolling back dependencies

* fixing go mod tidy

* Geth v1.13.6

* fix tests

* Add ping interval, set to 500ms for tests. This didnt work

* Update to v1.14.8

* Spread it out to different bootnodes

* Fix it

* Remove Memsize

* Update all out of date dependencies

* Fix geth body change

* Fix Test

* Fix Build

* Fix Tests

* Fix Tests Again

* Fix Tests Again

* Fix Tests

* Fix Test

* Copy USB Package for HID

* Push it up

* Finally fix all tests with felix's changes

* updating geth dependency

* Update go-ethereum to v1.14.11

* fixing import

* reverting blob change

* fixing Implicit memory aliasing in for loop.

* WIP changes

* wip getting a little further on e2e runs

* getting a little further

* getting a little further

* setting everything to capella

* more partial fixes

* more fixes but still WIP

* fixing access list transactions"

* some cleanup

* making configs dynamic

* reverting time

* skip lower bound in builder

* updating to geth v1.14.12

* fixing verify blob to pointer

* go mod tidy

* fixing linting

* missed removing another terminal difficulty item

* another missed update

* updating more dependencies to fix cicd

* fixing holiman dependency update

* downgrading geth to 1.14.11 due to p2p loop issue

* reverting builder middleware caused by downgrade

* fixing more rollback issues

* upgrading back to 1.14.12 after discussing with preston

* mod tidy

* gofmt

* partial review feedback

* trying to start e2e from bellatrix instead

* reverting some changes

---------

Co-authored-by: Preston Van Loon <preston@pvl.dev>
Co-authored-by: nisdas <nishdas93@gmail.com>
2025-01-14 08:35:49 +00:00
terence
e5784d09f0 Update spec test to v1.5.0-beta.0 (#14788) 2025-01-13 20:05:34 +00:00
terence
e577bb0dcf Revert BlobSidecarsByRoot/Range version to v1 (#14785)
* Update blobs by range rpc topics to v1

* Update blobs by range rpc topics to v1

* RPC handler comments: Use "Added", "Modified" and "Upgraded".

- Added: No message with this message name was previously existing.
- Upgraded: A message with this message name was existing in the previous fork, but the schema version is upgraded in the current fork.
- Modified: The couple message name, schema version is the same than in the previous fork, but the implementation of the handler is modified in the current fork.

---------

Co-authored-by: Manu NALEPA <enalepa@offchainlabs.com>
2025-01-13 16:58:44 +00:00
Radosław Kapka
153d1872ae Separate type for unaggregated network attestations (#14659)
* definitions and gossip

* validator

* broadcast

* broadcast the correct att depending on version

* small updates

* don't check bits after Electra

* nitpick

* tests

* changelog <3

* review

* more review

* review yet again

* try a different design

* fix gossip issues

* cleanup

* tests

* reduce cognitive complexity

* Preston's review

* move changelog entry to unreleased section

* fix pending atts pool issues

* reviews

* Potuz's comments

* test fixes
2025-01-13 16:48:20 +00:00
terence
80aa811ab9 Fix kzg commitment inclusion proof depth minimal value (#14787) 2025-01-13 15:51:30 +00:00
Bastin
39cf2c8f06 Read LC Bootstraps from DB (#14718)
* fix bootstrap handler

* add tests for get bootstrap handler

* changelog

* make CreateDefaultLightClientBootstrap private

* remove fulu test

---------

Co-authored-by: Radosław Kapka <rkapka@wp.pl>
2025-01-10 16:51:55 +00:00
Bastin
e99df5e489 Save LC Bootstrap DB Space Optimization (#14775)
* add db optimization altair

* add db optimization

* add tests

* fix tests

* fix changelog

* remove debug code

* remove unused code

* fix comment

* remove unused code
2025-01-09 18:00:08 +00:00
oftenoccur
393e63e8e5 refactor: using slices.Contains to simplify the code (#14781)
Signed-off-by: oftenoccur <ezc5@sina.com>
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2025-01-09 00:04:45 +00:00
Manu NALEPA
c48d40907c Add Fulu fork boilerplate (#14771)
* Prepare for future fork boilerplate.

* Implement the Fulu fork boilerplate.

* `Upgraded state to <fork> log`: Move from debug to info.

Rationale:
This log is the only one notifying the user a new fork happened.
A new fork is always a little bit stressful for a node operator.
Having at least one log indicating the client switched fork is something useful.

* Update testing/util/helpers.go

Co-authored-by: Radosław Kapka <rkapka@wp.pl>

* Fix Radek's comment.

* Fix Radek's comment.

* Update beacon-chain/state/state-native/state_trie.go

Co-authored-by: Radosław Kapka <rkapka@wp.pl>

* Update beacon-chain/state/state-native/state_trie.go

Co-authored-by: Radosław Kapka <rkapka@wp.pl>

* Fix Radek's comment.

* Fix Radek's comment.

* Fix Radek's comment.

* Remove Electra struct type aliasing.

---------

Co-authored-by: Radosław Kapka <rkapka@wp.pl>
2025-01-07 20:09:12 +00:00
Nishant Das
a21f544219 Update to v0.33 (#14780) 2025-01-07 09:20:45 +00:00
Preston Van Loon
705a9e8dcd Electra: Spec review of process_slashings (#14766)
* Electra: Review process_slashings

* Update signature not to return the state, there is no need

* Update CHANGELOG.md
2025-01-06 13:24:58 +00:00
Skylar Ray
2dcb015470 Update CHANGELOG.md (#14753) 2025-01-06 13:09:25 +00:00
Nishant Das
211e1a4b7c Close Streams For Metadata Requests Better (#14776)
* Close streams better

* Changelog
2025-01-06 11:01:58 +00:00
Nishant Das
1efca9c28d Add Ability to Trace IDONTWANT Control Messages (#14778)
* Trace IDONTWANT Requests

* Changelog
2025-01-06 10:13:22 +00:00
Nishant Das
97d7ca828b Security Update For Dependencies (#14777)
* Update Golang Crypto

* Changelog
2025-01-06 10:00:59 +00:00
Preston Van Loon
31df250496 Electra: Update spec definition for process_registry_updates (#14767)
* Electra: review process_registry_updates

* Update CHANGELOG.md
2025-01-03 16:15:02 +00:00
Manu NALEPA
8a439a6f5d Simplify next Fork boilerplate creation. (#14761)
* Simplify next Fork boilerplate creation.

* Update beacon-chain/blockchain/execution_engine.go

Co-authored-by: Radosław Kapka <rkapka@wp.pl>

* Update beacon-chain/blockchain/execution_engine.go

Co-authored-by: Radosław Kapka <rkapka@wp.pl>

* Update beacon-chain/blockchain/execution_engine.go

Co-authored-by: Radosław Kapka <rkapka@wp.pl>

* Update beacon-chain/state/state-native/spec_parameters.go

Co-authored-by: Radosław Kapka <rkapka@wp.pl>

* Update beacon-chain/state/state-native/spec_parameters.go

Co-authored-by: Radosław Kapka <rkapka@wp.pl>

* Update beacon-chain/state/state-native/spec_parameters.go

Co-authored-by: Radosław Kapka <rkapka@wp.pl>

* Update beacon-chain/state/state-native/spec_parameters.go

Co-authored-by: Radosław Kapka <rkapka@wp.pl>

* Fix Radek's comments.

---------

Co-authored-by: Radosław Kapka <rkapka@wp.pl>
2025-01-03 14:39:08 +00:00
Radosław Kapka
8cff9356f1 Remove duplicate imports (#14772) 2025-01-03 11:42:14 +00:00
Nishant Das
afeb05c9a1 Update Go-Libp2p-Pubsub (#14770)
* Update to Current Master Head

* Changelog

* Update CHANGELOG.md
2025-01-03 10:52:46 +00:00
Preston Van Loon
fa16232924 Electra: Update spec definition for process_epoch (#14768)
* Electra: Review process_epoch

* Update CHANGELOG.md
2025-01-03 09:40:53 +00:00
Preston Van Loon
1f720bdbf4 Fix all typos (#14769) 2025-01-03 09:40:13 +00:00
Brindrajsinh Chauhan
79ea77ff57 update go version to 1.22.10 (#14729)
* update to go 1.22.10

* update change log

---------

Co-authored-by: Preston Van Loon <pvanloon@offchainlabs.com>
2025-01-02 23:07:38 +00:00
Radosław Kapka
d35cd0788e Remove v2 protos (#14765)
* Remove v2 protos

* changelog <3
2025-01-02 19:40:07 +00:00
Preston Van Loon
093e3df80a Remove slashingMultiplier argument from ProcessSlashings (#14762)
* Remove slashingMultiplier argument from ProcessSlashings

* Update CHANGELOG.md
2025-01-01 18:21:52 +00:00
Manu NALEPA
699a3b07a7 SSZ generation: Remove the // Hash: ... header. (#14760)
* `update-go-ssz.sh`: Remove the `// Hash: ...` line from the generated files header.

* Generate SSZ files.
2024-12-31 12:07:41 +00:00
Manu NALEPA
937d441e2e registerSubscribers: Register correctly. (#14759)
Issue before this commit:
The `currentSlot` in the `getSubnetsToSubscribe` is really set to the current slot. So, even if the `registerSubscribers` function is called
one epoch in advance, as done in `registerForUpcomingFork`, then
`currentSlot` will still be - really - the current slot.
==> The new blobs subnets will be subscribed only at the start of the
Electra fork, and not one epoch in advance.

With this commit:
The new blobs subnets will be effectively subscribed one epoch in advance.
2024-12-31 08:42:56 +00:00
terence
ead08d56d0 Implement EIP7691: Blob throughput increase (#14750)
* Add EIP-7691 blob throughput increase

* Review feedback

* Factorize blobs subscriptions.

---------

Co-authored-by: Manu NALEPA <enalepa@offchainlabs.com>
2024-12-30 19:23:56 +00:00
Savely
f55e62287a Fix Command Flag Typos and Syntax Issues (#14758)
* Update INTEROP.md

* Update INTEROP.md

---------

Co-authored-by: Radosław Kapka <rkapka@wp.pl>
2024-12-30 12:29:43 +00:00
Manu NALEPA
c7b2838873 Re-organize the content of the *.proto files. (#14755)
* Re-organize thet content of the `*.proto` files.

The content of the `*.proto` files is sorted by hard fork,
then with a top-down fashion.

Sorting first by hard fork lets the reader to easily see new or modified fields.
Then, sorting with a top-down fashion lets the user to first see the big picture,
then to dive into details.

Also, the `new in <hard fork>` mentions are only written for the given hard fork.
Thus, it'll avoid in the future the majority of the fields, not initially
present in phase 0, to have the `new in <hard fork> mention`.

This commit does not bring any new functional change.

* Update proto/prysm/v1alpha1/attestation.proto

Co-authored-by: Radosław Kapka <rkapka@wp.pl>

* Update proto/prysm/v1alpha1/beacon_state.proto

Co-authored-by: Radosław Kapka <rkapka@wp.pl>

* Fix Radek's comment.

---------

Co-authored-by: Radosław Kapka <rkapka@wp.pl>
2024-12-30 12:11:10 +00:00
Rupam Dey
9e7c1d6af6 Light client: add better error handling (#14749)
* add better error handling

* changelog
2024-12-26 20:46:29 +00:00
terence
6ce6b869e5 Implement consensus spec v1.5.0-alpha.10 (#14733)
* Use 16 bit random value

* enforce 0x02 credentials for consolidations

* Limit consolidating balance by validator effective balance

* Update max blob commitment size

* Fix next sync committee indices

* Bytes to little endian

* Handle proposer computations in between forks

* Fix config and tests

Fix tests

Fix tests

* Fix test stream events by properly set effective balance

Fix test stream events by properly set effective balance

* Preallocate buffers to avoid repeated allocations

* Potuz's feedback

* Use 16 bit random value

* enforce 0x02 credentials for consolidations

* Limit consolidating balance by validator effective balance

* Update max blob commitment size

* Fix next sync committee indices

* Bytes to little endian

* Handle proposer computations in between forks

* Fix config and tests

Fix tests

Fix tests

* Fix test stream events by properly set effective balance

Fix test stream events by properly set effective balance

* Preallocate buffers to avoid repeated allocations

* Potuz's feedback

* Fix change log
2024-12-23 17:32:41 +00:00
Charlton Liv
dbd53bd70d SA1019 fix: math/rand to crypto/rand (#14747)
* math/rand to crypto/rand

* Update CHANGELOG.md

* Update CHANGELOG.md

---------

Co-authored-by: terence <terence@prysmaticlabs.com>
Co-authored-by: Radosław Kapka <rkapka@wp.pl>
2024-12-23 10:18:38 +00:00
Radosław Kapka
d04b361cc3 Redesign of the attestation pool (#14324)
* Rename existing AttestationCache

* Cache with simple Add

* fix import cycle

* logic for unaggregated, aggregated and block attestations

* some small fixes

* remove Seen

* finishing touches

* feature flag

* extract forkchoice atts to separate type

* gate new functionality behind feature flag

* revert test files

* preparing for review

* change Id to [32]byte

* Potuz's review

* Potuz's review pt 2

* Nishant's review

* keep flat list of atts

* fix ForkchoiceAttestations() function

* Tests for Add, GetAll, Count

* Tests for remaining functions

* use DeepEqual

* fix tests

* documentation

* changelog <3

* v2 handlers

* nil check for forkchoice atts

* guard against 0 bits set

* fix failing test

* Preston's review

* better godocs
2024-12-23 09:59:32 +00:00
Manu NALEPA
96b31a9f64 Logging improvement. (#14735)
* Add a log before filesystem cache warm-up.

* Log `Successfully registered validator(s) on builder` ==> Debug.
2024-12-20 11:14:14 +00:00
Charlton Liv
a7c3004115 Go deps upgrade, from ioutil to io (#14737)
* ioutil to io

* Update CHANGELOG.md

---------

Co-authored-by: Radosław Kapka <rkapka@wp.pl>
2024-12-20 09:31:00 +00:00
Charlton Liv
30d5749ef6 Update CONTRIBUTING.md (#14738)
Co-authored-by: Radosław Kapka <rkapka@wp.pl>
2024-12-20 09:12:13 +00:00
terence
bc69ab8a44 Support for different blob target and max values (#14678)
* Add support for different blob target and max

* Fix change log to right section
2024-12-19 14:58:24 +00:00
Radosław Kapka
ed7b511949 Light Client: minor improvements (#14739) 2024-12-19 14:18:22 +00:00
Rupam Dey
0b7c005d7d add light client flag check to rpc handlers (#14736)
* add lc flag check to rpc handlers

* deps

* changelog

* update tests

* deps
2024-12-19 08:06:37 +00:00
Manu NALEPA
65e8c37b48 Refactor RPC handlers subscription. (#14732)
* Refactor RPC handlers subscription.

* Fix Sammy's comments.

* Update beacon-chain/sync/fork_watcher.go

Co-authored-by: Sammy Rosso <15244892+saolyn@users.noreply.github.com>

* Update beacon-chain/sync/fork_watcher.go

Co-authored-by: Sammy Rosso <15244892+saolyn@users.noreply.github.com>

* Update beacon-chain/sync/fork_watcher.go

Co-authored-by: Sammy Rosso <15244892+saolyn@users.noreply.github.com>

* Update beacon-chain/sync/fork_watcher.go

Co-authored-by: Sammy Rosso <15244892+saolyn@users.noreply.github.com>

---------

Co-authored-by: Sammy Rosso <15244892+saolyn@users.noreply.github.com>
2024-12-18 13:05:20 +00:00
Bastin
689015ff01 Add tests for save and read LC Bootstrap DB functions (#14724)
* add tests for bootstrapSaveAndRetreive

* not available boostrap

---------

Co-authored-by: Radosław Kapka <rkapka@wp.pl>
2024-12-18 09:17:32 +00:00
Bastin
08c14f02f6 clean up the updates by range handler (#14719)
* clean up the updates by range handler

* remove redundant HandleErrors

---------

Co-authored-by: Radosław Kapka <rkapka@wp.pl>
2024-12-18 08:08:29 +00:00
Bastin
4bb0b44f16 Add tests for saving light client updates (#14717)
* move flag settings out of individual tests

* add tests with better or worst old update

* remove whitespace

* add zero fields for default update at deneb block in electra

---------

Co-authored-by: Radosław Kapka <rkapka@wp.pl>
2024-12-18 08:08:25 +00:00
Manu NALEPA
29237cb0bc Refactor subnets subscriptions. (#14711)
* Refactor subnets subscriptions.

* Remove totally static/dynamic distinction.

* Unsubscribing from topic: Use INFO instead of log.

==> So we have something symmetrical with subscriptions.

* Address Nishant's comment.
2024-12-17 12:47:29 +00:00
Preston Van Loon
2b25ede641 Update changelog for v5.2.0 release (#14727)
* Update CHANGELOG.md for v5.2.0

* update latest develop
2024-12-17 06:12:02 +00:00
Preston Van Loon
b7de64a340 Check non-nil validator before accessing withdrawal credentials (#14705)
* Check non-nil validator before accessing withdrawal credentials

* Updated changelog
2024-12-16 16:34:01 +00:00
Manu NALEPA
11aa51e033 Display error in "Finished building block" only if error. (#14722) 2024-12-15 20:38:47 +00:00
terence
fa0dc09ce0 Add proper gas limit check through local computation (#14707)
* Add proper gas limit check through local computation

* Potuz's feedback

* Fix new line
2024-12-13 16:02:00 +00:00
Rupam Dey
d93a1b671c process lc finality update only for new finalized checkpoints (#14713)
* add checks for finalized checkpoint

* implement `EmptyExecutionPayloadHeader()` function

* changelog

* fix error message

* revert `process_block.go`

* fix error message

* testing

* Update CHANGELOG.md

Co-authored-by: Radosław Kapka <radoslaw.kapka@gmail.com>

* revert "testing"

---------

Co-authored-by: Radosław Kapka <radoslaw.kapka@gmail.com>
Co-authored-by: Radosław Kapka <rkapka@wp.pl>
2024-12-12 20:39:49 +00:00
Jun Song
1d8ffadd4f chore: add an error field to "Finished building block" (#14696)
* fix: print "Finished building block" only when succeeded

* Add failed log

* Apply preston's review
2024-12-12 17:07:34 +00:00
Nishant Das
ac1717f1e4 Revert "Change Max Payload Size (#14692)" (#14716)
This reverts commit df81fa3e9a.
2024-12-12 15:21:47 +00:00
Dan Park
6e6012b12f Bugfix: Apply eip7549 to slashing pool (#14691)
* Apply eip7549 to slashing pool

* Add CHANGELOG.md

* Update bazel

---------

Co-authored-by: Radosław Kapka <rkapka@wp.pl>
2024-12-11 18:57:21 +00:00
Nishant Das
008f157e17 Update Quic-go to the latest version (#14710)
* Update to v0.48.2

* Changelog
2024-12-11 09:37:54 +00:00
Bastin
7afb8c3c86 move light client rpc helpers tests to core (#14695)
* move rpc helpers tests to core

* remove helpers tests

* fix linter

* deleted extra files

* fix conflicts

---------

Co-authored-by: Radosław Kapka <rkapka@wp.pl>
Co-authored-by: Inspector-Butters <mohamadbastin@gmail.com>
2024-12-10 19:51:29 +00:00
terence
e925d35d55 Fix proposer boost test (#14701) 2024-12-10 18:00:24 +00:00
Manu NALEPA
1f2d8cfae9 searchForPeers: Replace batchSize by batchPeriod. (#14704)
Rationale:
Before this commit, the internal loop exited if:
- the expected amount of peers is found, or,
- the iterator returns `false` (exhaustion), or
- `batchSize` iterations are done.

The issue with the iterations count is, in case not enough
peer are found AND `iterator.Next` always returns `true`,
we don't control WHEN the loop is going to stop.

The root cause is we don't control the time needed to
run the `iterator.Next` function, which is a function of
`devp2P (geth)`.

The value of `batchSize (2000)` was chosen arbitrarily.
It turns out the time needed to run `iterator.Next` can go from a few micro seconds to a few hundreds of milliseconds.

==> In small networks (example: E2E tests), it was possible for the loop not to exit during several dozen of seconds.

With this commit, we replace the `batchSize` by a `batchPeriod`, ensuring the loop will never
run longer than `batchPeriod`, even in a small network.

Co-authored-by: Nishant Das <nishdas93@gmail.com>
2024-12-10 04:52:02 +00:00
terence
63bc965ddc Revert "Proposer checks gas limit before accepting builder's bid" (#14706)
* Revert "Proposer checks gas limit before accepting builder's bid (#14311)"

This reverts commit f43383a3fb.

* Change list
2024-12-10 01:37:19 +00:00
Rupam Dey
a0791d77eb fix segmentation fault in E2E when light-client feature flag is enabled (#14699)
* use `blockEpoch` in `BlockToLightClientHeader`

* deps

* dont use `EmptyExecutionPayload()`

* use original logic

* changelog

* add feature flag check

* fix

* fix error messages

* update `BlockToLightClientHeader` tests

* changelog

* deps
2024-12-10 01:13:58 +00:00
Manu NALEPA
0d810a1fd6 startDB: Add log when checkpoint sync. (#14690) 2024-12-09 18:46:41 +00:00
terence
92bbf6344c Check kzg commitment for beacon-api propose block (#14702)
Co-authored-by: Preston Van Loon <pvanloon@offchainlabs.com>
2024-12-09 14:38:28 +00:00
Nishant Das
df81fa3e9a Change Max Payload Size (#14692)
* Increase Max Payload Size

* Changelog

* Use MaxGossipSize

* Remove change
2024-12-09 13:53:24 +00:00
Rupam Dey
30a136f1fb save light client updates (diff) (#14683)
* update diff

* deps

* add tests for `SaveLightClientUpdate`

* cleanup imports

* lint

* changelog

* fix incorrect arithmetic

* check for lightclient feature flag

* fix tests

* fix `saveLightClientBootstrap` and `saveLightClientUpdate`

* replace and with or

* move feature check to `postBlockProcess`

---------

Co-authored-by: Radosław Kapka <rkapka@wp.pl>
2024-12-04 21:22:43 +00:00
terence
b23c562b67 Pass alpha 9 spec tests (#14667)
* Add missed exit checks to consolidation processing

* Use safe add

* gaz

* Pass spec tests (except single attestation)

Revert params.SetupTestConfigCleanupWithLock(t)

* Update earlist exit epoch for upgrade to electra

* Validate that each committee bitfield in an aggregate contains at least one non-zero bit

* Add single attestation

* Add single attestation to ssz static

* Fix typo

Co-authored-by: Md Amaan <114795592+Redidacove@users.noreply.github.com>

* Update UpgradeToElectra comments

* Add no lint dupword

---------

Co-authored-by: james-prysm <james@prysmaticlabs.com>
Co-authored-by: Md Amaan <114795592+Redidacove@users.noreply.github.com>
2024-12-04 16:08:10 +00:00
kasey
ae36630ccd Raise http body limit for fetching genesis state on Holesky (#14689)
* use larger limit when fetching genesis

* changelog

---------

Co-authored-by: Kasey Kirkham <kasey@users.noreply.github.com>
2024-12-03 21:08:19 +00:00
Preston Van Loon
ac72fe2e0e Remove interop genesis service from beacon node (#14417)
* Remove interop dependencies from production binary for beacon-chain. Specifically, remove the interop genesis service.

Finding links to pebble: 
bazel query 'somepath(//cmd/beacon-chain, @com_github_cockroachdb_pebble//...)' --notool_deps

* Update INTEROP.md

* Remove interop config

* Remove ancient interop script

* Add electra support for premine genesis

* Add example of --chain-config-file, test interop instructions

* Fixes

* Add binary size reduction

* Update binary size reduction

* Fix duplicate switch case

* Move CHANGELOG entries to unreleased section

* gofmt

* fix
2024-12-03 19:08:49 +00:00
Nishant Das
d09885b7ce Make QUIC The Default Transport (#14688)
* Make it the default

* Changelog

* Remove outdated flag

* Update `go-libp2p` to `v0.36.5` and `webtransport-go` to `master`.

---------

Co-authored-by: Manu NALEPA <enalepa@offchainlabs.com>
2024-12-03 17:00:15 +00:00
Nishant Das
dc643c9f32 Fix Deadline Again During Rollback (#14686)
* fix it again

* CHANGELOG
2024-12-02 13:29:36 +00:00
Dhruv Bodani
9fa49e7bc9 Add error counter for SSE endpoint (#14681)
* add error counter for SSE endpoint

* add changelog entry
2024-11-29 12:18:53 +00:00
Sammy Rosso
1139c90ab2 Add metadata fields to getBlobSidecars (#14677)
* add metadata fields to getBlobSidecars

* gaz

* changelog

* Dhruv + Radek' reviews
2024-11-28 16:42:55 +00:00
Manu NALEPA
79d05a87bb listenForNewNodes and FindPeersWithSubnet: Stop using ReadNodes and use iterator instead. (#14669)
* `listenForNewNodes` and `FindPeersWithSubnet`: Stop using `Readnodes` and use iterator instead.

It avoids infinite loop in small devnets.

* Update beacon-chain/p2p/discovery.go

Co-authored-by: Sammy Rosso <15244892+saolyn@users.noreply.github.com>

---------

Co-authored-by: Sammy Rosso <15244892+saolyn@users.noreply.github.com>
2024-11-28 11:25:28 +00:00
kasey
1707cf3ec7 http response handling improvements (#14673)
Co-authored-by: Kasey Kirkham <kasey@users.noreply.github.com>
2024-11-27 22:13:45 +00:00
wangjingcun
bdbb850250 chore: fix 404 status URL (#14675)
Signed-off-by: wangjingcun <wangjingcun@aliyun.com>
Co-authored-by: Radosław Kapka <rkapka@wp.pl>
2024-11-27 15:54:00 +00:00
Dhruv Bodani
b28b1ed6ce Add error count prom metric (#14670)
* add error count prom metric

* address review comments

* add comment for response writer

* update changelog
2024-11-27 11:56:07 +00:00
Sammy Rosso
74bb0821a8 Use slot to determine fork version (#14653)
* Use slot to determine version

* gaz

* solve cyclic dependency

* Radek' review

* unit test

* gaz

* use require instead of assert

* fix test

* fix test

* fix TestGetAggregateAttestation

* fix ListAttestations test

* James' review

* Radek' review

* add extra checks to GetAttesterSlashingsV2

* fix matchingAtts

* improve tests + fix

* fix

* stop appending all non electra atts

* more tests

* changelog

* revert TestProduceSyncCommitteeContribution changes

---------

Co-authored-by: Radosław Kapka <rkapka@wp.pl>
Co-authored-by: rkapka <radoslaw.kapka@gmail.com>
2024-11-26 22:52:58 +00:00
terence
8025a483e2 Remove kzg proof check for blob reconstructor (#14671) 2024-11-26 19:36:42 +00:00
Manu NALEPA
0475631543 Improve connection/disconnection logging. (#14665)
* Improve disconnection logs.

* Update beacon-chain/p2p/handshake.go

Co-authored-by: Sammy Rosso <15244892+saolyn@users.noreply.github.com>

* Address Sammy's comment.

* Update beacon-chain/p2p/handshake.go

Co-authored-by: Sammy Rosso <15244892+saolyn@users.noreply.github.com>

* Fix Sammy's comment.

* Fix Sammy's comment.

* `MockPeerManager`: Stop mixing value and pointer receivers (deepsource).

* Remove unused parameters (deepsource)

* Fix receiver names (deepsource)

* Change not after into before (deepsource)

* Update beacon-chain/p2p/handshake.go

Co-authored-by: Sammy Rosso <15244892+saolyn@users.noreply.github.com>

* Update beacon-chain/p2p/peers/status.go

Co-authored-by: Sammy Rosso <15244892+saolyn@users.noreply.github.com>

---------

Co-authored-by: Sammy Rosso <15244892+saolyn@users.noreply.github.com>
2024-11-26 17:53:27 +00:00
Potuz
f27092fa91 Check if validator exists when applying pending deposit (#14666)
* Check if validator exists when applying pending deposit

* Add test TestProcessPendingDepositsMultiplesSameDeposits

* keep a map of added pubkeys

---------

Co-authored-by: terence tsao <terence@prysmaticlabs.com>
2024-11-25 20:31:02 +00:00
Radosław Kapka
67cef41cbf Better attestation packing for Electra (#14534)
* Better attestation packing for Electra

* changelog <3

* bzl

* sort before constructing on-chain aggregates

* move ctx to top

* extract Electra logic and add comments

* benchmark
2024-11-25 18:41:51 +00:00
Manu NALEPA
258908d50e Diverse log improvements, comment additions and small refactors. (#14658)
* `logProposedBlock`: Fix log.

Before, the value of the pointer to the function were printed for `blockNumber`
instead of the block number itself.

* Add blob prefix before sidecars.

In order to prepare for data columns sidecars.

* Verification: Add log prefix.

* `validate_aggregate_proof.go`: Add comments.

* `blobSubscriber`: Fix error message.

* `registerHandlers`: Rename, add comments and little refactor.

* Remove duplicate `pb` vs. `ethpb` import.

* `rpc_ping.go`: Factorize / Add comments.

* `blobSidecarsByRangeRPCHandler`: Do not write error response if rate limited.

* `sendRecentBeaconBlocksRequest` ==> `sendBeaconBlocksRequest`.

The function itself does not know anything about the age of the beacon block.

* `beaconBlocksByRangeRPCHandler`: Refactor and add logs.

* `retentionSeconds` ==> `retentionDuration`.

* `oneEpoch`: Add documentation.

* `TestProposer_ProposeBlock_OK`: Improve error message.

* `getLocalPayloadFromEngine`: Tiny refactor.

* `eth1DataMajorityVote`: Improve log message.

* Implement `ConvertPeerIDToNodeID`and do note generate random private key if peerDAS is enabled.

* Remove useless `_`.

* `parsePeersEnr`: Fix error mesages.

* `ShouldOverrideFCU`: Fix error message.

* `blocks.go`: Minor comments improvements.

* CI: Upgrade golanci and enable spancheck.

* `ConvertPeerIDToNodeID`: Add godoc comment.

* Update CHANGELOG.md

Co-authored-by: Sammy Rosso <15244892+saolyn@users.noreply.github.com>

* Update beacon-chain/sync/initial-sync/service_test.go

Co-authored-by: Sammy Rosso <15244892+saolyn@users.noreply.github.com>

* Update beacon-chain/sync/rpc_beacon_blocks_by_range.go

Co-authored-by: Sammy Rosso <15244892+saolyn@users.noreply.github.com>

* Update beacon-chain/sync/rpc_blob_sidecars_by_range.go

Co-authored-by: Sammy Rosso <15244892+saolyn@users.noreply.github.com>

* Update beacon-chain/sync/rpc_ping.go

Co-authored-by: Sammy Rosso <15244892+saolyn@users.noreply.github.com>

* Remove trailing whitespace in godoc.

---------

Co-authored-by: Sammy Rosso <15244892+saolyn@users.noreply.github.com>
2024-11-25 09:22:33 +00:00
Manu NALEPA
415a42a4aa Add proto for DataColumnIdentifier, DataColumnSidecar, DataColumnSidecarsByRangeRequest and MetadataV2. (#14649)
* Add data column sidecars proto.

* Fix Terence's comment.

* Re-add everything.
2024-11-22 09:50:06 +00:00
kasey
25eae3acda Fix eventstream electra atts (#14655)
* fix handler for electra atts

* same fix for attestation_slashing

* changelog

---------

Co-authored-by: Kasey Kirkham <kasey@users.noreply.github.com>
2024-11-22 03:04:00 +00:00
Rupam Dey
956d9d108c Update light-client consensus types (#14652)
* update diff

* deps

* changelog

* remove `SetNextSyncCommitteeBranchElectra`
2024-11-21 12:28:44 +00:00
Sammy Rosso
c285715f9f Add missing Eth-Consensus-Version headers (#14647)
* add missing Eth-Consensus-Version headers

* changelog

* fix header return value
2024-11-20 22:16:33 +00:00
james-prysm
9382ae736d validator REST: attestation v2 (#14633)
* wip

* fixing tests

* adding unit tests

* fixing tests

* adding back v1 usage

* changelog

* rolling back test and adding placeholder

* adding electra tests

* adding attestation nil check based on review

* reduce code duplication

* linting

* fixing tests

* based on sammy review

* radek feedback

* adding fall back for pre electra and updated tests

* fixing api calls and associated tests

* gaz

* Update validator/client/beacon-api/propose_attestation.go

Co-authored-by: Radosław Kapka <rkapka@wp.pl>

* review feedback

* add missing fallback

* fixing tests

---------

Co-authored-by: Radosław Kapka <rkapka@wp.pl>
2024-11-20 17:13:57 +00:00
Radosław Kapka
f16ff45a6b Update light client protobufs (#14650)
* Update light client protobufs

* changelog <3
2024-11-20 14:47:54 +00:00
kasey
8d6577be84 defer payload attribute computation (#14644)
* defer payload attribute computation

* fire payload event on skipped slots

* changelog

* fix test and missing version attr

* fix lint

* deepsource

* mv head block lookup for missed slots to streamer

---------

Co-authored-by: Kasey Kirkham <kasey@users.noreply.github.com>
2024-11-19 16:49:52 +00:00
james-prysm
9de75b5376 reorganizing p2p and backfill service registration for consistency (#14640)
* reorganizing for consistency

* Update beacon-chain/node/node.go

Co-authored-by: kasey <489222+kasey@users.noreply.github.com>

* kasey's feedback

---------

Co-authored-by: kasey <489222+kasey@users.noreply.github.com>
2024-11-19 16:29:59 +00:00
james-prysm
a7ba11df37 adding nil checks on attestation interface (#14638)
* adding nil checks on interface

* changelog

* add linting

* adding missed checks

* review feedback

* attestation bits should not be in nil check

* fixing nil checks

* simplifying function

* fixing some missed items

* more missed items

* fixing more tests

* reverting some changes and fixing more tests

* adding in source check back in

* missed test

* sammy's review

* radek feedback
2024-11-18 17:51:17 +00:00
Stefano
00aeea3656 feat(issue-12348): add validator index label to validator_statuses me… (#14473)
* feat(issue-12348): add validator index label to validator_statuses metric

* fix: epochDuties added label on emission of metric

---------

Co-authored-by: james-prysm <90280386+james-prysm@users.noreply.github.com>
2024-11-18 16:35:05 +00:00
james-prysm
9dbf979e77 move get data after nil check for attestations (#14642)
* move getData to after validations

* changelog
2024-11-15 18:28:35 +00:00
james-prysm
be60504512 Validator REST api: adding in check for empty keys changed (#14637)
* adding in check for empty keys changed

* changelog

* kasey feedback

* fixing unit tests

* Update CHANGELOG.md

Co-authored-by: Sammy Rosso <15244892+saolyn@users.noreply.github.com>

---------

Co-authored-by: Sammy Rosso <15244892+saolyn@users.noreply.github.com>
2024-11-13 16:09:11 +00:00
james-prysm
1857496159 Electra: unskipping merkle spec tests: (#14635)
* unskipping spec tests

* changelog
2024-11-12 15:41:44 +00:00
Justin Traglia
ccf61e1700 Rename remaining "deposit receipt" to "deposit request" (#14629)
* Rename remaining "deposit receipt" to "deposit request"

* Add changelog entry

---------

Co-authored-by: james-prysm <90280386+james-prysm@users.noreply.github.com>
2024-11-08 21:15:43 +00:00
Justin Traglia
4edbd2f9ef Remove outdated spectest exclusions for EIP-6110 (#14630)
Co-authored-by: james-prysm <90280386+james-prysm@users.noreply.github.com>
2024-11-08 20:41:02 +00:00
james-prysm
5179af1438 validator REST API: block v2 and Electra support (#14623)
* adding electra to validator client rest for get and post, also migrates to use the v2 endpoints

* changelog

* fixing test

* fixing linting
2024-11-08 18:24:51 +00:00
Sammy Rosso
c0f9689e30 Add POST /eth/v2/beacon/pool/attestations endpoint (#14621)
* modify v1 and add v2

* test

* changelog

* small fixes

* fix tests

* simplify functions + remove duplication

* Radek' review + group V2 tests

* better errors

* fix tests
2024-11-08 11:33:27 +00:00
Sammy Rosso
ff8240a04f Add /eth/v2/validator/aggregate_attestation (#14481)
* add endpoint

* changelog

* fix tests

* fix endpoint

* remove useless broken code

* review + fix endpoint

* gaz

* fix aggregate selection proof test

* fixes

* new way of aggregating

* nit

* fix part of the tests

* fix tests

* cleanup

* fix AggSelectionProof test

* tests

* v1 tests

* v2 tests

* commiittee bits

---------

Co-authored-by: rkapka <radoslaw.kapka@gmail.com>
Co-authored-by: Radosław Kapka <rkapka@wp.pl>
2024-11-07 13:34:18 +00:00
Nishant Das
847498c648 Optimize Message ID Computation (#14591)
* Cast to String Without Allocating

* Make it its own method

* Changelog

* Gosec

* Add benchmark, fuzz test, and @kasey's implementation.

* Gosec

* Fix benchmark test names

* Kasey's Suggestion

* Radek's Suggestion

---------

Co-authored-by: Preston Van Loon <preston@pvl.dev>
2024-11-07 12:54:58 +00:00
Jun Song
2633684339 Use GetBlockAttestationV2 at handler (#14624) 2024-11-07 05:52:53 +00:00
terence
ab3f1963e2 Return early blob constructor if not deneb (#14605)
* Return early blob constructor if not deneb

* Update CHANGELOG.md

Co-authored-by: Radosław Kapka <rkapka@wp.pl>

* Remove test

* Remove space

---------

Co-authored-by: Radosław Kapka <rkapka@wp.pl>
2024-11-06 15:09:20 +00:00
Justin Traglia
b87d02eeb3 Fix various small things in state-native code (#14604)
* Add nil checks in AppendPending*() functions

* Import errors

* Run goimports

* Move PendingDeposit.Amount to right spot

* Rename DequeuePartialWithdrawals to DequeuePendingPartialWithdrawals

* Remove parans from errNotSupported arg

* In electraField, move LatestExecutionPayloadHeader

* Add changelog entry

---------

Co-authored-by: james-prysm <90280386+james-prysm@users.noreply.github.com>
2024-11-05 16:07:40 +00:00
Cam Sweeney
bcb4155523 prevent panic by returning on connection error (#14602)
* prevent panic by returning on connection error

* add test

* don't close eventschannel on error

---------

Co-authored-by: Sammy Rosso <15244892+saolyn@users.noreply.github.com>
Co-authored-by: james-prysm <90280386+james-prysm@users.noreply.github.com>
2024-11-04 21:10:58 +00:00
Preston Van Loon
77f10b9e0e Benchmark process slots (#14616)
* Benchmark process slots

* Update changelog
2024-11-04 16:27:07 +00:00
Nishant Das
928b707ef1 Rollback Block With Context Deadline (#14608)
* Rollback deadline

* Fix it

* Preston's Suggestion
2024-11-04 15:47:30 +00:00
Nishant Das
91c15247e5 Allow Protobuf State To Be Created Without Copying (#14613)
* Read raw validator registry

* Changelog

* Radek's Suggestion

* Add Nil Check
2024-11-04 15:09:15 +00:00
Potuz
5ef5b65ffe Blocks after capella are execution (#14614)
* Blocks after capella are execution

* fix test
2024-11-04 13:59:41 +00:00
Nishant Das
9ae97786c5 Build Proto State Object Once (#14612)
* Call it Once

* Changelog
2024-11-04 09:21:34 +00:00
Potuz
66d1bb54f6 Change the signature of ProcessPayload (#14610) 2024-11-03 14:37:52 +00:00
Potuz
4d98049054 Use ROBlock earlier in the pipeline (#14609) 2024-11-03 11:04:12 +00:00
Justin Traglia
d5ff25b59d Fix order & add slashed=false to new validator instances (#14595)
* Fix order & add slashed=false to new validator instances

* Add a line to the changelog

* Update godocs
2024-11-02 15:35:40 +00:00
james-prysm
a265cf08fa adding in a check to make sure duplicates are now allowed (#14601) 2024-11-01 19:11:12 +00:00
james-prysm
f2ade3caff Remove validator count log (#14600)
* remove validator count API call and update logs

* fixing test

* changelog

* removing unused function

* gaz

* casing

* fixing more tests
2024-11-01 16:58:29 +00:00
james-prysm
e6ffc0701e Electra: exclude empty requests in requests list (#14580)
* implementing new decisions around exectuion requests

* fixing test fixture

* adding in more edge case checks and tests

* changelog

* fixing unsafe type cast

* Update beacon-chain/execution/engine_client_test.go

Co-authored-by: Preston Van Loon <pvanloon@offchainlabs.com>

* Update proto/engine/v1/electra.go

Co-authored-by: Preston Van Loon <pvanloon@offchainlabs.com>

* Update proto/engine/v1/electra.go

Co-authored-by: Preston Van Loon <pvanloon@offchainlabs.com>

* Update proto/engine/v1/electra.go

Co-authored-by: Preston Van Loon <pvanloon@offchainlabs.com>

* Update proto/engine/v1/electra.go

Co-authored-by: Preston Van Loon <pvanloon@offchainlabs.com>

* Update proto/engine/v1/electra_test.go

Co-authored-by: Preston Van Loon <pvanloon@offchainlabs.com>

* Update proto/engine/v1/electra_test.go

Co-authored-by: Preston Van Loon <pvanloon@offchainlabs.com>

* updating based on preston's feedback and adding more tests for edge cases

* adding more edgecases, and unit tests

* fixing tests

* missed some export changes

* adding more tests

* Update proto/engine/v1/electra.go

Co-authored-by: Potuz <potuz@prysmaticlabs.com>

* reducing complexity of function based on feedback

---------

Co-authored-by: Preston Van Loon <pvanloon@offchainlabs.com>
Co-authored-by: Potuz <potuz@prysmaticlabs.com>
2024-10-31 19:12:23 +00:00
james-prysm
61c296e075 eip7251: Bugfix and more withdrawal tests (#14578)
* addressing bug with withdrawals for devnet 5

* changelog

* fixing if statement check

* adding test

* terence's review comments

* attempting to fix weird comment formatting

* moving back more comments

* Update CHANGELOG.md

Co-authored-by: Sammy Rosso <15244892+saolyn@users.noreply.github.com>

---------

Co-authored-by: Sammy Rosso <15244892+saolyn@users.noreply.github.com>
2024-10-31 17:02:22 +00:00
Sammy Rosso
f264680739 Simplify ExitedValidatorIndices (#14587)
* fix

* add to comment

* modify test

* remove unused parameter

* changelog

* exclude ejected from exited

* fix linter

---------

Co-authored-by: james-prysm <90280386+james-prysm@users.noreply.github.com>
2024-10-31 14:49:25 +00:00
Sammy Rosso
8fe024f6a1 Simplify EjectedValidatorIndices (#14588)
* fix

* fix test

* add to comment

* changelog
2024-10-31 11:22:40 +00:00
Nishant Das
6b7dd833a3 Use Read Only Head State When Computing Active Indices (#14592)
* Use Read Only Head State

* Use Read Only Head State
2024-10-31 06:48:56 +00:00
james-prysm
060527032b small improvements to logs (#14405)
* removing redundant log, and poorly worded log

* move log printing message

* changelog

* reverting a log change
2024-10-29 20:42:24 +00:00
Preston Van Loon
a29ecb6bbe Update beacon-chain pgo profile (#14589)
* Update pprof image with a recent one

* Update CHANGELOG.md
2024-10-29 15:18:56 +00:00
james-prysm
54656e172f keymanager API: bug fixes and inconsistencies (#14586)
* fixing error handling and returning empty requests with the wrong wallet type

* changelog

* adding some unit tests

* Update validator/rpc/handlers_keymanager.go

Co-authored-by: Sammy Rosso <15244892+saolyn@users.noreply.github.com>

* Update CHANGELOG.md

Co-authored-by: Sammy Rosso <15244892+saolyn@users.noreply.github.com>

* Update validator/rpc/handlers_keymanager.go

Co-authored-by: Sammy Rosso <15244892+saolyn@users.noreply.github.com>

* Update validator/rpc/intercepter.go

Co-authored-by: Sammy Rosso <15244892+saolyn@users.noreply.github.com>

* Update validator/rpc/intercepter_test.go

Co-authored-by: Sammy Rosso <15244892+saolyn@users.noreply.github.com>

* Update validator/rpc/intercepter_test.go

Co-authored-by: Sammy Rosso <15244892+saolyn@users.noreply.github.com>

* lint

---------

Co-authored-by: Sammy Rosso <15244892+saolyn@users.noreply.github.com>
2024-10-29 14:37:14 +00:00
kasey
97c8adb003 fix --backfill-oldest-slot flag handling (#14584)
* fix --backfill-oldest-slot flag handling

* changelog

---------

Co-authored-by: Kasey Kirkham <kasey@users.noreply.github.com>
2024-10-28 15:58:30 +00:00
Nishant Das
2fe8614115 Rollback Block During Processing (#14554)
* Change it to rollback

* Spacing

* Reverse order of rollback

* Add Rollback Test

* Potuz's Test Suggestion

* Potuz's Suggestion
2024-10-28 14:06:20 +00:00
Sammy Rosso
09accc7132 Add GET /eth/v2/beacon/pool/attestations endpoint (#14560)
* add ListAttestationsV2 endpoint

* fix endpoint

* changelog

* add endpoint to tests

* add trailing comma

* add version header + lint fix

* all reviews

* modify v1 and comments

* fix linter

* Radek' review
2024-10-28 10:59:27 +00:00
terence
53f1f11c6d Fix length check between kzg commitments and exist (#14581) 2024-10-25 17:59:57 +00:00
Sammy Rosso
48fe9d9c4d Add missing version headers (#14566)
* add version headers

* use headstate and add unit test

* changelog
2024-10-25 16:01:55 +00:00
Preston Van Loon
4386c244e1 Docker fix: Update bazel-lib to latest version (#14579)
* Update bazel-lib

* Update rules_oci

* Compress pkg_tar

* Add a note about 401 download for distroless/cc-debian11

* Update CHANGELOG.md

* Re-upload distroless/cc-debian11 to prysmaticlabs/distroless/cc-debian11 such that the image is public.

Ran the following command:
gcrane cp 'gcr.io/distroless/cc-debian11@sha256:b82f113425c5b5c714151aaacd8039bc141821cdcd3c65202d42bdf9c43ae60b' gcr.io/prysmaticlabs/distroless/cc-debian11:latest

* Back out "Update rules_oci"

This backs out commit 64200fb25e.
2024-10-25 02:30:21 +00:00
terence
7ac522d8ff Use engine api get-blobs for block subscriber (#14513)
* Use engine api get-blobs for block subscriber

Debug

changelog

add proto marshal and unmarshal

Kasey's feedback

* Feedback

* Preston's feedback

* Exist argument should not be hardcoded with kzg count
2024-10-24 21:30:14 +00:00
kasey
52cf3a155d Safe StreamEvents write loop (#14557)
* new type for tests where errors are only logged

* StreamHandler waits for write loop exit

* add test case for writer timeout

* add changelog

* add missing file

* logging fix

* fix logging test to allow info logs

* naming/comments; make response controller private

* simplify cancel defers

* fix typo in test file name

---------

Co-authored-by: Kasey Kirkham <kasey@users.noreply.github.com>
2024-10-24 19:16:17 +00:00
Potuz
83ed320826 Use ROBlock in block processing pipeline (#14571)
* Use ROBlock in block processing pipeline

* Pass blockchain tests

* passing forkchoice tests

* pass rpc test

* change changelog
2024-10-24 13:27:15 +00:00
1189 changed files with 73571 additions and 56665 deletions

View File

@@ -1 +1 @@
7.1.0
7.4.1

View File

@@ -33,5 +33,5 @@ Fixes #
**Acknowledgements**
- [ ] I have read [CONTRIBUTING.md](https://github.com/prysmaticlabs/prysm/blob/develop/CONTRIBUTING.md).
- [ ] I have made an appropriate entry to [CHANGELOG.md](https://github.com/prysmaticlabs/prysm/blob/develop/CHANGELOG.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.

View File

@@ -1,4 +1,4 @@
FROM golang:1.22-alpine
FROM golang:1.24-alpine
COPY entrypoint.sh /entrypoint.sh

View File

@@ -1,33 +1,34 @@
name: CI
# 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
branches: [ "develop" ]
jobs:
changed_files:
runs-on: ubuntu-latest
name: Check CHANGELOG.md
run-changelog-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: changelog modified
id: changelog-modified
uses: tj-actions/changed-files@v45
with:
files: CHANGELOG.md
- name: Checkout source code
uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
- name: List all changed files
- 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_CHANGED_FILES: ${{ steps.changelog-modified.outputs.all_changed_files }}
run: |
if [[ ${ALL_CHANGED_FILES[*]} =~ (^|[[:space:]])"CHANGELOG.md"($|[[:space:]]) ]];
then
echo "CHANGELOG.md was modified.";
exit 0;
else
echo "CHANGELOG.md was not modified.";
echo "Please see CHANGELOG.md and follow the instructions to add your changes to that file."
echo "In some rare scenarios, a changelog entry is not required and this CI check can be ignored."
exit 1;
fi
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
View 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"

View File

@@ -16,7 +16,7 @@ jobs:
- uses: actions/checkout@v3
- uses: actions/setup-go@v4
with:
go-version: '1.22.3'
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.22.3'
go-version: '1.23.5'
- uses: shogo82148/actions-go-fuzz/run@v0
with:
packages: ${{ matrix.package }}

View File

@@ -28,15 +28,15 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Go 1.22
- name: Set up Go 1.24
uses: actions/setup-go@v4
with:
go-version: '1.22.6'
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.19.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
@@ -45,16 +45,16 @@ jobs:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Go 1.22
- name: Set up Go 1.24
uses: actions/setup-go@v4
with:
go-version: '1.22.6'
go-version: '1.24.0'
id: go
- name: Golangci-lint
uses: golangci/golangci-lint-action@v5
with:
version: v1.55.2
version: v1.64.5
args: --config=.golangci.yml --out-${NO_FUTURE}format colored-line-number
build:
@@ -64,7 +64,7 @@ jobs:
- name: Set up Go 1.x
uses: actions/setup-go@v4
with:
go-version: '1.22.6'
go-version: '1.24.0'
id: go
- name: Check out code into the Go module directory

View File

@@ -1,28 +1,20 @@
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.22.6'
linters:
enable-all: true
disable:
# Deprecated linters:
- deadcode
- exhaustivestruct
- golint
- govet
- ifshort
- interfacer
- maligned
- nosnakecase
- scopelint
- structcheck
- varcheck
# Disabled for now:
- asasalint
@@ -34,6 +26,8 @@ linters:
- dogsled
- dupl
- durationcheck
- errname
- err113
- exhaustive
- exhaustruct
- forbidigo
@@ -47,17 +41,17 @@ linters:
- gocyclo
- godot
- godox
- goerr113
- gofumpt
- gomnd
- gomoddirectives
- gosec
- inamedparam
- interfacebloat
- intrange
- ireturn
- lll
- maintidx
- makezero
- mnd
- musttag
- nakedret
- nestif
@@ -72,13 +66,16 @@ linters:
- predeclared
- promlinter
- protogetter
- recvcheck
- revive
- spancheck
- staticcheck
- stylecheck
- tagalign
- tagliatelle
- thelper
- unparam
- usetesting
- varnamelen
- wrapcheck
- wsl

View File

@@ -165,7 +165,7 @@ STATICCHECK_ANALYZERS = [
"sa6006",
"sa9001",
"sa9002",
#"sa9003", # Doesn't build. See https://github.com/dominikh/go-tools/pull/1483
"sa9003",
"sa9004",
"sa9005",
"sa9006",
@@ -197,6 +197,7 @@ 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",

View File

@@ -4,18 +4,321 @@ All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
## [Unreleased](https://github.com/prysmaticlabs/prysm/compare/v5.1.2...HEAD)
## [v5.3.2](https://github.com/prysmaticlabs/prysm/compare/v5.3.1...v5.3.2) - 2025-03-25
This release introduces support for the `Hoodi` testnet.
Release highlights:
- Ability to run the node on the `Hoodi` tesnet. See https://blog.ethereum.org/2025/03/18/hoodi-holesky for more information about `Hoodi`.
- A new feature that allows treat certain blocks as invalid. This is especially useful when the network is split, allowing the node to discontinue following unwanted forks.
Testnet operators are required to update to this release. Without this release you will be unable to run the node on the `Hoodi` testnet.
Mainnet operators are recommended to update to this release at their regular cadence.
### Added
- Electra EIP6110: Queue deposit [pr](https://github.com/prysmaticlabs/prysm/pull/14430)
- enable SSZ for builder API calls. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14976)
- Add Hoodi testnet flag `--hoodi` to specify Hoodi testnet config and bootnodes. [[PR]](https://github.com/prysmaticlabs/prysm/pull/15057)
- block_gossip topic support to the beacon api event stream. [[PR]](https://github.com/prysmaticlabs/prysm/pull/15038)
- Added a static analyzer to discourage use of panic() in Prysm. [[PR]](https://github.com/prysmaticlabs/prysm/pull/15075)
- Add a feature flag `--blacklist-roots` to allow the node to specify blocks that will be treated as invalid. [[PR]](https://github.com/prysmaticlabs/prysm/pull/15030)
### Changed
- changed request object for `POST /eth/v1/beacon/states/head/validators` to omit the field if empty for satisfying other clients. [[PR]](https://github.com/prysmaticlabs/prysm/pull/15031)
- Update spec test to v1.5.0-beta.3. [[PR]](https://github.com/prysmaticlabs/prysm/pull/15050)
- Update Gossip and RPC message limits to comply with the spec. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14799)
- Return 404 instead of 500 from API when when a blob for a requested index is not found. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14845)
- Save Electra orphaned attestations into attestations pool's block attestations. [[PR]](https://github.com/prysmaticlabs/prysm/pull/15060)
- Removed redundant string conversion in `BeaconDbStater.State` to improve code clarity and maintainability. [[PR]](https://github.com/prysmaticlabs/prysm/pull/15081)
### Fixed
- Update seen unaggregated att cache to properly handle Electra attestations. [[PR]](https://github.com/prysmaticlabs/prysm/pull/15034)
- cosmetic fix for calling `/prysm/validators/performance` when connecting to non prysm beacon nodes and removing the 404 error log. [[PR]](https://github.com/prysmaticlabs/prysm/pull/15062)
- Tracked validator cache: Make sure no to loose the reference. [[PR]](https://github.com/prysmaticlabs/prysm/pull/15077)
- Fixed proposing at genesis when starting post Bellatrix. [[PR]](https://github.com/prysmaticlabs/prysm/pull/15084)
## [v5.3.1](https://github.com/prysmaticlabs/prysm/compare/v5.3.0...v5.3.1) - 2025-03-13
This release is packed with critical fixes for **Electra** and some important fixes for mainnet too.
The release highlights include:
- Ensure that deleting a block from the database clears its entry in the slot->root db index. This issue was causing some operators to have a bricked database, requiring a full resync. [[PR]](https://github.com/prysmaticlabs/prysm/pull/15011)
- Updated go to go1.24.0. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14969)
- Added a feature flag to sync from an arbitrary beacon block root at startup. [[PR]](https://github.com/prysmaticlabs/prysm/pull/15000)
- Updated default gas limit from 30M to 36M. Override this with `--suggested-gas-limit=` in the validator client. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14858)
Known issues in **Electra**:
- Duplicate attestations are needlessly processed. This is being addressed in [[PR]](https://github.com/prysmaticlabs/prysm/pull/15034).
Testnet operators are strongly encouraged to update to this release. There are many fixes and improvements from the Holesky upgrade incident.
Mainnet operators are recommended to update to this release at their regular cadence.
### Added
- enable E2E for minimal and mainnet tests. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14842)
- enable web3signer E2E for electra. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14936)
- Enable multiclient E2E for electra. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14946)
- Enable Scenario E2E tests with electra. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14946)
- Add endpoint for getting pending deposits. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14941)
- Add request hash to header for builder: executable data to block. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14955)
- Log execution requests in each block. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14956)
- Add endpoint for getting pending partial withdrawals. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14949)
- Tracked validators cache: Added the `ItemCount` method. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14957)
- Tracked validators cache: Added the `Indices` method. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14957)
- Added deposit request testing for electra. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14964)
- Added support for otel tracing transport in HTTP clients in Prysm. This allows for tracing headers to be sent with http requests such that spans between the validator and beacon chain can be connected in the tracing graph. This change does nothing without `--enable-tracing`. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14972)
- Add SSZ support to light client finality and optimistic APIs. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14836)
- add log to committee index when committeebits are not the expected length of 1. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14993)
- Add acceptable address types for static peers. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14886)
- Added a feature flag to sync from an arbitrary beacon block root at startup. [[PR]](https://github.com/prysmaticlabs/prysm/pull/15000)
### Changed
- updates geth to 1.15.0. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14842)
- Updates blst to v3.14.0 and fixes the references in our deps.bzl file. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14921)
- Updated tracing exporter from jaeger to otelhttp. This should not be a breaking change. Jaeger supports otel format, however you may need to update your URL as the default otel-collector port is 4318. See the [OpenTelemtry Protocol Exporter docs](https://opentelemetry.io/docs/specs/otel/protocol/exporter/) for more details. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14928)
- Don't use MaxCover for Electra on-chain attestations. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14925)
- Tracked validators cache: Remove validators from the cache if not seen after 1 hour. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14957)
- execution requests errors on ssz length have been improved. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14962)
- deprecate beacon api endpoints based on [3.0.0 release](https://github.com/ethereum/beacon-APIs/pull/506) for electra. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14967)
- Use go-cmp for printing better diffs for assertions.DeepEqual. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14978)
- Reorganized beacon chain flags in `--help` text into logical sections. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14959)
- `--validators-registration-batch-size`: Change default value from `0` to `200`. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14981)
- Updated go to go1.24.0. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14969)
- Updated gosec to v2.22.1 and golangci to v1.64.5. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14969)
- Updated github.com/trailofbits/go-mutexasserts. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14969)
- Updated rules_go to cf3c3af34bd869b864f5f2b98e2f41c2b220d6c9 to support go1.24.0. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14969)
- Validate blob sidecar re-order signature and bad parent block. [[PR]](https://github.com/prysmaticlabs/prysm/pull/15013)
- Updated default gas limit from 30M to 36M. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14858)
- Ignore errors from `hasSeenBit` and don't pack unaggregated attestations. [[PR]](https://github.com/prysmaticlabs/prysm/pull/15018)
### Removed
- Remove Fulu state and block. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14905)
- Removed the log summarizing all started services. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14958)
### Fixed
- fixed max and target blob per block from static to dynamic values. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14911)
- refactored publish block and block ssz functions to fix gocognit. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14913)
- refactored publish blinded block and blinded block ssz to correctly deal with version headers and sent blocks. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14913)
- Only check for electra related engine methods if electra is active. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14924)
- Fixed bug that breaks new blob storage layout code on Windows, caused by accidental use of platform-dependent path parsing package. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14931)
- Fix E2E Process Deposit Evaluator for Electra. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14933)
- Fixed the `bazel run //:gazelle` command in `DEPENDENCIES.md`. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14934)
- Fix E2E Deposit Activation Evaluator for Electra. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14938)
- Dedicated processing of `SingleAttestation` in the monitor service. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14965)
- adding in content type and accept headers for builder API call on registration. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14961)
- fixed gocognit in block conversions between json and proto types. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14953)
- Lint: Fix violations of S1009: should omit nil check; len() for nil slices is defined as zero. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14973)
- Lint: Fix violations of non-constant format string in call. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14974)
- Fixed violations of gosec G301. This is a check that created files and directories have file permissions 0750 and 0600 respectively. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14980)
- Check for the correct attester slashing type during gossip validation. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14985)
- cosmetic fix for post electra validator logs displaying attestation committee information correctly. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14992)
- fix inserting the wrong committee index into the seen cache for electra attestations. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14998)
- Allow any block type to be unmarshaled rather than only phase0 blocks in `slotByBlockRoot`. [[PR]](https://github.com/prysmaticlabs/prysm/pull/15008)
- Fixed pruner to not block while pruning large database by introducing batchSize. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14929)
- Decompose Electra block attestations to prevent redundant packing. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14896)
- Fixed use of deprecated rand.Seed. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14969)
- Fixed build issue with SszGen where the go binary was not present in the $PATH. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14969)
- fixed /eth/v1/config/spec displays BLOB_SIDECAR_SUBNET_COUNT,BLOB_SIDECAR_SUBNET_COUNT_ELECTRA. [[PR]](https://github.com/prysmaticlabs/prysm/pull/15016)
- Ensure that deleting a block from the database clears its entry in the slot->root db index. [[PR]](https://github.com/prysmaticlabs/prysm/pull/15011)
- Broadcasting BLS to execution changes should not use the request context in a go routine. Use context.Background() for the broadcasting go routine. [[PR]](https://github.com/prysmaticlabs/prysm/pull/15019)
- /eth/v1/validator/sync_committee_contribution should check for optimistic status and return a 503 if it's optimistic. [[PR]](https://github.com/prysmaticlabs/prysm/pull/15022)
- Fixes printing superfluous response.WriteHeader call from error in builder. [[PR]](https://github.com/prysmaticlabs/prysm/pull/15025)
- Fixes e2e run with builder having wrong gaslimit header due to not being set on eth1 nodes. [[PR]](https://github.com/prysmaticlabs/prysm/pull/15025)
- Fixed a bug in the event stream handler when processing payload attribute events where the timestamp and slot of the event would be based on the head rather than the current slot. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14963)
- Handle unaggregated attestations when decomposing Electra block attestations. [[PR]](https://github.com/prysmaticlabs/prysm/pull/15027)
## [v5.3.0](https://github.com/prysmaticlabs/prysm/compare/v5.2.0...v5.3.0) - 2025-02-12
This release includes support for Pectra activation in the [Holesky](https://github.com/eth-clients/holesky) and [Sepolia](https://github.com/eth-clients/sepolia) testnets! The release contains many fixes for Electra that have been found in rigorous testing through devnets in the last few months.
For mainnet, we have a few nice features for you to try:
- [PR #14023](https://github.com/prysmaticlabs/prysm/pull/14023) introduces a new file layout structure for storing blobs. Rather than storing all blob root directories in one parent directory, blob root directories are organized in subdirectories by epoch. This should vastly decrease the blob cache warmup time when Prysm is starting. Try this feature with `--blob-storage-layout=by-epoch`.
Updating to this release is **required** for Holesky and Sepolia operators and it is **recommended** for mainnet users as there are a few bug fixes that apply to deneb logic.
### Added
- Added an error field to log `Finished building block`. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14696)
- Implemented a new `EmptyExecutionPayloadHeader` function. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14713)
- Added proper gas limit check for header from the builder. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14707)
- `Finished building block`: Display error only if not nil. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14722)
- Added light client feature flag check to RPC handlers. [PR](https://github.com/prysmaticlabs/prysm/pull/14736). [[PR]](https://github.com/prysmaticlabs/prysm/pull/14782)
- Added support to update target and max blob count to different values per hard fork config. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14678)
- Log before blob filesystem cache warm-up. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14735)
- New design for the attestation pool. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14324)
- Add field param placeholder for Electra blob target and max to pass spec tests. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14733)
- Light client: Add better error handling. [PR](https://github.com/prysmaticlabs/prysm/pull/14749). [[PR]](https://github.com/prysmaticlabs/prysm/pull/14782)
- Add EIP-7691: Blob throughput increase. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14750)
- Trace IDONTWANT Messages in Pubsub. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14778)
- Add Fulu fork boilerplate. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14771)
- DB optimization for saving light client bootstraps (save unique sync committees only). [[PR]](https://github.com/prysmaticlabs/prysm/pull/14782)
- Separate type for unaggregated network attestations. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14659)
- Remote signer electra fork support. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14477)
- Add Electra test case to rewards API. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14816)
- Update `proto_test.go` to Electra. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14817)
- Update slasher service to Electra. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14812)
- Builder API endpoint to support Electra. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14344)
- Added protoc toolchains with a version of v25.3. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14818)
- Add test cases for the eth_lightclient_bootstrap API SSZ support. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14824)
- Handle `AttesterSlashingElectra` everywhere in the codebase. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14823)
- Add Beacon DB pruning service to prune historical data older than MIN_EPOCHS_FOR_BLOCK_REQUESTS (roughly equivalent to the weak subjectivity period). [[PR]](https://github.com/prysmaticlabs/prysm/pull/14687)
- Nil consolidation request check for core processing. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14851)
- Updated blob sidecar api endpoint for Electra. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14852)
- Slashing pool service to convert slashings from Phase0 to Electra at the fork. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14844)
- check to stop eth1 voting after electra and eth1 deposits stop. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14835)
- WARN log message on node startup advising of the upcoming deprecation of the --enable-historical-state-representation feature flag. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14856)
- Beacon API event support for `SingleAttestation` and `SignedAggregateAttestationAndProofElectra`. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14855)
- Added Electra tests for `TestLightClient_NewLightClientOptimisticUpdateFromBeaconState` and `TestLightClient_NewLightClientFinalityUpdateFromBeaconState`. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14783)
- New option to select an alternate blob storage layout. Rather than a flat directory with a subdir for each block root, a multi-level scheme is used to organize blobs by epoch/slot/root, enabling leaner syscalls, indexing and pruning. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14023)
- Send pending att queue's attestations through the notification feed. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14862)
- Prune all pending deposits and proofs in post-Electra. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14829)
- Add Pectra testnet dates. (Sepolia and Holesky). [[PR]](https://github.com/prysmaticlabs/prysm/pull/14884)
### Changed
- Process light client finality updates only for new finalized epochs instead of doing it for every block. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14713)
- Refactor subnets subscriptions. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14711)
- Refactor RPC handlers subscriptions. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14732)
- Go deps upgrade, from `ioutil` to `io`. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14737)
- Move successfully registered validator(s) on builder log to debug. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14735)
- Update some test files to use `crypto/rand` instead of `math/rand`. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14747)
- Re-organize the content of the `*.proto` files (No functional change). [[PR]](https://github.com/prysmaticlabs/prysm/pull/14755)
- SSZ files generation: Remove the `// Hash: ...` header.[[PR]](https://github.com/prysmaticlabs/prysm/pull/14760)
- Updated Electra spec definition for `process_epoch`. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14768)
- Update our `go-libp2p-pubsub` dependency. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14770)
- Re-organize the content of files to ease the creation of a new fork boilerplate. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14761)
- Updated spec definition electra `process_registry_updates`. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14767)
- Fixed Metadata errors for peers connected via QUIC. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14776)
- Updated spec definitions for `process_slashings` in godocs. Simplified `ProcessSlashings` API. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14766)
- Update spec tests to v1.5.0-beta.0. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14788)
- Process light client finality updates only for new finalized epochs instead of doing it for every block. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14718)
- Update blobs by rpc topics from V2 to V1. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14785)
- Updated geth to 1.14~. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14351)
- E2e tests start from bellatrix. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14351)
- Version pinning unclog after making some ux improvements. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14802)
- Remove helpers to check for execution/compounding withdrawal credentials and expose them as methods. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14808)
- Refactor `2006-01-02 15:04:05` to `time.DateTime`. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14792)
- Updated Prysm to Go v1.23.5. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14818)
- Updated Bazel version to v7.4.1. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14818)
- Updated rules_go to v0.46.0. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14818)
- Updated golang.org/x/tools to be compatible with v1.23.5. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14818)
- CI now requires proto files to be properly formatted with clang-format. [[PR](https://github.com/prysmaticlabs/prysm/pull/14831)]. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14831)
- Improved test coverage of beacon-chain/core/electra/churn.go. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14837)
- Update electra spec test to beta1. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14841)
- Move deposit request nil check to apply all. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14849)
- Do not mark blocks as invalid on context deadlines during state transition. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14838)
- Update electra core processing to not mark block bad if execution request error. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14826)
- Dependency: Updated go-ethereum to v1.14.13. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14872)
- improving readability on proposer settings loader. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14868)
- Removes existing validator.processSlot span and adds validator.processSlot span to slotCtx. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14874)
- DownloadFinalizedData has moved from the api/client package to beacon-chain/sync/checkpoint. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14871)
- Updated Blob-Batch-Limit to increase to 192 for electra. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14883)
- Updated Blob-Batch-Limit-Burst-Factor to increase to 3. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14883)
- Changed the derived batch limit when serving blobs. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14883)
- Updated go-libp2p-pubsub to v0.13.0. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14890)
- Rename light client flag from `enable-lightclient` to `enable-light-client`. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14887)
- Update electra spec test to beta2. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14901)
### Removed
- Cleanup ProcessSlashings method to remove unnecessary argument. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14762)
- Remove `/proto/eth/v2` directory. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14765)
- Remove `/memsize/` pprof endpoint as it will no longer be supported in go 1.23. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14351)
- Clean `TestCanUpgrade*` tests. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14791)
- Remove `Copy()` from the `ReadOnlyBeaconBlock` interface. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14811)
- Removed a tracing span on signature requests. These requests usually took less than 5 nanoseconds and are generally not worth tracing. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14864)
### Fixed
- Added check to prevent nil pointer deference or out of bounds array access when validating the BLSToExecutionChange on an impossibly nil validator. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14705)
- EIP-7691: Ensure new blobs subnets are subscribed on epoch in advance. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14759)
- Fix kzg commitment inclusion proof depth minimal value. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14787)
- Replace exampleIP to `96.7.129.13`. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14795)
- Fixed a p2p test to reliably return a static IP through DNS resolution. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14800)
- `ToBlinded`: Use Fulu struct for Fulu (instead of Electra). [[PR]](https://github.com/prysmaticlabs/prysm/pull/14797)
- fix panic with type cast on pbgenericblock(). [[PR]](https://github.com/prysmaticlabs/prysm/pull/14801)
- Prysmctl generate genesis state: fix truncation of ExtraData to 32 bytes to satisfy SSZ marshaling. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14803)
- added conditional evaluators to fix scenario e2e tests. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14798)
- Use `SingleAttestation` for Fulu in p2p attestation map. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14809)
- `UpgradeToFulu`: Respect the specification. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14821)
- `nodeFilter`: Implement `filterPeerForBlobSubnet` to avoid error logs. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14822)
- Fixed deposit packing for post-Electra: early return if EIP-6110 is applied. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14697)
- Fix batch process new pending deposits by getting validators from state. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14827)
- Fix handling unfound block at slot. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14852)
- Fixed incorrect attester slashing length check. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14833)
- Fix monitor service for Electra. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14853)
- add more nil checks on ToConsensus functions for added safety. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14867)
- Fix electra state to safe share references on pending fields when append. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14895)
- Add missing config values from the spec. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14903)
- We remove the unused `rebuildTrie` assignments for fields which do not use them. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14906)
- fix block api endpoint to handle blocks with the same structure but on different forks (i.e. fulu and electra). [[PR]](https://github.com/prysmaticlabs/prysm/pull/14897)
- We change how we track blob indexes during their reconstruction from the EL to prevent. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14909)
- We now use the correct maximum value when serving blobs for electra blocks. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14910)
### Security
- go version upgrade to 1.22.10 for CVE CVE-2024-34156. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14729)
- Update golang.org/x/crypto to v0.31.0 to address CVE-2024-45337. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14777)
- Update golang.org/x/net to v0.33.0 to address CVE-2024-45338. [[PR]](https://github.com/prysmaticlabs/prysm/pull/14780)
## [v5.2.0](https://github.com/prysmaticlabs/prysm/compare/v5.1.2...v5.2.0)
Updating to this release is highly recommended, especially for users running v5.1.1 or v5.1.2.
This release is **mandatory** for all validator clients using mev-boost with a gas limit increase.
Without upgrading to this release, validator clients will default to using local execution blocks
when the gas limit starts to increase.
This release has several fixes and new features. In this release, we have enabled QUIC protocol by
default, which uses port 13000 for `--p2p-quic-port`. This may be a [breaking change](https://github.com/prysmaticlabs/prysm/pull/14688#issuecomment-2516713826)
if you're using port 13000 already. This release has some improvements for raising the gas limit,
but there are [known issues](https://hackmd.io/@ttsao/prysm-gas-limit) with the proposer settings
file provided gas limit not being respected for mev-boost outsourced blocks. Signalling an increase
for the gas limit works perfectly for local block production as of this release. See [pumpthegas.org](https://pumpthegas.org) for more info on raising the gas limit on L1.
Notable features:
- Prysm can reuse blobs from the EL via engine_getBlobsV1, [potentially saving bandwidth](https://hackmd.io/@ttsao/get-blobs-early-results).
- QUIC is enabled by default. This is a UDP based networking protocol with default port 13000.
### Added
- Electra EIP6110: Queue deposit [pr](https://github.com/prysmaticlabs/prysm/pull/14430).
- Add Bellatrix tests for light client functions.
- Add Discovery Rebooter Feature.
- Added GetBlockAttestationsV2 endpoint.
- Light client support: Consensus types for Electra
- Light client support: Consensus types for Electra.
- Added SubmitPoolAttesterSlashingV2 endpoint.
- Added SubmitAggregateAndProofsRequestV2 endpoint.
- Updated the `beacon-chain/monitor` package to Electra. [PR](https://github.com/prysmaticlabs/prysm/pull/14562)
- Added ListAttestationsV2 endpoint.
- Add ability to rollback node's internal state during processing.
- Change how unsafe protobuf state is created to prevent unnecessary copies.
- Added benchmarks for process slots for Capella, Deneb, Electra.
- Add helper to cast bytes to string without allocating memory.
- Added GetAggregatedAttestationV2 endpoint.
- Added SubmitAttestationsV2 endpoint.
- Validator REST mode Electra block support.
- Added validator index label to `validator_statuses` metric.
- Added Validator REST mode use of Attestation V2 endpoints and Electra attestations.
- PeerDAS: Added proto for `DataColumnIdentifier`, `DataColumnSidecar`, `DataColumnSidecarsByRangeRequest` and `MetadataV2`.
- Better attestation packing for Electra. [PR](https://github.com/prysmaticlabs/prysm/pull/14534)
- P2P: Add logs when a peer is (dis)connected. Add the reason of the disconnection when we initiate it.
- Added a Prometheus error counter metric for HTTP requests to track beacon node requests.
- Added a Prometheus error counter metric for SSE requests.
- Save light client updates and bootstraps in DB.
- Added more comprehensive tests for `BlockToLightClientHeader`. [PR](https://github.com/prysmaticlabs/prysm/pull/14699)
- Added light client feature flag check to RPC handlers. [PR](https://github.com/prysmaticlabs/prysm/pull/14736)
- Light client: Add better error handling. [PR](https://github.com/prysmaticlabs/prysm/pull/14749)
### Changed
@@ -25,28 +328,88 @@ The format is based on Keep a Changelog, and this project adheres to Semantic Ve
- Updated the default `scrape-interval` in `Client-stats` to 2 minutes to accommodate Beaconcha.in API rate limits.
- Switch to compounding when consolidating with source==target.
- Revert block db save when saving state fails.
- Return false from HasBlock if the block is being synced.
- Return false from HasBlock if the block is being synced.
- Cleanup forkchoice on failed insertions.
- Use read only validator for core processing to avoid unnecessary copying.
- Use ROBlock across block processing pipeline.
- Added missing Eth-Consensus-Version headers to GetBlockAttestationsV2 and GetAttesterSlashingsV2 endpoints.
- When instantiating new validators, explicit set `Slashed` to false and move `EffectiveBalance` to match struct definition.
- Updated pgo profile for beacon chain with holesky data. This improves the profile guided
optimizations in the go compiler.
- Use read only state when computing the active validator list.
- Simplified `ExitedValidatorIndices`.
- Simplified `EjectedValidatorIndices`.
- `engine_newPayloadV4`,`engine_getPayloadV4` are changes due to new execution request serialization decisions, [PR](https://github.com/prysmaticlabs/prysm/pull/14580)
- Fixed various small things in state-native code.
- Use ROBlock earlier in block syncing pipeline.
- Changed the signature of `ProcessPayload`.
- Only Build the Protobuf state once during serialization.
- Capella blocks are execution.
- Fixed panic when http request to subscribe to event stream fails.
- Return early for blob reconstructor during capella fork.
- Updated block endpoint from V1 to V2.
- Rename instances of "deposit receipts" to "deposit requests".
- Non-blocking payload attribute event handling in beacon api [pr](https://github.com/prysmaticlabs/prysm/pull/14644).
- Updated light client protobufs. [PR](https://github.com/prysmaticlabs/prysm/pull/14650)
- Added `Eth-Consensus-Version` header to `ListAttestationsV2` and `GetAggregateAttestationV2` endpoints.
- Updated light client consensus types. [PR](https://github.com/prysmaticlabs/prysm/pull/14652)
- Update earliest exit epoch for upgrade to electra
- Add missed exit checks to consolidation processing
- Fixed pending deposits processing on Electra.
- Modified `ListAttestationsV2`, `GetAttesterSlashingsV2` and `GetAggregateAttestationV2` endpoints to use slot to determine fork version.
- Improvements to HTTP response handling. [pr](https://github.com/prysmaticlabs/prysm/pull/14673)
- Updated `Blobs` endpoint to return additional metadata fields.
- Made QUIC the default method to connect with peers.
- Check kzg commitments align with blobs and proofs for beacon api end point.
- Revert "Proposer checks gas limit before accepting builder's bid".
- Updated quic-go to v0.48.2 .
### Deprecated
- `/eth/v1alpha1/validator/activation/stream` grpc wait for activation stream is deprecated. [pr](https://github.com/prysmaticlabs/prysm/pull/14514)
- `--interop-genesis-time` and `--interop-num-validators` have been deprecated in the beacon node as the functionality has been removed. These flags have no effect.
### Removed
- Removed finalized validator index cache, no longer needed.
- Removed validator queue position log on key reload and wait for activation.
- Removed outdated spectest exclusions for EIP-6110.
- Removed support for starting a beacon node with a deterministic interop genesis state via interop flags. Alternatively, create a genesis state with prysmctl and use `--genesis-state`. This removes about 9Mb (~11%) of unnecessary code and dependencies from the final production binary.
- Removed kzg proof check from blob reconstructor.
### Fixed
- Fixed mesh size by appending `gParams.Dhi = gossipSubDhi`
- Fix skipping partial withdrawals count.
- wait for the async StreamEvent writer to exit before leaving the http handler, avoiding race condition panics [pr](https://github.com/prysmaticlabs/prysm/pull/14557)
- Certain deb files were returning a 404 which made building new docker images without an existing
cache impossible. This has been fixed with updates to rules_oci and bazel-lib.
- Fixed an issue where the length check between block body KZG commitments and the existing cache from the database was incompatible.
- Fix `--backfill-oldest-slot` handling - this flag was totally broken, the code would always backfill to the default slot [pr](https://github.com/prysmaticlabs/prysm/pull/14584)
- Fix keymanager API should return corrected error format for malformed tokens
- Fix keymanager API so that get keys returns an empty response instead of a 500 error when using an unsupported keystore.
- Small log improvement, removing some redundant or duplicate logs
- EIP7521 - Fixes withdrawal bug by accounting for pending partial withdrawals and deducting already withdrawn amounts from the sweep balance. [PR](https://github.com/prysmaticlabs/prysm/pull/14578)
- unskip electra merkle spec test
- Fix panic in validator REST mode when checking status after removing all keys
- Fix panic on attestation interface since we call data before validation
- corrects nil check on some interface attestation types
- temporary solution to handling electra attesation and attester_slashing events. [pr](14655)
- Diverse log improvements and comment additions.
- Validate that each committee bitfield in an aggregate contains at least one non-zero bit
- P2P: Avoid infinite loop when looking for peers in small networks.
- Fixed another rollback bug due to a context deadline.
- Fix checkpoint sync bug on holesky. [pr](https://github.com/prysmaticlabs/prysm/pull/14689)
- Fix proposer boost spec tests being flakey by adjusting start time from 3 to 2s into slot.
- Fix segmentation fault in E2E when light-client feature flag is enabled. [PR](https://github.com/prysmaticlabs/prysm/pull/14699)
- Fix `searchForPeers` infinite loop in small networks.
- Fix slashing pool behavior to enforce MaxAttesterSlashings limit in Electra version.
### Security
## [v5.1.2](https://github.com/prysmaticlabs/prysm/compare/v5.1.1...v5.1.2) - 2024-10-16
## [v5.1.2](https://github.com/prysmaticlabs/prysm/compare/v5.1.1...v5.1.2) - 2024-10-16
This is a hotfix release with one change.
This is a hotfix release with one change.
Prysm v5.1.1 contains an updated implementation of the beacon api streaming events endpoint. This
new implementation contains a bug that can cause a panic in certain conditions. The issue is
@@ -55,23 +418,23 @@ meantime we are issuing a patch that recovers from the panic to prevent the node
This only impacts the v5.1.1 release beacon api event stream endpoints. This endpoint is used by the
prysm REST mode validator (a feature which requires the validator to be configured to use the beacon
api intead of prysm's stock grpc endpoints) or accessory software that connects to the events api,
api instead of prysm's stock grpc endpoints) or accessory software that connects to the events api,
like https://github.com/ethpandaops/ethereum-metrics-exporter
### Fixed
### Fixed
- Recover from panics when writing the event stream [#14545](https://github.com/prysmaticlabs/prysm/pull/14545)
## [v5.1.1](https://github.com/prysmaticlabs/prysm/compare/v5.1.0...v5.1.1) - 2024-10-15
This release has a number of features and improvements. Most notably, the feature flag
`--enable-experimental-state` has been flipped to "opt out" via `--disable-experimental-state`.
This release has a number of features and improvements. Most notably, the feature flag
`--enable-experimental-state` has been flipped to "opt out" via `--disable-experimental-state`.
The experimental state management design has shown significant improvements in memory usage at
runtime. Updates to libp2p's gossipsub have some bandwidith stability improvements with support for
IDONTWANT control messages.
IDONTWANT control messages.
The gRPC gateway has been deprecated from Prysm in this release. If you need JSON data, consider the
standardized beacon-APIs.
standardized beacon-APIs.
Updating to this release is recommended at your convenience.
@@ -94,6 +457,7 @@ Updating to this release is recommended at your convenience.
- fastssz version bump (better error messages).
- SSE implementation that sheds stuck clients. [pr](https://github.com/prysmaticlabs/prysm/pull/14413)
- Added GetPoolAttesterSlashingsV2 endpoint.
- Use engine API get-blobs for block subscriber to reduce block import latency and potentially reduce bandwidth.
### Changed
@@ -112,7 +476,7 @@ Updating to this release is recommended at your convenience.
- `grpc-gateway-corsdomain` is renamed to http-cors-domain. The old name can still be used as an alias.
- `api-timeout` is changed from int flag to duration flag, default value updated.
- Light client support: abstracted out the light client headers with different versions.
- `ApplyToEveryValidator` has been changed to prevent misuse bugs, it takes a closure that takes a `ReadOnlyValidator` and returns a raw pointer to a `Validator`.
- `ApplyToEveryValidator` has been changed to prevent misuse bugs, it takes a closure that takes a `ReadOnlyValidator` and returns a raw pointer to a `Validator`.
- Removed gorilla mux library and replaced it with net/http updates in go 1.22.
- Clean up `ProposeBlock` for validator client to reduce cognitive scoring and enable further changes.
- Updated k8s-io/client-go to v0.30.4 and k8s-io/apimachinery to v0.30.4
@@ -123,7 +487,7 @@ Updating to this release is recommended at your convenience.
- Updated Sepolia bootnodes.
- Make committee aware packing the default by deprecating `--enable-committee-aware-packing`.
- Moved `ConvertKzgCommitmentToVersionedHash` to the `primitives` package.
- Updated correlation penalty for EIP-7251.
- Updated correlation penalty for EIP-7251.
### Deprecated
- `--disable-grpc-gateway` flag is deprecated due to grpc gateway removal.
@@ -153,6 +517,7 @@ Updating to this release is recommended at your convenience.
- Light client support: fix light client attested header execution fields' wrong version bug.
- Testing: added custom matcher for better push settings testing.
- Registered `GetDepositSnapshot` Beacon API endpoint.
- Fix rolling back of a block due to a context deadline.
### Security
@@ -296,7 +661,7 @@ Updating to this release is recommended at your earliest convenience, especially
- use time.NewTimer() to avoid possible memory leaks
- paranoid underflow protection without error handling
- Fix CommitteeAssignments to not return every validator
- Fix dependent root retrival genesis case
- Fix dependent root retrieval genesis case
- Restrict Dials From Discovery
- Always close cache warm chan to prevent blocking
- Keep only the latest value in the health channel
@@ -363,6 +728,7 @@ block profit. If you want to preserve the existing behavior, set --local-block-v
- Set default LocalBlockValueBoost to 10
- Add bid value metrics
- REST VC metrics
- `startDB`: Add log when checkpoint sync.
### Changed
@@ -447,7 +813,7 @@ block profit. If you want to preserve the existing behavior, set --local-block-v
- handle special case of batch size=1
- Always Set Inprogress Boolean In Cache
- Builder APIs: adding headers to post endpoint
- Rename mispelled variable
- Rename misspelled variable
- allow blob by root within da period
- Rewrite Pruning Implementation To Handle EIP 7045
- Set default fee recipient if tracked val fails
@@ -517,7 +883,7 @@ Known Issues
- Support beacon_committee_selections
- /eth/v1/beacon/deposit_snapshot
- Docker images now have coreutils pre-installed
- da_waited_time_milliseconds tracks total time waiting for data availablity check in ReceiveBlock
- da_waited_time_milliseconds tracks total time waiting for data availability check in ReceiveBlock
- blob_written, blob_disk_count, blob_disk_bytes new metrics for tracking blobs on disk
- Backfill supports blob backfilling
- Add mainnet deneb fork epoch config
@@ -595,34 +961,34 @@ AVX support (eg Celeron) after the Deneb fork. This is not an issue for mainnet.
- Linter: Wastedassign linter enabled to improve code quality.
- API Enhancements:
- Added payload return in Wei for /eth/v3/validator/blocks.
- Added Holesky Deneb Epoch for better epoch management.
- Added payload return in Wei for /eth/v3/validator/blocks.
- Added Holesky Deneb Epoch for better epoch management.
- Testing Enhancements:
- Clear cache in tests of core helpers to ensure test reliability.
- Added Debug State Transition Method for improved debugging.
- Backfilling test: Enabled backfill in E2E tests for more comprehensive coverage.
- Clear cache in tests of core helpers to ensure test reliability.
- Added Debug State Transition Method for improved debugging.
- Backfilling test: Enabled backfill in E2E tests for more comprehensive coverage.
- API Updates: Re-enabled jwt on keymanager API for enhanced security.
- Logging Improvements: Enhanced block by root log for better traceability.
- Validator Client Improvements:
- Added Spans to Core Validator Methods for enhanced monitoring.
- Improved readability in validator client code for better maintenance (various commits).
- Added Spans to Core Validator Methods for enhanced monitoring.
- Improved readability in validator client code for better maintenance (various commits).
### Changed
- Optimizations and Refinements:
- Lowered resource usage in certain processes for efficiency.
- Moved blob rpc validation closer to peer read for optimized processing.
- Cleaned up validate beacon block code for clarity and efficiency.
- Updated Sepolia Deneb fork epoch for alignment with network changes.
- Changed blob latency metrics to milliseconds for more precise measurement.
- Altered getLegacyDatabaseLocation message for better clarity.
- Improved wait for activation method for enhanced performance.
- Capitalized Aggregated Unaggregated Attestations Log for consistency.
- Modified HistoricalRoots usage for accuracy.
- Adjusted checking of attribute emptiness for efficiency.
- Lowered resource usage in certain processes for efficiency.
- Moved blob rpc validation closer to peer read for optimized processing.
- Cleaned up validate beacon block code for clarity and efficiency.
- Updated Sepolia Deneb fork epoch for alignment with network changes.
- Changed blob latency metrics to milliseconds for more precise measurement.
- Altered getLegacyDatabaseLocation message for better clarity.
- Improved wait for activation method for enhanced performance.
- Capitalized Aggregated Unaggregated Attestations Log for consistency.
- Modified HistoricalRoots usage for accuracy.
- Adjusted checking of attribute emptiness for efficiency.
- Database Management:
- Moved --db-backup-output-dir as a deprecated flag for database management simplification.
- Added the Ability to Defragment the Beacon State for improved database performance.
- Moved --db-backup-output-dir as a deprecated flag for database management simplification.
- Added the Ability to Defragment the Beacon State for improved database performance.
- Dependency Update: Bumped quic-go version from 0.39.3 to 0.39.4 for up-to-date dependencies.
### Removed
@@ -633,12 +999,12 @@ AVX support (eg Celeron) after the Deneb fork. This is not an issue for mainnet.
### Fixed
- Bug Fixes:
- Fixed off by one error for improved accuracy.
- Resolved small typo in error messages for clarity.
- Addressed minor issue in blsToExecChange validator for better validation.
- Corrected blobsidecar json tag for commitment inclusion proof.
- Fixed ssz post-requests content type check.
- Resolved issue with port logging in bootnode.
- Fixed off by one error for improved accuracy.
- Resolved small typo in error messages for clarity.
- Addressed minor issue in blsToExecChange validator for better validation.
- Corrected blobsidecar json tag for commitment inclusion proof.
- Fixed ssz post-requests content type check.
- Resolved issue with port logging in bootnode.
- Test Fixes: Re-enabled Slasher E2E Test for more comprehensive testing.
### Security
@@ -692,7 +1058,7 @@ and Raspberry Pi users.
- Add Goerli Deneb Fork Epoch
- Use deneb key for deneb state in saveStatesEfficientInternal
- Initialize Inactivity Scores Correctly
- Excluse DA wait time for chain processing time
- Excludes DA wait time for chain processing time
- Initialize sig cache for verification.Initializer
- Verify roblobs
- KZG Commitment inclusion proof verifier
@@ -725,7 +1091,7 @@ and Raspberry Pi users.
- Exit early if blob by root request is empty
- Request missing blobs while processing pending queue
- Check blob exists before requesting from peer
- Passing block as arugment for sidecar validation
- Passing block as argument for sidecar validation
#### Blob Management
@@ -1022,13 +1388,13 @@ _Most of the PRs here involve shifting our http endpoints to using vanilla http
- Remove no-op cancel func
- Update Terms of Service
- fix head slot in log
- DEPRECTATION: Remove exchange transition configuration call
- DEPRECATION: Remove exchange transition configuration call
- fix segmentation fork when Capella for epoch is MaxUint64
- Return Error Gracefully When Removing 4881 Flag
- Add zero length check on indices during NextSyncCommitteeIndices
- Replace Empty Slice Literals with Nil Slices
- Refactor Error String Formatting According to Go Best Practices
- Fix redundant type converstion
- Fix redundant type conversion
- docs: fix typo
- Add Clarification To Sync Committee Cache
- Fix typos
@@ -1050,7 +1416,7 @@ small set of users.
### Security
No security issues in thsi release.
No security issues in this release.
## [v4.1.0](https://github.com/prysmaticlabs/prysm/compare/v4.0.8...v4.1.0) - 2023-08-22
@@ -1065,9 +1431,9 @@ No security issues in thsi release.
now features runtime detection, automatically enabling optimized code paths if your CPU supports it.
- **Multiarch Containers Preview Available**: multiarch (:wave: arm64 support :wave:) containers will be offered for
preview at the following locations:
- Beacon Chain: [gcr.io/prylabs-dev/prysm/beacon-chain:v4.1.0](gcr.io/prylabs-dev/prysm/beacon-chain:v4.1.0)
- Validator: [gcr.io/prylabs-dev/prysm/validator:v4.1.0](gcr.io/prylabs-dev/prysm/validator:v4.1.0)
- Please note that in the next cycle, we will exclusively use these containers at the canonical URLs.
- Beacon Chain: [gcr.io/prylabs-dev/prysm/beacon-chain:v4.1.0](gcr.io/prylabs-dev/prysm/beacon-chain:v4.1.0)
- Validator: [gcr.io/prylabs-dev/prysm/validator:v4.1.0](gcr.io/prylabs-dev/prysm/validator:v4.1.0)
- Please note that in the next cycle, we will exclusively use these containers at the canonical URLs.
### Added
@@ -1566,7 +1932,7 @@ notes [here](https://hackmd.io/TtyFurRJRKuklG3n8lMO9Q). This release is **strong
Note: The released docker images are using the portable version of the blst cryptography library. The Prysm team will
release docker images with the non-portable blst library as the default image. In the meantime, you can compile docker
images with blst non-portable locally with the `--define=blst_modern=true` bazel flag, use the "-modern-" assets
attached to releases, or set environment varaible USE_PRYSM_MODERN=true when using prysm.sh.
attached to releases, or set environment variable USE_PRYSM_MODERN=true when using prysm.sh.
### Added
@@ -1915,7 +2281,7 @@ There are some known issues with this release.
- Beacon node can bootstrap from non-genesis state (i.e bellatrix state)
- Refactor bytesutil, add support for go1.20 slice to array conversions
- Add Span information for attestation record save request
- Matric addition
- Metric addition
- Identify invalid signature within batch verification
- Support for getting consensus values from beacon config
- EIP-4881: Spec implementation
@@ -1981,7 +2347,7 @@ See [flashbots/mev-boost#404](https://github.com/flashbots/mev-boost/issues/404)
- Added more histogram metrics for block arrival latency times block_arrival_latency_milliseconds
- Priority queue RetrieveByKey now uses read lock instead of write lock
- Use custom types for certain ethclient requests. Fixes an issue when using prysm on gnosis chain.
- Updted forkchoice endpoint /eth/v1/debug/forkchoice (was /eth/v1/debug/beacon/forkchoice)
- Updated forkchoice endpoint /eth/v1/debug/forkchoice (was /eth/v1/debug/beacon/forkchoice)
- Include empty fields in builder json client.
- Computing committee assignments for slots older than the oldest historical root in the beacon state is now forbidden
@@ -2213,7 +2579,7 @@ There are no security updates in this release.
removed: `GetBeaconState`, `ProduceBlock`, `ListForkChoiceHeads`, `ListBlocks`, `SubmitValidatorRegistration`, `GetBlock`, `ProposeBlock`
- API: Forkchoice method `GetForkChoice` has been removed.
- All previously deprecated feature flags have been
removed. `--enable-active-balance-cache`, `--correctly-prune-canonical-atts`, `--correctly-insert-orphaned-atts`, `--enable-next-slot-state-cache`, `--enable-batch-gossip-verification`, `--enable-get-block-optimizations`, `--enable-balance-trie-computation`, `--disable-next-slot-state-cache`, `--attestation-aggregation-strategy`, `--attestation-aggregation-force-opt-maxcover`, `--pyrmont`, `--disable-get-block-optimizations`, `--disable-proposer-atts-selection-using-max-cover`, `--disable-optimized-balance-update`, `--disable-active-balance-cache`, `--disable-balance-trie-computation`, `--disable-batch-gossip-verification`, `--disable-correctly-prune-canonical-atts`, `--disable-correctly-insert-orphaned-atts`, `--enable-native-state`, `--enable-peer-scorer`, `--enable-gossip-batch-aggregation`, `--experimental-disable-boundry-checks`
removed. `--enable-active-balance-cache`, `--correctly-prune-canonical-atts`, `--correctly-insert-orphaned-atts`, `--enable-next-slot-state-cache`, `--enable-batch-gossip-verification`, `--enable-get-block-optimizations`, `--enable-balance-trie-computation`, `--disable-next-slot-state-cache`, `--attestation-aggregation-strategy`, `--attestation-aggregation-force-opt-maxcover`, `--pyrmont`, `--disable-get-block-optimizations`, `--disable-proposer-atts-selection-using-max-cover`, `--disable-optimized-balance-update`, `--disable-active-balance-cache`, `--disable-balance-trie-computation`, `--disable-batch-gossip-verification`, `--disable-correctly-prune-canonical-atts`, `--disable-correctly-insert-orphaned-atts`, `--enable-native-state`, `--enable-peer-scorer`, `--enable-gossip-batch-aggregation`, `--experimental-disable-boundary-checks`
- Validator Web API: Removed unused ImportAccounts and DeleteAccounts rpc options
### Fixed
@@ -2429,7 +2795,7 @@ There are two known issues with this release:
- Bellatrix support. See [kiln testnet instructions](https://hackmd.io/OqIoTiQvS9KOIataIFksBQ?view)
- Weak subjectivity sync / checkpoint sync. This is an experimental feature and may have unintended side effects for
certain operators serving historical data. See
the [documentation](https://docs.prylabs.network/docs/next/prysm-usage/checkpoint-sync) for more details.
the [documentation](https://docs.prylabs.network/docs/prysm-usage/checkpoint-sync) for more details.
- A faster build of blst for beacon chain on linux amd64. Use the environment variable `USE_PRYSM_MODERN=true` with
prysm.sh, use the "modern" binary, or bazel build with `--define=blst_modern=true`.
- Vectorized sha256. This may have performance improvements with use of the new flag `--enable-vectorized-htr`.
@@ -2610,7 +2976,7 @@ notes [here](https://github.com/prysmaticlabs/prysm-web-ui/releases/tag/v1.0.0)
- Added uint64 overflow protection
- Sync committee pool returns empty slice instead of nil on cache miss
- Improved description of datadir flag
- Simplied web password requirements
- Simplified web password requirements
- Web JWT tokens no longer expire.
- Updated keymanager protos
- Watch and update jwt secret when auth token file updated on disk.
@@ -2621,7 +2987,7 @@ notes [here](https://github.com/prysmaticlabs/prysm-web-ui/releases/tag/v1.0.0)
- Refactor for weak subjectivity sync implementation
- Update naming for Atlair previous epoch attester
- Remove duplicate MerkleizeTrieLeaves method.
- Add explict error for validator flag checks on out of bound positions
- Add explicit error for validator flag checks on out of bound positions
- Simplify method to check if the beacon chain client should update the justified epoch value.
- Rename web UI performance endpoint to "summary"
- Refactor powchain service to be more functional
@@ -2647,7 +3013,7 @@ notes [here](https://github.com/prysmaticlabs/prysm-web-ui/releases/tag/v1.0.0)
Upstream go-ethereum is now used with familiar go.mod tooling.
- Removed duplicate aggergation validation p2p pipelines.
- Metrics calculation removed extra condition
- Removed superflous errors from peer scoring parameters registration
- Removed superfluous errors from peer scoring parameters registration
### Fixed
@@ -2889,4 +3255,4 @@ There are no security updates in this release.
# Older than v2.0.0
For changelog history for releases older than v2.0.0, please refer to https://github.com/prysmaticlabs/prysm/releases
For changelog history for releases older than v2.0.0, please refer to https://github.com/prysmaticlabs/prysm/releases

View File

@@ -125,11 +125,11 @@ Navigate to your fork of the repo on GitHub. On the upper left where the current
**16. Add an entry to CHANGELOG.md.**
If your change is user facing, you must include a CHANGELOG.md entry. See the [Maintaining CHANGELOG.md](#maintaining-changelogmd) section for more information.
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. 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 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. 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.
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.**
@@ -177,16 +177,10 @@ $ git push myrepo feature-in-progress-branch -f
## Maintaining CHANGELOG.md
This project follows the changelog guidelines from [keepachangelog.com](https://keepachangelog.com/en/1.1.0/).
All PRs with user facing changes should have an entry in the CHANGELOG.md file and the change should be categorized in the appropriate category within the "Unreleased" section. The categories are:
- `Added` for new features.
- `Changed` for changes in existing functionality.
- `Deprecated` for soon-to-be removed features.
- `Removed` for now removed features.
- `Fixed` for any bug fixes.
- `Security` in case of vulnerabilities. Please see the [Security Policy](SECURITY.md) for responsible disclosure before adding a change with this category.
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

View File

@@ -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 `bazel 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:

View File

@@ -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,21 +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
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
@@ -44,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.

1689
MODULE.bazel.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,7 @@
# Prysm: An Ethereum Consensus Implementation Written in Go
<h1 align="left">Prysm: An Ethereum Consensus Implementation Written in Go</h1>
<div align="left">
[![Build status](https://badge.buildkite.com/b555891daf3614bae4284dcf365b2340cefc0089839526f096.svg?branch=master)](https://buildkite.com/prysmatic-labs/prysm)
[![Go Report Card](https://goreportcard.com/badge/github.com/prysmaticlabs/prysm)](https://goreportcard.com/report/github.com/prysmaticlabs/prysm)
[![Consensus_Spec_Version 1.4.0](https://img.shields.io/badge/Consensus%20Spec%20Version-v1.4.0-blue.svg)](https://github.com/ethereum/consensus-specs/tree/v1.4.0)
@@ -7,31 +9,60 @@
[![Discord](https://user-images.githubusercontent.com/7288322/34471967-1df7808a-efbb-11e7-9088-ed0b04151291.png)](https://discord.gg/prysmaticlabs)
[![GitPOAP Badge](https://public-api.gitpoap.io/v1/repo/prysmaticlabs/prysm/badge)](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)
[![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](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)

View File

@@ -16,6 +16,34 @@ 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(
@@ -101,9 +129,9 @@ http_archive(
http_archive(
name = "aspect_bazel_lib",
sha256 = "f5ea76682b209cc0bd90d0f5a3b26d2f7a6a2885f0c5f615e72913f4805dbb0d",
strip_prefix = "bazel-lib-2.5.0",
url = "https://github.com/aspect-build/bazel-lib/releases/download/v2.5.0/bazel-lib-v2.5.0.tar.gz",
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")
@@ -132,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 = "80a98277ad1311dacd837f9b16db62887702e9f1d1c4c9f796d0121a46c8e184",
strip_prefix = "rules_go-cf3c3af34bd869b864f5f2b98e2f41c2b220d6c9",
urls = [
"https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.46.0/rules_go-v0.46.0.zip",
"https://github.com/bazelbuild/rules_go/releases/download/v0.46.0/rules_go-v0.46.0.zip",
"https://github.com/bazel-contrib/rules_go/archive/cf3c3af34bd869b864f5f2b98e2f41c2b220d6c9.tar.gz",
],
)
@@ -165,7 +193,7 @@ load("@rules_oci//oci:pull.bzl", "oci_pull")
oci_pull(
name = "linux_debian11_multiarch_base", # Debian bullseye
digest = "sha256:b82f113425c5b5c714151aaacd8039bc141821cdcd3c65202d42bdf9c43ae60b", # 2023-12-12
image = "gcr.io/distroless/cc-debian11",
image = "gcr.io/prysmaticlabs/distroless/cc-debian11",
platforms = [
"linux/amd64",
"linux/arm64/v8",
@@ -182,7 +210,7 @@ load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_depe
go_rules_dependencies()
go_register_toolchains(
go_version = "1.22.4",
go_version = "1.24.0",
nogo = "@//:nogo",
)
@@ -227,7 +255,7 @@ filegroup(
url = "https://github.com/ethereum/EIPs/archive/5480440fe51742ed23342b68cf106cefd427e39d.tar.gz",
)
consensus_spec_version = "v1.5.0-alpha.8"
consensus_spec_version = "v1.5.0-beta.4"
bls_test_version = "v0.1.1"
@@ -243,7 +271,7 @@ filegroup(
visibility = ["//visibility:public"],
)
""",
integrity = "sha256-BsGIbEyJuYrzhShGl0tHhR4lP5Qwno8R3k8a6YBR/DA=",
integrity = "sha256-QG0NUqaCvP5lKaKKwF/fmeICZVjONMlb7EE+MtYl0C0=",
url = "https://github.com/ethereum/consensus-spec-tests/releases/download/%s/general.tar.gz" % consensus_spec_version,
)
@@ -259,7 +287,7 @@ filegroup(
visibility = ["//visibility:public"],
)
""",
integrity = "sha256-DkdvhPP2KiqUOpwFXQIFDCWCwsUDIC/xhTBD+TZevm0=",
integrity = "sha256-8NQngTSSqzW/j3tOUi3r5h+94ChRbLNWTt7BOGqr4+E=",
url = "https://github.com/ethereum/consensus-spec-tests/releases/download/%s/minimal.tar.gz" % consensus_spec_version,
)
@@ -275,7 +303,7 @@ filegroup(
visibility = ["//visibility:public"],
)
""",
integrity = "sha256-vkZqV0HB8A2Uc56C1Us/p5G57iaHL+zw2No93Xt6M/4=",
integrity = "sha256-gFqxbaBnJ7dtdoj0zFbVrtlHv/bLNuWjrTHkyCAjFjI=",
url = "https://github.com/ethereum/consensus-spec-tests/releases/download/%s/mainnet.tar.gz" % consensus_spec_version,
)
@@ -290,7 +318,7 @@ filegroup(
visibility = ["//visibility:public"],
)
""",
integrity = "sha256-D/HPAW61lKqjoWwl7N0XvhdX+67dCEFAy8JxVzqBGtU=",
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,
)
@@ -337,9 +365,9 @@ filegroup(
visibility = ["//visibility:public"],
)
""",
integrity = "sha256-b7ZTT+olF+VXEJYNTV5jggNtCkt9dOejm1i2VE+zy+0=",
strip_prefix = "holesky-874c199423ccd180607320c38cbaca05d9a1573a",
url = "https://github.com/eth-clients/holesky/archive/874c199423ccd180607320c38cbaca05d9a1573a.tar.gz", # 2024-06-18
integrity = "sha256-YVFFrCmjoGZ3fXMWpsCpSsYbANy1grnqYwOLKIg2SsA=",
strip_prefix = "holesky-32a72e21c6e53c262f27d50dd540cb654517d03a",
url = "https://github.com/eth-clients/holesky/archive/32a72e21c6e53c262f27d50dd540cb654517d03a.tar.gz", # 2025-03-17
)
http_archive(
@@ -353,9 +381,25 @@ filegroup(
visibility = ["//visibility:public"],
)
""",
integrity = "sha256-cY/UgpCcYEhQf7JefD65FI8tn/A+rAvKhcm2/qiVdqY=",
strip_prefix = "sepolia-f2c219a93c4491cee3d90c18f2f8e82aed850eab",
url = "https://github.com/eth-clients/sepolia/archive/f2c219a93c4491cee3d90c18f2f8e82aed850eab.tar.gz", # 2024-09-19
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(
@@ -403,7 +447,7 @@ 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")

9
api/apiutil/BUILD.bazel Normal file
View 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
View 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())
}

View File

@@ -5,16 +5,31 @@ go_library(
srcs = [
"client.go",
"errors.go",
"json_rest_handler.go",
"options.go",
],
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",
],
)

View File

@@ -3,61 +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",
"health.go",
"log.go",
"structs.go",
"template.go",
],
importpath = "github.com/prysmaticlabs/prysm/v5/api/client/beacon",
visibility = ["//visibility:public"],
deps = [
"//api/client:go_default_library",
"//api/client/beacon/iface:go_default_library",
"//api/server:go_default_library",
"//api/server/structs:go_default_library",
"//beacon-chain/core/helpers:go_default_library",
"//beacon-chain/state:go_default_library",
"//consensus-types/interfaces: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",
"health_test.go",
],
srcs = ["client_test.go"],
embed = [":go_default_library"],
deps = [
"//api/client:go_default_library",
"//api/client/beacon/testing: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",
"@org_uber_go_mock//gomock:go_default_library",
],
)

View 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",
],
)

View 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),
}
}

View File

@@ -1,12 +1,10 @@
package grpc_api
package chain
import (
"context"
"github.com/golang/protobuf/ptypes/empty"
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v5/validator/client/iface"
"google.golang.org/grpc"
)
type grpcChainClient struct {
@@ -36,7 +34,3 @@ func (c *grpcChainClient) ValidatorPerformance(ctx context.Context, in *ethpb.Va
func (c *grpcChainClient) ValidatorParticipation(ctx context.Context, in *ethpb.GetValidatorParticipationRequest) (*ethpb.ValidatorParticipationResponse, error) {
return c.beaconChainClient.GetValidatorParticipation(ctx, in)
}
func NewGrpcChainClient(cc grpc.ClientConnInterface) iface.ChainClient {
return &grpcChainClient{ethpb.NewBeaconChainClient(cc)}
}

View File

@@ -1,4 +1,4 @@
package iface
package chain
import (
"context"
@@ -7,11 +7,11 @@ import (
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
)
type ChainClient interface {
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)
ValidatorPerformance(ctx context.Context, in *ethpb.ValidatorPerformanceRequest) (*ethpb.ValidatorPerformanceResponse, error)
ValidatorParticipation(ctx context.Context, in *ethpb.GetValidatorParticipationRequest) (*ethpb.ValidatorParticipationResponse, error)
ValidatorPerformance(context.Context, *ethpb.ValidatorPerformanceRequest) (*ethpb.ValidatorPerformanceResponse, error)
}

View File

@@ -1,30 +1,27 @@
package beacon_api
package chain
import (
"bytes"
"context"
"encoding/json"
"reflect"
"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/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"
"github.com/prysmaticlabs/prysm/v5/validator/client/iface"
)
type beaconApiChainClient struct {
fallbackClient iface.ChainClient
jsonRestHandler JsonRestHandler
stateValidatorsProvider StateValidatorsProvider
fallbackClient Client
jsonRestHandler client.JsonRestHandler
stateValidatorsProvider shared_providers.StateValidators
}
const getValidatorPerformanceEndpoint = "/prysm/validators/performance"
func (c beaconApiChainClient) headBlockHeaders(ctx context.Context) (*structs.GetBlockHeaderResponse, error) {
blockHeader := structs.GetBlockHeaderResponse{}
err := c.jsonRestHandler.Get(ctx, "/eth/v1/beacon/headers/head", &blockHeader)
@@ -152,7 +149,7 @@ func (c beaconApiChainClient) ValidatorBalances(ctx context.Context, in *ethpb.L
}
// TODO: Implement me
panic("beaconApiChainClient.ValidatorBalances is not implemented. To use a fallback client, pass a fallback client as the last argument of NewBeaconApiChainClientWithFallback.")
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 beaconApiChainClient) Validators(ctx context.Context, in *ethpb.ListValidatorsRequest) (*ethpb.Validators, error) {
@@ -316,33 +313,16 @@ func (c beaconApiChainClient) ValidatorQueue(ctx context.Context, in *empty.Empt
}
// TODO: Implement me
panic("beaconApiChainClient.ValidatorQueue is not implemented. To use a fallback client, pass a fallback client as the last argument of NewBeaconApiChainClientWithFallback.")
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 beaconApiChainClient) ValidatorPerformance(ctx context.Context, in *ethpb.ValidatorPerformanceRequest) (*ethpb.ValidatorPerformanceResponse, error) {
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, getValidatorPerformanceEndpoint, nil, bytes.NewBuffer(request), resp); err != nil {
return nil, err
if c.fallbackClient != nil {
return c.fallbackClient.ValidatorPerformance(ctx, in)
}
return &ethpb.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
// TODO: Implement me
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 (c beaconApiChainClient) ValidatorParticipation(ctx context.Context, in *ethpb.GetValidatorParticipationRequest) (*ethpb.ValidatorParticipationResponse, error) {
@@ -351,13 +331,5 @@ func (c beaconApiChainClient) ValidatorParticipation(ctx context.Context, in *et
}
// TODO: Implement me
panic("beaconApiChainClient.ValidatorParticipation is not implemented. To use a fallback client, pass a fallback client as the last argument of NewBeaconApiChainClientWithFallback.")
}
func NewBeaconApiChainClientWithFallback(jsonRestHandler JsonRestHandler, fallbackClient iface.ChainClient) iface.ChainClient {
return &beaconApiChainClient{
jsonRestHandler: jsonRestHandler,
fallbackClient: fallbackClient,
stateValidatorsProvider: beaconApiStateValidatorsProvider{jsonRestHandler: jsonRestHandler},
}
return nil, errors.New("beaconApiChainClient.ValidatorParticipation is not implemented. To use a fallback client, pass a fallback client as the last argument of NewBeaconApiChainClientWithFallback.")
}

View File

@@ -1,9 +1,7 @@
package beacon_api
package chain
import (
"bytes"
"context"
"encoding/json"
"errors"
"fmt"
"math"
@@ -11,14 +9,13 @@ import (
"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/encoding/bytesutil"
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"
"github.com/prysmaticlabs/prysm/v5/validator/client/beacon-api/mock"
"go.uber.org/mock/gomock"
"google.golang.org/protobuf/types/known/emptypb"
)
@@ -919,43 +916,3 @@ func TestGetChainHead(t *testing.T) {
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(structs.GetValidatorPerformanceRequest{
PublicKeys: [][]byte{publicKeys[0][:], publicKeys[2][:], publicKeys[1][:]},
})
require.NoError(t, err)
wantResponse := &structs.GetValidatorPerformanceResponse{}
want := &ethpb.ValidatorPerformanceResponse{}
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().Post(
gomock.Any(),
getValidatorPerformanceEndpoint,
nil,
bytes.NewBuffer(request),
wantResponse,
).Return(
nil,
)
c := beaconApiChainClient{
jsonRestHandler: jsonRestHandler,
}
got, err := c.ValidatorPerformance(ctx, &ethpb.ValidatorPerformanceRequest{
PublicKeys: [][]byte{publicKeys[0][:], publicKeys[2][:], publicKeys[1][:]},
})
require.NoError(t, err)
require.DeepEqual(t, want.PublicKeys, got.PublicKeys)
}

View File

@@ -1,276 +0,0 @@
package beacon
import (
"context"
"fmt"
"path"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/pkg/errors"
base "github.com/prysmaticlabs/prysm/v5/api/client"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/helpers"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/state"
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
"github.com/prysmaticlabs/prysm/v5/encoding/bytesutil"
"github.com/prysmaticlabs/prysm/v5/encoding/ssz/detect"
"github.com/prysmaticlabs/prysm/v5/io/file"
"github.com/prysmaticlabs/prysm/v5/runtime/version"
"github.com/prysmaticlabs/prysm/v5/time/slots"
"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.WithFields(logrus.Fields{
"name": vu.Config.ConfigName,
"fork": version.String(vu.Fork),
}).Info("Detected supported config in remote finalized state")
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("blockSlot", b.Block().Slot()).
WithField("stateSlot", s.Slot()).
WithField("stateRoot", hexutil.Encode(sr[:])).
WithField("blockRoot", 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
}

View File

@@ -11,7 +11,6 @@ import (
"regexp"
"sort"
"strconv"
"text/template"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/pkg/errors"
@@ -29,12 +28,13 @@ 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.
@@ -63,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))
}
@@ -104,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)
@@ -112,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
@@ -136,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
@@ -195,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) {
@@ -212,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")
}
@@ -228,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))
}
@@ -246,13 +231,29 @@ 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
}

View File

@@ -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",
},
}

View 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"],
)

View File

@@ -1,22 +1,25 @@
package testing
package health
import (
"context"
"reflect"
"sync"
"github.com/prysmaticlabs/prysm/v5/api/client/beacon/iface"
"go.uber.org/mock/gomock"
)
var (
_ = iface.HealthNode(&MockHealthClient{})
)
// 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
}
@@ -38,6 +41,16 @@ func (m *MockHealthClient) IsHealthy(arg0 context.Context) bool {
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
@@ -50,10 +63,3 @@ func (mr *MockHealthClientMockRecorder) IsHealthy(arg0 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsHealthy", reflect.TypeOf((*MockHealthClient)(nil).IsHealthy), arg0)
}
// NewMockHealthClient creates a new mock instance.
func NewMockHealthClient(ctrl *gomock.Controller) *MockHealthClient {
mock := &MockHealthClient{ctrl: ctrl}
mock.recorder = &MockHealthClientMockRecorder{mock}
return mock
}

View File

@@ -1,10 +1,10 @@
package iface
package health
import "context"
type HealthTracker interface {
HealthUpdates() <-chan bool
IsHealthy() bool
IsHealthy(ctx context.Context) bool
CheckHealth(ctx context.Context) bool
}

View File

@@ -1,32 +1,30 @@
package beacon
package health
import (
"context"
"sync"
"github.com/prysmaticlabs/prysm/v5/api/client/beacon/iface"
)
type NodeHealthTracker struct {
type healthTracker struct {
isHealthy *bool
healthChan chan bool
node iface.HealthNode
node HealthNode
sync.RWMutex
}
func NewNodeHealthTracker(node iface.HealthNode) *NodeHealthTracker {
return &NodeHealthTracker{
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 *NodeHealthTracker) HealthUpdates() <-chan bool {
func (n *healthTracker) HealthUpdates() <-chan bool {
return n.healthChan
}
func (n *NodeHealthTracker) IsHealthy() bool {
func (n *healthTracker) IsHealthy(_ context.Context) bool {
n.RLock()
defer n.RUnlock()
if n.isHealthy == nil {
@@ -35,7 +33,7 @@ func (n *NodeHealthTracker) IsHealthy() bool {
return *n.isHealthy
}
func (n *NodeHealthTracker) CheckHealth(ctx context.Context) bool {
func (n *healthTracker) CheckHealth(ctx context.Context) bool {
n.Lock()
defer n.Unlock()

View File

@@ -1,14 +1,17 @@
package beacon
package health
import (
"context"
"sync"
"testing"
healthTesting "github.com/prysmaticlabs/prysm/v5/api/client/beacon/testing"
"go.uber.org/mock/gomock"
)
var (
_ = HealthTracker(&MockHealthClient{})
)
func TestNodeHealth_IsHealthy(t *testing.T) {
tests := []struct {
name string
@@ -20,11 +23,11 @@ func TestNodeHealth_IsHealthy(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
n := &NodeHealthTracker{
n := &healthTracker{
isHealthy: &tt.isHealthy,
healthChan: make(chan bool, 1),
}
if got := n.IsHealthy(); got != tt.want {
if got := n.IsHealthy(context.Background()); got != tt.want {
t.Errorf("IsHealthy() = %v, want %v", got, tt.want)
}
})
@@ -47,9 +50,9 @@ func TestNodeHealth_UpdateNodeHealth(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
client := healthTesting.NewMockHealthClient(ctrl)
client := NewMockHealthClient(ctrl)
client.EXPECT().IsHealthy(gomock.Any()).Return(tt.newStatus)
n := &NodeHealthTracker{
n := &healthTracker{
isHealthy: &tt.initial,
node: client,
healthChan: make(chan bool, 1),
@@ -80,8 +83,8 @@ func TestNodeHealth_UpdateNodeHealth(t *testing.T) {
func TestNodeHealth_Concurrency(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
client := healthTesting.NewMockHealthClient(ctrl)
n := NewNodeHealthTracker(client)
client := NewMockHealthClient(ctrl)
n := NewTracker(client)
var wg sync.WaitGroup
// Number of goroutines to spawn for both reading and writing
@@ -104,7 +107,7 @@ func TestNodeHealth_Concurrency(t *testing.T) {
for i := 0; i < numGoroutines; i++ {
go func() {
defer wg.Done()
_ = n.IsHealthy() // Just read the value
_ = n.IsHealthy(context.Background()) // Just read the value
}()
}

View File

@@ -1,8 +0,0 @@
load("@prysm//tools/go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = ["health.go"],
importpath = "github.com/prysmaticlabs/prysm/v5/api/client/beacon/iface",
visibility = ["//visibility:public"],
)

View File

@@ -1,24 +1,28 @@
load("@prysm//tools/go:def.bzl", "go_library")
package(default_testonly = True)
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/testing/validator-mock",
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",
"//validator/client/iface:go_default_library",
"@org_golang_google_protobuf//types/known/emptypb:go_default_library",
"@org_uber_go_mock//gomock:go_default_library",
],

View File

@@ -7,7 +7,7 @@
//
// Package validator_mock is a generated GoMock package.
package validator_mock
package mock
import (
context "context"

View File

@@ -58,7 +58,7 @@ func (mr *MockJsonRestHandlerMockRecorder) Get(ctx, endpoint, resp any) *gomock.
// Host mocks base method.
func (m *MockJsonRestHandler) Host() string {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "HTTPHost")
ret := m.ctrl.Call(m, "Host")
ret0, _ := ret[0].(string)
return ret0
}
@@ -66,7 +66,7 @@ func (m *MockJsonRestHandler) Host() string {
// 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, "HTTPHost", reflect.TypeOf((*MockJsonRestHandler)(nil).Host))
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Host", reflect.TypeOf((*MockJsonRestHandler)(nil).Host))
}
// HttpClient mocks base method.

View File

@@ -1,5 +1,3 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: github.com/prysmaticlabs/prysm/v5/validator/client/iface (interfaces: NodeClient)
//
// Generated by this command:
//
@@ -7,13 +5,13 @@
//
// Package validator_mock is a generated GoMock package.
package validator_mock
package mock
import (
context "context"
reflect "reflect"
beacon "github.com/prysmaticlabs/prysm/v5/api/client/beacon"
"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"
@@ -58,10 +56,10 @@ func (mr *MockNodeClientMockRecorder) Genesis(arg0, arg1 any) *gomock.Call {
}
// HealthTracker mocks base method.
func (m *MockNodeClient) HealthTracker() *beacon.NodeHealthTracker {
func (m *MockNodeClient) HealthTracker() health.HealthTracker {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "HealthTracker")
ret0, _ := ret[0].(*beacon.NodeHealthTracker)
ret0, _ := ret[0].(health.HealthTracker)
return ret0
}

View File

@@ -7,14 +7,15 @@
//
// Package validator_mock is a generated GoMock package.
package validator_mock
package mock
import (
context "context"
reflect "reflect"
"github.com/prysmaticlabs/prysm/v5/api/client/beacon"
validator "github.com/prysmaticlabs/prysm/v5/consensus-types/validator"
iface "github.com/prysmaticlabs/prysm/v5/validator/client/iface"
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
gomock "go.uber.org/mock/gomock"
)
@@ -42,10 +43,10 @@ func (m *MockPrysmChainClient) EXPECT() *MockPrysmChainClientMockRecorder {
}
// ValidatorCount mocks base method.
func (m *MockPrysmChainClient) ValidatorCount(arg0 context.Context, arg1 string, arg2 []validator.Status) ([]iface.ValidatorCount, error) {
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].([]iface.ValidatorCount)
ret0, _ := ret[0].([]beacon.ValidatorCount)
ret1, _ := ret[1].(error)
return ret0, ret1
}
@@ -55,3 +56,18 @@ func (mr *MockPrysmChainClientMockRecorder) ValidatorCount(arg0, arg1, arg2 any)
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)
}

View File

@@ -7,16 +7,16 @@
//
// Package validator_mock is a generated GoMock package.
package validator_mock
package mock
import (
context "context"
reflect "reflect"
"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"
iface "github.com/prysmaticlabs/prysm/v5/validator/client/iface"
gomock "go.uber.org/mock/gomock"
emptypb "google.golang.org/protobuf/types/known/emptypb"
)
@@ -45,10 +45,10 @@ func (m *MockValidatorClient) EXPECT() *MockValidatorClientMockRecorder {
}
// AggregatedSelections mocks base method.
func (m *MockValidatorClient) AggregatedSelections(arg0 context.Context, arg1 []iface.BeaconCommitteeSelection) ([]iface.BeaconCommitteeSelection, error) {
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].([]iface.BeaconCommitteeSelection)
ret0, _ := ret[0].([]beacon.BeaconCommitteeSelection)
ret1, _ := ret[1].(error)
return ret0, ret1
}
@@ -60,10 +60,10 @@ func (mr *MockValidatorClientMockRecorder) AggregatedSelections(arg0, arg1 any)
}
// AggregatedSyncSelections mocks base method.
func (m *MockValidatorClient) AggregatedSyncSelections(arg0 context.Context, arg1 []iface.SyncCommitteeSelection) ([]iface.SyncCommitteeSelection, error) {
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].([]iface.SyncCommitteeSelection)
ret0, _ := ret[0].([]beacon.SyncCommitteeSelection)
ret1, _ := ret[1].(error)
return ret0, ret1
}
@@ -135,10 +135,10 @@ func (mr *MockValidatorClientMockRecorder) DomainData(arg0, arg1 any) *gomock.Ca
}
// Duties mocks base method.
func (m *MockValidatorClient) Duties(arg0 context.Context, arg1 *eth.DutiesRequest) (*eth.DutiesResponse, error) {
func (m *MockValidatorClient) Duties(arg0 context.Context, arg1 *eth.DutiesRequest) (*eth.ValidatorDutiesContainer, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Duties", arg0, arg1)
ret0, _ := ret[0].(*eth.DutiesResponse)
ret0, _ := ret[0].(*eth.ValidatorDutiesContainer)
ret1, _ := ret[1].(error)
return ret0, ret1
}
@@ -181,7 +181,7 @@ func (mr *MockValidatorClientMockRecorder) FeeRecipientByPubKey(arg0, arg1 any)
// Host mocks base method.
func (m *MockValidatorClient) Host() string {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "HTTPHost")
ret := m.ctrl.Call(m, "Host")
ret0, _ := ret[0].(string)
return ret0
}
@@ -189,7 +189,7 @@ func (m *MockValidatorClient) Host() string {
// 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, "HTTPHost", reflect.TypeOf((*MockValidatorClient)(nil).Host))
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Host", reflect.TypeOf((*MockValidatorClient)(nil).Host))
}
// MultipleValidatorStatus mocks base method.
@@ -238,7 +238,7 @@ func (mr *MockValidatorClientMockRecorder) ProposeAttestation(arg0, arg1 any) *g
}
// ProposeAttestationElectra mocks base method.
func (m *MockValidatorClient) ProposeAttestationElectra(arg0 context.Context, arg1 *eth.AttestationElectra) (*eth.AttestResponse, error) {
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)
@@ -412,7 +412,7 @@ func (mr *MockValidatorClientMockRecorder) SubmitValidatorRegistrations(arg0, ar
}
// SubscribeCommitteeSubnets mocks base method.
func (m *MockValidatorClient) SubscribeCommitteeSubnets(arg0 context.Context, arg1 *eth.CommitteeSubnetsSubscribeRequest, arg2 []*eth.DutiesResponse_Duty) (*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)
@@ -501,21 +501,6 @@ func (mr *MockValidatorClientMockRecorder) ValidatorStatus(arg0, arg1 any) *gomo
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 any) *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()

View 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",
],
)

View 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
}

View File

@@ -1,23 +1,22 @@
package grpc_api
package node
import (
"context"
"github.com/golang/protobuf/ptypes/empty"
"github.com/prysmaticlabs/prysm/v5/api/client/beacon"
"github.com/prysmaticlabs/prysm/v5/api/client/beacon/health"
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v5/validator/client/iface"
log "github.com/sirupsen/logrus"
"google.golang.org/grpc"
)
var (
_ = iface.NodeClient(&grpcNodeClient{})
_ = Client(&grpcNodeClient{})
)
type grpcNodeClient struct {
nodeClient ethpb.NodeClient
healthTracker *beacon.NodeHealthTracker
healthTracker health.HealthTracker
}
func (c *grpcNodeClient) SyncStatus(ctx context.Context, in *empty.Empty) (*ethpb.SyncStatus, error) {
@@ -45,12 +44,12 @@ func (c *grpcNodeClient) IsHealthy(ctx context.Context) bool {
return true
}
func (c *grpcNodeClient) HealthTracker() *beacon.NodeHealthTracker {
func (c *grpcNodeClient) HealthTracker() health.HealthTracker {
return c.healthTracker
}
func NewNodeClient(cc grpc.ClientConnInterface) iface.NodeClient {
func NewNodeClient(cc grpc.ClientConnInterface) Client {
g := &grpcNodeClient{nodeClient: ethpb.NewNodeClient(cc)}
g.healthTracker = beacon.NewNodeHealthTracker(g)
g.healthTracker = health.NewTracker(g)
return g
}

View File

@@ -1,17 +1,17 @@
package iface
package node
import (
"context"
"github.com/golang/protobuf/ptypes/empty"
"github.com/prysmaticlabs/prysm/v5/api/client/beacon"
"github.com/prysmaticlabs/prysm/v5/api/client/beacon/health"
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
)
type NodeClient interface {
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() *beacon.NodeHealthTracker
HealthTracker() health.HealthTracker
}

View File

@@ -1,4 +1,4 @@
package beacon_api
package node
import (
"context"
@@ -7,25 +7,26 @@ import (
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/golang/protobuf/ptypes/empty"
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/v5/api/client/beacon"
"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"
"github.com/prysmaticlabs/prysm/v5/validator/client/iface"
"google.golang.org/protobuf/types/known/timestamppb"
)
var (
_ = iface.NodeClient(&beaconApiNodeClient{})
_ = Client(&beaconapiNodeClient{})
)
type beaconApiNodeClient struct {
fallbackClient iface.NodeClient
jsonRestHandler JsonRestHandler
genesisProvider GenesisProvider
healthTracker *beacon.NodeHealthTracker
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) {
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
@@ -40,7 +41,7 @@ func (c *beaconApiNodeClient) SyncStatus(ctx context.Context, _ *empty.Empty) (*
}, nil
}
func (c *beaconApiNodeClient) Genesis(ctx context.Context, _ *empty.Empty) (*ethpb.Genesis, error) {
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")
@@ -79,7 +80,7 @@ func (c *beaconApiNodeClient) Genesis(ctx context.Context, _ *empty.Empty) (*eth
}, nil
}
func (c *beaconApiNodeClient) Version(ctx context.Context, _ *empty.Empty) (*ethpb.Version, error) {
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
@@ -94,29 +95,19 @@ func (c *beaconApiNodeClient) Version(ctx context.Context, _ *empty.Empty) (*eth
}, nil
}
func (c *beaconApiNodeClient) Peers(ctx context.Context, in *empty.Empty) (*ethpb.Peers, error) {
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
panic("beaconApiNodeClient.Peers is not implemented. To use a fallback client, pass a fallback client as the last argument of NewBeaconApiNodeClientWithFallback.")
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 {
func (c *beaconapiNodeClient) IsHealthy(ctx context.Context) bool {
return c.jsonRestHandler.Get(ctx, "/eth/v1/node/health", nil) == nil
}
func (c *beaconApiNodeClient) HealthTracker() *beacon.NodeHealthTracker {
func (c *beaconapiNodeClient) HealthTracker() health.HealthTracker {
return c.healthTracker
}
func NewNodeClientWithFallback(jsonRestHandler JsonRestHandler, fallbackClient iface.NodeClient) iface.NodeClient {
b := &beaconApiNodeClient{
jsonRestHandler: jsonRestHandler,
fallbackClient: fallbackClient,
genesisProvider: &beaconApiGenesisProvider{jsonRestHandler: jsonRestHandler},
}
b.healthTracker = beacon.NewNodeHealthTracker(b)
return b
}

View File

@@ -1,4 +1,4 @@
package beacon_api
package node
import (
"context"
@@ -6,10 +6,10 @@ import (
"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"
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v5/testing/assert"
"github.com/prysmaticlabs/prysm/v5/validator/client/beacon-api/mock"
"go.uber.org/mock/gomock"
"google.golang.org/protobuf/types/known/emptypb"
"google.golang.org/protobuf/types/known/timestamppb"
@@ -135,7 +135,7 @@ func TestGetGenesis(t *testing.T) {
)
}
nodeClient := &beaconApiNodeClient{
nodeClient := &beaconapiNodeClient{
genesisProvider: genesisProvider,
jsonRestHandler: jsonRestHandler,
}
@@ -213,7 +213,7 @@ func TestGetSyncStatus(t *testing.T) {
testCase.restEndpointResponse,
)
nodeClient := &beaconApiNodeClient{jsonRestHandler: jsonRestHandler}
nodeClient := &beaconapiNodeClient{jsonRestHandler: jsonRestHandler}
syncStatus, err := nodeClient.SyncStatus(ctx, &emptypb.Empty{})
if testCase.expectedResponse == nil {
@@ -277,7 +277,7 @@ func TestGetVersion(t *testing.T) {
testCase.restEndpointResponse,
)
nodeClient := &beaconApiNodeClient{jsonRestHandler: jsonRestHandler}
nodeClient := &beaconapiNodeClient{jsonRestHandler: jsonRestHandler}
version, err := nodeClient.Version(ctx, &emptypb.Empty{})
if testCase.expectedResponse == nil {

View File

@@ -3,56 +3,53 @@ 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/v5/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/event: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",
"//monitoring/tracing/trace: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",
"@com_github_sirupsen_logrus//:go_default_library",
"@org_golang_google_grpc//:go_default_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/event:go_default_library",
"//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_sirupsen_logrus//hooks/test:go_default_library",
"@org_golang_google_protobuf//types/known/emptypb:go_default_library",
"@org_uber_go_mock//gomock:go_default_library",
],
)

View 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)}
}

View File

@@ -1,4 +1,4 @@
package grpc_api
package prysm_api
import (
"context"
@@ -7,21 +7,21 @@ import (
"github.com/golang/protobuf/ptypes/empty"
"github.com/pkg/errors"
"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"
"github.com/prysmaticlabs/prysm/v5/validator/client/iface"
"google.golang.org/grpc"
)
type grpcPrysmChainClient struct {
chainClient iface.ChainClient
chainClient chain.Client
}
func (g grpcPrysmChainClient) ValidatorCount(ctx context.Context, _ string, statuses []validator.Status) ([]iface.ValidatorCount, error) {
func (g grpcPrysmChainClient) ValidatorCount(ctx context.Context, _ string, statuses []validator.Status) ([]beacon.ValidatorCount, error) {
resp, err := g.chainClient.Validators(ctx, &ethpb.ListValidatorsRequest{PageSize: 0})
if err != nil {
return nil, errors.Wrap(err, "list validators failed")
@@ -52,7 +52,7 @@ func (g grpcPrysmChainClient) ValidatorCount(ctx context.Context, _ string, stat
}
// 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)
@@ -75,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,
})
@@ -91,6 +91,6 @@ func validatorCountByStatus(validators []*ethpb.Validator, statuses []validator.
return resp, nil
}
func NewGrpcPrysmChainClient(cc grpc.ClientConnInterface) iface.PrysmChainClient {
return &grpcPrysmChainClient{chainClient: &grpcChainClient{ethpb.NewBeaconChainClient(cc)}}
func (c *grpcPrysmChainClient) ValidatorPerformance(ctx context.Context, in *ethpb.ValidatorPerformanceRequest) (*ethpb.ValidatorPerformanceResponse, error) {
return c.chainClient.ValidatorPerformance(ctx, in)
}

View File

@@ -1,21 +1,21 @@
package grpc_api
package prysm_api
import (
"context"
"testing"
"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"
mock "github.com/prysmaticlabs/prysm/v5/testing/validator-mock"
"github.com/prysmaticlabs/prysm/v5/validator/client/iface"
"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{
@@ -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,

View 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)
}

View 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 &ethpb.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
}

View File

@@ -1,15 +1,20 @@
package beacon_api
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"
"github.com/prysmaticlabs/prysm/v5/validator/client/beacon-api/mock"
"github.com/prysmaticlabs/prysm/v5/validator/client/iface"
"go.uber.org/mock/gomock"
)
@@ -23,7 +28,7 @@ func TestGetValidatorCount(t *testing.T) {
versionResponse structs.GetVersionResponse
validatorCountResponse structs.GetValidatorCountResponse
validatorCountCalled int
expectedResponse []iface.ValidatorCount
expectedResponse []beacon.ValidatorCount
expectedError string
}{
{
@@ -42,7 +47,7 @@ func TestGetValidatorCount(t *testing.T) {
},
},
validatorCountCalled: 1,
expectedResponse: []iface.ValidatorCount{
expectedResponse: []beacon.ValidatorCount{
{
Status: "active",
Count: 10,
@@ -141,8 +146,8 @@ func TestGetValidatorCount(t *testing.T) {
).Times(test.validatorCountCalled)
// Type assertion.
var client iface.PrysmChainClient = &prysmChainClient{
nodeClient: &beaconApiNodeClient{jsonRestHandler: jsonRestHandler},
var client Client = &prysmChainClient{
nodeClient: node.NewNodeClientWithFallback(jsonRestHandler, nil),
jsonRestHandler: jsonRestHandler,
}
@@ -156,5 +161,61 @@ func TestGetValidatorCount(t *testing.T) {
}
})
}
}
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 := &ethpb.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, &ethpb.ValidatorPerformanceRequest{
PublicKeys: [][]byte{publicKeys[0][:], publicKeys[2][:], publicKeys[1][:]},
})
require.NoError(t, err)
require.DeepEqual(t, want.PublicKeys, got.PublicKeys)
}

View 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",
],
)

View 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
}

View 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)
}

View 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
}

View File

@@ -1,14 +1,14 @@
package beacon_api
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"
"github.com/prysmaticlabs/prysm/v5/validator/client/beacon-api/mock"
"go.uber.org/mock/gomock"
)
@@ -36,7 +36,7 @@ func TestGetGenesis_ValidGenesis(t *testing.T) {
},
).Times(1)
genesisProvider := &beaconApiGenesisProvider{jsonRestHandler: jsonRestHandler}
genesisProvider := &genesisProvider{jsonRestHandler: jsonRestHandler}
resp, err := genesisProvider.Genesis(ctx)
assert.NoError(t, err)
require.NotNil(t, resp)
@@ -63,7 +63,7 @@ func TestGetGenesis_NilData(t *testing.T) {
structs.GetGenesisResponse{Data: nil},
).Times(1)
genesisProvider := &beaconApiGenesisProvider{jsonRestHandler: jsonRestHandler}
genesisProvider := &genesisProvider{jsonRestHandler: jsonRestHandler}
_, err := genesisProvider.Genesis(ctx)
assert.ErrorContains(t, "genesis data is nil", err)
}
@@ -92,7 +92,7 @@ func TestGetGenesis_EndpointCalledOnlyOnce(t *testing.T) {
},
).Times(1)
genesisProvider := &beaconApiGenesisProvider{jsonRestHandler: jsonRestHandler}
genesisProvider := &genesisProvider{jsonRestHandler: jsonRestHandler}
_, err := genesisProvider.Genesis(ctx)
assert.NoError(t, err)
resp, err := genesisProvider.Genesis(ctx)
@@ -133,7 +133,7 @@ func TestGetGenesis_EndpointCanBeCalledAgainAfterError(t *testing.T) {
},
).Times(1)
genesisProvider := &beaconApiGenesisProvider{jsonRestHandler: jsonRestHandler}
genesisProvider := &genesisProvider{jsonRestHandler: jsonRestHandler}
_, err := genesisProvider.Genesis(ctx)
require.ErrorContains(t, "foo", err)
resp, err := genesisProvider.Genesis(ctx)

View 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)
}

View 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}
}

View File

@@ -1,4 +1,4 @@
package beacon_api
package shared_providers
import (
"bytes"
@@ -9,21 +9,17 @@ import (
"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 StateValidatorsProvider 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 stateValidatorsProvider struct {
jsonRestHandler client.JsonRestHandler
}
type beaconApiStateValidatorsProvider struct {
jsonRestHandler JsonRestHandler
}
func (c beaconApiStateValidatorsProvider) StateValidators(
func (c stateValidatorsProvider) StateValidators(
ctx context.Context,
stringPubkeys []string,
indexes []primitives.ValidatorIndex,
@@ -33,7 +29,7 @@ func (c beaconApiStateValidatorsProvider) StateValidators(
return c.getStateValidatorsHelper(ctx, "/eth/v1/beacon/states/head/validators", append(stringIndices, stringPubkeys...), statuses)
}
func (c beaconApiStateValidatorsProvider) StateValidatorsForSlot(
func (c stateValidatorsProvider) StateValidatorsForSlot(
ctx context.Context,
slot primitives.Slot,
stringPubkeys []string,
@@ -44,7 +40,7 @@ func (c beaconApiStateValidatorsProvider) StateValidatorsForSlot(
return c.getStateValidatorsHelper(ctx, fmt.Sprintf("/eth/v1/beacon/states/%d/validators", slot), append(stringIndices, stringPubkeys...), statuses)
}
func (c beaconApiStateValidatorsProvider) StateValidatorsForHead(
func (c stateValidatorsProvider) StateValidatorsForHead(
ctx context.Context,
stringPubkeys []string,
indices []primitives.ValidatorIndex,
@@ -66,7 +62,7 @@ func convertValidatorIndicesToStrings(indices []primitives.ValidatorIndex) []str
return result
}
func (c beaconApiStateValidatorsProvider) getStateValidatorsHelper(
func (c stateValidatorsProvider) getStateValidatorsHelper(
ctx context.Context,
endpoint string,
vals []string,
@@ -112,7 +108,7 @@ func (c beaconApiStateValidatorsProvider) getStateValidatorsHelper(
queryParams.Add("status", st)
}
query := buildURL(endpoint, queryParams)
query := apiutil.BuildURL(endpoint, queryParams)
err = c.jsonRestHandler.Get(ctx, query, stateValidatorsJson)
if err != nil {

View File

@@ -1,4 +1,4 @@
package beacon_api
package shared_providers
import (
"bytes"
@@ -8,11 +8,12 @@ import (
"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"
"github.com/prysmaticlabs/prysm/v5/validator/client/beacon-api/mock"
"go.uber.org/mock/gomock"
)
@@ -84,7 +85,7 @@ func TestGetStateValidators_Nominal_POST(t *testing.T) {
},
).Times(1)
stateValidatorsProvider := beaconApiStateValidatorsProvider{jsonRestHandler: jsonRestHandler}
stateValidatorsProvider := stateValidatorsProvider{jsonRestHandler: jsonRestHandler}
actual, err := stateValidatorsProvider.StateValidators(ctx, []string{
"0x8000091c2ae64ee414a54c1cc1fc67dec663408bc636cb86756e0200e41a75c8f86603f104f02c856983d2783116be13", // active_ongoing
"0x80000e851c0f53c3246ff726d7ff7766661ca5e12a07c45c114d208d54f0f8233d4380b2e9aff759d69795d1df905526", // active_exiting
@@ -175,7 +176,7 @@ func TestGetStateValidators_Nominal_GET(t *testing.T) {
queryParams.Add("status", st)
}
query := buildURL("/eth/v1/beacon/states/head/validators", queryParams)
query := apiutil.BuildURL("/eth/v1/beacon/states/head/validators", queryParams)
jsonRestHandler.EXPECT().Get(
gomock.Any(),
@@ -190,7 +191,7 @@ func TestGetStateValidators_Nominal_GET(t *testing.T) {
},
).Times(1)
stateValidatorsProvider := beaconApiStateValidatorsProvider{jsonRestHandler: jsonRestHandler}
stateValidatorsProvider := stateValidatorsProvider{jsonRestHandler: jsonRestHandler}
actual, err := stateValidatorsProvider.StateValidators(ctx, []string{
"0x8000091c2ae64ee414a54c1cc1fc67dec663408bc636cb86756e0200e41a75c8f86603f104f02c856983d2783116be13", // active_ongoing
"0x80000e851c0f53c3246ff726d7ff7766661ca5e12a07c45c114d208d54f0f8233d4380b2e9aff759d69795d1df905526", // active_exiting
@@ -244,7 +245,7 @@ func TestGetStateValidators_GetRestJsonResponseOnError(t *testing.T) {
queryParams.Add("status", st)
}
query := buildURL("/eth/v1/beacon/states/head/validators", queryParams)
query := apiutil.BuildURL("/eth/v1/beacon/states/head/validators", queryParams)
jsonRestHandler.EXPECT().Get(
gomock.Any(),
@@ -254,7 +255,7 @@ func TestGetStateValidators_GetRestJsonResponseOnError(t *testing.T) {
errors.New("an error"),
).Times(1)
stateValidatorsProvider := beaconApiStateValidatorsProvider{jsonRestHandler: jsonRestHandler}
stateValidatorsProvider := stateValidatorsProvider{jsonRestHandler: jsonRestHandler}
_, err = stateValidatorsProvider.StateValidators(ctx, []string{
"0x8000091c2ae64ee414a54c1cc1fc67dec663408bc636cb86756e0200e41a75c8f86603f104f02c856983d2783116be13", // active_ongoing
},
@@ -293,7 +294,7 @@ func TestGetStateValidators_DataIsNil_POST(t *testing.T) {
},
).Times(1)
stateValidatorsProvider := beaconApiStateValidatorsProvider{jsonRestHandler: jsonRestHandler}
stateValidatorsProvider := stateValidatorsProvider{jsonRestHandler: jsonRestHandler}
_, err = stateValidatorsProvider.StateValidators(ctx, []string{
"0x8000091c2ae64ee414a54c1cc1fc67dec663408bc636cb86756e0200e41a75c8f86603f104f02c856983d2783116be13", // active_ongoing
},
@@ -338,7 +339,7 @@ func TestGetStateValidators_DataIsNil_GET(t *testing.T) {
queryParams.Add("status", st)
}
query := buildURL("/eth/v1/beacon/states/head/validators", queryParams)
query := apiutil.BuildURL("/eth/v1/beacon/states/head/validators", queryParams)
jsonRestHandler.EXPECT().Get(
gomock.Any(),
@@ -353,7 +354,7 @@ func TestGetStateValidators_DataIsNil_GET(t *testing.T) {
},
).Times(1)
stateValidatorsProvider := beaconApiStateValidatorsProvider{jsonRestHandler: jsonRestHandler}
stateValidatorsProvider := stateValidatorsProvider{jsonRestHandler: jsonRestHandler}
_, err = stateValidatorsProvider.StateValidators(ctx, []string{
"0x8000091c2ae64ee414a54c1cc1fc67dec663408bc636cb86756e0200e41a75c8f86603f104f02c856983d2783116be13", // active_ongoing
},

View 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
}

View 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)
}

View File

@@ -1,12 +0,0 @@
load("@prysm//tools/go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = ["mock.go"],
importpath = "github.com/prysmaticlabs/prysm/v5/api/client/beacon/testing",
visibility = ["//visibility:public"],
deps = [
"//api/client/beacon/iface:go_default_library",
"@org_uber_go_mock//gomock:go_default_library",
],
)

View File

@@ -4,30 +4,26 @@ go_library(
name = "go_default_library",
srcs = [
"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",
"beacon_committee_selections.go",
"client.go",
"domain_data.go",
"doppelganger.go",
"duties.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",
@@ -37,15 +33,20 @@ go_library(
"sync_committee.go",
"sync_committee_selections.go",
],
importpath = "github.com/prysmaticlabs/prysm/v5/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",
"//config/features:go_default_library",
"//config/params:go_default_library",
"//consensus-types/primitives:go_default_library",
"//consensus-types/validator:go_default_library",
@@ -57,7 +58,7 @@ go_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",
@@ -65,45 +66,41 @@ go_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 = [
"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",
"beacon_committee_selections_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",
@@ -112,32 +109,38 @@ go_test(
"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",
"//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",
"//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",
"//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_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",
],
)

View File

@@ -1,4 +1,4 @@
package beacon_api
package validator_api
import (
"context"
@@ -7,6 +7,7 @@ import (
"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"
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
@@ -21,7 +22,7 @@ func (c *beaconApiValidatorClient) attestationData(
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)
query := apiutil.BuildURL("/eth/v1/validator/attestation_data", params)
produceAttestationDataResponseJson := structs.GetAttestationDataResponse{}
if err := c.jsonRestHandler.Get(ctx, query, &produceAttestationDataResponseJson); err != nil {
@@ -38,7 +39,7 @@ func (c *beaconApiValidatorClient) attestationData(
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)
}
@@ -61,7 +62,7 @@ func (c *beaconApiValidatorClient) attestationData(
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)
}
@@ -79,7 +80,7 @@ func (c *beaconApiValidatorClient) attestationData(
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)
}

View File

@@ -1,4 +1,4 @@
package beacon_api
package validator_api
import (
"context"
@@ -8,11 +8,11 @@ import (
"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"
"github.com/prysmaticlabs/prysm/v5/validator/client/beacon-api/mock"
"go.uber.org/mock/gomock"
)

View File

@@ -1,12 +1,9 @@
package beacon_api
package validator_api
import (
"bytes"
"context"
"encoding/json"
"fmt"
neturl "net/url"
"regexp"
"strconv"
"github.com/pkg/errors"
@@ -27,26 +24,6 @@ var beaconAPITogRPCValidatorStatus = map[string]ethpb.ValidatorStatus{
"withdrawal_done": ethpb.ValidatorStatus_EXITED,
}
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())
}
func (c *beaconApiValidatorClient) fork(ctx context.Context) (*structs.GetStateForkResponse, error) {
const endpoint = "/eth/v1/beacon/states/head/fork"

View File

@@ -1,4 +1,4 @@
package beacon_api
package validator_api
import (
"bytes"
@@ -8,11 +8,12 @@ import (
"net/url"
"testing"
"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"
"github.com/prysmaticlabs/prysm/v5/validator/client/beacon-api/mock"
"go.uber.org/mock/gomock"
)
@@ -56,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))
})
}
}
@@ -65,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)
}
@@ -85,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)
}

View File

@@ -1,4 +1,4 @@
package beacon_api
package validator_api
import (
"math/big"

View File

@@ -1,18 +1,18 @@
package beacon_api
package validator_api
import (
"testing"
"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"
testhelpers "github.com/prysmaticlabs/prysm/v5/validator/client/beacon-api/test-helpers"
)
func TestGetBeaconBlockConverter_Phase0Valid(t *testing.T) {
expectedBeaconBlock := testhelpers.GenerateProtoPhase0BeaconBlock()
expectedBeaconBlock := test_helpers.GenerateProtoPhase0BeaconBlock()
beaconBlockConverter := &beaconApiBeaconBlockConverter{}
beaconBlock, err := beaconBlockConverter.ConvertRESTPhase0BlockToProto(testhelpers.GenerateJsonPhase0BeaconBlock())
beaconBlock, err := beaconBlockConverter.ConvertRESTPhase0BlockToProto(test_helpers.GenerateJsonPhase0BeaconBlock())
require.NoError(t, err)
assert.DeepEqual(t, expectedBeaconBlock, beaconBlock)
}
@@ -27,7 +27,7 @@ func TestGetBeaconBlockConverter_Phase0Error(t *testing.T) {
name: "nil body",
expectedErrorMessage: "block body is nil",
generateData: func() *structs.BeaconBlock {
beaconBlock := testhelpers.GenerateJsonPhase0BeaconBlock()
beaconBlock := test_helpers.GenerateJsonPhase0BeaconBlock()
beaconBlock.Body = nil
return beaconBlock
},
@@ -36,7 +36,7 @@ func TestGetBeaconBlockConverter_Phase0Error(t *testing.T) {
name: "nil eth1 data",
expectedErrorMessage: "eth1 data is nil",
generateData: func() *structs.BeaconBlock {
beaconBlock := testhelpers.GenerateJsonPhase0BeaconBlock()
beaconBlock := test_helpers.GenerateJsonPhase0BeaconBlock()
beaconBlock.Body.Eth1Data = nil
return beaconBlock
},
@@ -45,7 +45,7 @@ func TestGetBeaconBlockConverter_Phase0Error(t *testing.T) {
name: "bad slot",
expectedErrorMessage: "failed to parse slot `foo`",
generateData: func() *structs.BeaconBlock {
beaconBlock := testhelpers.GenerateJsonPhase0BeaconBlock()
beaconBlock := test_helpers.GenerateJsonPhase0BeaconBlock()
beaconBlock.Slot = "foo"
return beaconBlock
},
@@ -54,7 +54,7 @@ func TestGetBeaconBlockConverter_Phase0Error(t *testing.T) {
name: "bad proposer index",
expectedErrorMessage: "failed to parse proposer index `bar`",
generateData: func() *structs.BeaconBlock {
beaconBlock := testhelpers.GenerateJsonPhase0BeaconBlock()
beaconBlock := test_helpers.GenerateJsonPhase0BeaconBlock()
beaconBlock.ProposerIndex = "bar"
return beaconBlock
},
@@ -63,7 +63,7 @@ func TestGetBeaconBlockConverter_Phase0Error(t *testing.T) {
name: "bad parent root",
expectedErrorMessage: "failed to decode parent root `foo`",
generateData: func() *structs.BeaconBlock {
beaconBlock := testhelpers.GenerateJsonPhase0BeaconBlock()
beaconBlock := test_helpers.GenerateJsonPhase0BeaconBlock()
beaconBlock.ParentRoot = "foo"
return beaconBlock
},
@@ -72,7 +72,7 @@ func TestGetBeaconBlockConverter_Phase0Error(t *testing.T) {
name: "bad state root",
expectedErrorMessage: "failed to decode state root `bar`",
generateData: func() *structs.BeaconBlock {
beaconBlock := testhelpers.GenerateJsonPhase0BeaconBlock()
beaconBlock := test_helpers.GenerateJsonPhase0BeaconBlock()
beaconBlock.StateRoot = "bar"
return beaconBlock
},
@@ -81,7 +81,7 @@ func TestGetBeaconBlockConverter_Phase0Error(t *testing.T) {
name: "bad randao reveal",
expectedErrorMessage: "failed to decode randao reveal `foo`",
generateData: func() *structs.BeaconBlock {
beaconBlock := testhelpers.GenerateJsonPhase0BeaconBlock()
beaconBlock := test_helpers.GenerateJsonPhase0BeaconBlock()
beaconBlock.Body.RandaoReveal = "foo"
return beaconBlock
},
@@ -90,7 +90,7 @@ func TestGetBeaconBlockConverter_Phase0Error(t *testing.T) {
name: "bad deposit root",
expectedErrorMessage: "failed to decode deposit root `bar`",
generateData: func() *structs.BeaconBlock {
beaconBlock := testhelpers.GenerateJsonPhase0BeaconBlock()
beaconBlock := test_helpers.GenerateJsonPhase0BeaconBlock()
beaconBlock.Body.Eth1Data.DepositRoot = "bar"
return beaconBlock
},
@@ -99,7 +99,7 @@ func TestGetBeaconBlockConverter_Phase0Error(t *testing.T) {
name: "bad deposit count",
expectedErrorMessage: "failed to parse deposit count `foo`",
generateData: func() *structs.BeaconBlock {
beaconBlock := testhelpers.GenerateJsonPhase0BeaconBlock()
beaconBlock := test_helpers.GenerateJsonPhase0BeaconBlock()
beaconBlock.Body.Eth1Data.DepositCount = "foo"
return beaconBlock
},
@@ -108,7 +108,7 @@ func TestGetBeaconBlockConverter_Phase0Error(t *testing.T) {
name: "bad block hash",
expectedErrorMessage: "failed to decode block hash `bar`",
generateData: func() *structs.BeaconBlock {
beaconBlock := testhelpers.GenerateJsonPhase0BeaconBlock()
beaconBlock := test_helpers.GenerateJsonPhase0BeaconBlock()
beaconBlock.Body.Eth1Data.BlockHash = "bar"
return beaconBlock
},
@@ -117,7 +117,7 @@ func TestGetBeaconBlockConverter_Phase0Error(t *testing.T) {
name: "bad graffiti",
expectedErrorMessage: "failed to decode graffiti `foo`",
generateData: func() *structs.BeaconBlock {
beaconBlock := testhelpers.GenerateJsonPhase0BeaconBlock()
beaconBlock := test_helpers.GenerateJsonPhase0BeaconBlock()
beaconBlock.Body.Graffiti = "foo"
return beaconBlock
},
@@ -126,7 +126,7 @@ func TestGetBeaconBlockConverter_Phase0Error(t *testing.T) {
name: "bad proposer slashings",
expectedErrorMessage: "failed to get proposer slashings",
generateData: func() *structs.BeaconBlock {
beaconBlock := testhelpers.GenerateJsonPhase0BeaconBlock()
beaconBlock := test_helpers.GenerateJsonPhase0BeaconBlock()
beaconBlock.Body.ProposerSlashings[0] = nil
return beaconBlock
},
@@ -135,7 +135,7 @@ func TestGetBeaconBlockConverter_Phase0Error(t *testing.T) {
name: "bad attester slashings",
expectedErrorMessage: "failed to get attester slashings",
generateData: func() *structs.BeaconBlock {
beaconBlock := testhelpers.GenerateJsonPhase0BeaconBlock()
beaconBlock := test_helpers.GenerateJsonPhase0BeaconBlock()
beaconBlock.Body.AttesterSlashings[0] = nil
return beaconBlock
},
@@ -144,7 +144,7 @@ func TestGetBeaconBlockConverter_Phase0Error(t *testing.T) {
name: "bad attestations",
expectedErrorMessage: "failed to get attestations",
generateData: func() *structs.BeaconBlock {
beaconBlock := testhelpers.GenerateJsonPhase0BeaconBlock()
beaconBlock := test_helpers.GenerateJsonPhase0BeaconBlock()
beaconBlock.Body.Attestations[0] = nil
return beaconBlock
},
@@ -153,7 +153,7 @@ func TestGetBeaconBlockConverter_Phase0Error(t *testing.T) {
name: "bad deposits",
expectedErrorMessage: "failed to get deposits",
generateData: func() *structs.BeaconBlock {
beaconBlock := testhelpers.GenerateJsonPhase0BeaconBlock()
beaconBlock := test_helpers.GenerateJsonPhase0BeaconBlock()
beaconBlock.Body.Deposits[0] = nil
return beaconBlock
},
@@ -162,7 +162,7 @@ func TestGetBeaconBlockConverter_Phase0Error(t *testing.T) {
name: "bad voluntary exits",
expectedErrorMessage: "failed to get voluntary exits",
generateData: func() *structs.BeaconBlock {
beaconBlock := testhelpers.GenerateJsonPhase0BeaconBlock()
beaconBlock := test_helpers.GenerateJsonPhase0BeaconBlock()
beaconBlock.Body.VoluntaryExits[0] = nil
return beaconBlock
},
@@ -181,9 +181,9 @@ func TestGetBeaconBlockConverter_Phase0Error(t *testing.T) {
}
func TestGetBeaconBlockConverter_AltairValid(t *testing.T) {
expectedBeaconBlock := testhelpers.GenerateProtoAltairBeaconBlock()
expectedBeaconBlock := test_helpers.GenerateProtoAltairBeaconBlock()
beaconBlockConverter := &beaconApiBeaconBlockConverter{}
beaconBlock, err := beaconBlockConverter.ConvertRESTAltairBlockToProto(testhelpers.GenerateJsonAltairBeaconBlock())
beaconBlock, err := beaconBlockConverter.ConvertRESTAltairBlockToProto(test_helpers.GenerateJsonAltairBeaconBlock())
require.NoError(t, err)
assert.DeepEqual(t, expectedBeaconBlock, beaconBlock)
}
@@ -198,7 +198,7 @@ func TestGetBeaconBlockConverter_AltairError(t *testing.T) {
name: "nil body",
expectedErrorMessage: "block body is nil",
generateData: func() *structs.BeaconBlockAltair {
beaconBlock := testhelpers.GenerateJsonAltairBeaconBlock()
beaconBlock := test_helpers.GenerateJsonAltairBeaconBlock()
beaconBlock.Body = nil
return beaconBlock
},
@@ -207,7 +207,7 @@ func TestGetBeaconBlockConverter_AltairError(t *testing.T) {
name: "nil sync aggregate",
expectedErrorMessage: "sync aggregate is nil",
generateData: func() *structs.BeaconBlockAltair {
beaconBlock := testhelpers.GenerateJsonAltairBeaconBlock()
beaconBlock := test_helpers.GenerateJsonAltairBeaconBlock()
beaconBlock.Body.SyncAggregate = nil
return beaconBlock
},
@@ -216,7 +216,7 @@ func TestGetBeaconBlockConverter_AltairError(t *testing.T) {
name: "bad phase0 fields",
expectedErrorMessage: "failed to get the phase0 fields of the altair block",
generateData: func() *structs.BeaconBlockAltair {
beaconBlock := testhelpers.GenerateJsonAltairBeaconBlock()
beaconBlock := test_helpers.GenerateJsonAltairBeaconBlock()
beaconBlock.Body.Eth1Data = nil
return beaconBlock
},
@@ -225,7 +225,7 @@ func TestGetBeaconBlockConverter_AltairError(t *testing.T) {
name: "bad sync committee bits",
expectedErrorMessage: "failed to decode sync committee bits `foo`",
generateData: func() *structs.BeaconBlockAltair {
beaconBlock := testhelpers.GenerateJsonAltairBeaconBlock()
beaconBlock := test_helpers.GenerateJsonAltairBeaconBlock()
beaconBlock.Body.SyncAggregate.SyncCommitteeBits = "foo"
return beaconBlock
},
@@ -234,7 +234,7 @@ func TestGetBeaconBlockConverter_AltairError(t *testing.T) {
name: "bad sync committee signature",
expectedErrorMessage: "failed to decode sync committee signature `bar`",
generateData: func() *structs.BeaconBlockAltair {
beaconBlock := testhelpers.GenerateJsonAltairBeaconBlock()
beaconBlock := test_helpers.GenerateJsonAltairBeaconBlock()
beaconBlock.Body.SyncAggregate.SyncCommitteeSignature = "bar"
return beaconBlock
},
@@ -253,9 +253,9 @@ func TestGetBeaconBlockConverter_AltairError(t *testing.T) {
}
func TestGetBeaconBlockConverter_BellatrixValid(t *testing.T) {
expectedBeaconBlock := testhelpers.GenerateProtoBellatrixBeaconBlock()
expectedBeaconBlock := test_helpers.GenerateProtoBellatrixBeaconBlock()
beaconBlockConverter := &beaconApiBeaconBlockConverter{}
beaconBlock, err := beaconBlockConverter.ConvertRESTBellatrixBlockToProto(testhelpers.GenerateJsonBellatrixBeaconBlock())
beaconBlock, err := beaconBlockConverter.ConvertRESTBellatrixBlockToProto(test_helpers.GenerateJsonBellatrixBeaconBlock())
require.NoError(t, err)
assert.DeepEqual(t, expectedBeaconBlock, beaconBlock)
}
@@ -270,7 +270,7 @@ func TestGetBeaconBlockConverter_BellatrixError(t *testing.T) {
name: "nil body",
expectedErrorMessage: "block body is nil",
generateData: func() *structs.BeaconBlockBellatrix {
beaconBlock := testhelpers.GenerateJsonBellatrixBeaconBlock()
beaconBlock := test_helpers.GenerateJsonBellatrixBeaconBlock()
beaconBlock.Body = nil
return beaconBlock
},
@@ -279,7 +279,7 @@ func TestGetBeaconBlockConverter_BellatrixError(t *testing.T) {
name: "nil execution payload",
expectedErrorMessage: "execution payload is nil",
generateData: func() *structs.BeaconBlockBellatrix {
beaconBlock := testhelpers.GenerateJsonBellatrixBeaconBlock()
beaconBlock := test_helpers.GenerateJsonBellatrixBeaconBlock()
beaconBlock.Body.ExecutionPayload = nil
return beaconBlock
},
@@ -288,7 +288,7 @@ func TestGetBeaconBlockConverter_BellatrixError(t *testing.T) {
name: "bad altair fields",
expectedErrorMessage: "failed to get the altair fields of the bellatrix block",
generateData: func() *structs.BeaconBlockBellatrix {
beaconBlock := testhelpers.GenerateJsonBellatrixBeaconBlock()
beaconBlock := test_helpers.GenerateJsonBellatrixBeaconBlock()
beaconBlock.Body.Eth1Data = nil
return beaconBlock
},
@@ -297,7 +297,7 @@ func TestGetBeaconBlockConverter_BellatrixError(t *testing.T) {
name: "bad parent hash",
expectedErrorMessage: "failed to decode execution payload parent hash `foo`",
generateData: func() *structs.BeaconBlockBellatrix {
beaconBlock := testhelpers.GenerateJsonBellatrixBeaconBlock()
beaconBlock := test_helpers.GenerateJsonBellatrixBeaconBlock()
beaconBlock.Body.ExecutionPayload.ParentHash = "foo"
return beaconBlock
},
@@ -306,7 +306,7 @@ func TestGetBeaconBlockConverter_BellatrixError(t *testing.T) {
name: "bad fee recipient",
expectedErrorMessage: "failed to decode execution payload fee recipient `bar`",
generateData: func() *structs.BeaconBlockBellatrix {
beaconBlock := testhelpers.GenerateJsonBellatrixBeaconBlock()
beaconBlock := test_helpers.GenerateJsonBellatrixBeaconBlock()
beaconBlock.Body.ExecutionPayload.FeeRecipient = "bar"
return beaconBlock
},
@@ -315,7 +315,7 @@ func TestGetBeaconBlockConverter_BellatrixError(t *testing.T) {
name: "bad state root",
expectedErrorMessage: "failed to decode execution payload state root `foo`",
generateData: func() *structs.BeaconBlockBellatrix {
beaconBlock := testhelpers.GenerateJsonBellatrixBeaconBlock()
beaconBlock := test_helpers.GenerateJsonBellatrixBeaconBlock()
beaconBlock.Body.ExecutionPayload.StateRoot = "foo"
return beaconBlock
},
@@ -324,7 +324,7 @@ func TestGetBeaconBlockConverter_BellatrixError(t *testing.T) {
name: "bad receipts root",
expectedErrorMessage: "failed to decode execution payload receipts root `bar`",
generateData: func() *structs.BeaconBlockBellatrix {
beaconBlock := testhelpers.GenerateJsonBellatrixBeaconBlock()
beaconBlock := test_helpers.GenerateJsonBellatrixBeaconBlock()
beaconBlock.Body.ExecutionPayload.ReceiptsRoot = "bar"
return beaconBlock
},
@@ -333,7 +333,7 @@ func TestGetBeaconBlockConverter_BellatrixError(t *testing.T) {
name: "bad logs bloom",
expectedErrorMessage: "failed to decode execution payload logs bloom `foo`",
generateData: func() *structs.BeaconBlockBellatrix {
beaconBlock := testhelpers.GenerateJsonBellatrixBeaconBlock()
beaconBlock := test_helpers.GenerateJsonBellatrixBeaconBlock()
beaconBlock.Body.ExecutionPayload.LogsBloom = "foo"
return beaconBlock
},
@@ -342,7 +342,7 @@ func TestGetBeaconBlockConverter_BellatrixError(t *testing.T) {
name: "bad prev randao",
expectedErrorMessage: "failed to decode execution payload prev randao `bar`",
generateData: func() *structs.BeaconBlockBellatrix {
beaconBlock := testhelpers.GenerateJsonBellatrixBeaconBlock()
beaconBlock := test_helpers.GenerateJsonBellatrixBeaconBlock()
beaconBlock.Body.ExecutionPayload.PrevRandao = "bar"
return beaconBlock
},
@@ -351,7 +351,7 @@ func TestGetBeaconBlockConverter_BellatrixError(t *testing.T) {
name: "bad block number",
expectedErrorMessage: "failed to parse execution payload block number `foo`",
generateData: func() *structs.BeaconBlockBellatrix {
beaconBlock := testhelpers.GenerateJsonBellatrixBeaconBlock()
beaconBlock := test_helpers.GenerateJsonBellatrixBeaconBlock()
beaconBlock.Body.ExecutionPayload.BlockNumber = "foo"
return beaconBlock
},
@@ -360,7 +360,7 @@ func TestGetBeaconBlockConverter_BellatrixError(t *testing.T) {
name: "bad gas limit",
expectedErrorMessage: "failed to parse execution payload gas limit `bar`",
generateData: func() *structs.BeaconBlockBellatrix {
beaconBlock := testhelpers.GenerateJsonBellatrixBeaconBlock()
beaconBlock := test_helpers.GenerateJsonBellatrixBeaconBlock()
beaconBlock.Body.ExecutionPayload.GasLimit = "bar"
return beaconBlock
},
@@ -369,7 +369,7 @@ func TestGetBeaconBlockConverter_BellatrixError(t *testing.T) {
name: "bad gas used",
expectedErrorMessage: "failed to parse execution payload gas used `foo`",
generateData: func() *structs.BeaconBlockBellatrix {
beaconBlock := testhelpers.GenerateJsonBellatrixBeaconBlock()
beaconBlock := test_helpers.GenerateJsonBellatrixBeaconBlock()
beaconBlock.Body.ExecutionPayload.GasUsed = "foo"
return beaconBlock
},
@@ -378,7 +378,7 @@ func TestGetBeaconBlockConverter_BellatrixError(t *testing.T) {
name: "bad timestamp",
expectedErrorMessage: "failed to parse execution payload timestamp `bar`",
generateData: func() *structs.BeaconBlockBellatrix {
beaconBlock := testhelpers.GenerateJsonBellatrixBeaconBlock()
beaconBlock := test_helpers.GenerateJsonBellatrixBeaconBlock()
beaconBlock.Body.ExecutionPayload.Timestamp = "bar"
return beaconBlock
},
@@ -387,7 +387,7 @@ func TestGetBeaconBlockConverter_BellatrixError(t *testing.T) {
name: "bad extra data",
expectedErrorMessage: "failed to decode execution payload extra data `foo`",
generateData: func() *structs.BeaconBlockBellatrix {
beaconBlock := testhelpers.GenerateJsonBellatrixBeaconBlock()
beaconBlock := test_helpers.GenerateJsonBellatrixBeaconBlock()
beaconBlock.Body.ExecutionPayload.ExtraData = "foo"
return beaconBlock
},
@@ -396,7 +396,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() *structs.BeaconBlockBellatrix {
beaconBlock := testhelpers.GenerateJsonBellatrixBeaconBlock()
beaconBlock := test_helpers.GenerateJsonBellatrixBeaconBlock()
beaconBlock.Body.ExecutionPayload.BaseFeePerGas = "bar"
return beaconBlock
},
@@ -405,7 +405,7 @@ func TestGetBeaconBlockConverter_BellatrixError(t *testing.T) {
name: "bad block hash",
expectedErrorMessage: "failed to decode execution payload block hash `foo`",
generateData: func() *structs.BeaconBlockBellatrix {
beaconBlock := testhelpers.GenerateJsonBellatrixBeaconBlock()
beaconBlock := test_helpers.GenerateJsonBellatrixBeaconBlock()
beaconBlock.Body.ExecutionPayload.BlockHash = "foo"
return beaconBlock
},
@@ -414,7 +414,7 @@ func TestGetBeaconBlockConverter_BellatrixError(t *testing.T) {
name: "bad transactions",
expectedErrorMessage: "failed to get execution payload transactions",
generateData: func() *structs.BeaconBlockBellatrix {
beaconBlock := testhelpers.GenerateJsonBellatrixBeaconBlock()
beaconBlock := test_helpers.GenerateJsonBellatrixBeaconBlock()
beaconBlock.Body.ExecutionPayload.Transactions[0] = "bar"
return beaconBlock
},
@@ -433,9 +433,9 @@ func TestGetBeaconBlockConverter_BellatrixError(t *testing.T) {
}
func TestGetBeaconBlockConverter_CapellaValid(t *testing.T) {
expectedBeaconBlock := testhelpers.GenerateProtoCapellaBeaconBlock()
expectedBeaconBlock := test_helpers.GenerateProtoCapellaBeaconBlock()
beaconBlockConverter := &beaconApiBeaconBlockConverter{}
beaconBlock, err := beaconBlockConverter.ConvertRESTCapellaBlockToProto(testhelpers.GenerateJsonCapellaBeaconBlock())
beaconBlock, err := beaconBlockConverter.ConvertRESTCapellaBlockToProto(test_helpers.GenerateJsonCapellaBeaconBlock())
require.NoError(t, err)
assert.DeepEqual(t, expectedBeaconBlock, beaconBlock)
}
@@ -450,7 +450,7 @@ func TestGetBeaconBlockConverter_CapellaError(t *testing.T) {
name: "nil body",
expectedErrorMessage: "block body is nil",
generateData: func() *structs.BeaconBlockCapella {
beaconBlock := testhelpers.GenerateJsonCapellaBeaconBlock()
beaconBlock := test_helpers.GenerateJsonCapellaBeaconBlock()
beaconBlock.Body = nil
return beaconBlock
},
@@ -459,7 +459,7 @@ func TestGetBeaconBlockConverter_CapellaError(t *testing.T) {
name: "nil execution payload",
expectedErrorMessage: "execution payload is nil",
generateData: func() *structs.BeaconBlockCapella {
beaconBlock := testhelpers.GenerateJsonCapellaBeaconBlock()
beaconBlock := test_helpers.GenerateJsonCapellaBeaconBlock()
beaconBlock.Body.ExecutionPayload = nil
return beaconBlock
},
@@ -468,7 +468,7 @@ func TestGetBeaconBlockConverter_CapellaError(t *testing.T) {
name: "bad bellatrix fields",
expectedErrorMessage: "failed to get the bellatrix fields of the capella block",
generateData: func() *structs.BeaconBlockCapella {
beaconBlock := testhelpers.GenerateJsonCapellaBeaconBlock()
beaconBlock := test_helpers.GenerateJsonCapellaBeaconBlock()
beaconBlock.Body.Eth1Data = nil
return beaconBlock
},
@@ -477,7 +477,7 @@ func TestGetBeaconBlockConverter_CapellaError(t *testing.T) {
name: "bad withdrawals",
expectedErrorMessage: "failed to get withdrawals",
generateData: func() *structs.BeaconBlockCapella {
beaconBlock := testhelpers.GenerateJsonCapellaBeaconBlock()
beaconBlock := test_helpers.GenerateJsonCapellaBeaconBlock()
beaconBlock.Body.ExecutionPayload.Withdrawals[0] = nil
return beaconBlock
},
@@ -486,7 +486,7 @@ func TestGetBeaconBlockConverter_CapellaError(t *testing.T) {
name: "bad bls execution changes",
expectedErrorMessage: "failed to get bls to execution changes",
generateData: func() *structs.BeaconBlockCapella {
beaconBlock := testhelpers.GenerateJsonCapellaBeaconBlock()
beaconBlock := test_helpers.GenerateJsonCapellaBeaconBlock()
beaconBlock.Body.BLSToExecutionChanges[0] = nil
return beaconBlock
},

View File

@@ -1,9 +1,10 @@
package beacon_api
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"
@@ -22,7 +23,7 @@ func jsonifyBlsToExecutionChanges(blsToExecutionChanges []*ethpb.SignedBLSToExec
jsonBlsToExecutionChanges := make([]*structs.SignedBLSToExecutionChange, len(blsToExecutionChanges))
for index, signedBlsToExecutionChange := range blsToExecutionChanges {
blsToExecutionChangeJson := &structs.BLSToExecutionChange{
ValidatorIndex: uint64ToString(signedBlsToExecutionChange.Message.ValidatorIndex),
ValidatorIndex: apiutil.Uint64ToString(signedBlsToExecutionChange.Message.ValidatorIndex),
FromBLSPubkey: hexutil.Encode(signedBlsToExecutionChange.Message.FromBlsPubkey),
ToExecutionAddress: hexutil.Encode(signedBlsToExecutionChange.Message.ToExecutionAddress),
}
@@ -38,7 +39,7 @@ func jsonifyBlsToExecutionChanges(blsToExecutionChanges []*ethpb.SignedBLSToExec
func jsonifyEth1Data(eth1Data *ethpb.Eth1Data) *structs.Eth1Data {
return &structs.Eth1Data{
BlockHash: hexutil.Encode(eth1Data.BlockHash),
DepositCount: uint64ToString(eth1Data.DepositCount),
DepositCount: apiutil.Uint64ToString(eth1Data.DepositCount),
DepositRoot: hexutil.Encode(eth1Data.DepositRoot),
}
}
@@ -51,6 +52,14 @@ func jsonifyAttestations(attestations []*ethpb.Attestation) []*structs.Attestati
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 {
@@ -73,7 +82,7 @@ func jsonifyDeposits(deposits []*ethpb.Deposit) []*structs.Deposit {
jsonDeposit := &structs.Deposit{
Data: &structs.DepositData{
Amount: uint64ToString(deposit.Data.Amount),
Amount: apiutil.Uint64ToString(deposit.Data.Amount),
Pubkey: hexutil.Encode(deposit.Data.PublicKey),
Signature: hexutil.Encode(deposit.Data.Signature),
WithdrawalCredentials: hexutil.Encode(deposit.Data.WithdrawalCredentials),
@@ -103,8 +112,8 @@ func JsonifySignedVoluntaryExits(voluntaryExits []*ethpb.SignedVoluntaryExit) []
for index, signedVoluntaryExit := range voluntaryExits {
jsonSignedVoluntaryExit := &structs.SignedVoluntaryExit{
Message: &structs.VoluntaryExit{
Epoch: uint64ToString(signedVoluntaryExit.Exit.Epoch),
ValidatorIndex: uint64ToString(signedVoluntaryExit.Exit.ValidatorIndex),
Epoch: apiutil.Uint64ToString(signedVoluntaryExit.Exit.Epoch),
ValidatorIndex: apiutil.Uint64ToString(signedVoluntaryExit.Exit.ValidatorIndex),
},
Signature: hexutil.Encode(signedVoluntaryExit.Signature),
}
@@ -118,8 +127,8 @@ func jsonifySignedBeaconBlockHeader(signedBeaconBlockHeader *ethpb.SignedBeaconB
Message: &structs.BeaconBlockHeader{
BodyRoot: hexutil.Encode(signedBeaconBlockHeader.Header.BodyRoot),
ParentRoot: hexutil.Encode(signedBeaconBlockHeader.Header.ParentRoot),
ProposerIndex: uint64ToString(signedBeaconBlockHeader.Header.ProposerIndex),
Slot: uint64ToString(signedBeaconBlockHeader.Header.Slot),
ProposerIndex: apiutil.Uint64ToString(signedBeaconBlockHeader.Header.ProposerIndex),
Slot: apiutil.Uint64ToString(signedBeaconBlockHeader.Header.Slot),
StateRoot: hexutil.Encode(signedBeaconBlockHeader.Header.StateRoot),
},
Signature: hexutil.Encode(signedBeaconBlockHeader.Signature),
@@ -129,7 +138,7 @@ func jsonifySignedBeaconBlockHeader(signedBeaconBlockHeader *ethpb.SignedBeaconB
func jsonifyIndexedAttestation(indexedAttestation *ethpb.IndexedAttestation) *structs.IndexedAttestation {
attestingIndices := make([]string, len(indexedAttestation.AttestingIndices))
for index, attestingIndex := range indexedAttestation.AttestingIndices {
attestingIndex := uint64ToString(attestingIndex)
attestingIndex := apiutil.Uint64ToString(attestingIndex)
attestingIndices[index] = attestingIndex
}
@@ -143,14 +152,14 @@ func jsonifyIndexedAttestation(indexedAttestation *ethpb.IndexedAttestation) *st
func jsonifyAttestationData(attestationData *ethpb.AttestationData) *structs.AttestationData {
return &structs.AttestationData{
BeaconBlockRoot: hexutil.Encode(attestationData.BeaconBlockRoot),
CommitteeIndex: uint64ToString(attestationData.CommitteeIndex),
Slot: uint64ToString(attestationData.Slot),
CommitteeIndex: apiutil.Uint64ToString(attestationData.CommitteeIndex),
Slot: apiutil.Uint64ToString(attestationData.Slot),
Source: &structs.Checkpoint{
Epoch: uint64ToString(attestationData.Source.Epoch),
Epoch: apiutil.Uint64ToString(attestationData.Source.Epoch),
Root: hexutil.Encode(attestationData.Source.Root),
},
Target: &structs.Checkpoint{
Epoch: uint64ToString(attestationData.Target.Epoch),
Epoch: apiutil.Uint64ToString(attestationData.Target.Epoch),
Root: hexutil.Encode(attestationData.Target.Root),
},
}
@@ -164,10 +173,28 @@ func jsonifyAttestation(attestation *ethpb.Attestation) *structs.Attestation {
}
}
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: uint64ToString(signedAggregateAndProof.Message.AggregatorIndex),
AggregatorIndex: apiutil.Uint64ToString(signedAggregateAndProof.Message.AggregatorIndex),
Aggregate: jsonifyAttestation(signedAggregateAndProof.Message.Aggregate),
SelectionProof: hexutil.Encode(signedAggregateAndProof.Message.SelectionProof),
},
@@ -175,6 +202,17 @@ func jsonifySignedAggregateAndProof(signedAggregateAndProof *ethpb.SignedAggrega
}
}
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 {

View File

@@ -1,4 +1,4 @@
package beacon_api
package validator_api
import (
"testing"

View File

@@ -1,4 +1,4 @@
package beacon_api
package validator_api
import (
"strconv"
@@ -197,6 +197,39 @@ func convertAttestationToProto(jsonAttestation *structs.Attestation) (*ethpb.Att
}, nil
}
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 &ethpb.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 {

View File

@@ -1,4 +1,4 @@
package beacon_api
package validator_api
import (
"testing"

View 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
}

View File

@@ -1,10 +1,11 @@
package beacon_api
package validator_api
import (
"context"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/pkg/errors"
"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"
@@ -24,7 +25,7 @@ func (c *beaconApiValidatorClient) domainData(ctx context.Context, epoch primiti
return nil, errors.Wrapf(err, "failed to get genesis info")
}
if !validRoot(genesis.GenesisValidatorsRoot) {
if !apiutil.ValidRoot(genesis.GenesisValidatorsRoot) {
return nil, errors.Errorf("invalid genesis validators root: %s", genesis.GenesisValidatorsRoot)
}

View File

@@ -1,4 +1,4 @@
package beacon_api
package validator_api
import (
"context"
@@ -6,12 +6,12 @@ import (
"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/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"
"github.com/prysmaticlabs/prysm/v5/validator/client/beacon-api/mock"
"go.uber.org/mock/gomock"
)

View File

@@ -1,4 +1,4 @@
package beacon_api
package validator_api
import (
"context"
@@ -220,7 +220,7 @@ func buildResponse(
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))

View File

@@ -1,4 +1,4 @@
package beacon_api
package validator_api
import (
"bytes"
@@ -8,11 +8,11 @@ import (
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/pkg/errors"
"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"
"github.com/prysmaticlabs/prysm/v5/validator/client/beacon-api/mock"
"go.uber.org/mock/gomock"
)

View 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 &ethpb.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] = &ethpb.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
}

View File

@@ -1,515 +1,24 @@
package beacon_api
package validator_api
import (
"bytes"
"context"
"encoding/json"
"errors"
"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"
"github.com/prysmaticlabs/prysm/v5/validator/client/beacon-api/mock"
"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 := &beaconApiDutiesProvider{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 := &beaconApiDutiesProvider{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 := &beaconApiDutiesProvider{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 := &beaconApiDutiesProvider{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 := &beaconApiDutiesProvider{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 := &beaconApiDutiesProvider{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 := &beaconApiDutiesProvider{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 := &beaconApiDutiesProvider{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 := &beaconApiDutiesProvider{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 := &beaconApiDutiesProvider{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 := &beaconApiDutiesProvider{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 := &beaconApiDutiesProvider{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 := &beaconApiDutiesProvider{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 := &beaconApiDutiesProvider{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 := &beaconApiDutiesProvider{jsonRestHandler: jsonRestHandler}
_, err := dutiesProvider.Committees(ctx, epoch)
assert.ErrorContains(t, "committee at index `0` is nil", err)
}
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}}
@@ -527,8 +36,6 @@ func TestGetDutiesForEpoch_Error(t *testing.T) {
fetchProposerDutiesError error
generateSyncDuties func() []*structs.SyncCommitteeDuty
fetchSyncDutiesError error
generateCommittees func() []*structs.Committee
fetchCommitteesError error
}{
{
name: "get attester duties failed",
@@ -545,11 +52,6 @@ func TestGetDutiesForEpoch_Error(t *testing.T) {
expectedError: "failed to get sync duties for epoch `1`: foo error",
fetchSyncDutiesError: errors.New("foo error"),
},
{
name: "get committees failed",
expectedError: "failed to get committees for epoch `1`: foo error",
fetchCommitteesError: errors.New("foo error"),
},
{
name: "bad attester validator index",
expectedError: "failed to parse attester validator index `foo`",
@@ -604,46 +106,6 @@ func TestGetDutiesForEpoch_Error(t *testing.T) {
return syncDuties
},
},
{
name: "bad committee index",
expectedError: "failed to parse committee index `foo`",
generateCommittees: func() []*structs.Committee {
committees := generateValidCommittees(committeeIndices, committeeSlots, validatorIndices)
committees[0].Index = "foo"
return committees
},
},
{
name: "bad committee slot",
expectedError: "failed to parse slot `foo`",
generateCommittees: func() []*structs.Committee {
committees := generateValidCommittees(committeeIndices, committeeSlots, validatorIndices)
committees[0].Slot = "foo"
return committees
},
},
{
name: "bad committee validator index",
expectedError: "failed to parse committee validator index `foo`",
generateCommittees: func() []*structs.Committee {
committees := generateValidCommittees(committeeIndices, committeeSlots, validatorIndices)
committees[0].Validators[0] = "foo"
return committees
},
},
{
name: "committee index and slot not found in committees mapping",
expectedError: "failed to find validators for committee index `1` and slot `2`",
generateAttesterDuties: func() []*structs.AttesterDuty {
attesterDuties := generateValidAttesterDuties(pubkeys, validatorIndices, committeeIndices, committeeSlots)
attesterDuties[0].CommitteeIndex = "1"
attesterDuties[0].Slot = "2"
return attesterDuties
},
generateCommittees: func() []*structs.Committee {
return []*structs.Committee{}
},
},
}
for _, testCase := range testCases {
@@ -674,13 +136,6 @@ func TestGetDutiesForEpoch_Error(t *testing.T) {
syncDuties = testCase.generateSyncDuties()
}
var committees []*structs.Committee
if testCase.generateCommittees == nil {
committees = generateValidCommittees(committeeIndices, committeeSlots, validatorIndices)
} else {
committees = testCase.generateCommittees()
}
dutiesProvider := mock.NewMockdutiesProvider(ctrl)
dutiesProvider.EXPECT().AttesterDuties(
ctx,
@@ -708,20 +163,12 @@ func TestGetDutiesForEpoch_Error(t *testing.T) {
testCase.fetchSyncDutiesError,
).AnyTimes()
dutiesProvider.EXPECT().Committees(
ctx,
epoch,
).Return(
committees,
testCase.fetchCommitteesError,
).AnyTimes()
vals := make([]validatorForDuty, len(pubkeys))
vals := make([]beacon.ValidatorForDuty, len(pubkeys))
for i := 0; i < len(pubkeys); i++ {
vals[i] = validatorForDuty{
pubkey: pubkeys[i],
index: validatorIndices[i],
status: ethpb.ValidatorStatus_ACTIVE,
vals[i] = beacon.ValidatorForDuty{
Pubkey: pubkeys[i],
Index: validatorIndices[i],
Status: ethpb.ValidatorStatus_ACTIVE,
}
}
@@ -767,13 +214,6 @@ func TestGetDutiesForEpoch_Valid(t *testing.T) {
ctx := context.Background()
dutiesProvider := mock.NewMockdutiesProvider(ctrl)
dutiesProvider.EXPECT().Committees(
ctx,
epoch,
).Return(
generateValidCommittees(committeeIndices, committeeSlots, validatorIndices),
nil,
).Times(1)
dutiesProvider.EXPECT().AttesterDuties(
ctx,
@@ -943,12 +383,12 @@ func TestGetDutiesForEpoch_Valid(t *testing.T) {
}
validatorClient := &beaconApiValidatorClient{dutiesProvider: dutiesProvider}
vals := make([]validatorForDuty, len(pubkeys))
vals := make([]beacon.ValidatorForDuty, len(pubkeys))
for i := 0; i < len(pubkeys); i++ {
vals[i] = validatorForDuty{
pubkey: pubkeys[i],
index: validatorIndices[i],
status: ethpb.ValidatorStatus_ACTIVE,
vals[i] = beacon.ValidatorForDuty{
Pubkey: pubkeys[i],
Index: validatorIndices[i],
Status: ethpb.ValidatorStatus_ACTIVE,
}
}
duties, err := validatorClient.dutiesForEpoch(
@@ -958,7 +398,14 @@ func TestGetDutiesForEpoch_Valid(t *testing.T) {
testCase.fetchSyncDuties,
)
require.NoError(t, err)
assert.DeepEqual(t, expectedDuties, duties)
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)
}
})
}
}
@@ -983,14 +430,14 @@ func TestGetDuties_Valid(t *testing.T) {
valCount := 12
pubkeys := make([][]byte, valCount)
validatorIndices := make([]primitives.ValidatorIndex, valCount)
vals := make([]validatorForDuty, 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] = validatorForDuty{
pubkey: pubkeys[i],
index: validatorIndices[i],
status: ethpb.ValidatorStatus_ACTIVE,
vals[i] = beacon.ValidatorForDuty{
Pubkey: pubkeys[i],
Index: validatorIndices[i],
Status: ethpb.ValidatorStatus_ACTIVE,
}
}
@@ -1004,13 +451,6 @@ func TestGetDuties_Valid(t *testing.T) {
ctx := context.Background()
dutiesProvider := mock.NewMockdutiesProvider(ctrl)
dutiesProvider.EXPECT().Committees(
ctx,
testCase.epoch,
).Return(
generateValidCommittees(committeeIndices, committeeSlots, validatorIndices),
nil,
).Times(2)
dutiesProvider.EXPECT().AttesterDuties(
ctx,
@@ -1041,14 +481,6 @@ func TestGetDuties_Valid(t *testing.T) {
).Times(2)
}
dutiesProvider.EXPECT().Committees(
ctx,
testCase.epoch+1,
).Return(
reverseSlice(generateValidCommittees(committeeIndices, committeeSlots, validatorIndices)),
nil,
).Times(2)
dutiesProvider.EXPECT().AttesterDuties(
ctx,
testCase.epoch+1,
@@ -1209,7 +641,7 @@ func TestGetDuties_Valid(t *testing.T) {
)
require.NoError(t, err)
expectedDuties := &ethpb.DutiesResponse{
expectedDuties := &ethpb.ValidatorDutiesContainer{
CurrentEpochDuties: expectedCurrentEpochDuties,
NextEpochDuties: expectedNextEpochDuties,
}
@@ -1298,10 +730,6 @@ func TestGetDuties_GetDutiesForEpochFailed(t *testing.T) {
ctx,
gomock.Any(),
).Times(2)
dutiesProvider.EXPECT().Committees(
ctx,
gomock.Any(),
).Times(2)
validatorClient := &beaconApiValidatorClient{
stateValidatorsProvider: stateValidatorsProvider,
@@ -1316,72 +744,61 @@ func TestGetDuties_GetDutiesForEpochFailed(t *testing.T) {
assert.ErrorContains(t, "foo error", err)
}
func generateValidCommittees(committeeIndices []primitives.CommitteeIndex, slots []primitives.Slot, validatorIndices []primitives.ValidatorIndex) []*structs.Committee {
return []*structs.Committee{
{
Index: strconv.FormatUint(uint64(committeeIndices[0]), 10),
Slot: strconv.FormatUint(uint64(slots[0]), 10),
Validators: []string{
strconv.FormatUint(uint64(validatorIndices[0]), 10),
strconv.FormatUint(uint64(validatorIndices[1]), 10),
},
},
{
Index: strconv.FormatUint(uint64(committeeIndices[1]), 10),
Slot: strconv.FormatUint(uint64(slots[1]), 10),
Validators: []string{
strconv.FormatUint(uint64(validatorIndices[2]), 10),
strconv.FormatUint(uint64(validatorIndices[3]), 10),
},
},
{
Index: strconv.FormatUint(uint64(committeeIndices[2]), 10),
Slot: strconv.FormatUint(uint64(slots[2]), 10),
Validators: []string{
strconv.FormatUint(uint64(validatorIndices[4]), 10),
strconv.FormatUint(uint64(validatorIndices[5]), 10),
},
},
}
}
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),
Slot: strconv.FormatUint(uint64(slots[0]), 10),
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),
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),
Slot: strconv.FormatUint(uint64(slots[1]), 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),
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),
Slot: strconv.FormatUint(uint64(slots[2]), 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),
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),
},
}
}

View File

@@ -1,4 +1,4 @@
package beacon_api
package validator_api
import (
"bytes"
@@ -10,6 +10,7 @@ import (
"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"
@@ -35,7 +36,7 @@ func (c *beaconApiValidatorClient) beaconBlock(ctx context.Context, slot primiti
// 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 := buildURL(fmt.Sprintf("/eth/v3/validator/blocks/%d", slot), queryParams)
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{}
@@ -69,8 +70,15 @@ func (c *beaconApiValidatorClient) beaconBlock(ctx context.Context, slot primiti
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{}
@@ -93,7 +101,7 @@ func (c *beaconApiValidatorClient) beaconBlock(ctx context.Context, slot primiti
}
response = genericBlock
case version.String(version.Bellatrix):
if blinded {
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")
@@ -115,7 +123,7 @@ func (c *beaconApiValidatorClient) beaconBlock(ctx context.Context, slot primiti
response = genericBlock
}
case version.String(version.Capella):
if blinded {
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")
@@ -137,7 +145,7 @@ func (c *beaconApiValidatorClient) beaconBlock(ctx context.Context, slot primiti
response = genericBlock
}
case version.String(version.Deneb):
if blinded {
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")
@@ -158,6 +166,50 @@ func (c *beaconApiValidatorClient) beaconBlock(ctx context.Context, slot primiti
}
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)
}
@@ -170,7 +222,7 @@ func (c *beaconApiValidatorClient) fallBackToBlinded(
queryParams neturl.Values,
) (*abstractProduceBlockResponseJson, error) {
resp := &abstractProduceBlockResponseJson{}
url := buildURL(fmt.Sprintf("/eth/v1/validator/blinded_blocks/%d", slot), queryParams)
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
}
@@ -183,7 +235,7 @@ func (c *beaconApiValidatorClient) fallBackToFull(
queryParams neturl.Values,
) (*abstractProduceBlockResponseJson, error) {
resp := &abstractProduceBlockResponseJson{}
url := buildURL(fmt.Sprintf("/eth/v2/validator/blocks/%d", slot), queryParams)
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
}

View File

@@ -1,4 +1,4 @@
package beacon_api
package validator_api
import (
"context"
@@ -9,14 +9,14 @@ import (
"testing"
"github.com/ethereum/go-ethereum/common/hexutil"
"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"
"github.com/prysmaticlabs/prysm/v5/validator/client/beacon-api/mock"
testhelpers "github.com/prysmaticlabs/prysm/v5/validator/client/beacon-api/test-helpers"
"go.uber.org/mock/gomock"
)
@@ -149,8 +149,8 @@ func TestGetBeaconBlock_Phase0Valid(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
proto := testhelpers.GenerateProtoPhase0BeaconBlock()
block := testhelpers.GenerateJsonPhase0BeaconBlock()
proto := test_helpers.GenerateProtoPhase0BeaconBlock()
block := test_helpers.GenerateJsonPhase0BeaconBlock()
bytes, err := json.Marshal(block)
require.NoError(t, err)
@@ -191,8 +191,8 @@ func TestGetBeaconBlock_AltairValid(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
proto := testhelpers.GenerateProtoAltairBeaconBlock()
block := testhelpers.GenerateJsonAltairBeaconBlock()
proto := test_helpers.GenerateProtoAltairBeaconBlock()
block := test_helpers.GenerateJsonAltairBeaconBlock()
bytes, err := json.Marshal(block)
require.NoError(t, err)
@@ -234,8 +234,8 @@ func TestGetBeaconBlock_BellatrixValid(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
proto := testhelpers.GenerateProtoBellatrixBeaconBlock()
block := testhelpers.GenerateJsonBellatrixBeaconBlock()
proto := test_helpers.GenerateProtoBellatrixBeaconBlock()
block := test_helpers.GenerateJsonBellatrixBeaconBlock()
bytes, err := json.Marshal(block)
require.NoError(t, err)
@@ -279,8 +279,8 @@ func TestGetBeaconBlock_BlindedBellatrixValid(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
proto := testhelpers.GenerateProtoBlindedBellatrixBeaconBlock()
block := testhelpers.GenerateJsonBlindedBellatrixBeaconBlock()
proto := test_helpers.GenerateProtoBlindedBellatrixBeaconBlock()
block := test_helpers.GenerateJsonBlindedBellatrixBeaconBlock()
bytes, err := json.Marshal(block)
require.NoError(t, err)
@@ -324,8 +324,8 @@ func TestGetBeaconBlock_CapellaValid(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
proto := testhelpers.GenerateProtoCapellaBeaconBlock()
block := testhelpers.GenerateJsonCapellaBeaconBlock()
proto := test_helpers.GenerateProtoCapellaBeaconBlock()
block := test_helpers.GenerateJsonCapellaBeaconBlock()
bytes, err := json.Marshal(block)
require.NoError(t, err)
@@ -369,8 +369,8 @@ func TestGetBeaconBlock_BlindedCapellaValid(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
proto := testhelpers.GenerateProtoBlindedCapellaBeaconBlock()
block := testhelpers.GenerateJsonBlindedCapellaBeaconBlock()
proto := test_helpers.GenerateProtoBlindedCapellaBeaconBlock()
block := test_helpers.GenerateJsonBlindedCapellaBeaconBlock()
bytes, err := json.Marshal(block)
require.NoError(t, err)
@@ -414,8 +414,8 @@ func TestGetBeaconBlock_DenebValid(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
proto := testhelpers.GenerateProtoDenebBeaconBlockContents()
block := testhelpers.GenerateJsonDenebBeaconBlockContents()
proto := test_helpers.GenerateProtoDenebBeaconBlockContents()
block := test_helpers.GenerateJsonDenebBeaconBlockContents()
bytes, err := json.Marshal(block)
require.NoError(t, err)
@@ -459,8 +459,8 @@ func TestGetBeaconBlock_BlindedDenebValid(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
proto := testhelpers.GenerateProtoBlindedDenebBeaconBlock()
block := testhelpers.GenerateJsonBlindedDenebBeaconBlock()
proto := test_helpers.GenerateProtoBlindedDenebBeaconBlock()
block := test_helpers.GenerateJsonBlindedDenebBeaconBlock()
bytes, err := json.Marshal(block)
require.NoError(t, err)
@@ -500,12 +500,102 @@ 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 := &ethpb.GenericBeaconBlock{
Block: &ethpb.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 := &ethpb.GenericBeaconBlock{
Block: &ethpb.GenericBeaconBlock_BlindedElectra{
BlindedElectra: proto,
},
IsBlinded: true,
}
assert.DeepEqual(t, expectedBeaconBlock, beaconBlock)
}
func TestGetBeaconBlock_FallbackToBlindedBlock(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
proto := testhelpers.GenerateProtoBlindedDenebBeaconBlock()
block := testhelpers.GenerateJsonBlindedDenebBeaconBlock()
proto := test_helpers.GenerateProtoBlindedDenebBeaconBlock()
block := test_helpers.GenerateJsonBlindedDenebBeaconBlock()
blockBytes, err := json.Marshal(block)
require.NoError(t, err)
@@ -555,8 +645,8 @@ func TestGetBeaconBlock_FallbackToFullBlock(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
proto := testhelpers.GenerateProtoDenebBeaconBlockContents()
block := testhelpers.GenerateJsonDenebBeaconBlockContents()
proto := test_helpers.GenerateProtoDenebBeaconBlockContents()
block := test_helpers.GenerateJsonDenebBeaconBlockContents()
blockBytes, err := json.Marshal(block)
require.NoError(t, err)

View File

@@ -1,4 +1,4 @@
package grpc_api
package validator_api
import (
"context"
@@ -8,13 +8,13 @@ import (
"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"
"github.com/prysmaticlabs/prysm/v5/validator/client/iface"
log "github.com/sirupsen/logrus"
"google.golang.org/grpc"
)
@@ -23,8 +23,59 @@ type grpcValidatorClient struct {
isEventStreamRunning bool
}
func (c *grpcValidatorClient) Duties(ctx context.Context, in *ethpb.DutiesRequest) (*ethpb.DutiesResponse, error) {
return c.beaconNodeValidatorClient.GetDuties(ctx, in)
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 &ethpb.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 &ethpb.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) {
@@ -71,7 +122,7 @@ func (c *grpcValidatorClient) ProposeAttestation(ctx context.Context, in *ethpb.
return c.beaconNodeValidatorClient.ProposeAttestation(ctx, in)
}
func (c *grpcValidatorClient) ProposeAttestationElectra(ctx context.Context, in *ethpb.AttestationElectra) (*ethpb.AttestResponse, error) {
func (c *grpcValidatorClient) ProposeAttestationElectra(ctx context.Context, in *ethpb.SingleAttestation) (*ethpb.AttestResponse, error) {
return c.beaconNodeValidatorClient.ProposeAttestationElectra(ctx, in)
}
@@ -115,7 +166,7 @@ func (c *grpcValidatorClient) SubmitValidatorRegistrations(ctx context.Context,
return c.beaconNodeValidatorClient.SubmitValidatorRegistrations(ctx, in)
}
func (c *grpcValidatorClient) SubscribeCommitteeSubnets(ctx context.Context, in *ethpb.CommitteeSubnetsSubscribeRequest, _ []*ethpb.DutiesResponse_Duty) (*empty.Empty, error) {
func (c *grpcValidatorClient) SubscribeCommitteeSubnets(ctx context.Context, in *ethpb.CommitteeSubnetsSubscribeRequest, _ []*ethpb.ValidatorDuty) (*empty.Empty, error) {
return c.beaconNodeValidatorClient.SubscribeCommitteeSubnets(ctx, in)
}
@@ -150,15 +201,15 @@ func (c *grpcValidatorClient) AggregatedSigAndAggregationBits(
return c.beaconNodeValidatorClient.AggregatedSigAndAggregationBits(ctx, in)
}
func (*grpcValidatorClient) AggregatedSelections(context.Context, []iface.BeaconCommitteeSelection) ([]iface.BeaconCommitteeSelection, error) {
return nil, iface.ErrNotSupported
func (*grpcValidatorClient) AggregatedSelections(context.Context, []beacon.BeaconCommitteeSelection) ([]beacon.BeaconCommitteeSelection, error) {
return nil, client.ErrNotSupported
}
func (*grpcValidatorClient) AggregatedSyncSelections(context.Context, []iface.SyncCommitteeSelection) ([]iface.SyncCommitteeSelection, error) {
return nil, iface.ErrNotSupported
func (*grpcValidatorClient) AggregatedSyncSelections(context.Context, []beacon.SyncCommitteeSelection) ([]beacon.SyncCommitteeSelection, error) {
return nil, client.ErrNotSupported
}
func NewGrpcValidatorClient(cc grpc.ClientConnInterface) iface.ValidatorClient {
func NewGrpcValidatorClient(cc grpc.ClientConnInterface) Client {
return &grpcValidatorClient{ethpb.NewBeaconNodeValidatorClient(cc), false}
}
@@ -255,10 +306,10 @@ func (c *grpcValidatorClient) EventStreamIsRunning() bool {
}
func (*grpcValidatorClient) Host() string {
log.Warn(iface.ErrNotSupported)
log.Warn(client.ErrNotSupported)
return ""
}
func (*grpcValidatorClient) SetHost(_ string) {
log.Warn(iface.ErrNotSupported)
log.Warn(client.ErrNotSupported)
}

View File

@@ -1,4 +1,4 @@
package grpc_api
package validator_api
import (
"context"
@@ -9,6 +9,7 @@ import (
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"
@@ -18,6 +19,58 @@ import (
"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 := &eth.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()

View File

@@ -1,4 +1,4 @@
package beacon_api
package validator_api
import (
"context"

View File

@@ -1,4 +1,4 @@
package beacon_api
package validator_api
import (
"bytes"
@@ -9,12 +9,14 @@ import (
"github.com/ethereum/go-ethereum/common/hexutil"
"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/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"
"github.com/prysmaticlabs/prysm/v5/validator/client/beacon-api/mock"
"go.uber.org/mock/gomock"
)
@@ -67,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(
@@ -109,9 +109,7 @@ func TestIndex_UnexistingValidator(t *testing.T) {
).Times(1)
validatorClient := beaconApiValidatorClient{
stateValidatorsProvider: beaconApiStateValidatorsProvider{
jsonRestHandler: jsonRestHandler,
},
stateValidatorsProvider: shared_providers.NewStateValidators(jsonRestHandler),
}
_, err := validatorClient.ValidatorIndex(
@@ -159,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(
@@ -209,16 +205,14 @@ func TestIndex_JsonResponseError(t *testing.T) {
jsonRestHandler.EXPECT().Get(
gomock.Any(),
buildURL("/eth/v1/beacon/states/head/validators", queryParams),
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(

View File

@@ -0,0 +1,46 @@
package validator_api
import (
"context"
"github.com/golang/protobuf/ptypes/empty"
"github.com/prysmaticlabs/prysm/v5/api/client/beacon"
"github.com/prysmaticlabs/prysm/v5/api/client/event"
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
)
type Client interface {
Duties(ctx context.Context, in *ethpb.DutiesRequest) (*ethpb.ValidatorDutiesContainer, error)
DomainData(ctx context.Context, in *ethpb.DomainRequest) (*ethpb.DomainResponse, error)
WaitForChainStart(ctx context.Context, in *empty.Empty) (*ethpb.ChainStartResponse, error)
ValidatorIndex(ctx context.Context, in *ethpb.ValidatorIndexRequest) (*ethpb.ValidatorIndexResponse, error)
ValidatorStatus(ctx context.Context, in *ethpb.ValidatorStatusRequest) (*ethpb.ValidatorStatusResponse, error)
MultipleValidatorStatus(ctx context.Context, in *ethpb.MultipleValidatorStatusRequest) (*ethpb.MultipleValidatorStatusResponse, error)
BeaconBlock(ctx context.Context, in *ethpb.BlockRequest) (*ethpb.GenericBeaconBlock, error)
ProposeBeaconBlock(ctx context.Context, in *ethpb.GenericSignedBeaconBlock) (*ethpb.ProposeResponse, error)
PrepareBeaconProposer(ctx context.Context, in *ethpb.PrepareBeaconProposerRequest) (*empty.Empty, error)
FeeRecipientByPubKey(ctx context.Context, in *ethpb.FeeRecipientByPubKeyRequest) (*ethpb.FeeRecipientByPubKeyResponse, error)
AttestationData(ctx context.Context, in *ethpb.AttestationDataRequest) (*ethpb.AttestationData, error)
ProposeAttestation(ctx context.Context, in *ethpb.Attestation) (*ethpb.AttestResponse, error)
ProposeAttestationElectra(ctx context.Context, in *ethpb.SingleAttestation) (*ethpb.AttestResponse, error)
SubmitAggregateSelectionProof(ctx context.Context, in *ethpb.AggregateSelectionRequest, index primitives.ValidatorIndex, committeeLength uint64) (*ethpb.AggregateSelectionResponse, error)
SubmitAggregateSelectionProofElectra(ctx context.Context, in *ethpb.AggregateSelectionRequest, _ primitives.ValidatorIndex, _ uint64) (*ethpb.AggregateSelectionElectraResponse, error)
SubmitSignedAggregateSelectionProof(ctx context.Context, in *ethpb.SignedAggregateSubmitRequest) (*ethpb.SignedAggregateSubmitResponse, error)
SubmitSignedAggregateSelectionProofElectra(ctx context.Context, in *ethpb.SignedAggregateSubmitElectraRequest) (*ethpb.SignedAggregateSubmitResponse, error)
ProposeExit(ctx context.Context, in *ethpb.SignedVoluntaryExit) (*ethpb.ProposeExitResponse, error)
SubscribeCommitteeSubnets(ctx context.Context, in *ethpb.CommitteeSubnetsSubscribeRequest, duties []*ethpb.ValidatorDuty) (*empty.Empty, error)
CheckDoppelGanger(ctx context.Context, in *ethpb.DoppelGangerRequest) (*ethpb.DoppelGangerResponse, error)
SyncMessageBlockRoot(ctx context.Context, in *empty.Empty) (*ethpb.SyncMessageBlockRootResponse, error)
SubmitSyncMessage(ctx context.Context, in *ethpb.SyncCommitteeMessage) (*empty.Empty, error)
SyncSubcommitteeIndex(ctx context.Context, in *ethpb.SyncSubcommitteeIndexRequest) (*ethpb.SyncSubcommitteeIndexResponse, error)
SyncCommitteeContribution(ctx context.Context, in *ethpb.SyncCommitteeContributionRequest) (*ethpb.SyncCommitteeContribution, error)
SubmitSignedContributionAndProof(ctx context.Context, in *ethpb.SignedContributionAndProof) (*empty.Empty, error)
SubmitValidatorRegistrations(ctx context.Context, in *ethpb.SignedValidatorRegistrationsV1) (*empty.Empty, error)
StartEventStream(ctx context.Context, topics []string, eventsChannel chan<- *event.Event)
EventStreamIsRunning() bool
AggregatedSelections(ctx context.Context, selections []beacon.BeaconCommitteeSelection) ([]beacon.BeaconCommitteeSelection, error)
AggregatedSyncSelections(ctx context.Context, selections []beacon.SyncCommitteeSelection) ([]beacon.SyncCommitteeSelection, error)
Host() string
SetHost(host string)
}

View File

@@ -1,4 +1,4 @@
package beacon_api
package validator_api
import "github.com/sirupsen/logrus"

View File

@@ -1,4 +1,4 @@
package beacon_api
package validator_api
import (
"github.com/prometheus/client_golang/prometheus"

View File

@@ -1,4 +1,4 @@
package beacon_api
package validator_api
import (
"bytes"

View File

@@ -1,4 +1,4 @@
package beacon_api
package validator_api
import (
"bytes"
@@ -8,11 +8,11 @@ import (
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/pkg/errors"
"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"
"github.com/prysmaticlabs/prysm/v5/validator/client/beacon-api/mock"
"go.uber.org/mock/gomock"
)

View File

@@ -0,0 +1,87 @@
package validator_api
import (
"bytes"
"context"
"encoding/json"
"net/http"
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/helpers"
"github.com/prysmaticlabs/prysm/v5/network/httputil"
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v5/runtime/version"
)
func (c *beaconApiValidatorClient) proposeAttestation(ctx context.Context, attestation *ethpb.Attestation) (*ethpb.AttestResponse, error) {
if err := helpers.ValidateNilAttestation(attestation); err != nil {
return nil, err
}
marshalledAttestation, err := json.Marshal(jsonifyAttestations([]*ethpb.Attestation{attestation}))
if err != nil {
return nil, err
}
headers := map[string]string{"Eth-Consensus-Version": version.String(attestation.Version())}
err = c.jsonRestHandler.Post(
ctx,
"/eth/v2/beacon/pool/attestations",
headers,
bytes.NewBuffer(marshalledAttestation),
nil,
)
errJson := &httputil.DefaultJsonError{}
if err != nil {
// TODO: remove this when v2 becomes default
if !errors.As(err, &errJson) {
return nil, err
}
if errJson.Code != http.StatusNotFound {
return nil, errJson
}
log.Debug("Endpoint /eth/v2/beacon/pool/attestations is not supported, falling back to older endpoints for submit attestation.")
if err = c.jsonRestHandler.Post(
ctx,
"/eth/v1/beacon/pool/attestations",
nil,
bytes.NewBuffer(marshalledAttestation),
nil,
); err != nil {
return nil, err
}
}
attestationDataRoot, err := attestation.Data.HashTreeRoot()
if err != nil {
return nil, errors.Wrap(err, "failed to compute attestation data root")
}
return &ethpb.AttestResponse{AttestationDataRoot: attestationDataRoot[:]}, nil
}
func (c *beaconApiValidatorClient) proposeAttestationElectra(ctx context.Context, attestation *ethpb.SingleAttestation) (*ethpb.AttestResponse, error) {
if err := helpers.ValidateNilAttestation(attestation); err != nil {
return nil, err
}
marshalledAttestation, err := json.Marshal(jsonifySingleAttestations([]*ethpb.SingleAttestation{attestation}))
if err != nil {
return nil, err
}
headers := map[string]string{"Eth-Consensus-Version": version.String(attestation.Version())}
if err = c.jsonRestHandler.Post(
ctx,
"/eth/v2/beacon/pool/attestations",
headers,
bytes.NewBuffer(marshalledAttestation),
nil,
); err != nil {
return nil, err
}
attestationDataRoot, err := attestation.Data.HashTreeRoot()
if err != nil {
return nil, errors.Wrap(err, "failed to compute attestation data root")
}
return &ethpb.AttestResponse{AttestationDataRoot: attestationDataRoot[:]}, nil
}

Some files were not shown because too many files have changed in this diff Show More