Compare commits

...

19 Commits

Author SHA1 Message Date
Radosław Kapka
73d278bdde Merge branch 'develop' into header-consts 2025-10-29 18:01:00 +01:00
rocksload
5a1a5b5ae5 refactor: use slices.Contains to simplify code (#15646)
Signed-off-by: rocksload <rocksload@outlook.com>
2025-10-29 14:40:33 +00:00
james-prysm
dbb2f0b047 changelog (#15929) 2025-10-28 15:42:05 +00:00
Manu NALEPA
7b3c11c818 Do not serve sidecars if corresponding block is not available in the database (#15933)
* Implement `AvailableBlocks`.

* `blobSidecarByRootRPCHandler`: Do not serve a sidecar if the corresponding block is not available.

* `dataColumnSidecarByRootRPCHandler`: Do not do extra work if only needed for TRACE logging.

* `TestDataColumnSidecarsByRootRPCHandler`: Re-arrange (no functional change).

* `TestDataColumnSidecarsByRootRPCHandler`: Save blocks corresponding to sidecars into DB.

* `dataColumnSidecarByRootRPCHandler`: Do not serve a sidecar if the corresponding block is not available.

* Add changelog

* `TestDataColumnSidecarsByRootRPCHandler`: Use `assert` instead of `require` in goroutines.

https://github.com/stretchr/testify?tab=readme-ov-file#require-package
2025-10-28 15:39:35 +00:00
Manu NALEPA
c9b34d556d Update go-netroute to v0.3.0 (#15934) 2025-10-28 12:57:14 +00:00
fernantho
10a2f0687b SSZ-QL: calculate generalized indices for elements (#15873)
* added tests for calculating generalized indices

* added first version of GI calculation walking the specified path with no recursion. Extended test coverage for bitlist and bitvectors.
vectors need more testing

* refactored code. Detached PathElement processing, currently done at the beginning. Swap to regex to gain flexibility.

* added an updateRoot function with the GI formula. more refactoring

* added changelog

* replaced TODO tag

* udpated some comments

* simplified code - removed duplicated code in processingLengthField function

* run gazelle

* merging all input path processing into path.go

* reviewed Jun's feedback

* removed unnecessary idx pointer var + fixed error with length data type (uint64 instead of uint8)

* refactored path.go after merging path elements from generalized_indices.go

* re-computed GIs for tests as VariableTestContainer added a new field.

* added minor comment - rawPath MUST be snake case

removed extractFieldName func.

* fixed vector GI calculation - updated tests GIs

* removed updateRoot function in favor of inline code

* path input data enforced to be snake case

* added sanity checks for accessing outbound element indices - checked against vector.length/list.limit

* fixed issues triggered after merging develop

* Removed redundant comment

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

* removed unreachable condition as `strings.Split` always return a slice with length >= 1

If s does not contain sep and sep is not empty, Split returns a slice of
length 1 whose only element is s.

* added tests to cover edge cases + cleaned code (toLower is no longer needed in extractFieldName function

* added Jun's feedback + more testing

* postponed snake case conversion to do it on a per-element-basis. Added more testing focused mainly in snake case conversion

* addressed several Jun's comments.

* added sanity check to prevent length of a multi-dimensional array. added more tests with extended paths

* Update encoding/ssz/query/generalized_index.go

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

* Update encoding/ssz/query/generalized_index.go

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

* Update encoding/ssz/query/generalized_index.go

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

* placed constant bitsPerChunk in the right place. Exported BitsPerChunk and BytesPerChunk and updated code that use them

* added helpers for computing GI of each data type

* changed %q in favor of %s

* Update encoding/ssz/query/path.go

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

* removed the least restrictive condition isBasicType

* replaced length of containerInfo.order for containerInfo.fields for clarity

* removed outdated comment

* removed toSnakeCase conversion.

* moved isBasicType func to its natural place, SSZType

* cosmetic refactor

- renamed itemLengthFromInfo to itemLength (same name is in spec).
- arranged all SSZ helpers.

* cleaned tests

* renamed "root" to "index"

* removed unnecessary check for negative integers. Replaced %q for %s.

* refactored regex variables and prevented re-assignation

* added length regex explanation

* added more testing for stressing regex for path processing

* renamed currentIndex to parentIndex for clarity and documented the returns from calculate<Type>GeneralizedIndex functions

* Update encoding/ssz/query/generalized_index.go

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

* run gazelle

* fixed never asserted error. Updated error message

---------

Co-authored-by: Jun Song <87601811+syjn99@users.noreply.github.com>
Co-authored-by: Radosław Kapka <radoslaw.kapka@gmail.com>
Co-authored-by: Radosław Kapka <rkapka@wp.pl>
2025-10-27 23:27:34 +00:00
Manu NALEPA
4fb75d6d0b Add some metrics improvements (#15922)
* Define TCP and QUIC as `InternetProtocol` (no functional change).

* Group types. (No functional changes)

* Rename variables and use range syntax.

* Add `p2pMaxPeers` and `p2pPeerCountDirectionType` metrics

* `p2p_subscribed_topic_peer_total`: Reset to avoid dangling values.

* `validateConfig`:
- Use `Warning` with fields instead of `Warnf`.
- Avoid to both modify in place the input value and return it.

* Add `p2p_minimum_peers_per_subnet` metric.

* `beaconConfig` => `cfg`.

https://github.com/OffchainLabs/prysm/pull/15880#discussion_r2436826215

* Add changelog

---------

Co-authored-by: james-prysm <90280386+james-prysm@users.noreply.github.com>
2025-10-26 15:16:05 +00:00
terence
6d596edea2 Use SlotTicker instead of time.Ticker for attestation pool pruning (#15917)
* Use SlotTicker instead of time.Ticker for attestation pool pruning

* Offset one second before slot start
2025-10-24 15:35:26 +00:00
Bastin
9153c5a202 light client logging (#15927) 2025-10-24 14:42:27 +00:00
james-prysm
26ce94e224 removes misleading keymanager info log (#15926)
* simple change

* fixing test"
"
2025-10-24 14:28:30 +00:00
terence
255ea2fac1 Return optimistic response only when handling blinded blocks (#15925)
* Return optimistic response only when handling blinded blocks in proposer

* Remove blind condition
2025-10-24 03:37:32 +00:00
terence
46bc81b4c8 Add metric to track data columns recovered from execution layer (#15924) 2025-10-23 15:50:25 +00:00
kasey
9c4774b82e default new blob storage layouts to by-epoch (#15904)
* default new blob storage layouts to by-epoch

also, do not log migration message until we see a directory that needs to be migrated

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

* manu feedback

---------

Co-authored-by: Kasey Kirkham <kasey@users.noreply.github.com>
Co-authored-by: Manu NALEPA <enalepa@offchainlabs.com>
2025-10-22 20:09:18 +00:00
terence
7dd4f5948c Update consensus spec tests to v1.6.0-beta.1 with new hashes and URL template (#15918) 2025-10-22 18:22:19 +00:00
Radosław Kapka
2f090c52d9 Allow custom headers in validator client HTTP requests (#15884)
* Allow custom headers in validator client HTTP requests

* changelog <3

* improve flag description

* Bastin's review

* James' review

* add godoc for NodeConnectionOption
2025-10-22 13:47:35 +00:00
Manu NALEPA
3ecb5d0b67 Remove Reading static P2P private key from a file. log if Fulu is enabled. (#15913) 2025-10-22 11:52:31 +00:00
rkapka
608fa30c95 build fix 2025-10-10 17:50:33 +02:00
rkapka
012dbba2e0 changelog <3 2025-10-10 17:49:21 +02:00
rkapka
2c56d9e0db Always use constants for API headers 2025-10-10 17:41:17 +02:00
201 changed files with 2754 additions and 1150 deletions

View File

@@ -4,6 +4,29 @@ 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.
## [v6.1.4](https://github.com/prysmaticlabs/prysm/compare/v6.1.3...v6.1.4) - 2025-10-24
This release includes a bug fix affecting block proposals in rare cases, along with an important update for Windows users running post-Fusaka fork.
### Added
- SSZ-QL: Add endpoints for `BeaconState`/`BeaconBlock`. [[PR]](https://github.com/prysmaticlabs/prysm/pull/15888)
- Add native state diff type and marshalling functions. [[PR]](https://github.com/prysmaticlabs/prysm/pull/15250)
- Update the earliest available slot after pruning operations in beacon chain database pruner. This ensures the P2P layer accurately knows which historical data is available after pruning, preventing nodes from advertising or attempting to serve data that has been pruned. [[PR]](https://github.com/prysmaticlabs/prysm/pull/15694)
### Fixed
- Correctly advertise (in ENR and beacon API) attestation subnets when using `--subscribe-all-subnets`. [[PR]](https://github.com/prysmaticlabs/prysm/pull/15880)
- `randomPeer`: Return if the context is cancelled when waiting for peers. [[PR]](https://github.com/prysmaticlabs/prysm/pull/15876)
- Improve error message when the byte count read from disk when reading a data column sidecars is lower than expected. (Mostly, because the file is truncated.). [[PR]](https://github.com/prysmaticlabs/prysm/pull/15881)
- Delete the genesis state file when --clear-db / --force-clear-db is specified. [[PR]](https://github.com/prysmaticlabs/prysm/pull/15883)
- Fix sync committee subscription to use subnet indices instead of committee indices. [[PR]](https://github.com/prysmaticlabs/prysm/pull/15885)
- Fixed metadata extraction on Windows by correctly splitting file paths. [[PR]](https://github.com/prysmaticlabs/prysm/pull/15899)
- `VerifyDataColumnsSidecarKZGProofs`: Check if sizes match. [[PR]](https://github.com/prysmaticlabs/prysm/pull/15892)
- Fix recoverStateSummary to persist state summaries in stateSummaryBucket instead of stateBucket (#15896). [[PR]](https://github.com/prysmaticlabs/prysm/pull/15896)
- `updateCustodyInfoInDB`: Use `NumberOfCustodyGroups` instead of `NumberOfColumns`. [[PR]](https://github.com/prysmaticlabs/prysm/pull/15908)
- Sync committee uses correct state to calculate position. [[PR]](https://github.com/prysmaticlabs/prysm/pull/15905)
## [v6.1.3](https://github.com/prysmaticlabs/prysm/compare/v6.1.2...v6.1.3) - 2025-10-20
This release has several important beacon API and p2p fixes.

View File

@@ -253,16 +253,16 @@ filegroup(
url = "https://github.com/ethereum/EIPs/archive/5480440fe51742ed23342b68cf106cefd427e39d.tar.gz",
)
consensus_spec_version = "v1.6.0-beta.0"
consensus_spec_version = "v1.6.0-beta.1"
load("@prysm//tools:download_spectests.bzl", "consensus_spec_tests")
consensus_spec_tests(
name = "consensus_spec_tests",
flavors = {
"general": "sha256-rT3jQp2+ZaDiO66gIQggetzqr+kGeexaLqEhbx4HDMY=",
"minimal": "sha256-wowwwyvd0KJLsE+oDOtPkrhZyJndJpJ0lbXYsLH6XBw=",
"mainnet": "sha256-4ZLrLNeO7NihZ4TuWH5V5fUhvW9Y3mAPBQDCqrfShps=",
"general": "sha256-oEj0MTViJHjZo32nABK36gfvSXpbwkBk/jt6Mj7pWFI=",
"minimal": "sha256-cS4NPv6IRBoCSmWomQ8OEo8IsVNW9YawUFqoRZQBUj4=",
"mainnet": "sha256-BYuLndMPAh4p13IRJgNfVakrCVL69KRrNw2tdc3ETbE=",
},
version = consensus_spec_version,
)
@@ -278,7 +278,7 @@ filegroup(
visibility = ["//visibility:public"],
)
""",
integrity = "sha256-sBe3Rx8zGq9IrvfgIhZQpYidGjy3mE1SiCb6/+pjLdY=",
integrity = "sha256-yrq3tdwPS8Ri+ueeLAHssIT3ssMrX7zvHiJ8Xf9GVYs=",
strip_prefix = "consensus-specs-" + consensus_spec_version[1:],
url = "https://github.com/ethereum/consensus-specs/archive/refs/tags/%s.tar.gz" % consensus_spec_version,
)

View File

@@ -6,15 +6,25 @@ go_library(
"client.go",
"errors.go",
"options.go",
"transport.go",
],
importpath = "github.com/OffchainLabs/prysm/v6/api/client",
visibility = ["//visibility:public"],
deps = ["@com_github_pkg_errors//:go_default_library"],
deps = [
"//api:go_default_library",
"@com_github_pkg_errors//:go_default_library",
],
)
go_test(
name = "go_default_test",
srcs = ["client_test.go"],
srcs = [
"client_test.go",
"transport_test.go",
],
embed = [":go_default_library"],
deps = ["//testing/require:go_default_library"],
deps = [
"//testing/assert:go_default_library",
"//testing/require:go_default_library",
],
)

View File

@@ -11,6 +11,7 @@ go_library(
importpath = "github.com/OffchainLabs/prysm/v6/api/client/beacon",
visibility = ["//visibility:public"],
deps = [
"//api:go_default_library",
"//api/client:go_default_library",
"//api/server:go_default_library",
"//api/server/structs:go_default_library",

View File

@@ -11,6 +11,7 @@ import (
"regexp"
"strconv"
"github.com/OffchainLabs/prysm/v6/api"
"github.com/OffchainLabs/prysm/v6/api/client"
"github.com/OffchainLabs/prysm/v6/api/server"
"github.com/OffchainLabs/prysm/v6/api/server/structs"
@@ -273,7 +274,7 @@ func (c *Client) SubmitChangeBLStoExecution(ctx context.Context, request []*stru
if err != nil {
return errors.Wrap(err, "invalid format, failed to create new POST request object")
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set(api.ContentTypeHeader, api.JsonMediaType)
resp, err := c.Do(req)
if err != nil {
return err

View File

@@ -171,7 +171,7 @@ func (c *Client) do(ctx context.Context, method string, path string, body io.Rea
if err != nil {
return
}
req.Header.Add("User-Agent", version.BuildData())
req.Header.Add(api.UserAgentHeader, version.BuildData())
for _, o := range opts {
o(req)
}
@@ -232,11 +232,11 @@ func (c *Client) GetHeader(ctx context.Context, slot primitives.Slot, parentHash
var getOpts reqOption
if c.sszEnabled {
getOpts = func(r *http.Request) {
r.Header.Set("Accept", api.OctetStreamMediaType)
r.Header.Set(api.AcceptHeader, api.OctetStreamMediaType)
}
} else {
getOpts = func(r *http.Request) {
r.Header.Set("Accept", api.JsonMediaType)
r.Header.Set(api.AcceptHeader, api.JsonMediaType)
}
}
data, header, err := c.do(ctx, http.MethodGet, path, nil, http.StatusOK, getOpts)
@@ -259,8 +259,8 @@ func (c *Client) GetHeader(ctx context.Context, slot primitives.Slot, parentHash
func (c *Client) parseHeaderResponse(data []byte, header http.Header, slot primitives.Slot) (SignedBid, error) {
var versionHeader string
if c.sszEnabled || header.Get(api.VersionHeader) != "" {
versionHeader = header.Get(api.VersionHeader)
if c.sszEnabled || header.Get(api.EthConsensusVersionHeader) != "" {
versionHeader = header.Get(api.EthConsensusVersionHeader)
} else {
// If we don't have a version header, attempt to parse JSON for version
v := &VersionResponse{}
@@ -390,8 +390,8 @@ func (c *Client) RegisterValidator(ctx context.Context, svr []*ethpb.SignedValid
)
if c.sszEnabled {
postOpts = func(r *http.Request) {
r.Header.Set("Content-Type", api.OctetStreamMediaType)
r.Header.Set("Accept", api.OctetStreamMediaType)
r.Header.Set(api.ContentTypeHeader, api.OctetStreamMediaType)
r.Header.Set(api.AcceptHeader, api.OctetStreamMediaType)
}
body, err = sszValidatorRegisterRequest(svr)
if err != nil {
@@ -401,8 +401,8 @@ func (c *Client) RegisterValidator(ctx context.Context, svr []*ethpb.SignedValid
}
} else {
postOpts = func(r *http.Request) {
r.Header.Set("Content-Type", api.JsonMediaType)
r.Header.Set("Accept", api.JsonMediaType)
r.Header.Set(api.ContentTypeHeader, api.JsonMediaType)
r.Header.Set(api.AcceptHeader, api.JsonMediaType)
}
body, err = jsonValidatorRegisterRequest(svr)
if err != nil {
@@ -446,7 +446,7 @@ func sszValidatorRegisterRequest(svr []*ethpb.SignedValidatorRegistrationV1) ([]
return ssz, nil
}
var errResponseVersionMismatch = errors.New("builder API response uses a different version than requested in " + api.VersionHeader + " header")
var errResponseVersionMismatch = errors.New("builder API response uses a different version than requested in " + api.EthConsensusVersionHeader + " header")
func getVersionsBlockToPayload(blockVersion int) (int, error) {
if blockVersion >= version.Fulu {
@@ -525,7 +525,7 @@ func (c *Client) SubmitBlindedBlockPostFulu(ctx context.Context, sb interfaces.R
func (c *Client) checkBlockVersion(respBytes []byte, header http.Header) (int, error) {
var versionHeader string
if c.sszEnabled {
versionHeader = strings.ToLower(header.Get(api.VersionHeader))
versionHeader = strings.ToLower(header.Get(api.EthConsensusVersionHeader))
} else {
// fallback to JSON-based version extraction
v := &VersionResponse{}
@@ -555,9 +555,9 @@ func (c *Client) buildBlindedBlockRequest(sb interfaces.ReadOnlySignedBeaconBloc
return nil, nil, errors.Wrap(err, "could not marshal SSZ for blinded block")
}
opt := func(r *http.Request) {
r.Header.Set(api.VersionHeader, version.String(sb.Version()))
r.Header.Set("Content-Type", api.OctetStreamMediaType)
r.Header.Set("Accept", api.OctetStreamMediaType)
r.Header.Set(api.EthConsensusVersionHeader, version.String(sb.Version()))
r.Header.Set(api.ContentTypeHeader, api.OctetStreamMediaType)
r.Header.Set(api.AcceptHeader, api.OctetStreamMediaType)
}
return body, opt, nil
}
@@ -571,9 +571,9 @@ func (c *Client) buildBlindedBlockRequest(sb interfaces.ReadOnlySignedBeaconBloc
return nil, nil, errors.Wrap(err, "error marshaling blinded block to JSON")
}
opt := func(r *http.Request) {
r.Header.Set(api.VersionHeader, version.String(sb.Version()))
r.Header.Set("Content-Type", api.JsonMediaType)
r.Header.Set("Accept", api.JsonMediaType)
r.Header.Set(api.EthConsensusVersionHeader, version.String(sb.Version()))
r.Header.Set(api.ContentTypeHeader, api.JsonMediaType)
r.Header.Set(api.AcceptHeader, api.JsonMediaType)
}
return body, opt, nil
}
@@ -676,7 +676,7 @@ func (c *Client) parseBlindedBlockResponseJSON(
// happy path, and an error with information about the server response body for a non-200 response.
func (c *Client) Status(ctx context.Context) error {
getOpts := func(r *http.Request) {
r.Header.Set("Accept", api.JsonMediaType)
r.Header.Set(api.AcceptHeader, api.JsonMediaType)
}
_, _, err := c.do(ctx, http.MethodGet, getStatus, nil, http.StatusOK, getOpts)
return err

View File

@@ -92,8 +92,8 @@ func TestClient_RegisterValidator(t *testing.T) {
t.Run("JSON success", func(t *testing.T) {
hc := &http.Client{
Transport: roundtrip(func(r *http.Request) (*http.Response, error) {
require.Equal(t, api.JsonMediaType, r.Header.Get("Content-Type"))
require.Equal(t, api.JsonMediaType, r.Header.Get("Accept"))
require.Equal(t, api.JsonMediaType, r.Header.Get(api.ContentTypeHeader))
require.Equal(t, api.JsonMediaType, r.Header.Get(api.AcceptHeader))
body, err := io.ReadAll(r.Body)
defer func() {
require.NoError(t, r.Body.Close())
@@ -127,8 +127,8 @@ func TestClient_RegisterValidator(t *testing.T) {
t.Run("SSZ success", func(t *testing.T) {
hc := &http.Client{
Transport: roundtrip(func(r *http.Request) (*http.Response, error) {
require.Equal(t, api.OctetStreamMediaType, r.Header.Get("Content-Type"))
require.Equal(t, api.OctetStreamMediaType, r.Header.Get("Accept"))
require.Equal(t, api.OctetStreamMediaType, r.Header.Get(api.ContentTypeHeader))
require.Equal(t, api.OctetStreamMediaType, r.Header.Get(api.AcceptHeader))
body, err := io.ReadAll(r.Body)
defer func() {
require.NoError(t, r.Body.Close())
@@ -225,7 +225,7 @@ func TestClient_GetHeader(t *testing.T) {
hc := &http.Client{
Transport: roundtrip(func(r *http.Request) (*http.Response, error) {
require.Equal(t, expectedPath, r.URL.Path)
require.Equal(t, api.JsonMediaType, r.Header.Get("Accept"))
require.Equal(t, api.JsonMediaType, r.Header.Get(api.AcceptHeader))
return &http.Response{
StatusCode: http.StatusOK,
Body: io.NopCloser(bytes.NewBufferString(testExampleHeaderResponse)),
@@ -260,7 +260,7 @@ func TestClient_GetHeader(t *testing.T) {
t.Run("bellatrix ssz", func(t *testing.T) {
hc := &http.Client{
Transport: roundtrip(func(r *http.Request) (*http.Response, error) {
require.Equal(t, api.OctetStreamMediaType, r.Header.Get("Accept"))
require.Equal(t, api.OctetStreamMediaType, r.Header.Get(api.AcceptHeader))
require.Equal(t, expectedPath, r.URL.Path)
epr := &ExecHeaderResponse{}
require.NoError(t, json.Unmarshal([]byte(testExampleHeaderResponse), epr))
@@ -269,7 +269,7 @@ func TestClient_GetHeader(t *testing.T) {
ssz, err := pro.MarshalSSZ()
require.NoError(t, err)
header := http.Header{}
header.Set(api.VersionHeader, "bellatrix")
header.Set(api.EthConsensusVersionHeader, "bellatrix")
return &http.Response{
StatusCode: http.StatusOK,
Header: header,
@@ -306,7 +306,7 @@ func TestClient_GetHeader(t *testing.T) {
t.Run("capella", func(t *testing.T) {
hc := &http.Client{
Transport: roundtrip(func(r *http.Request) (*http.Response, error) {
require.Equal(t, api.JsonMediaType, r.Header.Get("Accept"))
require.Equal(t, api.JsonMediaType, r.Header.Get(api.AcceptHeader))
require.Equal(t, expectedPath, r.URL.Path)
return &http.Response{
StatusCode: http.StatusOK,
@@ -338,7 +338,7 @@ func TestClient_GetHeader(t *testing.T) {
t.Run("capella ssz", func(t *testing.T) {
hc := &http.Client{
Transport: roundtrip(func(r *http.Request) (*http.Response, error) {
require.Equal(t, api.OctetStreamMediaType, r.Header.Get("Accept"))
require.Equal(t, api.OctetStreamMediaType, r.Header.Get(api.AcceptHeader))
require.Equal(t, expectedPath, r.URL.Path)
epr := &ExecHeaderResponseCapella{}
require.NoError(t, json.Unmarshal([]byte(testExampleHeaderResponseCapella), epr))
@@ -347,7 +347,7 @@ func TestClient_GetHeader(t *testing.T) {
ssz, err := pro.MarshalSSZ()
require.NoError(t, err)
header := http.Header{}
header.Set(api.VersionHeader, "capella")
header.Set(api.EthConsensusVersionHeader, "capella")
return &http.Response{
StatusCode: http.StatusOK,
Header: header,
@@ -380,7 +380,7 @@ func TestClient_GetHeader(t *testing.T) {
t.Run("deneb", func(t *testing.T) {
hc := &http.Client{
Transport: roundtrip(func(r *http.Request) (*http.Response, error) {
require.Equal(t, api.JsonMediaType, r.Header.Get("Accept"))
require.Equal(t, api.JsonMediaType, r.Header.Get(api.AcceptHeader))
require.Equal(t, expectedPath, r.URL.Path)
return &http.Response{
StatusCode: http.StatusOK,
@@ -420,7 +420,7 @@ func TestClient_GetHeader(t *testing.T) {
t.Run("deneb ssz", func(t *testing.T) {
hc := &http.Client{
Transport: roundtrip(func(r *http.Request) (*http.Response, error) {
require.Equal(t, api.OctetStreamMediaType, r.Header.Get("Accept"))
require.Equal(t, api.OctetStreamMediaType, r.Header.Get(api.AcceptHeader))
require.Equal(t, expectedPath, r.URL.Path)
epr := &ExecHeaderResponseDeneb{}
require.NoError(t, json.Unmarshal([]byte(testExampleHeaderResponseDeneb), epr))
@@ -429,7 +429,7 @@ func TestClient_GetHeader(t *testing.T) {
ssz, err := pro.MarshalSSZ()
require.NoError(t, err)
header := http.Header{}
header.Set(api.VersionHeader, "deneb")
header.Set(api.EthConsensusVersionHeader, "deneb")
return &http.Response{
StatusCode: http.StatusOK,
Header: header,
@@ -488,7 +488,7 @@ func TestClient_GetHeader(t *testing.T) {
t.Run("electra", func(t *testing.T) {
hc := &http.Client{
Transport: roundtrip(func(r *http.Request) (*http.Response, error) {
require.Equal(t, api.JsonMediaType, r.Header.Get("Accept"))
require.Equal(t, api.JsonMediaType, r.Header.Get(api.AcceptHeader))
require.Equal(t, expectedPath, r.URL.Path)
return &http.Response{
StatusCode: http.StatusOK,
@@ -533,7 +533,7 @@ func TestClient_GetHeader(t *testing.T) {
t.Run("electra ssz", func(t *testing.T) {
hc := &http.Client{
Transport: roundtrip(func(r *http.Request) (*http.Response, error) {
require.Equal(t, api.OctetStreamMediaType, r.Header.Get("Accept"))
require.Equal(t, api.OctetStreamMediaType, r.Header.Get(api.AcceptHeader))
require.Equal(t, expectedPath, r.URL.Path)
epr := &ExecHeaderResponseElectra{}
require.NoError(t, json.Unmarshal([]byte(testExampleHeaderResponseElectra), epr))
@@ -542,7 +542,7 @@ func TestClient_GetHeader(t *testing.T) {
ssz, err := pro.MarshalSSZ()
require.NoError(t, err)
header := http.Header{}
header.Set(api.VersionHeader, "electra")
header.Set(api.EthConsensusVersionHeader, "electra")
return &http.Response{
StatusCode: http.StatusOK,
Header: header,
@@ -612,9 +612,9 @@ func TestSubmitBlindedBlock(t *testing.T) {
hc := &http.Client{
Transport: roundtrip(func(r *http.Request) (*http.Response, error) {
require.Equal(t, postBlindedBeaconBlockPath, r.URL.Path)
require.Equal(t, "bellatrix", r.Header.Get("Eth-Consensus-Version"))
require.Equal(t, api.JsonMediaType, r.Header.Get("Content-Type"))
require.Equal(t, api.JsonMediaType, r.Header.Get("Accept"))
require.Equal(t, "bellatrix", r.Header.Get(api.EthConsensusVersionHeader))
require.Equal(t, api.JsonMediaType, r.Header.Get(api.ContentTypeHeader))
require.Equal(t, api.JsonMediaType, r.Header.Get(api.AcceptHeader))
return &http.Response{
StatusCode: http.StatusOK,
Body: io.NopCloser(bytes.NewBufferString(testExampleExecutionPayload)),
@@ -640,9 +640,9 @@ func TestSubmitBlindedBlock(t *testing.T) {
hc := &http.Client{
Transport: roundtrip(func(r *http.Request) (*http.Response, error) {
require.Equal(t, postBlindedBeaconBlockPath, r.URL.Path)
require.Equal(t, "bellatrix", r.Header.Get(api.VersionHeader))
require.Equal(t, api.OctetStreamMediaType, r.Header.Get("Content-Type"))
require.Equal(t, api.OctetStreamMediaType, r.Header.Get("Accept"))
require.Equal(t, "bellatrix", r.Header.Get(api.EthConsensusVersionHeader))
require.Equal(t, api.OctetStreamMediaType, r.Header.Get(api.ContentTypeHeader))
require.Equal(t, api.OctetStreamMediaType, r.Header.Get(api.AcceptHeader))
epr := &ExecutionPayloadResponse{}
require.NoError(t, json.Unmarshal([]byte(testExampleExecutionPayload), epr))
ep := &structs.ExecutionPayload{}
@@ -652,7 +652,7 @@ func TestSubmitBlindedBlock(t *testing.T) {
ssz, err := pro.MarshalSSZ()
require.NoError(t, err)
header := http.Header{}
header.Set(api.VersionHeader, "bellatrix")
header.Set(api.EthConsensusVersionHeader, "bellatrix")
return &http.Response{
StatusCode: http.StatusOK,
Header: header,
@@ -680,9 +680,9 @@ func TestSubmitBlindedBlock(t *testing.T) {
hc := &http.Client{
Transport: roundtrip(func(r *http.Request) (*http.Response, error) {
require.Equal(t, postBlindedBeaconBlockPath, r.URL.Path)
require.Equal(t, "capella", r.Header.Get(api.VersionHeader))
require.Equal(t, api.JsonMediaType, r.Header.Get("Content-Type"))
require.Equal(t, api.JsonMediaType, r.Header.Get("Accept"))
require.Equal(t, "capella", r.Header.Get(api.EthConsensusVersionHeader))
require.Equal(t, api.JsonMediaType, r.Header.Get(api.ContentTypeHeader))
require.Equal(t, api.JsonMediaType, r.Header.Get(api.AcceptHeader))
return &http.Response{
StatusCode: http.StatusOK,
Body: io.NopCloser(bytes.NewBufferString(testExampleExecutionPayloadCapella)),
@@ -710,9 +710,9 @@ func TestSubmitBlindedBlock(t *testing.T) {
hc := &http.Client{
Transport: roundtrip(func(r *http.Request) (*http.Response, error) {
require.Equal(t, postBlindedBeaconBlockPath, r.URL.Path)
require.Equal(t, "capella", r.Header.Get(api.VersionHeader))
require.Equal(t, api.OctetStreamMediaType, r.Header.Get("Content-Type"))
require.Equal(t, api.OctetStreamMediaType, r.Header.Get("Accept"))
require.Equal(t, "capella", r.Header.Get(api.EthConsensusVersionHeader))
require.Equal(t, api.OctetStreamMediaType, r.Header.Get(api.ContentTypeHeader))
require.Equal(t, api.OctetStreamMediaType, r.Header.Get(api.AcceptHeader))
epr := &ExecutionPayloadResponse{}
require.NoError(t, json.Unmarshal([]byte(testExampleExecutionPayloadCapella), epr))
ep := &structs.ExecutionPayloadCapella{}
@@ -722,7 +722,7 @@ func TestSubmitBlindedBlock(t *testing.T) {
ssz, err := pro.MarshalSSZ()
require.NoError(t, err)
header := http.Header{}
header.Set(api.VersionHeader, "capella")
header.Set(api.EthConsensusVersionHeader, "capella")
return &http.Response{
StatusCode: http.StatusOK,
Header: header,
@@ -753,9 +753,9 @@ func TestSubmitBlindedBlock(t *testing.T) {
hc := &http.Client{
Transport: roundtrip(func(r *http.Request) (*http.Response, error) {
require.Equal(t, postBlindedBeaconBlockPath, r.URL.Path)
require.Equal(t, "deneb", r.Header.Get(api.VersionHeader))
require.Equal(t, api.JsonMediaType, r.Header.Get("Content-Type"))
require.Equal(t, api.JsonMediaType, r.Header.Get("Accept"))
require.Equal(t, "deneb", r.Header.Get(api.EthConsensusVersionHeader))
require.Equal(t, api.JsonMediaType, r.Header.Get(api.ContentTypeHeader))
require.Equal(t, api.JsonMediaType, r.Header.Get(api.AcceptHeader))
var req structs.SignedBlindedBeaconBlockDeneb
err := json.NewDecoder(r.Body).Decode(&req)
require.NoError(t, err)
@@ -793,9 +793,9 @@ func TestSubmitBlindedBlock(t *testing.T) {
hc := &http.Client{
Transport: roundtrip(func(r *http.Request) (*http.Response, error) {
require.Equal(t, postBlindedBeaconBlockPath, r.URL.Path)
require.Equal(t, "deneb", r.Header.Get(api.VersionHeader))
require.Equal(t, api.OctetStreamMediaType, r.Header.Get("Content-Type"))
require.Equal(t, api.OctetStreamMediaType, r.Header.Get("Accept"))
require.Equal(t, "deneb", r.Header.Get(api.EthConsensusVersionHeader))
require.Equal(t, api.OctetStreamMediaType, r.Header.Get(api.ContentTypeHeader))
require.Equal(t, api.OctetStreamMediaType, r.Header.Get(api.AcceptHeader))
epr := &ExecPayloadResponseDeneb{}
require.NoError(t, json.Unmarshal([]byte(testExampleExecutionPayloadDeneb), epr))
pro, blob, err := epr.ToProto()
@@ -807,7 +807,7 @@ func TestSubmitBlindedBlock(t *testing.T) {
ssz, err := combined.MarshalSSZ()
require.NoError(t, err)
header := http.Header{}
header.Set(api.VersionHeader, "deneb")
header.Set(api.EthConsensusVersionHeader, "deneb")
return &http.Response{
StatusCode: http.StatusOK,
Header: header,
@@ -840,9 +840,9 @@ func TestSubmitBlindedBlock(t *testing.T) {
hc := &http.Client{
Transport: roundtrip(func(r *http.Request) (*http.Response, error) {
require.Equal(t, postBlindedBeaconBlockPath, r.URL.Path)
require.Equal(t, "electra", r.Header.Get(api.VersionHeader))
require.Equal(t, api.JsonMediaType, r.Header.Get("Content-Type"))
require.Equal(t, api.JsonMediaType, r.Header.Get("Accept"))
require.Equal(t, "electra", r.Header.Get(api.EthConsensusVersionHeader))
require.Equal(t, api.JsonMediaType, r.Header.Get(api.ContentTypeHeader))
require.Equal(t, api.JsonMediaType, r.Header.Get(api.AcceptHeader))
var req structs.SignedBlindedBeaconBlockElectra
err := json.NewDecoder(r.Body).Decode(&req)
require.NoError(t, err)
@@ -880,9 +880,9 @@ func TestSubmitBlindedBlock(t *testing.T) {
hc := &http.Client{
Transport: roundtrip(func(r *http.Request) (*http.Response, error) {
require.Equal(t, postBlindedBeaconBlockPath, r.URL.Path)
require.Equal(t, "electra", r.Header.Get(api.VersionHeader))
require.Equal(t, api.OctetStreamMediaType, r.Header.Get("Content-Type"))
require.Equal(t, api.OctetStreamMediaType, r.Header.Get("Accept"))
require.Equal(t, "electra", r.Header.Get(api.EthConsensusVersionHeader))
require.Equal(t, api.OctetStreamMediaType, r.Header.Get(api.ContentTypeHeader))
require.Equal(t, api.OctetStreamMediaType, r.Header.Get(api.AcceptHeader))
epr := &ExecPayloadResponseDeneb{}
require.NoError(t, json.Unmarshal([]byte(testExampleExecutionPayloadDeneb), epr))
pro, blob, err := epr.ToProto()
@@ -894,7 +894,7 @@ func TestSubmitBlindedBlock(t *testing.T) {
ssz, err := combined.MarshalSSZ()
require.NoError(t, err)
header := http.Header{}
header.Set(api.VersionHeader, "electra")
header.Set(api.EthConsensusVersionHeader, "electra")
return &http.Response{
StatusCode: http.StatusOK,
Header: header,
@@ -1566,9 +1566,9 @@ func TestSubmitBlindedBlockPostFulu(t *testing.T) {
hc := &http.Client{
Transport: roundtrip(func(r *http.Request) (*http.Response, error) {
require.Equal(t, postBlindedBeaconBlockV2Path, r.URL.Path)
require.Equal(t, "bellatrix", r.Header.Get("Eth-Consensus-Version"))
require.Equal(t, api.JsonMediaType, r.Header.Get("Content-Type"))
require.Equal(t, api.JsonMediaType, r.Header.Get("Accept"))
require.Equal(t, "bellatrix", r.Header.Get(api.EthConsensusVersionHeader))
require.Equal(t, api.JsonMediaType, r.Header.Get(api.ContentTypeHeader))
require.Equal(t, api.JsonMediaType, r.Header.Get(api.AcceptHeader))
// Post-Fulu: only return status code, no payload
return &http.Response{
StatusCode: http.StatusAccepted,
@@ -1591,9 +1591,9 @@ func TestSubmitBlindedBlockPostFulu(t *testing.T) {
hc := &http.Client{
Transport: roundtrip(func(r *http.Request) (*http.Response, error) {
require.Equal(t, postBlindedBeaconBlockV2Path, r.URL.Path)
require.Equal(t, "bellatrix", r.Header.Get(api.VersionHeader))
require.Equal(t, api.OctetStreamMediaType, r.Header.Get("Content-Type"))
require.Equal(t, api.OctetStreamMediaType, r.Header.Get("Accept"))
require.Equal(t, "bellatrix", r.Header.Get(api.EthConsensusVersionHeader))
require.Equal(t, api.OctetStreamMediaType, r.Header.Get(api.ContentTypeHeader))
require.Equal(t, api.OctetStreamMediaType, r.Header.Get(api.AcceptHeader))
// Post-Fulu: only return status code, no payload
return &http.Response{
StatusCode: http.StatusAccepted,
@@ -1617,7 +1617,7 @@ func TestSubmitBlindedBlockPostFulu(t *testing.T) {
hc := &http.Client{
Transport: roundtrip(func(r *http.Request) (*http.Response, error) {
require.Equal(t, postBlindedBeaconBlockV2Path, r.URL.Path)
require.Equal(t, "bellatrix", r.Header.Get("Eth-Consensus-Version"))
require.Equal(t, "bellatrix", r.Header.Get(api.EthConsensusVersionHeader))
message := ErrorMessage{
Code: 400,
Message: "Bad Request",

View File

@@ -73,8 +73,8 @@ func (h *EventStream) Subscribe(eventsChannel chan<- *Event) {
Data: []byte(errors.Wrap(err, "failed to create HTTP request").Error()),
}
}
req.Header.Set("Accept", api.EventStreamMediaType)
req.Header.Set("Connection", api.KeepAlive)
req.Header.Set(api.AcceptHeader, api.EventStreamMediaType)
req.Header.Set(api.ConnectionHeader, api.KeepAlive)
resp, err := h.httpClient.Do(req)
if err != nil {
eventsChannel <- &Event{

View File

@@ -4,6 +4,8 @@ import (
"fmt"
"net/http"
"time"
"github.com/OffchainLabs/prysm/v6/api"
)
// ReqOption is a request functional option.
@@ -12,14 +14,14 @@ type ReqOption func(*http.Request)
// WithSSZEncoding is a request functional option that adds SSZ encoding header.
func WithSSZEncoding() ReqOption {
return func(req *http.Request) {
req.Header.Set("Accept", "application/octet-stream")
req.Header.Set(api.AcceptEncodingHeader, api.OctetStreamMediaType)
}
}
// WithAuthorizationToken is a request functional option that adds header for authorization token.
func WithAuthorizationToken(token string) ReqOption {
return func(req *http.Request) {
req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", token))
req.Header.Set(api.AuthorizationHeader, fmt.Sprintf("%s %s", api.BearerAuthorization, token))
}
}

25
api/client/transport.go Normal file
View File

@@ -0,0 +1,25 @@
package client
import "net/http"
// CustomHeadersTransport adds custom headers to each request
type CustomHeadersTransport struct {
base http.RoundTripper
headers map[string][]string
}
func NewCustomHeadersTransport(base http.RoundTripper, headers map[string][]string) *CustomHeadersTransport {
return &CustomHeadersTransport{
base: base,
headers: headers,
}
}
func (t *CustomHeadersTransport) RoundTrip(req *http.Request) (*http.Response, error) {
for header, values := range t.headers {
for _, value := range values {
req.Header.Add(header, value)
}
}
return t.base.RoundTrip(req)
}

View File

@@ -0,0 +1,25 @@
package client
import (
"net/http"
"net/http/httptest"
"testing"
"github.com/OffchainLabs/prysm/v6/testing/assert"
"github.com/OffchainLabs/prysm/v6/testing/require"
)
type noopTransport struct{}
func (*noopTransport) RoundTrip(*http.Request) (*http.Response, error) {
return nil, nil
}
func TestRoundTrip(t *testing.T) {
tr := &CustomHeadersTransport{base: &noopTransport{}, headers: map[string][]string{"key1": []string{"value1", "value2"}, "key2": []string{"value3"}}}
req := httptest.NewRequest("GET", "http://foo", nil)
_, err := tr.RoundTrip(req)
require.NoError(t, err)
assert.DeepEqual(t, []string{"value1", "value2"}, req.Header.Values("key1"))
assert.DeepEqual(t, []string{"value3"}, req.Header.Values("key2"))
}

View File

@@ -3,18 +3,38 @@ package api
import "net/http"
const (
VersionHeader = "Eth-Consensus-Version"
ExecutionPayloadBlindedHeader = "Eth-Execution-Payload-Blinded"
ExecutionPayloadValueHeader = "Eth-Execution-Payload-Value"
ConsensusBlockValueHeader = "Eth-Consensus-Block-Value"
JsonMediaType = "application/json"
OctetStreamMediaType = "application/octet-stream"
EventStreamMediaType = "text/event-stream"
KeepAlive = "keep-alive"
// Headers
EthConsensusVersionHeader = "Eth-Consensus-Version"
EthExecutionPayloadBlindedHeader = "Eth-Execution-Payload-Blinded"
EthExecutionPayloadValueHeader = "Eth-Execution-Payload-Value"
EthConsensusBlockValueHeader = "Eth-Consensus-Block-Value"
AcceptEncodingHeader = "Accept-Encoding"
AcceptHeader = "Accept"
AccessControlAllowOriginHeader = "Access-Control-Allow-Origin"
AuthorizationHeader = "Authorization"
CacheControlHeader = "Cache-Control"
ConnectionHeader = "Connection"
ContentEncodingHeader = "Content-Encoding"
ContentLengthHeader = "Content-Length"
ContentTypeHeader = "Content-Type"
HostHeader = "Host"
OriginHeader = "Origin"
UserAgentHeader = "User-Agent"
// Header values
JsonMediaType = "application/json"
OctetStreamMediaType = "application/octet-stream"
PlainMediaType = "text/plain"
EventStreamMediaType = "text/event-stream"
KeepAlive = "keep-alive"
GzipEncoding = "gzip"
BasicAuthorization = "Basic"
BearerAuthorization = "Bearer"
NoCache = "no-cache"
)
// SetSSEHeaders sets the headers needed for a server-sent event response.
func SetSSEHeaders(w http.ResponseWriter) {
w.Header().Set("Content-Type", EventStreamMediaType)
w.Header().Set("Connection", KeepAlive)
w.Header().Set(ContentTypeHeader, EventStreamMediaType)
w.Header().Set(ConnectionHeader, KeepAlive)
}

View File

@@ -47,7 +47,7 @@ func ContentTypeHandler(acceptedMediaTypes []string) Middleware {
next.ServeHTTP(w, r)
return
}
contentType := r.Header.Get("Content-Type")
contentType := r.Header.Get(api.ContentTypeHeader)
if contentType == "" {
http.Error(w, "Content-Type header is missing", http.StatusUnsupportedMediaType)
return
@@ -75,7 +75,7 @@ func ContentTypeHandler(acceptedMediaTypes []string) Middleware {
func AcceptHeaderHandler(serverAcceptedTypes []string) Middleware {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if _, ok := apiutil.Negotiate(r.Header.Get("Accept"), serverAcceptedTypes); !ok {
if _, ok := apiutil.Negotiate(r.Header.Get(api.AcceptHeader), serverAcceptedTypes); !ok {
http.Error(w, "Not Acceptable", http.StatusNotAcceptable)
return
}
@@ -88,7 +88,7 @@ func AcceptHeaderHandler(serverAcceptedTypes []string) Middleware {
func AcceptEncodingHeaderHandler() Middleware {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if !strings.Contains(r.Header.Get("Accept-Encoding"), "gzip") {
if !strings.Contains(r.Header.Get(api.AcceptEncodingHeader), api.GzipEncoding) {
next.ServeHTTP(w, r)
return
}
@@ -116,10 +116,10 @@ type gzipResponseWriter struct {
}
func (g *gzipResponseWriter) WriteHeader(statusCode int) {
if strings.Contains(g.Header().Get("Content-Type"), api.JsonMediaType) {
if strings.Contains(g.Header().Get(api.ContentTypeHeader), api.JsonMediaType) {
// Removing the current Content-Length because zipping will change it.
g.Header().Del("Content-Length")
g.Header().Set("Content-Encoding", "gzip")
g.Header().Del(api.ContentLengthHeader)
g.Header().Set(api.ContentEncodingHeader, api.GzipEncoding)
g.zip = true
}

View File

@@ -132,7 +132,7 @@ func TestContentTypeHandler(t *testing.T) {
}
req := httptest.NewRequest(httpMethod, "/", nil)
if tt.contentType != "" {
req.Header.Set("Content-Type", tt.contentType)
req.Header.Set(api.ContentTypeHeader, tt.contentType)
}
rr := httptest.NewRecorder()
@@ -148,7 +148,7 @@ func TestContentTypeHandler(t *testing.T) {
func TestAcceptEncodingHeaderHandler(t *testing.T) {
dummyContent := "Test gzip middleware content"
nextHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", r.Header.Get("Accept"))
w.Header().Set(api.ContentTypeHeader, r.Header.Get(api.AcceptHeader))
w.WriteHeader(http.StatusOK)
_, err := w.Write([]byte(dummyContent))
require.NoError(t, err)
@@ -165,7 +165,7 @@ func TestAcceptEncodingHeaderHandler(t *testing.T) {
{
name: "Accept gzip",
accept: api.JsonMediaType,
acceptEncoding: "gzip",
acceptEncoding: api.GzipEncoding,
expectCompressed: true,
},
{
@@ -189,7 +189,7 @@ func TestAcceptEncodingHeaderHandler(t *testing.T) {
{
name: "SSZ",
accept: api.OctetStreamMediaType,
acceptEncoding: "gzip",
acceptEncoding: api.GzipEncoding,
expectCompressed: false,
},
}
@@ -197,16 +197,16 @@ func TestAcceptEncodingHeaderHandler(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
req := httptest.NewRequest("GET", "/", nil)
req.Header.Set("Accept", tt.accept)
req.Header.Set(api.AcceptHeader, tt.accept)
if tt.acceptEncoding != "" {
req.Header.Set("Accept-Encoding", tt.acceptEncoding)
req.Header.Set(api.AcceptEncodingHeader, tt.acceptEncoding)
}
rr := &frozenHeaderRecorder{ResponseRecorder: httptest.NewRecorder()}
handler.ServeHTTP(rr, req)
if tt.expectCompressed {
require.Equal(t, "gzip", rr.frozenHeader.Get("Content-Encoding"), "Expected Content-Encoding header to be 'gzip'")
require.Equal(t, api.GzipEncoding, rr.frozenHeader.Get(api.ContentEncodingHeader), "Expected Content-Encoding header to be 'gzip'")
compressedBody := rr.Body.Bytes()
require.NotEqual(t, dummyContent, string(compressedBody), "Response body should be compressed and differ from the original")
@@ -230,7 +230,7 @@ func TestAcceptEncodingHeaderHandler(t *testing.T) {
}
func TestAcceptHeaderHandler(t *testing.T) {
acceptedTypes := []string{"application/json", "application/octet-stream"}
acceptedTypes := []string{api.JsonMediaType, api.OctetStreamMediaType}
nextHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
_, err := w.Write([]byte("next handler"))
@@ -295,7 +295,7 @@ func TestAcceptHeaderHandler(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
req := httptest.NewRequest("GET", "/", nil)
if tt.acceptHeader != "" {
req.Header.Set("Accept", tt.acceptHeader)
req.Header.Set(api.AcceptHeader, tt.acceptHeader)
}
rr := httptest.NewRecorder()

View File

@@ -472,8 +472,8 @@ func (s *Service) removeStartupState() {
func (s *Service) updateCustodyInfoInDB(slot primitives.Slot) (primitives.Slot, uint64, error) {
isSubscribedToAllDataSubnets := flags.Get().SubscribeAllDataSubnets
beaconConfig := params.BeaconConfig()
custodyRequirement := beaconConfig.CustodyRequirement
cfg := params.BeaconConfig()
custodyRequirement := cfg.CustodyRequirement
// Check if the node was previously subscribed to all data subnets, and if so,
// store the new status accordingly.
@@ -493,7 +493,7 @@ func (s *Service) updateCustodyInfoInDB(slot primitives.Slot) (primitives.Slot,
// Compute the custody group count.
custodyGroupCount := custodyRequirement
if isSubscribedToAllDataSubnets {
custodyGroupCount = beaconConfig.NumberOfCustodyGroups
custodyGroupCount = cfg.NumberOfCustodyGroups
}
// Safely compute the fulu fork slot.
@@ -536,11 +536,11 @@ func spawnCountdownIfPreGenesis(ctx context.Context, genesisTime time.Time, db d
}
func fuluForkSlot() (primitives.Slot, error) {
beaconConfig := params.BeaconConfig()
cfg := params.BeaconConfig()
fuluForkEpoch := beaconConfig.FuluForkEpoch
if fuluForkEpoch == beaconConfig.FarFutureEpoch {
return beaconConfig.FarFutureSlot, nil
fuluForkEpoch := cfg.FuluForkEpoch
if fuluForkEpoch == cfg.FarFutureEpoch {
return cfg.FarFutureSlot, nil
}
forkFuluSlot, err := slots.EpochStart(fuluForkEpoch)

View File

@@ -472,6 +472,36 @@ func (s *ChainService) HasBlock(ctx context.Context, rt [32]byte) bool {
return s.InitSyncBlockRoots[rt]
}
func (s *ChainService) AvailableBlocks(ctx context.Context, blockRoots [][32]byte) map[[32]byte]bool {
if s.DB == nil {
return nil
}
count := len(blockRoots)
availableRoots := make(map[[32]byte]bool, count)
notInDBRoots := make([][32]byte, 0, count)
for _, root := range blockRoots {
if s.DB.HasBlock(ctx, root) {
availableRoots[root] = true
continue
}
notInDBRoots = append(notInDBRoots, root)
}
if s.InitSyncBlockRoots == nil {
return availableRoots
}
for _, root := range notInDBRoots {
if s.InitSyncBlockRoots[root] {
availableRoots[root] = true
}
}
return availableRoots
}
// RecentBlockSlot mocks the same method in the chain service.
func (s *ChainService) RecentBlockSlot([32]byte) (primitives.Slot, error) {
return s.BlockSlot, nil

View File

@@ -3,6 +3,7 @@ package blockchain
import (
"context"
"fmt"
"slices"
"github.com/OffchainLabs/prysm/v6/beacon-chain/db/filters"
"github.com/OffchainLabs/prysm/v6/config/params"
@@ -81,12 +82,10 @@ func (v *WeakSubjectivityVerifier) VerifyWeakSubjectivity(ctx context.Context, f
if err != nil {
return errors.Wrap(err, "error while retrieving block roots to verify weak subjectivity")
}
for _, root := range roots {
if v.root == root {
log.Info("Weak subjectivity check has passed!!")
v.verified = true
return nil
}
if slices.Contains(roots, v.root) {
log.Info("Weak subjectivity check has passed!!")
v.verified = true
return nil
}
return errors.Wrap(errWSBlockNotFoundInEpoch, fmt.Sprintf("root=%#x, epoch=%d", v.root, v.epoch))
}

View File

@@ -401,7 +401,7 @@ func ComputeProposerIndex(bState state.ReadOnlyBeaconState, activeIndices []prim
return 0, errors.New("empty active indices list")
}
hashFunc := hash.CustomSHA256Hasher()
beaconConfig := params.BeaconConfig()
cfg := params.BeaconConfig()
seedBuffer := make([]byte, len(seed)+8)
copy(seedBuffer, seed[:])
@@ -426,14 +426,14 @@ func ComputeProposerIndex(bState state.ReadOnlyBeaconState, activeIndices []prim
offset := (i % 16) * 2
randomValue := uint64(randomBytes[offset]) | uint64(randomBytes[offset+1])<<8
if effectiveBal*fieldparams.MaxRandomValueElectra >= beaconConfig.MaxEffectiveBalanceElectra*randomValue {
if effectiveBal*fieldparams.MaxRandomValueElectra >= cfg.MaxEffectiveBalanceElectra*randomValue {
return candidateIndex, nil
}
} else {
binary.LittleEndian.PutUint64(seedBuffer[len(seed):], i/32)
randomByte := hashFunc(seedBuffer)[i%32]
if effectiveBal*fieldparams.MaxRandomByte >= beaconConfig.MaxEffectiveBalance*uint64(randomByte) {
if effectiveBal*fieldparams.MaxRandomByte >= cfg.MaxEffectiveBalance*uint64(randomByte) {
return candidateIndex, nil
}
}

View File

@@ -89,14 +89,14 @@ func CustodyGroups(nodeId enode.ID, custodyGroupCount uint64) ([]uint64, error)
// ComputeColumnsForCustodyGroup computes the columns for a given custody group.
// https://github.com/ethereum/consensus-specs/blob/master/specs/fulu/das-core.md#compute_columns_for_custody_group
func ComputeColumnsForCustodyGroup(custodyGroup uint64) ([]uint64, error) {
beaconConfig := params.BeaconConfig()
numberOfCustodyGroups := beaconConfig.NumberOfCustodyGroups
cfg := params.BeaconConfig()
numberOfCustodyGroups := cfg.NumberOfCustodyGroups
if custodyGroup >= numberOfCustodyGroups {
return nil, ErrCustodyGroupTooLarge
}
numberOfColumns := beaconConfig.NumberOfColumns
numberOfColumns := cfg.NumberOfColumns
columnsPerGroup := numberOfColumns / numberOfCustodyGroups
@@ -112,9 +112,9 @@ func ComputeColumnsForCustodyGroup(custodyGroup uint64) ([]uint64, error) {
// ComputeCustodyGroupForColumn computes the custody group for a given column.
// It is the reciprocal function of ComputeColumnsForCustodyGroup.
func ComputeCustodyGroupForColumn(columnIndex uint64) (uint64, error) {
beaconConfig := params.BeaconConfig()
numberOfColumns := beaconConfig.NumberOfColumns
numberOfCustodyGroups := beaconConfig.NumberOfCustodyGroups
cfg := params.BeaconConfig()
numberOfColumns := cfg.NumberOfColumns
numberOfCustodyGroups := cfg.NumberOfCustodyGroups
if columnIndex >= numberOfColumns {
return 0, ErrIndexTooLarge

View File

@@ -84,10 +84,10 @@ func ValidatorsCustodyRequirement(state beaconState.ReadOnlyBeaconState, validat
totalNodeBalance += validator.EffectiveBalance()
}
beaconConfig := params.BeaconConfig()
numberOfCustodyGroups := beaconConfig.NumberOfCustodyGroups
validatorCustodyRequirement := beaconConfig.ValidatorCustodyRequirement
balancePerAdditionalCustodyGroup := beaconConfig.BalancePerAdditionalCustodyGroup
cfg := params.BeaconConfig()
numberOfCustodyGroups := cfg.NumberOfCustodyGroups
validatorCustodyRequirement := cfg.ValidatorCustodyRequirement
balancePerAdditionalCustodyGroup := cfg.BalancePerAdditionalCustodyGroup
count := totalNodeBalance / balancePerAdditionalCustodyGroup
return min(max(count, validatorCustodyRequirement), numberOfCustodyGroups), nil

View File

@@ -196,7 +196,7 @@ func TestAltairCompatible(t *testing.T) {
}
func TestCanUpgradeTo(t *testing.T) {
beaconConfig := params.BeaconConfig()
cfg := params.BeaconConfig()
outerTestCases := []struct {
name string
@@ -205,32 +205,32 @@ func TestCanUpgradeTo(t *testing.T) {
}{
{
name: "Altair",
forkEpoch: &beaconConfig.AltairForkEpoch,
forkEpoch: &cfg.AltairForkEpoch,
upgradeFunc: time.CanUpgradeToAltair,
},
{
name: "Bellatrix",
forkEpoch: &beaconConfig.BellatrixForkEpoch,
forkEpoch: &cfg.BellatrixForkEpoch,
upgradeFunc: time.CanUpgradeToBellatrix,
},
{
name: "Capella",
forkEpoch: &beaconConfig.CapellaForkEpoch,
forkEpoch: &cfg.CapellaForkEpoch,
upgradeFunc: time.CanUpgradeToCapella,
},
{
name: "Deneb",
forkEpoch: &beaconConfig.DenebForkEpoch,
forkEpoch: &cfg.DenebForkEpoch,
upgradeFunc: time.CanUpgradeToDeneb,
},
{
name: "Electra",
forkEpoch: &beaconConfig.ElectraForkEpoch,
forkEpoch: &cfg.ElectraForkEpoch,
upgradeFunc: time.CanUpgradeToElectra,
},
{
name: "Fulu",
forkEpoch: &beaconConfig.FuluForkEpoch,
forkEpoch: &cfg.FuluForkEpoch,
upgradeFunc: time.CanUpgradeToFulu,
},
}
@@ -238,7 +238,7 @@ func TestCanUpgradeTo(t *testing.T) {
for _, otc := range outerTestCases {
params.SetupTestConfigCleanup(t)
*otc.forkEpoch = 5
params.OverrideBeaconConfig(beaconConfig)
params.OverrideBeaconConfig(cfg)
innerTestCases := []struct {
name string

View File

@@ -212,7 +212,8 @@ func filterNoop(_ string) bool {
return true
}
func isRootDir(p string) bool {
// IsBlockRootDir returns true if the path segment looks like a block root directory.
func IsBlockRootDir(p string) bool {
dir := filepath.Base(p)
return len(dir) == rootStringLen && strings.HasPrefix(dir, "0x")
}

View File

@@ -188,7 +188,7 @@ func TestListDir(t *testing.T) {
name: "root filter",
dirPath: ".",
expected: []string{childlessBlob.name, blobWithSsz.name, blobWithSszAndTmp.name},
filter: isRootDir,
filter: IsBlockRootDir,
},
{
name: "ssz filter",

View File

@@ -19,12 +19,14 @@ import (
const (
// Full root in directory will be 66 chars, eg:
// >>> len('0x0002fb4db510b8618b04dc82d023793739c26346a8b02eb73482e24b0fec0555') == 66
rootStringLen = 66
sszExt = "ssz"
partExt = "part"
periodicEpochBaseDir = "by-epoch"
rootStringLen = 66
sszExt = "ssz"
partExt = "part"
)
// PeriodicEpochBaseDir is the name of the base directory for the by-epoch layout.
const PeriodicEpochBaseDir = "by-epoch"
const (
LayoutNameFlat = "flat"
LayoutNameByEpoch = "by-epoch"
@@ -130,11 +132,11 @@ func migrateLayout(fs afero.Fs, from, to fsLayout, cache *blobStorageSummaryCach
if iter.atEOF() {
return errLayoutNotDetected
}
log.WithField("fromLayout", from.name()).WithField("toLayout", to.name()).Info("Migrating blob filesystem layout. This one-time operation can take extra time (up to a few minutes for systems with extended blob storage and a cold disk cache).")
lastMoved := ""
parentDirs := make(map[string]bool) // this map should have < 65k keys by design
moved := 0
dc := newDirCleaner()
migrationLogged := false
for ident, err := iter.next(); !errors.Is(err, io.EOF); ident, err = iter.next() {
if err != nil {
if errors.Is(err, errIdentFailure) {
@@ -146,6 +148,11 @@ func migrateLayout(fs afero.Fs, from, to fsLayout, cache *blobStorageSummaryCach
}
return errors.Wrapf(errMigrationFailure, "failed to iterate previous layout structure while migrating blobs, err=%s", err.Error())
}
if !migrationLogged {
log.WithField("fromLayout", from.name()).WithField("toLayout", to.name()).
Info("Migrating blob filesystem layout. This one-time operation can take extra time (up to a few minutes for systems with extended blob storage and a cold disk cache).")
migrationLogged = true
}
src := from.dir(ident)
target := to.dir(ident)
if src != lastMoved {

View File

@@ -34,7 +34,7 @@ func (l *periodicEpochLayout) name() string {
func (l *periodicEpochLayout) blockParentDirs(ident blobIdent) []string {
return []string{
periodicEpochBaseDir,
PeriodicEpochBaseDir,
l.periodDir(ident.epoch),
l.epochDir(ident.epoch),
}
@@ -50,28 +50,28 @@ func (l *periodicEpochLayout) notify(ident blobIdent) error {
// If before == 0, it won't be used as a filter and all idents will be returned.
func (l *periodicEpochLayout) iterateIdents(before primitives.Epoch) (*identIterator, error) {
_, err := l.fs.Stat(periodicEpochBaseDir)
_, err := l.fs.Stat(PeriodicEpochBaseDir)
if err != nil {
if os.IsNotExist(err) {
return &identIterator{eof: true}, nil // The directory is non-existent, which is fine; stop iteration.
}
return nil, errors.Wrapf(err, "error reading path %s", periodicEpochBaseDir)
return nil, errors.Wrapf(err, "error reading path %s", PeriodicEpochBaseDir)
}
// iterate root, which should have directories named by "period"
entries, err := listDir(l.fs, periodicEpochBaseDir)
entries, err := listDir(l.fs, PeriodicEpochBaseDir)
if err != nil {
return nil, errors.Wrapf(err, "failed to list %s", periodicEpochBaseDir)
return nil, errors.Wrapf(err, "failed to list %s", PeriodicEpochBaseDir)
}
return &identIterator{
fs: l.fs,
path: periodicEpochBaseDir,
path: PeriodicEpochBaseDir,
// Please see comments on the `layers` field in `identIterator`` if the role of the layers is unclear.
layers: []layoutLayer{
{populateIdent: populateNoop, filter: isBeforePeriod(before)},
{populateIdent: populateEpoch, filter: isBeforeEpoch(before)},
{populateIdent: populateRoot, filter: isRootDir}, // extract root from path
{populateIdent: populateIndex, filter: isSszFile}, // extract index from filename
{populateIdent: populateRoot, filter: IsBlockRootDir}, // extract root from path
{populateIdent: populateIndex, filter: isSszFile}, // extract index from filename
},
entries: entries,
}, nil
@@ -98,7 +98,7 @@ func (l *periodicEpochLayout) epochDir(epoch primitives.Epoch) string {
}
func (l *periodicEpochLayout) periodDir(epoch primitives.Epoch) string {
return filepath.Join(periodicEpochBaseDir, fmt.Sprintf("%d", periodForEpoch(epoch)))
return filepath.Join(PeriodicEpochBaseDir, fmt.Sprintf("%d", periodForEpoch(epoch)))
}
func (l *periodicEpochLayout) sszPath(n blobIdent) string {

View File

@@ -30,7 +30,7 @@ func (l *flatLayout) iterateIdents(before primitives.Epoch) (*identIterator, err
if os.IsNotExist(err) {
return &identIterator{eof: true}, nil // The directory is non-existent, which is fine; stop iteration.
}
return nil, errors.Wrapf(err, "error reading path %s", periodicEpochBaseDir)
return nil, errors.Wrap(err, "error reading blob base dir")
}
entries, err := listDir(l.fs, ".")
if err != nil {
@@ -199,10 +199,10 @@ func (l *flatSlotReader) isSSZAndBefore(fname string) bool {
// the epoch can be determined.
func isFlatCachedAndBefore(cache *blobStorageSummaryCache, before primitives.Epoch) func(string) bool {
if before == 0 {
return isRootDir
return IsBlockRootDir
}
return func(p string) bool {
if !isRootDir(p) {
if !IsBlockRootDir(p) {
return false
}
root, err := rootFromPath(p)

View File

@@ -28,6 +28,7 @@ type ReadOnlyDatabase interface {
BlocksBySlot(ctx context.Context, slot primitives.Slot) ([]interfaces.ReadOnlySignedBeaconBlock, error)
BlockRootsBySlot(ctx context.Context, slot primitives.Slot) (bool, [][32]byte, error)
HasBlock(ctx context.Context, blockRoot [32]byte) bool
AvailableBlocks(ctx context.Context, blockRoots [][32]byte) map[[32]byte]bool
GenesisBlock(ctx context.Context) (interfaces.ReadOnlySignedBeaconBlock, error)
GenesisBlockRoot(ctx context.Context) ([32]byte, error)
IsFinalizedBlock(ctx context.Context, blockRoot [32]byte) bool

View File

@@ -336,6 +336,42 @@ func (s *Store) HasBlock(ctx context.Context, blockRoot [32]byte) bool {
return exists
}
// AvailableBlocks returns a set of roots indicating which blocks corresponding to `blockRoots` are available in the storage.
func (s *Store) AvailableBlocks(ctx context.Context, blockRoots [][32]byte) map[[32]byte]bool {
_, span := trace.StartSpan(ctx, "BeaconDB.AvailableBlocks")
defer span.End()
count := len(blockRoots)
availableRoots := make(map[[32]byte]bool, count)
// First, check the cache for each block root.
notInCacheRoots := make([][32]byte, 0, count)
for _, root := range blockRoots {
if v, ok := s.blockCache.Get(string(root[:])); v != nil && ok {
availableRoots[root] = true
continue
}
notInCacheRoots = append(notInCacheRoots, root)
}
// Next, check the database for the remaining block roots.
if err := s.db.View(func(tx *bolt.Tx) error {
bkt := tx.Bucket(blocksBucket)
for _, root := range notInCacheRoots {
if bkt.Get(root[:]) != nil {
availableRoots[root] = true
}
}
return nil
}); err != nil {
panic(err) // lint:nopanic -- View never returns an error.
}
return availableRoots
}
// BlocksBySlot retrieves a list of beacon blocks and its respective roots by slot.
func (s *Store) BlocksBySlot(ctx context.Context, slot primitives.Slot) ([]interfaces.ReadOnlySignedBeaconBlock, error) {
ctx, span := trace.StartSpan(ctx, "BeaconDB.BlocksBySlot")

View File

@@ -656,6 +656,44 @@ func TestStore_BlocksCRUD_NoCache(t *testing.T) {
}
}
func TestAvailableBlocks(t *testing.T) {
ctx := t.Context()
db := setupDB(t)
b0, b1, b2 := util.NewBeaconBlock(), util.NewBeaconBlock(), util.NewBeaconBlock()
b0.Block.Slot, b1.Block.Slot, b2.Block.Slot = 10, 20, 30
sb0, err := blocks.NewSignedBeaconBlock(b0)
require.NoError(t, err)
r0, err := b0.Block.HashTreeRoot()
require.NoError(t, err)
// Save b0 but remove it from cache.
err = db.SaveBlock(ctx, sb0)
require.NoError(t, err)
db.blockCache.Del(string(r0[:]))
// b1 is not saved at all.
r1, err := b1.Block.HashTreeRoot()
require.NoError(t, err)
// Save b2 in cache and DB.
sb2, err := blocks.NewSignedBeaconBlock(b2)
require.NoError(t, err)
r2, err := b2.Block.HashTreeRoot()
require.NoError(t, err)
require.NoError(t, db.SaveBlock(ctx, sb2))
require.NoError(t, err)
expected := map[[32]byte]bool{r0: true, r2: true}
actual := db.AvailableBlocks(ctx, [][32]byte{r0, r1, r2})
require.Equal(t, len(expected), len(actual))
for i := range expected {
require.Equal(t, true, actual[i])
}
}
func TestStore_Blocks_FiltersCorrectly(t *testing.T) {
for _, tt := range blockTests {
t.Run(tt.name, func(t *testing.T) {

View File

@@ -25,6 +25,7 @@ go_library(
"//testing/spectest:__subpackages__",
],
deps = [
"//api:go_default_library",
"//beacon-chain/blockchain/kzg:go_default_library",
"//beacon-chain/cache:go_default_library",
"//beacon-chain/cache/depositsnapshot:go_default_library",
@@ -98,6 +99,7 @@ go_test(
data = glob(["testdata/**"]),
embed = [":go_default_library"],
deps = [
"//api:go_default_library",
"//async/event:go_default_library",
"//beacon-chain/blockchain/kzg:go_default_library",
"//beacon-chain/cache/depositsnapshot:go_default_library",

View File

@@ -13,6 +13,7 @@ import (
"strings"
"testing"
"github.com/OffchainLabs/prysm/v6/api"
"github.com/OffchainLabs/prysm/v6/beacon-chain/blockchain/kzg"
"github.com/OffchainLabs/prysm/v6/beacon-chain/core/peerdas"
"github.com/OffchainLabs/prysm/v6/beacon-chain/db/filesystem"
@@ -177,7 +178,7 @@ func TestClient_HTTP(t *testing.T) {
want, ok := fix["ExecutionPayload"].(*pb.ExecutionPayload)
require.Equal(t, true, ok)
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.Header().Set(api.ContentTypeHeader, api.JsonMediaType)
defer func() {
require.NoError(t, r.Body.Close())
}()
@@ -223,7 +224,7 @@ func TestClient_HTTP(t *testing.T) {
want, ok := fix["ExecutionPayloadCapellaWithValue"].(*pb.GetPayloadV2ResponseJson)
require.Equal(t, true, ok)
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.Header().Set(api.ContentTypeHeader, api.JsonMediaType)
defer func() {
require.NoError(t, r.Body.Close())
}()
@@ -276,7 +277,7 @@ func TestClient_HTTP(t *testing.T) {
want, ok := fix["ExecutionPayloadDenebWithValue"].(*pb.GetPayloadV3ResponseJson)
require.Equal(t, true, ok)
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.Header().Set(api.ContentTypeHeader, api.JsonMediaType)
defer func() {
require.NoError(t, r.Body.Close())
}()
@@ -331,7 +332,7 @@ func TestClient_HTTP(t *testing.T) {
want, ok := fix["ExecutionBundleElectra"].(*pb.GetPayloadV4ResponseJson)
require.Equal(t, true, ok)
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.Header().Set(api.ContentTypeHeader, api.JsonMediaType)
defer func() {
require.NoError(t, r.Body.Close())
}()
@@ -413,7 +414,7 @@ func TestClient_HTTP(t *testing.T) {
want, ok := fix["ExecutionBundleFulu"].(*pb.GetPayloadV5ResponseJson)
require.Equal(t, true, ok)
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.Header().Set(api.ContentTypeHeader, api.JsonMediaType)
defer func() {
require.NoError(t, r.Body.Close())
}()
@@ -935,7 +936,7 @@ func TestClient_HTTP(t *testing.T) {
want, ok := fix["ExecutionBlock"].(*pb.ExecutionBlock)
require.Equal(t, true, ok)
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.Header().Set(api.ContentTypeHeader, api.JsonMediaType)
defer func() {
require.NoError(t, r.Body.Close())
}()
@@ -966,7 +967,7 @@ func TestClient_HTTP(t *testing.T) {
want, ok := fix["ExecutionBlock"].(*pb.ExecutionBlock)
require.Equal(t, true, ok)
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.Header().Set(api.ContentTypeHeader, api.JsonMediaType)
defer func() {
require.NoError(t, r.Body.Close())
}()
@@ -1060,7 +1061,7 @@ func TestReconstructFullBellatrixBlock(t *testing.T) {
require.NoError(t, err)
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.Header().Set(api.ContentTypeHeader, api.JsonMediaType)
defer func() {
require.NoError(t, r.Body.Close())
}()
@@ -1163,7 +1164,7 @@ func TestReconstructFullBellatrixBlockBatch(t *testing.T) {
require.NoError(t, err)
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.Header().Set(api.ContentTypeHeader, api.JsonMediaType)
defer func() {
require.NoError(t, r.Body.Close())
}()
@@ -1236,7 +1237,7 @@ func TestReconstructFullBellatrixBlockBatch(t *testing.T) {
require.NoError(t, err)
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.Header().Set(api.ContentTypeHeader, api.JsonMediaType)
defer func() {
require.NoError(t, r.Body.Close())
}()
@@ -2153,7 +2154,7 @@ func (*testEngineService) NewPayloadV2(
func forkchoiceUpdateSetup(t *testing.T, fcs *pb.ForkchoiceState, att *pb.PayloadAttributes, res *ForkchoiceUpdatedResponse) *Service {
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.Header().Set(api.ContentTypeHeader, api.JsonMediaType)
defer func() {
require.NoError(t, r.Body.Close())
}()
@@ -2192,7 +2193,7 @@ func forkchoiceUpdateSetup(t *testing.T, fcs *pb.ForkchoiceState, att *pb.Payloa
func forkchoiceUpdateSetupV2(t *testing.T, fcs *pb.ForkchoiceState, att *pb.PayloadAttributesV2, res *ForkchoiceUpdatedResponse) *Service {
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.Header().Set(api.ContentTypeHeader, api.JsonMediaType)
defer func() {
require.NoError(t, r.Body.Close())
}()
@@ -2231,7 +2232,7 @@ func forkchoiceUpdateSetupV2(t *testing.T, fcs *pb.ForkchoiceState, att *pb.Payl
func newPayloadSetup(t *testing.T, status *pb.PayloadStatus, payload *pb.ExecutionPayload) *Service {
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.Header().Set(api.ContentTypeHeader, api.JsonMediaType)
defer func() {
require.NoError(t, r.Body.Close())
}()
@@ -2265,7 +2266,7 @@ func newPayloadSetup(t *testing.T, status *pb.PayloadStatus, payload *pb.Executi
func newPayloadV2Setup(t *testing.T, status *pb.PayloadStatus, payload *pb.ExecutionPayloadCapella) *Service {
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.Header().Set(api.ContentTypeHeader, api.JsonMediaType)
defer func() {
require.NoError(t, r.Body.Close())
}()
@@ -2299,7 +2300,7 @@ func newPayloadV2Setup(t *testing.T, status *pb.PayloadStatus, payload *pb.Execu
func newPayloadV3Setup(t *testing.T, status *pb.PayloadStatus, payload *pb.ExecutionPayloadDeneb) *Service {
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.Header().Set(api.ContentTypeHeader, api.JsonMediaType)
defer func() {
require.NoError(t, r.Body.Close())
}()
@@ -2333,7 +2334,7 @@ func newPayloadV3Setup(t *testing.T, status *pb.PayloadStatus, payload *pb.Execu
func newPayloadV4Setup(t *testing.T, status *pb.PayloadStatus, payload *pb.ExecutionPayloadDeneb, requests *pb.ExecutionRequests) *Service {
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.Header().Set(api.ContentTypeHeader, api.JsonMediaType)
defer func() {
require.NoError(t, r.Body.Close())
}()
@@ -2414,7 +2415,7 @@ func TestReconstructBlindedBlockBatch(t *testing.T) {
func Test_ExchangeCapabilities(t *testing.T) {
t.Run("empty response works", func(t *testing.T) {
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.Header().Set(api.ContentTypeHeader, api.JsonMediaType)
defer func() {
require.NoError(t, r.Body.Close())
}()
@@ -2446,7 +2447,7 @@ func Test_ExchangeCapabilities(t *testing.T) {
})
t.Run("list of items", func(t *testing.T) {
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.Header().Set(api.ContentTypeHeader, api.JsonMediaType)
defer func() {
require.NoError(t, r.Body.Close())
}()
@@ -2641,7 +2642,7 @@ func createRandomKzgCommitments(t *testing.T, num int) [][]byte {
func createBlobServer(t *testing.T, numBlobs int, callbackFuncs ...func()) *httptest.Server {
return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.Header().Set(api.ContentTypeHeader, api.JsonMediaType)
defer func() {
require.NoError(t, r.Body.Close())
}()
@@ -2666,7 +2667,7 @@ func createBlobServer(t *testing.T, numBlobs int, callbackFuncs ...func()) *http
func createBlobServerV2(t *testing.T, numBlobs int, blobMasks []bool) *httptest.Server {
return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.Header().Set(api.ContentTypeHeader, api.JsonMediaType)
defer func() {
require.NoError(t, r.Body.Close())
}()

View File

@@ -6,6 +6,7 @@ import (
"net/http/httptest"
"testing"
"github.com/OffchainLabs/prysm/v6/api"
pb "github.com/OffchainLabs/prysm/v6/proto/engine/v1"
"github.com/OffchainLabs/prysm/v6/testing/require"
"github.com/ethereum/go-ethereum/common/hexutil"
@@ -54,7 +55,7 @@ func (s *mockEngine) ServeHTTP(w http.ResponseWriter, r *http.Request) {
http.Error(w, "failed to decode request: "+err.Error(), http.StatusBadRequest)
return
}
w.Header().Set("Content-Type", "application/json")
w.Header().Set(api.ContentTypeHeader, api.JsonMediaType)
defer func() {
require.NoError(s.t, r.Body.Close())
}()

View File

@@ -7,6 +7,7 @@ import (
"strings"
"time"
"github.com/OffchainLabs/prysm/v6/api"
"github.com/OffchainLabs/prysm/v6/config/params"
contracts "github.com/OffchainLabs/prysm/v6/contracts/deposit"
"github.com/OffchainLabs/prysm/v6/io/logs"
@@ -120,7 +121,7 @@ func (s *Service) newRPCClientWithAuth(ctx context.Context, endpoint network.End
if err != nil {
return nil, err
}
headers.Set("Authorization", header)
headers.Set(api.AuthorizationHeader, header)
}
for _, h := range s.cfg.headers {
if h == "" {

View File

@@ -6,6 +6,7 @@ go_library(
"cache.go",
"helpers.go",
"lightclient.go",
"log.go",
"store.go",
],
importpath = "github.com/OffchainLabs/prysm/v6/beacon-chain/light-client",

View File

@@ -0,0 +1,5 @@
package light_client
import "github.com/sirupsen/logrus"
var log = logrus.WithField("prefix", "light-client")

View File

@@ -14,7 +14,6 @@ import (
"github.com/OffchainLabs/prysm/v6/consensus-types/primitives"
"github.com/OffchainLabs/prysm/v6/time/slots"
"github.com/pkg/errors"
log "github.com/sirupsen/logrus"
)
var ErrLightClientBootstrapNotFound = errors.New("light client bootstrap not found")

View File

@@ -81,6 +81,7 @@ go_test(
],
embed = [":go_default_library"],
deps = [
"//api:go_default_library",
"//api/server/middleware:go_default_library",
"//beacon-chain/blockchain:go_default_library",
"//beacon-chain/builder:go_default_library",

View File

@@ -12,6 +12,7 @@ import (
"os"
"os/signal"
"path/filepath"
"slices"
"strconv"
"strings"
"sync"
@@ -1135,10 +1136,8 @@ func (b *BeaconNode) registerLightClientStore() {
func hasNetworkFlag(cliCtx *cli.Context) bool {
for _, flag := range features.NetworkFlags {
for _, name := range flag.Names() {
if cliCtx.IsSet(name) {
return true
}
if slices.ContainsFunc(flag.Names(), cliCtx.IsSet) {
return true
}
}
return false

View File

@@ -10,6 +10,7 @@ import (
"testing"
"time"
"github.com/OffchainLabs/prysm/v6/api"
"github.com/OffchainLabs/prysm/v6/api/server/middleware"
"github.com/OffchainLabs/prysm/v6/beacon-chain/blockchain"
"github.com/OffchainLabs/prysm/v6/beacon-chain/builder"
@@ -249,18 +250,18 @@ func TestCORS(t *testing.T) {
// Create a request and response recorder
req := httptest.NewRequest("GET", "http://example.com/some-path", nil)
req.Header.Set("Origin", tc.origin)
req.Header.Set(api.OriginHeader, tc.origin)
rr := httptest.NewRecorder()
// Serve HTTP
handler.ServeHTTP(rr, req)
// Check the CORS headers based on the expected outcome
if tc.expectAllow && rr.Header().Get("Access-Control-Allow-Origin") != tc.origin {
t.Errorf("Expected Access-Control-Allow-Origin header to be %v, got %v", tc.origin, rr.Header().Get("Access-Control-Allow-Origin"))
if tc.expectAllow && rr.Header().Get(api.AccessControlAllowOriginHeader) != tc.origin {
t.Errorf("Expected Access-Control-Allow-Origin header to be %v, got %v", tc.origin, rr.Header().Get(api.AccessControlAllowOriginHeader))
}
if !tc.expectAllow && rr.Header().Get("Access-Control-Allow-Origin") != "" {
t.Errorf("Expected Access-Control-Allow-Origin header to be empty for disallowed origin, got %v", rr.Header().Get("Access-Control-Allow-Origin"))
if !tc.expectAllow && rr.Header().Get(api.AccessControlAllowOriginHeader) != "" {
t.Errorf("Expected Access-Control-Allow-Origin header to be empty for disallowed origin, got %v", rr.Header().Get(api.AccessControlAllowOriginHeader))
}
})
}

View File

@@ -10,11 +10,13 @@ import (
// pruneExpired prunes attestations pool on every slot interval.
func (s *Service) pruneExpired() {
ticker := time.NewTicker(s.cfg.pruneInterval)
defer ticker.Stop()
secondsPerSlot := params.BeaconConfig().SecondsPerSlot
offset := time.Duration(secondsPerSlot-1) * time.Second
slotTicker := slots.NewSlotTickerWithOffset(s.genesisTime, offset, secondsPerSlot)
defer slotTicker.Done()
for {
select {
case <-ticker.C:
case <-slotTicker.C():
s.pruneExpiredAtts()
s.updateMetrics()
case <-s.ctx.Done():

View File

@@ -17,7 +17,9 @@ import (
)
func TestPruneExpired_Ticker(t *testing.T) {
ctx, cancel := context.WithTimeout(t.Context(), 3*time.Second)
// Need timeout longer than the offset (secondsPerSlot - 1) + some buffer
timeout := time.Duration(params.BeaconConfig().SecondsPerSlot+5) * time.Second
ctx, cancel := context.WithTimeout(t.Context(), timeout)
defer cancel()
s, err := NewService(ctx, &Config{

View File

@@ -7,6 +7,7 @@ import (
statefeed "github.com/OffchainLabs/prysm/v6/beacon-chain/core/feed/state"
"github.com/OffchainLabs/prysm/v6/beacon-chain/db"
"github.com/OffchainLabs/prysm/v6/beacon-chain/startup"
"github.com/sirupsen/logrus"
)
// This is the default queue size used if we have specified an invalid one.
@@ -63,12 +64,17 @@ func (cfg *Config) connManagerLowHigh() (int, int) {
return low, high
}
// validateConfig validates whether the values provided are accurate and will set
// the appropriate values for those that are invalid.
func validateConfig(cfg *Config) *Config {
if cfg.QueueSize == 0 {
log.Warnf("Invalid pubsub queue size of %d initialized, setting the quese size as %d instead", cfg.QueueSize, defaultPubsubQueueSize)
cfg.QueueSize = defaultPubsubQueueSize
// validateConfig validates whether the provided config has valid values and sets
// the invalid ones to default.
func validateConfig(cfg *Config) {
if cfg.QueueSize > 0 {
return
}
return cfg
log.WithFields(logrus.Fields{
"queueSize": cfg.QueueSize,
"default": defaultPubsubQueueSize,
}).Warning("Invalid pubsub queue size, setting the queue size to the default value")
cfg.QueueSize = defaultPubsubQueueSize
}

View File

@@ -259,11 +259,11 @@ func (s *Service) custodyGroupCountFromPeerENR(pid peer.ID) uint64 {
}
func fuluForkSlot() (primitives.Slot, error) {
beaconConfig := params.BeaconConfig()
cfg := params.BeaconConfig()
fuluForkEpoch := beaconConfig.FuluForkEpoch
if fuluForkEpoch == beaconConfig.FarFutureEpoch {
return beaconConfig.FarFutureSlot, nil
fuluForkEpoch := cfg.FuluForkEpoch
if fuluForkEpoch == cfg.FarFutureEpoch {
return cfg.FarFutureSlot, nil
}
forkFuluSlot, err := slots.EpochStart(fuluForkEpoch)

View File

@@ -3,6 +3,7 @@ package p2p
import (
"strings"
"github.com/OffchainLabs/prysm/v6/beacon-chain/p2p/peers"
"github.com/libp2p/go-libp2p/core/peer"
"github.com/libp2p/go-libp2p/core/peerstore"
"github.com/prometheus/client_golang/prometheus"
@@ -26,12 +27,25 @@ var (
Help: "The number of peers in a given state.",
},
[]string{"state"})
p2pMaxPeers = promauto.NewGauge(prometheus.GaugeOpts{
Name: "p2p_max_peers",
Help: "The target maximum number of peers.",
})
p2pPeerCountDirectionType = promauto.NewGaugeVec(prometheus.GaugeOpts{
Name: "p2p_peer_count_direction_type",
Help: "The number of peers in a given direction and type.",
},
[]string{"direction", "type"})
connectedPeersCount = promauto.NewGaugeVec(prometheus.GaugeOpts{
Name: "connected_libp2p_peers",
Help: "Tracks the total number of connected libp2p peers by agent string",
},
[]string{"agent"},
)
minimumPeersPerSubnet = promauto.NewGauge(prometheus.GaugeOpts{
Name: "p2p_minimum_peers_per_subnet",
Help: "The minimum number of peers to connect to per subnet",
})
avgScoreConnectedClients = promauto.NewGaugeVec(prometheus.GaugeOpts{
Name: "connected_libp2p_peers_average_scores",
Help: "Tracks the overall p2p scores of connected libp2p peers by agent string",
@@ -174,18 +188,26 @@ var (
)
func (s *Service) updateMetrics() {
store := s.Host().Peerstore()
connectedPeers := s.peers.Connected()
p2pPeerCount.WithLabelValues("Connected").Set(float64(len(connectedPeers)))
p2pPeerCount.WithLabelValues("Disconnected").Set(float64(len(s.peers.Disconnected())))
p2pPeerCount.WithLabelValues("Connecting").Set(float64(len(s.peers.Connecting())))
p2pPeerCount.WithLabelValues("Disconnecting").Set(float64(len(s.peers.Disconnecting())))
p2pPeerCount.WithLabelValues("Bad").Set(float64(len(s.peers.Bad())))
store := s.Host().Peerstore()
numConnectedPeersByClient := make(map[string]float64)
upperTCP := strings.ToUpper(string(peers.TCP))
upperQUIC := strings.ToUpper(string(peers.QUIC))
p2pPeerCountDirectionType.WithLabelValues("inbound", upperTCP).Set(float64(len(s.peers.InboundConnectedWithProtocol(peers.TCP))))
p2pPeerCountDirectionType.WithLabelValues("inbound", upperQUIC).Set(float64(len(s.peers.InboundConnectedWithProtocol(peers.QUIC))))
p2pPeerCountDirectionType.WithLabelValues("outbound", upperTCP).Set(float64(len(s.peers.OutboundConnectedWithProtocol(peers.TCP))))
p2pPeerCountDirectionType.WithLabelValues("outbound", upperQUIC).Set(float64(len(s.peers.OutboundConnectedWithProtocol(peers.QUIC))))
connectedPeersCountByClient := make(map[string]float64)
peerScoresByClient := make(map[string][]float64)
for i := 0; i < len(connectedPeers); i++ {
p := connectedPeers[i]
for _, p := range connectedPeers {
pid, err := peer.Decode(p.String())
if err != nil {
log.WithError(err).Debug("Could not decode peer string")
@@ -193,16 +215,18 @@ func (s *Service) updateMetrics() {
}
foundName := agentFromPid(pid, store)
numConnectedPeersByClient[foundName] += 1
connectedPeersCountByClient[foundName] += 1
// Get peer scoring data.
overallScore := s.peers.Scorers().Score(pid)
peerScoresByClient[foundName] = append(peerScoresByClient[foundName], overallScore)
}
connectedPeersCount.Reset() // Clear out previous results.
for agent, total := range numConnectedPeersByClient {
for agent, total := range connectedPeersCountByClient {
connectedPeersCount.WithLabelValues(agent).Set(total)
}
avgScoreConnectedClients.Reset() // Clear out previous results.
for agent, scoringData := range peerScoresByClient {
avgScore := average(scoringData)

View File

@@ -25,6 +25,7 @@ package peers
import (
"context"
"net"
"slices"
"sort"
"strings"
"time"
@@ -81,29 +82,31 @@ const (
type InternetProtocol string
const (
TCP = "tcp"
QUIC = "quic"
TCP = InternetProtocol("tcp")
QUIC = InternetProtocol("quic")
)
// Status is the structure holding the peer status information.
type Status struct {
ctx context.Context
scorers *scorers.Service
store *peerdata.Store
ipTracker map[string]uint64
rand *rand.Rand
ipColocationWhitelist []*net.IPNet
}
type (
// Status is the structure holding the peer status information.
Status struct {
ctx context.Context
scorers *scorers.Service
store *peerdata.Store
ipTracker map[string]uint64
rand *rand.Rand
ipColocationWhitelist []*net.IPNet
}
// StatusConfig represents peer status service params.
type StatusConfig struct {
// PeerLimit specifies maximum amount of concurrent peers that are expected to be connect to the node.
PeerLimit int
// ScorerParams holds peer scorer configuration params.
ScorerParams *scorers.Config
// IPColocationWhitelist contains CIDR ranges that are exempt from IP colocation limits.
IPColocationWhitelist []*net.IPNet
}
// StatusConfig represents peer status service params.
StatusConfig struct {
// PeerLimit specifies maximum amount of concurrent peers that are expected to be connect to the node.
PeerLimit int
// ScorerParams holds peer scorer configuration params.
ScorerParams *scorers.Config
// IPColocationWhitelist contains CIDR ranges that are exempt from IP colocation limits.
IPColocationWhitelist []*net.IPNet
}
)
// NewStatus creates a new status entity.
func NewStatus(ctx context.Context, config *StatusConfig) *Status {
@@ -304,11 +307,8 @@ func (p *Status) SubscribedToSubnet(index uint64) []peer.ID {
connectedStatus := peerData.ConnState == Connecting || peerData.ConnState == Connected
if connectedStatus && peerData.MetaData != nil && !peerData.MetaData.IsNil() && peerData.MetaData.AttnetsBitfield() != nil {
indices := indicesFromBitfield(peerData.MetaData.AttnetsBitfield())
for _, idx := range indices {
if idx == index {
peers = append(peers, pid)
break
}
if slices.Contains(indices, index) {
peers = append(peers, pid)
}
}
}

View File

@@ -345,17 +345,17 @@ func TopicFromMessage(msg string, epoch primitives.Epoch) (string, error) {
return "", errors.Errorf("%s: %s", invalidRPCMessageType, msg)
}
beaconConfig := params.BeaconConfig()
cfg := params.BeaconConfig()
// Check if the message is to be updated in fulu.
if epoch >= beaconConfig.FuluForkEpoch {
if epoch >= cfg.FuluForkEpoch {
if version, ok := fuluMapping[msg]; ok {
return protocolPrefix + msg + version, nil
}
}
// Check if the message is to be updated in altair.
if epoch >= beaconConfig.AltairForkEpoch {
if epoch >= cfg.AltairForkEpoch {
if version, ok := altairMapping[msg]; ok {
return protocolPrefix + msg + version, nil
}

View File

@@ -14,6 +14,7 @@ import (
"github.com/OffchainLabs/prysm/v6/beacon-chain/p2p/peers"
"github.com/OffchainLabs/prysm/v6/beacon-chain/p2p/peers/scorers"
"github.com/OffchainLabs/prysm/v6/beacon-chain/p2p/types"
"github.com/OffchainLabs/prysm/v6/cmd/beacon-chain/flags"
"github.com/OffchainLabs/prysm/v6/config/features"
"github.com/OffchainLabs/prysm/v6/config/params"
"github.com/OffchainLabs/prysm/v6/consensus-types/primitives"
@@ -106,12 +107,16 @@ func NewService(ctx context.Context, cfg *Config) (*Service, error) {
ctx, cancel := context.WithCancel(ctx)
_ = cancel // govet fix for lost cancel. Cancel is handled in service.Stop().
cfg = validateConfig(cfg)
validateConfig(cfg)
privKey, err := privKey(cfg)
if err != nil {
return nil, errors.Wrapf(err, "failed to generate p2p private key")
}
p2pMaxPeers.Set(float64(cfg.MaxPeers))
minimumPeersPerSubnet.Set(float64(flags.Get().MinimumPeersPerSubnet))
metaData, err := metaDataFromDB(ctx, cfg.DB)
if err != nil {
log.WithError(err).Error("Failed to create peer metadata")

View File

@@ -514,18 +514,18 @@ func initializePersistentSubnets(id enode.ID, epoch primitives.Epoch) error {
//
// return [compute_subscribed_subnet(node_id, epoch, index) for index in range(SUBNETS_PER_NODE)]
func computeSubscribedSubnets(nodeID enode.ID, epoch primitives.Epoch) ([]uint64, error) {
beaconConfig := params.BeaconConfig()
cfg := params.BeaconConfig()
if flags.Get().SubscribeToAllSubnets {
subnets := make([]uint64, 0, beaconConfig.AttestationSubnetCount)
for i := range beaconConfig.AttestationSubnetCount {
subnets := make([]uint64, 0, cfg.AttestationSubnetCount)
for i := range cfg.AttestationSubnetCount {
subnets = append(subnets, i)
}
return subnets, nil
}
subnets := make([]uint64, 0, beaconConfig.SubnetsPerNode)
for i := range beaconConfig.SubnetsPerNode {
subnets := make([]uint64, 0, cfg.SubnetsPerNode)
for i := range cfg.SubnetsPerNode {
sub, err := computeSubscribedSubnet(nodeID, epoch, i)
if err != nil {
return nil, errors.Wrap(err, "compute subscribed subnet")

View File

@@ -524,12 +524,12 @@ func TestSubnetComputation(t *testing.T) {
require.NoError(t, err)
localNode := enode.NewLocalNode(db, convertedKey)
beaconConfig := params.BeaconConfig()
cfg := params.BeaconConfig()
t.Run("standard", func(t *testing.T) {
retrievedSubnets, err := computeSubscribedSubnets(localNode.ID(), 1000)
require.NoError(t, err)
require.Equal(t, beaconConfig.SubnetsPerNode, uint64(len(retrievedSubnets)))
require.Equal(t, cfg.SubnetsPerNode, uint64(len(retrievedSubnets)))
require.Equal(t, retrievedSubnets[0]+1, retrievedSubnets[1])
})
@@ -541,8 +541,8 @@ func TestSubnetComputation(t *testing.T) {
retrievedSubnets, err := computeSubscribedSubnets(localNode.ID(), 1000)
require.NoError(t, err)
require.Equal(t, beaconConfig.AttestationSubnetCount, uint64(len(retrievedSubnets)))
for i := range beaconConfig.AttestationSubnetCount {
require.Equal(t, cfg.AttestationSubnetCount, uint64(len(retrievedSubnets)))
for i := range cfg.AttestationSubnetCount {
require.Equal(t, i, retrievedSubnets[i])
}
})

View File

@@ -68,7 +68,10 @@ func privKey(cfg *Config) (*ecdsa.PrivateKey, error) {
}
if defaultKeysExist {
log.WithField("filePath", defaultKeyPath).Info("Reading static P2P private key from a file. To generate a new random private key at every start, please remove this file.")
if !params.FuluEnabled() {
log.WithField("filePath", defaultKeyPath).Info("Reading static P2P private key from a file. To generate a new random private key at every start, please remove this file.")
}
return privKeyFromFile(defaultKeyPath)
}

View File

@@ -101,9 +101,9 @@ func versionHeaderFromRequest(body []byte) (string, error) {
// from the request. If the version header is not provided and not required, it attempts
// to derive it from the request body.
func validateVersionHeader(r *http.Request, body []byte, versionRequired bool) (string, error) {
versionHeader := r.Header.Get(api.VersionHeader)
versionHeader := r.Header.Get(api.EthConsensusVersionHeader)
if versionRequired && versionHeader == "" {
return "", fmt.Errorf("%s header is required", api.VersionHeader)
return "", fmt.Errorf("%s header is required", api.EthConsensusVersionHeader)
}
if !versionRequired && versionHeader == "" {
@@ -219,7 +219,7 @@ func (s *Server) getBlockV2Ssz(w http.ResponseWriter, blk interfaces.ReadOnlySig
httputil.HandleError(w, fmt.Sprintf("Unknown block type %T", blk), http.StatusInternalServerError)
return
}
w.Header().Set(api.VersionHeader, version.String(blk.Version()))
w.Header().Set(api.EthConsensusVersionHeader, version.String(blk.Version()))
httputil.WriteSsz(w, result)
}
@@ -254,7 +254,7 @@ func (s *Server) getBlockV2Json(ctx context.Context, w http.ResponseWriter, blk
httputil.HandleError(w, fmt.Sprintf("Unknown block type %T", blk), http.StatusInternalServerError)
return
}
w.Header().Set(api.VersionHeader, result.Version)
w.Header().Set(api.EthConsensusVersionHeader, result.Version)
httputil.WriteJson(w, result)
}
@@ -368,7 +368,7 @@ func (s *Server) GetBlockAttestationsV2(w http.ResponseWriter, r *http.Request)
Finalized: s.FinalizationFetcher.IsFinalized(ctx, root),
Data: attBytes,
}
w.Header().Set(api.VersionHeader, version.String(v))
w.Header().Set(api.EthConsensusVersionHeader, version.String(v))
httputil.WriteJson(w, resp)
}
@@ -1693,7 +1693,7 @@ func (s *Server) GetPendingConsolidations(w http.ResponseWriter, r *http.Request
httputil.HandleError(w, "Could not get pending consolidations: "+err.Error(), http.StatusInternalServerError)
return
}
w.Header().Set(api.VersionHeader, version.String(st.Version()))
w.Header().Set(api.EthConsensusVersionHeader, version.String(st.Version()))
if httputil.RespondWithSsz(r) {
sszData, err := serializeItems(pd)
if err != nil {
@@ -1749,7 +1749,7 @@ func (s *Server) GetPendingDeposits(w http.ResponseWriter, r *http.Request) {
httputil.HandleError(w, "Could not get pending deposits: "+err.Error(), http.StatusInternalServerError)
return
}
w.Header().Set(api.VersionHeader, version.String(st.Version()))
w.Header().Set(api.EthConsensusVersionHeader, version.String(st.Version()))
if httputil.RespondWithSsz(r) {
sszData, err := serializeItems(pd)
if err != nil {
@@ -1805,7 +1805,7 @@ func (s *Server) GetPendingPartialWithdrawals(w http.ResponseWriter, r *http.Req
httputil.HandleError(w, "Could not get pending partial withdrawals: "+err.Error(), http.StatusInternalServerError)
return
}
w.Header().Set(api.VersionHeader, version.String(st.Version()))
w.Header().Set(api.EthConsensusVersionHeader, version.String(st.Version()))
if httputil.RespondWithSsz(r) {
sszData, err := serializeItems(ppw)
if err != nil {
@@ -1858,7 +1858,7 @@ func (s *Server) GetProposerLookahead(w http.ResponseWriter, r *http.Request) {
httputil.HandleError(w, "Could not get proposer look ahead: "+err.Error(), http.StatusInternalServerError)
return
}
w.Header().Set(api.VersionHeader, version.String(st.Version()))
w.Header().Set(api.EthConsensusVersionHeader, version.String(st.Version()))
if httputil.RespondWithSsz(r) {
sszLen := (*primitives.ValidatorIndex)(nil).SizeSSZ()
sszData := make([]byte, len(pl)*sszLen)

View File

@@ -150,7 +150,7 @@ func (s *Server) ListAttestationsV2(w http.ResponseWriter, r *http.Request) {
return
}
w.Header().Set(api.VersionHeader, version.String(v))
w.Header().Set(api.EthConsensusVersionHeader, version.String(v))
httputil.WriteJson(w, &structs.ListAttestationsResponse{
Version: version.String(v),
Data: attsData,
@@ -225,9 +225,9 @@ func (s *Server) SubmitAttestationsV2(w http.ResponseWriter, r *http.Request) {
ctx, span := trace.StartSpan(r.Context(), "beacon.SubmitAttestationsV2")
defer span.End()
versionHeader := r.Header.Get(api.VersionHeader)
versionHeader := r.Header.Get(api.EthConsensusVersionHeader)
if versionHeader == "" {
httputil.HandleError(w, api.VersionHeader+" header is required", http.StatusBadRequest)
httputil.HandleError(w, api.EthConsensusVersionHeader+" header is required", http.StatusBadRequest)
return
}
v, err := version.FromString(versionHeader)
@@ -826,7 +826,7 @@ func (s *Server) GetAttesterSlashingsV2(w http.ResponseWriter, r *http.Request)
Version: version.String(v),
Data: attBytes,
}
w.Header().Set(api.VersionHeader, version.String(v))
w.Header().Set(api.EthConsensusVersionHeader, version.String(v))
httputil.WriteJson(w, resp)
}
@@ -861,9 +861,9 @@ func (s *Server) SubmitAttesterSlashingsV2(w http.ResponseWriter, r *http.Reques
ctx, span := trace.StartSpan(r.Context(), "beacon.SubmitAttesterSlashingsV2")
defer span.End()
versionHeader := r.Header.Get(api.VersionHeader)
versionHeader := r.Header.Get(api.EthConsensusVersionHeader)
if versionHeader == "" {
httputil.HandleError(w, api.VersionHeader+" header is required", http.StatusBadRequest)
httputil.HandleError(w, api.EthConsensusVersionHeader+" header is required", http.StatusBadRequest)
}
v, err := version.FromString(versionHeader)
if err != nil {

View File

@@ -656,7 +656,7 @@ func TestSubmitAttestations(t *testing.T) {
_, err := body.WriteString(singleAtt)
require.NoError(t, err)
request := httptest.NewRequest(http.MethodPost, "http://example.com", &body)
request.Header.Set(api.VersionHeader, version.String(version.Phase0))
request.Header.Set(api.EthConsensusVersionHeader, version.String(version.Phase0))
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
@@ -685,7 +685,7 @@ func TestSubmitAttestations(t *testing.T) {
_, err := body.WriteString(multipleAtts)
require.NoError(t, err)
request := httptest.NewRequest(http.MethodPost, "http://example.com", &body)
request.Header.Set(api.VersionHeader, version.String(version.Phase0))
request.Header.Set(api.EthConsensusVersionHeader, version.String(version.Phase0))
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
@@ -705,7 +705,7 @@ func TestSubmitAttestations(t *testing.T) {
_, err := body.WriteString(singleAtt)
require.NoError(t, err)
request := httptest.NewRequest(http.MethodPost, "http://example.com", &body)
request.Header.Set(api.VersionHeader, version.String(version.Phase0))
request.Header.Set(api.EthConsensusVersionHeader, version.String(version.Phase0))
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
@@ -721,7 +721,7 @@ func TestSubmitAttestations(t *testing.T) {
_, err := body.WriteString(singleAttElectra)
require.NoError(t, err)
request := httptest.NewRequest(http.MethodPost, "http://example.com", &body)
request.Header.Set(api.VersionHeader, version.String(version.Electra))
request.Header.Set(api.EthConsensusVersionHeader, version.String(version.Electra))
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
@@ -734,7 +734,7 @@ func TestSubmitAttestations(t *testing.T) {
})
t.Run("no body", func(t *testing.T) {
request := httptest.NewRequest(http.MethodPost, "http://example.com", nil)
request.Header.Set(api.VersionHeader, version.String(version.Phase0))
request.Header.Set(api.EthConsensusVersionHeader, version.String(version.Phase0))
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
@@ -750,7 +750,7 @@ func TestSubmitAttestations(t *testing.T) {
_, err := body.WriteString("[]")
require.NoError(t, err)
request := httptest.NewRequest(http.MethodPost, "http://example.com", &body)
request.Header.Set(api.VersionHeader, version.String(version.Phase0))
request.Header.Set(api.EthConsensusVersionHeader, version.String(version.Phase0))
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
@@ -766,7 +766,7 @@ func TestSubmitAttestations(t *testing.T) {
_, err := body.WriteString(invalidAtt)
require.NoError(t, err)
request := httptest.NewRequest(http.MethodPost, "http://example.com", &body)
request.Header.Set(api.VersionHeader, version.String(version.Phase0))
request.Header.Set(api.EthConsensusVersionHeader, version.String(version.Phase0))
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
@@ -794,7 +794,7 @@ func TestSubmitAttestations(t *testing.T) {
_, err := body.WriteString(singleAttElectra)
require.NoError(t, err)
request := httptest.NewRequest(http.MethodPost, "http://example.com", &body)
request.Header.Set(api.VersionHeader, version.String(version.Electra))
request.Header.Set(api.EthConsensusVersionHeader, version.String(version.Electra))
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
@@ -823,7 +823,7 @@ func TestSubmitAttestations(t *testing.T) {
_, err := body.WriteString(multipleAttsElectra)
require.NoError(t, err)
request := httptest.NewRequest(http.MethodPost, "http://example.com", &body)
request.Header.Set(api.VersionHeader, version.String(version.Electra))
request.Header.Set(api.EthConsensusVersionHeader, version.String(version.Electra))
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
@@ -835,7 +835,7 @@ func TestSubmitAttestations(t *testing.T) {
})
t.Run("no body", func(t *testing.T) {
request := httptest.NewRequest(http.MethodPost, "http://example.com", nil)
request.Header.Set(api.VersionHeader, version.String(version.Electra))
request.Header.Set(api.EthConsensusVersionHeader, version.String(version.Electra))
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
@@ -851,7 +851,7 @@ func TestSubmitAttestations(t *testing.T) {
_, err := body.WriteString("[]")
require.NoError(t, err)
request := httptest.NewRequest(http.MethodPost, "http://example.com", &body)
request.Header.Set(api.VersionHeader, version.String(version.Electra))
request.Header.Set(api.EthConsensusVersionHeader, version.String(version.Electra))
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
@@ -867,7 +867,7 @@ func TestSubmitAttestations(t *testing.T) {
_, err := body.WriteString(invalidAttElectra)
require.NoError(t, err)
request := httptest.NewRequest(http.MethodPost, "http://example.com", &body)
request.Header.Set(api.VersionHeader, version.String(version.Electra))
request.Header.Set(api.EthConsensusVersionHeader, version.String(version.Electra))
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
@@ -2168,7 +2168,7 @@ func TestSubmitAttesterSlashings(t *testing.T) {
_, err = body.Write(b)
require.NoError(t, err)
request := httptest.NewRequest(http.MethodPost, "http://example.com/beacon/pool/attester_electras", &body)
request.Header.Set(api.VersionHeader, version.String(version.Electra))
request.Header.Set(api.EthConsensusVersionHeader, version.String(version.Electra))
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
@@ -2232,7 +2232,7 @@ func TestSubmitAttesterSlashings(t *testing.T) {
_, err = body.Write(b)
require.NoError(t, err)
request := httptest.NewRequest(http.MethodPost, "http://example.com/beacon/pool/attester_slashings", &body)
request.Header.Set(api.VersionHeader, version.String(version.Electra))
request.Header.Set(api.EthConsensusVersionHeader, version.String(version.Electra))
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
@@ -2262,7 +2262,7 @@ func TestSubmitAttesterSlashings(t *testing.T) {
_, err = body.WriteString(invalidAttesterSlashing)
require.NoError(t, err)
request := httptest.NewRequest(http.MethodPost, "http://example.com/beacon/pool/attester_slashings", &body)
request.Header.Set(api.VersionHeader, version.String(version.Electra))
request.Header.Set(api.EthConsensusVersionHeader, version.String(version.Electra))
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}

File diff suppressed because it is too large Load Diff

View File

@@ -1442,7 +1442,7 @@ func TestGetValidatorIdentities(t *testing.T) {
_, err := body.WriteString("[]")
require.NoError(t, err)
request := httptest.NewRequest(http.MethodPost, "http://example.com/eth/v1/beacon/states/{state_id}/validator_identities", &body)
request.Header.Set("Accept", api.OctetStreamMediaType)
request.Header.Set(api.AcceptHeader, api.OctetStreamMediaType)
request.SetPathValue("state_id", "head")
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
@@ -1466,7 +1466,7 @@ func TestGetValidatorIdentities(t *testing.T) {
_, err := body.WriteString("[\"0\",\"1\"]")
require.NoError(t, err)
request := httptest.NewRequest(http.MethodPost, "http://example.com/eth/v1/beacon/states/{state_id}/validator_identities", &body)
request.Header.Set("Accept", api.OctetStreamMediaType)
request.Header.Set(api.AcceptHeader, api.OctetStreamMediaType)
request.SetPathValue("state_id", "head")
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
@@ -1494,7 +1494,7 @@ func TestGetValidatorIdentities(t *testing.T) {
_, err := body.WriteString(fmt.Sprintf("[\"%s\",\"%s\"]", hexPubkey1, hexPubkey2))
require.NoError(t, err)
request := httptest.NewRequest(http.MethodPost, "http://example.com/eth/v1/beacon/states/{state_id}/validator_identities", &body)
request.Header.Set("Accept", api.OctetStreamMediaType)
request.Header.Set(api.AcceptHeader, api.OctetStreamMediaType)
request.SetPathValue("state_id", "head")
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
@@ -1521,7 +1521,7 @@ func TestGetValidatorIdentities(t *testing.T) {
_, err := body.WriteString(fmt.Sprintf("[\"%s\",\"1\"]", hexPubkey))
require.NoError(t, err)
request := httptest.NewRequest(http.MethodPost, "http://example.com/eth/v1/beacon/states/{state_id}/validator_identities", &body)
request.Header.Set("Accept", api.OctetStreamMediaType)
request.Header.Set(api.AcceptHeader, api.OctetStreamMediaType)
request.SetPathValue("state_id", "head")
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
@@ -1548,7 +1548,7 @@ func TestGetValidatorIdentities(t *testing.T) {
_, err := body.WriteString(fmt.Sprintf("[\"%s\",\"%s\"]", hexPubkey, hexutil.Encode([]byte(strings.Repeat("x", fieldparams.BLSPubkeyLength)))))
require.NoError(t, err)
request := httptest.NewRequest(http.MethodPost, "http://example.com/eth/v1/beacon/states/{state_id}/validator_identities", &body)
request.Header.Set("Accept", api.OctetStreamMediaType)
request.Header.Set(api.AcceptHeader, api.OctetStreamMediaType)
request.SetPathValue("state_id", "head")
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
@@ -1572,7 +1572,7 @@ func TestGetValidatorIdentities(t *testing.T) {
_, err := body.WriteString("[\"1\",\"99999\"]")
require.NoError(t, err)
request := httptest.NewRequest(http.MethodPost, "http://example.com/eth/v1/beacon/states/{state_id}/validator_identities", &body)
request.Header.Set("Accept", api.OctetStreamMediaType)
request.Header.Set(api.AcceptHeader, api.OctetStreamMediaType)
request.SetPathValue("state_id", "head")
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}

View File

@@ -68,7 +68,7 @@ func (s *Server) Blobs(w http.ResponseWriter, r *http.Request) {
httputil.HandleError(w, err.Error(), http.StatusInternalServerError)
return
}
w.Header().Set(api.VersionHeader, version.String(blk.Version()))
w.Header().Set(api.EthConsensusVersionHeader, version.String(blk.Version()))
httputil.WriteSsz(w, sszResp)
return
}
@@ -91,7 +91,7 @@ func (s *Server) Blobs(w http.ResponseWriter, r *http.Request) {
ExecutionOptimistic: isOptimistic,
Finalized: s.FinalizationFetcher.IsFinalized(ctx, blkRoot),
}
w.Header().Set(api.VersionHeader, version.String(blk.Version()))
w.Header().Set(api.EthConsensusVersionHeader, version.String(blk.Version()))
httputil.WriteJson(w, resp)
}
@@ -180,7 +180,7 @@ func (s *Server) GetBlobs(w http.ResponseWriter, r *http.Request) {
copy(sszData[i*sszLen:(i+1)*sszLen], verifiedBlobs[i].Blob)
}
w.Header().Set(api.VersionHeader, version.String(blk.Version()))
w.Header().Set(api.EthConsensusVersionHeader, version.String(blk.Version()))
httputil.WriteSsz(w, sszData)
return
}
@@ -205,7 +205,7 @@ func (s *Server) GetBlobs(w http.ResponseWriter, r *http.Request) {
ExecutionOptimistic: isOptimistic,
Finalized: s.FinalizationFetcher.IsFinalized(ctx, blkRoot),
}
w.Header().Set(api.VersionHeader, version.String(blk.Version()))
w.Header().Set(api.EthConsensusVersionHeader, version.String(blk.Version()))
httputil.WriteJson(w, resp)
}

View File

@@ -227,7 +227,7 @@ func TestBlobs(t *testing.T) {
}
s.Blobs(writer, request)
assert.Equal(t, version.String(version.Deneb), writer.Header().Get(api.VersionHeader))
assert.Equal(t, version.String(version.Deneb), writer.Header().Get(api.EthConsensusVersionHeader))
assert.Equal(t, http.StatusOK, writer.Code)
resp := &structs.SidecarsResponse{}
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), resp))
@@ -381,7 +381,7 @@ func TestBlobs(t *testing.T) {
t.Run("ssz", func(t *testing.T) {
u := "http://foo.example/finalized?indices=0"
request := httptest.NewRequest("GET", u, nil)
request.Header.Add("Accept", "application/octet-stream")
request.Header.Add(api.AcceptHeader, api.OctetStreamMediaType)
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.Blocker = &lookup.BeaconDbBlocker{
@@ -393,7 +393,7 @@ func TestBlobs(t *testing.T) {
BlobStorage: bs,
}
s.Blobs(writer, request)
assert.Equal(t, version.String(version.Deneb), writer.Header().Get(api.VersionHeader))
assert.Equal(t, version.String(version.Deneb), writer.Header().Get(api.EthConsensusVersionHeader))
assert.Equal(t, http.StatusOK, writer.Code)
require.Equal(t, len(writer.Body.Bytes()), fieldparams.BlobSidecarSize) // size of each sidecar
// can directly unmarshal to sidecar since there's only 1
@@ -404,7 +404,7 @@ func TestBlobs(t *testing.T) {
t.Run("ssz multiple blobs", func(t *testing.T) {
u := "http://foo.example/finalized"
request := httptest.NewRequest("GET", u, nil)
request.Header.Add("Accept", "application/octet-stream")
request.Header.Add(api.AcceptHeader, api.OctetStreamMediaType)
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.Blocker = &lookup.BeaconDbBlocker{
@@ -467,7 +467,7 @@ func TestBlobs_Electra(t *testing.T) {
}
s.Blobs(writer, request)
assert.Equal(t, version.String(version.Electra), writer.Header().Get(api.VersionHeader))
assert.Equal(t, version.String(version.Electra), writer.Header().Get(api.EthConsensusVersionHeader))
assert.Equal(t, http.StatusOK, writer.Code)
resp := &structs.SidecarsResponse{}
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), resp))
@@ -499,7 +499,7 @@ func TestBlobs_Electra(t *testing.T) {
}
s.Blobs(writer, request)
assert.Equal(t, version.String(version.Electra), writer.Header().Get(api.VersionHeader))
assert.Equal(t, version.String(version.Electra), writer.Header().Get(api.EthConsensusVersionHeader))
assert.Equal(t, http.StatusOK, writer.Code)
resp := &structs.SidecarsResponse{}
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), resp))
@@ -867,7 +867,7 @@ func TestGetBlobs(t *testing.T) {
t.Run("ssz", func(t *testing.T) {
u := "http://foo.example/finalized"
request := httptest.NewRequest("GET", u, nil)
request.Header.Add("Accept", "application/octet-stream")
request.Header.Add(api.AcceptHeader, api.OctetStreamMediaType)
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.Blocker = &lookup.BeaconDbBlocker{
@@ -879,7 +879,7 @@ func TestGetBlobs(t *testing.T) {
BlobStorage: bs,
}
s.GetBlobs(writer, request)
assert.Equal(t, version.String(version.Deneb), writer.Header().Get(api.VersionHeader))
assert.Equal(t, version.String(version.Deneb), writer.Header().Get(api.EthConsensusVersionHeader))
assert.Equal(t, http.StatusOK, writer.Code)
require.Equal(t, fieldparams.BlobSize*4, len(writer.Body.Bytes())) // size of 4 sidecars
// unmarshal all 4 blobs
@@ -889,7 +889,7 @@ func TestGetBlobs(t *testing.T) {
t.Run("ssz multiple blobs", func(t *testing.T) {
u := "http://foo.example/finalized"
request := httptest.NewRequest("GET", u, nil)
request.Header.Add("Accept", "application/octet-stream")
request.Header.Add(api.AcceptHeader, api.OctetStreamMediaType)
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.Blocker = &lookup.BeaconDbBlocker{
@@ -1038,7 +1038,7 @@ func TestGetBlobs(t *testing.T) {
}
s.GetBlobs(writer, request)
assert.Equal(t, version.String(version.Electra), writer.Header().Get(api.VersionHeader))
assert.Equal(t, version.String(version.Electra), writer.Header().Get(api.EthConsensusVersionHeader))
assert.Equal(t, http.StatusOK, writer.Code)
resp := &structs.GetBlobsResponse{}
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), resp))
@@ -1078,7 +1078,7 @@ func TestGetBlobs(t *testing.T) {
}
s.GetBlobs(writer, request)
assert.Equal(t, version.String(version.Fulu), writer.Header().Get(api.VersionHeader))
assert.Equal(t, version.String(version.Fulu), writer.Header().Get(api.EthConsensusVersionHeader))
assert.Equal(t, http.StatusOK, writer.Code)
resp := &structs.GetBlobsResponse{}
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), resp))
@@ -1132,7 +1132,7 @@ func TestGetBlobs(t *testing.T) {
}
s.GetBlobs(writer, request)
assert.Equal(t, version.String(version.Fulu), writer.Header().Get(api.VersionHeader))
assert.Equal(t, version.String(version.Fulu), writer.Header().Get(api.EthConsensusVersionHeader))
assert.Equal(t, http.StatusOK, writer.Code)
resp := &structs.GetBlobsResponse{}
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), resp))

View File

@@ -129,7 +129,7 @@ func (s *Server) getBeaconStateV2(ctx context.Context, w http.ResponseWriter, id
Finalized: isFinalized,
Data: jsonBytes,
}
w.Header().Set(api.VersionHeader, ver)
w.Header().Set(api.EthConsensusVersionHeader, ver)
httputil.WriteJson(w, resp)
}
@@ -145,7 +145,7 @@ func (s *Server) getBeaconStateSSZV2(ctx context.Context, w http.ResponseWriter,
httputil.HandleError(w, "Could not marshal state into SSZ: "+err.Error(), http.StatusInternalServerError)
return
}
w.Header().Set(api.VersionHeader, version.String(st.Version()))
w.Header().Set(api.EthConsensusVersionHeader, version.String(st.Version()))
httputil.WriteSsz(w, sszState)
}
@@ -279,7 +279,7 @@ func (s *Server) DataColumnSidecars(w http.ResponseWriter, r *http.Request) {
httputil.HandleError(w, err.Error(), http.StatusInternalServerError)
return
}
w.Header().Set(api.VersionHeader, version.String(blk.Version()))
w.Header().Set(api.EthConsensusVersionHeader, version.String(blk.Version()))
httputil.WriteSsz(w, sszResp)
return
}
@@ -302,7 +302,7 @@ func (s *Server) DataColumnSidecars(w http.ResponseWriter, r *http.Request) {
ExecutionOptimistic: isOptimistic,
Finalized: s.FinalizationFetcher.IsFinalized(ctx, blkRoot),
}
w.Header().Set(api.VersionHeader, version.String(blk.Version()))
w.Header().Set(api.EthConsensusVersionHeader, version.String(blk.Version()))
httputil.WriteJson(w, resp)
}

View File

@@ -320,13 +320,13 @@ func TestGetBeaconStateSSZV2(t *testing.T) {
request := httptest.NewRequest(http.MethodGet, "http://example.com/eth/v2/debug/beacon/states/{state_id}", nil)
request.SetPathValue("state_id", "head")
request.Header.Set("Accept", api.OctetStreamMediaType)
request.Header.Set(api.AcceptHeader, api.OctetStreamMediaType)
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.GetBeaconStateV2(writer, request)
require.Equal(t, http.StatusOK, writer.Code)
assert.Equal(t, version.String(version.Phase0), writer.Header().Get(api.VersionHeader))
assert.Equal(t, version.String(version.Phase0), writer.Header().Get(api.EthConsensusVersionHeader))
sszExpected, err := fakeState.MarshalSSZ()
require.NoError(t, err)
assert.DeepEqual(t, sszExpected, writer.Body.Bytes())
@@ -344,13 +344,13 @@ func TestGetBeaconStateSSZV2(t *testing.T) {
request := httptest.NewRequest(http.MethodGet, "http://example.com/eth/v2/debug/beacon/states/{state_id}", nil)
request.SetPathValue("state_id", "head")
request.Header.Set("Accept", api.OctetStreamMediaType)
request.Header.Set(api.AcceptHeader, api.OctetStreamMediaType)
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.GetBeaconStateV2(writer, request)
require.Equal(t, http.StatusOK, writer.Code)
assert.Equal(t, version.String(version.Altair), writer.Header().Get(api.VersionHeader))
assert.Equal(t, version.String(version.Altair), writer.Header().Get(api.EthConsensusVersionHeader))
sszExpected, err := fakeState.MarshalSSZ()
require.NoError(t, err)
assert.DeepEqual(t, sszExpected, writer.Body.Bytes())
@@ -368,13 +368,13 @@ func TestGetBeaconStateSSZV2(t *testing.T) {
request := httptest.NewRequest(http.MethodGet, "http://example.com/eth/v2/debug/beacon/states/{state_id}", nil)
request.SetPathValue("state_id", "head")
request.Header.Set("Accept", api.OctetStreamMediaType)
request.Header.Set(api.AcceptHeader, api.OctetStreamMediaType)
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.GetBeaconStateV2(writer, request)
require.Equal(t, http.StatusOK, writer.Code)
assert.Equal(t, version.String(version.Bellatrix), writer.Header().Get(api.VersionHeader))
assert.Equal(t, version.String(version.Bellatrix), writer.Header().Get(api.EthConsensusVersionHeader))
sszExpected, err := fakeState.MarshalSSZ()
require.NoError(t, err)
assert.DeepEqual(t, sszExpected, writer.Body.Bytes())
@@ -392,13 +392,13 @@ func TestGetBeaconStateSSZV2(t *testing.T) {
request := httptest.NewRequest(http.MethodGet, "http://example.com/eth/v2/debug/beacon/states/{state_id}", nil)
request.SetPathValue("state_id", "head")
request.Header.Set("Accept", api.OctetStreamMediaType)
request.Header.Set(api.AcceptHeader, api.OctetStreamMediaType)
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.GetBeaconStateV2(writer, request)
require.Equal(t, http.StatusOK, writer.Code)
assert.Equal(t, version.String(version.Capella), writer.Header().Get(api.VersionHeader))
assert.Equal(t, version.String(version.Capella), writer.Header().Get(api.EthConsensusVersionHeader))
sszExpected, err := fakeState.MarshalSSZ()
require.NoError(t, err)
assert.DeepEqual(t, sszExpected, writer.Body.Bytes())
@@ -416,13 +416,13 @@ func TestGetBeaconStateSSZV2(t *testing.T) {
request := httptest.NewRequest(http.MethodGet, "http://example.com/eth/v2/debug/beacon/states/{state_id}", nil)
request.SetPathValue("state_id", "head")
request.Header.Set("Accept", api.OctetStreamMediaType)
request.Header.Set(api.AcceptHeader, api.OctetStreamMediaType)
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.GetBeaconStateV2(writer, request)
require.Equal(t, http.StatusOK, writer.Code)
assert.Equal(t, version.String(version.Deneb), writer.Header().Get(api.VersionHeader))
assert.Equal(t, version.String(version.Deneb), writer.Header().Get(api.EthConsensusVersionHeader))
sszExpected, err := fakeState.MarshalSSZ()
require.NoError(t, err)
assert.DeepEqual(t, sszExpected, writer.Body.Bytes())

View File

@@ -101,7 +101,7 @@ func (w *StreamingResponseWriterRecorder) RequireStatus(t *testing.T, status int
}
func (w *StreamingResponseWriterRecorder) Flush() {
w.WriteHeader(200)
w.WriteHeader(http.StatusOK)
fw, ok := w.ResponseWriter.(http.Flusher)
if ok {
fw.Flush()

View File

@@ -31,6 +31,7 @@ go_test(
srcs = ["handlers_test.go"],
embed = [":go_default_library"],
deps = [
"//api:go_default_library",
"//api/server/structs:go_default_library",
"//async/event:go_default_library",
"//beacon-chain/blockchain/testing:go_default_library",

View File

@@ -43,7 +43,7 @@ func (s *Server) GetLightClientBootstrap(w http.ResponseWriter, req *http.Reques
return
}
w.Header().Set(api.VersionHeader, version.String(bootstrap.Version()))
w.Header().Set(api.EthConsensusVersionHeader, version.String(bootstrap.Version()))
if httputil.RespondWithSsz(req) {
ssz, err := bootstrap.MarshalSSZ()
@@ -111,7 +111,7 @@ func (s *Server) GetLightClientUpdatesByRange(w http.ResponseWriter, req *http.R
}
if httputil.RespondWithSsz(req) {
w.Header().Set("Content-Type", "application/octet-stream")
w.Header().Set(api.ContentTypeHeader, api.OctetStreamMediaType)
for _, update := range updates {
if ctx.Err() != nil {
@@ -174,7 +174,7 @@ func (s *Server) GetLightClientFinalityUpdate(w http.ResponseWriter, req *http.R
return
}
w.Header().Set(api.VersionHeader, version.String(update.Version()))
w.Header().Set(api.EthConsensusVersionHeader, version.String(update.Version()))
if httputil.RespondWithSsz(req) {
data, err := update.MarshalSSZ()
if err != nil {
@@ -207,7 +207,7 @@ func (s *Server) GetLightClientOptimisticUpdate(w http.ResponseWriter, req *http
return
}
w.Header().Set(api.VersionHeader, version.String(update.Version()))
w.Header().Set(api.EthConsensusVersionHeader, version.String(update.Version()))
if httputil.RespondWithSsz(req) {
data, err := update.MarshalSSZ()
if err != nil {

View File

@@ -11,6 +11,7 @@ import (
"strconv"
"testing"
"github.com/OffchainLabs/prysm/v6/api"
"github.com/OffchainLabs/prysm/v6/api/server/structs"
"github.com/OffchainLabs/prysm/v6/async/event"
blockchainTest "github.com/OffchainLabs/prysm/v6/beacon-chain/blockchain/testing"
@@ -114,7 +115,7 @@ func TestLightClientHandler_GetLightClientBootstrap(t *testing.T) {
}
request := httptest.NewRequest("GET", "http://foo.com/", nil)
request.SetPathValue("block_root", hexutil.Encode(blockRoot[:]))
request.Header.Add("Accept", "application/octet-stream")
request.Header.Add(api.AcceptHeader, api.OctetStreamMediaType)
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
@@ -235,7 +236,7 @@ func TestLightClientHandler_GetLightClientByRange(t *testing.T) {
t.Run("single update ssz", func(t *testing.T) {
url := fmt.Sprintf("http://foo.com/?count=1&start_period=%d", startPeriod)
request := httptest.NewRequest("GET", url, nil)
request.Header.Add("Accept", "application/octet-stream")
request.Header.Add(api.AcceptHeader, api.OctetStreamMediaType)
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
@@ -290,7 +291,7 @@ func TestLightClientHandler_GetLightClientByRange(t *testing.T) {
t.Run("multiple updates ssz", func(t *testing.T) {
url := fmt.Sprintf("http://foo.com/?count=100&start_period=%d", startPeriod)
request := httptest.NewRequest("GET", url, nil)
request.Header.Add("Accept", "application/octet-stream")
request.Header.Add(api.AcceptHeader, api.OctetStreamMediaType)
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
@@ -405,7 +406,7 @@ func TestLightClientHandler_GetLightClientByRange(t *testing.T) {
t.Run("ssz", func(t *testing.T) {
url := fmt.Sprintf("http://foo.com/?count=100&start_period=%d", startPeriod)
request := httptest.NewRequest("GET", url, nil)
request.Header.Add("Accept", "application/octet-stream")
request.Header.Add(api.AcceptHeader, api.OctetStreamMediaType)
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
@@ -777,7 +778,7 @@ func TestLightClientHandler_GetLightClientFinalityUpdate(t *testing.T) {
s.LCStore.SetLastFinalityUpdate(update, false)
request := httptest.NewRequest("GET", "http://foo.com", nil)
request.Header.Add("Accept", "application/octet-stream")
request.Header.Add(api.AcceptHeader, api.OctetStreamMediaType)
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.GetLightClientFinalityUpdate(writer, request)
@@ -870,7 +871,7 @@ func TestLightClientHandler_GetLightClientOptimisticUpdate(t *testing.T) {
s.LCStore.SetLastOptimisticUpdate(update, false)
request := httptest.NewRequest("GET", "http://foo.com", nil)
request.Header.Add("Accept", "application/octet-stream")
request.Header.Add(api.AcceptHeader, api.OctetStreamMediaType)
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.GetLightClientOptimisticUpdate(writer, request)

View File

@@ -4,6 +4,7 @@ import (
"encoding/json"
"fmt"
"net/http"
"slices"
"strconv"
"strings"
@@ -388,12 +389,9 @@ func syncRewardsVals(
scIndices := make([]primitives.ValidatorIndex, 0, len(allScIndices))
scVals := make([]*precompute.Validator, 0, len(allScIndices))
for _, valIdx := range valIndices {
for _, scIdx := range allScIndices {
if valIdx == scIdx {
scVals = append(scVals, allVals[valIdx])
scIndices = append(scIndices, valIdx)
break
}
if slices.Contains(allScIndices, valIdx) {
scVals = append(scVals, allVals[valIdx])
scIndices = append(scIndices, valIdx)
}
}

View File

@@ -127,7 +127,7 @@ func (s *Server) GetAggregateAttestationV2(w http.ResponseWriter, r *http.Reques
}
}
w.Header().Set(api.VersionHeader, version.String(v))
w.Header().Set(api.EthConsensusVersionHeader, version.String(v))
httputil.WriteSsz(w, data)
return
}
@@ -160,7 +160,7 @@ func (s *Server) GetAggregateAttestationV2(w http.ResponseWriter, r *http.Reques
}
resp.Data = data
}
w.Header().Set(api.VersionHeader, version.String(v))
w.Header().Set(api.EthConsensusVersionHeader, version.String(v))
httputil.WriteJson(w, resp)
}
@@ -397,9 +397,9 @@ func (s *Server) SubmitAggregateAndProofsV2(w http.ResponseWriter, r *http.Reque
return
}
versionHeader := r.Header.Get(api.VersionHeader)
versionHeader := r.Header.Get(api.EthConsensusVersionHeader)
if versionHeader == "" {
httputil.HandleError(w, api.VersionHeader+" header is required", http.StatusBadRequest)
httputil.HandleError(w, api.EthConsensusVersionHeader+" header is required", http.StatusBadRequest)
return
}
v, err := version.FromString(versionHeader)

View File

@@ -123,20 +123,20 @@ func (s *Server) produceBlockV3(ctx context.Context, w http.ResponseWriter, r *h
consensusBlockValue = "0"
}
w.Header().Set(api.ExecutionPayloadBlindedHeader, fmt.Sprintf("%v", v1alpha1resp.IsBlinded))
w.Header().Set(api.ExecutionPayloadValueHeader, v1alpha1resp.PayloadValue)
w.Header().Set(api.ConsensusBlockValueHeader, consensusBlockValue)
w.Header().Set(api.EthExecutionPayloadBlindedHeader, fmt.Sprintf("%v", v1alpha1resp.IsBlinded))
w.Header().Set(api.EthExecutionPayloadValueHeader, v1alpha1resp.PayloadValue)
w.Header().Set(api.EthConsensusBlockValueHeader, consensusBlockValue)
phase0Block, ok := v1alpha1resp.Block.(*eth.GenericBeaconBlock_Phase0)
if ok {
w.Header().Set(api.VersionHeader, version.String(version.Phase0))
w.Header().Set(api.EthConsensusVersionHeader, version.String(version.Phase0))
// rewards aren't used in phase 0
handleProducePhase0V3(w, isSSZ, phase0Block, v1alpha1resp.PayloadValue)
return
}
altairBlock, ok := v1alpha1resp.Block.(*eth.GenericBeaconBlock_Altair)
if ok {
w.Header().Set(api.VersionHeader, version.String(version.Altair))
w.Header().Set(api.EthConsensusVersionHeader, version.String(version.Altair))
handleProduceAltairV3(w, isSSZ, altairBlock, v1alpha1resp.PayloadValue, consensusBlockValue)
return
}
@@ -151,61 +151,61 @@ func (s *Server) produceBlockV3(ctx context.Context, w http.ResponseWriter, r *h
}
blindedBellatrixBlock, ok := v1alpha1resp.Block.(*eth.GenericBeaconBlock_BlindedBellatrix)
if ok {
w.Header().Set(api.VersionHeader, version.String(version.Bellatrix))
w.Header().Set(api.EthConsensusVersionHeader, version.String(version.Bellatrix))
handleProduceBlindedBellatrixV3(w, isSSZ, blindedBellatrixBlock, v1alpha1resp.PayloadValue, consensusBlockValue)
return
}
bellatrixBlock, ok := v1alpha1resp.Block.(*eth.GenericBeaconBlock_Bellatrix)
if ok {
w.Header().Set(api.VersionHeader, version.String(version.Bellatrix))
w.Header().Set(api.EthConsensusVersionHeader, version.String(version.Bellatrix))
handleProduceBellatrixV3(w, isSSZ, bellatrixBlock, v1alpha1resp.PayloadValue, consensusBlockValue)
return
}
blindedCapellaBlock, ok := v1alpha1resp.Block.(*eth.GenericBeaconBlock_BlindedCapella)
if ok {
w.Header().Set(api.VersionHeader, version.String(version.Capella))
w.Header().Set(api.EthConsensusVersionHeader, version.String(version.Capella))
handleProduceBlindedCapellaV3(w, isSSZ, blindedCapellaBlock, v1alpha1resp.PayloadValue, consensusBlockValue)
return
}
capellaBlock, ok := v1alpha1resp.Block.(*eth.GenericBeaconBlock_Capella)
if ok {
w.Header().Set(api.VersionHeader, version.String(version.Capella))
w.Header().Set(api.EthConsensusVersionHeader, version.String(version.Capella))
handleProduceCapellaV3(w, isSSZ, capellaBlock, v1alpha1resp.PayloadValue, consensusBlockValue)
return
}
blindedDenebBlockContents, ok := v1alpha1resp.Block.(*eth.GenericBeaconBlock_BlindedDeneb)
if ok {
w.Header().Set(api.VersionHeader, version.String(version.Deneb))
w.Header().Set(api.EthConsensusVersionHeader, version.String(version.Deneb))
handleProduceBlindedDenebV3(w, isSSZ, blindedDenebBlockContents, v1alpha1resp.PayloadValue, consensusBlockValue)
return
}
denebBlockContents, ok := v1alpha1resp.Block.(*eth.GenericBeaconBlock_Deneb)
if ok {
w.Header().Set(api.VersionHeader, version.String(version.Deneb))
w.Header().Set(api.EthConsensusVersionHeader, version.String(version.Deneb))
handleProduceDenebV3(w, isSSZ, denebBlockContents, v1alpha1resp.PayloadValue, consensusBlockValue)
return
}
blindedElectraBlockContents, ok := v1alpha1resp.Block.(*eth.GenericBeaconBlock_BlindedElectra)
if ok {
w.Header().Set(api.VersionHeader, version.String(version.Electra))
w.Header().Set(api.EthConsensusVersionHeader, version.String(version.Electra))
handleProduceBlindedElectraV3(w, isSSZ, blindedElectraBlockContents, v1alpha1resp.PayloadValue, consensusBlockValue)
return
}
electraBlockContents, ok := v1alpha1resp.Block.(*eth.GenericBeaconBlock_Electra)
if ok {
w.Header().Set(api.VersionHeader, version.String(version.Electra))
w.Header().Set(api.EthConsensusVersionHeader, version.String(version.Electra))
handleProduceElectraV3(w, isSSZ, electraBlockContents, v1alpha1resp.PayloadValue, consensusBlockValue)
return
}
blindedFuluBlockContents, ok := v1alpha1resp.Block.(*eth.GenericBeaconBlock_BlindedFulu)
if ok {
w.Header().Set(api.VersionHeader, version.String(version.Fulu))
w.Header().Set(api.EthConsensusVersionHeader, version.String(version.Fulu))
handleProduceBlindedFuluV3(w, isSSZ, blindedFuluBlockContents, v1alpha1resp.PayloadValue, consensusBlockValue)
return
}
fuluBlockContents, ok := v1alpha1resp.Block.(*eth.GenericBeaconBlock_Fulu)
if ok {
w.Header().Set(api.VersionHeader, version.String(version.Fulu))
w.Header().Set(api.EthConsensusVersionHeader, version.String(version.Fulu))
handleProduceFuluV3(w, isSSZ, fuluBlockContents, v1alpha1resp.PayloadValue, consensusBlockValue)
return
}

View File

@@ -64,10 +64,10 @@ func TestProduceBlockV3(t *testing.T) {
want := fmt.Sprintf(`{"version":"phase0","execution_payload_blinded":false,"execution_payload_value":"","consensus_block_value":"","data":%s}`, string(jsonBytes))
body := strings.ReplaceAll(writer.Body.String(), "\n", "")
require.Equal(t, want, body)
require.Equal(t, "false", writer.Header().Get(api.ExecutionPayloadBlindedHeader))
require.Equal(t, "", writer.Header().Get(api.ExecutionPayloadValueHeader))
require.Equal(t, "phase0", writer.Header().Get(api.VersionHeader))
require.Equal(t, "", writer.Header().Get(api.ConsensusBlockValueHeader))
require.Equal(t, "false", writer.Header().Get(api.EthExecutionPayloadBlindedHeader))
require.Equal(t, "", writer.Header().Get(api.EthExecutionPayloadValueHeader))
require.Equal(t, "phase0", writer.Header().Get(api.EthConsensusVersionHeader))
require.Equal(t, "", writer.Header().Get(api.EthConsensusBlockValueHeader))
})
t.Run("Altair", func(t *testing.T) {
var block *structs.SignedBeaconBlockAltair
@@ -100,10 +100,10 @@ func TestProduceBlockV3(t *testing.T) {
want := fmt.Sprintf(`{"version":"altair","execution_payload_blinded":false,"execution_payload_value":"","consensus_block_value":"10000000000","data":%s}`, string(jsonBytes))
body := strings.ReplaceAll(writer.Body.String(), "\n", "")
require.Equal(t, want, body)
require.Equal(t, "false", writer.Header().Get(api.ExecutionPayloadBlindedHeader))
require.Equal(t, "", writer.Header().Get(api.ExecutionPayloadValueHeader))
require.Equal(t, "altair", writer.Header().Get(api.VersionHeader))
require.Equal(t, "10000000000", writer.Header().Get(api.ConsensusBlockValueHeader))
require.Equal(t, "false", writer.Header().Get(api.EthExecutionPayloadBlindedHeader))
require.Equal(t, "", writer.Header().Get(api.EthExecutionPayloadValueHeader))
require.Equal(t, "altair", writer.Header().Get(api.EthConsensusVersionHeader))
require.Equal(t, "10000000000", writer.Header().Get(api.EthConsensusBlockValueHeader))
})
t.Run("Bellatrix", func(t *testing.T) {
var block *structs.SignedBeaconBlockBellatrix
@@ -138,10 +138,10 @@ func TestProduceBlockV3(t *testing.T) {
want := fmt.Sprintf(`{"version":"bellatrix","execution_payload_blinded":false,"execution_payload_value":"2000","consensus_block_value":"10000000000","data":%s}`, string(jsonBytes))
body := strings.ReplaceAll(writer.Body.String(), "\n", "")
require.Equal(t, want, body)
require.Equal(t, "false", writer.Header().Get(api.ExecutionPayloadBlindedHeader))
require.Equal(t, "2000", writer.Header().Get(api.ExecutionPayloadValueHeader))
require.Equal(t, "bellatrix", writer.Header().Get(api.VersionHeader))
require.Equal(t, "10000000000", writer.Header().Get(api.ConsensusBlockValueHeader))
require.Equal(t, "false", writer.Header().Get(api.EthExecutionPayloadBlindedHeader))
require.Equal(t, "2000", writer.Header().Get(api.EthExecutionPayloadValueHeader))
require.Equal(t, "bellatrix", writer.Header().Get(api.EthConsensusVersionHeader))
require.Equal(t, "10000000000", writer.Header().Get(api.EthConsensusBlockValueHeader))
})
t.Run("BlindedBellatrix", func(t *testing.T) {
var block *structs.SignedBlindedBeaconBlockBellatrix
@@ -176,10 +176,10 @@ func TestProduceBlockV3(t *testing.T) {
want := fmt.Sprintf(`{"version":"bellatrix","execution_payload_blinded":true,"execution_payload_value":"2000","consensus_block_value":"10000000000","data":%s}`, string(jsonBytes))
body := strings.ReplaceAll(writer.Body.String(), "\n", "")
require.Equal(t, want, body)
require.Equal(t, "true", writer.Header().Get(api.ExecutionPayloadBlindedHeader))
require.Equal(t, "2000", writer.Header().Get(api.ExecutionPayloadValueHeader))
require.Equal(t, "bellatrix", writer.Header().Get(api.VersionHeader))
require.Equal(t, "10000000000", writer.Header().Get(api.ConsensusBlockValueHeader))
require.Equal(t, "true", writer.Header().Get(api.EthExecutionPayloadBlindedHeader))
require.Equal(t, "2000", writer.Header().Get(api.EthExecutionPayloadValueHeader))
require.Equal(t, "bellatrix", writer.Header().Get(api.EthConsensusVersionHeader))
require.Equal(t, "10000000000", writer.Header().Get(api.EthConsensusBlockValueHeader))
})
t.Run("Capella", func(t *testing.T) {
var block *structs.SignedBeaconBlockCapella
@@ -214,10 +214,10 @@ func TestProduceBlockV3(t *testing.T) {
want := fmt.Sprintf(`{"version":"capella","execution_payload_blinded":false,"execution_payload_value":"2000","consensus_block_value":"10000000000","data":%s}`, string(jsonBytes))
body := strings.ReplaceAll(writer.Body.String(), "\n", "")
require.Equal(t, want, body)
require.Equal(t, "false", writer.Header().Get(api.ExecutionPayloadBlindedHeader))
require.Equal(t, "2000", writer.Header().Get(api.ExecutionPayloadValueHeader))
require.Equal(t, "capella", writer.Header().Get(api.VersionHeader))
require.Equal(t, "10000000000", writer.Header().Get(api.ConsensusBlockValueHeader))
require.Equal(t, "false", writer.Header().Get(api.EthExecutionPayloadBlindedHeader))
require.Equal(t, "2000", writer.Header().Get(api.EthExecutionPayloadValueHeader))
require.Equal(t, "capella", writer.Header().Get(api.EthConsensusVersionHeader))
require.Equal(t, "10000000000", writer.Header().Get(api.EthConsensusBlockValueHeader))
})
t.Run("Blinded Capella", func(t *testing.T) {
var block *structs.SignedBlindedBeaconBlockCapella
@@ -252,10 +252,10 @@ func TestProduceBlockV3(t *testing.T) {
want := fmt.Sprintf(`{"version":"capella","execution_payload_blinded":true,"execution_payload_value":"2000","consensus_block_value":"10000000000","data":%s}`, string(jsonBytes))
body := strings.ReplaceAll(writer.Body.String(), "\n", "")
require.Equal(t, want, body)
require.Equal(t, "true", writer.Header().Get(api.ExecutionPayloadBlindedHeader))
require.Equal(t, "2000", writer.Header().Get(api.ExecutionPayloadValueHeader))
require.Equal(t, "capella", writer.Header().Get(api.VersionHeader))
require.Equal(t, "10000000000", writer.Header().Get(api.ConsensusBlockValueHeader))
require.Equal(t, "true", writer.Header().Get(api.EthExecutionPayloadBlindedHeader))
require.Equal(t, "2000", writer.Header().Get(api.EthExecutionPayloadValueHeader))
require.Equal(t, "capella", writer.Header().Get(api.EthConsensusVersionHeader))
require.Equal(t, "10000000000", writer.Header().Get(api.EthConsensusBlockValueHeader))
})
t.Run("Deneb", func(t *testing.T) {
var block *structs.SignedBeaconBlockContentsDeneb
@@ -290,10 +290,10 @@ func TestProduceBlockV3(t *testing.T) {
want := fmt.Sprintf(`{"version":"deneb","execution_payload_blinded":false,"execution_payload_value":"2000","consensus_block_value":"10000000000","data":%s}`, string(jsonBytes))
body := strings.ReplaceAll(writer.Body.String(), "\n", "")
require.Equal(t, want, body)
require.Equal(t, "false", writer.Header().Get(api.ExecutionPayloadBlindedHeader))
require.Equal(t, "2000", writer.Header().Get(api.ExecutionPayloadValueHeader))
require.Equal(t, "deneb", writer.Header().Get(api.VersionHeader))
require.Equal(t, "10000000000", writer.Header().Get(api.ConsensusBlockValueHeader))
require.Equal(t, "false", writer.Header().Get(api.EthExecutionPayloadBlindedHeader))
require.Equal(t, "2000", writer.Header().Get(api.EthExecutionPayloadValueHeader))
require.Equal(t, "deneb", writer.Header().Get(api.EthConsensusVersionHeader))
require.Equal(t, "10000000000", writer.Header().Get(api.EthConsensusBlockValueHeader))
})
t.Run("Blinded Deneb", func(t *testing.T) {
var block *structs.SignedBlindedBeaconBlockDeneb
@@ -328,10 +328,10 @@ func TestProduceBlockV3(t *testing.T) {
want := fmt.Sprintf(`{"version":"deneb","execution_payload_blinded":true,"execution_payload_value":"2000","consensus_block_value":"10000000000","data":%s}`, string(jsonBytes))
body := strings.ReplaceAll(writer.Body.String(), "\n", "")
require.Equal(t, want, body)
require.Equal(t, "true", writer.Header().Get(api.ExecutionPayloadBlindedHeader))
require.Equal(t, "2000", writer.Header().Get(api.ExecutionPayloadValueHeader))
require.Equal(t, "deneb", writer.Header().Get(api.VersionHeader))
require.Equal(t, "10000000000", writer.Header().Get(api.ConsensusBlockValueHeader))
require.Equal(t, "true", writer.Header().Get(api.EthExecutionPayloadBlindedHeader))
require.Equal(t, "2000", writer.Header().Get(api.EthExecutionPayloadValueHeader))
require.Equal(t, "deneb", writer.Header().Get(api.EthConsensusVersionHeader))
require.Equal(t, "10000000000", writer.Header().Get(api.EthConsensusBlockValueHeader))
})
t.Run("Electra", func(t *testing.T) {
var block *structs.SignedBeaconBlockContentsElectra
@@ -366,10 +366,10 @@ func TestProduceBlockV3(t *testing.T) {
want := fmt.Sprintf(`{"version":"electra","execution_payload_blinded":false,"execution_payload_value":"2000","consensus_block_value":"10000000000","data":%s}`, string(jsonBytes))
body := strings.ReplaceAll(writer.Body.String(), "\n", "")
require.Equal(t, want, body)
require.Equal(t, "false", writer.Header().Get(api.ExecutionPayloadBlindedHeader))
require.Equal(t, "2000", writer.Header().Get(api.ExecutionPayloadValueHeader))
require.Equal(t, "electra", writer.Header().Get(api.VersionHeader))
require.Equal(t, "10000000000", writer.Header().Get(api.ConsensusBlockValueHeader))
require.Equal(t, "false", writer.Header().Get(api.EthExecutionPayloadBlindedHeader))
require.Equal(t, "2000", writer.Header().Get(api.EthExecutionPayloadValueHeader))
require.Equal(t, "electra", writer.Header().Get(api.EthConsensusVersionHeader))
require.Equal(t, "10000000000", writer.Header().Get(api.EthConsensusBlockValueHeader))
})
t.Run("Blinded Electra", func(t *testing.T) {
var block *structs.SignedBlindedBeaconBlockElectra
@@ -404,10 +404,10 @@ func TestProduceBlockV3(t *testing.T) {
want := fmt.Sprintf(`{"version":"electra","execution_payload_blinded":true,"execution_payload_value":"2000","consensus_block_value":"10000000000","data":%s}`, string(jsonBytes))
body := strings.ReplaceAll(writer.Body.String(), "\n", "")
require.Equal(t, want, body)
require.Equal(t, "true", writer.Header().Get(api.ExecutionPayloadBlindedHeader))
require.Equal(t, "2000", writer.Header().Get(api.ExecutionPayloadValueHeader))
require.Equal(t, "electra", writer.Header().Get(api.VersionHeader))
require.Equal(t, "10000000000", writer.Header().Get(api.ConsensusBlockValueHeader))
require.Equal(t, "true", writer.Header().Get(api.EthExecutionPayloadBlindedHeader))
require.Equal(t, "2000", writer.Header().Get(api.EthExecutionPayloadValueHeader))
require.Equal(t, "electra", writer.Header().Get(api.EthConsensusVersionHeader))
require.Equal(t, "10000000000", writer.Header().Get(api.EthConsensusBlockValueHeader))
})
t.Run("Fulu", func(t *testing.T) {
var block *structs.SignedBeaconBlockContentsFulu
@@ -442,10 +442,10 @@ func TestProduceBlockV3(t *testing.T) {
want := fmt.Sprintf(`{"version":"fulu","execution_payload_blinded":false,"execution_payload_value":"2000","consensus_block_value":"10000000000","data":%s}`, string(jsonBytes))
body := strings.ReplaceAll(writer.Body.String(), "\n", "")
require.Equal(t, want, body)
require.Equal(t, "false", writer.Header().Get(api.ExecutionPayloadBlindedHeader))
require.Equal(t, "2000", writer.Header().Get(api.ExecutionPayloadValueHeader))
require.Equal(t, "fulu", writer.Header().Get(api.VersionHeader))
require.Equal(t, "10000000000", writer.Header().Get(api.ConsensusBlockValueHeader))
require.Equal(t, "false", writer.Header().Get(api.EthExecutionPayloadBlindedHeader))
require.Equal(t, "2000", writer.Header().Get(api.EthExecutionPayloadValueHeader))
require.Equal(t, "fulu", writer.Header().Get(api.EthConsensusVersionHeader))
require.Equal(t, "10000000000", writer.Header().Get(api.EthConsensusBlockValueHeader))
})
t.Run("Blinded Fulu", func(t *testing.T) {
var block *structs.SignedBlindedBeaconBlockFulu
@@ -480,10 +480,10 @@ func TestProduceBlockV3(t *testing.T) {
want := fmt.Sprintf(`{"version":"fulu","execution_payload_blinded":true,"execution_payload_value":"2000","consensus_block_value":"10000000000","data":%s}`, string(jsonBytes))
body := strings.ReplaceAll(writer.Body.String(), "\n", "")
require.Equal(t, want, body)
require.Equal(t, "true", writer.Header().Get(api.ExecutionPayloadBlindedHeader))
require.Equal(t, "2000", writer.Header().Get(api.ExecutionPayloadValueHeader))
require.Equal(t, "fulu", writer.Header().Get(api.VersionHeader))
require.Equal(t, "10000000000", writer.Header().Get(api.ConsensusBlockValueHeader))
require.Equal(t, "true", writer.Header().Get(api.EthExecutionPayloadBlindedHeader))
require.Equal(t, "2000", writer.Header().Get(api.EthExecutionPayloadValueHeader))
require.Equal(t, "fulu", writer.Header().Get(api.EthConsensusVersionHeader))
require.Equal(t, "10000000000", writer.Header().Get(api.EthConsensusBlockValueHeader))
})
t.Run("invalid query parameter slot empty", func(t *testing.T) {
v1alpha1Server := mock2.NewMockBeaconNodeValidatorServer(ctrl)
@@ -573,10 +573,10 @@ func TestProduceBlockV3(t *testing.T) {
want := fmt.Sprintf(`{"version":"fulu","execution_payload_blinded":false,"execution_payload_value":"2000","consensus_block_value":"0","data":%s}`, string(jsonBytes))
body := strings.ReplaceAll(writer.Body.String(), "\n", "")
require.Equal(t, want, body)
require.Equal(t, "false", writer.Header().Get(api.ExecutionPayloadBlindedHeader))
require.Equal(t, "2000", writer.Header().Get(api.ExecutionPayloadValueHeader))
require.Equal(t, "fulu", writer.Header().Get(api.VersionHeader))
require.Equal(t, "0", writer.Header().Get(api.ConsensusBlockValueHeader))
require.Equal(t, "false", writer.Header().Get(api.EthExecutionPayloadBlindedHeader))
require.Equal(t, "2000", writer.Header().Get(api.EthExecutionPayloadValueHeader))
require.Equal(t, "fulu", writer.Header().Get(api.EthConsensusVersionHeader))
require.Equal(t, "0", writer.Header().Get(api.EthConsensusBlockValueHeader))
})
}
@@ -611,7 +611,7 @@ func TestProduceBlockV3SSZ(t *testing.T) {
SyncChecker: syncChecker,
}
request := httptest.NewRequest(http.MethodGet, fmt.Sprintf("http://foo.example/eth/v3/validator/blocks/1?randao_reveal=%s&graffiti=%s", randao, graffiti), nil)
request.Header.Set("Accept", api.OctetStreamMediaType)
request.Header.Set(api.AcceptHeader, api.OctetStreamMediaType)
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
server.ProduceBlockV3(writer, request)
@@ -623,10 +623,10 @@ func TestProduceBlockV3SSZ(t *testing.T) {
ssz, err := bl.Phase0.Block.MarshalSSZ()
require.NoError(t, err)
require.Equal(t, string(ssz), writer.Body.String())
require.Equal(t, "false", writer.Header().Get(api.ExecutionPayloadBlindedHeader))
require.Equal(t, "", writer.Header().Get(api.ExecutionPayloadValueHeader))
require.Equal(t, "phase0", writer.Header().Get(api.VersionHeader))
require.Equal(t, "", writer.Header().Get(api.ConsensusBlockValueHeader))
require.Equal(t, "false", writer.Header().Get(api.EthExecutionPayloadBlindedHeader))
require.Equal(t, "", writer.Header().Get(api.EthExecutionPayloadValueHeader))
require.Equal(t, "phase0", writer.Header().Get(api.EthConsensusVersionHeader))
require.Equal(t, "", writer.Header().Get(api.EthConsensusBlockValueHeader))
})
t.Run("Altair", func(t *testing.T) {
var block *structs.SignedBeaconBlockAltair
@@ -649,7 +649,7 @@ func TestProduceBlockV3SSZ(t *testing.T) {
BlockRewardFetcher: rewardFetcher,
}
request := httptest.NewRequest(http.MethodGet, fmt.Sprintf("http://foo.example/eth/v3/validator/blocks/1?randao_reveal=%s&graffiti=%s", randao, graffiti), nil)
request.Header.Set("Accept", api.OctetStreamMediaType)
request.Header.Set(api.AcceptHeader, api.OctetStreamMediaType)
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
server.ProduceBlockV3(writer, request)
@@ -661,10 +661,10 @@ func TestProduceBlockV3SSZ(t *testing.T) {
ssz, err := bl.Altair.Block.MarshalSSZ()
require.NoError(t, err)
require.Equal(t, string(ssz), writer.Body.String())
require.Equal(t, "false", writer.Header().Get(api.ExecutionPayloadBlindedHeader))
require.Equal(t, "", writer.Header().Get(api.ExecutionPayloadValueHeader))
require.Equal(t, "altair", writer.Header().Get(api.VersionHeader))
require.Equal(t, "10000000000", writer.Header().Get(api.ConsensusBlockValueHeader))
require.Equal(t, "false", writer.Header().Get(api.EthExecutionPayloadBlindedHeader))
require.Equal(t, "", writer.Header().Get(api.EthExecutionPayloadValueHeader))
require.Equal(t, "altair", writer.Header().Get(api.EthConsensusVersionHeader))
require.Equal(t, "10000000000", writer.Header().Get(api.EthConsensusBlockValueHeader))
})
t.Run("Bellatrix", func(t *testing.T) {
var block *structs.SignedBeaconBlockBellatrix
@@ -691,7 +691,7 @@ func TestProduceBlockV3SSZ(t *testing.T) {
BlockRewardFetcher: rewardFetcher,
}
request := httptest.NewRequest(http.MethodGet, fmt.Sprintf("http://foo.example/eth/v3/validator/blocks/1?randao_reveal=%s&graffiti=%s", randao, graffiti), nil)
request.Header.Set("Accept", api.OctetStreamMediaType)
request.Header.Set(api.AcceptHeader, api.OctetStreamMediaType)
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
server.ProduceBlockV3(writer, request)
@@ -703,10 +703,10 @@ func TestProduceBlockV3SSZ(t *testing.T) {
ssz, err := bl.Bellatrix.Block.MarshalSSZ()
require.NoError(t, err)
require.Equal(t, string(ssz), writer.Body.String())
require.Equal(t, "false", writer.Header().Get(api.ExecutionPayloadBlindedHeader))
require.Equal(t, "2000", writer.Header().Get(api.ExecutionPayloadValueHeader))
require.Equal(t, "bellatrix", writer.Header().Get(api.VersionHeader))
require.Equal(t, "10000000000", writer.Header().Get(api.ConsensusBlockValueHeader))
require.Equal(t, "false", writer.Header().Get(api.EthExecutionPayloadBlindedHeader))
require.Equal(t, "2000", writer.Header().Get(api.EthExecutionPayloadValueHeader))
require.Equal(t, "bellatrix", writer.Header().Get(api.EthConsensusVersionHeader))
require.Equal(t, "10000000000", writer.Header().Get(api.EthConsensusBlockValueHeader))
})
t.Run("BlindedBellatrix", func(t *testing.T) {
var block *structs.SignedBlindedBeaconBlockBellatrix
@@ -732,7 +732,7 @@ func TestProduceBlockV3SSZ(t *testing.T) {
BlockRewardFetcher: rewardFetcher,
}
request := httptest.NewRequest(http.MethodGet, fmt.Sprintf("http://foo.example/eth/v3/validator/blocks/1?randao_reveal=%s&graffiti=%s", randao, graffiti), nil)
request.Header.Set("Accept", api.OctetStreamMediaType)
request.Header.Set(api.AcceptHeader, api.OctetStreamMediaType)
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
server.ProduceBlockV3(writer, request)
@@ -744,10 +744,10 @@ func TestProduceBlockV3SSZ(t *testing.T) {
ssz, err := bl.BlindedBellatrix.Block.MarshalSSZ()
require.NoError(t, err)
require.Equal(t, string(ssz), writer.Body.String())
require.Equal(t, "true", writer.Header().Get(api.ExecutionPayloadBlindedHeader))
require.Equal(t, "2000", writer.Header().Get(api.ExecutionPayloadValueHeader))
require.Equal(t, "bellatrix", writer.Header().Get(api.VersionHeader))
require.Equal(t, "10000000000", writer.Header().Get(api.ConsensusBlockValueHeader))
require.Equal(t, "true", writer.Header().Get(api.EthExecutionPayloadBlindedHeader))
require.Equal(t, "2000", writer.Header().Get(api.EthExecutionPayloadValueHeader))
require.Equal(t, "bellatrix", writer.Header().Get(api.EthConsensusVersionHeader))
require.Equal(t, "10000000000", writer.Header().Get(api.EthConsensusBlockValueHeader))
})
t.Run("Capella", func(t *testing.T) {
var block *structs.SignedBeaconBlockCapella
@@ -773,7 +773,7 @@ func TestProduceBlockV3SSZ(t *testing.T) {
BlockRewardFetcher: rewardFetcher,
}
request := httptest.NewRequest(http.MethodGet, fmt.Sprintf("http://foo.example/eth/v3/validator/blocks/1?randao_reveal=%s&graffiti=%s", randao, graffiti), nil)
request.Header.Set("Accept", api.OctetStreamMediaType)
request.Header.Set(api.AcceptHeader, api.OctetStreamMediaType)
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
server.ProduceBlockV3(writer, request)
@@ -785,10 +785,10 @@ func TestProduceBlockV3SSZ(t *testing.T) {
ssz, err := bl.Capella.Block.MarshalSSZ()
require.NoError(t, err)
require.Equal(t, string(ssz), writer.Body.String())
require.Equal(t, "false", writer.Header().Get(api.ExecutionPayloadBlindedHeader))
require.Equal(t, "2000", writer.Header().Get(api.ExecutionPayloadValueHeader))
require.Equal(t, "capella", writer.Header().Get(api.VersionHeader))
require.Equal(t, "10000000000", writer.Header().Get(api.ConsensusBlockValueHeader))
require.Equal(t, "false", writer.Header().Get(api.EthExecutionPayloadBlindedHeader))
require.Equal(t, "2000", writer.Header().Get(api.EthExecutionPayloadValueHeader))
require.Equal(t, "capella", writer.Header().Get(api.EthConsensusVersionHeader))
require.Equal(t, "10000000000", writer.Header().Get(api.EthConsensusBlockValueHeader))
})
t.Run("Blinded Capella", func(t *testing.T) {
var block *structs.SignedBlindedBeaconBlockCapella
@@ -814,7 +814,7 @@ func TestProduceBlockV3SSZ(t *testing.T) {
BlockRewardFetcher: rewardFetcher,
}
request := httptest.NewRequest(http.MethodGet, fmt.Sprintf("http://foo.example/eth/v3/validator/blocks/1?randao_reveal=%s&graffiti=%s", randao, graffiti), nil)
request.Header.Set("Accept", api.OctetStreamMediaType)
request.Header.Set(api.AcceptHeader, api.OctetStreamMediaType)
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
server.ProduceBlockV3(writer, request)
@@ -826,10 +826,10 @@ func TestProduceBlockV3SSZ(t *testing.T) {
ssz, err := bl.BlindedCapella.Block.MarshalSSZ()
require.NoError(t, err)
require.Equal(t, string(ssz), writer.Body.String())
require.Equal(t, "true", writer.Header().Get(api.ExecutionPayloadBlindedHeader))
require.Equal(t, "2000", writer.Header().Get(api.ExecutionPayloadValueHeader))
require.Equal(t, "capella", writer.Header().Get(api.VersionHeader))
require.Equal(t, "10000000000", writer.Header().Get(api.ConsensusBlockValueHeader))
require.Equal(t, "true", writer.Header().Get(api.EthExecutionPayloadBlindedHeader))
require.Equal(t, "2000", writer.Header().Get(api.EthExecutionPayloadValueHeader))
require.Equal(t, "capella", writer.Header().Get(api.EthConsensusVersionHeader))
require.Equal(t, "10000000000", writer.Header().Get(api.EthConsensusBlockValueHeader))
})
t.Run("Deneb", func(t *testing.T) {
var block *structs.SignedBeaconBlockContentsDeneb
@@ -855,7 +855,7 @@ func TestProduceBlockV3SSZ(t *testing.T) {
BlockRewardFetcher: rewardFetcher,
}
request := httptest.NewRequest(http.MethodGet, fmt.Sprintf("http://foo.example/eth/v3/validator/blocks/1?randao_reveal=%s&graffiti=%s", randao, graffiti), nil)
request.Header.Set("Accept", api.OctetStreamMediaType)
request.Header.Set(api.AcceptHeader, api.OctetStreamMediaType)
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
server.ProduceBlockV3(writer, request)
@@ -867,10 +867,10 @@ func TestProduceBlockV3SSZ(t *testing.T) {
ssz, err := bl.Deneb.MarshalSSZ()
require.NoError(t, err)
require.Equal(t, string(ssz), writer.Body.String())
require.Equal(t, "false", writer.Header().Get(api.ExecutionPayloadBlindedHeader))
require.Equal(t, "2000", writer.Header().Get(api.ExecutionPayloadValueHeader))
require.Equal(t, "deneb", writer.Header().Get(api.VersionHeader))
require.Equal(t, "10000000000", writer.Header().Get(api.ConsensusBlockValueHeader))
require.Equal(t, "false", writer.Header().Get(api.EthExecutionPayloadBlindedHeader))
require.Equal(t, "2000", writer.Header().Get(api.EthExecutionPayloadValueHeader))
require.Equal(t, "deneb", writer.Header().Get(api.EthConsensusVersionHeader))
require.Equal(t, "10000000000", writer.Header().Get(api.EthConsensusBlockValueHeader))
})
t.Run("Blinded Deneb", func(t *testing.T) {
var block *structs.SignedBlindedBeaconBlockDeneb
@@ -896,7 +896,7 @@ func TestProduceBlockV3SSZ(t *testing.T) {
BlockRewardFetcher: rewardFetcher,
}
request := httptest.NewRequest(http.MethodGet, fmt.Sprintf("http://foo.example/eth/v3/validator/blocks/1?randao_reveal=%s&graffiti=%s", randao, graffiti), nil)
request.Header.Set("Accept", api.OctetStreamMediaType)
request.Header.Set(api.AcceptHeader, api.OctetStreamMediaType)
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
server.ProduceBlockV3(writer, request)
@@ -908,10 +908,10 @@ func TestProduceBlockV3SSZ(t *testing.T) {
ssz, err := bl.BlindedDeneb.MarshalSSZ()
require.NoError(t, err)
require.Equal(t, string(ssz), writer.Body.String())
require.Equal(t, "true", writer.Header().Get(api.ExecutionPayloadBlindedHeader))
require.Equal(t, "2000", writer.Header().Get(api.ExecutionPayloadValueHeader))
require.Equal(t, "deneb", writer.Header().Get(api.VersionHeader))
require.Equal(t, "10000000000", writer.Header().Get(api.ConsensusBlockValueHeader))
require.Equal(t, "true", writer.Header().Get(api.EthExecutionPayloadBlindedHeader))
require.Equal(t, "2000", writer.Header().Get(api.EthExecutionPayloadValueHeader))
require.Equal(t, "deneb", writer.Header().Get(api.EthConsensusVersionHeader))
require.Equal(t, "10000000000", writer.Header().Get(api.EthConsensusBlockValueHeader))
})
t.Run("Electra", func(t *testing.T) {
var block *structs.SignedBeaconBlockContentsElectra
@@ -937,7 +937,7 @@ func TestProduceBlockV3SSZ(t *testing.T) {
BlockRewardFetcher: rewardFetcher,
}
request := httptest.NewRequest(http.MethodGet, fmt.Sprintf("http://foo.example/eth/v3/validator/blocks/1?randao_reveal=%s&graffiti=%s", randao, graffiti), nil)
request.Header.Set("Accept", api.OctetStreamMediaType)
request.Header.Set(api.AcceptHeader, api.OctetStreamMediaType)
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
server.ProduceBlockV3(writer, request)
@@ -949,10 +949,10 @@ func TestProduceBlockV3SSZ(t *testing.T) {
ssz, err := bl.Electra.MarshalSSZ()
require.NoError(t, err)
require.Equal(t, string(ssz), writer.Body.String())
require.Equal(t, "false", writer.Header().Get(api.ExecutionPayloadBlindedHeader))
require.Equal(t, "2000", writer.Header().Get(api.ExecutionPayloadValueHeader))
require.Equal(t, "electra", writer.Header().Get(api.VersionHeader))
require.Equal(t, "10000000000", writer.Header().Get(api.ConsensusBlockValueHeader))
require.Equal(t, "false", writer.Header().Get(api.EthExecutionPayloadBlindedHeader))
require.Equal(t, "2000", writer.Header().Get(api.EthExecutionPayloadValueHeader))
require.Equal(t, "electra", writer.Header().Get(api.EthConsensusVersionHeader))
require.Equal(t, "10000000000", writer.Header().Get(api.EthConsensusBlockValueHeader))
})
t.Run("Blinded Electra", func(t *testing.T) {
var block *structs.SignedBlindedBeaconBlockElectra
@@ -978,7 +978,7 @@ func TestProduceBlockV3SSZ(t *testing.T) {
BlockRewardFetcher: rewardFetcher,
}
request := httptest.NewRequest(http.MethodGet, fmt.Sprintf("http://foo.example/eth/v3/validator/blocks/1?randao_reveal=%s&graffiti=%s", randao, graffiti), nil)
request.Header.Set("Accept", api.OctetStreamMediaType)
request.Header.Set(api.AcceptHeader, api.OctetStreamMediaType)
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
server.ProduceBlockV3(writer, request)
@@ -990,10 +990,10 @@ func TestProduceBlockV3SSZ(t *testing.T) {
ssz, err := bl.BlindedElectra.MarshalSSZ()
require.NoError(t, err)
require.Equal(t, string(ssz), writer.Body.String())
require.Equal(t, "true", writer.Header().Get(api.ExecutionPayloadBlindedHeader))
require.Equal(t, "2000", writer.Header().Get(api.ExecutionPayloadValueHeader))
require.Equal(t, "electra", writer.Header().Get(api.VersionHeader))
require.Equal(t, "10000000000", writer.Header().Get(api.ConsensusBlockValueHeader))
require.Equal(t, "true", writer.Header().Get(api.EthExecutionPayloadBlindedHeader))
require.Equal(t, "2000", writer.Header().Get(api.EthExecutionPayloadValueHeader))
require.Equal(t, "electra", writer.Header().Get(api.EthConsensusVersionHeader))
require.Equal(t, "10000000000", writer.Header().Get(api.EthConsensusBlockValueHeader))
})
t.Run("Fulu", func(t *testing.T) {
var block *structs.SignedBeaconBlockContentsFulu
@@ -1019,7 +1019,7 @@ func TestProduceBlockV3SSZ(t *testing.T) {
BlockRewardFetcher: rewardFetcher,
}
request := httptest.NewRequest(http.MethodGet, fmt.Sprintf("http://foo.example/eth/v3/validator/blocks/1?randao_reveal=%s&graffiti=%s", randao, graffiti), nil)
request.Header.Set("Accept", api.OctetStreamMediaType)
request.Header.Set(api.AcceptHeader, api.OctetStreamMediaType)
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
server.ProduceBlockV3(writer, request)
@@ -1031,10 +1031,10 @@ func TestProduceBlockV3SSZ(t *testing.T) {
ssz, err := bl.Fulu.MarshalSSZ()
require.NoError(t, err)
require.Equal(t, string(ssz), writer.Body.String())
require.Equal(t, "false", writer.Header().Get(api.ExecutionPayloadBlindedHeader))
require.Equal(t, "2000", writer.Header().Get(api.ExecutionPayloadValueHeader))
require.Equal(t, "fulu", writer.Header().Get(api.VersionHeader))
require.Equal(t, "10000000000", writer.Header().Get(api.ConsensusBlockValueHeader))
require.Equal(t, "false", writer.Header().Get(api.EthExecutionPayloadBlindedHeader))
require.Equal(t, "2000", writer.Header().Get(api.EthExecutionPayloadValueHeader))
require.Equal(t, "fulu", writer.Header().Get(api.EthConsensusVersionHeader))
require.Equal(t, "10000000000", writer.Header().Get(api.EthConsensusBlockValueHeader))
})
t.Run("Blinded Fulu", func(t *testing.T) {
var block *structs.SignedBlindedBeaconBlockFulu
@@ -1060,7 +1060,7 @@ func TestProduceBlockV3SSZ(t *testing.T) {
BlockRewardFetcher: rewardFetcher,
}
request := httptest.NewRequest(http.MethodGet, fmt.Sprintf("http://foo.example/eth/v3/validator/blocks/1?randao_reveal=%s&graffiti=%s", randao, graffiti), nil)
request.Header.Set("Accept", api.OctetStreamMediaType)
request.Header.Set(api.AcceptHeader, api.OctetStreamMediaType)
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
server.ProduceBlockV3(writer, request)
@@ -1072,10 +1072,10 @@ func TestProduceBlockV3SSZ(t *testing.T) {
ssz, err := bl.BlindedFulu.MarshalSSZ()
require.NoError(t, err)
require.Equal(t, string(ssz), writer.Body.String())
require.Equal(t, "true", writer.Header().Get(api.ExecutionPayloadBlindedHeader))
require.Equal(t, "2000", writer.Header().Get(api.ExecutionPayloadValueHeader))
require.Equal(t, "fulu", writer.Header().Get(api.VersionHeader))
require.Equal(t, "10000000000", writer.Header().Get(api.ConsensusBlockValueHeader))
require.Equal(t, "true", writer.Header().Get(api.EthExecutionPayloadBlindedHeader))
require.Equal(t, "2000", writer.Header().Get(api.EthExecutionPayloadValueHeader))
require.Equal(t, "fulu", writer.Header().Get(api.EthConsensusVersionHeader))
require.Equal(t, "10000000000", writer.Header().Get(api.EthConsensusBlockValueHeader))
})
t.Run("0 block value is returned on error", func(t *testing.T) {
rewardFetcher := &rewardtesting.MockBlockRewardFetcher{Error: &httputil.DefaultJsonError{}}
@@ -1103,7 +1103,7 @@ func TestProduceBlockV3SSZ(t *testing.T) {
BlockRewardFetcher: rewardFetcher,
}
request := httptest.NewRequest(http.MethodGet, fmt.Sprintf("http://foo.example/eth/v3/validator/blocks/1?randao_reveal=%s&graffiti=%s", randao, graffiti), nil)
request.Header.Set("Accept", api.OctetStreamMediaType)
request.Header.Set(api.AcceptHeader, api.OctetStreamMediaType)
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
server.ProduceBlockV3(writer, request)
@@ -1115,9 +1115,9 @@ func TestProduceBlockV3SSZ(t *testing.T) {
ssz, err := bl.Fulu.MarshalSSZ()
require.NoError(t, err)
require.Equal(t, string(ssz), writer.Body.String())
require.Equal(t, "false", writer.Header().Get(api.ExecutionPayloadBlindedHeader))
require.Equal(t, "2000", writer.Header().Get(api.ExecutionPayloadValueHeader))
require.Equal(t, "fulu", writer.Header().Get(api.VersionHeader))
require.Equal(t, "0", writer.Header().Get(api.ConsensusBlockValueHeader))
require.Equal(t, "false", writer.Header().Get(api.EthExecutionPayloadBlindedHeader))
require.Equal(t, "2000", writer.Header().Get(api.EthExecutionPayloadValueHeader))
require.Equal(t, "fulu", writer.Header().Get(api.EthConsensusVersionHeader))
require.Equal(t, "0", writer.Header().Get(api.EthConsensusBlockValueHeader))
})
}

View File

@@ -312,7 +312,7 @@ func TestGetAggregateAttestation(t *testing.T) {
attDataRoot := hexutil.Encode(reqRoot[:])
url := "http://example.com?attestation_data_root=" + attDataRoot + "&slot=2" + "&committee_index=0"
request := httptest.NewRequest(http.MethodGet, url, nil)
request.Header.Add("Accept", "application/octet-stream")
request.Header.Add(api.AcceptHeader, api.OctetStreamMediaType)
writer := httptest.NewRecorder()
s.GetAggregateAttestationV2(writer, request)
@@ -349,7 +349,7 @@ func TestGetAggregateAttestation(t *testing.T) {
attDataRoot := hexutil.Encode(reqRoot[:])
url := "http://example.com?attestation_data_root=" + attDataRoot + "&slot=1" + "&committee_index=0"
request := httptest.NewRequest(http.MethodGet, url, nil)
request.Header.Add("Accept", "application/octet-stream")
request.Header.Add(api.AcceptHeader, api.OctetStreamMediaType)
writer := httptest.NewRecorder()
s.GetAggregateAttestationV2(writer, request)
@@ -460,7 +460,7 @@ func TestGetAggregateAttestation(t *testing.T) {
attDataRoot := hexutil.Encode(reqRoot[:])
url := "http://example.com?attestation_data_root=" + attDataRoot + "&slot=2" + "&committee_index=0"
request := httptest.NewRequest(http.MethodGet, url, nil)
request.Header.Add("Accept", "application/octet-stream")
request.Header.Add(api.AcceptHeader, api.OctetStreamMediaType)
writer := httptest.NewRecorder()
s.GetAggregateAttestationV2(writer, request)
@@ -497,7 +497,7 @@ func TestGetAggregateAttestation(t *testing.T) {
attDataRoot := hexutil.Encode(reqRoot[:])
url := "http://example.com?attestation_data_root=" + attDataRoot + "&slot=1" + "&committee_index=0"
request := httptest.NewRequest(http.MethodGet, url, nil)
request.Header.Add("Accept", "application/octet-stream")
request.Header.Add(api.AcceptHeader, api.OctetStreamMediaType)
writer := httptest.NewRecorder()
s.GetAggregateAttestationV2(writer, request)
@@ -533,7 +533,7 @@ func TestGetAggregateAttestation(t *testing.T) {
attDataRoot := hexutil.Encode(reqRoot[:])
url := "http://example.com?attestation_data_root=" + attDataRoot + "&slot=4" + "&committee_index=0"
request := httptest.NewRequest(http.MethodGet, url, nil)
request.Header.Add("Accept", "application/octet-stream")
request.Header.Add(api.AcceptHeader, api.OctetStreamMediaType)
writer := httptest.NewRecorder()
s.GetAggregateAttestationV2(writer, request)
@@ -574,7 +574,7 @@ func TestGetAggregateAttestation(t *testing.T) {
attDataRoot := hexutil.Encode(reqRoot[:])
url := "http://example.com?attestation_data_root=" + attDataRoot + "&slot=3" + "&committee_index=0"
request := httptest.NewRequest(http.MethodGet, url, nil)
request.Header.Add("Accept", "application/octet-stream")
request.Header.Add(api.AcceptHeader, api.OctetStreamMediaType)
writer := httptest.NewRecorder()
s.GetAggregateAttestationV2(writer, request)
@@ -819,7 +819,7 @@ func TestSubmitAggregateAndProofs(t *testing.T) {
_, err := body.WriteString(singleAggregateElectra)
require.NoError(t, err)
request := httptest.NewRequest(http.MethodPost, "http://example.com", &body)
request.Header.Set(api.VersionHeader, version.String(version.Electra))
request.Header.Set(api.EthConsensusVersionHeader, version.String(version.Electra))
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
@@ -835,7 +835,7 @@ func TestSubmitAggregateAndProofs(t *testing.T) {
_, err := body.WriteString(singleAggregate)
require.NoError(t, err)
request := httptest.NewRequest(http.MethodPost, "http://example.com", &body)
request.Header.Set(api.VersionHeader, version.String(version.Phase0))
request.Header.Set(api.EthConsensusVersionHeader, version.String(version.Phase0))
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
@@ -857,7 +857,7 @@ func TestSubmitAggregateAndProofs(t *testing.T) {
_, err := body.WriteString(multipleAggregatesElectra)
require.NoError(t, err)
request := httptest.NewRequest(http.MethodPost, "http://example.com", &body)
request.Header.Set(api.VersionHeader, version.String(version.Electra))
request.Header.Set(api.EthConsensusVersionHeader, version.String(version.Electra))
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
@@ -874,7 +874,7 @@ func TestSubmitAggregateAndProofs(t *testing.T) {
_, err := body.WriteString(multipleAggregates)
require.NoError(t, err)
request := httptest.NewRequest(http.MethodPost, "http://example.com", &body)
request.Header.Set(api.VersionHeader, version.String(version.Phase0))
request.Header.Set(api.EthConsensusVersionHeader, version.String(version.Phase0))
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
@@ -892,7 +892,7 @@ func TestSubmitAggregateAndProofs(t *testing.T) {
_, err := body.WriteString(singleAggregate)
require.NoError(t, err)
request := httptest.NewRequest(http.MethodPost, "http://example.com", &body)
request.Header.Set(api.VersionHeader, version.String(version.Phase0))
request.Header.Set(api.EthConsensusVersionHeader, version.String(version.Phase0))
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
@@ -907,7 +907,7 @@ func TestSubmitAggregateAndProofs(t *testing.T) {
_, err := body.WriteString(singleAggregateElectra)
require.NoError(t, err)
request := httptest.NewRequest(http.MethodPost, "http://example.com", &body)
request.Header.Set(api.VersionHeader, version.String(version.Electra))
request.Header.Set(api.EthConsensusVersionHeader, version.String(version.Electra))
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
@@ -919,7 +919,7 @@ func TestSubmitAggregateAndProofs(t *testing.T) {
})
t.Run("no body", func(t *testing.T) {
request := httptest.NewRequest(http.MethodPost, "http://example.com", nil)
request.Header.Set(api.VersionHeader, version.String(version.Electra))
request.Header.Set(api.EthConsensusVersionHeader, version.String(version.Electra))
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
@@ -932,7 +932,7 @@ func TestSubmitAggregateAndProofs(t *testing.T) {
})
t.Run("no body-pre-electra", func(t *testing.T) {
request := httptest.NewRequest(http.MethodPost, "http://example.com", nil)
request.Header.Set(api.VersionHeader, version.String(version.Bellatrix))
request.Header.Set(api.EthConsensusVersionHeader, version.String(version.Bellatrix))
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
@@ -948,7 +948,7 @@ func TestSubmitAggregateAndProofs(t *testing.T) {
_, err := body.WriteString("[]")
require.NoError(t, err)
request := httptest.NewRequest(http.MethodPost, "http://example.com", &body)
request.Header.Set(api.VersionHeader, version.String(version.Electra))
request.Header.Set(api.EthConsensusVersionHeader, version.String(version.Electra))
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
@@ -964,7 +964,7 @@ func TestSubmitAggregateAndProofs(t *testing.T) {
_, err := body.WriteString("[]")
require.NoError(t, err)
request := httptest.NewRequest(http.MethodPost, "http://example.com", &body)
request.Header.Set(api.VersionHeader, version.String(version.Altair))
request.Header.Set(api.EthConsensusVersionHeader, version.String(version.Altair))
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
@@ -980,7 +980,7 @@ func TestSubmitAggregateAndProofs(t *testing.T) {
_, err := body.WriteString(invalidAggregateElectra)
require.NoError(t, err)
request := httptest.NewRequest(http.MethodPost, "http://example.com", &body)
request.Header.Set(api.VersionHeader, version.String(version.Electra))
request.Header.Set(api.EthConsensusVersionHeader, version.String(version.Electra))
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
@@ -995,7 +995,7 @@ func TestSubmitAggregateAndProofs(t *testing.T) {
_, err := body.WriteString(invalidAggregate)
require.NoError(t, err)
request := httptest.NewRequest(http.MethodPost, "http://example.com", &body)
request.Header.Set(api.VersionHeader, version.String(version.Deneb))
request.Header.Set(api.EthConsensusVersionHeader, version.String(version.Deneb))
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
@@ -1460,7 +1460,7 @@ func TestGetAttestationData(t *testing.T) {
url := fmt.Sprintf("http://example.com?slot=%d&committee_index=%d", slot, 0)
request := httptest.NewRequest(http.MethodGet, url, nil)
request.Header.Add("Accept", "application/octet-stream")
request.Header.Add(api.AcceptHeader, api.OctetStreamMediaType)
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
@@ -1779,7 +1779,7 @@ func TestGetAttestationData(t *testing.T) {
url := fmt.Sprintf("http://example.com?slot=%d&committee_index=%d", slot, 0)
request := httptest.NewRequest(http.MethodGet, url, nil)
request.Header.Add("Accept", "application/octet-stream")
request.Header.Add(api.AcceptHeader, api.OctetStreamMediaType)
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
@@ -1968,7 +1968,7 @@ func TestGetAttestationData(t *testing.T) {
url := fmt.Sprintf("http://example.com?slot=%d&committee_index=%d", slot, 0)
request := httptest.NewRequest(http.MethodGet, url, nil)
request.Header.Add("Accept", "application/octet-stream")
request.Header.Add(api.AcceptHeader, api.OctetStreamMediaType)
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}

View File

@@ -10,6 +10,7 @@ import (
"net/http/httptest"
"testing"
"github.com/OffchainLabs/prysm/v6/api"
"github.com/OffchainLabs/prysm/v6/api/server/structs"
chainMock "github.com/OffchainLabs/prysm/v6/beacon-chain/blockchain/testing"
"github.com/OffchainLabs/prysm/v6/beacon-chain/core/helpers"
@@ -49,7 +50,7 @@ func individualVotesHelper(t *testing.T, request *structs.GetIndividualVotesRequ
&buf,
)
client := &http.Client{}
rawResp, err := client.Post(srv.URL, "application/json", req.Body)
rawResp, err := client.Post(srv.URL, api.JsonMediaType, req.Body)
require.NoError(t, err)
defer func() {
if err := rawResp.Body.Close(); err != nil {

View File

@@ -312,14 +312,14 @@ func (vs *Server) ProposeBeaconBlock(ctx context.Context, req *ethpb.GenericSign
rob, err := blocks.NewROBlockWithRoot(block, root)
if block.IsBlinded() {
block, blobSidecars, err = vs.handleBlindedBlock(ctx, block)
if errors.Is(err, builderapi.ErrBadGateway) {
log.WithError(err).Info("Optimistically proposed block - builder relay temporarily unavailable, block may arrive over P2P")
return &ethpb.ProposeResponse{BlockRoot: root[:]}, nil
}
} else if block.Version() >= version.Deneb {
blobSidecars, dataColumnSidecars, err = vs.handleUnblindedBlock(rob, req)
}
if err != nil {
if errors.Is(err, builderapi.ErrBadGateway) && block.IsBlinded() {
log.WithError(err).Info("Optimistically proposed block - builder relay temporarily unavailable, block may arrive over P2P")
return &ethpb.ProposeResponse{BlockRoot: root[:]}, nil
}
return nil, status.Errorf(codes.Internal, "%s: %v", "handle block failed", err)
}

View File

@@ -34,6 +34,7 @@ go_test(
],
embed = [":go_default_library"],
deps = [
"//api:go_default_library",
"//api/server/structs:go_default_library",
"//beacon-chain/blockchain/testing:go_default_library",
"//beacon-chain/core/altair:go_default_library",

View File

@@ -9,6 +9,7 @@ import (
"testing"
"time"
"github.com/OffchainLabs/prysm/v6/api"
"github.com/OffchainLabs/prysm/v6/api/server/structs"
mock "github.com/OffchainLabs/prysm/v6/beacon-chain/blockchain/testing"
"github.com/OffchainLabs/prysm/v6/beacon-chain/core/epoch/precompute"
@@ -38,7 +39,7 @@ func TestServer_GetValidatorPerformance(t *testing.T) {
req := httptest.NewRequest("POST", "/foo", nil)
client := &http.Client{}
rawResp, err := client.Post(srv.URL, "application/json", req.Body)
rawResp, err := client.Post(srv.URL, api.JsonMediaType, req.Body)
require.NoError(t, err)
require.Equal(t, http.StatusBadRequest, rawResp.StatusCode)
})
@@ -88,7 +89,7 @@ func TestServer_GetValidatorPerformance(t *testing.T) {
srv := httptest.NewServer(http.HandlerFunc(vs.GetPerformance))
req := httptest.NewRequest("POST", "/foo", &buf)
client := &http.Client{}
rawResp, err := client.Post(srv.URL, "application/json", req.Body)
rawResp, err := client.Post(srv.URL, api.JsonMediaType, req.Body)
require.NoError(t, err)
defer func() {
if err := rawResp.Body.Close(); err != nil {
@@ -153,7 +154,7 @@ func TestServer_GetValidatorPerformance(t *testing.T) {
srv := httptest.NewServer(http.HandlerFunc(vs.GetPerformance))
req := httptest.NewRequest("POST", "/foo", &buf)
client := &http.Client{}
rawResp, err := client.Post(srv.URL, "application/json", req.Body)
rawResp, err := client.Post(srv.URL, api.JsonMediaType, req.Body)
require.NoError(t, err)
defer func() {
if err := rawResp.Body.Close(); err != nil {
@@ -218,7 +219,7 @@ func TestServer_GetValidatorPerformance(t *testing.T) {
srv := httptest.NewServer(http.HandlerFunc(vs.GetPerformance))
req := httptest.NewRequest("POST", "/foo", &buf)
client := &http.Client{}
rawResp, err := client.Post(srv.URL, "application/json", req.Body)
rawResp, err := client.Post(srv.URL, api.JsonMediaType, req.Body)
require.NoError(t, err)
defer func() {
if err := rawResp.Body.Close(); err != nil {
@@ -280,7 +281,7 @@ func TestServer_GetValidatorPerformance(t *testing.T) {
srv := httptest.NewServer(http.HandlerFunc(vs.GetPerformance))
req := httptest.NewRequest("POST", "/foo", &buf)
client := &http.Client{}
rawResp, err := client.Post(srv.URL, "application/json", req.Body)
rawResp, err := client.Post(srv.URL, api.JsonMediaType, req.Body)
require.NoError(t, err)
defer func() {
if err := rawResp.Body.Close(); err != nil {
@@ -342,7 +343,7 @@ func TestServer_GetValidatorPerformance(t *testing.T) {
srv := httptest.NewServer(http.HandlerFunc(vs.GetPerformance))
req := httptest.NewRequest("POST", "/foo", &buf)
client := &http.Client{}
rawResp, err := client.Post(srv.URL, "application/json", req.Body)
rawResp, err := client.Post(srv.URL, api.JsonMediaType, req.Body)
require.NoError(t, err)
defer func() {
if err := rawResp.Body.Close(); err != nil {
@@ -404,7 +405,7 @@ func TestServer_GetValidatorPerformance(t *testing.T) {
srv := httptest.NewServer(http.HandlerFunc(vs.GetPerformance))
req := httptest.NewRequest("POST", "/foo", &buf)
client := &http.Client{}
rawResp, err := client.Post(srv.URL, "application/json", req.Body)
rawResp, err := client.Post(srv.URL, api.JsonMediaType, req.Body)
require.NoError(t, err)
defer func() {
if err := rawResp.Body.Close(); err != nil {

View File

@@ -90,10 +90,10 @@ func (s *Service) updateCustodyInfoIfNeeded() error {
// custodyGroupCount computes the custody group count based on the custody requirement,
// the validators custody requirement, and whether the node is subscribed to all data subnets.
func (s *Service) custodyGroupCount(context.Context) (uint64, error) {
beaconConfig := params.BeaconConfig()
cfg := params.BeaconConfig()
if flags.Get().SubscribeAllDataSubnets {
return beaconConfig.NumberOfCustodyGroups, nil
return cfg.NumberOfCustodyGroups, nil
}
validatorsCustodyRequirement, err := s.validatorsCustodyRequirement()
@@ -101,7 +101,7 @@ func (s *Service) custodyGroupCount(context.Context) (uint64, error) {
return 0, errors.Wrap(err, "validators custody requirement")
}
return max(beaconConfig.CustodyRequirement, validatorsCustodyRequirement), nil
return max(cfg.CustodyRequirement, validatorsCustodyRequirement), nil
}
// validatorsCustodyRequirements computes the custody requirements based on the

View File

@@ -116,11 +116,11 @@ func withSubscribeAllDataSubnets(t *testing.T, fn func()) {
func TestUpdateCustodyInfoIfNeeded(t *testing.T) {
params.SetupTestConfigCleanup(t)
beaconConfig := params.BeaconConfig()
beaconConfig.NumberOfCustodyGroups = 128
beaconConfig.CustodyRequirement = 4
beaconConfig.SamplesPerSlot = 8
params.OverrideBeaconConfig(beaconConfig)
cfg := params.BeaconConfig()
cfg.NumberOfCustodyGroups = 128
cfg.CustodyRequirement = 4
cfg.SamplesPerSlot = 8
params.OverrideBeaconConfig(cfg)
t.Run("Skip update when actual custody count >= target", func(t *testing.T) {
setup := setupCustodyTest(t, false)
@@ -159,7 +159,7 @@ func TestUpdateCustodyInfoIfNeeded(t *testing.T) {
require.NoError(t, err)
const expectedSlot = primitives.Slot(100)
setup.assertCustodyInfo(t, expectedSlot, beaconConfig.NumberOfCustodyGroups)
setup.assertCustodyInfo(t, expectedSlot, cfg.NumberOfCustodyGroups)
})
})
}

View File

@@ -1366,16 +1366,16 @@ func TestFetchSidecars(t *testing.T) {
})
t.Run("Nominal", func(t *testing.T) {
beaconConfig := params.BeaconConfig()
numberOfColumns := beaconConfig.NumberOfColumns
samplesPerSlot := beaconConfig.SamplesPerSlot
cfg := params.BeaconConfig()
numberOfColumns := cfg.NumberOfColumns
samplesPerSlot := cfg.SamplesPerSlot
// Define "now" to be one epoch after genesis time + retention period.
genesisTime := time.Date(2025, time.August, 10, 0, 0, 0, 0, time.UTC)
secondsPerSlot := beaconConfig.SecondsPerSlot
slotsPerEpoch := beaconConfig.SlotsPerEpoch
secondsPerSlot := cfg.SecondsPerSlot
slotsPerEpoch := cfg.SlotsPerEpoch
secondsPerEpoch := uint64(slotsPerEpoch.Mul(secondsPerSlot))
retentionEpochs := beaconConfig.MinEpochsForDataColumnSidecarsRequest
retentionEpochs := cfg.MinEpochsForDataColumnSidecarsRequest
nowWrtGenesisSecs := retentionEpochs.Add(1).Mul(secondsPerEpoch)
now := genesisTime.Add(time.Duration(nowWrtGenesisSecs) * time.Second)

View File

@@ -530,12 +530,12 @@ func TestOriginOutsideRetention(t *testing.T) {
func TestFetchOriginSidecars(t *testing.T) {
ctx := t.Context()
beaconConfig := params.BeaconConfig()
cfg := params.BeaconConfig()
genesisTime := time.Date(2025, time.August, 10, 0, 0, 0, 0, time.UTC)
secondsPerSlot := beaconConfig.SecondsPerSlot
slotsPerEpoch := beaconConfig.SlotsPerEpoch
secondsPerSlot := cfg.SecondsPerSlot
slotsPerEpoch := cfg.SlotsPerEpoch
secondsPerEpoch := uint64(slotsPerEpoch.Mul(secondsPerSlot))
retentionEpochs := beaconConfig.MinEpochsForDataColumnSidecarsRequest
retentionEpochs := cfg.MinEpochsForDataColumnSidecarsRequest
genesisValidatorRoot := [fieldparams.RootLength]byte{}

View File

@@ -192,6 +192,13 @@ var (
},
)
dataColumnsRecoveredFromELTotal = promauto.NewCounter(
prometheus.CounterOpts{
Name: "data_columns_recovered_from_el_total",
Help: "Count the number of times data columns have been recovered from the execution layer.",
},
)
// Data column sidecar validation, beacon metrics specs
dataColumnSidecarVerificationRequestsCounter = promauto.NewCounter(prometheus.CounterOpts{
Name: "beacon_data_column_sidecar_processing_requests_total",
@@ -279,6 +286,7 @@ func (s *Service) updateMetrics() {
topicPeerCount.WithLabelValues(formattedTopic).Set(float64(len(s.cfg.p2p.PubSub().ListPeers(formattedTopic))))
}
subscribedTopicPeerCount.Reset()
for _, topic := range s.cfg.p2p.PubSub().GetTopics() {
subscribedTopicPeerCount.WithLabelValues(topic).Set(float64(len(s.cfg.p2p.PubSub().ListPeers(topic))))
}

View File

@@ -5,6 +5,7 @@ import (
"context"
"encoding/hex"
"fmt"
"slices"
"github.com/OffchainLabs/prysm/v6/beacon-chain/blockchain"
"github.com/OffchainLabs/prysm/v6/beacon-chain/core/blocks"
@@ -382,10 +383,8 @@ func (s *Service) savePending(root [32]byte, pending any, isEqual func(other any
// Skip if the attestation/aggregate from the same validator already exists in
// the pending queue.
for _, a := range s.blkRootToPendingAtts[root] {
if isEqual(a) {
return
}
if slices.ContainsFunc(s.blkRootToPendingAtts[root], isEqual) {
return
}
pendingAttCount.Inc()

View File

@@ -10,6 +10,7 @@ import (
"github.com/OffchainLabs/prysm/v6/beacon-chain/p2p"
"github.com/OffchainLabs/prysm/v6/beacon-chain/p2p/types"
"github.com/OffchainLabs/prysm/v6/cmd/beacon-chain/flags"
fieldparams "github.com/OffchainLabs/prysm/v6/config/fieldparams"
"github.com/OffchainLabs/prysm/v6/config/params"
"github.com/OffchainLabs/prysm/v6/consensus-types/primitives"
"github.com/OffchainLabs/prysm/v6/encoding/bytesutil"
@@ -58,6 +59,17 @@ func (s *Service) blobSidecarByRootRPCHandler(ctx context.Context, msg interface
return errors.Wrapf(err, "unexpected error computing min valid blob request slot, current_slot=%d", cs)
}
// Extract all needed roots.
roots := make([][fieldparams.RootLength]byte, 0, len(blobIdents))
for _, ident := range blobIdents {
root := bytesutil.ToBytes32(ident.BlockRoot)
roots = append(roots, root)
}
// Filter all available roots in block storage.
availableRoots := s.cfg.beaconDB.AvailableBlocks(ctx, roots)
// Serve each requested blob sidecar.
for i := range blobIdents {
if err := ctx.Err(); err != nil {
closeStream(stream, log)
@@ -69,7 +81,15 @@ func (s *Service) blobSidecarByRootRPCHandler(ctx context.Context, msg interface
<-ticker.C
}
s.rateLimiter.add(stream, 1)
root, idx := bytesutil.ToBytes32(blobIdents[i].BlockRoot), blobIdents[i].Index
// Do not serve a blob sidecar if the corresponding block is not available.
if !availableRoots[root] {
log.Trace("Peer requested blob sidecar by root but corresponding block not found in db")
continue
}
sc, err := s.cfg.blobStorage.Get(root, idx)
if err != nil {
log := log.WithFields(logrus.Fields{
@@ -113,19 +133,19 @@ func (s *Service) blobSidecarByRootRPCHandler(ctx context.Context, msg interface
}
func validateBlobByRootRequest(blobIdents types.BlobSidecarsByRootReq, slot primitives.Slot) error {
beaconConfig := params.BeaconConfig()
cfg := params.BeaconConfig()
epoch := slots.ToEpoch(slot)
blobIdentCount := uint64(len(blobIdents))
if epoch >= beaconConfig.ElectraForkEpoch {
if blobIdentCount > beaconConfig.MaxRequestBlobSidecarsElectra {
if epoch >= cfg.ElectraForkEpoch {
if blobIdentCount > cfg.MaxRequestBlobSidecarsElectra {
return types.ErrMaxBlobReqExceeded
}
return nil
}
if blobIdentCount > beaconConfig.MaxRequestBlobSidecars {
if blobIdentCount > cfg.MaxRequestBlobSidecars {
return types.ErrMaxBlobReqExceeded
}

View File

@@ -38,8 +38,8 @@ func (s *Service) dataColumnSidecarsByRangeRPCHandler(ctx context.Context, msg i
defer cancel()
SetRPCStreamDeadlines(stream)
beaconConfig := params.BeaconConfig()
maxRequestDataColumnSidecars := beaconConfig.MaxRequestDataColumnSidecars
cfg := params.BeaconConfig()
maxRequestDataColumnSidecars := cfg.MaxRequestDataColumnSidecars
remotePeer := stream.Conn().RemotePeer()
log := log.WithFields(logrus.Fields{
@@ -102,7 +102,7 @@ func (s *Service) dataColumnSidecarsByRangeRPCHandler(ctx context.Context, msg i
// Once the quota is reached, we're done serving the request.
if maxRequestDataColumnSidecars == 0 {
log.WithField("initialQuota", beaconConfig.MaxRequestDataColumnSidecars).Trace("Reached quota for data column sidecars by range request")
log.WithField("initialQuota", cfg.MaxRequestDataColumnSidecars).Trace("Reached quota for data column sidecars by range request")
break
}
}

View File

@@ -31,9 +31,9 @@ import (
func TestDataColumnSidecarsByRangeRPCHandler(t *testing.T) {
params.SetupTestConfigCleanup(t)
beaconConfig := params.BeaconConfig()
beaconConfig.FuluForkEpoch = 0
params.OverrideBeaconConfig(beaconConfig)
cfg := params.BeaconConfig()
cfg.FuluForkEpoch = 0
params.OverrideBeaconConfig(cfg)
params.BeaconConfig().InitializeForkSchedule()
ctx := context.Background()
t.Run("wrong message type", func(t *testing.T) {

View File

@@ -56,18 +56,6 @@ func (s *Service) dataColumnSidecarByRootRPCHandler(ctx context.Context, msg int
return errors.Wrap(err, "validate data columns by root request")
}
requestedColumnsByRoot := make(map[[fieldparams.RootLength]byte][]uint64)
for _, columnIdent := range requestedColumnIdents {
var root [fieldparams.RootLength]byte
copy(root[:], columnIdent.BlockRoot)
requestedColumnsByRoot[root] = append(requestedColumnsByRoot[root], columnIdent.Columns...)
}
// Sort by column index for each root.
for _, columns := range requestedColumnsByRoot {
slices.Sort(columns)
}
// Compute the oldest slot we'll allow a peer to request, based on the current slot.
minReqSlot, err := dataColumnsRPCMinValidSlot(s.cfg.clock.CurrentSlot())
if err != nil {
@@ -84,6 +72,12 @@ func (s *Service) dataColumnSidecarByRootRPCHandler(ctx context.Context, msg int
}
if log.Logger.Level >= logrus.TraceLevel {
requestedColumnsByRoot := make(map[[fieldparams.RootLength]byte][]uint64)
for _, ident := range requestedColumnIdents {
root := bytesutil.ToBytes32(ident.BlockRoot)
requestedColumnsByRoot[root] = append(requestedColumnsByRoot[root], ident.Columns...)
}
// We optimistially assume the peer requests the same set of columns for all roots,
// pre-sizing the map accordingly.
requestedRootsByColumnSet := make(map[string][]string, 1)
@@ -96,6 +90,17 @@ func (s *Service) dataColumnSidecarByRootRPCHandler(ctx context.Context, msg int
log.WithField("requested", requestedRootsByColumnSet).Trace("Serving data column sidecars by root")
}
// Extract all requested roots.
roots := make([][fieldparams.RootLength]byte, 0, len(requestedColumnIdents))
for _, ident := range requestedColumnIdents {
root := bytesutil.ToBytes32(ident.BlockRoot)
roots = append(roots, root)
}
// Filter all available roots in block storage.
availableRoots := s.cfg.beaconDB.AvailableBlocks(ctx, roots)
// Serve each requested data column sidecar.
count := 0
for _, ident := range requestedColumnIdents {
if err := ctx.Err(); err != nil {
@@ -117,6 +122,12 @@ func (s *Service) dataColumnSidecarByRootRPCHandler(ctx context.Context, msg int
s.rateLimiter.add(stream, int64(len(columns)))
// Do not serve a blob sidecar if the corresponding block is not available.
if !availableRoots[root] {
log.Trace("Peer requested blob sidecar by root but corresponding block not found in db")
continue
}
// Retrieve the requested sidecars from the store.
verifiedRODataColumns, err := s.cfg.dataColumnStorage.Get(root, columns)
if err != nil {
@@ -163,9 +174,9 @@ func dataColumnsRPCMinValidSlot(currentSlot primitives.Slot) (primitives.Slot, e
return primitives.Slot(math.MaxUint64), nil
}
beaconConfig := params.BeaconConfig()
minReqEpochs := beaconConfig.MinEpochsForDataColumnSidecarsRequest
minStartEpoch := beaconConfig.FuluForkEpoch
cfg := params.BeaconConfig()
minReqEpochs := cfg.MinEpochsForDataColumnSidecarsRequest
minStartEpoch := cfg.FuluForkEpoch
currEpoch := slots.ToEpoch(currentSlot)
if currEpoch > minReqEpochs && currEpoch-minReqEpochs > minStartEpoch {

View File

@@ -10,6 +10,7 @@ import (
chainMock "github.com/OffchainLabs/prysm/v6/beacon-chain/blockchain/testing"
"github.com/OffchainLabs/prysm/v6/beacon-chain/db/filesystem"
testDB "github.com/OffchainLabs/prysm/v6/beacon-chain/db/testing"
"github.com/OffchainLabs/prysm/v6/beacon-chain/p2p"
p2ptest "github.com/OffchainLabs/prysm/v6/beacon-chain/p2p/testing"
"github.com/OffchainLabs/prysm/v6/beacon-chain/p2p/types"
@@ -19,6 +20,7 @@ import (
"github.com/OffchainLabs/prysm/v6/config/params"
"github.com/OffchainLabs/prysm/v6/consensus-types/blocks"
"github.com/OffchainLabs/prysm/v6/consensus-types/primitives"
"github.com/OffchainLabs/prysm/v6/testing/assert"
"github.com/OffchainLabs/prysm/v6/testing/require"
"github.com/OffchainLabs/prysm/v6/testing/util"
"github.com/libp2p/go-libp2p/core/network"
@@ -28,9 +30,9 @@ import (
func TestDataColumnSidecarsByRootRPCHandler(t *testing.T) {
params.SetupTestConfigCleanup(t)
beaconConfig := params.BeaconConfig()
beaconConfig.FuluForkEpoch = 0
params.OverrideBeaconConfig(beaconConfig)
cfg := params.BeaconConfig()
cfg.FuluForkEpoch = 0
params.OverrideBeaconConfig(cfg)
params.BeaconConfig().InitializeForkSchedule()
ctxMap, err := ContextByteVersionsForValRoot(params.BeaconConfig().GenesisValidatorsRoot)
require.NoError(t, err)
@@ -43,9 +45,9 @@ func TestDataColumnSidecarsByRootRPCHandler(t *testing.T) {
t.Run("invalid request", func(t *testing.T) {
params.SetupTestConfigCleanup(t)
beaconConfig := params.BeaconConfig()
beaconConfig.MaxRequestDataColumnSidecars = 1
params.OverrideBeaconConfig(beaconConfig)
cfg := params.BeaconConfig()
cfg.MaxRequestDataColumnSidecars = 1
params.OverrideBeaconConfig(cfg)
localP2P := p2ptest.NewTestP2P(t)
service := &Service{cfg: &config{p2p: localP2P}}
@@ -96,30 +98,54 @@ func TestDataColumnSidecarsByRootRPCHandler(t *testing.T) {
}()
params.SetupTestConfigCleanup(t)
beaconConfig := params.BeaconConfig()
beaconConfig.FuluForkEpoch = 1
params.OverrideBeaconConfig(beaconConfig)
cfg := params.BeaconConfig()
cfg.FuluForkEpoch = 1
params.OverrideBeaconConfig(cfg)
localP2P := p2ptest.NewTestP2P(t)
clock := startup.NewClock(time.Now(), [fieldparams.RootLength]byte{})
params := []util.DataColumnParam{
{Slot: 10, Index: 1}, {Slot: 10, Index: 2}, {Slot: 10, Index: 3},
{Slot: 40, Index: 4}, {Slot: 40, Index: 6},
{Slot: 45, Index: 7}, {Slot: 45, Index: 8}, {Slot: 45, Index: 9},
_, verifiedRODataColumns := util.CreateTestVerifiedRoDataColumnSidecars(
t,
[]util.DataColumnParam{
{Slot: 10, Index: 1}, {Slot: 10, Index: 2}, {Slot: 10, Index: 3},
{Slot: 40, Index: 4}, {Slot: 40, Index: 6},
{Slot: 45, Index: 7}, {Slot: 45, Index: 8}, {Slot: 45, Index: 9},
{Slot: 46, Index: 10}, // Corresponding block won't be saved in DB
},
)
dataColumnStorage := filesystem.NewEphemeralDataColumnStorage(t)
err := dataColumnStorage.Save(verifiedRODataColumns)
require.NoError(t, err)
beaconDB := testDB.SetupDB(t)
indices := [...]int{0, 3, 5}
roBlocks := make([]blocks.ROBlock, 0, len(indices))
for _, i := range indices {
blockPb := util.NewBeaconBlock()
signedBeaconBlock, err := blocks.NewSignedBeaconBlock(blockPb)
require.NoError(t, err)
// Here the block root has to match the sidecar's block root.
// (However, the block root does not match the actual root of the block, but we don't care for this test.)
roBlock, err := blocks.NewROBlockWithRoot(signedBeaconBlock, verifiedRODataColumns[i].BlockRoot())
require.NoError(t, err)
roBlocks = append(roBlocks, roBlock)
}
_, verifiedRODataColumns := util.CreateTestVerifiedRoDataColumnSidecars(t, params)
storage := filesystem.NewEphemeralDataColumnStorage(t)
err := storage.Save(verifiedRODataColumns)
err = beaconDB.SaveROBlocks(ctx, roBlocks, false /*cache*/)
require.NoError(t, err)
service := &Service{
cfg: &config{
p2p: localP2P,
beaconDB: beaconDB,
clock: clock,
dataColumnStorage: storage,
dataColumnStorage: dataColumnStorage,
chain: &chainMock.ChainService{},
},
rateLimiter: newRateLimiter(localP2P),
@@ -134,6 +160,7 @@ func TestDataColumnSidecarsByRootRPCHandler(t *testing.T) {
root0 := verifiedRODataColumns[0].BlockRoot()
root3 := verifiedRODataColumns[3].BlockRoot()
root5 := verifiedRODataColumns[5].BlockRoot()
root8 := verifiedRODataColumns[8].BlockRoot()
remoteP2P.BHost.SetStreamHandler(protocolID, func(stream network.Stream) {
defer wg.Done()
@@ -147,22 +174,22 @@ func TestDataColumnSidecarsByRootRPCHandler(t *testing.T) {
break
}
require.NoError(t, err)
assert.NoError(t, err)
sidecars = append(sidecars, sidecar)
}
require.Equal(t, 5, len(sidecars))
require.Equal(t, root3, sidecars[0].BlockRoot())
require.Equal(t, root3, sidecars[1].BlockRoot())
require.Equal(t, root5, sidecars[2].BlockRoot())
require.Equal(t, root5, sidecars[3].BlockRoot())
require.Equal(t, root5, sidecars[4].BlockRoot())
assert.Equal(t, 5, len(sidecars))
assert.Equal(t, root3, sidecars[0].BlockRoot())
assert.Equal(t, root3, sidecars[1].BlockRoot())
assert.Equal(t, root5, sidecars[2].BlockRoot())
assert.Equal(t, root5, sidecars[3].BlockRoot())
assert.Equal(t, root5, sidecars[4].BlockRoot())
require.Equal(t, uint64(4), sidecars[0].Index)
require.Equal(t, uint64(6), sidecars[1].Index)
require.Equal(t, uint64(7), sidecars[2].Index)
require.Equal(t, uint64(8), sidecars[3].Index)
require.Equal(t, uint64(9), sidecars[4].Index)
assert.Equal(t, uint64(4), sidecars[0].Index)
assert.Equal(t, uint64(6), sidecars[1].Index)
assert.Equal(t, uint64(7), sidecars[2].Index)
assert.Equal(t, uint64(8), sidecars[3].Index)
assert.Equal(t, uint64(9), sidecars[4].Index)
})
localP2P.Connect(remoteP2P)
@@ -182,6 +209,10 @@ func TestDataColumnSidecarsByRootRPCHandler(t *testing.T) {
BlockRoot: root5[:],
Columns: []uint64{7, 8, 9},
},
{
BlockRoot: root8[:],
Columns: []uint64{10},
},
}
err = service.dataColumnSidecarByRootRPCHandler(ctx, msg, stream)

View File

@@ -465,8 +465,8 @@ func SendDataColumnSidecarsByRangeRequest(
return nil, nil
}
beaconConfig := params.BeaconConfig()
numberOfColumns := beaconConfig.NumberOfColumns
cfg := params.BeaconConfig()
numberOfColumns := cfg.NumberOfColumns
maxRequestDataColumnSidecars := params.BeaconConfig().MaxRequestDataColumnSidecars
// Check if we do not request too many sidecars.

View File

@@ -889,9 +889,9 @@ func TestErrInvalidFetchedDataDistinction(t *testing.T) {
func TestSendDataColumnSidecarsByRangeRequest(t *testing.T) {
params.SetupTestConfigCleanup(t)
beaconConfig := params.BeaconConfig()
beaconConfig.FuluForkEpoch = 0
params.OverrideBeaconConfig(beaconConfig)
cfg := params.BeaconConfig()
cfg.FuluForkEpoch = 0
params.OverrideBeaconConfig(cfg)
params.BeaconConfig().InitializeForkSchedule()
ctxMap, err := ContextByteVersionsForValRoot(params.BeaconConfig().GenesisValidatorsRoot)
require.NoError(t, err)
@@ -923,9 +923,9 @@ func TestSendDataColumnSidecarsByRangeRequest(t *testing.T) {
t.Run("too many columns in request", func(t *testing.T) {
params.SetupTestConfigCleanup(t)
beaconConfig := params.BeaconConfig()
beaconConfig.MaxRequestDataColumnSidecars = 0
params.OverrideBeaconConfig(beaconConfig)
cfg := params.BeaconConfig()
cfg.MaxRequestDataColumnSidecars = 0
params.OverrideBeaconConfig(cfg)
request := &ethpb.DataColumnSidecarsByRangeRequest{Count: 1, Columns: []uint64{1, 2, 3}}
_, err := SendDataColumnSidecarsByRangeRequest(DataColumnSidecarsParams{Ctx: t.Context()}, "", request)
@@ -1193,9 +1193,9 @@ func TestIsSidecarIndexRequested(t *testing.T) {
func TestSendDataColumnSidecarsByRootRequest(t *testing.T) {
params.SetupTestConfigCleanup(t)
beaconConfig := params.BeaconConfig()
beaconConfig.FuluForkEpoch = 0
params.OverrideBeaconConfig(beaconConfig)
cfg := params.BeaconConfig()
cfg.FuluForkEpoch = 0
params.OverrideBeaconConfig(cfg)
params.BeaconConfig().InitializeForkSchedule()
ctxMap, err := ContextByteVersionsForValRoot(params.BeaconConfig().GenesisValidatorsRoot)
require.NoError(t, err)
@@ -1223,9 +1223,9 @@ func TestSendDataColumnSidecarsByRootRequest(t *testing.T) {
t.Run("too many columns in request", func(t *testing.T) {
params.SetupTestConfigCleanup(t)
beaconConfig := params.BeaconConfig()
beaconConfig.MaxRequestDataColumnSidecars = 4
params.OverrideBeaconConfig(beaconConfig)
cfg := params.BeaconConfig()
cfg.MaxRequestDataColumnSidecars = 4
params.OverrideBeaconConfig(cfg)
request := p2ptypes.DataColumnsByRootIdentifiers{
{Columns: []uint64{1, 2, 3}},

View File

@@ -445,7 +445,7 @@ func TestStatusRPCRequest_RequestSent(t *testing.T) {
custodyGroupCount = uint64(4)
)
beaconConfig := params.BeaconConfig()
cfg := params.BeaconConfig()
ctx := t.Context()
testCases := []struct {
@@ -456,7 +456,7 @@ func TestStatusRPCRequest_RequestSent(t *testing.T) {
}{
{
name: "before fulu",
fuluForkEpoch: beaconConfig.FarFutureEpoch,
fuluForkEpoch: cfg.FarFutureEpoch,
topic: "/eth2/beacon_chain/req/status/1/ssz_snappy",
streamHandler: func(service *Service, stream network.Stream, genesisState beaconState.BeaconState, beaconRoot, headRoot, finalizedRoot []byte) {
out := &ethpb.Status{}

View File

@@ -695,10 +695,10 @@ func (s *Service) dataColumnSubnetIndices(primitives.Slot) map[uint64]bool {
// the validators custody requirement, and whether the node is subscribed to all data subnets.
// https://github.com/ethereum/consensus-specs/blob/master/specs/fulu/das-core.md#custody-sampling
func (s *Service) samplingSize() (uint64, error) {
beaconConfig := params.BeaconConfig()
cfg := params.BeaconConfig()
if flags.Get().SubscribeAllDataSubnets {
return beaconConfig.DataColumnSidecarSubnetCount, nil
return cfg.DataColumnSidecarSubnetCount, nil
}
// Compute the validators custody requirement.
@@ -712,7 +712,7 @@ func (s *Service) samplingSize() (uint64, error) {
return 0, errors.Wrap(err, "custody group count")
}
return max(beaconConfig.SamplesPerSlot, validatorsCustodyRequirement, custodyGroupCount), nil
return max(cfg.SamplesPerSlot, validatorsCustodyRequirement, custodyGroupCount), nil
}
func (s *Service) persistentAndAggregatorSubnetIndices(currentSlot primitives.Slot) map[uint64]bool {

View File

@@ -224,6 +224,8 @@ func (s *Service) processDataColumnSidecarsFromExecution(ctx context.Context, so
}
if len(unseenIndices) > 0 {
dataColumnsRecoveredFromELTotal.Inc()
log.WithFields(logrus.Fields{
"root": fmt.Sprintf("%#x", source.Root()),
"slot": source.Slot(),

View File

@@ -3,6 +3,7 @@ package sync
import (
"context"
"fmt"
"slices"
"github.com/OffchainLabs/prysm/v6/beacon-chain/blockchain"
"github.com/OffchainLabs/prysm/v6/beacon-chain/core/blocks"
@@ -290,11 +291,8 @@ func (s *Service) validateIndexInCommittee(ctx context.Context, a ethpb.Att, val
}
var withinCommittee bool
for _, i := range committee {
if validatorIndex == i {
withinCommittee = true
break
}
if slices.Contains(committee, validatorIndex) {
withinCommittee = true
}
if !withinCommittee {
return pubsub.ValidationReject, fmt.Errorf("validator index %d is not within the committee: %v",

View File

@@ -5,6 +5,7 @@ import (
"encoding/binary"
"fmt"
"reflect"
"slices"
"strings"
"github.com/OffchainLabs/prysm/v6/beacon-chain/blockchain"
@@ -336,13 +337,7 @@ func validateAttestingIndex(
// _[REJECT]_ The attester is a member of the committee -- i.e.
// `attestation.attester_index in get_beacon_committee(state, attestation.data.slot, index)`.
inCommittee := false
for _, ix := range committee {
if attestingIndex == ix {
inCommittee = true
break
}
}
inCommittee := slices.Contains(committee, attestingIndex)
if !inCommittee {
return pubsub.ValidationReject, errors.New("attester is not a member of the committee")
}

View File

@@ -1,3 +0,0 @@
### Fixed
- Fix recoverStateSummary to persist state summaries in stateSummaryBucket instead of stateBucket (#15896).

View File

@@ -0,0 +1,3 @@
### Ignored
- Add log prefix to the light-client package.

View File

@@ -0,0 +1,3 @@
### Added
- Added GeneralizedIndicesFromPath function to calculate the GIs for a given sszInfo object and a PathElement

View File

@@ -0,0 +1,3 @@
### Removed
- log mentioning removed flag `--show-deposit-data`

View File

@@ -1,3 +0,0 @@
### Ignored
- Changelog entries for v6.1.3 through v6.1.2

View File

@@ -0,0 +1,3 @@
### Ignored
- Changelog entries for v6.1.4 through v6.1.3

View File

@@ -1,2 +0,0 @@
### Fixed
- Delete the genesis state file when --clear-db / --force-clear-db is specified.

View File

@@ -0,0 +1,2 @@
### Changed
- Use the `by-epoch' blob storage layout by default and log a warning to users who continue to use the flat layout, encouraging them to switch.

View File

@@ -1,2 +0,0 @@
### Fixed
- Correctly advertise (in ENR and beacon API) attestation subnets when using `--subscribe-all-subnets`.

View File

@@ -0,0 +1,3 @@
### Fixed
- `blobSidecarByRootRPCHandler`: Do not serve a sidecar if the corresponding block is not available.
- `dataColumnSidecarByRootRPCHandler`: Do not serve a sidecar if the corresponding block is not available.

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