Compare commits

...

42 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
308 changed files with 6173 additions and 4584 deletions

View File

@@ -4,6 +4,43 @@ 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.
## [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
- 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.
@@ -21,7 +58,7 @@ Known issues in **Electra**:
Testnet operators are strongly encouraged to update to this release. There are many fixes and improvements from the Holesky upgrade incident.
Mainner operators are recommended to update to this release at their regular cadence.
Mainnet operators are recommended to update to this release at their regular cadence.
### Added
@@ -3218,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

@@ -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

@@ -255,7 +255,7 @@ filegroup(
url = "https://github.com/ethereum/EIPs/archive/5480440fe51742ed23342b68cf106cefd427e39d.tar.gz",
)
consensus_spec_version = "v1.5.0-beta.3"
consensus_spec_version = "v1.5.0-beta.4"
bls_test_version = "v0.1.1"
@@ -271,7 +271,7 @@ filegroup(
visibility = ["//visibility:public"],
)
""",
integrity = "sha256-z+j0BEJuXMBKbGL+7jq35zddzZMW1je8/uvTz5+wboQ=",
integrity = "sha256-QG0NUqaCvP5lKaKKwF/fmeICZVjONMlb7EE+MtYl0C0=",
url = "https://github.com/ethereum/consensus-spec-tests/releases/download/%s/general.tar.gz" % consensus_spec_version,
)
@@ -287,7 +287,7 @@ filegroup(
visibility = ["//visibility:public"],
)
""",
integrity = "sha256-5/YUOXH65CmM1plZ8twJ3BQxwM51jgSpOB8/VSBI19k=",
integrity = "sha256-8NQngTSSqzW/j3tOUi3r5h+94ChRbLNWTt7BOGqr4+E=",
url = "https://github.com/ethereum/consensus-spec-tests/releases/download/%s/minimal.tar.gz" % consensus_spec_version,
)
@@ -303,7 +303,7 @@ filegroup(
visibility = ["//visibility:public"],
)
""",
integrity = "sha256-iZ2eNhwRnbxrjR+5gMBUYakaCXicvPChwFUkZtQUbbI=",
integrity = "sha256-gFqxbaBnJ7dtdoj0zFbVrtlHv/bLNuWjrTHkyCAjFjI=",
url = "https://github.com/ethereum/consensus-spec-tests/releases/download/%s/mainnet.tar.gz" % consensus_spec_version,
)
@@ -318,7 +318,7 @@ filegroup(
visibility = ["//visibility:public"],
)
""",
integrity = "sha256-inAXV7xNM5J1aUdP7JNXFO2iFFZ7dth38Ji+mJW50Ts=",
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,
)

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

@@ -5,15 +5,14 @@ go_library(
srcs = [
"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",
"//consensus-types/primitives:go_default_library",
@@ -28,15 +27,10 @@ go_library(
go_test(
name = "go_default_test",
srcs = [
"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",
"//testing/require: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,7 +7,7 @@ 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)

View File

@@ -1,4 +1,4 @@
package beacon_api
package chain
import (
"context"
@@ -8,17 +8,18 @@ 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"
"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
}
func (c beaconApiChainClient) headBlockHeaders(ctx context.Context) (*structs.GetBlockHeaderResponse, error) {
@@ -332,11 +333,3 @@ func (c beaconApiChainClient) ValidatorParticipation(ctx context.Context, in *et
// TODO: Implement me
return nil, errors.New("beaconApiChainClient.ValidatorParticipation is not implemented. To use a fallback client, pass a fallback client as the last argument of NewBeaconApiChainClientWithFallback.")
}
func NewBeaconApiChainClientWithFallback(jsonRestHandler JsonRestHandler, fallbackClient iface.ChainClient) iface.ChainClient {
return &beaconApiChainClient{
jsonRestHandler: jsonRestHandler,
fallbackClient: fallbackClient,
stateValidatorsProvider: beaconApiStateValidatorsProvider{jsonRestHandler: jsonRestHandler},
}
}

View File

@@ -1,4 +1,4 @@
package beacon_api
package chain
import (
"context"
@@ -9,13 +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"
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"
)

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

@@ -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,15 +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"
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
iface "github.com/prysmaticlabs/prysm/v5/validator/client/iface"
gomock "go.uber.org/mock/gomock"
)
@@ -43,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
}

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

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
return nil, errors.New("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,
})
@@ -94,7 +94,3 @@ func validatorCountByStatus(validators []*ethpb.Validator, statuses []validator.
func (c *grpcPrysmChainClient) ValidatorPerformance(ctx context.Context, in *ethpb.ValidatorPerformanceRequest) (*ethpb.ValidatorPerformanceResponse, error) {
return c.chainClient.ValidatorPerformance(ctx, in)
}
func NewGrpcPrysmChainClient(cc grpc.ClientConnInterface) iface.PrysmChainClient {
return &grpcPrysmChainClient{chainClient: &grpcChainClient{ethpb.NewBeaconChainClient(cc)}}
}

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

@@ -1,22 +1,15 @@
package iface
package prysm_api
import (
"context"
"github.com/pkg/errors"
"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"
)
var ErrNotSupported = errors.New("endpoint not supported")
type ValidatorCount struct {
Status string
Count uint64
}
// PrysmChainClient defines an interface required to implement all the prysm specific custom endpoints.
type PrysmChainClient interface {
ValidatorCount(context.Context, string, []validator.Status) ([]ValidatorCount, error)
// 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

@@ -1,4 +1,4 @@
package beacon_api
package prysm_api
import (
"bytes"
@@ -10,26 +10,21 @@ import (
"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"
"github.com/prysmaticlabs/prysm/v5/validator/client/iface"
)
// NewPrysmChainClient returns implementation of iface.PrysmChainClient.
func NewPrysmChainClient(jsonRestHandler JsonRestHandler, nodeClient iface.NodeClient) iface.PrysmChainClient {
return prysmChainClient{
jsonRestHandler: jsonRestHandler,
nodeClient: nodeClient,
}
}
type prysmChainClient struct {
jsonRestHandler JsonRestHandler
nodeClient iface.NodeClient
jsonRestHandler client.JsonRestHandler
nodeClient node.Client
}
func (c prysmChainClient) ValidatorCount(ctx context.Context, stateID string, statuses []validator2.Status) ([]iface.ValidatorCount, error) {
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 {
@@ -37,7 +32,7 @@ func (c prysmChainClient) ValidatorCount(ctx context.Context, stateID string, st
}
if !strings.Contains(strings.ToLower(nodeVersion.Version), "prysm") {
return nil, iface.ErrNotSupported
return nil, client.ErrNotSupported
}
queryParams := neturl.Values{}
@@ -45,7 +40,7 @@ func (c prysmChainClient) ValidatorCount(ctx context.Context, stateID string, st
queryParams.Add("status", status.String())
}
queryUrl := buildURL(fmt.Sprintf("/eth/v1/beacon/states/%s/validator_count", stateID), queryParams)
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 {
@@ -60,14 +55,14 @@ func (c prysmChainClient) ValidatorCount(ctx context.Context, stateID string, st
return nil, errors.New("mismatch between validator count data and the number of statuses provided")
}
var resp []iface.ValidatorCount
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, iface.ValidatorCount{
resp = append(resp, beacon.ValidatorCount{
Status: vc.Status,
Count: count,
})
@@ -84,7 +79,7 @@ func (c prysmChainClient) ValidatorPerformance(ctx context.Context, in *ethpb.Va
}
if !strings.Contains(strings.ToLower(nodeVersion.Version), "prysm") {
return nil, iface.ErrNotSupported
return nil, client.ErrNotSupported
}
request, err := json.Marshal(structs.GetValidatorPerformanceRequest{

View File

@@ -1,4 +1,4 @@
package beacon_api
package prysm_api
import (
"bytes"
@@ -7,13 +7,14 @@ import (
"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"
)
@@ -27,7 +28,7 @@ func TestGetValidatorCount(t *testing.T) {
versionResponse structs.GetVersionResponse
validatorCountResponse structs.GetValidatorCountResponse
validatorCountCalled int
expectedResponse []iface.ValidatorCount
expectedResponse []beacon.ValidatorCount
expectedError string
}{
{
@@ -46,7 +47,7 @@ func TestGetValidatorCount(t *testing.T) {
},
},
validatorCountCalled: 1,
expectedResponse: []iface.ValidatorCount{
expectedResponse: []beacon.ValidatorCount{
{
Status: "active",
Count: 10,
@@ -145,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,
}
@@ -207,8 +208,8 @@ func Test_beaconApiBeaconChainClient_GetValidatorPerformance(t *testing.T) {
nil,
)
var client iface.PrysmChainClient = &prysmChainClient{
nodeClient: &beaconApiNodeClient{jsonRestHandler: jsonRestHandler},
var client Client = &prysmChainClient{
nodeClient: node.NewNodeClientWithFallback(jsonRestHandler, nil),
jsonRestHandler: jsonRestHandler,
}

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

@@ -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,35 +66,27 @@ 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",
@@ -106,9 +99,8 @@ go_test(
"propose_beacon_block_phase0_test.go",
"propose_beacon_block_test.go",
"propose_exit_test.go",
"prysm_beacon_chain_client_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",
@@ -121,29 +113,34 @@ go_test(
],
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),
}
}
@@ -81,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),
@@ -111,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),
}
@@ -126,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),
@@ -137,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
}
@@ -151,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),
},
}
@@ -183,8 +184,8 @@ func jsonifyAttestationElectra(attestation *ethpb.AttestationElectra) *structs.A
func jsonifySingleAttestation(attestation *ethpb.SingleAttestation) *structs.SingleAttestation {
return &structs.SingleAttestation{
CommitteeIndex: uint64ToString(attestation.CommitteeId),
AttesterIndex: uint64ToString(attestation.AttesterIndex),
CommitteeIndex: apiutil.Uint64ToString(attestation.CommitteeId),
AttesterIndex: apiutil.Uint64ToString(attestation.AttesterIndex),
Data: jsonifyAttestationData(attestation.Data),
Signature: hexutil.Encode(attestation.Signature),
}
@@ -193,7 +194,7 @@ func jsonifySingleAttestation(attestation *ethpb.SingleAttestation) *structs.Sin
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),
},
@@ -204,7 +205,7 @@ func jsonifySignedAggregateAndProof(signedAggregateAndProof *ethpb.SignedAggrega
func jsonifySignedAggregateAndProofElectra(signedAggregateAndProof *ethpb.SignedAggregateAttestationAndProofElectra) *structs.SignedAggregateAttestationAndProofElectra {
return &structs.SignedAggregateAttestationAndProofElectra{
Message: &structs.AggregateAttestationAndProofElectra{
AggregatorIndex: uint64ToString(signedAggregateAndProof.Message.AggregatorIndex),
AggregatorIndex: apiutil.Uint64ToString(signedAggregateAndProof.Message.AggregatorIndex),
Aggregate: jsonifyAttestationElectra(signedAggregateAndProof.Message.Aggregate),
SelectionProof: hexutil.Encode(signedAggregateAndProof.Message.SelectionProof),
},

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"

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"

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{}
@@ -221,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
}
@@ -234,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)
@@ -504,8 +504,8 @@ func TestGetBeaconBlock_ElectraValid(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
proto := testhelpers.GenerateProtoElectraBeaconBlockContents()
block := testhelpers.GenerateJsonElectraBeaconBlockContents()
proto := test_helpers.GenerateProtoElectraBeaconBlockContents()
block := test_helpers.GenerateJsonElectraBeaconBlockContents()
bytes, err := json.Marshal(block)
require.NoError(t, err)
@@ -549,8 +549,8 @@ func TestGetBeaconBlock_BlindedElectraValid(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
proto := testhelpers.GenerateProtoBlindedElectraBeaconBlock()
block := testhelpers.GenerateJsonBlindedElectraBeaconBlock()
proto := test_helpers.GenerateProtoBlindedElectraBeaconBlock()
block := test_helpers.GenerateJsonBlindedElectraBeaconBlock()
bytes, err := json.Marshal(block)
require.NoError(t, err)
@@ -594,8 +594,8 @@ 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)
@@ -645,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) {
@@ -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

@@ -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,34 +8,34 @@ import (
"net/http"
"testing"
"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/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"
"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"
)
func TestProposeAttestation(t *testing.T) {
attestation := &ethpb.Attestation{
AggregationBits: testhelpers.FillByteSlice(4, 74),
AggregationBits: test_helpers.FillByteSlice(4, 74),
Data: &ethpb.AttestationData{
Slot: 75,
CommitteeIndex: 76,
BeaconBlockRoot: testhelpers.FillByteSlice(32, 38),
BeaconBlockRoot: test_helpers.FillByteSlice(32, 38),
Source: &ethpb.Checkpoint{
Epoch: 78,
Root: testhelpers.FillByteSlice(32, 79),
Root: test_helpers.FillByteSlice(32, 79),
},
Target: &ethpb.Checkpoint{
Epoch: 80,
Root: testhelpers.FillByteSlice(32, 81),
Root: test_helpers.FillByteSlice(32, 81),
},
},
Signature: testhelpers.FillByteSlice(96, 82),
Signature: test_helpers.FillByteSlice(96, 82),
}
tests := []struct {
@@ -57,30 +57,30 @@ func TestProposeAttestation(t *testing.T) {
{
name: "nil attestation data",
attestation: &ethpb.Attestation{
AggregationBits: testhelpers.FillByteSlice(4, 74),
Signature: testhelpers.FillByteSlice(96, 82),
AggregationBits: test_helpers.FillByteSlice(4, 74),
Signature: test_helpers.FillByteSlice(96, 82),
},
expectedErrorMessage: "attestation is nil",
},
{
name: "nil source checkpoint",
attestation: &ethpb.Attestation{
AggregationBits: testhelpers.FillByteSlice(4, 74),
AggregationBits: test_helpers.FillByteSlice(4, 74),
Data: &ethpb.AttestationData{
Target: &ethpb.Checkpoint{},
},
Signature: testhelpers.FillByteSlice(96, 82),
Signature: test_helpers.FillByteSlice(96, 82),
},
expectedErrorMessage: "attestation's source can't be nil",
},
{
name: "nil target checkpoint",
attestation: &ethpb.Attestation{
AggregationBits: testhelpers.FillByteSlice(4, 74),
AggregationBits: test_helpers.FillByteSlice(4, 74),
Data: &ethpb.AttestationData{
Source: &ethpb.Checkpoint{},
},
Signature: testhelpers.FillByteSlice(96, 82),
Signature: test_helpers.FillByteSlice(96, 82),
},
expectedErrorMessage: "attestation's target can't be nil",
},
@@ -91,7 +91,7 @@ func TestProposeAttestation(t *testing.T) {
Source: &ethpb.Checkpoint{},
Target: &ethpb.Checkpoint{},
},
Signature: testhelpers.FillByteSlice(96, 82),
Signature: test_helpers.FillByteSlice(96, 82),
},
expectedErrorMessage: "attestation's bitfield can't be nil",
},
@@ -150,21 +150,21 @@ func TestProposeAttestation(t *testing.T) {
func TestProposeAttestationFallBack(t *testing.T) {
attestation := &ethpb.Attestation{
AggregationBits: testhelpers.FillByteSlice(4, 74),
AggregationBits: test_helpers.FillByteSlice(4, 74),
Data: &ethpb.AttestationData{
Slot: 75,
CommitteeIndex: 76,
BeaconBlockRoot: testhelpers.FillByteSlice(32, 38),
BeaconBlockRoot: test_helpers.FillByteSlice(32, 38),
Source: &ethpb.Checkpoint{
Epoch: 78,
Root: testhelpers.FillByteSlice(32, 79),
Root: test_helpers.FillByteSlice(32, 79),
},
Target: &ethpb.Checkpoint{
Epoch: 80,
Root: testhelpers.FillByteSlice(32, 81),
Root: test_helpers.FillByteSlice(32, 81),
},
},
Signature: testhelpers.FillByteSlice(96, 82),
Signature: test_helpers.FillByteSlice(96, 82),
}
ctrl := gomock.NewController(t)
@@ -220,17 +220,17 @@ func TestProposeAttestationElectra(t *testing.T) {
Data: &ethpb.AttestationData{
Slot: 75,
CommitteeIndex: 76,
BeaconBlockRoot: testhelpers.FillByteSlice(32, 38),
BeaconBlockRoot: test_helpers.FillByteSlice(32, 38),
Source: &ethpb.Checkpoint{
Epoch: 78,
Root: testhelpers.FillByteSlice(32, 79),
Root: test_helpers.FillByteSlice(32, 79),
},
Target: &ethpb.Checkpoint{
Epoch: 80,
Root: testhelpers.FillByteSlice(32, 81),
Root: test_helpers.FillByteSlice(32, 81),
},
},
Signature: testhelpers.FillByteSlice(96, 82),
Signature: test_helpers.FillByteSlice(96, 82),
CommitteeId: 83,
}
@@ -254,7 +254,7 @@ func TestProposeAttestationElectra(t *testing.T) {
name: "nil attestation data",
attestation: &ethpb.SingleAttestation{
AttesterIndex: 74,
Signature: testhelpers.FillByteSlice(96, 82),
Signature: test_helpers.FillByteSlice(96, 82),
CommitteeId: 83,
},
expectedErrorMessage: "attestation is nil",
@@ -266,7 +266,7 @@ func TestProposeAttestationElectra(t *testing.T) {
Data: &ethpb.AttestationData{
Target: &ethpb.Checkpoint{},
},
Signature: testhelpers.FillByteSlice(96, 82),
Signature: test_helpers.FillByteSlice(96, 82),
CommitteeId: 83,
},
expectedErrorMessage: "attestation's source can't be nil",
@@ -278,7 +278,7 @@ func TestProposeAttestationElectra(t *testing.T) {
Data: &ethpb.AttestationData{
Source: &ethpb.Checkpoint{},
},
Signature: testhelpers.FillByteSlice(96, 82),
Signature: test_helpers.FillByteSlice(96, 82),
CommitteeId: 83,
},
expectedErrorMessage: "attestation's target can't be nil",

View File

@@ -1,4 +1,4 @@
package beacon_api
package validator_api
import (
"bytes"
@@ -8,6 +8,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/encoding/bytesutil"
"github.com/prysmaticlabs/prysm/v5/network/httputil"
@@ -221,8 +222,8 @@ func marshallBeaconBlockPhase0(block *ethpb.SignedBeaconBlock) ([]byte, error) {
VoluntaryExits: JsonifySignedVoluntaryExits(block.Block.Body.VoluntaryExits),
},
ParentRoot: hexutil.Encode(block.Block.ParentRoot),
ProposerIndex: uint64ToString(block.Block.ProposerIndex),
Slot: uint64ToString(block.Block.Slot),
ProposerIndex: apiutil.Uint64ToString(block.Block.ProposerIndex),
Slot: apiutil.Uint64ToString(block.Block.Slot),
StateRoot: hexutil.Encode(block.Block.StateRoot),
},
}
@@ -235,8 +236,8 @@ func marshallBeaconBlockAltair(block *ethpb.SignedBeaconBlockAltair) ([]byte, er
Signature: hexutil.Encode(block.Signature),
Message: &structs.BeaconBlockAltair{
ParentRoot: hexutil.Encode(block.Block.ParentRoot),
ProposerIndex: uint64ToString(block.Block.ProposerIndex),
Slot: uint64ToString(block.Block.Slot),
ProposerIndex: apiutil.Uint64ToString(block.Block.ProposerIndex),
Slot: apiutil.Uint64ToString(block.Block.Slot),
StateRoot: hexutil.Encode(block.Block.StateRoot),
Body: &structs.BeaconBlockBodyAltair{
Attestations: jsonifyAttestations(block.Block.Body.Attestations),
@@ -263,8 +264,8 @@ func marshallBeaconBlockBellatrix(block *ethpb.SignedBeaconBlockBellatrix) ([]by
Signature: hexutil.Encode(block.Signature),
Message: &structs.BeaconBlockBellatrix{
ParentRoot: hexutil.Encode(block.Block.ParentRoot),
ProposerIndex: uint64ToString(block.Block.ProposerIndex),
Slot: uint64ToString(block.Block.Slot),
ProposerIndex: apiutil.Uint64ToString(block.Block.ProposerIndex),
Slot: apiutil.Uint64ToString(block.Block.Slot),
StateRoot: hexutil.Encode(block.Block.StateRoot),
Body: &structs.BeaconBlockBodyBellatrix{
Attestations: jsonifyAttestations(block.Block.Body.Attestations),
@@ -286,10 +287,10 @@ func marshallBeaconBlockBellatrix(block *ethpb.SignedBeaconBlockBellatrix) ([]by
ReceiptsRoot: hexutil.Encode(block.Block.Body.ExecutionPayload.ReceiptsRoot),
LogsBloom: hexutil.Encode(block.Block.Body.ExecutionPayload.LogsBloom),
PrevRandao: hexutil.Encode(block.Block.Body.ExecutionPayload.PrevRandao),
BlockNumber: uint64ToString(block.Block.Body.ExecutionPayload.BlockNumber),
GasLimit: uint64ToString(block.Block.Body.ExecutionPayload.GasLimit),
GasUsed: uint64ToString(block.Block.Body.ExecutionPayload.GasUsed),
Timestamp: uint64ToString(block.Block.Body.ExecutionPayload.Timestamp),
BlockNumber: apiutil.Uint64ToString(block.Block.Body.ExecutionPayload.BlockNumber),
GasLimit: apiutil.Uint64ToString(block.Block.Body.ExecutionPayload.GasLimit),
GasUsed: apiutil.Uint64ToString(block.Block.Body.ExecutionPayload.GasUsed),
Timestamp: apiutil.Uint64ToString(block.Block.Body.ExecutionPayload.Timestamp),
ExtraData: hexutil.Encode(block.Block.Body.ExecutionPayload.ExtraData),
BaseFeePerGas: bytesutil.LittleEndianBytesToBigInt(block.Block.Body.ExecutionPayload.BaseFeePerGas).String(),
BlockHash: hexutil.Encode(block.Block.Body.ExecutionPayload.BlockHash),
@@ -307,8 +308,8 @@ func marshallBeaconBlockBlindedBellatrix(block *ethpb.SignedBlindedBeaconBlockBe
Signature: hexutil.Encode(block.Signature),
Message: &structs.BlindedBeaconBlockBellatrix{
ParentRoot: hexutil.Encode(block.Block.ParentRoot),
ProposerIndex: uint64ToString(block.Block.ProposerIndex),
Slot: uint64ToString(block.Block.Slot),
ProposerIndex: apiutil.Uint64ToString(block.Block.ProposerIndex),
Slot: apiutil.Uint64ToString(block.Block.Slot),
StateRoot: hexutil.Encode(block.Block.StateRoot),
Body: &structs.BlindedBeaconBlockBodyBellatrix{
Attestations: jsonifyAttestations(block.Block.Body.Attestations),
@@ -330,10 +331,10 @@ func marshallBeaconBlockBlindedBellatrix(block *ethpb.SignedBlindedBeaconBlockBe
ReceiptsRoot: hexutil.Encode(block.Block.Body.ExecutionPayloadHeader.ReceiptsRoot),
LogsBloom: hexutil.Encode(block.Block.Body.ExecutionPayloadHeader.LogsBloom),
PrevRandao: hexutil.Encode(block.Block.Body.ExecutionPayloadHeader.PrevRandao),
BlockNumber: uint64ToString(block.Block.Body.ExecutionPayloadHeader.BlockNumber),
GasLimit: uint64ToString(block.Block.Body.ExecutionPayloadHeader.GasLimit),
GasUsed: uint64ToString(block.Block.Body.ExecutionPayloadHeader.GasUsed),
Timestamp: uint64ToString(block.Block.Body.ExecutionPayloadHeader.Timestamp),
BlockNumber: apiutil.Uint64ToString(block.Block.Body.ExecutionPayloadHeader.BlockNumber),
GasLimit: apiutil.Uint64ToString(block.Block.Body.ExecutionPayloadHeader.GasLimit),
GasUsed: apiutil.Uint64ToString(block.Block.Body.ExecutionPayloadHeader.GasUsed),
Timestamp: apiutil.Uint64ToString(block.Block.Body.ExecutionPayloadHeader.Timestamp),
ExtraData: hexutil.Encode(block.Block.Body.ExecutionPayloadHeader.ExtraData),
BaseFeePerGas: bytesutil.LittleEndianBytesToBigInt(block.Block.Body.ExecutionPayloadHeader.BaseFeePerGas).String(),
BlockHash: hexutil.Encode(block.Block.Body.ExecutionPayloadHeader.BlockHash),
@@ -351,8 +352,8 @@ func marshallBeaconBlockCapella(block *ethpb.SignedBeaconBlockCapella) ([]byte,
Signature: hexutil.Encode(block.Signature),
Message: &structs.BeaconBlockCapella{
ParentRoot: hexutil.Encode(block.Block.ParentRoot),
ProposerIndex: uint64ToString(block.Block.ProposerIndex),
Slot: uint64ToString(block.Block.Slot),
ProposerIndex: apiutil.Uint64ToString(block.Block.ProposerIndex),
Slot: apiutil.Uint64ToString(block.Block.Slot),
StateRoot: hexutil.Encode(block.Block.StateRoot),
Body: &structs.BeaconBlockBodyCapella{
Attestations: jsonifyAttestations(block.Block.Body.Attestations),
@@ -374,10 +375,10 @@ func marshallBeaconBlockCapella(block *ethpb.SignedBeaconBlockCapella) ([]byte,
ReceiptsRoot: hexutil.Encode(block.Block.Body.ExecutionPayload.ReceiptsRoot),
LogsBloom: hexutil.Encode(block.Block.Body.ExecutionPayload.LogsBloom),
PrevRandao: hexutil.Encode(block.Block.Body.ExecutionPayload.PrevRandao),
BlockNumber: uint64ToString(block.Block.Body.ExecutionPayload.BlockNumber),
GasLimit: uint64ToString(block.Block.Body.ExecutionPayload.GasLimit),
GasUsed: uint64ToString(block.Block.Body.ExecutionPayload.GasUsed),
Timestamp: uint64ToString(block.Block.Body.ExecutionPayload.Timestamp),
BlockNumber: apiutil.Uint64ToString(block.Block.Body.ExecutionPayload.BlockNumber),
GasLimit: apiutil.Uint64ToString(block.Block.Body.ExecutionPayload.GasLimit),
GasUsed: apiutil.Uint64ToString(block.Block.Body.ExecutionPayload.GasUsed),
Timestamp: apiutil.Uint64ToString(block.Block.Body.ExecutionPayload.Timestamp),
ExtraData: hexutil.Encode(block.Block.Body.ExecutionPayload.ExtraData),
BaseFeePerGas: bytesutil.LittleEndianBytesToBigInt(block.Block.Body.ExecutionPayload.BaseFeePerGas).String(),
BlockHash: hexutil.Encode(block.Block.Body.ExecutionPayload.BlockHash),
@@ -397,8 +398,8 @@ func marshallBeaconBlockBlindedCapella(block *ethpb.SignedBlindedBeaconBlockCape
Signature: hexutil.Encode(block.Signature),
Message: &structs.BlindedBeaconBlockCapella{
ParentRoot: hexutil.Encode(block.Block.ParentRoot),
ProposerIndex: uint64ToString(block.Block.ProposerIndex),
Slot: uint64ToString(block.Block.Slot),
ProposerIndex: apiutil.Uint64ToString(block.Block.ProposerIndex),
Slot: apiutil.Uint64ToString(block.Block.Slot),
StateRoot: hexutil.Encode(block.Block.StateRoot),
Body: &structs.BlindedBeaconBlockBodyCapella{
Attestations: jsonifyAttestations(block.Block.Body.Attestations),
@@ -420,10 +421,10 @@ func marshallBeaconBlockBlindedCapella(block *ethpb.SignedBlindedBeaconBlockCape
ReceiptsRoot: hexutil.Encode(block.Block.Body.ExecutionPayloadHeader.ReceiptsRoot),
LogsBloom: hexutil.Encode(block.Block.Body.ExecutionPayloadHeader.LogsBloom),
PrevRandao: hexutil.Encode(block.Block.Body.ExecutionPayloadHeader.PrevRandao),
BlockNumber: uint64ToString(block.Block.Body.ExecutionPayloadHeader.BlockNumber),
GasLimit: uint64ToString(block.Block.Body.ExecutionPayloadHeader.GasLimit),
GasUsed: uint64ToString(block.Block.Body.ExecutionPayloadHeader.GasUsed),
Timestamp: uint64ToString(block.Block.Body.ExecutionPayloadHeader.Timestamp),
BlockNumber: apiutil.Uint64ToString(block.Block.Body.ExecutionPayloadHeader.BlockNumber),
GasLimit: apiutil.Uint64ToString(block.Block.Body.ExecutionPayloadHeader.GasLimit),
GasUsed: apiutil.Uint64ToString(block.Block.Body.ExecutionPayloadHeader.GasUsed),
Timestamp: apiutil.Uint64ToString(block.Block.Body.ExecutionPayloadHeader.Timestamp),
ExtraData: hexutil.Encode(block.Block.Body.ExecutionPayloadHeader.ExtraData),
BaseFeePerGas: bytesutil.LittleEndianBytesToBigInt(block.Block.Body.ExecutionPayloadHeader.BaseFeePerGas).String(),
BlockHash: hexutil.Encode(block.Block.Body.ExecutionPayloadHeader.BlockHash),

View File

@@ -1,4 +1,4 @@
package beacon_api
package validator_api
import (
"bytes"
@@ -7,12 +7,13 @@ import (
"testing"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/prysmaticlabs/prysm/v5/api/apiutil"
"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"
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"
)
@@ -30,8 +31,8 @@ func TestProposeBeaconBlock_Altair(t *testing.T) {
Signature: hexutil.Encode(altairBlock.Altair.Signature),
Message: &structs.BeaconBlockAltair{
ParentRoot: hexutil.Encode(altairBlock.Altair.Block.ParentRoot),
ProposerIndex: uint64ToString(altairBlock.Altair.Block.ProposerIndex),
Slot: uint64ToString(altairBlock.Altair.Block.Slot),
ProposerIndex: apiutil.Uint64ToString(altairBlock.Altair.Block.ProposerIndex),
Slot: apiutil.Uint64ToString(altairBlock.Altair.Block.Slot),
StateRoot: hexutil.Encode(altairBlock.Altair.Block.StateRoot),
Body: &structs.BeaconBlockBodyAltair{
Attestations: jsonifyAttestations(altairBlock.Altair.Block.Body.Attestations),
@@ -80,8 +81,8 @@ func TestProposeBeaconBlock_Altair(t *testing.T) {
func generateSignedAltairBlock() *ethpb.GenericSignedBeaconBlock_Altair {
return &ethpb.GenericSignedBeaconBlock_Altair{
Altair: &ethpb.SignedBeaconBlockAltair{
Block: testhelpers.GenerateProtoAltairBeaconBlock(),
Signature: testhelpers.FillByteSlice(96, 112),
Block: test_helpers.GenerateProtoAltairBeaconBlock(),
Signature: test_helpers.FillByteSlice(96, 112),
},
}
}

View File

@@ -1,4 +1,4 @@
package beacon_api
package validator_api
import (
"bytes"
@@ -7,14 +7,15 @@ import (
"testing"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/prysmaticlabs/prysm/v5/api/apiutil"
"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/encoding/bytesutil"
enginev1 "github.com/prysmaticlabs/prysm/v5/proto/engine/v1"
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v5/testing/assert"
"github.com/prysmaticlabs/prysm/v5/testing/require"
"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"
)
@@ -32,8 +33,8 @@ func TestProposeBeaconBlock_BlindedBellatrix(t *testing.T) {
Signature: hexutil.Encode(blindedBellatrixBlock.BlindedBellatrix.Signature),
Message: &structs.BlindedBeaconBlockBellatrix{
ParentRoot: hexutil.Encode(blindedBellatrixBlock.BlindedBellatrix.Block.ParentRoot),
ProposerIndex: uint64ToString(blindedBellatrixBlock.BlindedBellatrix.Block.ProposerIndex),
Slot: uint64ToString(blindedBellatrixBlock.BlindedBellatrix.Block.Slot),
ProposerIndex: apiutil.Uint64ToString(blindedBellatrixBlock.BlindedBellatrix.Block.ProposerIndex),
Slot: apiutil.Uint64ToString(blindedBellatrixBlock.BlindedBellatrix.Block.Slot),
StateRoot: hexutil.Encode(blindedBellatrixBlock.BlindedBellatrix.Block.StateRoot),
Body: &structs.BlindedBeaconBlockBodyBellatrix{
Attestations: jsonifyAttestations(blindedBellatrixBlock.BlindedBellatrix.Block.Body.Attestations),
@@ -51,17 +52,17 @@ func TestProposeBeaconBlock_BlindedBellatrix(t *testing.T) {
ExecutionPayloadHeader: &structs.ExecutionPayloadHeader{
BaseFeePerGas: bytesutil.LittleEndianBytesToBigInt(blindedBellatrixBlock.BlindedBellatrix.Block.Body.ExecutionPayloadHeader.BaseFeePerGas).String(),
BlockHash: hexutil.Encode(blindedBellatrixBlock.BlindedBellatrix.Block.Body.ExecutionPayloadHeader.BlockHash),
BlockNumber: uint64ToString(blindedBellatrixBlock.BlindedBellatrix.Block.Body.ExecutionPayloadHeader.BlockNumber),
BlockNumber: apiutil.Uint64ToString(blindedBellatrixBlock.BlindedBellatrix.Block.Body.ExecutionPayloadHeader.BlockNumber),
ExtraData: hexutil.Encode(blindedBellatrixBlock.BlindedBellatrix.Block.Body.ExecutionPayloadHeader.ExtraData),
FeeRecipient: hexutil.Encode(blindedBellatrixBlock.BlindedBellatrix.Block.Body.ExecutionPayloadHeader.FeeRecipient),
GasLimit: uint64ToString(blindedBellatrixBlock.BlindedBellatrix.Block.Body.ExecutionPayloadHeader.GasLimit),
GasUsed: uint64ToString(blindedBellatrixBlock.BlindedBellatrix.Block.Body.ExecutionPayloadHeader.GasUsed),
GasLimit: apiutil.Uint64ToString(blindedBellatrixBlock.BlindedBellatrix.Block.Body.ExecutionPayloadHeader.GasLimit),
GasUsed: apiutil.Uint64ToString(blindedBellatrixBlock.BlindedBellatrix.Block.Body.ExecutionPayloadHeader.GasUsed),
LogsBloom: hexutil.Encode(blindedBellatrixBlock.BlindedBellatrix.Block.Body.ExecutionPayloadHeader.LogsBloom),
ParentHash: hexutil.Encode(blindedBellatrixBlock.BlindedBellatrix.Block.Body.ExecutionPayloadHeader.ParentHash),
PrevRandao: hexutil.Encode(blindedBellatrixBlock.BlindedBellatrix.Block.Body.ExecutionPayloadHeader.PrevRandao),
ReceiptsRoot: hexutil.Encode(blindedBellatrixBlock.BlindedBellatrix.Block.Body.ExecutionPayloadHeader.ReceiptsRoot),
StateRoot: hexutil.Encode(blindedBellatrixBlock.BlindedBellatrix.Block.Body.ExecutionPayloadHeader.StateRoot),
Timestamp: uint64ToString(blindedBellatrixBlock.BlindedBellatrix.Block.Body.ExecutionPayloadHeader.Timestamp),
Timestamp: apiutil.Uint64ToString(blindedBellatrixBlock.BlindedBellatrix.Block.Body.ExecutionPayloadHeader.Timestamp),
TransactionsRoot: hexutil.Encode(blindedBellatrixBlock.BlindedBellatrix.Block.Body.ExecutionPayloadHeader.TransactionsRoot),
},
},
@@ -101,37 +102,37 @@ func generateSignedBlindedBellatrixBlock() *ethpb.GenericSignedBeaconBlock_Blind
Block: &ethpb.BlindedBeaconBlockBellatrix{
Slot: 1,
ProposerIndex: 2,
ParentRoot: testhelpers.FillByteSlice(32, 3),
StateRoot: testhelpers.FillByteSlice(32, 4),
ParentRoot: test_helpers.FillByteSlice(32, 3),
StateRoot: test_helpers.FillByteSlice(32, 4),
Body: &ethpb.BlindedBeaconBlockBodyBellatrix{
RandaoReveal: testhelpers.FillByteSlice(96, 5),
RandaoReveal: test_helpers.FillByteSlice(96, 5),
Eth1Data: &ethpb.Eth1Data{
DepositRoot: testhelpers.FillByteSlice(32, 6),
DepositRoot: test_helpers.FillByteSlice(32, 6),
DepositCount: 7,
BlockHash: testhelpers.FillByteSlice(32, 8),
BlockHash: test_helpers.FillByteSlice(32, 8),
},
Graffiti: testhelpers.FillByteSlice(32, 9),
Graffiti: test_helpers.FillByteSlice(32, 9),
ProposerSlashings: []*ethpb.ProposerSlashing{
{
Header_1: &ethpb.SignedBeaconBlockHeader{
Header: &ethpb.BeaconBlockHeader{
Slot: 10,
ProposerIndex: 11,
ParentRoot: testhelpers.FillByteSlice(32, 12),
StateRoot: testhelpers.FillByteSlice(32, 13),
BodyRoot: testhelpers.FillByteSlice(32, 14),
ParentRoot: test_helpers.FillByteSlice(32, 12),
StateRoot: test_helpers.FillByteSlice(32, 13),
BodyRoot: test_helpers.FillByteSlice(32, 14),
},
Signature: testhelpers.FillByteSlice(96, 15),
Signature: test_helpers.FillByteSlice(96, 15),
},
Header_2: &ethpb.SignedBeaconBlockHeader{
Header: &ethpb.BeaconBlockHeader{
Slot: 16,
ProposerIndex: 17,
ParentRoot: testhelpers.FillByteSlice(32, 18),
StateRoot: testhelpers.FillByteSlice(32, 19),
BodyRoot: testhelpers.FillByteSlice(32, 20),
ParentRoot: test_helpers.FillByteSlice(32, 18),
StateRoot: test_helpers.FillByteSlice(32, 19),
BodyRoot: test_helpers.FillByteSlice(32, 20),
},
Signature: testhelpers.FillByteSlice(96, 21),
Signature: test_helpers.FillByteSlice(96, 21),
},
},
{
@@ -139,21 +140,21 @@ func generateSignedBlindedBellatrixBlock() *ethpb.GenericSignedBeaconBlock_Blind
Header: &ethpb.BeaconBlockHeader{
Slot: 22,
ProposerIndex: 23,
ParentRoot: testhelpers.FillByteSlice(32, 24),
StateRoot: testhelpers.FillByteSlice(32, 25),
BodyRoot: testhelpers.FillByteSlice(32, 26),
ParentRoot: test_helpers.FillByteSlice(32, 24),
StateRoot: test_helpers.FillByteSlice(32, 25),
BodyRoot: test_helpers.FillByteSlice(32, 26),
},
Signature: testhelpers.FillByteSlice(96, 27),
Signature: test_helpers.FillByteSlice(96, 27),
},
Header_2: &ethpb.SignedBeaconBlockHeader{
Header: &ethpb.BeaconBlockHeader{
Slot: 28,
ProposerIndex: 29,
ParentRoot: testhelpers.FillByteSlice(32, 30),
StateRoot: testhelpers.FillByteSlice(32, 31),
BodyRoot: testhelpers.FillByteSlice(32, 32),
ParentRoot: test_helpers.FillByteSlice(32, 30),
StateRoot: test_helpers.FillByteSlice(32, 31),
BodyRoot: test_helpers.FillByteSlice(32, 32),
},
Signature: testhelpers.FillByteSlice(96, 33),
Signature: test_helpers.FillByteSlice(96, 33),
},
},
},
@@ -164,34 +165,34 @@ func generateSignedBlindedBellatrixBlock() *ethpb.GenericSignedBeaconBlock_Blind
Data: &ethpb.AttestationData{
Slot: 36,
CommitteeIndex: 37,
BeaconBlockRoot: testhelpers.FillByteSlice(32, 38),
BeaconBlockRoot: test_helpers.FillByteSlice(32, 38),
Source: &ethpb.Checkpoint{
Epoch: 39,
Root: testhelpers.FillByteSlice(32, 40),
Root: test_helpers.FillByteSlice(32, 40),
},
Target: &ethpb.Checkpoint{
Epoch: 41,
Root: testhelpers.FillByteSlice(32, 42),
Root: test_helpers.FillByteSlice(32, 42),
},
},
Signature: testhelpers.FillByteSlice(96, 43),
Signature: test_helpers.FillByteSlice(96, 43),
},
Attestation_2: &ethpb.IndexedAttestation{
AttestingIndices: []uint64{44, 45},
Data: &ethpb.AttestationData{
Slot: 46,
CommitteeIndex: 47,
BeaconBlockRoot: testhelpers.FillByteSlice(32, 38),
BeaconBlockRoot: test_helpers.FillByteSlice(32, 38),
Source: &ethpb.Checkpoint{
Epoch: 49,
Root: testhelpers.FillByteSlice(32, 50),
Root: test_helpers.FillByteSlice(32, 50),
},
Target: &ethpb.Checkpoint{
Epoch: 51,
Root: testhelpers.FillByteSlice(32, 52),
Root: test_helpers.FillByteSlice(32, 52),
},
},
Signature: testhelpers.FillByteSlice(96, 53),
Signature: test_helpers.FillByteSlice(96, 53),
},
},
{
@@ -200,90 +201,90 @@ func generateSignedBlindedBellatrixBlock() *ethpb.GenericSignedBeaconBlock_Blind
Data: &ethpb.AttestationData{
Slot: 56,
CommitteeIndex: 57,
BeaconBlockRoot: testhelpers.FillByteSlice(32, 38),
BeaconBlockRoot: test_helpers.FillByteSlice(32, 38),
Source: &ethpb.Checkpoint{
Epoch: 59,
Root: testhelpers.FillByteSlice(32, 60),
Root: test_helpers.FillByteSlice(32, 60),
},
Target: &ethpb.Checkpoint{
Epoch: 61,
Root: testhelpers.FillByteSlice(32, 62),
Root: test_helpers.FillByteSlice(32, 62),
},
},
Signature: testhelpers.FillByteSlice(96, 63),
Signature: test_helpers.FillByteSlice(96, 63),
},
Attestation_2: &ethpb.IndexedAttestation{
AttestingIndices: []uint64{64, 65},
Data: &ethpb.AttestationData{
Slot: 66,
CommitteeIndex: 67,
BeaconBlockRoot: testhelpers.FillByteSlice(32, 38),
BeaconBlockRoot: test_helpers.FillByteSlice(32, 38),
Source: &ethpb.Checkpoint{
Epoch: 69,
Root: testhelpers.FillByteSlice(32, 70),
Root: test_helpers.FillByteSlice(32, 70),
},
Target: &ethpb.Checkpoint{
Epoch: 71,
Root: testhelpers.FillByteSlice(32, 72),
Root: test_helpers.FillByteSlice(32, 72),
},
},
Signature: testhelpers.FillByteSlice(96, 73),
Signature: test_helpers.FillByteSlice(96, 73),
},
},
},
Attestations: []*ethpb.Attestation{
{
AggregationBits: testhelpers.FillByteSlice(4, 74),
AggregationBits: test_helpers.FillByteSlice(4, 74),
Data: &ethpb.AttestationData{
Slot: 75,
CommitteeIndex: 76,
BeaconBlockRoot: testhelpers.FillByteSlice(32, 38),
BeaconBlockRoot: test_helpers.FillByteSlice(32, 38),
Source: &ethpb.Checkpoint{
Epoch: 78,
Root: testhelpers.FillByteSlice(32, 79),
Root: test_helpers.FillByteSlice(32, 79),
},
Target: &ethpb.Checkpoint{
Epoch: 80,
Root: testhelpers.FillByteSlice(32, 81),
Root: test_helpers.FillByteSlice(32, 81),
},
},
Signature: testhelpers.FillByteSlice(96, 82),
Signature: test_helpers.FillByteSlice(96, 82),
},
{
AggregationBits: testhelpers.FillByteSlice(4, 83),
AggregationBits: test_helpers.FillByteSlice(4, 83),
Data: &ethpb.AttestationData{
Slot: 84,
CommitteeIndex: 85,
BeaconBlockRoot: testhelpers.FillByteSlice(32, 38),
BeaconBlockRoot: test_helpers.FillByteSlice(32, 38),
Source: &ethpb.Checkpoint{
Epoch: 87,
Root: testhelpers.FillByteSlice(32, 88),
Root: test_helpers.FillByteSlice(32, 88),
},
Target: &ethpb.Checkpoint{
Epoch: 89,
Root: testhelpers.FillByteSlice(32, 90),
Root: test_helpers.FillByteSlice(32, 90),
},
},
Signature: testhelpers.FillByteSlice(96, 91),
Signature: test_helpers.FillByteSlice(96, 91),
},
},
Deposits: []*ethpb.Deposit{
{
Proof: testhelpers.FillByteArraySlice(33, testhelpers.FillByteSlice(32, 92)),
Proof: test_helpers.FillByteArraySlice(33, test_helpers.FillByteSlice(32, 92)),
Data: &ethpb.Deposit_Data{
PublicKey: testhelpers.FillByteSlice(48, 94),
WithdrawalCredentials: testhelpers.FillByteSlice(32, 95),
PublicKey: test_helpers.FillByteSlice(48, 94),
WithdrawalCredentials: test_helpers.FillByteSlice(32, 95),
Amount: 96,
Signature: testhelpers.FillByteSlice(96, 97),
Signature: test_helpers.FillByteSlice(96, 97),
},
},
{
Proof: testhelpers.FillByteArraySlice(33, testhelpers.FillByteSlice(32, 98)),
Proof: test_helpers.FillByteArraySlice(33, test_helpers.FillByteSlice(32, 98)),
Data: &ethpb.Deposit_Data{
PublicKey: testhelpers.FillByteSlice(48, 100),
WithdrawalCredentials: testhelpers.FillByteSlice(32, 101),
PublicKey: test_helpers.FillByteSlice(48, 100),
WithdrawalCredentials: test_helpers.FillByteSlice(32, 101),
Amount: 102,
Signature: testhelpers.FillByteSlice(96, 103),
Signature: test_helpers.FillByteSlice(96, 103),
},
},
},
@@ -293,39 +294,48 @@ func generateSignedBlindedBellatrixBlock() *ethpb.GenericSignedBeaconBlock_Blind
Epoch: 104,
ValidatorIndex: 105,
},
Signature: testhelpers.FillByteSlice(96, 106),
Signature: test_helpers.FillByteSlice(96, 106),
},
{
Exit: &ethpb.VoluntaryExit{
Epoch: 107,
ValidatorIndex: 108,
},
Signature: testhelpers.FillByteSlice(96, 109),
Signature: test_helpers.FillByteSlice(96, 109),
},
},
SyncAggregate: &ethpb.SyncAggregate{
SyncCommitteeBits: testhelpers.FillByteSlice(64, 110),
SyncCommitteeSignature: testhelpers.FillByteSlice(96, 111),
SyncCommitteeBits: test_helpers.FillByteSlice(64, 110),
SyncCommitteeSignature: test_helpers.FillByteSlice(96, 111),
},
ExecutionPayloadHeader: &enginev1.ExecutionPayloadHeader{
ParentHash: testhelpers.FillByteSlice(32, 112),
FeeRecipient: testhelpers.FillByteSlice(20, 113),
StateRoot: testhelpers.FillByteSlice(32, 114),
ReceiptsRoot: testhelpers.FillByteSlice(32, 115),
LogsBloom: testhelpers.FillByteSlice(256, 116),
PrevRandao: testhelpers.FillByteSlice(32, 117),
ParentHash: test_helpers.FillByteSlice(32, 112),
FeeRecipient: test_helpers.FillByteSlice(20, 113),
StateRoot: test_helpers.FillByteSlice(32, 114),
ReceiptsRoot: test_helpers.FillByteSlice(32, 115),
LogsBloom: test_helpers.FillByteSlice(256, 116),
PrevRandao: test_helpers.FillByteSlice(32, 117),
BlockNumber: 118,
GasLimit: 119,
GasUsed: 120,
Timestamp: 121,
ExtraData: testhelpers.FillByteSlice(32, 122),
BaseFeePerGas: testhelpers.FillByteSlice(32, 123),
BlockHash: testhelpers.FillByteSlice(32, 124),
TransactionsRoot: testhelpers.FillByteSlice(32, 125),
ExtraData: test_helpers.FillByteSlice(32, 122),
BaseFeePerGas: test_helpers.FillByteSlice(32, 123),
BlockHash: test_helpers.FillByteSlice(32, 124),
TransactionsRoot: test_helpers.FillByteSlice(32, 125),
},
},
},
Signature: testhelpers.FillByteSlice(96, 126),
Signature: test_helpers.FillByteSlice(96, 126),
},
}
}
func generateSignedBellatrixBlock() *ethpb.GenericSignedBeaconBlock_Bellatrix {
return &ethpb.GenericSignedBeaconBlock_Bellatrix{
Bellatrix: &ethpb.SignedBeaconBlockBellatrix{
Block: test_helpers.GenerateProtoBellatrixBeaconBlock(),
Signature: test_helpers.FillByteSlice(96, 127),
},
}
}

View File

@@ -1,4 +1,4 @@
package beacon_api
package validator_api
import (
"bytes"
@@ -7,14 +7,15 @@ import (
"testing"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/prysmaticlabs/prysm/v5/api/apiutil"
"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/encoding/bytesutil"
enginev1 "github.com/prysmaticlabs/prysm/v5/proto/engine/v1"
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v5/testing/assert"
"github.com/prysmaticlabs/prysm/v5/testing/require"
"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"
)
@@ -32,8 +33,8 @@ func TestProposeBeaconBlock_BlindedCapella(t *testing.T) {
Signature: hexutil.Encode(blindedCapellaBlock.BlindedCapella.Signature),
Message: &structs.BlindedBeaconBlockCapella{
ParentRoot: hexutil.Encode(blindedCapellaBlock.BlindedCapella.Block.ParentRoot),
ProposerIndex: uint64ToString(blindedCapellaBlock.BlindedCapella.Block.ProposerIndex),
Slot: uint64ToString(blindedCapellaBlock.BlindedCapella.Block.Slot),
ProposerIndex: apiutil.Uint64ToString(blindedCapellaBlock.BlindedCapella.Block.ProposerIndex),
Slot: apiutil.Uint64ToString(blindedCapellaBlock.BlindedCapella.Block.Slot),
StateRoot: hexutil.Encode(blindedCapellaBlock.BlindedCapella.Block.StateRoot),
Body: &structs.BlindedBeaconBlockBodyCapella{
Attestations: jsonifyAttestations(blindedCapellaBlock.BlindedCapella.Block.Body.Attestations),
@@ -51,17 +52,17 @@ func TestProposeBeaconBlock_BlindedCapella(t *testing.T) {
ExecutionPayloadHeader: &structs.ExecutionPayloadHeaderCapella{
BaseFeePerGas: bytesutil.LittleEndianBytesToBigInt(blindedCapellaBlock.BlindedCapella.Block.Body.ExecutionPayloadHeader.BaseFeePerGas).String(),
BlockHash: hexutil.Encode(blindedCapellaBlock.BlindedCapella.Block.Body.ExecutionPayloadHeader.BlockHash),
BlockNumber: uint64ToString(blindedCapellaBlock.BlindedCapella.Block.Body.ExecutionPayloadHeader.BlockNumber),
BlockNumber: apiutil.Uint64ToString(blindedCapellaBlock.BlindedCapella.Block.Body.ExecutionPayloadHeader.BlockNumber),
ExtraData: hexutil.Encode(blindedCapellaBlock.BlindedCapella.Block.Body.ExecutionPayloadHeader.ExtraData),
FeeRecipient: hexutil.Encode(blindedCapellaBlock.BlindedCapella.Block.Body.ExecutionPayloadHeader.FeeRecipient),
GasLimit: uint64ToString(blindedCapellaBlock.BlindedCapella.Block.Body.ExecutionPayloadHeader.GasLimit),
GasUsed: uint64ToString(blindedCapellaBlock.BlindedCapella.Block.Body.ExecutionPayloadHeader.GasUsed),
GasLimit: apiutil.Uint64ToString(blindedCapellaBlock.BlindedCapella.Block.Body.ExecutionPayloadHeader.GasLimit),
GasUsed: apiutil.Uint64ToString(blindedCapellaBlock.BlindedCapella.Block.Body.ExecutionPayloadHeader.GasUsed),
LogsBloom: hexutil.Encode(blindedCapellaBlock.BlindedCapella.Block.Body.ExecutionPayloadHeader.LogsBloom),
ParentHash: hexutil.Encode(blindedCapellaBlock.BlindedCapella.Block.Body.ExecutionPayloadHeader.ParentHash),
PrevRandao: hexutil.Encode(blindedCapellaBlock.BlindedCapella.Block.Body.ExecutionPayloadHeader.PrevRandao),
ReceiptsRoot: hexutil.Encode(blindedCapellaBlock.BlindedCapella.Block.Body.ExecutionPayloadHeader.ReceiptsRoot),
StateRoot: hexutil.Encode(blindedCapellaBlock.BlindedCapella.Block.Body.ExecutionPayloadHeader.StateRoot),
Timestamp: uint64ToString(blindedCapellaBlock.BlindedCapella.Block.Body.ExecutionPayloadHeader.Timestamp),
Timestamp: apiutil.Uint64ToString(blindedCapellaBlock.BlindedCapella.Block.Body.ExecutionPayloadHeader.Timestamp),
TransactionsRoot: hexutil.Encode(blindedCapellaBlock.BlindedCapella.Block.Body.ExecutionPayloadHeader.TransactionsRoot),
WithdrawalsRoot: hexutil.Encode(blindedCapellaBlock.BlindedCapella.Block.Body.ExecutionPayloadHeader.WithdrawalsRoot),
},
@@ -103,37 +104,37 @@ func generateSignedBlindedCapellaBlock() *ethpb.GenericSignedBeaconBlock_Blinded
Block: &ethpb.BlindedBeaconBlockCapella{
Slot: 1,
ProposerIndex: 2,
ParentRoot: testhelpers.FillByteSlice(32, 3),
StateRoot: testhelpers.FillByteSlice(32, 4),
ParentRoot: test_helpers.FillByteSlice(32, 3),
StateRoot: test_helpers.FillByteSlice(32, 4),
Body: &ethpb.BlindedBeaconBlockBodyCapella{
RandaoReveal: testhelpers.FillByteSlice(96, 5),
RandaoReveal: test_helpers.FillByteSlice(96, 5),
Eth1Data: &ethpb.Eth1Data{
DepositRoot: testhelpers.FillByteSlice(32, 6),
DepositRoot: test_helpers.FillByteSlice(32, 6),
DepositCount: 7,
BlockHash: testhelpers.FillByteSlice(32, 8),
BlockHash: test_helpers.FillByteSlice(32, 8),
},
Graffiti: testhelpers.FillByteSlice(32, 9),
Graffiti: test_helpers.FillByteSlice(32, 9),
ProposerSlashings: []*ethpb.ProposerSlashing{
{
Header_1: &ethpb.SignedBeaconBlockHeader{
Header: &ethpb.BeaconBlockHeader{
Slot: 10,
ProposerIndex: 11,
ParentRoot: testhelpers.FillByteSlice(32, 12),
StateRoot: testhelpers.FillByteSlice(32, 13),
BodyRoot: testhelpers.FillByteSlice(32, 14),
ParentRoot: test_helpers.FillByteSlice(32, 12),
StateRoot: test_helpers.FillByteSlice(32, 13),
BodyRoot: test_helpers.FillByteSlice(32, 14),
},
Signature: testhelpers.FillByteSlice(96, 15),
Signature: test_helpers.FillByteSlice(96, 15),
},
Header_2: &ethpb.SignedBeaconBlockHeader{
Header: &ethpb.BeaconBlockHeader{
Slot: 16,
ProposerIndex: 17,
ParentRoot: testhelpers.FillByteSlice(32, 18),
StateRoot: testhelpers.FillByteSlice(32, 19),
BodyRoot: testhelpers.FillByteSlice(32, 20),
ParentRoot: test_helpers.FillByteSlice(32, 18),
StateRoot: test_helpers.FillByteSlice(32, 19),
BodyRoot: test_helpers.FillByteSlice(32, 20),
},
Signature: testhelpers.FillByteSlice(96, 21),
Signature: test_helpers.FillByteSlice(96, 21),
},
},
{
@@ -141,21 +142,21 @@ func generateSignedBlindedCapellaBlock() *ethpb.GenericSignedBeaconBlock_Blinded
Header: &ethpb.BeaconBlockHeader{
Slot: 22,
ProposerIndex: 23,
ParentRoot: testhelpers.FillByteSlice(32, 24),
StateRoot: testhelpers.FillByteSlice(32, 25),
BodyRoot: testhelpers.FillByteSlice(32, 26),
ParentRoot: test_helpers.FillByteSlice(32, 24),
StateRoot: test_helpers.FillByteSlice(32, 25),
BodyRoot: test_helpers.FillByteSlice(32, 26),
},
Signature: testhelpers.FillByteSlice(96, 27),
Signature: test_helpers.FillByteSlice(96, 27),
},
Header_2: &ethpb.SignedBeaconBlockHeader{
Header: &ethpb.BeaconBlockHeader{
Slot: 28,
ProposerIndex: 29,
ParentRoot: testhelpers.FillByteSlice(32, 30),
StateRoot: testhelpers.FillByteSlice(32, 31),
BodyRoot: testhelpers.FillByteSlice(32, 32),
ParentRoot: test_helpers.FillByteSlice(32, 30),
StateRoot: test_helpers.FillByteSlice(32, 31),
BodyRoot: test_helpers.FillByteSlice(32, 32),
},
Signature: testhelpers.FillByteSlice(96, 33),
Signature: test_helpers.FillByteSlice(96, 33),
},
},
},
@@ -166,34 +167,34 @@ func generateSignedBlindedCapellaBlock() *ethpb.GenericSignedBeaconBlock_Blinded
Data: &ethpb.AttestationData{
Slot: 36,
CommitteeIndex: 37,
BeaconBlockRoot: testhelpers.FillByteSlice(32, 38),
BeaconBlockRoot: test_helpers.FillByteSlice(32, 38),
Source: &ethpb.Checkpoint{
Epoch: 39,
Root: testhelpers.FillByteSlice(32, 40),
Root: test_helpers.FillByteSlice(32, 40),
},
Target: &ethpb.Checkpoint{
Epoch: 41,
Root: testhelpers.FillByteSlice(32, 42),
Root: test_helpers.FillByteSlice(32, 42),
},
},
Signature: testhelpers.FillByteSlice(96, 43),
Signature: test_helpers.FillByteSlice(96, 43),
},
Attestation_2: &ethpb.IndexedAttestation{
AttestingIndices: []uint64{44, 45},
Data: &ethpb.AttestationData{
Slot: 46,
CommitteeIndex: 47,
BeaconBlockRoot: testhelpers.FillByteSlice(32, 38),
BeaconBlockRoot: test_helpers.FillByteSlice(32, 38),
Source: &ethpb.Checkpoint{
Epoch: 49,
Root: testhelpers.FillByteSlice(32, 50),
Root: test_helpers.FillByteSlice(32, 50),
},
Target: &ethpb.Checkpoint{
Epoch: 51,
Root: testhelpers.FillByteSlice(32, 52),
Root: test_helpers.FillByteSlice(32, 52),
},
},
Signature: testhelpers.FillByteSlice(96, 53),
Signature: test_helpers.FillByteSlice(96, 53),
},
},
{
@@ -202,90 +203,90 @@ func generateSignedBlindedCapellaBlock() *ethpb.GenericSignedBeaconBlock_Blinded
Data: &ethpb.AttestationData{
Slot: 56,
CommitteeIndex: 57,
BeaconBlockRoot: testhelpers.FillByteSlice(32, 38),
BeaconBlockRoot: test_helpers.FillByteSlice(32, 38),
Source: &ethpb.Checkpoint{
Epoch: 59,
Root: testhelpers.FillByteSlice(32, 60),
Root: test_helpers.FillByteSlice(32, 60),
},
Target: &ethpb.Checkpoint{
Epoch: 61,
Root: testhelpers.FillByteSlice(32, 62),
Root: test_helpers.FillByteSlice(32, 62),
},
},
Signature: testhelpers.FillByteSlice(96, 63),
Signature: test_helpers.FillByteSlice(96, 63),
},
Attestation_2: &ethpb.IndexedAttestation{
AttestingIndices: []uint64{64, 65},
Data: &ethpb.AttestationData{
Slot: 66,
CommitteeIndex: 67,
BeaconBlockRoot: testhelpers.FillByteSlice(32, 38),
BeaconBlockRoot: test_helpers.FillByteSlice(32, 38),
Source: &ethpb.Checkpoint{
Epoch: 69,
Root: testhelpers.FillByteSlice(32, 70),
Root: test_helpers.FillByteSlice(32, 70),
},
Target: &ethpb.Checkpoint{
Epoch: 71,
Root: testhelpers.FillByteSlice(32, 72),
Root: test_helpers.FillByteSlice(32, 72),
},
},
Signature: testhelpers.FillByteSlice(96, 73),
Signature: test_helpers.FillByteSlice(96, 73),
},
},
},
Attestations: []*ethpb.Attestation{
{
AggregationBits: testhelpers.FillByteSlice(4, 74),
AggregationBits: test_helpers.FillByteSlice(4, 74),
Data: &ethpb.AttestationData{
Slot: 75,
CommitteeIndex: 76,
BeaconBlockRoot: testhelpers.FillByteSlice(32, 38),
BeaconBlockRoot: test_helpers.FillByteSlice(32, 38),
Source: &ethpb.Checkpoint{
Epoch: 78,
Root: testhelpers.FillByteSlice(32, 79),
Root: test_helpers.FillByteSlice(32, 79),
},
Target: &ethpb.Checkpoint{
Epoch: 80,
Root: testhelpers.FillByteSlice(32, 81),
Root: test_helpers.FillByteSlice(32, 81),
},
},
Signature: testhelpers.FillByteSlice(96, 82),
Signature: test_helpers.FillByteSlice(96, 82),
},
{
AggregationBits: testhelpers.FillByteSlice(4, 83),
AggregationBits: test_helpers.FillByteSlice(4, 83),
Data: &ethpb.AttestationData{
Slot: 84,
CommitteeIndex: 85,
BeaconBlockRoot: testhelpers.FillByteSlice(32, 38),
BeaconBlockRoot: test_helpers.FillByteSlice(32, 38),
Source: &ethpb.Checkpoint{
Epoch: 87,
Root: testhelpers.FillByteSlice(32, 88),
Root: test_helpers.FillByteSlice(32, 88),
},
Target: &ethpb.Checkpoint{
Epoch: 89,
Root: testhelpers.FillByteSlice(32, 90),
Root: test_helpers.FillByteSlice(32, 90),
},
},
Signature: testhelpers.FillByteSlice(96, 91),
Signature: test_helpers.FillByteSlice(96, 91),
},
},
Deposits: []*ethpb.Deposit{
{
Proof: testhelpers.FillByteArraySlice(33, testhelpers.FillByteSlice(32, 92)),
Proof: test_helpers.FillByteArraySlice(33, test_helpers.FillByteSlice(32, 92)),
Data: &ethpb.Deposit_Data{
PublicKey: testhelpers.FillByteSlice(48, 94),
WithdrawalCredentials: testhelpers.FillByteSlice(32, 95),
PublicKey: test_helpers.FillByteSlice(48, 94),
WithdrawalCredentials: test_helpers.FillByteSlice(32, 95),
Amount: 96,
Signature: testhelpers.FillByteSlice(96, 97),
Signature: test_helpers.FillByteSlice(96, 97),
},
},
{
Proof: testhelpers.FillByteArraySlice(33, testhelpers.FillByteSlice(32, 98)),
Proof: test_helpers.FillByteArraySlice(33, test_helpers.FillByteSlice(32, 98)),
Data: &ethpb.Deposit_Data{
PublicKey: testhelpers.FillByteSlice(48, 100),
WithdrawalCredentials: testhelpers.FillByteSlice(32, 101),
PublicKey: test_helpers.FillByteSlice(48, 100),
WithdrawalCredentials: test_helpers.FillByteSlice(32, 101),
Amount: 102,
Signature: testhelpers.FillByteSlice(96, 103),
Signature: test_helpers.FillByteSlice(96, 103),
},
},
},
@@ -295,58 +296,58 @@ func generateSignedBlindedCapellaBlock() *ethpb.GenericSignedBeaconBlock_Blinded
Epoch: 104,
ValidatorIndex: 105,
},
Signature: testhelpers.FillByteSlice(96, 106),
Signature: test_helpers.FillByteSlice(96, 106),
},
{
Exit: &ethpb.VoluntaryExit{
Epoch: 107,
ValidatorIndex: 108,
},
Signature: testhelpers.FillByteSlice(96, 109),
Signature: test_helpers.FillByteSlice(96, 109),
},
},
SyncAggregate: &ethpb.SyncAggregate{
SyncCommitteeBits: testhelpers.FillByteSlice(64, 110),
SyncCommitteeSignature: testhelpers.FillByteSlice(96, 111),
SyncCommitteeBits: test_helpers.FillByteSlice(64, 110),
SyncCommitteeSignature: test_helpers.FillByteSlice(96, 111),
},
ExecutionPayloadHeader: &enginev1.ExecutionPayloadHeaderCapella{
ParentHash: testhelpers.FillByteSlice(32, 112),
FeeRecipient: testhelpers.FillByteSlice(20, 113),
StateRoot: testhelpers.FillByteSlice(32, 114),
ReceiptsRoot: testhelpers.FillByteSlice(32, 115),
LogsBloom: testhelpers.FillByteSlice(256, 116),
PrevRandao: testhelpers.FillByteSlice(32, 117),
ParentHash: test_helpers.FillByteSlice(32, 112),
FeeRecipient: test_helpers.FillByteSlice(20, 113),
StateRoot: test_helpers.FillByteSlice(32, 114),
ReceiptsRoot: test_helpers.FillByteSlice(32, 115),
LogsBloom: test_helpers.FillByteSlice(256, 116),
PrevRandao: test_helpers.FillByteSlice(32, 117),
BlockNumber: 118,
GasLimit: 119,
GasUsed: 120,
Timestamp: 121,
ExtraData: testhelpers.FillByteSlice(32, 122),
BaseFeePerGas: testhelpers.FillByteSlice(32, 123),
BlockHash: testhelpers.FillByteSlice(32, 124),
TransactionsRoot: testhelpers.FillByteSlice(32, 125),
WithdrawalsRoot: testhelpers.FillByteSlice(32, 126),
ExtraData: test_helpers.FillByteSlice(32, 122),
BaseFeePerGas: test_helpers.FillByteSlice(32, 123),
BlockHash: test_helpers.FillByteSlice(32, 124),
TransactionsRoot: test_helpers.FillByteSlice(32, 125),
WithdrawalsRoot: test_helpers.FillByteSlice(32, 126),
},
BlsToExecutionChanges: []*ethpb.SignedBLSToExecutionChange{
{
Message: &ethpb.BLSToExecutionChange{
ValidatorIndex: 127,
FromBlsPubkey: testhelpers.FillByteSlice(48, 128),
ToExecutionAddress: testhelpers.FillByteSlice(20, 129),
FromBlsPubkey: test_helpers.FillByteSlice(48, 128),
ToExecutionAddress: test_helpers.FillByteSlice(20, 129),
},
Signature: testhelpers.FillByteSlice(96, 130),
Signature: test_helpers.FillByteSlice(96, 130),
},
{
Message: &ethpb.BLSToExecutionChange{
ValidatorIndex: 131,
FromBlsPubkey: testhelpers.FillByteSlice(48, 132),
ToExecutionAddress: testhelpers.FillByteSlice(20, 133),
FromBlsPubkey: test_helpers.FillByteSlice(48, 132),
ToExecutionAddress: test_helpers.FillByteSlice(20, 133),
},
Signature: testhelpers.FillByteSlice(96, 134),
Signature: test_helpers.FillByteSlice(96, 134),
},
},
},
},
Signature: testhelpers.FillByteSlice(96, 135),
Signature: test_helpers.FillByteSlice(96, 135),
},
}
}

View File

@@ -1,4 +1,4 @@
package beacon_api
package validator_api
import (
"bytes"
@@ -6,11 +6,11 @@ import (
"encoding/json"
"testing"
"github.com/prysmaticlabs/prysm/v5/api/client/beacon/mock"
"github.com/prysmaticlabs/prysm/v5/api/server/structs"
rpctesting "github.com/prysmaticlabs/prysm/v5/beacon-chain/rpc/eth/shared/testing"
"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 (
"bytes"
@@ -6,11 +6,11 @@ import (
"encoding/json"
"testing"
"github.com/prysmaticlabs/prysm/v5/api/client/beacon/mock"
"github.com/prysmaticlabs/prysm/v5/api/server/structs"
rpctesting "github.com/prysmaticlabs/prysm/v5/beacon-chain/rpc/eth/shared/testing"
"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 (
"bytes"
@@ -6,11 +6,11 @@ import (
"encoding/json"
"testing"
"github.com/prysmaticlabs/prysm/v5/api/client/beacon/mock"
"github.com/prysmaticlabs/prysm/v5/api/server/structs"
rpctesting "github.com/prysmaticlabs/prysm/v5/beacon-chain/rpc/eth/shared/testing"
"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 (
"bytes"
@@ -7,13 +7,14 @@ import (
"testing"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/prysmaticlabs/prysm/v5/api/apiutil"
"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/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/validator/client/beacon-api/mock"
testhelpers "github.com/prysmaticlabs/prysm/v5/validator/client/beacon-api/test-helpers"
"go.uber.org/mock/gomock"
)
@@ -31,8 +32,8 @@ func TestProposeBeaconBlock_Capella(t *testing.T) {
Signature: hexutil.Encode(capellaBlock.Capella.Signature),
Message: &structs.BeaconBlockCapella{
ParentRoot: hexutil.Encode(capellaBlock.Capella.Block.ParentRoot),
ProposerIndex: uint64ToString(capellaBlock.Capella.Block.ProposerIndex),
Slot: uint64ToString(capellaBlock.Capella.Block.Slot),
ProposerIndex: apiutil.Uint64ToString(capellaBlock.Capella.Block.ProposerIndex),
Slot: apiutil.Uint64ToString(capellaBlock.Capella.Block.Slot),
StateRoot: hexutil.Encode(capellaBlock.Capella.Block.StateRoot),
Body: &structs.BeaconBlockBodyCapella{
Attestations: jsonifyAttestations(capellaBlock.Capella.Block.Body.Attestations),
@@ -50,17 +51,17 @@ func TestProposeBeaconBlock_Capella(t *testing.T) {
ExecutionPayload: &structs.ExecutionPayloadCapella{
BaseFeePerGas: bytesutil.LittleEndianBytesToBigInt(capellaBlock.Capella.Block.Body.ExecutionPayload.BaseFeePerGas).String(),
BlockHash: hexutil.Encode(capellaBlock.Capella.Block.Body.ExecutionPayload.BlockHash),
BlockNumber: uint64ToString(capellaBlock.Capella.Block.Body.ExecutionPayload.BlockNumber),
BlockNumber: apiutil.Uint64ToString(capellaBlock.Capella.Block.Body.ExecutionPayload.BlockNumber),
ExtraData: hexutil.Encode(capellaBlock.Capella.Block.Body.ExecutionPayload.ExtraData),
FeeRecipient: hexutil.Encode(capellaBlock.Capella.Block.Body.ExecutionPayload.FeeRecipient),
GasLimit: uint64ToString(capellaBlock.Capella.Block.Body.ExecutionPayload.GasLimit),
GasUsed: uint64ToString(capellaBlock.Capella.Block.Body.ExecutionPayload.GasUsed),
GasLimit: apiutil.Uint64ToString(capellaBlock.Capella.Block.Body.ExecutionPayload.GasLimit),
GasUsed: apiutil.Uint64ToString(capellaBlock.Capella.Block.Body.ExecutionPayload.GasUsed),
LogsBloom: hexutil.Encode(capellaBlock.Capella.Block.Body.ExecutionPayload.LogsBloom),
ParentHash: hexutil.Encode(capellaBlock.Capella.Block.Body.ExecutionPayload.ParentHash),
PrevRandao: hexutil.Encode(capellaBlock.Capella.Block.Body.ExecutionPayload.PrevRandao),
ReceiptsRoot: hexutil.Encode(capellaBlock.Capella.Block.Body.ExecutionPayload.ReceiptsRoot),
StateRoot: hexutil.Encode(capellaBlock.Capella.Block.Body.ExecutionPayload.StateRoot),
Timestamp: uint64ToString(capellaBlock.Capella.Block.Body.ExecutionPayload.Timestamp),
Timestamp: apiutil.Uint64ToString(capellaBlock.Capella.Block.Body.ExecutionPayload.Timestamp),
Transactions: jsonifyTransactions(capellaBlock.Capella.Block.Body.ExecutionPayload.Transactions),
Withdrawals: jsonifyWithdrawals(capellaBlock.Capella.Block.Body.ExecutionPayload.Withdrawals),
},
@@ -97,8 +98,8 @@ func TestProposeBeaconBlock_Capella(t *testing.T) {
func generateSignedCapellaBlock() *ethpb.GenericSignedBeaconBlock_Capella {
return &ethpb.GenericSignedBeaconBlock_Capella{
Capella: &ethpb.SignedBeaconBlockCapella{
Block: testhelpers.GenerateProtoCapellaBeaconBlock(),
Signature: testhelpers.FillByteSlice(96, 127),
Block: test_helpers.GenerateProtoCapellaBeaconBlock(),
Signature: test_helpers.FillByteSlice(96, 127),
},
}
}

View File

@@ -1,4 +1,4 @@
package beacon_api
package validator_api
import (
"bytes"
@@ -6,11 +6,11 @@ import (
"encoding/json"
"testing"
"github.com/prysmaticlabs/prysm/v5/api/client/beacon/mock"
"github.com/prysmaticlabs/prysm/v5/api/server/structs"
rpctesting "github.com/prysmaticlabs/prysm/v5/beacon-chain/rpc/eth/shared/testing"
"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 (
"bytes"
@@ -6,11 +6,11 @@ import (
"encoding/json"
"testing"
"github.com/prysmaticlabs/prysm/v5/api/client/beacon/mock"
"github.com/prysmaticlabs/prysm/v5/api/server/structs"
rpctesting "github.com/prysmaticlabs/prysm/v5/beacon-chain/rpc/eth/shared/testing"
"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 (
"bytes"
@@ -6,11 +6,11 @@ import (
"encoding/json"
"testing"
"github.com/prysmaticlabs/prysm/v5/api/client/beacon/mock"
"github.com/prysmaticlabs/prysm/v5/api/server/structs"
rpctesting "github.com/prysmaticlabs/prysm/v5/beacon-chain/rpc/eth/shared/testing"
"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 (
"bytes"
@@ -7,12 +7,13 @@ import (
"testing"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/prysmaticlabs/prysm/v5/api/apiutil"
"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"
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"
)
@@ -30,8 +31,8 @@ func TestProposeBeaconBlock_Phase0(t *testing.T) {
Signature: hexutil.Encode(phase0Block.Phase0.Signature),
Message: &structs.BeaconBlock{
ParentRoot: hexutil.Encode(phase0Block.Phase0.Block.ParentRoot),
ProposerIndex: uint64ToString(phase0Block.Phase0.Block.ProposerIndex),
Slot: uint64ToString(phase0Block.Phase0.Block.Slot),
ProposerIndex: apiutil.Uint64ToString(phase0Block.Phase0.Block.ProposerIndex),
Slot: apiutil.Uint64ToString(phase0Block.Phase0.Block.Slot),
StateRoot: hexutil.Encode(phase0Block.Phase0.Block.StateRoot),
Body: &structs.BeaconBlockBody{
Attestations: jsonifyAttestations(phase0Block.Phase0.Block.Body.Attestations),
@@ -76,8 +77,8 @@ func TestProposeBeaconBlock_Phase0(t *testing.T) {
func generateSignedPhase0Block() *ethpb.GenericSignedBeaconBlock_Phase0 {
return &ethpb.GenericSignedBeaconBlock_Phase0{
Phase0: &ethpb.SignedBeaconBlock{
Block: testhelpers.GenerateProtoPhase0BeaconBlock(),
Signature: testhelpers.FillByteSlice(96, 110),
Block: test_helpers.GenerateProtoPhase0BeaconBlock(),
Signature: test_helpers.FillByteSlice(96, 110),
},
}
}

View File

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

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

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

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