Compare commits

...

21 Commits

Author SHA1 Message Date
terence tsao
ab41335404 Capture time when >50% of beacon attestation arrive 2024-06-04 20:00:58 -07:00
kasey
ea2624b5ab always close cache warm chan to prevent blocking (#14080)
* always close cache warm chan to prevent blocking

* test that waitForCache does not block

* combine defers to reduce cognitive overhead

* lint

---------

Co-authored-by: Kasey Kirkham <kasey@users.noreply.github.com>
2024-06-04 22:08:06 +00:00
james-prysm
1b40f941cf middleware for content type and accept headers (#14075)
* middleware for content type

* adding accept middleware too and tests

* Update beacon-chain/rpc/endpoints.go

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

* Update beacon-chain/rpc/endpoints.go

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

* Update beacon-chain/rpc/endpoints.go

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

* Update beacon-chain/rpc/endpoints.go

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

* including radek's review

---------

Co-authored-by: Radosław Kapka <rkapka@wp.pl>
2024-06-04 20:38:21 +00:00
terence
57830435d7 Process epoch error to use correct state version (#14069)
* Process epoch error to use correct state version

* Fix return instead
2024-06-03 19:54:28 +00:00
Nishant Das
44d850de51 Change It To Debug (#14072) 2024-06-03 10:50:00 +00:00
Radosław Kapka
b08e691127 Organize validator flags (#14028)
* Organize validator flags

* whitespace

* fix comment in test

* remove unneeded flags
2024-05-31 18:36:18 +00:00
Radosław Kapka
968e82b02d EIP-7549 gRPC (part 1) (#14055)
* interfaces move

* build fix

* remove annoying warning

* more build fixes

* review

* core code

* tests part 1

* tests part 2

* TranslateParticipation doesn't need Electra

* remove unused function

* pending atts don't need Electra

* tests part 3

* build fixes

* review

* EIP-7549 gRPC part 1
2024-05-31 17:24:06 +00:00
james-prysm
de04ce8329 EIP-7002:Execution layer triggerable withdrawals (#14031)
* wip fixing 7002 branch

* fixing tests and functions

* fixing linting

* temp fix for transition

* adding unit tests for method

* fixing linting

* partial review from terence

* Update withdrawals.go

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

* Update withdrawals.go

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

* Update withdrawals.go

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

* Update beacon-chain/core/electra/withdrawals.go

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

* addressing feedback

---------

Co-authored-by: Sammy Rosso <15244892+saolyn@users.noreply.github.com>
Co-authored-by: Radosław Kapka <rkapka@wp.pl>
2024-05-31 16:55:49 +00:00
terence
5efecff631 Fix mockgen sh (#14068)
* Fix mockgen sh

* Radek's suggestion

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

* Generate prysm chain client

---------

Co-authored-by: Radosław Kapka <rkapka@wp.pl>
2024-05-31 16:24:17 +00:00
Radosław Kapka
3ab759e163 One more validator client cleanup (#14048)
* interface names

* interface method names

* inspection

* regenerate pb and mock

* Revert beacon node changes

* build fix

* review

* more functions

* combine parameters
2024-05-31 15:53:58 +00:00
james-prysm
836d369c6c api fix for panic on unsynced unfound block (#14063)
* api fix for panic

* adding test

* fixing how we handle the error
2024-05-31 14:46:38 +00:00
Nishant Das
568273453b Update Libp2p Dependencies (#14060)
* Update to v0.35.0 and v0.11.0

* Update Protobuf

* Update bazel deps
2024-05-30 08:56:55 +00:00
Nishant Das
7a4ecb6060 Restrict Dials From Discovery (#14052)
* Fix Excessive Subnet Dials

* Handle backoff in Iterator

* Slow Down Lookups

* Add Flag To Configure Dials

* Preston's Review

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

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

* Reduce polling period

* Manu's Review

---------

Co-authored-by: Preston Van Loon <pvanloon@offchainlabs.com>
2024-05-30 06:57:26 +00:00
terence
82f0ea5b11 Fix dependent root retrival for first epoch (#14059) 2024-05-30 04:15:00 +00:00
Sammy Rosso
6fddd13cb2 Multiple BN HTTP resolver (#13433)
* http resolver

* Redo

* Revert "Redo"

This reverts commit 5437c44ac2.

* Revert "http resolver"

This reverts commit 206207b530.

* Add host change to ValidatorClient + Validator

* Update mockgen

* Tidy

* Add mock validator

* Update gomock

* Gaz

* Solve interface issues

* Fix host

* Fix test

* Add tests

* Add endpoint change log

* Fix log

* Gen mock

* Fix test

* Fix deepsource

* Lint + deepsource

* Move to healthCheckRoutine

* Fix build errors

* Switch host to string

* Forgot a couple

* Radek' review

* Add PushProposerSettings to goroutine

* Radek' review

* James' review + test fix

* Radek' suggestion

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

* Check if new node is healthy

* Fix linter errors

* Add host switch logic to ChangeHost

* Lint + comment

* Fix messy merge

* rename ChangeHost to SetHost

* improve log

* remove log

* switch one node

* rename param

---------

Co-authored-by: Radosław Kapka <rkapka@wp.pl>
Co-authored-by: rkapka <radoslaw.kapka@gmail.com>
2024-05-29 01:43:06 +00:00
terence
43c7659d18 Fix dependent root retrival genesis case (#14053)
* Fix dependent root retrival genesis case

* Remove print
2024-05-28 16:50:41 +00:00
Radosław Kapka
2d15e53dab Eip 7549 core (#14037)
* interfaces move

* build fix

* remove annoying warning

* more build fixes

* review

* core code

* tests part 1

* tests part 2

* TranslateParticipation doesn't need Electra

* remove unused function

* pending atts don't need Electra

* tests part 3

* build fixes

* review

* remove newline

* review

* fix test
2024-05-28 13:56:36 +00:00
Radosław Kapka
2f2152e039 Only log error when aggregator check fails (#14046)
* Only log error when aggregator check fails

* review
2024-05-27 18:05:46 +00:00
Preston Van Loon
2542189efc eip-7251: process_effective_balance_updates (#14003)
* eip-7251: process_effective_balance_updates

Spectests for process_effective_balance_updates

process_effective_balance_updates unit tests

* PR feedback from the amazing @rkapka

---------

Co-authored-by: james-prysm <90280386+james-prysm@users.noreply.github.com>
2024-05-25 00:12:38 +00:00
terence
8e6d39a44b Support electra blob type for by range request (#14047)
Co-authored-by: james-prysm <90280386+james-prysm@users.noreply.github.com>
2024-05-24 18:56:40 +00:00
terence
c35889d4c6 Fix CommitteeAssignments to not return every validator (#14039)
* Rewrite CommitteeAssignments to not return every validator

* Potuz's feedback
2024-05-24 16:56:42 +00:00
230 changed files with 7269 additions and 3395 deletions

View File

@@ -14,7 +14,7 @@ go_library(
"//validator:__subpackages__",
],
deps = [
"//api/server:go_default_library",
"//api/server/middleware:go_default_library",
"//runtime:go_default_library",
"@com_github_gorilla_mux//:go_default_library",
"@com_github_grpc_ecosystem_grpc_gateway_v2//runtime:go_default_library",

View File

@@ -11,7 +11,7 @@ import (
"github.com/gorilla/mux"
gwruntime "github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/v5/api/server"
"github.com/prysmaticlabs/prysm/v5/api/server/middleware"
"github.com/prysmaticlabs/prysm/v5/runtime"
"google.golang.org/grpc"
"google.golang.org/grpc/connectivity"
@@ -104,7 +104,7 @@ func (g *Gateway) Start() {
}
}
corsMux := server.CorsHandler(g.cfg.allowedOrigins).Middleware(g.cfg.router)
corsMux := middleware.CorsHandler(g.cfg.allowedOrigins).Middleware(g.cfg.router)
if g.cfg.muxHandler != nil {
g.cfg.router.PathPrefix("/").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {

View File

@@ -2,29 +2,14 @@ load("@prysm//tools/go:def.bzl", "go_library", "go_test")
go_library(
name = "go_default_library",
srcs = [
"error.go",
"middleware.go",
"util.go",
],
srcs = ["error.go"],
importpath = "github.com/prysmaticlabs/prysm/v5/api/server",
visibility = ["//visibility:public"],
deps = [
"@com_github_gorilla_mux//:go_default_library",
"@com_github_rs_cors//:go_default_library",
],
)
go_test(
name = "go_default_test",
srcs = [
"error_test.go",
"middleware_test.go",
"util_test.go",
],
srcs = ["error_test.go"],
embed = [":go_default_library"],
deps = [
"//testing/assert:go_default_library",
"//testing/require:go_default_library",
],
deps = ["//testing/assert:go_default_library"],
)

View File

@@ -1,32 +0,0 @@
package server
import (
"net/http"
"github.com/gorilla/mux"
"github.com/rs/cors"
)
// NormalizeQueryValuesHandler normalizes an input query of "key=value1,value2,value3" to "key=value1&key=value2&key=value3"
func NormalizeQueryValuesHandler(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
query := r.URL.Query()
NormalizeQueryValues(query)
r.URL.RawQuery = query.Encode()
next.ServeHTTP(w, r)
})
}
// CorsHandler sets the cors settings on api endpoints
func CorsHandler(allowOrigins []string) mux.MiddlewareFunc {
c := cors.New(cors.Options{
AllowedOrigins: allowOrigins,
AllowedMethods: []string{http.MethodPost, http.MethodGet, http.MethodDelete, http.MethodOptions},
AllowCredentials: true,
MaxAge: 600,
AllowedHeaders: []string{"*"},
})
return c.Handler
}

View File

@@ -0,0 +1,29 @@
load("@prysm//tools/go:def.bzl", "go_library", "go_test")
go_library(
name = "go_default_library",
srcs = [
"middleware.go",
"util.go",
],
importpath = "github.com/prysmaticlabs/prysm/v5/api/server/middleware",
visibility = ["//visibility:public"],
deps = [
"@com_github_gorilla_mux//:go_default_library",
"@com_github_rs_cors//:go_default_library",
],
)
go_test(
name = "go_default_test",
srcs = [
"middleware_test.go",
"util_test.go",
],
embed = [":go_default_library"],
deps = [
"//api:go_default_library",
"//testing/assert:go_default_library",
"//testing/require:go_default_library",
],
)

View File

@@ -0,0 +1,112 @@
package middleware
import (
"fmt"
"net/http"
"strings"
"github.com/gorilla/mux"
"github.com/rs/cors"
)
// NormalizeQueryValuesHandler normalizes an input query of "key=value1,value2,value3" to "key=value1&key=value2&key=value3"
func NormalizeQueryValuesHandler(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
query := r.URL.Query()
NormalizeQueryValues(query)
r.URL.RawQuery = query.Encode()
next.ServeHTTP(w, r)
})
}
// CorsHandler sets the cors settings on api endpoints
func CorsHandler(allowOrigins []string) mux.MiddlewareFunc {
c := cors.New(cors.Options{
AllowedOrigins: allowOrigins,
AllowedMethods: []string{http.MethodPost, http.MethodGet, http.MethodDelete, http.MethodOptions},
AllowCredentials: true,
MaxAge: 600,
AllowedHeaders: []string{"*"},
})
return c.Handler
}
// ContentTypeHandler checks request for the appropriate media types otherwise returning a http.StatusUnsupportedMediaType error
func ContentTypeHandler(acceptedMediaTypes []string) mux.MiddlewareFunc {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// skip the GET request
if r.Method == http.MethodGet {
next.ServeHTTP(w, r)
return
}
contentType := r.Header.Get("Content-Type")
if contentType == "" {
http.Error(w, "Content-Type header is missing", http.StatusUnsupportedMediaType)
return
}
accepted := false
for _, acceptedType := range acceptedMediaTypes {
if strings.TrimSpace(contentType) == strings.TrimSpace(acceptedType) {
accepted = true
break
}
}
if !accepted {
http.Error(w, fmt.Sprintf("Unsupported media type: %s", contentType), http.StatusUnsupportedMediaType)
return
}
next.ServeHTTP(w, r)
})
}
}
// AcceptHeaderHandler checks if the client's response preference is handled
func AcceptHeaderHandler(serverAcceptedTypes []string) mux.MiddlewareFunc {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
acceptHeader := r.Header.Get("Accept")
// header is optional and should skip if not provided
if acceptHeader == "" {
next.ServeHTTP(w, r)
return
}
accepted := false
acceptTypes := strings.Split(acceptHeader, ",")
// follows rules defined in https://datatracker.ietf.org/doc/html/rfc2616#section-14.1
for _, acceptType := range acceptTypes {
acceptType = strings.TrimSpace(acceptType)
if acceptType == "*/*" {
accepted = true
break
}
for _, serverAcceptedType := range serverAcceptedTypes {
if strings.HasPrefix(acceptType, serverAcceptedType) {
accepted = true
break
}
if acceptType != "/*" && strings.HasSuffix(acceptType, "/*") && strings.HasPrefix(serverAcceptedType, acceptType[:len(acceptType)-2]) {
accepted = true
break
}
}
if accepted {
break
}
}
if !accepted {
http.Error(w, fmt.Sprintf("Not Acceptable: %s", acceptHeader), http.StatusNotAcceptable)
return
}
next.ServeHTTP(w, r)
})
}
}

View File

@@ -0,0 +1,199 @@
package middleware
import (
"net/http"
"net/http/httptest"
"testing"
"github.com/prysmaticlabs/prysm/v5/api"
"github.com/prysmaticlabs/prysm/v5/testing/require"
)
func TestNormalizeQueryValuesHandler(t *testing.T) {
nextHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
_, err := w.Write([]byte("next handler"))
require.NoError(t, err)
})
handler := NormalizeQueryValuesHandler(nextHandler)
tests := []struct {
name string
inputQuery string
expectedQuery string
}{
{
name: "3 values",
inputQuery: "key=value1,value2,value3",
expectedQuery: "key=value1&key=value2&key=value3", // replace with expected normalized value
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
req, err := http.NewRequest("GET", "/test?"+test.inputQuery, nil)
if err != nil {
t.Fatal(err)
}
rr := httptest.NewRecorder()
handler.ServeHTTP(rr, req)
if rr.Code != http.StatusOK {
t.Errorf("handler returned wrong status code: got %v want %v", rr.Code, http.StatusOK)
}
if req.URL.RawQuery != test.expectedQuery {
t.Errorf("query not normalized: got %v want %v", req.URL.RawQuery, test.expectedQuery)
}
if rr.Body.String() != "next handler" {
t.Errorf("next handler was not executed")
}
})
}
}
func TestContentTypeHandler(t *testing.T) {
acceptedMediaTypes := []string{api.JsonMediaType, api.OctetStreamMediaType}
nextHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
_, err := w.Write([]byte("next handler"))
require.NoError(t, err)
})
handler := ContentTypeHandler(acceptedMediaTypes)(nextHandler)
tests := []struct {
name string
contentType string
expectedStatusCode int
isGet bool
}{
{
name: "Accepted Content-Type - application/json",
contentType: api.JsonMediaType,
expectedStatusCode: http.StatusOK,
},
{
name: "Accepted Content-Type - ssz format",
contentType: api.OctetStreamMediaType,
expectedStatusCode: http.StatusOK,
},
{
name: "Unsupported Content-Type - text/plain",
contentType: "text/plain",
expectedStatusCode: http.StatusUnsupportedMediaType,
},
{
name: "Missing Content-Type",
contentType: "",
expectedStatusCode: http.StatusUnsupportedMediaType,
},
{
name: "GET request skips content type check",
contentType: "",
expectedStatusCode: http.StatusOK,
isGet: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
httpMethod := http.MethodPost
if tt.isGet {
httpMethod = http.MethodGet
}
req := httptest.NewRequest(httpMethod, "/", nil)
if tt.contentType != "" {
req.Header.Set("Content-Type", tt.contentType)
}
rr := httptest.NewRecorder()
handler.ServeHTTP(rr, req)
if status := rr.Code; status != tt.expectedStatusCode {
t.Errorf("handler returned wrong status code: got %v want %v", status, tt.expectedStatusCode)
}
})
}
}
func TestAcceptHeaderHandler(t *testing.T) {
acceptedTypes := []string{"application/json", "application/octet-stream"}
nextHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
_, err := w.Write([]byte("next handler"))
require.NoError(t, err)
})
handler := AcceptHeaderHandler(acceptedTypes)(nextHandler)
tests := []struct {
name string
acceptHeader string
expectedStatusCode int
}{
{
name: "Accepted Accept-Type - application/json",
acceptHeader: "application/json",
expectedStatusCode: http.StatusOK,
},
{
name: "Accepted Accept-Type - application/octet-stream",
acceptHeader: "application/octet-stream",
expectedStatusCode: http.StatusOK,
},
{
name: "Accepted Accept-Type with parameters",
acceptHeader: "application/json;q=0.9, application/octet-stream;q=0.8",
expectedStatusCode: http.StatusOK,
},
{
name: "Unsupported Accept-Type - text/plain",
acceptHeader: "text/plain",
expectedStatusCode: http.StatusNotAcceptable,
},
{
name: "Missing Accept header",
acceptHeader: "",
expectedStatusCode: http.StatusOK,
},
{
name: "*/* is accepted",
acceptHeader: "*/*",
expectedStatusCode: http.StatusOK,
},
{
name: "application/* is accepted",
acceptHeader: "application/*",
expectedStatusCode: http.StatusOK,
},
{
name: "/* is unsupported",
acceptHeader: "/*",
expectedStatusCode: http.StatusNotAcceptable,
},
{
name: "application/ is unsupported",
acceptHeader: "application/",
expectedStatusCode: http.StatusNotAcceptable,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
req := httptest.NewRequest("GET", "/", nil)
if tt.acceptHeader != "" {
req.Header.Set("Accept", tt.acceptHeader)
}
rr := httptest.NewRecorder()
handler.ServeHTTP(rr, req)
if status := rr.Code; status != tt.expectedStatusCode {
t.Errorf("handler returned wrong status code: got %v want %v", status, tt.expectedStatusCode)
}
})
}
}

View File

@@ -1,4 +1,4 @@
package server
package middleware
import (
"net/url"

View File

@@ -1,4 +1,4 @@
package server
package middleware
import (
"testing"

View File

@@ -1,54 +0,0 @@
package server
import (
"net/http"
"net/http/httptest"
"testing"
"github.com/prysmaticlabs/prysm/v5/testing/require"
)
func TestNormalizeQueryValuesHandler(t *testing.T) {
nextHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
_, err := w.Write([]byte("next handler"))
require.NoError(t, err)
})
handler := NormalizeQueryValuesHandler(nextHandler)
tests := []struct {
name string
inputQuery string
expectedQuery string
}{
{
name: "3 values",
inputQuery: "key=value1,value2,value3",
expectedQuery: "key=value1&key=value2&key=value3", // replace with expected normalized value
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
req, err := http.NewRequest("GET", "/test?"+test.inputQuery, nil)
if err != nil {
t.Fatal(err)
}
rr := httptest.NewRecorder()
handler.ServeHTTP(rr, req)
if rr.Code != http.StatusOK {
t.Errorf("handler returned wrong status code: got %v want %v", rr.Code, http.StatusOK)
}
if req.URL.RawQuery != test.expectedQuery {
t.Errorf("query not normalized: got %v want %v", req.URL.RawQuery, test.expectedQuery)
}
if rr.Body.String() != "next handler" {
t.Errorf("next handler was not executed")
}
})
}
}

View File

@@ -80,11 +80,11 @@ func (s *Service) OnAttestation(ctx context.Context, a ethpb.Att, disparity time
}
// Use the target state to verify attesting indices are valid.
committee, err := helpers.BeaconCommitteeFromState(ctx, baseState, a.GetData().Slot, a.GetData().CommitteeIndex)
committees, err := helpers.AttestationCommittees(ctx, baseState, a)
if err != nil {
return err
}
indexedAtt, err := attestation.ConvertToIndexed(ctx, a, committee)
indexedAtt, err := attestation.ConvertToIndexed(ctx, a, committees...)
if err != nil {
return err
}

View File

@@ -7,9 +7,11 @@ import (
"time"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/transition"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/state"
fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams"
"github.com/prysmaticlabs/prysm/v5/config/params"
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
"github.com/prysmaticlabs/prysm/v5/crypto/bls"
"github.com/prysmaticlabs/prysm/v5/encoding/bytesutil"
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v5/testing/assert"
@@ -125,25 +127,36 @@ func TestStore_OnAttestation_ErrorConditions(t *testing.T) {
}
func TestStore_OnAttestation_Ok_DoublyLinkedTree(t *testing.T) {
service, tr := minimalTestService(t)
ctx := tr.ctx
eval := func(ctx context.Context, service *Service, genesisState state.BeaconState, pks []bls.SecretKey) {
service.SetGenesisTime(time.Unix(time.Now().Unix()-int64(params.BeaconConfig().SecondsPerSlot), 0))
require.NoError(t, service.saveGenesisData(ctx, genesisState))
att, err := util.GenerateAttestations(genesisState, pks, 1, 0, false)
require.NoError(t, err)
tRoot := bytesutil.ToBytes32(att[0].GetData().Target.Root)
copied := genesisState.Copy()
copied, err = transition.ProcessSlots(ctx, copied, 1)
require.NoError(t, err)
require.NoError(t, service.cfg.BeaconDB.SaveState(ctx, copied, tRoot))
ojc := &ethpb.Checkpoint{Epoch: 0, Root: tRoot[:]}
ofc := &ethpb.Checkpoint{Epoch: 0, Root: tRoot[:]}
state, blkRoot, err := prepareForkchoiceState(ctx, 0, tRoot, tRoot, params.BeaconConfig().ZeroHash, ojc, ofc)
require.NoError(t, err)
require.NoError(t, service.cfg.ForkChoiceStore.InsertNode(ctx, state, blkRoot))
require.NoError(t, service.OnAttestation(ctx, att[0], 0))
}
genesisState, pks := util.DeterministicGenesisState(t, 64)
service.SetGenesisTime(time.Unix(time.Now().Unix()-int64(params.BeaconConfig().SecondsPerSlot), 0))
require.NoError(t, service.saveGenesisData(ctx, genesisState))
att, err := util.GenerateAttestations(genesisState, pks, 1, 0, false)
require.NoError(t, err)
tRoot := bytesutil.ToBytes32(att[0].Data.Target.Root)
copied := genesisState.Copy()
copied, err = transition.ProcessSlots(ctx, copied, 1)
require.NoError(t, err)
require.NoError(t, service.cfg.BeaconDB.SaveState(ctx, copied, tRoot))
ojc := &ethpb.Checkpoint{Epoch: 0, Root: tRoot[:]}
ofc := &ethpb.Checkpoint{Epoch: 0, Root: tRoot[:]}
state, blkRoot, err := prepareForkchoiceState(ctx, 0, tRoot, tRoot, params.BeaconConfig().ZeroHash, ojc, ofc)
require.NoError(t, err)
require.NoError(t, service.cfg.ForkChoiceStore.InsertNode(ctx, state, blkRoot))
require.NoError(t, service.OnAttestation(ctx, att[0], 0))
t.Run("pre-Electra", func(t *testing.T) {
service, tr := minimalTestService(t)
ctx := tr.ctx
genesisState, pks := util.DeterministicGenesisState(t, 64)
eval(ctx, service, genesisState, pks)
})
t.Run("post-Electra", func(t *testing.T) {
service, tr := minimalTestService(t)
ctx := tr.ctx
genesisState, pks := util.DeterministicGenesisStateElectra(t, 64)
eval(ctx, service, genesisState, pks)
})
}
func TestService_GetRecentPreState(t *testing.T) {

View File

@@ -366,11 +366,11 @@ func (s *Service) handleEpochBoundary(ctx context.Context, slot primitives.Slot,
func (s *Service) handleBlockAttestations(ctx context.Context, blk interfaces.ReadOnlyBeaconBlock, st state.BeaconState) error {
// Feed in block's attestations to fork choice store.
for _, a := range blk.Body().Attestations() {
committee, err := helpers.BeaconCommitteeFromState(ctx, st, a.GetData().Slot, a.GetData().CommitteeIndex)
committees, err := helpers.AttestationCommittees(ctx, st, a)
if err != nil {
return err
}
indices, err := attestation.AttestingIndices(a, committee)
indices, err := attestation.AttestingIndices(a, committees...)
if err != nil {
return err
}

View File

@@ -1963,68 +1963,130 @@ func TestNoViableHead_Reboot(t *testing.T) {
}
func TestOnBlock_HandleBlockAttestations(t *testing.T) {
service, tr := minimalTestService(t)
ctx := tr.ctx
t.Run("pre-Electra", func(t *testing.T) {
service, tr := minimalTestService(t)
ctx := tr.ctx
st, keys := util.DeterministicGenesisState(t, 64)
stateRoot, err := st.HashTreeRoot(ctx)
require.NoError(t, err, "Could not hash genesis state")
st, keys := util.DeterministicGenesisState(t, 64)
stateRoot, err := st.HashTreeRoot(ctx)
require.NoError(t, err, "Could not hash genesis state")
require.NoError(t, service.saveGenesisData(ctx, st))
require.NoError(t, service.saveGenesisData(ctx, st))
genesis := blocks.NewGenesisBlock(stateRoot[:])
wsb, err := consensusblocks.NewSignedBeaconBlock(genesis)
require.NoError(t, err)
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, wsb), "Could not save genesis block")
parentRoot, err := genesis.Block.HashTreeRoot()
require.NoError(t, err, "Could not get signing root")
require.NoError(t, service.cfg.BeaconDB.SaveState(ctx, st, parentRoot), "Could not save genesis state")
require.NoError(t, service.cfg.BeaconDB.SaveHeadBlockRoot(ctx, parentRoot), "Could not save genesis state")
genesis := blocks.NewGenesisBlock(stateRoot[:])
wsb, err := consensusblocks.NewSignedBeaconBlock(genesis)
require.NoError(t, err)
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, wsb), "Could not save genesis block")
parentRoot, err := genesis.Block.HashTreeRoot()
require.NoError(t, err, "Could not get signing root")
require.NoError(t, service.cfg.BeaconDB.SaveState(ctx, st, parentRoot), "Could not save genesis state")
require.NoError(t, service.cfg.BeaconDB.SaveHeadBlockRoot(ctx, parentRoot), "Could not save genesis state")
st, err = service.HeadState(ctx)
require.NoError(t, err)
b, err := util.GenerateFullBlock(st, keys, util.DefaultBlockGenConfig(), 1)
require.NoError(t, err)
wsb, err = consensusblocks.NewSignedBeaconBlock(b)
require.NoError(t, err)
root, err := b.Block.HashTreeRoot()
require.NoError(t, err)
preState, err := service.getBlockPreState(ctx, wsb.Block())
require.NoError(t, err)
postState, err := service.validateStateTransition(ctx, preState, wsb)
require.NoError(t, err)
require.NoError(t, service.savePostStateInfo(ctx, root, wsb, postState))
require.NoError(t, service.postBlockProcess(&postBlockProcessConfig{ctx, wsb, root, [32]byte{}, postState, false}))
st, err = service.HeadState(ctx)
require.NoError(t, err)
b, err := util.GenerateFullBlock(st, keys, util.DefaultBlockGenConfig(), 1)
require.NoError(t, err)
wsb, err = consensusblocks.NewSignedBeaconBlock(b)
require.NoError(t, err)
root, err := b.Block.HashTreeRoot()
require.NoError(t, err)
preState, err := service.getBlockPreState(ctx, wsb.Block())
require.NoError(t, err)
postState, err := service.validateStateTransition(ctx, preState, wsb)
require.NoError(t, err)
require.NoError(t, service.savePostStateInfo(ctx, root, wsb, postState))
require.NoError(t, service.postBlockProcess(&postBlockProcessConfig{ctx, wsb, root, [32]byte{}, postState, false}))
st, err = service.HeadState(ctx)
require.NoError(t, err)
b, err = util.GenerateFullBlock(st, keys, util.DefaultBlockGenConfig(), 2)
require.NoError(t, err)
wsb, err = consensusblocks.NewSignedBeaconBlock(b)
require.NoError(t, err)
st, err = service.HeadState(ctx)
require.NoError(t, err)
b, err = util.GenerateFullBlock(st, keys, util.DefaultBlockGenConfig(), 2)
require.NoError(t, err)
wsb, err = consensusblocks.NewSignedBeaconBlock(b)
require.NoError(t, err)
// prepare another block that is not inserted
st3, err := transition.ExecuteStateTransition(ctx, st, wsb)
require.NoError(t, err)
b3, err := util.GenerateFullBlock(st3, keys, util.DefaultBlockGenConfig(), 3)
require.NoError(t, err)
wsb3, err := consensusblocks.NewSignedBeaconBlock(b3)
require.NoError(t, err)
// prepare another block that is not inserted
st3, err := transition.ExecuteStateTransition(ctx, st, wsb)
require.NoError(t, err)
b3, err := util.GenerateFullBlock(st3, keys, util.DefaultBlockGenConfig(), 3)
require.NoError(t, err)
wsb3, err := consensusblocks.NewSignedBeaconBlock(b3)
require.NoError(t, err)
require.Equal(t, 1, len(wsb.Block().Body().Attestations()))
a := wsb.Block().Body().Attestations()[0]
r := bytesutil.ToBytes32(a.GetData().BeaconBlockRoot)
require.Equal(t, true, service.cfg.ForkChoiceStore.HasNode(r))
require.Equal(t, 1, len(wsb.Block().Body().Attestations()))
a := wsb.Block().Body().Attestations()[0]
r := bytesutil.ToBytes32(a.GetData().BeaconBlockRoot)
require.Equal(t, true, service.cfg.ForkChoiceStore.HasNode(r))
require.Equal(t, 1, len(wsb.Block().Body().Attestations()))
a3 := wsb3.Block().Body().Attestations()[0]
r3 := bytesutil.ToBytes32(a3.GetData().BeaconBlockRoot)
require.Equal(t, false, service.cfg.ForkChoiceStore.HasNode(r3))
require.Equal(t, 1, len(wsb.Block().Body().Attestations()))
a3 := wsb3.Block().Body().Attestations()[0]
r3 := bytesutil.ToBytes32(a3.GetData().BeaconBlockRoot)
require.Equal(t, false, service.cfg.ForkChoiceStore.HasNode(r3))
require.NoError(t, service.handleBlockAttestations(ctx, wsb.Block(), st)) // fine to use the same committee as st
require.Equal(t, 0, service.cfg.AttPool.ForkchoiceAttestationCount())
require.NoError(t, service.handleBlockAttestations(ctx, wsb3.Block(), st3)) // fine to use the same committee as st
require.Equal(t, 1, len(service.cfg.AttPool.BlockAttestations()))
require.NoError(t, service.handleBlockAttestations(ctx, wsb.Block(), st)) // fine to use the same committee as st
require.Equal(t, 0, service.cfg.AttPool.ForkchoiceAttestationCount())
require.NoError(t, service.handleBlockAttestations(ctx, wsb3.Block(), st3)) // fine to use the same committee as st
require.Equal(t, 1, len(service.cfg.AttPool.BlockAttestations()))
})
t.Run("post-Electra", func(t *testing.T) {
service, tr := minimalTestService(t)
ctx := tr.ctx
st, keys := util.DeterministicGenesisStateElectra(t, 64)
require.NoError(t, service.saveGenesisData(ctx, st))
genesis, err := blocks.NewGenesisBlockForState(ctx, st)
require.NoError(t, err)
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, genesis), "Could not save genesis block")
parentRoot, err := genesis.Block().HashTreeRoot()
require.NoError(t, err, "Could not get signing root")
require.NoError(t, service.cfg.BeaconDB.SaveState(ctx, st, parentRoot), "Could not save genesis state")
require.NoError(t, service.cfg.BeaconDB.SaveHeadBlockRoot(ctx, parentRoot), "Could not save genesis state")
st, err = service.HeadState(ctx)
require.NoError(t, err)
b, err := util.GenerateFullBlockElectra(st, keys, util.DefaultBlockGenConfig(), 1)
require.NoError(t, err)
wsb, err := consensusblocks.NewSignedBeaconBlock(b)
require.NoError(t, err)
root, err := b.Block.HashTreeRoot()
require.NoError(t, err)
preState, err := service.getBlockPreState(ctx, wsb.Block())
require.NoError(t, err)
postState, err := service.validateStateTransition(ctx, preState, wsb)
require.NoError(t, err)
require.NoError(t, service.savePostStateInfo(ctx, root, wsb, postState))
require.NoError(t, service.postBlockProcess(&postBlockProcessConfig{ctx, wsb, root, [32]byte{}, postState, false}))
st, err = service.HeadState(ctx)
require.NoError(t, err)
b, err = util.GenerateFullBlockElectra(st, keys, util.DefaultBlockGenConfig(), 2)
require.NoError(t, err)
wsb, err = consensusblocks.NewSignedBeaconBlock(b)
require.NoError(t, err)
// prepare another block that is not inserted
st3, err := transition.ExecuteStateTransition(ctx, st, wsb)
require.NoError(t, err)
b3, err := util.GenerateFullBlockElectra(st3, keys, util.DefaultBlockGenConfig(), 3)
require.NoError(t, err)
wsb3, err := consensusblocks.NewSignedBeaconBlock(b3)
require.NoError(t, err)
require.Equal(t, 1, len(wsb.Block().Body().Attestations()))
a := wsb.Block().Body().Attestations()[0]
r := bytesutil.ToBytes32(a.GetData().BeaconBlockRoot)
require.Equal(t, true, service.cfg.ForkChoiceStore.HasNode(r))
require.Equal(t, 1, len(wsb.Block().Body().Attestations()))
a3 := wsb3.Block().Body().Attestations()[0]
r3 := bytesutil.ToBytes32(a3.GetData().BeaconBlockRoot)
require.Equal(t, false, service.cfg.ForkChoiceStore.HasNode(r3))
require.NoError(t, service.handleBlockAttestations(ctx, wsb.Block(), st)) // fine to use the same committee as st
require.Equal(t, 0, service.cfg.AttPool.ForkchoiceAttestationCount())
require.NoError(t, service.handleBlockAttestations(ctx, wsb3.Block(), st3)) // fine to use the same committee as st
require.Equal(t, 1, len(service.cfg.AttPool.BlockAttestations()))
})
}
func TestFillMissingBlockPayloadId_DiffSlotExitEarly(t *testing.T) {

View File

@@ -73,7 +73,7 @@ func TestProcessAttestations_Ok(t *testing.T) {
require.NoError(t, service.saveGenesisData(ctx, genesisState))
atts, err := util.GenerateAttestations(genesisState, pks, 1, 0, false)
require.NoError(t, err)
tRoot := bytesutil.ToBytes32(atts[0].Data.Target.Root)
tRoot := bytesutil.ToBytes32(atts[0].GetData().Target.Root)
copied := genesisState.Copy()
copied, err = transition.ProcessSlots(ctx, copied, 1)
require.NoError(t, err)
@@ -131,8 +131,8 @@ func TestService_ProcessAttestationsAndUpdateHead(t *testing.T) {
}
require.NoError(t, service.cfg.AttPool.SaveForkchoiceAttestations(attsToSave))
// Verify the target is in forkchoice
require.Equal(t, true, fcs.HasNode(bytesutil.ToBytes32(atts[0].Data.BeaconBlockRoot)))
require.Equal(t, tRoot, bytesutil.ToBytes32(atts[0].Data.BeaconBlockRoot))
require.Equal(t, true, fcs.HasNode(bytesutil.ToBytes32(atts[0].GetData().BeaconBlockRoot)))
require.Equal(t, tRoot, bytesutil.ToBytes32(atts[0].GetData().BeaconBlockRoot))
require.Equal(t, true, fcs.HasNode(service.originBlockRoot))
// Insert a new block to forkchoice

View File

@@ -479,12 +479,12 @@ func (s *Service) sendBlockAttestationsToSlasher(signed interfaces.ReadOnlySigne
// is done in the background to avoid adding more load to this critical code path.
ctx := context.TODO()
for _, att := range signed.Block().Body().Attestations() {
committee, err := helpers.BeaconCommitteeFromState(ctx, preState, att.GetData().Slot, att.GetData().CommitteeIndex)
committees, err := helpers.AttestationCommittees(ctx, preState, att)
if err != nil {
log.WithError(err).Error("Could not get attestation committee")
log.WithError(err).Error("Could not get attestation committees")
return
}
indexedAtt, err := attestation.ConvertToIndexed(ctx, att, committee)
indexedAtt, err := attestation.ConvertToIndexed(ctx, att, committees...)
if err != nil {
log.WithError(err).Error("Could not convert to indexed attestation")
return

View File

@@ -13,6 +13,7 @@ import (
"github.com/prysmaticlabs/prysm/v5/beacon-chain/db"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/db/filesystem"
testDB "github.com/prysmaticlabs/prysm/v5/beacon-chain/db/testing"
mockExecution "github.com/prysmaticlabs/prysm/v5/beacon-chain/execution/testing"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/forkchoice"
doublylinkedtree "github.com/prysmaticlabs/prysm/v5/beacon-chain/forkchoice/doubly-linked-tree"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/operations/attestations"
@@ -120,6 +121,7 @@ func minimalTestService(t *testing.T, opts ...Option) (*Service, *testServiceReq
WithTrackedValidatorsCache(cache.NewTrackedValidatorsCache()),
WithBlobStorage(filesystem.NewEphemeralBlobStorage(t)),
WithSyncChecker(mock.MockChecker{}),
WithExecutionEngineCaller(&mockExecution.EngineClient{}),
}
// append the variadic opts so they override the defaults by being processed afterwards
opts = append(defOpts, opts...)

View File

@@ -66,11 +66,11 @@ func ProcessAttestationNoVerifySignature(
if err != nil {
return nil, err
}
committee, err := helpers.BeaconCommitteeFromState(ctx, beaconState, att.GetData().Slot, att.GetData().CommitteeIndex)
committees, err := helpers.AttestationCommittees(ctx, beaconState, att)
if err != nil {
return nil, err
}
indices, err := attestation.AttestingIndices(att, committee)
indices, err := attestation.AttestingIndices(att, committees...)
if err != nil {
return nil, err
}

View File

@@ -195,47 +195,95 @@ func TestProcessAttestations_InvalidAggregationBitsLength(t *testing.T) {
}
func TestProcessAttestations_OK(t *testing.T) {
beaconState, privKeys := util.DeterministicGenesisStateAltair(t, 100)
t.Run("pre-Electra", func(t *testing.T) {
beaconState, privKeys := util.DeterministicGenesisStateAltair(t, 100)
aggBits := bitfield.NewBitlist(3)
aggBits.SetBitAt(0, true)
var mockRoot [32]byte
copy(mockRoot[:], "hello-world")
att := util.HydrateAttestation(&ethpb.Attestation{
Data: &ethpb.AttestationData{
Source: &ethpb.Checkpoint{Root: mockRoot[:]},
Target: &ethpb.Checkpoint{Root: mockRoot[:]},
},
AggregationBits: aggBits,
aggBits := bitfield.NewBitlist(3)
aggBits.SetBitAt(0, true)
var mockRoot [32]byte
copy(mockRoot[:], "hello-world")
att := util.HydrateAttestation(&ethpb.Attestation{
Data: &ethpb.AttestationData{
Source: &ethpb.Checkpoint{Root: mockRoot[:]},
Target: &ethpb.Checkpoint{Root: mockRoot[:]},
},
AggregationBits: aggBits,
})
cfc := beaconState.CurrentJustifiedCheckpoint()
cfc.Root = mockRoot[:]
require.NoError(t, beaconState.SetCurrentJustifiedCheckpoint(cfc))
committee, err := helpers.BeaconCommitteeFromState(context.Background(), beaconState, att.Data.Slot, 0)
require.NoError(t, err)
attestingIndices, err := attestation.AttestingIndices(att, committee)
require.NoError(t, err)
sigs := make([]bls.Signature, len(attestingIndices))
for i, indice := range attestingIndices {
sb, err := signing.ComputeDomainAndSign(beaconState, 0, att.Data, params.BeaconConfig().DomainBeaconAttester, privKeys[indice])
require.NoError(t, err)
sig, err := bls.SignatureFromBytes(sb)
require.NoError(t, err)
sigs[i] = sig
}
att.Signature = bls.AggregateSignatures(sigs).Marshal()
block := util.NewBeaconBlockAltair()
block.Block.Body.Attestations = []*ethpb.Attestation{att}
err = beaconState.SetSlot(beaconState.Slot() + params.BeaconConfig().MinAttestationInclusionDelay)
require.NoError(t, err)
wsb, err := blocks.NewSignedBeaconBlock(block)
require.NoError(t, err)
_, err = altair.ProcessAttestationsNoVerifySignature(context.Background(), beaconState, wsb.Block())
require.NoError(t, err)
})
t.Run("post-Electra", func(t *testing.T) {
beaconState, privKeys := util.DeterministicGenesisStateElectra(t, 100)
cfc := beaconState.CurrentJustifiedCheckpoint()
cfc.Root = mockRoot[:]
require.NoError(t, beaconState.SetCurrentJustifiedCheckpoint(cfc))
aggBits := bitfield.NewBitlist(3)
aggBits.SetBitAt(0, true)
committeeBits := primitives.NewAttestationCommitteeBits()
committeeBits.SetBitAt(0, true)
var mockRoot [32]byte
copy(mockRoot[:], "hello-world")
att := util.HydrateAttestationElectra(&ethpb.AttestationElectra{
Data: &ethpb.AttestationData{
Source: &ethpb.Checkpoint{Root: mockRoot[:]},
Target: &ethpb.Checkpoint{Root: mockRoot[:]},
},
AggregationBits: aggBits,
CommitteeBits: committeeBits,
})
committee, err := helpers.BeaconCommitteeFromState(context.Background(), beaconState, att.Data.Slot, att.Data.CommitteeIndex)
require.NoError(t, err)
attestingIndices, err := attestation.AttestingIndices(att, committee)
require.NoError(t, err)
sigs := make([]bls.Signature, len(attestingIndices))
for i, indice := range attestingIndices {
sb, err := signing.ComputeDomainAndSign(beaconState, 0, att.Data, params.BeaconConfig().DomainBeaconAttester, privKeys[indice])
cfc := beaconState.CurrentJustifiedCheckpoint()
cfc.Root = mockRoot[:]
require.NoError(t, beaconState.SetCurrentJustifiedCheckpoint(cfc))
committee, err := helpers.BeaconCommitteeFromState(context.Background(), beaconState, att.Data.Slot, 0)
require.NoError(t, err)
sig, err := bls.SignatureFromBytes(sb)
attestingIndices, err := attestation.AttestingIndices(att, committee)
require.NoError(t, err)
sigs[i] = sig
}
att.Signature = bls.AggregateSignatures(sigs).Marshal()
sigs := make([]bls.Signature, len(attestingIndices))
for i, indice := range attestingIndices {
sb, err := signing.ComputeDomainAndSign(beaconState, 0, att.Data, params.BeaconConfig().DomainBeaconAttester, privKeys[indice])
require.NoError(t, err)
sig, err := bls.SignatureFromBytes(sb)
require.NoError(t, err)
sigs[i] = sig
}
att.Signature = bls.AggregateSignatures(sigs).Marshal()
block := util.NewBeaconBlockAltair()
block.Block.Body.Attestations = []*ethpb.Attestation{att}
block := util.NewBeaconBlockElectra()
block.Block.Body.Attestations = []*ethpb.AttestationElectra{att}
err = beaconState.SetSlot(beaconState.Slot() + params.BeaconConfig().MinAttestationInclusionDelay)
require.NoError(t, err)
wsb, err := blocks.NewSignedBeaconBlock(block)
require.NoError(t, err)
_, err = altair.ProcessAttestationsNoVerifySignature(context.Background(), beaconState, wsb.Block())
require.NoError(t, err)
err = beaconState.SetSlot(beaconState.Slot() + params.BeaconConfig().MinAttestationInclusionDelay)
require.NoError(t, err)
wsb, err := blocks.NewSignedBeaconBlock(block)
require.NoError(t, err)
_, err = altair.ProcessAttestationsNoVerifySignature(context.Background(), beaconState, wsb.Block())
require.NoError(t, err)
})
}
func TestProcessAttestationNoVerify_SourceTargetHead(t *testing.T) {

View File

@@ -28,87 +28,87 @@ import (
// process_historical_roots_update(state)
// process_participation_flag_updates(state) # [New in Altair]
// process_sync_committee_updates(state) # [New in Altair]
func ProcessEpoch(ctx context.Context, state state.BeaconState) (state.BeaconState, error) {
func ProcessEpoch(ctx context.Context, state state.BeaconState) error {
ctx, span := trace.StartSpan(ctx, "altair.ProcessEpoch")
defer span.End()
if state == nil || state.IsNil() {
return nil, errors.New("nil state")
return errors.New("nil state")
}
vp, bp, err := InitializePrecomputeValidators(ctx, state)
if err != nil {
return nil, err
return err
}
// New in Altair.
vp, bp, err = ProcessEpochParticipation(ctx, state, bp, vp)
if err != nil {
return nil, err
return err
}
state, err = precompute.ProcessJustificationAndFinalizationPreCompute(state, bp)
if err != nil {
return nil, errors.Wrap(err, "could not process justification")
return errors.Wrap(err, "could not process justification")
}
// New in Altair.
state, vp, err = ProcessInactivityScores(ctx, state, vp)
if err != nil {
return nil, errors.Wrap(err, "could not process inactivity updates")
return errors.Wrap(err, "could not process inactivity updates")
}
// New in Altair.
state, err = ProcessRewardsAndPenaltiesPrecompute(state, bp, vp)
if err != nil {
return nil, errors.Wrap(err, "could not process rewards and penalties")
return errors.Wrap(err, "could not process rewards and penalties")
}
state, err = e.ProcessRegistryUpdates(ctx, state)
if err != nil {
return nil, errors.Wrap(err, "could not process registry updates")
return errors.Wrap(err, "could not process registry updates")
}
// Modified in Altair and Bellatrix.
proportionalSlashingMultiplier, err := state.ProportionalSlashingMultiplier()
if err != nil {
return nil, err
return err
}
state, err = e.ProcessSlashings(state, proportionalSlashingMultiplier)
if err != nil {
return nil, err
return err
}
state, err = e.ProcessEth1DataReset(state)
if err != nil {
return nil, err
return err
}
state, err = e.ProcessEffectiveBalanceUpdates(state)
if err != nil {
return nil, err
return err
}
state, err = e.ProcessSlashingsReset(state)
if err != nil {
return nil, err
return err
}
state, err = e.ProcessRandaoMixesReset(state)
if err != nil {
return nil, err
return err
}
state, err = e.ProcessHistoricalDataUpdate(state)
if err != nil {
return nil, err
return err
}
// New in Altair.
state, err = ProcessParticipationFlagUpdates(state)
if err != nil {
return nil, err
return err
}
// New in Altair.
state, err = ProcessSyncCommitteeUpdates(ctx, state)
_, err = ProcessSyncCommitteeUpdates(ctx, state)
if err != nil {
return nil, err
return err
}
return state, nil
return nil
}

View File

@@ -13,9 +13,9 @@ import (
func TestProcessEpoch_CanProcess(t *testing.T) {
st, _ := util.DeterministicGenesisStateAltair(t, params.BeaconConfig().MaxValidatorsPerCommittee)
require.NoError(t, st.SetSlot(10*params.BeaconConfig().SlotsPerEpoch))
newState, err := altair.ProcessEpoch(context.Background(), st)
err := altair.ProcessEpoch(context.Background(), st)
require.NoError(t, err)
require.Equal(t, uint64(0), newState.Slashings()[2], "Unexpected slashed balance")
require.Equal(t, uint64(0), st.Slashings()[2], "Unexpected slashed balance")
b := st.Balances()
require.Equal(t, params.BeaconConfig().MaxValidatorsPerCommittee, uint64(len(b)))
@@ -45,9 +45,9 @@ func TestProcessEpoch_CanProcess(t *testing.T) {
func TestProcessEpoch_CanProcessBellatrix(t *testing.T) {
st, _ := util.DeterministicGenesisStateBellatrix(t, params.BeaconConfig().MaxValidatorsPerCommittee)
require.NoError(t, st.SetSlot(10*params.BeaconConfig().SlotsPerEpoch))
newState, err := altair.ProcessEpoch(context.Background(), st)
err := altair.ProcessEpoch(context.Background(), st)
require.NoError(t, err)
require.Equal(t, uint64(0), newState.Slashings()[2], "Unexpected slashed balance")
require.Equal(t, uint64(0), st.Slashings()[2], "Unexpected slashed balance")
b := st.Balances()
require.Equal(t, params.BeaconConfig().MaxValidatorsPerCommittee, uint64(len(b)))

View File

@@ -154,7 +154,7 @@ func TranslateParticipation(ctx context.Context, state state.BeaconState, atts [
if err != nil {
return nil, err
}
committee, err := helpers.BeaconCommitteeFromState(ctx, state, att.Data.Slot, att.Data.CommitteeIndex)
committee, err := helpers.BeaconCommitteeFromState(ctx, state, att.GetData().Slot, att.GetData().CommitteeIndex)
if err != nil {
return nil, err
}

View File

@@ -200,23 +200,6 @@ func ProcessAttestationNoVerifySignature(
return beaconState, nil
}
// VerifyAttestationSignature converts and attestation into an indexed attestation and verifies
// the signature in that attestation.
func VerifyAttestationSignature(ctx context.Context, beaconState state.ReadOnlyBeaconState, att ethpb.Att) error {
if err := helpers.ValidateNilAttestation(att); err != nil {
return err
}
committee, err := helpers.BeaconCommitteeFromState(ctx, beaconState, att.GetData().Slot, att.GetData().CommitteeIndex)
if err != nil {
return err
}
indexedAtt, err := attestation.ConvertToIndexed(ctx, att, committee)
if err != nil {
return err
}
return VerifyIndexedAttestation(ctx, beaconState, indexedAtt)
}
// VerifyIndexedAttestation determines the validity of an indexed attestation.
//
// Spec pseudocode definition:

View File

@@ -578,53 +578,109 @@ func TestRetrieveAttestationSignatureSet_VerifiesMultipleAttestations(t *testing
}
}
st, err := util.NewBeaconState()
require.NoError(t, err)
require.NoError(t, st.SetSlot(5))
require.NoError(t, st.SetValidators(validators))
t.Run("pre-Electra", func(t *testing.T) {
st, err := util.NewBeaconState()
require.NoError(t, err)
require.NoError(t, st.SetSlot(5))
require.NoError(t, st.SetValidators(validators))
comm1, err := helpers.BeaconCommitteeFromState(context.Background(), st, 1 /*slot*/, 0 /*committeeIndex*/)
require.NoError(t, err)
att1 := util.HydrateAttestation(&ethpb.Attestation{
AggregationBits: bitfield.NewBitlist(uint64(len(comm1))),
Data: &ethpb.AttestationData{
Slot: 1,
},
comm1, err := helpers.BeaconCommitteeFromState(context.Background(), st, 1 /*slot*/, 0 /*committeeIndex*/)
require.NoError(t, err)
att1 := util.HydrateAttestation(&ethpb.Attestation{
AggregationBits: bitfield.NewBitlist(uint64(len(comm1))),
Data: &ethpb.AttestationData{
Slot: 1,
},
})
domain, err := signing.Domain(st.Fork(), st.Fork().Epoch, params.BeaconConfig().DomainBeaconAttester, st.GenesisValidatorsRoot())
require.NoError(t, err)
root, err := signing.ComputeSigningRoot(att1.Data, domain)
require.NoError(t, err)
var sigs []bls.Signature
for i, u := range comm1 {
att1.AggregationBits.SetBitAt(uint64(i), true)
sigs = append(sigs, keys[u].Sign(root[:]))
}
att1.Signature = bls.AggregateSignatures(sigs).Marshal()
comm2, err := helpers.BeaconCommitteeFromState(context.Background(), st, 1 /*slot*/, 1 /*committeeIndex*/)
require.NoError(t, err)
att2 := util.HydrateAttestation(&ethpb.Attestation{
AggregationBits: bitfield.NewBitlist(uint64(len(comm2))),
Data: &ethpb.AttestationData{
Slot: 1,
CommitteeIndex: 1,
},
})
root, err = signing.ComputeSigningRoot(att2.Data, domain)
require.NoError(t, err)
sigs = nil
for i, u := range comm2 {
att2.AggregationBits.SetBitAt(uint64(i), true)
sigs = append(sigs, keys[u].Sign(root[:]))
}
att2.Signature = bls.AggregateSignatures(sigs).Marshal()
set, err := blocks.AttestationSignatureBatch(ctx, st, []ethpb.Att{att1, att2})
require.NoError(t, err)
verified, err := set.Verify()
require.NoError(t, err)
assert.Equal(t, true, verified, "Multiple signatures were unable to be verified.")
})
domain, err := signing.Domain(st.Fork(), st.Fork().Epoch, params.BeaconConfig().DomainBeaconAttester, st.GenesisValidatorsRoot())
require.NoError(t, err)
root, err := signing.ComputeSigningRoot(att1.Data, domain)
require.NoError(t, err)
var sigs []bls.Signature
for i, u := range comm1 {
att1.AggregationBits.SetBitAt(uint64(i), true)
sigs = append(sigs, keys[u].Sign(root[:]))
}
att1.Signature = bls.AggregateSignatures(sigs).Marshal()
t.Run("post-Electra", func(t *testing.T) {
st, err := util.NewBeaconStateElectra()
require.NoError(t, err)
require.NoError(t, st.SetSlot(5))
require.NoError(t, st.SetValidators(validators))
comm2, err := helpers.BeaconCommitteeFromState(context.Background(), st, 1 /*slot*/, 1 /*committeeIndex*/)
require.NoError(t, err)
att2 := util.HydrateAttestation(&ethpb.Attestation{
AggregationBits: bitfield.NewBitlist(uint64(len(comm2))),
Data: &ethpb.AttestationData{
Slot: 1,
CommitteeIndex: 1,
},
comm1, err := helpers.BeaconCommitteeFromState(context.Background(), st, 1 /*slot*/, 0 /*committeeIndex*/)
require.NoError(t, err)
commBits1 := primitives.NewAttestationCommitteeBits()
commBits1.SetBitAt(0, true)
att1 := util.HydrateAttestationElectra(&ethpb.AttestationElectra{
AggregationBits: bitfield.NewBitlist(uint64(len(comm1))),
CommitteeBits: commBits1,
Data: &ethpb.AttestationData{
Slot: 1,
},
})
domain, err := signing.Domain(st.Fork(), st.Fork().Epoch, params.BeaconConfig().DomainBeaconAttester, st.GenesisValidatorsRoot())
require.NoError(t, err)
root, err := signing.ComputeSigningRoot(att1.Data, domain)
require.NoError(t, err)
var sigs []bls.Signature
for i, u := range comm1 {
att1.AggregationBits.SetBitAt(uint64(i), true)
sigs = append(sigs, keys[u].Sign(root[:]))
}
att1.Signature = bls.AggregateSignatures(sigs).Marshal()
comm2, err := helpers.BeaconCommitteeFromState(context.Background(), st, 1 /*slot*/, 1 /*committeeIndex*/)
require.NoError(t, err)
commBits2 := primitives.NewAttestationCommitteeBits()
commBits2.SetBitAt(1, true)
att2 := util.HydrateAttestationElectra(&ethpb.AttestationElectra{
AggregationBits: bitfield.NewBitlist(uint64(len(comm2))),
CommitteeBits: commBits2,
Data: &ethpb.AttestationData{
Slot: 1,
},
})
root, err = signing.ComputeSigningRoot(att2.Data, domain)
require.NoError(t, err)
sigs = nil
for i, u := range comm2 {
att2.AggregationBits.SetBitAt(uint64(i), true)
sigs = append(sigs, keys[u].Sign(root[:]))
}
att2.Signature = bls.AggregateSignatures(sigs).Marshal()
set, err := blocks.AttestationSignatureBatch(ctx, st, []ethpb.Att{att1, att2})
require.NoError(t, err)
verified, err := set.Verify()
require.NoError(t, err)
assert.Equal(t, true, verified, "Multiple signatures were unable to be verified.")
})
root, err = signing.ComputeSigningRoot(att2.Data, domain)
require.NoError(t, err)
sigs = nil
for i, u := range comm2 {
att2.AggregationBits.SetBitAt(uint64(i), true)
sigs = append(sigs, keys[u].Sign(root[:]))
}
att2.Signature = bls.AggregateSignatures(sigs).Marshal()
set, err := blocks.AttestationSignatureBatch(ctx, st, []ethpb.Att{att1, att2})
require.NoError(t, err)
verified, err := set.Verify()
require.NoError(t, err)
assert.Equal(t, true, verified, "Multiple signatures were unable to be verified.")
}
func TestRetrieveAttestationSignatureSet_AcrossFork(t *testing.T) {

View File

@@ -297,21 +297,6 @@ func TestFuzzVerifyIndexedAttestationn_10000(t *testing.T) {
}
}
func TestFuzzVerifyAttestation_10000(t *testing.T) {
fuzzer := fuzz.NewWithSeed(0)
state := &ethpb.BeaconState{}
attestation := &ethpb.Attestation{}
ctx := context.Background()
for i := 0; i < 10000; i++ {
fuzzer.Fuzz(state)
fuzzer.Fuzz(attestation)
s, err := state_native.InitializeFromProtoUnsafePhase0(state)
require.NoError(t, err)
err = VerifyAttestationSignature(ctx, s, attestation)
_ = err
}
}
func TestFuzzProcessDeposits_10000(t *testing.T) {
fuzzer := fuzz.NewWithSeed(0)
state := &ethpb.BeaconState{}

View File

@@ -163,7 +163,42 @@ func NewGenesisBlockForState(ctx context.Context, st state.BeaconState) (interfa
SyncCommitteeBits: make([]byte, fieldparams.SyncCommitteeLength/8),
SyncCommitteeSignature: make([]byte, fieldparams.BLSSignatureLength),
},
ExecutionPayload: &enginev1.ExecutionPayloadDeneb{ // Deneb difference.
ExecutionPayload: &enginev1.ExecutionPayloadDeneb{
ParentHash: make([]byte, 32),
FeeRecipient: make([]byte, 20),
StateRoot: make([]byte, 32),
ReceiptsRoot: make([]byte, 32),
LogsBloom: make([]byte, 256),
PrevRandao: make([]byte, 32),
ExtraData: make([]byte, 0),
BaseFeePerGas: make([]byte, 32),
BlockHash: make([]byte, 32),
Transactions: make([][]byte, 0),
Withdrawals: make([]*enginev1.Withdrawal, 0),
},
BlsToExecutionChanges: make([]*ethpb.SignedBLSToExecutionChange, 0),
BlobKzgCommitments: make([][]byte, 0),
},
},
Signature: params.BeaconConfig().EmptySignature[:],
})
case *ethpb.BeaconStateElectra:
return blocks.NewSignedBeaconBlock(&ethpb.SignedBeaconBlockElectra{
Block: &ethpb.BeaconBlockElectra{
ParentRoot: params.BeaconConfig().ZeroHash[:],
StateRoot: root[:],
Body: &ethpb.BeaconBlockBodyElectra{
RandaoReveal: make([]byte, 96),
Eth1Data: &ethpb.Eth1Data{
DepositRoot: make([]byte, 32),
BlockHash: make([]byte, 32),
},
Graffiti: make([]byte, 32),
SyncAggregate: &ethpb.SyncAggregate{
SyncCommitteeBits: make([]byte, fieldparams.SyncCommitteeLength/8),
SyncCommitteeSignature: make([]byte, fieldparams.BLSSignatureLength),
},
ExecutionPayload: &enginev1.ExecutionPayloadElectra{
ParentHash: make([]byte, 32),
FeeRecipient: make([]byte, 20),
StateRoot: make([]byte, 32),

View File

@@ -192,11 +192,11 @@ func createAttestationSignatureBatch(
descs := make([]string, len(atts))
for i, a := range atts {
sigs[i] = a.GetSignature()
c, err := helpers.BeaconCommitteeFromState(ctx, beaconState, a.GetData().Slot, a.GetData().CommitteeIndex)
committees, err := helpers.AttestationCommittees(ctx, beaconState, a)
if err != nil {
return nil, err
}
ia, err := attestation.ConvertToIndexed(ctx, a, c)
ia, err := attestation.ConvertToIndexed(ctx, a, committees...)
if err != nil {
return nil, err
}

View File

@@ -22,6 +22,7 @@ go_library(
"//beacon-chain/core/helpers:go_default_library",
"//beacon-chain/core/signing:go_default_library",
"//beacon-chain/core/time:go_default_library",
"//beacon-chain/core/validators:go_default_library",
"//beacon-chain/state:go_default_library",
"//beacon-chain/state/state-native:go_default_library",
"//config/params:go_default_library",
@@ -32,7 +33,9 @@ go_library(
"//proto/engine/v1:go_default_library",
"//proto/prysm/v1alpha1:go_default_library",
"//time/slots:go_default_library",
"@com_github_ethereum_go_ethereum//common/hexutil:go_default_library",
"@com_github_pkg_errors//:go_default_library",
"@com_github_sirupsen_logrus//:go_default_library",
"@io_opencensus_go//trace:go_default_library",
],
)
@@ -43,8 +46,10 @@ go_test(
"churn_test.go",
"consolidations_test.go",
"deposits_test.go",
"effective_balance_updates_test.go",
"upgrade_test.go",
"validator_test.go",
"withdrawals_test.go",
],
deps = [
":go_default_library",
@@ -62,8 +67,12 @@ go_test(
"//proto/engine/v1:go_default_library",
"//proto/prysm/v1alpha1:go_default_library",
"//runtime/interop:go_default_library",
"//testing/assert:go_default_library",
"//testing/require:go_default_library",
"//testing/util:go_default_library",
"//time/slots:go_default_library",
"@com_github_ethereum_go_ethereum//common/hexutil:go_default_library",
"@com_github_sirupsen_logrus//:go_default_library",
"@com_github_sirupsen_logrus//hooks/test:go_default_library",
],
)

View File

@@ -1,6 +1,13 @@
package electra
import "github.com/prysmaticlabs/prysm/v5/beacon-chain/state"
import (
"fmt"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/helpers"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/state"
"github.com/prysmaticlabs/prysm/v5/config/params"
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
)
// ProcessEffectiveBalanceUpdates processes effective balance updates during epoch processing.
//
@@ -24,6 +31,35 @@ import "github.com/prysmaticlabs/prysm/v5/beacon-chain/state"
// ):
// validator.effective_balance = min(balance - balance % EFFECTIVE_BALANCE_INCREMENT, EFFECTIVE_BALANCE_LIMIT)
func ProcessEffectiveBalanceUpdates(state state.BeaconState) error {
// TODO: replace with real implementation
return nil
effBalanceInc := params.BeaconConfig().EffectiveBalanceIncrement
hysteresisInc := effBalanceInc / params.BeaconConfig().HysteresisQuotient
downwardThreshold := hysteresisInc * params.BeaconConfig().HysteresisDownwardMultiplier
upwardThreshold := hysteresisInc * params.BeaconConfig().HysteresisUpwardMultiplier
bals := state.Balances()
// Update effective balances with hysteresis.
validatorFunc := func(idx int, val *ethpb.Validator) (bool, *ethpb.Validator, error) {
if val == nil {
return false, nil, fmt.Errorf("validator %d is nil in state", idx)
}
if idx >= len(bals) {
return false, nil, fmt.Errorf("validator index exceeds validator length in state %d >= %d", idx, len(state.Balances()))
}
balance := bals[idx]
effectiveBalanceLimit := params.BeaconConfig().MinActivationBalance
if helpers.HasCompoundingWithdrawalCredential(val) {
effectiveBalanceLimit = params.BeaconConfig().MaxEffectiveBalanceElectra
}
if balance+downwardThreshold < val.EffectiveBalance || val.EffectiveBalance+upwardThreshold < balance {
effectiveBal := min(balance-balance%effBalanceInc, effectiveBalanceLimit)
val.EffectiveBalance = effectiveBal
return false, val, nil
}
return false, val, nil
}
return state.ApplyToEveryValidator(validatorFunc)
}

View File

@@ -0,0 +1,144 @@
package electra_test
import (
"testing"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/electra"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/state"
state_native "github.com/prysmaticlabs/prysm/v5/beacon-chain/state/state-native"
"github.com/prysmaticlabs/prysm/v5/config/params"
eth "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v5/testing/require"
)
func TestProcessEffectiveBalnceUpdates(t *testing.T) {
effBalanceInc := params.BeaconConfig().EffectiveBalanceIncrement
hysteresisInc := effBalanceInc / params.BeaconConfig().HysteresisQuotient
downwardThreshold := hysteresisInc * params.BeaconConfig().HysteresisDownwardMultiplier
upwardThreshold := hysteresisInc * params.BeaconConfig().HysteresisUpwardMultiplier
tests := []struct {
name string
state state.BeaconState
wantErr bool
check func(*testing.T, state.BeaconState)
}{
{
name: "validator with compounding withdrawal credentials updates effective balance",
state: func() state.BeaconState {
pb := &eth.BeaconStateElectra{
Validators: []*eth.Validator{
{
EffectiveBalance: params.BeaconConfig().MinActivationBalance,
WithdrawalCredentials: []byte{params.BeaconConfig().CompoundingWithdrawalPrefixByte, 0x11},
},
},
Balances: []uint64{
params.BeaconConfig().MaxEffectiveBalanceElectra * 2,
},
}
st, err := state_native.InitializeFromProtoElectra(pb)
require.NoError(t, err)
return st
}(),
check: func(t *testing.T, bs state.BeaconState) {
val, err := bs.ValidatorAtIndex(0)
require.NoError(t, err)
require.Equal(t, params.BeaconConfig().MaxEffectiveBalanceElectra, val.EffectiveBalance)
},
},
{
name: "validator without compounding withdrawal credentials updates effective balance",
state: func() state.BeaconState {
pb := &eth.BeaconStateElectra{
Validators: []*eth.Validator{
{
EffectiveBalance: params.BeaconConfig().MinActivationBalance / 2,
WithdrawalCredentials: nil,
},
},
Balances: []uint64{
params.BeaconConfig().MaxEffectiveBalanceElectra,
},
}
st, err := state_native.InitializeFromProtoElectra(pb)
require.NoError(t, err)
return st
}(),
check: func(t *testing.T, bs state.BeaconState) {
val, err := bs.ValidatorAtIndex(0)
require.NoError(t, err)
require.Equal(t, params.BeaconConfig().MinActivationBalance, val.EffectiveBalance)
},
},
{
name: "validator effective balance moves only when outside of threshold",
state: func() state.BeaconState {
pb := &eth.BeaconStateElectra{
Validators: []*eth.Validator{
{
EffectiveBalance: params.BeaconConfig().MinActivationBalance,
WithdrawalCredentials: []byte{params.BeaconConfig().CompoundingWithdrawalPrefixByte, 0x11},
},
{
EffectiveBalance: params.BeaconConfig().MinActivationBalance,
WithdrawalCredentials: []byte{params.BeaconConfig().CompoundingWithdrawalPrefixByte, 0x11},
},
{
EffectiveBalance: params.BeaconConfig().MinActivationBalance,
WithdrawalCredentials: []byte{params.BeaconConfig().CompoundingWithdrawalPrefixByte, 0x11},
},
{
EffectiveBalance: params.BeaconConfig().MinActivationBalance,
WithdrawalCredentials: []byte{params.BeaconConfig().CompoundingWithdrawalPrefixByte, 0x11},
},
},
Balances: []uint64{
params.BeaconConfig().MinActivationBalance - downwardThreshold - 1, // beyond downward threshold
params.BeaconConfig().MinActivationBalance - downwardThreshold + 1, // within downward threshold
params.BeaconConfig().MinActivationBalance + upwardThreshold + 1, // beyond upward threshold
params.BeaconConfig().MinActivationBalance + upwardThreshold - 1, // within upward threshold
},
}
st, err := state_native.InitializeFromProtoElectra(pb)
require.NoError(t, err)
return st
}(),
check: func(t *testing.T, bs state.BeaconState) {
// validator 0 has a balance diff exceeding the threshold so a diff should be applied to
// effective balance and it moves by effective balance increment.
val, err := bs.ValidatorAtIndex(0)
require.NoError(t, err)
require.Equal(t, params.BeaconConfig().MinActivationBalance-params.BeaconConfig().EffectiveBalanceIncrement, val.EffectiveBalance)
// validator 1 has a balance diff within the threshold so the effective balance should not
// have changed.
val, err = bs.ValidatorAtIndex(1)
require.NoError(t, err)
require.Equal(t, params.BeaconConfig().MinActivationBalance, val.EffectiveBalance)
// Validator 2 has a balance diff exceeding the threshold so a diff should be applied to the
// effective balance and it moves by effective balance increment.
val, err = bs.ValidatorAtIndex(2)
require.NoError(t, err)
require.Equal(t, params.BeaconConfig().MinActivationBalance+params.BeaconConfig().EffectiveBalanceIncrement, val.EffectiveBalance)
// Validator 3 has a balance diff within the threshold so the effective balance should not
// have changed.
val, err = bs.ValidatorAtIndex(3)
require.NoError(t, err)
require.Equal(t, params.BeaconConfig().MinActivationBalance, val.EffectiveBalance)
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := electra.ProcessEffectiveBalanceUpdates(tt.state)
require.Equal(t, tt.wantErr, err != nil, "unexpected error returned wanted error=nil (%s), got error=%s", tt.wantErr, err)
if tt.check != nil {
tt.check(t, tt.state)
}
})
}
}

View File

@@ -46,80 +46,84 @@ var (
// process_effective_balance_updates(state)
// process_slashings_reset(state)
// process_randao_mixes_reset(state)
func ProcessEpoch(ctx context.Context, state state.BeaconState) (state.BeaconState, error) {
func ProcessEpoch(ctx context.Context, state state.BeaconState) error {
_, span := trace.StartSpan(ctx, "electra.ProcessEpoch")
defer span.End()
if state == nil || state.IsNil() {
return nil, errors.New("nil state")
return errors.New("nil state")
}
vp, bp, err := InitializePrecomputeValidators(ctx, state)
if err != nil {
return nil, err
return err
}
vp, bp, err = ProcessEpochParticipation(ctx, state, bp, vp)
if err != nil {
return nil, err
return err
}
state, err = precompute.ProcessJustificationAndFinalizationPreCompute(state, bp)
if err != nil {
return nil, errors.Wrap(err, "could not process justification")
return errors.Wrap(err, "could not process justification")
}
state, vp, err = ProcessInactivityScores(ctx, state, vp)
if err != nil {
return nil, errors.Wrap(err, "could not process inactivity updates")
return errors.Wrap(err, "could not process inactivity updates")
}
state, err = ProcessRewardsAndPenaltiesPrecompute(state, bp, vp)
if err != nil {
return nil, errors.Wrap(err, "could not process rewards and penalties")
return errors.Wrap(err, "could not process rewards and penalties")
}
state, err = ProcessRegistryUpdates(ctx, state)
if err != nil {
return nil, errors.Wrap(err, "could not process registry updates")
return errors.Wrap(err, "could not process registry updates")
}
proportionalSlashingMultiplier, err := state.ProportionalSlashingMultiplier()
if err != nil {
return nil, err
return err
}
state, err = ProcessSlashings(state, proportionalSlashingMultiplier)
if err != nil {
return nil, err
return err
}
state, err = ProcessEth1DataReset(state)
if err != nil {
return nil, err
return err
}
if err = ProcessPendingBalanceDeposits(ctx, state, primitives.Gwei(bp.ActiveCurrentEpoch)); err != nil {
return nil, err
return err
}
if err := ProcessPendingConsolidations(ctx, state); err != nil {
return nil, err
if err = ProcessPendingConsolidations(ctx, state); err != nil {
return err
}
if err := ProcessEffectiveBalanceUpdates(state); err != nil {
return nil, err
if err = ProcessEffectiveBalanceUpdates(state); err != nil {
return err
}
state, err = ProcessSlashingsReset(state)
if err != nil {
return nil, err
return err
}
state, err = ProcessRandaoMixesReset(state)
if err != nil {
return nil, err
return err
}
state, err = ProcessHistoricalDataUpdate(state)
if err != nil {
return nil, err
return err
}
state, err = ProcessParticipationFlagUpdates(state)
if err != nil {
return nil, err
return err
}
state, err = ProcessSyncCommitteeUpdates(ctx, state)
_, err = ProcessSyncCommitteeUpdates(ctx, state)
if err != nil {
return nil, err
return err
}
return state, nil
return nil
}

View File

@@ -1,13 +1,25 @@
package electra
import (
"bytes"
"context"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/helpers"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/validators"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/state"
"github.com/prysmaticlabs/prysm/v5/config/params"
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
"github.com/prysmaticlabs/prysm/v5/encoding/bytesutil"
enginev1 "github.com/prysmaticlabs/prysm/v5/proto/engine/v1"
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v5/time/slots"
log "github.com/sirupsen/logrus"
"go.opencensus.io/trace"
)
// ProcessExecutionLayerWithdrawRequests processes the validator withdrawals from the provided execution payload
// ProcessExecutionLayerWithdrawalRequests processes the validator withdrawals from the provided execution payload
// into the beacon state triggered by the execution layer.
//
// Spec pseudocode definition:
@@ -74,7 +86,109 @@ import (
// amount=to_withdraw,
// withdrawable_epoch=withdrawable_epoch,
// ))
func ProcessExecutionLayerWithdrawRequests(ctx context.Context, st state.BeaconState, wrs []*enginev1.ExecutionLayerWithdrawalRequest) (state.BeaconState, error) {
//TODO: replace with real implementation
func ProcessExecutionLayerWithdrawalRequests(ctx context.Context, st state.BeaconState, wrs []*enginev1.ExecutionLayerWithdrawalRequest) (state.BeaconState, error) {
ctx, span := trace.StartSpan(ctx, "electra.ProcessExecutionLayerWithdrawalRequests")
defer span.End()
currentEpoch := slots.ToEpoch(st.Slot())
for _, wr := range wrs {
if wr == nil {
return nil, errors.New("nil execution layer withdrawal request")
}
amount := wr.Amount
isFullExitRequest := amount == params.BeaconConfig().FullExitRequestAmount
// If partial withdrawal queue is full, only full exits are processed
if n, err := st.NumPendingPartialWithdrawals(); err != nil {
return nil, err
} else if n == params.BeaconConfig().PendingPartialWithdrawalsLimit && !isFullExitRequest {
// if the PendingPartialWithdrawalsLimit is met, the user would have paid for a partial withdrawal that's not included
log.Debugln("Skipping execution layer withdrawal request, PendingPartialWithdrawalsLimit reached")
continue
}
vIdx, exists := st.ValidatorIndexByPubkey(bytesutil.ToBytes48(wr.ValidatorPubkey))
if !exists {
log.Debugf("Skipping execution layer withdrawal request, validator index for %s not found\n", hexutil.Encode(wr.ValidatorPubkey))
continue
}
validator, err := st.ValidatorAtIndex(vIdx)
if err != nil {
return nil, err
}
// Verify withdrawal credentials
hasCorrectCredential := helpers.HasExecutionWithdrawalCredentials(validator)
isCorrectSourceAddress := bytes.Equal(validator.WithdrawalCredentials[12:], wr.SourceAddress)
if !hasCorrectCredential || !isCorrectSourceAddress {
log.Debugln("Skipping execution layer withdrawal request, wrong withdrawal credentials")
continue
}
// Verify the validator is active.
if !helpers.IsActiveValidator(validator, currentEpoch) {
log.Debugln("Skipping execution layer withdrawal request, validator not active")
continue
}
// Verify the validator has not yet submitted an exit.
if validator.ExitEpoch != params.BeaconConfig().FarFutureEpoch {
log.Debugln("Skipping execution layer withdrawal request, validator has submitted an exit already")
continue
}
// Verify the validator has been active long enough.
if currentEpoch < validator.ActivationEpoch.AddEpoch(params.BeaconConfig().ShardCommitteePeriod) {
log.Debugln("Skipping execution layer withdrawal request, validator has not been active long enough")
continue
}
pendingBalanceToWithdraw, err := st.PendingBalanceToWithdraw(vIdx)
if err != nil {
return nil, err
}
if isFullExitRequest {
// Only exit validator if it has no pending withdrawals in the queue
if pendingBalanceToWithdraw == 0 {
maxExitEpoch, churn := validators.MaxExitEpochAndChurn(st)
var err error
st, _, err = validators.InitiateValidatorExit(ctx, st, vIdx, maxExitEpoch, churn)
if err != nil {
return nil, err
}
}
continue
}
hasSufficientEffectiveBalance := validator.EffectiveBalance >= params.BeaconConfig().MinActivationBalance
vBal, err := st.BalanceAtIndex(vIdx)
if err != nil {
return nil, err
}
hasExcessBalance := vBal > params.BeaconConfig().MinActivationBalance+pendingBalanceToWithdraw
// Only allow partial withdrawals with compounding withdrawal credentials
if helpers.HasCompoundingWithdrawalCredential(validator) && hasSufficientEffectiveBalance && hasExcessBalance {
// Spec definition:
// to_withdraw = min(
// state.balances[index] - MIN_ACTIVATION_BALANCE - pending_balance_to_withdraw,
// amount
// )
// note: you can safely subtract these values because haxExcessBalance is checked
toWithdraw := min(vBal-params.BeaconConfig().MinActivationBalance-pendingBalanceToWithdraw, amount)
exitQueueEpoch, err := st.ExitEpochAndUpdateChurn(primitives.Gwei(toWithdraw))
if err != nil {
return nil, err
}
// safe add the uint64 to avoid overflow
withdrawableEpoch, err := exitQueueEpoch.SafeAddEpoch(params.BeaconConfig().MinValidatorWithdrawabilityDelay)
if err != nil {
return nil, errors.Wrap(err, "failed to add withdrawability delay to exit queue epoch")
}
if err := st.AppendPendingPartialWithdrawal(&ethpb.PendingPartialWithdrawal{
Index: vIdx,
Amount: toWithdraw,
WithdrawableEpoch: withdrawableEpoch,
}); err != nil {
return nil, err
}
}
}
return st, nil
}

View File

@@ -0,0 +1,295 @@
package electra_test
import (
"context"
"testing"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/electra"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/state"
"github.com/prysmaticlabs/prysm/v5/config/params"
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
"github.com/prysmaticlabs/prysm/v5/encoding/bytesutil"
enginev1 "github.com/prysmaticlabs/prysm/v5/proto/engine/v1"
eth "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v5/testing/assert"
"github.com/prysmaticlabs/prysm/v5/testing/require"
"github.com/prysmaticlabs/prysm/v5/testing/util"
"github.com/sirupsen/logrus"
"github.com/sirupsen/logrus/hooks/test"
)
func TestProcessExecutionLayerWithdrawRequests(t *testing.T) {
logHook := test.NewGlobal()
source, err := hexutil.Decode("0xb20a608c624Ca5003905aA834De7156C68b2E1d0")
require.NoError(t, err)
st, _ := util.DeterministicGenesisStateElectra(t, 1)
currentSlot := primitives.Slot(uint64(params.BeaconConfig().SlotsPerEpoch)*uint64(params.BeaconConfig().ShardCommitteePeriod) + 1)
require.NoError(t, st.SetSlot(currentSlot))
val, err := st.ValidatorAtIndex(0)
require.NoError(t, err)
type args struct {
st state.BeaconState
wrs []*enginev1.ExecutionLayerWithdrawalRequest
}
tests := []struct {
name string
args args
wantFn func(t *testing.T, got state.BeaconState)
wantErr bool
}{
{
name: "happy path exit and withdrawal only",
args: args{
st: func() state.BeaconState {
preSt := st.Copy()
require.NoError(t, preSt.AppendPendingPartialWithdrawal(&eth.PendingPartialWithdrawal{
Index: 0,
Amount: params.BeaconConfig().FullExitRequestAmount,
WithdrawableEpoch: 0,
}))
v, err := preSt.ValidatorAtIndex(0)
require.NoError(t, err)
prefix := make([]byte, 12)
prefix[0] = params.BeaconConfig().ETH1AddressWithdrawalPrefixByte
v.WithdrawalCredentials = append(prefix, source...)
require.NoError(t, preSt.SetValidators([]*eth.Validator{v}))
return preSt
}(),
wrs: []*enginev1.ExecutionLayerWithdrawalRequest{
{
SourceAddress: source,
ValidatorPubkey: bytesutil.SafeCopyBytes(val.PublicKey),
Amount: params.BeaconConfig().FullExitRequestAmount,
},
},
},
wantFn: func(t *testing.T, got state.BeaconState) {
wantPostSt := st.Copy()
v, err := wantPostSt.ValidatorAtIndex(0)
require.NoError(t, err)
prefix := make([]byte, 12)
prefix[0] = params.BeaconConfig().ETH1AddressWithdrawalPrefixByte
v.WithdrawalCredentials = append(prefix, source...)
v.ExitEpoch = 261
v.WithdrawableEpoch = 517
require.NoError(t, wantPostSt.SetValidators([]*eth.Validator{v}))
require.NoError(t, wantPostSt.AppendPendingPartialWithdrawal(&eth.PendingPartialWithdrawal{
Index: 0,
Amount: params.BeaconConfig().FullExitRequestAmount,
WithdrawableEpoch: 0,
}))
_, err = wantPostSt.ExitEpochAndUpdateChurn(primitives.Gwei(v.EffectiveBalance))
require.NoError(t, err)
require.DeepEqual(t, wantPostSt.Validators(), got.Validators())
webc, err := wantPostSt.ExitBalanceToConsume()
require.NoError(t, err)
gebc, err := got.ExitBalanceToConsume()
require.NoError(t, err)
require.DeepEqual(t, webc, gebc)
weee, err := wantPostSt.EarliestExitEpoch()
require.NoError(t, err)
geee, err := got.EarliestExitEpoch()
require.NoError(t, err)
require.DeepEqual(t, weee, geee)
},
},
{
name: "happy path has compounding",
args: args{
st: func() state.BeaconState {
preSt := st.Copy()
require.NoError(t, preSt.AppendPendingPartialWithdrawal(&eth.PendingPartialWithdrawal{
Index: 0,
Amount: params.BeaconConfig().FullExitRequestAmount,
WithdrawableEpoch: 0,
}))
v, err := preSt.ValidatorAtIndex(0)
require.NoError(t, err)
prefix := make([]byte, 12)
prefix[0] = params.BeaconConfig().CompoundingWithdrawalPrefixByte
v.WithdrawalCredentials = append(prefix, source...)
require.NoError(t, preSt.SetValidators([]*eth.Validator{v}))
bal, err := preSt.BalanceAtIndex(0)
require.NoError(t, err)
bal += 200
require.NoError(t, preSt.SetBalances([]uint64{bal}))
require.NoError(t, preSt.AppendPendingPartialWithdrawal(&eth.PendingPartialWithdrawal{
Index: 0,
Amount: 100,
WithdrawableEpoch: 0,
}))
return preSt
}(),
wrs: []*enginev1.ExecutionLayerWithdrawalRequest{
{
SourceAddress: source,
ValidatorPubkey: bytesutil.SafeCopyBytes(val.PublicKey),
Amount: 100,
},
},
},
wantFn: func(t *testing.T, got state.BeaconState) {
wantPostSt := st.Copy()
v, err := wantPostSt.ValidatorAtIndex(0)
require.NoError(t, err)
prefix := make([]byte, 12)
prefix[0] = params.BeaconConfig().CompoundingWithdrawalPrefixByte
v.WithdrawalCredentials = append(prefix, source...)
require.NoError(t, wantPostSt.SetValidators([]*eth.Validator{v}))
bal, err := wantPostSt.BalanceAtIndex(0)
require.NoError(t, err)
bal += 200
require.NoError(t, wantPostSt.SetBalances([]uint64{bal}))
require.NoError(t, wantPostSt.AppendPendingPartialWithdrawal(&eth.PendingPartialWithdrawal{
Index: 0,
Amount: 0,
WithdrawableEpoch: 0,
}))
require.NoError(t, wantPostSt.AppendPendingPartialWithdrawal(&eth.PendingPartialWithdrawal{
Index: 0,
Amount: 100,
WithdrawableEpoch: 0,
}))
require.NoError(t, wantPostSt.AppendPendingPartialWithdrawal(&eth.PendingPartialWithdrawal{
Index: 0,
Amount: 100,
WithdrawableEpoch: 517,
}))
wnppw, err := wantPostSt.NumPendingPartialWithdrawals()
require.NoError(t, err)
gnppw, err := got.NumPendingPartialWithdrawals()
require.NoError(t, err)
require.Equal(t, wnppw, gnppw)
wece, err := wantPostSt.EarliestConsolidationEpoch()
require.NoError(t, err)
gece, err := got.EarliestConsolidationEpoch()
require.NoError(t, err)
require.Equal(t, wece, gece)
_, err = wantPostSt.ExitEpochAndUpdateChurn(primitives.Gwei(100))
require.NoError(t, err)
require.DeepEqual(t, wantPostSt.Validators(), got.Validators())
webc, err := wantPostSt.ExitBalanceToConsume()
require.NoError(t, err)
gebc, err := got.ExitBalanceToConsume()
require.NoError(t, err)
require.DeepEqual(t, webc, gebc)
},
},
{
name: "validator already submitted exit",
args: args{
st: func() state.BeaconState {
preSt := st.Copy()
v, err := preSt.ValidatorAtIndex(0)
require.NoError(t, err)
prefix := make([]byte, 12)
prefix[0] = params.BeaconConfig().ETH1AddressWithdrawalPrefixByte
v.WithdrawalCredentials = append(prefix, source...)
v.ExitEpoch = 1000
require.NoError(t, preSt.SetValidators([]*eth.Validator{v}))
return preSt
}(),
wrs: []*enginev1.ExecutionLayerWithdrawalRequest{
{
SourceAddress: source,
ValidatorPubkey: bytesutil.SafeCopyBytes(val.PublicKey),
Amount: params.BeaconConfig().FullExitRequestAmount,
},
},
},
wantFn: func(t *testing.T, got state.BeaconState) {
wantPostSt := st.Copy()
v, err := wantPostSt.ValidatorAtIndex(0)
require.NoError(t, err)
prefix := make([]byte, 12)
prefix[0] = params.BeaconConfig().ETH1AddressWithdrawalPrefixByte
v.WithdrawalCredentials = append(prefix, source...)
v.ExitEpoch = 1000
require.NoError(t, wantPostSt.SetValidators([]*eth.Validator{v}))
eee, err := got.EarliestExitEpoch()
require.NoError(t, err)
require.Equal(t, eee, primitives.Epoch(0))
require.DeepEqual(t, wantPostSt.Validators(), got.Validators())
},
},
{
name: "validator too new",
args: args{
st: func() state.BeaconState {
preSt := st.Copy()
require.NoError(t, preSt.SetSlot(0))
v, err := preSt.ValidatorAtIndex(0)
require.NoError(t, err)
prefix := make([]byte, 12)
prefix[0] = params.BeaconConfig().ETH1AddressWithdrawalPrefixByte
v.WithdrawalCredentials = append(prefix, source...)
require.NoError(t, preSt.SetValidators([]*eth.Validator{v}))
return preSt
}(),
wrs: []*enginev1.ExecutionLayerWithdrawalRequest{
{
SourceAddress: source,
ValidatorPubkey: bytesutil.SafeCopyBytes(val.PublicKey),
Amount: params.BeaconConfig().FullExitRequestAmount,
},
},
},
wantFn: func(t *testing.T, got state.BeaconState) {
wantPostSt := st.Copy()
require.NoError(t, wantPostSt.SetSlot(0))
v, err := wantPostSt.ValidatorAtIndex(0)
require.NoError(t, err)
prefix := make([]byte, 12)
prefix[0] = params.BeaconConfig().ETH1AddressWithdrawalPrefixByte
v.WithdrawalCredentials = append(prefix, source...)
require.NoError(t, wantPostSt.SetValidators([]*eth.Validator{v}))
eee, err := got.EarliestExitEpoch()
require.NoError(t, err)
require.Equal(t, eee, primitives.Epoch(0))
require.DeepEqual(t, wantPostSt.Validators(), got.Validators())
},
},
{
name: "PendingPartialWithdrawalsLimit reached with partial withdrawal results in a skip",
args: args{
st: func() state.BeaconState {
cfg := params.BeaconConfig().Copy()
cfg.PendingPartialWithdrawalsLimit = 1
params.OverrideBeaconConfig(cfg)
logrus.SetLevel(logrus.DebugLevel)
preSt := st.Copy()
require.NoError(t, preSt.AppendPendingPartialWithdrawal(&eth.PendingPartialWithdrawal{
Index: 0,
Amount: params.BeaconConfig().FullExitRequestAmount,
WithdrawableEpoch: 0,
}))
return preSt
}(),
wrs: []*enginev1.ExecutionLayerWithdrawalRequest{
{
SourceAddress: source,
ValidatorPubkey: bytesutil.SafeCopyBytes(val.PublicKey),
Amount: 100,
},
},
},
wantFn: func(t *testing.T, got state.BeaconState) {
assert.LogsContain(t, logHook, "Skipping execution layer withdrawal request, PendingPartialWithdrawalsLimit reached")
params.SetupTestConfigCleanup(t)
logrus.SetLevel(logrus.InfoLevel) // reset
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := electra.ProcessExecutionLayerWithdrawalRequests(context.Background(), tt.args.st, tt.args.wrs)
if (err != nil) != tt.wantErr {
t.Errorf("ProcessExecutionLayerWithdrawalRequests() error = %v, wantErr %v", err, tt.wantErr)
return
}
tt.wantFn(t, got)
})
}
}

View File

@@ -470,7 +470,7 @@ func UnslashedAttestingIndices(ctx context.Context, state state.ReadOnlyBeaconSt
seen := make(map[uint64]bool)
for _, att := range atts {
committee, err := helpers.BeaconCommitteeFromState(ctx, state, att.Data.Slot, att.Data.CommitteeIndex)
committee, err := helpers.BeaconCommitteeFromState(ctx, state, att.GetData().Slot, att.GetData().CommitteeIndex)
if err != nil {
return nil, err
}

View File

@@ -34,6 +34,7 @@ go_library(
"//encoding/bytesutil:go_default_library",
"//math:go_default_library",
"//proto/prysm/v1alpha1:go_default_library",
"//runtime/version:go_default_library",
"//time:go_default_library",
"//time/slots:go_default_library",
"@com_github_pkg_errors//:go_default_library",

View File

@@ -21,6 +21,7 @@ import (
"github.com/prysmaticlabs/prysm/v5/encoding/bytesutil"
"github.com/prysmaticlabs/prysm/v5/math"
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v5/runtime/version"
"github.com/prysmaticlabs/prysm/v5/time/slots"
)
@@ -58,6 +59,29 @@ func SlotCommitteeCount(activeValidatorCount uint64) uint64 {
return committeesPerSlot
}
// AttestationCommittees returns beacon state committees that reflect attestation's committee indices.
func AttestationCommittees(ctx context.Context, st state.ReadOnlyBeaconState, att ethpb.Att) ([][]primitives.ValidatorIndex, error) {
var committees [][]primitives.ValidatorIndex
if att.Version() >= version.Electra {
committeeIndices := att.CommitteeBitsVal().BitIndices()
committees = make([][]primitives.ValidatorIndex, len(committeeIndices))
for i, ci := range committeeIndices {
committee, err := BeaconCommitteeFromState(ctx, st, att.GetData().Slot, primitives.CommitteeIndex(ci))
if err != nil {
return nil, err
}
committees[i] = committee
}
} else {
committee, err := BeaconCommitteeFromState(ctx, st, att.GetData().Slot, att.GetData().CommitteeIndex)
if err != nil {
return nil, err
}
committees = [][]primitives.ValidatorIndex{committee}
}
return committees, nil
}
// BeaconCommitteeFromState returns the crosslink committee of a given slot and committee index. This
// is a spec implementation where state is used as an argument. In case of state retrieval
// becomes expensive, consider using BeaconCommittee below.
@@ -143,105 +167,137 @@ func BeaconCommittee(
return ComputeCommittee(validatorIndices, seed, indexOffset, count)
}
// CommitteeAssignmentContainer represents a committee list, committee index, and to be attested slot for a given epoch.
type CommitteeAssignmentContainer struct {
// CommitteeAssignment represents committee list, committee index, and to be attested slot for a given epoch.
type CommitteeAssignment struct {
Committee []primitives.ValidatorIndex
AttesterSlot primitives.Slot
CommitteeIndex primitives.CommitteeIndex
}
// CommitteeAssignments is a map of validator indices pointing to the appropriate committee
// assignment for the given epoch.
//
// 1. Determine the proposer validator index for each slot.
// 2. Compute all committees.
// 3. Determine the attesting slot for each committee.
// 4. Construct a map of validator indices pointing to the respective committees.
func CommitteeAssignments(
ctx context.Context,
state state.BeaconState,
epoch primitives.Epoch,
) (map[primitives.ValidatorIndex]*CommitteeAssignmentContainer, map[primitives.ValidatorIndex][]primitives.Slot, error) {
// verifyAssignmentEpoch verifies if the given epoch is valid for assignment based on the provided state.
// It checks if the epoch is not greater than the next epoch, and if the start slot of the epoch is greater
// than or equal to the minimum valid start slot calculated based on the state's current slot and historical roots.
func verifyAssignmentEpoch(epoch primitives.Epoch, state state.BeaconState) error {
nextEpoch := time.NextEpoch(state)
if epoch > nextEpoch {
return nil, nil, fmt.Errorf(
"epoch %d can't be greater than next epoch %d",
epoch,
nextEpoch,
)
return fmt.Errorf("epoch %d can't be greater than next epoch %d", epoch, nextEpoch)
}
// We determine the slots in which proposers are supposed to act.
// Some validators may need to propose multiple times per epoch, so
// we use a map of proposer idx -> []slot to keep track of this possibility.
startSlot, err := slots.EpochStart(epoch)
if err != nil {
return nil, nil, err
return err
}
minValidStartSlot := primitives.Slot(0)
if state.Slot() >= params.BeaconConfig().SlotsPerHistoricalRoot {
minValidStartSlot = state.Slot() - params.BeaconConfig().SlotsPerHistoricalRoot
if stateSlot := state.Slot(); stateSlot >= params.BeaconConfig().SlotsPerHistoricalRoot {
minValidStartSlot = stateSlot - params.BeaconConfig().SlotsPerHistoricalRoot
}
if startSlot < minValidStartSlot {
return nil, nil, fmt.Errorf("start slot %d is smaller than the minimum valid start slot %d", startSlot, minValidStartSlot)
return fmt.Errorf("start slot %d is smaller than the minimum valid start slot %d", startSlot, minValidStartSlot)
}
return nil
}
// ProposerAssignments calculates proposer assignments for each validator during the specified epoch.
// It verifies the validity of the epoch, then iterates through each slot in the epoch to determine the
// proposer for that slot and assigns them accordingly.
func ProposerAssignments(ctx context.Context, state state.BeaconState, epoch primitives.Epoch) (map[primitives.ValidatorIndex][]primitives.Slot, error) {
// Verify if the epoch is valid for assignment based on the provided state.
if err := verifyAssignmentEpoch(epoch, state); err != nil {
return nil, err
}
startSlot, err := slots.EpochStart(epoch)
if err != nil {
return nil, err
}
proposerIndexToSlots := make(map[primitives.ValidatorIndex][]primitives.Slot, params.BeaconConfig().SlotsPerEpoch)
proposerAssignments := make(map[primitives.ValidatorIndex][]primitives.Slot)
originalStateSlot := state.Slot()
for slot := startSlot; slot < startSlot+params.BeaconConfig().SlotsPerEpoch; slot++ {
// Skip proposer assignment for genesis slot.
if slot == 0 {
continue
}
// Set the state's current slot.
if err := state.SetSlot(slot); err != nil {
return nil, nil, err
return nil, err
}
// Determine the proposer index for the current slot.
i, err := BeaconProposerIndex(ctx, state)
if err != nil {
return nil, nil, errors.Wrapf(err, "could not check proposer at slot %d", state.Slot())
return nil, errors.Wrapf(err, "could not check proposer at slot %d", state.Slot())
}
proposerIndexToSlots[i] = append(proposerIndexToSlots[i], slot)
// Append the slot to the proposer's assignments.
if _, ok := proposerAssignments[i]; !ok {
proposerAssignments[i] = make([]primitives.Slot, 0)
}
proposerAssignments[i] = append(proposerAssignments[i], slot)
}
// If previous proposer indices computation is outside if current proposal epoch range,
// we need to reset state slot back to start slot so that we can compute the correct committees.
currentProposalEpoch := epoch < nextEpoch
if !currentProposalEpoch {
if err := state.SetSlot(state.Slot() - params.BeaconConfig().SlotsPerEpoch); err != nil {
return nil, nil, err
}
// Reset state back to its original slot.
if err := state.SetSlot(originalStateSlot); err != nil {
return nil, err
}
activeValidatorIndices, err := ActiveValidatorIndices(ctx, state, epoch)
return proposerAssignments, nil
}
// CommitteeAssignments calculates committee assignments for each validator during the specified epoch.
// It retrieves active validator indices, determines the number of committees per slot, and computes
// assignments for each validator based on their presence in the provided validators slice.
func CommitteeAssignments(ctx context.Context, state state.BeaconState, epoch primitives.Epoch, validators []primitives.ValidatorIndex) (map[primitives.ValidatorIndex]*CommitteeAssignment, error) {
// Verify if the epoch is valid for assignment based on the provided state.
if err := verifyAssignmentEpoch(epoch, state); err != nil {
return nil, err
}
// Retrieve active validator count for the specified epoch.
activeValidatorCount, err := ActiveValidatorCount(ctx, state, epoch)
if err != nil {
return nil, nil, err
return nil, err
}
// Each slot in an epoch has a different set of committees. This value is derived from the
// active validator set, which does not change.
numCommitteesPerSlot := SlotCommitteeCount(uint64(len(activeValidatorIndices)))
validatorIndexToCommittee := make(map[primitives.ValidatorIndex]*CommitteeAssignmentContainer, len(activeValidatorIndices))
// Compute all committees for all slots.
for i := primitives.Slot(0); i < params.BeaconConfig().SlotsPerEpoch; i++ {
// Compute committees.
// Determine the number of committees per slot based on the number of active validator indices.
numCommitteesPerSlot := SlotCommitteeCount(activeValidatorCount)
startSlot, err := slots.EpochStart(epoch)
if err != nil {
return nil, err
}
assignments := make(map[primitives.ValidatorIndex]*CommitteeAssignment)
vals := make(map[primitives.ValidatorIndex]struct{})
for _, v := range validators {
vals[v] = struct{}{}
}
// Compute committee assignments for each slot in the epoch.
for slot := startSlot; slot < startSlot+params.BeaconConfig().SlotsPerEpoch; slot++ {
// Compute committees for the current slot.
for j := uint64(0); j < numCommitteesPerSlot; j++ {
slot := startSlot + i
committee, err := BeaconCommitteeFromState(ctx, state, slot, primitives.CommitteeIndex(j) /*committee index*/)
committee, err := BeaconCommitteeFromState(ctx, state, slot, primitives.CommitteeIndex(j))
if err != nil {
return nil, nil, err
return nil, err
}
cac := &CommitteeAssignmentContainer{
Committee: committee,
CommitteeIndex: primitives.CommitteeIndex(j),
AttesterSlot: slot,
}
for _, vIndex := range committee {
validatorIndexToCommittee[vIndex] = cac
if _, ok := vals[vIndex]; !ok { // Skip if the validator is not in the provided validators slice.
continue
}
if _, ok := assignments[vIndex]; !ok {
assignments[vIndex] = &CommitteeAssignment{}
}
assignments[vIndex].Committee = committee
assignments[vIndex].AttesterSlot = slot
assignments[vIndex].CommitteeIndex = primitives.CommitteeIndex(j)
}
}
}
return validatorIndexToCommittee, proposerIndexToSlots, nil
return assignments, nil
}
// VerifyBitfieldLength verifies that a bitfield length matches the given committee size.

View File

@@ -104,7 +104,10 @@ func TestCommitteeAssignments_CannotRetrieveFutureEpoch(t *testing.T) {
Slot: 0, // Epoch 0.
})
require.NoError(t, err)
_, _, err = helpers.CommitteeAssignments(context.Background(), state, epoch+1)
_, err = helpers.CommitteeAssignments(context.Background(), state, epoch+1, nil)
assert.ErrorContains(t, "can't be greater than next epoch", err)
_, err = helpers.ProposerAssignments(context.Background(), state, epoch+1)
assert.ErrorContains(t, "can't be greater than next epoch", err)
}
@@ -128,10 +131,10 @@ func TestCommitteeAssignments_NoProposerForSlot0(t *testing.T) {
RandaoMixes: make([][]byte, params.BeaconConfig().EpochsPerHistoricalVector),
})
require.NoError(t, err)
_, proposerIndexToSlots, err := helpers.CommitteeAssignments(context.Background(), state, 0)
require.NoError(t, err, "Failed to determine CommitteeAssignments")
for _, ss := range proposerIndexToSlots {
for _, s := range ss {
assignments, err := helpers.ProposerAssignments(context.Background(), state, 0)
require.NoError(t, err, "Failed to determine Assignments")
for _, slots := range assignments {
for _, s := range slots {
assert.NotEqual(t, uint64(0), s, "No proposer should be assigned to slot 0")
}
}
@@ -140,6 +143,7 @@ func TestCommitteeAssignments_NoProposerForSlot0(t *testing.T) {
func TestCommitteeAssignments_CanRetrieve(t *testing.T) {
// Initialize test with 256 validators, each slot and each index gets 4 validators.
validators := make([]*ethpb.Validator, 4*params.BeaconConfig().SlotsPerEpoch)
validatorIndices := make([]primitives.ValidatorIndex, len(validators))
for i := 0; i < len(validators); i++ {
// First 2 epochs only half validators are activated.
var activationEpoch primitives.Epoch
@@ -150,6 +154,7 @@ func TestCommitteeAssignments_CanRetrieve(t *testing.T) {
ActivationEpoch: activationEpoch,
ExitEpoch: params.BeaconConfig().FarFutureEpoch,
}
validatorIndices[i] = primitives.ValidatorIndex(i)
}
state, err := state_native.InitializeFromProtoPhase0(&ethpb.BeaconState{
@@ -201,14 +206,16 @@ func TestCommitteeAssignments_CanRetrieve(t *testing.T) {
t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
helpers.ClearCache()
validatorIndexToCommittee, proposerIndexToSlots, err := helpers.CommitteeAssignments(context.Background(), state, slots.ToEpoch(tt.slot))
require.NoError(t, err, "Failed to determine CommitteeAssignments")
cac := validatorIndexToCommittee[tt.index]
assignments, err := helpers.CommitteeAssignments(context.Background(), state, slots.ToEpoch(tt.slot), validatorIndices)
require.NoError(t, err, "Failed to determine Assignments")
cac := assignments[tt.index]
assert.Equal(t, tt.committeeIndex, cac.CommitteeIndex, "Unexpected committeeIndex for validator index %d", tt.index)
assert.Equal(t, tt.slot, cac.AttesterSlot, "Unexpected slot for validator index %d", tt.index)
if len(proposerIndexToSlots[tt.index]) > 0 && proposerIndexToSlots[tt.index][0] != tt.proposerSlot {
proposerAssignments, err := helpers.ProposerAssignments(context.Background(), state, slots.ToEpoch(tt.slot))
require.NoError(t, err)
if len(proposerAssignments[tt.index]) > 0 && proposerAssignments[tt.index][0] != tt.proposerSlot {
t.Errorf("wanted proposer slot %d, got proposer slot %d for validator index %d",
tt.proposerSlot, proposerIndexToSlots[tt.index][0], tt.index)
tt.proposerSlot, proposerAssignments[tt.index][0], tt.index)
}
assert.DeepEqual(t, tt.committee, cac.Committee, "Unexpected committee for validator index %d", tt.index)
})
@@ -238,13 +245,13 @@ func TestCommitteeAssignments_CannotRetrieveFuture(t *testing.T) {
RandaoMixes: make([][]byte, params.BeaconConfig().EpochsPerHistoricalVector),
})
require.NoError(t, err)
_, proposerIndxs, err := helpers.CommitteeAssignments(context.Background(), state, time.CurrentEpoch(state))
assignments, err := helpers.ProposerAssignments(context.Background(), state, time.CurrentEpoch(state))
require.NoError(t, err)
require.NotEqual(t, 0, len(proposerIndxs), "wanted non-zero proposer index set")
require.NotEqual(t, 0, len(assignments), "wanted non-zero proposer index set")
_, proposerIndxs, err = helpers.CommitteeAssignments(context.Background(), state, time.CurrentEpoch(state)+1)
assignments, err = helpers.ProposerAssignments(context.Background(), state, time.CurrentEpoch(state)+1)
require.NoError(t, err)
require.NotEqual(t, 0, len(proposerIndxs), "wanted non-zero proposer index set")
require.NotEqual(t, 0, len(assignments), "wanted non-zero proposer index set")
}
func TestCommitteeAssignments_CannotRetrieveOlderThanSlotsPerHistoricalRoot(t *testing.T) {
@@ -264,7 +271,7 @@ func TestCommitteeAssignments_CannotRetrieveOlderThanSlotsPerHistoricalRoot(t *t
RandaoMixes: make([][]byte, params.BeaconConfig().EpochsPerHistoricalVector),
})
require.NoError(t, err)
_, _, err = helpers.CommitteeAssignments(context.Background(), state, 0)
_, err = helpers.CommitteeAssignments(context.Background(), state, 0, nil)
require.ErrorContains(t, "start slot 0 is smaller than the minimum valid start slot 1", err)
}
@@ -286,12 +293,12 @@ func TestCommitteeAssignments_EverySlotHasMin1Proposer(t *testing.T) {
})
require.NoError(t, err)
epoch := primitives.Epoch(1)
_, proposerIndexToSlots, err := helpers.CommitteeAssignments(context.Background(), state, epoch)
require.NoError(t, err, "Failed to determine CommitteeAssignments")
assignments, err := helpers.ProposerAssignments(context.Background(), state, epoch)
require.NoError(t, err, "Failed to determine Assignments")
slotsWithProposers := make(map[primitives.Slot]bool)
for _, proposerSlots := range proposerIndexToSlots {
for _, slot := range proposerSlots {
for _, slots := range assignments {
for _, slot := range slots {
slotsWithProposers[slot] = true
}
}
@@ -708,3 +715,37 @@ func TestCommitteeIndices(t *testing.T) {
indices := helpers.CommitteeIndices(bitfield)
assert.DeepEqual(t, []primitives.CommitteeIndex{0, 1, 3}, indices)
}
func TestAttestationCommittees(t *testing.T) {
validators := make([]*ethpb.Validator, params.BeaconConfig().SlotsPerEpoch.Mul(params.BeaconConfig().TargetCommitteeSize))
for i := 0; i < len(validators); i++ {
validators[i] = &ethpb.Validator{
ExitEpoch: params.BeaconConfig().FarFutureEpoch,
}
}
state, err := state_native.InitializeFromProtoPhase0(&ethpb.BeaconState{
Validators: validators,
RandaoMixes: make([][]byte, params.BeaconConfig().EpochsPerHistoricalVector),
})
require.NoError(t, err)
t.Run("pre-Electra", func(t *testing.T) {
att := &ethpb.Attestation{Data: &ethpb.AttestationData{CommitteeIndex: 0}}
committees, err := helpers.AttestationCommittees(context.Background(), state, att)
require.NoError(t, err)
require.Equal(t, 1, len(committees))
assert.Equal(t, params.BeaconConfig().TargetCommitteeSize, uint64(len(committees[0])))
})
t.Run("post-Electra", func(t *testing.T) {
bits := primitives.NewAttestationCommitteeBits()
bits.SetBitAt(0, true)
bits.SetBitAt(1, true)
att := &ethpb.AttestationElectra{CommitteeBits: bits, Data: &ethpb.AttestationData{}}
committees, err := helpers.AttestationCommittees(context.Background(), state, att)
require.NoError(t, err)
require.Equal(t, 2, len(committees))
assert.Equal(t, params.BeaconConfig().TargetCommitteeSize, uint64(len(committees[0])))
assert.Equal(t, params.BeaconConfig().TargetCommitteeSize, uint64(len(committees[1])))
})
}

View File

@@ -500,11 +500,11 @@ func LastActivatedValidatorIndex(ctx context.Context, st state.ReadOnlyBeaconSta
// hasETH1WithdrawalCredential returns whether the validator has an ETH1
// Withdrawal prefix. It assumes that the caller has a lock on the state
func HasETH1WithdrawalCredential(val *ethpb.Validator) bool {
func HasETH1WithdrawalCredential(val interfaces.WithWithdrawalCredentials) bool {
if val == nil {
return false
}
return isETH1WithdrawalCredential(val.WithdrawalCredentials)
return isETH1WithdrawalCredential(val.GetWithdrawalCredentials())
}
func isETH1WithdrawalCredential(creds []byte) bool {

View File

@@ -226,7 +226,7 @@ func TestProcessEpoch_BadBalanceAltair(t *testing.T) {
epochParticipation[0] = participation
assert.NoError(t, s.SetCurrentParticipationBits(epochParticipation))
assert.NoError(t, s.SetPreviousParticipationBits(epochParticipation))
_, err = altair.ProcessEpoch(context.Background(), s)
err = altair.ProcessEpoch(context.Background(), s)
assert.ErrorContains(t, "addition overflows", err)
}

View File

@@ -216,7 +216,7 @@ func TestProcessEpoch_BadBalanceBellatrix(t *testing.T) {
epochParticipation[0] = participation
assert.NoError(t, s.SetCurrentParticipationBits(epochParticipation))
assert.NoError(t, s.SetPreviousParticipationBits(epochParticipation))
_, err = altair.ProcessEpoch(context.Background(), s)
err = altair.ProcessEpoch(context.Background(), s)
assert.ErrorContains(t, "addition overflows", err)
}

View File

@@ -257,14 +257,12 @@ func ProcessSlots(ctx context.Context, state state.BeaconState, slot primitives.
return nil, errors.Wrap(err, "could not process epoch with optimizations")
}
} else if state.Version() <= version.Deneb {
state, err = altair.ProcessEpoch(ctx, state)
if err != nil {
if err = altair.ProcessEpoch(ctx, state); err != nil {
tracing.AnnotateError(span, err)
return nil, errors.Wrap(err, fmt.Sprintf("could not process %s epoch", version.String(state.Version())))
}
} else {
state, err = electra.ProcessEpoch(ctx, state)
if err != nil {
if err = electra.ProcessEpoch(ctx, state); err != nil {
tracing.AnnotateError(span, err)
return nil, errors.Wrap(err, fmt.Sprintf("could not process %s epoch", version.String(state.Version())))
}

View File

@@ -445,11 +445,12 @@ func electraOperations(
if !ok {
return nil, errors.New("could not cast execution data to electra execution data")
}
st, err = electra.ProcessExecutionLayerWithdrawRequests(ctx, st, exe.WithdrawalRequests())
st, err = electra.ProcessExecutionLayerWithdrawalRequests(ctx, st, exe.WithdrawalRequests())
if err != nil {
return nil, errors.Wrap(err, "could not process execution layer withdrawal requests")
}
st, err = electra.ProcessDepositReceipts(ctx, st, exe.DepositReceipts())
st, err = electra.ProcessDepositReceipts(ctx, st, exe.DepositReceipts()) // TODO: EIP-6110 deposit changes.
if err != nil {
return nil, errors.Wrap(err, "could not process deposit receipts")
}

View File

@@ -92,14 +92,16 @@ func windowMin(latest, offset primitives.Slot) primitives.Slot {
func (p *blobPruner) warmCache() error {
p.Lock()
defer p.Unlock()
defer func() {
if !p.warmed {
p.warmed = true
close(p.cacheReady)
}
p.Unlock()
}()
if err := p.prune(0); err != nil {
return err
}
if !p.warmed {
p.warmed = true
close(p.cacheReady)
}
return nil
}

View File

@@ -2,16 +2,19 @@ package filesystem
import (
"bytes"
"context"
"fmt"
"math"
"os"
"path"
"sort"
"testing"
"time"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/verification"
fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams"
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
"github.com/prysmaticlabs/prysm/v5/encoding/bytesutil"
"github.com/prysmaticlabs/prysm/v5/testing/require"
"github.com/prysmaticlabs/prysm/v5/testing/util"
"github.com/spf13/afero"
@@ -34,6 +37,34 @@ func TestTryPruneDir_CachedNotExpired(t *testing.T) {
require.Equal(t, 0, pruned)
}
func TestCacheWarmFail(t *testing.T) {
fs := afero.NewMemMapFs()
n := blobNamer{root: bytesutil.ToBytes32([]byte("derp")), index: 0}
bp := n.path()
mkdir := path.Dir(bp)
require.NoError(t, fs.MkdirAll(mkdir, directoryPermissions))
// Create an empty blob index in the fs by touching the file at a seemingly valid path.
fi, err := fs.Create(bp)
require.NoError(t, err)
require.NoError(t, fi.Close())
// Cache warm should fail due to the unexpected EOF.
pr, err := newBlobPruner(fs, 0)
require.NoError(t, err)
require.ErrorIs(t, pr.warmCache(), errPruningFailures)
// The cache warm has finished, so calling waitForCache with a super short deadline
// should not block or hit the context deadline.
ctx := context.Background()
ctx, cancel := context.WithDeadline(ctx, time.Now().Add(1*time.Millisecond))
defer cancel()
c, err := pr.waitForCache(ctx)
// We will get an error and a nil value for the cache if we hit the deadline.
require.NoError(t, err)
require.NotNil(t, c)
}
func TestTryPruneDir_CachedExpired(t *testing.T) {
t.Run("empty directory", func(t *testing.T) {
fs := afero.NewMemMapFs()

View File

@@ -16,7 +16,7 @@ go_library(
],
deps = [
"//api/gateway:go_default_library",
"//api/server:go_default_library",
"//api/server/middleware:go_default_library",
"//async/event:go_default_library",
"//beacon-chain/blockchain:go_default_library",
"//beacon-chain/builder:go_default_library",

View File

@@ -20,7 +20,7 @@ import (
"github.com/gorilla/mux"
"github.com/pkg/errors"
apigateway "github.com/prysmaticlabs/prysm/v5/api/gateway"
"github.com/prysmaticlabs/prysm/v5/api/server"
"github.com/prysmaticlabs/prysm/v5/api/server/middleware"
"github.com/prysmaticlabs/prysm/v5/async/event"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/blockchain"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/builder"
@@ -409,8 +409,8 @@ func newRouter(cliCtx *cli.Context) *mux.Router {
allowedOrigins = strings.Split(flags.GPRCGatewayCorsDomain.Value, ",")
}
r := mux.NewRouter()
r.Use(server.NormalizeQueryValuesHandler)
r.Use(server.CorsHandler(allowedOrigins))
r.Use(middleware.NormalizeQueryValuesHandler)
r.Use(middleware.CorsHandler(allowedOrigins))
return r
}

View File

@@ -17,9 +17,9 @@ import (
func validAttesterSlashingForValIdx(t *testing.T, beaconState state.BeaconState, privs []bls.SecretKey, valIdx ...uint64) *ethpb.AttesterSlashing {
var slashings []*ethpb.AttesterSlashing
for _, idx := range valIdx {
slashing, err := util.GenerateAttesterSlashingForValidator(beaconState, privs[idx], primitives.ValidatorIndex(idx))
generatedSlashing, err := util.GenerateAttesterSlashingForValidator(beaconState, privs[idx], primitives.ValidatorIndex(idx))
require.NoError(t, err)
slashings = append(slashings, slashing)
slashings = append(slashings, generatedSlashing.(*ethpb.AttesterSlashing))
}
var allSig1 []bls.Signature
var allSig2 []bls.Signature
@@ -78,12 +78,14 @@ func TestPool_InsertAttesterSlashing(t *testing.T) {
pendingSlashings := make([]*PendingAttesterSlashing, 20)
slashings := make([]*ethpb.AttesterSlashing, 20)
for i := 0; i < len(pendingSlashings); i++ {
sl, err := util.GenerateAttesterSlashingForValidator(beaconState, privKeys[i], primitives.ValidatorIndex(i))
generatedSl, err := util.GenerateAttesterSlashingForValidator(beaconState, privKeys[i], primitives.ValidatorIndex(i))
require.NoError(t, err)
pendingSlashings[i] = &PendingAttesterSlashing{
attesterSlashing: sl,
attesterSlashing: generatedSl,
validatorToSlash: primitives.ValidatorIndex(i),
}
sl, ok := generatedSl.(*ethpb.AttesterSlashing)
require.Equal(t, true, ok, "Attester slashing has the wrong type (expected %T, got %T)", &ethpb.AttesterSlashing{}, generatedSl)
slashings[i] = sl
}
require.NoError(t, beaconState.SetSlot(params.BeaconConfig().SlotsPerEpoch))
@@ -303,12 +305,16 @@ func TestPool_InsertAttesterSlashing_SigFailsVerify_ClearPool(t *testing.T) {
pendingSlashings := make([]*PendingAttesterSlashing, 2)
slashings := make([]*ethpb.AttesterSlashing, 2)
for i := 0; i < 2; i++ {
sl, err := util.GenerateAttesterSlashingForValidator(beaconState, privKeys[i], primitives.ValidatorIndex(i))
generatedSl, err := util.GenerateAttesterSlashingForValidator(beaconState, privKeys[i], primitives.ValidatorIndex(i))
require.NoError(t, err)
pendingSlashings[i] = &PendingAttesterSlashing{
attesterSlashing: sl,
attesterSlashing: generatedSl,
validatorToSlash: primitives.ValidatorIndex(i),
}
sl, ok := generatedSl.(*ethpb.AttesterSlashing)
if !ok {
require.Equal(t, true, ok, "Attester slashing has the wrong type (expected %T, got %T)", &ethpb.AttesterSlashing{}, generatedSl)
}
slashings[i] = sl
}
// We mess up the signature of the second slashing.

View File

@@ -142,7 +142,7 @@ func (s *Service) internalBroadcastAttestation(ctx context.Context, subnet uint6
log.WithFields(logrus.Fields{
"attestationSlot": att.GetData().Slot,
"currentSlot": currSlot,
}).WithError(err).Warning("Attestation is too old to broadcast, discarding it")
}).WithError(err).Debug("Attestation is too old to broadcast, discarding it")
return
}

View File

@@ -4,6 +4,7 @@ import (
"bytes"
"crypto/ecdsa"
"net"
"sync"
"time"
"github.com/ethereum/go-ethereum/p2p/discover"
@@ -15,6 +16,7 @@ import (
"github.com/pkg/errors"
"github.com/prysmaticlabs/go-bitfield"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/cache"
"github.com/prysmaticlabs/prysm/v5/cmd/beacon-chain/flags"
"github.com/prysmaticlabs/prysm/v5/config/features"
"github.com/prysmaticlabs/prysm/v5/config/params"
ecdsaprysm "github.com/prysmaticlabs/prysm/v5/crypto/ecdsa"
@@ -106,7 +108,7 @@ func (s *Service) RefreshENR() {
// listen for new nodes watches for new nodes in the network and adds them to the peerstore.
func (s *Service) listenForNewNodes() {
iterator := enode.Filter(s.dv5Listener.RandomNodes(), s.filterPeer)
iterator := filterNodes(s.ctx, s.dv5Listener.RandomNodes(), s.filterPeer)
defer iterator.Close()
for {
@@ -122,29 +124,41 @@ func (s *Service) listenForNewNodes() {
time.Sleep(pollingPeriod)
continue
}
if exists := iterator.Next(); !exists {
break
}
node := iterator.Node()
peerInfo, _, err := convertToAddrInfo(node)
if err != nil {
log.WithError(err).Error("Could not convert to peer info")
wantedCount := s.wantedPeerDials()
if wantedCount == 0 {
log.Trace("Not looking for peers, at peer limit")
time.Sleep(pollingPeriod)
continue
}
if peerInfo == nil {
continue
// Restrict dials if limit is applied.
if flags.MaxDialIsActive() {
wantedCount = min(wantedCount, flags.Get().MaxConcurrentDials)
}
// Make sure that peer is not dialed too often, for each connection attempt there's a backoff period.
s.Peers().RandomizeBackOff(peerInfo.ID)
go func(info *peer.AddrInfo) {
if err := s.connectWithPeer(s.ctx, *info); err != nil {
log.WithError(err).Tracef("Could not connect with peer %s", info.String())
wantedNodes := enode.ReadNodes(iterator, wantedCount)
wg := new(sync.WaitGroup)
for i := 0; i < len(wantedNodes); i++ {
node := wantedNodes[i]
peerInfo, _, err := convertToAddrInfo(node)
if err != nil {
log.WithError(err).Error("Could not convert to peer info")
continue
}
}(peerInfo)
if peerInfo == nil {
continue
}
// Make sure that peer is not dialed too often, for each connection attempt there's a backoff period.
s.Peers().RandomizeBackOff(peerInfo.ID)
wg.Add(1)
go func(info *peer.AddrInfo) {
if err := s.connectWithPeer(s.ctx, *info); err != nil {
log.WithError(err).Tracef("Could not connect with peer %s", info.String())
}
wg.Done()
}(peerInfo)
}
wg.Wait()
}
}
@@ -384,6 +398,17 @@ func (s *Service) isPeerAtLimit(inbound bool) bool {
return activePeers >= maxPeers || numOfConns >= maxPeers
}
func (s *Service) wantedPeerDials() int {
maxPeers := int(s.cfg.MaxPeers)
activePeers := len(s.Peers().Active())
wantedCount := 0
if maxPeers > activePeers {
wantedCount = maxPeers - activePeers
}
return wantedCount
}
// PeersFromStringAddrs converts peer raw ENRs into multiaddrs for p2p.
func PeersFromStringAddrs(addrs []string) ([]ma.Multiaddr, error) {
var allAddrs []ma.Multiaddr

View File

@@ -2,10 +2,14 @@ package p2p
import (
"context"
"runtime"
"time"
"github.com/ethereum/go-ethereum/p2p/enode"
)
const backOffCounter = 50
// filterNodes wraps an iterator such that Next only returns nodes for which
// the 'check' function returns true. This custom implementation also
// checks for context deadlines so that in the event the parent context has
@@ -24,13 +28,21 @@ type filterIter struct {
// Next looks up for the next valid node according to our
// filter criteria.
func (f *filterIter) Next() bool {
lookupCounter := 0
for f.Iterator.Next() {
// Do not excessively perform lookups if we constantly receive non-viable peers.
if lookupCounter > backOffCounter {
lookupCounter = 0
runtime.Gosched()
time.Sleep(pollingPeriod)
}
if f.Context.Err() != nil {
return false
}
if f.check(f.Node()) {
return true
}
lookupCounter++
}
return false
}

View File

@@ -87,7 +87,12 @@ func (s *Service) FindPeersWithSubnet(ctx context.Context, topic string,
return false, errors.Errorf("unable to find requisite number of peers for topic %s - "+
"only %d out of %d peers were able to be found", topic, currNum, threshold)
}
nodes := enode.ReadNodes(iterator, int(params.BeaconNetworkConfig().MinimumPeersInSubnetSearch))
nodeCount := int(params.BeaconNetworkConfig().MinimumPeersInSubnetSearch)
// Restrict dials if limit is applied.
if flags.MaxDialIsActive() {
nodeCount = min(nodeCount, flags.Get().MaxConcurrentDials)
}
nodes := enode.ReadNodes(iterator, nodeCount)
for _, node := range nodes {
info, _, err := convertToAddrInfo(node)
if err != nil {

View File

@@ -10,6 +10,8 @@ go_library(
importpath = "github.com/prysmaticlabs/prysm/v5/beacon-chain/rpc",
visibility = ["//beacon-chain:__subpackages__"],
deps = [
"//api:go_default_library",
"//api/server/middleware:go_default_library",
"//beacon-chain/blockchain:go_default_library",
"//beacon-chain/builder:go_default_library",
"//beacon-chain/cache:go_default_library",

File diff suppressed because it is too large Load Diff

View File

@@ -60,8 +60,7 @@ func (s *Server) GetBlockV2(w http.ResponseWriter, r *http.Request) {
return
}
blk, err := s.Blocker.Block(ctx, []byte(blockId))
if err != nil {
shared.WriteBlockFetchError(w, blk, err)
if !shared.WriteBlockFetchError(w, blk, err) {
return
}
@@ -69,7 +68,7 @@ func (s *Server) GetBlockV2(w http.ResponseWriter, r *http.Request) {
if blk.Version() >= version.Bellatrix && blk.IsBlinded() {
blk, err = s.ExecutionPayloadReconstructor.ReconstructFullBlock(ctx, blk)
if err != nil {
shared.WriteBlockFetchError(w, blk, errors.Wrapf(err, "could not reconstruct full execution payload to create signed beacon block"))
httputil.HandleError(w, errors.Wrapf(err, "could not reconstruct full execution payload to create signed beacon block").Error(), http.StatusBadRequest)
return
}
}
@@ -892,6 +891,11 @@ func (s *Server) validateConsensus(ctx context.Context, blk interfaces.ReadOnlyS
if err != nil {
return errors.Wrap(err, "could not get parent block")
}
if err := blocks.BeaconBlockIsNil(blk); err != nil {
return errors.Wrap(err, "could not validate block")
}
parentStateRoot := parentBlock.Block().StateRoot()
parentState, err := s.Stater.State(ctx, parentStateRoot[:])
if err != nil {

View File

@@ -86,6 +86,24 @@ func fillDBTestBlocks(ctx context.Context, t *testing.T, beaconDB db.Database) (
}
func TestGetBlockV2(t *testing.T) {
t.Run("Unsycned Block", func(t *testing.T) {
mockBlockFetcher := &testutil.MockBlocker{BlockToReturn: nil}
mockChainService := &chainMock.ChainService{
FinalizedRoots: map[[32]byte]bool{},
}
s := &Server{
FinalizationFetcher: mockChainService,
Blocker: mockBlockFetcher,
}
request := httptest.NewRequest(http.MethodGet, "http://foo.example/eth/v2/beacon/blocks/{block_id}", nil)
request = mux.SetURLVars(request, map[string]string{"block_id": "123552314"})
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.GetBlockV2(writer, request)
require.Equal(t, http.StatusNotFound, writer.Code)
})
t.Run("phase0", func(t *testing.T) {
b := util.NewBeaconBlock()
b.Block.Slot = 123

View File

@@ -14,6 +14,7 @@ import (
"github.com/prysmaticlabs/prysm/v5/beacon-chain/state"
fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams"
"github.com/prysmaticlabs/prysm/v5/config/params"
"github.com/prysmaticlabs/prysm/v5/consensus-types/blocks"
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
"github.com/prysmaticlabs/prysm/v5/network/httputil"
"github.com/prysmaticlabs/prysm/v5/runtime/version"
@@ -33,6 +34,12 @@ func (s *Server) BlockRewards(w http.ResponseWriter, r *http.Request) {
if !shared.WriteBlockFetchError(w, blk, err) {
return
}
if err := blocks.BeaconBlockIsNil(blk); err != nil {
httputil.HandleError(w, fmt.Sprintf("block id %s was not found", blockId), http.StatusNotFound)
return
}
if blk.Version() == version.Phase0 {
httputil.HandleError(w, "Block rewards are not supported for Phase 0 blocks", http.StatusBadRequest)
return

View File

@@ -664,7 +664,7 @@ func (s *Server) GetAttesterDuties(w http.ResponseWriter, r *http.Request) {
return
}
committeeAssignments, _, err := helpers.CommitteeAssignments(ctx, st, requestedEpoch)
assignments, err := helpers.CommitteeAssignments(ctx, st, requestedEpoch, requestedValIndices)
if err != nil {
httputil.HandleError(w, "Could not compute committee assignments: "+err.Error(), http.StatusInternalServerError)
return
@@ -684,7 +684,7 @@ func (s *Server) GetAttesterDuties(w http.ResponseWriter, r *http.Request) {
httputil.HandleError(w, fmt.Sprintf("Invalid validator index %d", index), http.StatusBadRequest)
return
}
committee := committeeAssignments[index]
committee := assignments[index]
if committee == nil {
continue
}
@@ -708,10 +708,20 @@ func (s *Server) GetAttesterDuties(w http.ResponseWriter, r *http.Request) {
})
}
dependentRoot, err := attestationDependentRoot(st, requestedEpoch)
if err != nil {
httputil.HandleError(w, "Could not get dependent root: "+err.Error(), http.StatusInternalServerError)
return
var dependentRoot []byte
if requestedEpoch <= 1 {
r, err := s.BeaconDB.GenesisBlockRoot(ctx)
if err != nil {
httputil.HandleError(w, "Could not get genesis block root: "+err.Error(), http.StatusInternalServerError)
return
}
dependentRoot = r[:]
} else {
dependentRoot, err = attestationDependentRoot(st, requestedEpoch)
if err != nil {
httputil.HandleError(w, "Could not get dependent root: "+err.Error(), http.StatusInternalServerError)
return
}
}
isOptimistic, err := s.OptimisticModeFetcher.IsOptimistic(ctx)
if err != nil {
@@ -793,11 +803,11 @@ func (s *Server) GetProposerDuties(w http.ResponseWriter, r *http.Request) {
}
}
var proposals map[primitives.ValidatorIndex][]primitives.Slot
var assignments map[primitives.ValidatorIndex][]primitives.Slot
if nextEpochLookahead {
_, proposals, err = helpers.CommitteeAssignments(ctx, st, nextEpoch)
assignments, err = helpers.ProposerAssignments(ctx, st, nextEpoch)
} else {
_, proposals, err = helpers.CommitteeAssignments(ctx, st, requestedEpoch)
assignments, err = helpers.ProposerAssignments(ctx, st, requestedEpoch)
}
if err != nil {
httputil.HandleError(w, "Could not compute committee assignments: "+err.Error(), http.StatusInternalServerError)
@@ -805,7 +815,7 @@ func (s *Server) GetProposerDuties(w http.ResponseWriter, r *http.Request) {
}
duties := make([]*structs.ProposerDuty, 0)
for index, proposalSlots := range proposals {
for index, proposalSlots := range assignments {
val, err := st.ValidatorAtIndexReadOnly(index)
if err != nil {
httputil.HandleError(w, fmt.Sprintf("Could not get validator at index %d: %v", index, err), http.StatusInternalServerError)
@@ -822,10 +832,20 @@ func (s *Server) GetProposerDuties(w http.ResponseWriter, r *http.Request) {
}
}
dependentRoot, err := proposalDependentRoot(st, requestedEpoch)
if err != nil {
httputil.HandleError(w, "Could not get dependent root: "+err.Error(), http.StatusInternalServerError)
return
var dependentRoot []byte
if requestedEpoch == 0 {
r, err := s.BeaconDB.GenesisBlockRoot(ctx)
if err != nil {
httputil.HandleError(w, "Could not get genesis block root: "+err.Error(), http.StatusInternalServerError)
return
}
dependentRoot = r[:]
} else {
dependentRoot, err = proposalDependentRoot(st, requestedEpoch)
if err != nil {
httputil.HandleError(w, "Could not get dependent root: "+err.Error(), http.StatusInternalServerError)
return
}
}
isOptimistic, err := s.OptimisticModeFetcher.IsOptimistic(ctx)
if err != nil {

View File

@@ -1443,6 +1443,9 @@ func TestGetAttesterDuties(t *testing.T) {
chain := &mockChain.ChainService{
State: bs, Root: genesisRoot[:], Slot: &chainSlot,
}
db := dbutil.SetupDB(t)
require.NoError(t, db.SaveGenesisBlockRoot(context.Background(), genesisRoot))
s := &Server{
Stater: &testutil.MockStater{
StatesBySlot: map[primitives.Slot]state.BeaconState{
@@ -1453,6 +1456,7 @@ func TestGetAttesterDuties(t *testing.T) {
TimeFetcher: chain,
SyncChecker: &mockSync.Sync{IsSyncing: false},
OptimisticModeFetcher: chain,
BeaconDB: db,
}
t.Run("single validator", func(t *testing.T) {
@@ -1619,7 +1623,6 @@ func TestGetAttesterDuties(t *testing.T) {
blk.Block.Slot = 31
root, err := blk.Block.HashTreeRoot()
require.NoError(t, err)
db := dbutil.SetupDB(t)
util.SaveBlock(t, ctx, db, blk)
require.NoError(t, db.SaveGenesisBlockRoot(ctx, root))
@@ -1632,6 +1635,7 @@ func TestGetAttesterDuties(t *testing.T) {
TimeFetcher: chain,
OptimisticModeFetcher: chain,
SyncChecker: &mockSync.Sync{IsSyncing: false},
BeaconDB: db,
}
var body bytes.Buffer
@@ -1693,6 +1697,9 @@ func TestGetProposerDuties(t *testing.T) {
pubKeys[i] = deposits[i].Data.PublicKey
}
db := dbutil.SetupDB(t)
require.NoError(t, db.SaveGenesisBlockRoot(context.Background(), genesisRoot))
t.Run("ok", func(t *testing.T) {
bs, err := transition.GenesisBeaconState(context.Background(), deposits, 0, eth1Data)
require.NoError(t, err, "Could not set up genesis state")
@@ -1710,6 +1717,7 @@ func TestGetProposerDuties(t *testing.T) {
SyncChecker: &mockSync.Sync{IsSyncing: false},
PayloadIDCache: cache.NewPayloadIDCache(),
TrackedValidatorsCache: cache.NewTrackedValidatorsCache(),
BeaconDB: db,
}
request := httptest.NewRequest(http.MethodGet, "http://www.example.com/eth/v1/validator/duties/proposer/{epoch}", nil)
@@ -1737,6 +1745,7 @@ func TestGetProposerDuties(t *testing.T) {
t.Run("next epoch", func(t *testing.T) {
bs, err := transition.GenesisBeaconState(context.Background(), deposits, 0, eth1Data)
require.NoError(t, err, "Could not set up genesis state")
require.NoError(t, bs.SetSlot(params.BeaconConfig().SlotsPerEpoch))
require.NoError(t, bs.SetBlockRoots(roots))
chainSlot := primitives.Slot(0)
chain := &mockChain.ChainService{
@@ -1750,6 +1759,7 @@ func TestGetProposerDuties(t *testing.T) {
SyncChecker: &mockSync.Sync{IsSyncing: false},
PayloadIDCache: cache.NewPayloadIDCache(),
TrackedValidatorsCache: cache.NewTrackedValidatorsCache(),
BeaconDB: db,
}
request := httptest.NewRequest(http.MethodGet, "http://www.example.com/eth/v1/validator/duties/proposer/{epoch}", nil)
@@ -1792,6 +1802,7 @@ func TestGetProposerDuties(t *testing.T) {
SyncChecker: &mockSync.Sync{IsSyncing: false},
PayloadIDCache: cache.NewPayloadIDCache(),
TrackedValidatorsCache: cache.NewTrackedValidatorsCache(),
BeaconDB: db,
}
currentEpoch := slots.ToEpoch(bs.Slot())
@@ -1808,7 +1819,6 @@ func TestGetProposerDuties(t *testing.T) {
assert.StringContains(t, fmt.Sprintf("Request epoch %d can not be greater than next epoch %d", currentEpoch+2, currentEpoch+1), e.Message)
})
t.Run("execution optimistic", func(t *testing.T) {
ctx := context.Background()
bs, err := transition.GenesisBeaconState(context.Background(), deposits, 0, eth1Data)
require.NoError(t, err, "Could not set up genesis state")
// Set state to non-epoch start slot.
@@ -1818,11 +1828,6 @@ func TestGetProposerDuties(t *testing.T) {
blk := util.NewBeaconBlock()
blk.Block.ParentRoot = parentRoot[:]
blk.Block.Slot = 31
root, err := blk.Block.HashTreeRoot()
require.NoError(t, err)
db := dbutil.SetupDB(t)
util.SaveBlock(t, ctx, db, blk)
require.NoError(t, db.SaveGenesisBlockRoot(ctx, root))
chainSlot := primitives.Slot(0)
chain := &mockChain.ChainService{
@@ -1836,6 +1841,7 @@ func TestGetProposerDuties(t *testing.T) {
SyncChecker: &mockSync.Sync{IsSyncing: false},
PayloadIDCache: cache.NewPayloadIDCache(),
TrackedValidatorsCache: cache.NewTrackedValidatorsCache(),
BeaconDB: db,
}
request := httptest.NewRequest(http.MethodGet, "http://www.example.com/eth/v1/validator/duties/proposer/{epoch}", nil)

View File

@@ -105,23 +105,28 @@ func (bs *Server) ListValidatorAssignments(
}
// Initialize all committee related data.
committeeAssignments, proposerIndexToSlots, err := helpers.CommitteeAssignments(ctx, requestedState, requestedEpoch)
assignments, err := helpers.CommitteeAssignments(ctx, requestedState, requestedEpoch, filteredIndices[start:end])
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not compute committee assignments: %v", err)
}
proposalSlots, err := helpers.ProposerAssignments(ctx, requestedState, requestedEpoch)
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not compute proposer slots: %v", err)
}
for _, index := range filteredIndices[start:end] {
if uint64(index) >= uint64(requestedState.NumValidators()) {
return nil, status.Errorf(codes.OutOfRange, "Validator index %d >= validator count %d",
index, requestedState.NumValidators())
}
comAssignment := committeeAssignments[index]
a := assignments[index]
pubkey := requestedState.PubkeyAtIndex(index)
assign := &ethpb.ValidatorAssignments_CommitteeAssignment{
BeaconCommittees: comAssignment.Committee,
CommitteeIndex: comAssignment.CommitteeIndex,
AttesterSlot: comAssignment.AttesterSlot,
ProposerSlots: proposerIndexToSlots[index],
BeaconCommittees: a.Committee,
CommitteeIndex: a.CommitteeIndex,
AttesterSlot: a.AttesterSlot,
ProposerSlots: proposalSlots[index],
PublicKey: pubkey[:],
ValidatorIndex: index,
}

View File

@@ -174,16 +174,18 @@ func TestServer_ListAssignments_Pagination_DefaultPageSize_NoArchive(t *testing.
activeIndices, err := helpers.ActiveValidatorIndices(ctx, s, 0)
require.NoError(t, err)
committeeAssignments, proposerIndexToSlots, err := helpers.CommitteeAssignments(context.Background(), s, 0)
assignments, err := helpers.CommitteeAssignments(context.Background(), s, 0, activeIndices[0:params.BeaconConfig().DefaultPageSize])
require.NoError(t, err)
proposerSlots, err := helpers.ProposerAssignments(ctx, s, 0)
require.NoError(t, err)
for _, index := range activeIndices[0:params.BeaconConfig().DefaultPageSize] {
val, err := s.ValidatorAtIndex(index)
require.NoError(t, err)
wanted = append(wanted, &ethpb.ValidatorAssignments_CommitteeAssignment{
BeaconCommittees: committeeAssignments[index].Committee,
CommitteeIndex: committeeAssignments[index].CommitteeIndex,
AttesterSlot: committeeAssignments[index].AttesterSlot,
ProposerSlots: proposerIndexToSlots[index],
BeaconCommittees: assignments[index].Committee,
CommitteeIndex: assignments[index].CommitteeIndex,
AttesterSlot: assignments[index].AttesterSlot,
ProposerSlots: proposerSlots[index],
PublicKey: val.PublicKey,
ValidatorIndex: index,
})
@@ -244,16 +246,18 @@ func TestServer_ListAssignments_FilterPubkeysIndices_NoPagination(t *testing.T)
activeIndices, err := helpers.ActiveValidatorIndices(ctx, s, 0)
require.NoError(t, err)
committeeAssignments, proposerIndexToSlots, err := helpers.CommitteeAssignments(context.Background(), s, 0)
assignments, err := helpers.CommitteeAssignments(context.Background(), s, 0, activeIndices[1:4])
require.NoError(t, err)
proposerSlots, err := helpers.ProposerAssignments(ctx, s, 0)
require.NoError(t, err)
for _, index := range activeIndices[1:4] {
val, err := s.ValidatorAtIndex(index)
require.NoError(t, err)
wanted = append(wanted, &ethpb.ValidatorAssignments_CommitteeAssignment{
BeaconCommittees: committeeAssignments[index].Committee,
CommitteeIndex: committeeAssignments[index].CommitteeIndex,
AttesterSlot: committeeAssignments[index].AttesterSlot,
ProposerSlots: proposerIndexToSlots[index],
BeaconCommittees: assignments[index].Committee,
CommitteeIndex: assignments[index].CommitteeIndex,
AttesterSlot: assignments[index].AttesterSlot,
ProposerSlots: proposerSlots[index],
PublicKey: val.PublicKey,
ValidatorIndex: index,
})
@@ -312,16 +316,18 @@ func TestServer_ListAssignments_CanFilterPubkeysIndices_WithPagination(t *testin
activeIndices, err := helpers.ActiveValidatorIndices(ctx, s, 0)
require.NoError(t, err)
committeeAssignments, proposerIndexToSlots, err := helpers.CommitteeAssignments(context.Background(), s, 0)
as, err := helpers.CommitteeAssignments(context.Background(), s, 0, activeIndices[3:5])
require.NoError(t, err)
proposalSlots, err := helpers.ProposerAssignments(ctx, s, 0)
require.NoError(t, err)
for _, index := range activeIndices[3:5] {
val, err := s.ValidatorAtIndex(index)
require.NoError(t, err)
assignments = append(assignments, &ethpb.ValidatorAssignments_CommitteeAssignment{
BeaconCommittees: committeeAssignments[index].Committee,
CommitteeIndex: committeeAssignments[index].CommitteeIndex,
AttesterSlot: committeeAssignments[index].AttesterSlot,
ProposerSlots: proposerIndexToSlots[index],
BeaconCommittees: as[index].Committee,
CommitteeIndex: as[index].CommitteeIndex,
AttesterSlot: as[index].AttesterSlot,
ProposerSlots: proposalSlots[index],
PublicKey: val.PublicKey,
ValidatorIndex: index,
})
@@ -340,16 +346,18 @@ func TestServer_ListAssignments_CanFilterPubkeysIndices_WithPagination(t *testin
req = &ethpb.ListValidatorAssignmentsRequest{Indices: []primitives.ValidatorIndex{1, 2, 3, 4, 5, 6}, PageSize: 5, PageToken: "1"}
res, err = bs.ListValidatorAssignments(context.Background(), req)
require.NoError(t, err)
cAssignments, proposerIndexToSlots, err := helpers.CommitteeAssignments(context.Background(), s, 0)
as, err = helpers.CommitteeAssignments(context.Background(), s, 0, activeIndices[6:7])
require.NoError(t, err)
proposalSlots, err = helpers.ProposerAssignments(ctx, s, 0)
require.NoError(t, err)
for _, index := range activeIndices[6:7] {
val, err := s.ValidatorAtIndex(index)
require.NoError(t, err)
assignments = append(assignments, &ethpb.ValidatorAssignments_CommitteeAssignment{
BeaconCommittees: cAssignments[index].Committee,
CommitteeIndex: cAssignments[index].CommitteeIndex,
AttesterSlot: cAssignments[index].AttesterSlot,
ProposerSlots: proposerIndexToSlots[index],
BeaconCommittees: as[index].Committee,
CommitteeIndex: as[index].CommitteeIndex,
AttesterSlot: as[index].AttesterSlot,
ProposerSlots: proposalSlots[index],
PublicKey: val.PublicKey,
ValidatorIndex: index,
})

View File

@@ -9,6 +9,8 @@ import (
"github.com/prysmaticlabs/prysm/v5/api/pagination"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/helpers"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/db/filters"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/operations/attestations"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/state/stategen"
"github.com/prysmaticlabs/prysm/v5/cmd"
"github.com/prysmaticlabs/prysm/v5/config/params"
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
@@ -67,6 +69,13 @@ func (bs *Server) ListAttestations(
return nil, status.Errorf(codes.Internal, "Could not fetch attestations: %v", err)
}
case *ethpb.ListAttestationsRequest_Epoch:
if q.Epoch >= params.BeaconConfig().ElectraForkEpoch {
return &ethpb.ListAttestationsResponse{
Attestations: make([]*ethpb.Attestation, 0),
TotalSize: int32(0),
NextPageToken: strconv.Itoa(0),
}, nil
}
blocks, _, err = bs.BeaconDB.Blocks(ctx, filters.NewFilter().SetStartEpoch(q.Epoch).SetEndEpoch(q.Epoch))
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not fetch attestations: %v", err)
@@ -74,17 +83,15 @@ func (bs *Server) ListAttestations(
default:
return nil, status.Error(codes.InvalidArgument, "Must specify a filter criteria for fetching attestations")
}
atts := make([]ethpb.Att, 0, params.BeaconConfig().MaxAttestations*uint64(len(blocks)))
for _, blk := range blocks {
atts = append(atts, blk.Block().Body().Attestations()...)
atts, err := blockAttestations[*ethpb.Attestation](blocks)
if err != nil {
return nil, err
}
// We sort attestations according to the Sortable interface.
sort.Sort(sortableAttestations(atts))
numAttestations := len(atts)
// If there are no attestations, we simply return a response specifying this.
// Otherwise, attempting to paginate 0 attestations below would result in an error.
if numAttestations == 0 {
if len(atts) == 0 {
return &ethpb.ListAttestationsResponse{
Attestations: make([]*ethpb.Attestation, 0),
TotalSize: int32(0),
@@ -92,20 +99,77 @@ func (bs *Server) ListAttestations(
}, nil
}
start, end, nextPageToken, err := pagination.StartAndEndPage(req.PageToken, int(req.PageSize), numAttestations)
start, end, nextPageToken, err := pagination.StartAndEndPage(req.PageToken, int(req.PageSize), len(atts))
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not paginate attestations: %v", err)
}
attestations := make([]*ethpb.Attestation, 0, len(atts))
for _, att := range atts {
a, ok := att.(*ethpb.Attestation)
if ok {
attestations = append(attestations, a)
}
}
return &ethpb.ListAttestationsResponse{
Attestations: attestations[start:end],
TotalSize: int32(numAttestations),
Attestations: atts[start:end],
TotalSize: int32(len(atts)),
NextPageToken: nextPageToken,
}, nil
}
// ListAttestationsElectra retrieves attestations by block root, slot, or epoch.
// Attestations are sorted by data slot by default.
//
// The server may return an empty list when no attestations match the given
// filter criteria. This RPC should not return NOT_FOUND. Only one filter
// criteria should be used.
func (bs *Server) ListAttestationsElectra(ctx context.Context, req *ethpb.ListAttestationsRequest) (*ethpb.ListAttestationsElectraResponse, error) {
if int(req.PageSize) > cmd.Get().MaxRPCPageSize {
return nil, status.Errorf(codes.InvalidArgument, "Requested page size %d can not be greater than max size %d",
req.PageSize, cmd.Get().MaxRPCPageSize)
}
var blocks []interfaces.ReadOnlySignedBeaconBlock
var err error
switch q := req.QueryFilter.(type) {
case *ethpb.ListAttestationsRequest_GenesisEpoch:
return &ethpb.ListAttestationsElectraResponse{
Attestations: make([]*ethpb.AttestationElectra, 0),
TotalSize: int32(0),
NextPageToken: strconv.Itoa(0),
}, nil
case *ethpb.ListAttestationsRequest_Epoch:
if q.Epoch < params.BeaconConfig().ElectraForkEpoch {
return &ethpb.ListAttestationsElectraResponse{
Attestations: make([]*ethpb.AttestationElectra, 0),
TotalSize: int32(0),
NextPageToken: strconv.Itoa(0),
}, nil
}
blocks, _, err = bs.BeaconDB.Blocks(ctx, filters.NewFilter().SetStartEpoch(q.Epoch).SetEndEpoch(q.Epoch))
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not fetch attestations: %v", err)
}
default:
return nil, status.Error(codes.InvalidArgument, "Must specify a filter criteria for fetching attestations")
}
atts, err := blockAttestations[*ethpb.AttestationElectra](blocks)
if err != nil {
return nil, err
}
// If there are no attestations, we simply return a response specifying this.
// Otherwise, attempting to paginate 0 attestations below would result in an error.
if len(atts) == 0 {
return &ethpb.ListAttestationsElectraResponse{
Attestations: make([]*ethpb.AttestationElectra, 0),
TotalSize: int32(0),
NextPageToken: strconv.Itoa(0),
}, nil
}
start, end, nextPageToken, err := pagination.StartAndEndPage(req.PageToken, int(req.PageSize), len(atts))
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not paginate attestations: %v", err)
}
return &ethpb.ListAttestationsElectraResponse{
Attestations: atts[start:end],
TotalSize: int32(len(atts)),
NextPageToken: nextPageToken,
}, nil
}
@@ -128,6 +192,13 @@ func (bs *Server) ListIndexedAttestations(
return nil, status.Errorf(codes.Internal, "Could not fetch attestations: %v", err)
}
case *ethpb.ListIndexedAttestationsRequest_Epoch:
if q.Epoch >= params.BeaconConfig().ElectraForkEpoch {
return &ethpb.ListIndexedAttestationsResponse{
IndexedAttestations: make([]*ethpb.IndexedAttestation, 0),
TotalSize: int32(0),
NextPageToken: strconv.Itoa(0),
}, nil
}
blocks, _, err = bs.BeaconDB.Blocks(ctx, filters.NewFilter().SetStartEpoch(q.Epoch).SetEndEpoch(q.Epoch))
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not fetch attestations: %v", err)
@@ -136,29 +207,205 @@ func (bs *Server) ListIndexedAttestations(
return nil, status.Error(codes.InvalidArgument, "Must specify a filter criteria for fetching attestations")
}
attsArray := make([]ethpb.Att, 0, params.BeaconConfig().MaxAttestations*uint64(len(blocks)))
for _, b := range blocks {
attsArray = append(attsArray, b.Block().Body().Attestations()...)
indexedAtts, err := blockIndexedAttestations[*ethpb.IndexedAttestation](ctx, blocks, bs.StateGen)
if err != nil {
return nil, err
}
// We sort attestations according to the Sortable interface.
sort.Sort(sortableAttestations(attsArray))
numAttestations := len(attsArray)
// If there are no attestations, we simply return a response specifying this.
// Otherwise, attempting to paginate 0 attestations below would result in an error.
if numAttestations == 0 {
if len(indexedAtts) == 0 {
return &ethpb.ListIndexedAttestationsResponse{
IndexedAttestations: make([]*ethpb.IndexedAttestation, 0),
TotalSize: int32(0),
NextPageToken: strconv.Itoa(0),
}, nil
}
start, end, nextPageToken, err := pagination.StartAndEndPage(req.PageToken, int(req.PageSize), len(indexedAtts))
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not paginate attestations: %v", err)
}
return &ethpb.ListIndexedAttestationsResponse{
IndexedAttestations: indexedAtts[start:end],
TotalSize: int32(len(indexedAtts)),
NextPageToken: nextPageToken,
}, nil
}
// ListIndexedAttestationsElectra retrieves indexed attestations by block root.
// IndexedAttestationsForEpoch are sorted by data slot by default. Start-end epoch
// filter is used to retrieve blocks with.
//
// The server may return an empty list when no attestations match the given
// filter criteria. This RPC should not return NOT_FOUND.
func (bs *Server) ListIndexedAttestationsElectra(
ctx context.Context,
req *ethpb.ListIndexedAttestationsRequest,
) (*ethpb.ListIndexedAttestationsElectraResponse, error) {
var blocks []interfaces.ReadOnlySignedBeaconBlock
var err error
switch q := req.QueryFilter.(type) {
case *ethpb.ListIndexedAttestationsRequest_GenesisEpoch:
return &ethpb.ListIndexedAttestationsElectraResponse{
IndexedAttestations: make([]*ethpb.IndexedAttestationElectra, 0),
TotalSize: int32(0),
NextPageToken: strconv.Itoa(0),
}, nil
case *ethpb.ListIndexedAttestationsRequest_Epoch:
if q.Epoch < params.BeaconConfig().ElectraForkEpoch {
return &ethpb.ListIndexedAttestationsElectraResponse{
IndexedAttestations: make([]*ethpb.IndexedAttestationElectra, 0),
TotalSize: int32(0),
NextPageToken: strconv.Itoa(0),
}, nil
}
blocks, _, err = bs.BeaconDB.Blocks(ctx, filters.NewFilter().SetStartEpoch(q.Epoch).SetEndEpoch(q.Epoch))
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not fetch attestations: %v", err)
}
default:
return nil, status.Error(codes.InvalidArgument, "Must specify a filter criteria for fetching attestations")
}
indexedAtts, err := blockIndexedAttestations[*ethpb.IndexedAttestationElectra](ctx, blocks, bs.StateGen)
if err != nil {
return nil, err
}
// If there are no attestations, we simply return a response specifying this.
// Otherwise, attempting to paginate 0 attestations below would result in an error.
if len(indexedAtts) == 0 {
return &ethpb.ListIndexedAttestationsElectraResponse{
IndexedAttestations: make([]*ethpb.IndexedAttestationElectra, 0),
TotalSize: int32(0),
NextPageToken: strconv.Itoa(0),
}, nil
}
start, end, nextPageToken, err := pagination.StartAndEndPage(req.PageToken, int(req.PageSize), len(indexedAtts))
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not paginate attestations: %v", err)
}
return &ethpb.ListIndexedAttestationsElectraResponse{
IndexedAttestations: indexedAtts[start:end],
TotalSize: int32(len(indexedAtts)),
NextPageToken: nextPageToken,
}, nil
}
// AttestationPool retrieves pending attestations.
//
// The server returns a list of attestations that have been seen but not
// yet processed. Pool attestations eventually expire as the slot
// advances, so an attestation missing from this request does not imply
// that it was included in a block. The attestation may have expired.
// Refer to the ethereum consensus specification for more details on how
// attestations are processed and when they are no longer valid.
// https://github.com/ethereum/consensus-specs/blob/dev/specs/core/0_beacon-chain.md#attestations
func (bs *Server) AttestationPool(_ context.Context, req *ethpb.AttestationPoolRequest) (*ethpb.AttestationPoolResponse, error) {
atts, err := attestationsFromPool[*ethpb.Attestation](req.PageSize, bs.AttestationsPool)
if err != nil {
return nil, err
}
// If there are no attestations, we simply return a response specifying this.
// Otherwise, attempting to paginate 0 attestations below would result in an error.
if len(atts) == 0 {
return &ethpb.AttestationPoolResponse{
Attestations: make([]*ethpb.Attestation, 0),
TotalSize: int32(0),
NextPageToken: strconv.Itoa(0),
}, nil
}
start, end, nextPageToken, err := pagination.StartAndEndPage(req.PageToken, int(req.PageSize), len(atts))
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not paginate attestations: %v", err)
}
return &ethpb.AttestationPoolResponse{
Attestations: atts[start:end],
TotalSize: int32(len(atts)),
NextPageToken: nextPageToken,
}, nil
}
func (bs *Server) AttestationPoolElectra(_ context.Context, req *ethpb.AttestationPoolRequest) (*ethpb.AttestationPoolElectraResponse, error) {
atts, err := attestationsFromPool[*ethpb.AttestationElectra](req.PageSize, bs.AttestationsPool)
if err != nil {
return nil, err
}
// If there are no attestations, we simply return a response specifying this.
// Otherwise, attempting to paginate 0 attestations below would result in an error.
if len(atts) == 0 {
return &ethpb.AttestationPoolElectraResponse{
Attestations: make([]*ethpb.AttestationElectra, 0),
TotalSize: int32(0),
NextPageToken: strconv.Itoa(0),
}, nil
}
start, end, nextPageToken, err := pagination.StartAndEndPage(req.PageToken, int(req.PageSize), len(atts))
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not paginate attestations: %v", err)
}
return &ethpb.AttestationPoolElectraResponse{
Attestations: atts[start:end],
TotalSize: int32(len(atts)),
NextPageToken: nextPageToken,
}, nil
}
func blockAttestations[T ethpb.Att](blocks []interfaces.ReadOnlySignedBeaconBlock) ([]T, error) {
blockAtts := make([]ethpb.Att, 0, params.BeaconConfig().MaxAttestations*uint64(len(blocks)))
for _, blk := range blocks {
blockAtts = append(blockAtts, blk.Block().Body().Attestations()...)
}
// We sort attestations according to the Sortable interface.
sort.Sort(sortableAttestations(blockAtts))
numAttestations := len(blockAtts)
if numAttestations == 0 {
return []T{}, nil
}
atts := make([]T, 0, len(blockAtts))
for _, att := range blockAtts {
a, ok := att.(T)
if !ok {
var expected T
return nil, status.Errorf(codes.Internal, "Attestation is of the wrong type (expected %T, got %T)", expected, att)
}
atts = append(atts, a)
}
return atts, nil
}
func blockIndexedAttestations[T ethpb.IndexedAtt](
ctx context.Context,
blocks []interfaces.ReadOnlySignedBeaconBlock,
stateGen stategen.StateManager,
) ([]T, error) {
attsArray := make([]ethpb.Att, 0, params.BeaconConfig().MaxAttestations*uint64(len(blocks)))
for _, b := range blocks {
attsArray = append(attsArray, b.Block().Body().Attestations()...)
}
// We sort attestations according to the Sortable interface.
sort.Sort(sortableAttestations(attsArray))
numAttestations := len(attsArray)
if numAttestations == 0 {
return []T{}, nil
}
// We use the retrieved committees for the b root to convert all attestations
// into indexed form effectively.
mappedAttestations := mapAttestationsByTargetRoot(attsArray)
indexedAtts := make([]*ethpb.IndexedAttestation, 0, numAttestations)
indexed := make([]T, 0, numAttestations)
for targetRoot, atts := range mappedAttestations {
attState, err := bs.StateGen.StateByRoot(ctx, targetRoot)
attState, err := stateGen.StateByRoot(ctx, targetRoot)
if err != nil && strings.Contains(err.Error(), "unknown state summary") {
// We shouldn't stop the request if we encounter an attestation we don't have the state for.
log.Debugf("Could not get state for attestation target root %#x", targetRoot)
@@ -185,67 +432,36 @@ func (bs *Server) ListIndexedAttestations(
if err != nil {
return nil, err
}
a, ok := idxAtt.(*ethpb.IndexedAttestation)
if ok {
indexedAtts = append(indexedAtts, a)
a, ok := idxAtt.(T)
if !ok {
var expected T
return nil, status.Errorf(codes.Internal, "Indexed attestation is of the wrong type (expected %T, got %T)", expected, idxAtt)
}
indexed = append(indexed, a)
}
}
start, end, nextPageToken, err := pagination.StartAndEndPage(req.PageToken, int(req.PageSize), len(indexedAtts))
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not paginate attestations: %v", err)
}
return &ethpb.ListIndexedAttestationsResponse{
IndexedAttestations: indexedAtts[start:end],
TotalSize: int32(len(indexedAtts)),
NextPageToken: nextPageToken,
}, nil
return indexed, nil
}
// AttestationPool retrieves pending attestations.
//
// The server returns a list of attestations that have been seen but not
// yet processed. Pool attestations eventually expire as the slot
// advances, so an attestation missing from this request does not imply
// that it was included in a block. The attestation may have expired.
// Refer to the ethereum consensus specification for more details on how
// attestations are processed and when they are no longer valid.
// https://github.com/ethereum/consensus-specs/blob/dev/specs/core/0_beacon-chain.md#attestations
func (bs *Server) AttestationPool(
_ context.Context, req *ethpb.AttestationPoolRequest,
) (*ethpb.AttestationPoolResponse, error) {
if int(req.PageSize) > cmd.Get().MaxRPCPageSize {
func attestationsFromPool[T ethpb.Att](pageSize int32, pool attestations.Pool) ([]T, error) {
if int(pageSize) > cmd.Get().MaxRPCPageSize {
return nil, status.Errorf(
codes.InvalidArgument,
"Requested page size %d can not be greater than max size %d",
req.PageSize,
pageSize,
cmd.Get().MaxRPCPageSize,
)
}
atts := bs.AttestationsPool.AggregatedAttestations()
numAtts := len(atts)
if numAtts == 0 {
return &ethpb.AttestationPoolResponse{
Attestations: make([]*ethpb.Attestation, 0),
TotalSize: int32(0),
NextPageToken: strconv.Itoa(0),
}, nil
}
start, end, nextPageToken, err := pagination.StartAndEndPage(req.PageToken, int(req.PageSize), numAtts)
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not paginate attestations: %v", err)
}
attestations := make([]*ethpb.Attestation, 0, len(atts))
for _, att := range atts {
a, ok := att.(*ethpb.Attestation)
if ok {
attestations = append(attestations, a)
poolAtts := pool.AggregatedAttestations()
atts := make([]T, 0, len(poolAtts))
for _, att := range poolAtts {
a, ok := att.(T)
if !ok {
var expected T
return nil, status.Errorf(codes.Internal, "Attestation is of the wrong type (expected %T, got %T)", expected, att)
}
atts = append(atts, a)
}
return &ethpb.AttestationPoolResponse{
Attestations: attestations[start:end],
TotalSize: int32(numAtts),
NextPageToken: nextPageToken,
}, nil
return atts, nil
}

View File

@@ -462,6 +462,59 @@ func TestServer_ListAttestations_Pagination_DefaultPageSize(t *testing.T) {
assert.DeepEqual(t, atts[i:j], res.Attestations, "Incorrect attestations response")
}
func TestServer_ListAttestationsElectra(t *testing.T) {
params.SetupTestConfigCleanup(t)
cfg := params.BeaconConfig()
cfg.ElectraForkEpoch = 0
params.OverrideBeaconConfig(cfg)
db := dbTest.SetupDB(t)
ctx := context.Background()
st, err := state_native.InitializeFromProtoElectra(&ethpb.BeaconStateElectra{
Slot: 0,
})
require.NoError(t, err)
bs := &Server{
BeaconDB: db,
HeadFetcher: &chainMock.ChainService{
State: st,
},
}
cb := primitives.NewAttestationCommitteeBits()
cb.SetBitAt(2, true)
att := util.HydrateAttestationElectra(&ethpb.AttestationElectra{
AggregationBits: bitfield.NewBitlist(0),
Data: &ethpb.AttestationData{
Slot: 2,
},
CommitteeBits: cb,
})
parentRoot := [32]byte{1, 2, 3}
signedBlock := util.NewBeaconBlockElectra()
signedBlock.Block.ParentRoot = bytesutil.PadTo(parentRoot[:], 32)
signedBlock.Block.Body.Attestations = []*ethpb.AttestationElectra{att}
root, err := signedBlock.Block.HashTreeRoot()
require.NoError(t, err)
util.SaveBlock(t, ctx, db, signedBlock)
require.NoError(t, db.SaveGenesisBlockRoot(ctx, root))
wanted := &ethpb.ListAttestationsElectraResponse{
Attestations: []*ethpb.AttestationElectra{att},
NextPageToken: "",
TotalSize: 1,
}
res, err := bs.ListAttestationsElectra(ctx, &ethpb.ListAttestationsRequest{
QueryFilter: &ethpb.ListAttestationsRequest_Epoch{
Epoch: params.BeaconConfig().ElectraForkEpoch,
},
})
require.NoError(t, err)
require.DeepSSZEqual(t, wanted, res)
}
func TestServer_mapAttestationToTargetRoot(t *testing.T) {
count := primitives.Slot(100)
atts := make([]ethpb.Att, count)
@@ -494,8 +547,6 @@ func TestServer_mapAttestationToTargetRoot(t *testing.T) {
}
func TestServer_ListIndexedAttestations_GenesisEpoch(t *testing.T) {
params.SetupTestConfigCleanup(t)
params.OverrideBeaconConfig(params.BeaconConfig())
db := dbTest.SetupDB(t)
helpers.ClearCache()
ctx := context.Background()
@@ -606,8 +657,6 @@ func TestServer_ListIndexedAttestations_GenesisEpoch(t *testing.T) {
}
func TestServer_ListIndexedAttestations_OldEpoch(t *testing.T) {
params.SetupTestConfigCleanup(t)
params.OverrideBeaconConfig(params.BeaconConfig())
db := dbTest.SetupDB(t)
helpers.ClearCache()
ctx := context.Background()
@@ -690,6 +739,123 @@ func TestServer_ListIndexedAttestations_OldEpoch(t *testing.T) {
require.DeepEqual(t, indexedAtts, res.IndexedAttestations, "Incorrect list indexed attestations response")
}
func TestServer_ListIndexedAttestationsElectra(t *testing.T) {
params.SetupTestConfigCleanup(t)
cfg := params.BeaconConfig()
cfg.ElectraForkEpoch = 0
params.OverrideBeaconConfig(cfg)
db := dbTest.SetupDB(t)
helpers.ClearCache()
ctx := context.Background()
targetRoot1 := bytesutil.ToBytes32([]byte("root"))
targetRoot2 := bytesutil.ToBytes32([]byte("root2"))
count := params.BeaconConfig().SlotsPerEpoch
atts := make([]*ethpb.AttestationElectra, 0, count)
atts2 := make([]*ethpb.AttestationElectra, 0, count)
for i := primitives.Slot(0); i < count; i++ {
var targetRoot [32]byte
if i%2 == 0 {
targetRoot = targetRoot1
} else {
targetRoot = targetRoot2
}
cb := primitives.NewAttestationCommitteeBits()
cb.SetBitAt(0, true)
blockExample := util.NewBeaconBlockElectra()
blockExample.Block.Body.Attestations = []*ethpb.AttestationElectra{
{
Signature: make([]byte, fieldparams.BLSSignatureLength),
Data: &ethpb.AttestationData{
BeaconBlockRoot: make([]byte, fieldparams.RootLength),
Target: &ethpb.Checkpoint{
Root: targetRoot[:],
},
Source: &ethpb.Checkpoint{
Root: make([]byte, fieldparams.RootLength),
},
Slot: i,
},
AggregationBits: bitfield.NewBitlist(128 / uint64(params.BeaconConfig().SlotsPerEpoch)),
CommitteeBits: cb,
},
}
util.SaveBlock(t, ctx, db, blockExample)
if i%2 == 0 {
atts = append(atts, blockExample.Block.Body.Attestations...)
} else {
atts2 = append(atts2, blockExample.Block.Body.Attestations...)
}
}
// We setup 512 validators so that committee size matches the length of attestations' aggregation bits.
numValidators := uint64(512)
state, _ := util.DeterministicGenesisStateElectra(t, numValidators)
// Next up we convert the test attestations to indexed form:
indexedAtts := make([]*ethpb.IndexedAttestationElectra, len(atts)+len(atts2))
for i := 0; i < len(atts); i++ {
att := atts[i]
committee, err := helpers.BeaconCommitteeFromState(context.Background(), state, att.Data.Slot, 0)
require.NoError(t, err)
idxAtt, err := attestation.ConvertToIndexed(ctx, atts[i], committee)
require.NoError(t, err, "Could not convert attestation to indexed")
a, ok := idxAtt.(*ethpb.IndexedAttestationElectra)
require.Equal(t, true, ok, "unexpected type of indexed attestation")
indexedAtts[i] = a
}
for i := 0; i < len(atts2); i++ {
att := atts2[i]
committee, err := helpers.BeaconCommitteeFromState(context.Background(), state, att.Data.Slot, 0)
require.NoError(t, err)
idxAtt, err := attestation.ConvertToIndexed(ctx, atts2[i], committee)
require.NoError(t, err, "Could not convert attestation to indexed")
a, ok := idxAtt.(*ethpb.IndexedAttestationElectra)
require.Equal(t, true, ok, "unexpected type of indexed attestation")
indexedAtts[i+len(atts)] = a
}
bs := &Server{
BeaconDB: db,
GenesisTimeFetcher: &chainMock.ChainService{State: state},
HeadFetcher: &chainMock.ChainService{State: state},
StateGen: stategen.New(db, doublylinkedtree.New()),
}
err := db.SaveStateSummary(ctx, &ethpb.StateSummary{
Root: targetRoot1[:],
Slot: 1,
})
require.NoError(t, err)
err = db.SaveStateSummary(ctx, &ethpb.StateSummary{
Root: targetRoot2[:],
Slot: 2,
})
require.NoError(t, err)
require.NoError(t, db.SaveState(ctx, state, bytesutil.ToBytes32(targetRoot1[:])))
require.NoError(t, state.SetSlot(state.Slot()+1))
require.NoError(t, db.SaveState(ctx, state, bytesutil.ToBytes32(targetRoot2[:])))
res, err := bs.ListIndexedAttestationsElectra(ctx, &ethpb.ListIndexedAttestationsRequest{
QueryFilter: &ethpb.ListIndexedAttestationsRequest_Epoch{
Epoch: 0,
},
})
require.NoError(t, err)
assert.Equal(t, len(indexedAtts), len(res.IndexedAttestations), "Incorrect indexted attestations length")
sort.Slice(indexedAtts, func(i, j int) bool {
return indexedAtts[i].GetData().Slot < indexedAtts[j].GetData().Slot
})
sort.Slice(res.IndexedAttestations, func(i, j int) bool {
return res.IndexedAttestations[i].Data.Slot < res.IndexedAttestations[j].Data.Slot
})
assert.DeepEqual(t, indexedAtts, res.IndexedAttestations, "Incorrect list indexed attestations response")
}
func TestServer_AttestationPool_Pagination_ExceedsMaxPageSize(t *testing.T) {
ctx := context.Background()
bs := &Server{}
@@ -827,3 +993,24 @@ func TestServer_AttestationPool_Pagination_CustomPageSize(t *testing.T) {
assert.Equal(t, tt.res.NextPageToken, res.NextPageToken, "Unexpected next page token")
}
}
func TestServer_AttestationPoolElectra(t *testing.T) {
ctx := context.Background()
bs := &Server{
AttestationsPool: attestations.NewPool(),
}
atts := make([]ethpb.Att, params.BeaconConfig().DefaultPageSize+1)
for i := 0; i < len(atts); i++ {
att := util.NewAttestationElectra()
att.Data.Slot = primitives.Slot(i)
atts[i] = att
}
require.NoError(t, bs.AttestationsPool.SaveAggregatedAttestations(atts))
req := &ethpb.AttestationPoolRequest{}
res, err := bs.AttestationPoolElectra(ctx, req)
require.NoError(t, err)
assert.Equal(t, params.BeaconConfig().DefaultPageSize, len(res.Attestations), "Unexpected number of attestations")
assert.Equal(t, params.BeaconConfig().DefaultPageSize+1, int(res.TotalSize), "Unexpected total size")
}

View File

@@ -36,26 +36,31 @@ func (bs *Server) SubmitProposerSlashing(
}, nil
}
// SubmitAttesterSlashing receives an attester slashing object via
func (bs *Server) SubmitAttesterSlashing(ctx context.Context, req *ethpb.AttesterSlashing) (*ethpb.SubmitSlashingResponse, error) {
return bs.submitAttesterSlashing(ctx, req)
}
// SubmitAttesterSlashingElectra receives an attester slashing object via
// RPC and injects it into the beacon node's operations pool.
// Submission into this pool does not guarantee inclusion into a beacon block.
func (bs *Server) SubmitAttesterSlashing(
ctx context.Context,
req *ethpb.AttesterSlashing,
) (*ethpb.SubmitSlashingResponse, error) {
func (bs *Server) SubmitAttesterSlashingElectra(ctx context.Context, req *ethpb.AttesterSlashingElectra) (*ethpb.SubmitSlashingResponse, error) {
return bs.submitAttesterSlashing(ctx, req)
}
func (bs *Server) submitAttesterSlashing(ctx context.Context, slashing ethpb.AttSlashing) (*ethpb.SubmitSlashingResponse, error) {
beaconState, err := bs.HeadFetcher.HeadStateReadOnly(ctx)
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not retrieve head state: %v", err)
}
if err := bs.SlashingsPool.InsertAttesterSlashing(ctx, beaconState, req); err != nil {
if err := bs.SlashingsPool.InsertAttesterSlashing(ctx, beaconState, slashing); err != nil {
return nil, status.Errorf(codes.Internal, "Could not insert attester slashing into pool: %v", err)
}
if !features.Get().DisableBroadcastSlashings {
if err := bs.Broadcaster.Broadcast(ctx, req); err != nil {
if err := bs.Broadcaster.Broadcast(ctx, slashing); err != nil {
return nil, status.Errorf(codes.Internal, "Could not broadcast slashing object: %v", err)
}
}
indices := slice.IntersectionUint64(req.Attestation_1.AttestingIndices, req.Attestation_2.AttestingIndices)
indices := slice.IntersectionUint64(slashing.FirstAttestation().GetAttestingIndices(), slashing.SecondAttestation().GetAttestingIndices())
slashedIndices := make([]primitives.ValidatorIndex, len(indices))
for i, index := range indices {
slashedIndices[i] = primitives.ValidatorIndex(index)

View File

@@ -66,13 +66,13 @@ func TestServer_SubmitAttesterSlashing(t *testing.T) {
Broadcaster: mb,
}
slashing, err := util.GenerateAttesterSlashingForValidator(st, privs[2], primitives.ValidatorIndex(2))
generatedSlashing, err := util.GenerateAttesterSlashingForValidator(st, privs[2], primitives.ValidatorIndex(2))
require.NoError(t, err)
// We want the intersection of the slashing attesting indices
// to be slashed, so we expect validators 2 and 3 to be in the response
// slashed indices.
_, err = bs.SubmitAttesterSlashing(ctx, slashing)
_, err = bs.SubmitAttesterSlashing(ctx, generatedSlashing.(*ethpb.AttesterSlashing))
require.NoError(t, err)
assert.Equal(t, true, mb.BroadcastCalled.Load(), "Expected broadcast to be called when flag is set")
}
@@ -144,7 +144,7 @@ func TestServer_SubmitAttesterSlashing_DontBroadcast(t *testing.T) {
Broadcaster: mb,
}
slashing, err := util.GenerateAttesterSlashingForValidator(st, privs[2], primitives.ValidatorIndex(2))
generatedSlashing, err := util.GenerateAttesterSlashingForValidator(st, privs[2], primitives.ValidatorIndex(2))
require.NoError(t, err)
// We want the intersection of the slashing attesting indices
@@ -153,17 +153,42 @@ func TestServer_SubmitAttesterSlashing_DontBroadcast(t *testing.T) {
wanted := &ethpb.SubmitSlashingResponse{
SlashedIndices: []primitives.ValidatorIndex{2},
}
res, err := bs.SubmitAttesterSlashing(ctx, slashing)
res, err := bs.SubmitAttesterSlashing(ctx, generatedSlashing.(*ethpb.AttesterSlashing))
require.NoError(t, err)
if !proto.Equal(wanted, res) {
t.Errorf("Wanted %v, received %v", wanted, res)
}
assert.Equal(t, false, mb.BroadcastCalled.Load(), "Expected broadcast not to be called by default")
slashing, err = util.GenerateAttesterSlashingForValidator(st, privs[5], primitives.ValidatorIndex(5))
generatedSlashing, err = util.GenerateAttesterSlashingForValidator(st, privs[5], primitives.ValidatorIndex(5))
require.NoError(t, err)
// If any of the attesting indices in the slashing object have already
// been slashed, we should fail to insert properly into the attester slashing pool.
_, err = bs.SubmitAttesterSlashing(ctx, slashing)
_, err = bs.SubmitAttesterSlashing(ctx, generatedSlashing.(*ethpb.AttesterSlashing))
assert.NotNil(t, err, "Expected including a attester slashing for an already slashed validator to fail")
}
func TestServer_SubmitAttesterSlashingElectra(t *testing.T) {
ctx := context.Background()
st, privs := util.DeterministicGenesisStateElectra(t, 64)
slashedVal, err := st.ValidatorAtIndex(5)
require.NoError(t, err)
slashedVal.Slashed = true
require.NoError(t, st.UpdateValidatorAtIndex(5, slashedVal))
mb := &mockp2p.MockBroadcaster{}
bs := &Server{
HeadFetcher: &mock.ChainService{
State: st,
},
SlashingsPool: slashings.NewPool(),
Broadcaster: mb,
}
generatedSlashing, err := util.GenerateAttesterSlashingForValidator(st, privs[2], primitives.ValidatorIndex(2))
require.NoError(t, err)
_, err = bs.SubmitAttesterSlashingElectra(ctx, generatedSlashing.(*ethpb.AttesterSlashingElectra))
require.NoError(t, err)
assert.Equal(t, true, mb.BroadcastCalled.Load(), "Expected broadcast to be called when flag is set")
}

View File

@@ -7,6 +7,7 @@ import (
coreTime "github.com/prysmaticlabs/prysm/v5/beacon-chain/core/time"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/transition"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/rpc/core"
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
"github.com/prysmaticlabs/prysm/v5/encoding/bytesutil"
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v5/time/slots"
@@ -52,16 +53,31 @@ func (vs *Server) duties(ctx context.Context, req *ethpb.DutiesRequest) (*ethpb.
return nil, status.Errorf(codes.Internal, "Could not process slots up to %d: %v", epochStartSlot, err)
}
}
committeeAssignments, proposerIndexToSlots, err := helpers.CommitteeAssignments(ctx, s, req.Epoch)
requestIndices := make([]primitives.ValidatorIndex, 0, len(req.PublicKeys))
for _, pubKey := range req.PublicKeys {
idx, ok := s.ValidatorIndexByPubkey(bytesutil.ToBytes48(pubKey))
if !ok {
continue
}
requestIndices = append(requestIndices, idx)
}
assignments, err := helpers.CommitteeAssignments(ctx, s, req.Epoch, requestIndices)
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not compute committee assignments: %v", err)
}
// Query the next epoch assignments for committee subnet subscriptions.
nextCommitteeAssignments, _, err := helpers.CommitteeAssignments(ctx, s, req.Epoch+1)
nextEpochAssignments, err := helpers.CommitteeAssignments(ctx, s, req.Epoch+1, requestIndices)
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not compute next committee assignments: %v", err)
}
proposalSlots, err := helpers.ProposerAssignments(ctx, s, req.Epoch)
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not compute proposer slots: %v", err)
}
validatorAssignments := make([]*ethpb.DutiesResponse_Duty, 0, len(req.PublicKeys))
nextValidatorAssignments := make([]*ethpb.DutiesResponse_Duty, 0, len(req.PublicKeys))
@@ -81,20 +97,20 @@ func (vs *Server) duties(ctx context.Context, req *ethpb.DutiesRequest) (*ethpb.
assignment.ValidatorIndex = idx
assignment.Status = s
assignment.ProposerSlots = proposerIndexToSlots[idx]
assignment.ProposerSlots = proposalSlots[idx]
// The next epoch has no lookup for proposer indexes.
nextAssignment.ValidatorIndex = idx
nextAssignment.Status = s
ca, ok := committeeAssignments[idx]
ca, ok := assignments[idx]
if ok {
assignment.Committee = ca.Committee
assignment.AttesterSlot = ca.AttesterSlot
assignment.CommitteeIndex = ca.CommitteeIndex
}
// Save the next epoch assignments.
ca, ok = nextCommitteeAssignments[idx]
ca, ok = nextEpochAssignments[idx]
if ok {
nextAssignment.Committee = ca.Committee
nextAssignment.AttesterSlot = ca.AttesterSlot
@@ -123,9 +139,9 @@ func (vs *Server) duties(ctx context.Context, req *ethpb.DutiesRequest) (*ethpb.
// Next epoch sync committee duty is assigned with next period sync committee only during
// sync period epoch boundary (ie. EPOCHS_PER_SYNC_COMMITTEE_PERIOD - 1). Else wise
// next epoch sync committee duty is the same as current epoch.
nextSlotToEpoch := slots.ToEpoch(s.Slot() + 1)
nextEpoch := req.Epoch + 1
currentEpoch := coreTime.CurrentEpoch(s)
if slots.SyncCommitteePeriod(nextSlotToEpoch) == slots.SyncCommitteePeriod(currentEpoch)+1 {
if slots.SyncCommitteePeriod(nextEpoch) > slots.SyncCommitteePeriod(currentEpoch) {
nextAssignment.IsSyncCommittee, err = helpers.IsNextPeriodSyncCommittee(s, idx)
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not determine next epoch sync committee: %v", err)

View File

@@ -753,10 +753,12 @@ func injectSlashings(t *testing.T, st state.BeaconState, keys []bls.SecretKey, s
attSlashings := make([]*ethpb.AttesterSlashing, params.BeaconConfig().MaxAttesterSlashings)
for i := uint64(0); i < params.BeaconConfig().MaxAttesterSlashings; i++ {
attesterSlashing, err := util.GenerateAttesterSlashingForValidator(st, keys[i+params.BeaconConfig().MaxProposerSlashings], primitives.ValidatorIndex(i+params.BeaconConfig().MaxProposerSlashings) /* validator index */)
generatedAttesterSlashing, err := util.GenerateAttesterSlashingForValidator(st, keys[i+params.BeaconConfig().MaxProposerSlashings], primitives.ValidatorIndex(i+params.BeaconConfig().MaxProposerSlashings) /* validator index */)
require.NoError(t, err)
attesterSlashing, ok := generatedAttesterSlashing.(*ethpb.AttesterSlashing)
require.Equal(t, true, ok, "Attester slashing has the wrong type (expected %T, got %T)", &ethpb.AttesterSlashing{}, generatedAttesterSlashing)
attSlashings[i] = attesterSlashing
err = server.SlashingsPool.InsertAttesterSlashing(context.Background(), st, attesterSlashing)
err = server.SlashingsPool.InsertAttesterSlashing(context.Background(), st, generatedAttesterSlashing.(*ethpb.AttesterSlashing))
require.NoError(t, err)
}
return proposerSlashings, attSlashings

View File

@@ -16,7 +16,6 @@ import (
"github.com/pkg/errors"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
"github.com/prometheus/client_golang/prometheus/promhttp"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/blockchain"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/builder"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/cache"
@@ -311,13 +310,7 @@ func NewService(ctx context.Context, cfg *Config) *Service {
for _, e := range endpoints {
s.cfg.Router.HandleFunc(
e.template,
promhttp.InstrumentHandlerDuration(
httpRequestLatency.MustCurryWith(prometheus.Labels{"endpoint": e.name}),
promhttp.InstrumentHandlerCounter(
httpRequestCount.MustCurryWith(prometheus.Labels{"endpoint": e.name}),
e.handler,
),
),
e.handlerWithMiddleware(),
).Methods(e.methods...)
}

View File

@@ -158,7 +158,7 @@ func (b *BeaconState) ExpectedWithdrawals() ([]*enginev1.Withdrawal, uint64, err
withdrawals = append(withdrawals, &enginev1.Withdrawal{
Index: withdrawalIndex,
ValidatorIndex: validatorIndex,
Address: bytesutil.SafeCopyBytes(val.WithdrawalCredentials[ETH1AddressOffset:]),
Address: bytesutil.SafeCopyBytes(val.GetWithdrawalCredentials()[ETH1AddressOffset:]),
Amount: balance,
})
withdrawalIndex++
@@ -166,7 +166,7 @@ func (b *BeaconState) ExpectedWithdrawals() ([]*enginev1.Withdrawal, uint64, err
withdrawals = append(withdrawals, &enginev1.Withdrawal{
Index: withdrawalIndex,
ValidatorIndex: validatorIndex,
Address: bytesutil.SafeCopyBytes(val.WithdrawalCredentials[ETH1AddressOffset:]),
Address: bytesutil.SafeCopyBytes(val.GetWithdrawalCredentials()[ETH1AddressOffset:]),
Amount: balance - helpers.ValidatorMaxEffectiveBalance(val),
})
withdrawalIndex++

View File

@@ -209,7 +209,7 @@ func ReplayProcessSlots(ctx context.Context, state state.BeaconState, slot primi
return nil, errors.Wrap(err, "could not process epoch with optimizations")
}
} else {
state, err = altair.ProcessEpoch(ctx, state)
err = altair.ProcessEpoch(ctx, state)
if err != nil {
tracing.AnnotateError(span, err)
return nil, errors.Wrap(err, "could not process epoch")

View File

@@ -150,6 +150,12 @@ var (
Help: "Time to verify gossiped blob sidecars",
},
)
beaconAttestationReachHalfSummary = promauto.NewSummary(
prometheus.SummaryOpts{
Name: "attestation_reach_half_milliseconds",
Help: "Time for attestations to reach half",
},
)
pendingAttCount = promauto.NewCounter(prometheus.CounterOpts{
Name: "gossip_pending_attestations_total",
Help: "increased when receiving a new pending attestation",

View File

@@ -356,9 +356,10 @@ func readChunkedBlobSidecar(stream network.Stream, encoding encoder.NetworkEncod
if !found {
return b, errors.Wrapf(errBlobUnmarshal, fmt.Sprintf("unrecognized fork digest %#x", ctxb))
}
// Only deneb is supported at this time, because we lack a fork-spanning interface/union type for blobs.
if v != version.Deneb {
return b, fmt.Errorf("unexpected context bytes for deneb BlobSidecar, ctx=%#x, v=%s", ctxb, version.String(v))
// Only deneb and electra are supported at this time, because we lack a fork-spanning interface/union type for blobs.
// In electra, there's no changes to blob type.
if v < version.Deneb {
return b, fmt.Errorf("unexpected context bytes for BlobSidecar, ctx=%#x, v=%s", ctxb, version.String(v))
}
if err := decode(stream, pb); err != nil {
return b, errors.Wrap(err, "failed to decode the protobuf-encoded BlobSidecar message from RPC chunk stream")

View File

@@ -158,6 +158,7 @@ type Service struct {
newBlobVerifier verification.NewBlobVerifier
availableBlocker coverage.AvailableBlocker
ctxMap ContextByteVersions
attReceived chan struct{}
}
// NewService initializes new regular sync service.
@@ -173,6 +174,7 @@ func NewService(ctx context.Context, opts ...Option) *Service {
seenPendingBlocks: make(map[[32]byte]bool),
blkRootToPendingAtts: make(map[[32]byte][]*ethpb.SignedAggregateAttestationAndProof),
signatureChan: make(chan *signatureVerifier, verifierLimit),
attReceived: make(chan struct{}),
}
for _, opt := range opts {
if err := opt(r); err != nil {
@@ -237,6 +239,8 @@ func (s *Service) Start() {
s.maintainPeerStatuses()
s.resyncIfBehind()
go s.beaconAttestationWatcher()
// Update sync metrics.
async.RunEvery(s.ctx, syncMetricsInterval, s.updateMetrics)
}

View File

@@ -33,6 +33,8 @@ func (s *Service) committeeIndexBeaconAttestationSubscriber(_ context.Context, m
return nil
}
s.attReceived <- struct{}{}
return s.cfg.attPool.SaveUnaggregatedAttestation(a)
}
@@ -59,3 +61,29 @@ func (_ *Service) attesterSubnetIndices(currentSlot primitives.Slot) []uint64 {
}
return slice.SetUint64(commIds)
}
func (s *Service) beaconAttestationWatcher() {
slotTicker := slots.NewSlotTicker(s.cfg.chain.GenesisTime(), params.BeaconConfig().SecondsPerSlot)
count := 0
for {
select {
case currSlot := <-slotTicker.C():
log.Infof("Beacon Attestation Watcher: Clearing Slot: %d, Total received: %d", currSlot, count)
count = 0
case <-s.attReceived:
count++
// 1014657 / 32 / 2 =15854
if count == 15854 {
t := uint64(s.cfg.chain.GenesisTime().Unix())
d := slots.TimeIntoSlot(t)
currentSlot := slots.CurrentSlot(t)
duration := d.Milliseconds() - 4000
beaconAttestationReachHalfSummary.Observe(float64(duration))
log.Infof("Beacon Attestation Watcher: Receive enough attestation for slot: %d and it took time %d", currentSlot, duration)
}
case <-s.ctx.Done():
slotTicker.Done()
return
}
}
}

View File

@@ -170,7 +170,7 @@ func TestSubscribe_ReceivesAttesterSlashing(t *testing.T) {
1, /* validator index */
)
require.NoError(t, err, "Error generating attester slashing")
err = r.cfg.beaconDB.SaveState(ctx, beaconState, bytesutil.ToBytes32(attesterSlashing.Attestation_1.Data.BeaconBlockRoot))
err = r.cfg.beaconDB.SaveState(ctx, beaconState, bytesutil.ToBytes32(attesterSlashing.FirstAttestation().GetData().BeaconBlockRoot))
require.NoError(t, err)
p2pService.ReceivePubSub(topic, attesterSlashing)

View File

@@ -227,6 +227,12 @@ var (
Usage: "Sets the minimum number of peers that a node will attempt to peer with that are subscribed to a subnet.",
Value: 6,
}
// MaxConcurrentDials defines a flag to set the maximum number of peers that a node will attempt to dial with from discovery.
MaxConcurrentDials = &cli.Uint64Flag{
Name: "max-concurrent-dials",
Usage: "Sets the maximum number of peers that a node will attempt to dial with from discovery. By default we will dials as " +
"many peers as possible.",
}
// SuggestedFeeRecipient specifies the fee recipient for the transaction fees.
SuggestedFeeRecipient = &cli.StringFlag{
Name: "suggested-fee-recipient",

View File

@@ -11,6 +11,7 @@ type GlobalFlags struct {
SubscribeToAllSubnets bool
MinimumSyncPeers int
MinimumPeersPerSubnet int
MaxConcurrentDials int
BlockBatchLimit int
BlockBatchLimitBurstFactor int
BlobBatchLimit int
@@ -45,11 +46,17 @@ func ConfigureGlobalFlags(ctx *cli.Context) {
cfg.BlobBatchLimit = ctx.Int(BlobBatchLimit.Name)
cfg.BlobBatchLimitBurstFactor = ctx.Int(BlobBatchLimitBurstFactor.Name)
cfg.MinimumPeersPerSubnet = ctx.Int(MinPeersPerSubnet.Name)
cfg.MaxConcurrentDials = ctx.Int(MaxConcurrentDials.Name)
configureMinimumPeers(ctx, cfg)
Init(cfg)
}
// MaxDialIsActive checks if the user has enabled the max dial flag.
func MaxDialIsActive() bool {
return Get().MaxConcurrentDials > 0
}
func configureMinimumPeers(ctx *cli.Context, cfg *GlobalFlags) {
cfg.MinimumSyncPeers = ctx.Int(MinSyncPeers.Name)
maxPeers := ctx.Int(cmd.P2PMaxPeers.Name)

View File

@@ -72,6 +72,7 @@ var appFlags = []cli.Flag{
flags.WeakSubjectivityCheckpoint,
flags.Eth1HeaderReqLimit,
flags.MinPeersPerSubnet,
flags.MaxConcurrentDials,
flags.SuggestedFeeRecipient,
flags.TerminalTotalDifficultyOverride,
flags.TerminalBlockHashOverride,

View File

@@ -124,6 +124,7 @@ var appHelpFlagGroups = []flagGroup{
flags.WeakSubjectivityCheckpoint,
flags.Eth1HeaderReqLimit,
flags.MinPeersPerSubnet,
flags.MaxConcurrentDials,
flags.MevRelayEndpoint,
flags.MaxBuilderEpochMissedSlots,
flags.MaxBuilderConsecutiveMissedSlots,

View File

@@ -160,12 +160,12 @@ var Commands = []*cli.Command{
flags.InteropStartIndex,
cmd.GrpcMaxCallRecvMsgSizeFlag,
flags.CertFlag,
flags.GrpcHeadersFlag,
flags.GrpcRetriesFlag,
flags.GrpcRetryDelayFlag,
flags.GRPCHeadersFlag,
flags.GRPCRetriesFlag,
flags.GRPCRetryDelayFlag,
flags.ExitAllFlag,
flags.ForceExitFlag,
flags.VoluntaryExitJSONOutputPath,
flags.VoluntaryExitJSONOutputPathFlag,
features.Mainnet,
features.SepoliaTestnet,
features.HoleskyTestnet,

View File

@@ -58,9 +58,9 @@ var Commands = &cli.Command{
flags.BeaconRPCProviderFlag,
cmd.GrpcMaxCallRecvMsgSizeFlag,
flags.CertFlag,
flags.GrpcHeadersFlag,
flags.GrpcRetriesFlag,
flags.GrpcRetryDelayFlag,
flags.GRPCHeadersFlag,
flags.GRPCRetriesFlag,
flags.GRPCRetryDelayFlag,
features.Mainnet,
features.SepoliaTestnet,
features.HoleskyTestnet,
@@ -93,7 +93,7 @@ var Commands = &cli.Command{
flags.WalletPasswordFileFlag,
flags.BackupDirFlag,
flags.BackupPublicKeysFlag,
flags.BackupPasswordFile,
flags.BackupPasswordFileFlag,
features.Mainnet,
features.SepoliaTestnet,
features.HoleskyTestnet,
@@ -160,12 +160,12 @@ var Commands = &cli.Command{
flags.InteropStartIndex,
cmd.GrpcMaxCallRecvMsgSizeFlag,
flags.CertFlag,
flags.GrpcHeadersFlag,
flags.GrpcRetriesFlag,
flags.GrpcRetryDelayFlag,
flags.GRPCHeadersFlag,
flags.GRPCRetriesFlag,
flags.GRPCRetryDelayFlag,
flags.ExitAllFlag,
flags.ForceExitFlag,
flags.VoluntaryExitJSONOutputPath,
flags.VoluntaryExitJSONOutputPathFlag,
features.Mainnet,
features.SepoliaTestnet,
features.HoleskyTestnet,

View File

@@ -23,10 +23,10 @@ func accountsBackup(c *cli.Context) error {
dialOpts := client.ConstructDialOptions(
c.Int(cmd.GrpcMaxCallRecvMsgSizeFlag.Name),
c.String(flags.CertFlag.Name),
c.Uint(flags.GrpcRetriesFlag.Name),
c.Duration(flags.GrpcRetryDelayFlag.Name),
c.Uint(flags.GRPCRetriesFlag.Name),
c.Duration(flags.GRPCRetryDelayFlag.Name),
)
grpcHeaders := strings.Split(c.String(flags.GrpcHeadersFlag.Name), ",")
grpcHeaders := strings.Split(c.String(flags.GRPCHeadersFlag.Name), ",")
opts := []accounts.Option{
accounts.WithWallet(w),
@@ -62,7 +62,7 @@ func accountsBackup(c *cli.Context) error {
// Ask the user for their desired password for their backed up accounts.
backupsPassword, err := prompt.InputPassword(
c,
flags.BackupPasswordFile,
flags.BackupPasswordFileFlag,
"Enter a new password for your backed up accounts",
"Confirm new password",
true,

View File

@@ -20,10 +20,10 @@ func accountsDelete(c *cli.Context) error {
dialOpts := client.ConstructDialOptions(
c.Int(cmd.GrpcMaxCallRecvMsgSizeFlag.Name),
c.String(flags.CertFlag.Name),
c.Uint(flags.GrpcRetriesFlag.Name),
c.Duration(flags.GrpcRetryDelayFlag.Name),
c.Uint(flags.GRPCRetriesFlag.Name),
c.Duration(flags.GRPCRetryDelayFlag.Name),
)
grpcHeaders := strings.Split(c.String(flags.GrpcHeadersFlag.Name), ",")
grpcHeaders := strings.Split(c.String(flags.GRPCHeadersFlag.Name), ",")
opts := []accounts.Option{
accounts.WithWallet(w),

View File

@@ -98,7 +98,7 @@ func setupWalletCtx(
set.String(flags.DeletePublicKeysFlag.Name, cfg.deletePublicKeys, "")
set.String(flags.VoluntaryExitPublicKeysFlag.Name, cfg.voluntaryExitPublicKeys, "")
set.String(flags.BackupDirFlag.Name, cfg.backupDir, "")
set.String(flags.BackupPasswordFile.Name, cfg.backupPasswordFile, "")
set.String(flags.BackupPasswordFileFlag.Name, cfg.backupPasswordFile, "")
set.String(flags.BackupPublicKeysFlag.Name, cfg.backupPublicKeys, "")
set.String(flags.WalletPasswordFileFlag.Name, cfg.walletPasswordFile, "")
set.String(flags.AccountPasswordFileFlag.Name, cfg.accountPasswordFile, "")
@@ -106,7 +106,7 @@ func setupWalletCtx(
set.Bool(flags.SkipDepositConfirmationFlag.Name, cfg.skipDepositConfirm, "")
set.Bool(flags.SkipMnemonic25thWordCheckFlag.Name, true, "")
set.Bool(flags.ExitAllFlag.Name, cfg.exitAll, "")
set.String(flags.GrpcHeadersFlag.Name, cfg.grpcHeaders, "")
set.String(flags.GRPCHeadersFlag.Name, cfg.grpcHeaders, "")
if cfg.privateKeyFile != "" {
set.String(flags.ImportPrivateKeyFileFlag.Name, cfg.privateKeyFile, "")
@@ -120,13 +120,13 @@ func setupWalletCtx(
assert.NoError(tb, set.Set(flags.VoluntaryExitPublicKeysFlag.Name, cfg.voluntaryExitPublicKeys))
assert.NoError(tb, set.Set(flags.BackupDirFlag.Name, cfg.backupDir))
assert.NoError(tb, set.Set(flags.BackupPublicKeysFlag.Name, cfg.backupPublicKeys))
assert.NoError(tb, set.Set(flags.BackupPasswordFile.Name, cfg.backupPasswordFile))
assert.NoError(tb, set.Set(flags.BackupPasswordFileFlag.Name, cfg.backupPasswordFile))
assert.NoError(tb, set.Set(flags.WalletPasswordFileFlag.Name, cfg.walletPasswordFile))
assert.NoError(tb, set.Set(flags.AccountPasswordFileFlag.Name, cfg.accountPasswordFile))
assert.NoError(tb, set.Set(flags.NumAccountsFlag.Name, strconv.Itoa(int(cfg.numAccounts))))
assert.NoError(tb, set.Set(flags.SkipDepositConfirmationFlag.Name, strconv.FormatBool(cfg.skipDepositConfirm)))
assert.NoError(tb, set.Set(flags.ExitAllFlag.Name, strconv.FormatBool(cfg.exitAll)))
assert.NoError(tb, set.Set(flags.GrpcHeadersFlag.Name, cfg.grpcHeaders))
assert.NoError(tb, set.Set(flags.GRPCHeadersFlag.Name, cfg.grpcHeaders))
return cli.NewContext(&app, set, nil)
}

View File

@@ -27,10 +27,10 @@ func Exit(c *cli.Context, r io.Reader) error {
dialOpts := client.ConstructDialOptions(
c.Int(cmd.GrpcMaxCallRecvMsgSizeFlag.Name),
c.String(flags.CertFlag.Name),
c.Uint(flags.GrpcRetriesFlag.Name),
c.Duration(flags.GrpcRetryDelayFlag.Name),
c.Uint(flags.GRPCRetriesFlag.Name),
c.Duration(flags.GRPCRetryDelayFlag.Name),
)
grpcHeaders := strings.Split(c.String(flags.GrpcHeadersFlag.Name), ",")
grpcHeaders := strings.Split(c.String(flags.GRPCHeadersFlag.Name), ",")
beaconRPCProvider := c.String(flags.BeaconRPCProviderFlag.Name)
if !c.IsSet(flags.Web3SignerURLFlag.Name) && !c.IsSet(flags.WalletDirFlag.Name) && !c.IsSet(flags.InteropNumValidators.Name) {
return errors.Errorf("No validators found, please provide a prysm wallet directory via flag --%s "+
@@ -83,7 +83,7 @@ func Exit(c *cli.Context, r io.Reader) error {
accounts.WithBeaconRPCProvider(beaconRPCProvider),
accounts.WithBeaconRESTApiProvider(c.String(flags.BeaconRESTApiProviderFlag.Name)),
accounts.WithGRPCHeaders(grpcHeaders),
accounts.WithExitJSONOutputPath(c.String(flags.VoluntaryExitJSONOutputPath.Name)),
accounts.WithExitJSONOutputPath(c.String(flags.VoluntaryExitJSONOutputPathFlag.Name)),
}
// Get full set of public keys from the keymanager.
validatingPublicKeys, err := km.FetchValidatingPublicKeys(c.Context)

View File

@@ -37,7 +37,7 @@ func TestExitAccountsCli_OK(t *testing.T) {
}
mockNodeClient.EXPECT().
GetGenesis(gomock.Any(), gomock.Any()).
Genesis(gomock.Any(), gomock.Any()).
Return(&ethpb.Genesis{GenesisTime: genesisTime}, nil)
mockValidatorClient.EXPECT().
@@ -133,7 +133,7 @@ func TestExitAccountsCli_OK_AllPublicKeys(t *testing.T) {
}
mockNodeClient.EXPECT().
GetGenesis(gomock.Any(), gomock.Any()).
Genesis(gomock.Any(), gomock.Any()).
Return(&ethpb.Genesis{GenesisTime: genesisTime}, nil)
mockValidatorClient.EXPECT().
@@ -235,7 +235,7 @@ func TestExitAccountsCli_OK_ForceExit(t *testing.T) {
}
mockNodeClient.EXPECT().
GetGenesis(gomock.Any(), gomock.Any()).
Genesis(gomock.Any(), gomock.Any()).
Return(&ethpb.Genesis{GenesisTime: genesisTime}, nil)
mockValidatorClient.EXPECT().
@@ -324,7 +324,7 @@ func TestExitAccountsCli_WriteJSON_NoBroadcast(t *testing.T) {
}
mockNodeClient.EXPECT().
GetGenesis(gomock.Any(), gomock.Any()).
Genesis(gomock.Any(), gomock.Any()).
Return(&ethpb.Genesis{GenesisTime: genesisTime}, nil)
mockValidatorClient.EXPECT().

View File

@@ -27,10 +27,10 @@ func accountsImport(c *cli.Context) error {
dialOpts := client.ConstructDialOptions(
c.Int(cmd.GrpcMaxCallRecvMsgSizeFlag.Name),
c.String(flags.CertFlag.Name),
c.Uint(flags.GrpcRetriesFlag.Name),
c.Duration(flags.GrpcRetryDelayFlag.Name),
c.Uint(flags.GRPCRetriesFlag.Name),
c.Duration(flags.GRPCRetryDelayFlag.Name),
)
grpcHeaders := strings.Split(c.String(flags.GrpcHeadersFlag.Name), ",")
grpcHeaders := strings.Split(c.String(flags.GRPCHeadersFlag.Name), ",")
opts := []accounts.Option{
accounts.WithWallet(w),

View File

@@ -18,10 +18,10 @@ func accountsList(c *cli.Context) error {
dialOpts := client.ConstructDialOptions(
c.Int(cmd.GrpcMaxCallRecvMsgSizeFlag.Name),
c.String(flags.CertFlag.Name),
c.Uint(flags.GrpcRetriesFlag.Name),
c.Duration(flags.GrpcRetryDelayFlag.Name),
c.Uint(flags.GRPCRetriesFlag.Name),
c.Duration(flags.GRPCRetryDelayFlag.Name),
)
grpcHeaders := strings.Split(c.String(flags.GrpcHeadersFlag.Name), ",")
grpcHeaders := strings.Split(c.String(flags.GRPCHeadersFlag.Name), ",")
opts := []accounts.Option{
accounts.WithWallet(w),

View File

@@ -91,20 +91,20 @@ var (
Name: "graffiti",
Usage: "String to include in proposed blocks.",
}
// GrpcRetriesFlag defines the number of times to retry a failed gRPC request.
GrpcRetriesFlag = &cli.UintFlag{
// GRPCRetriesFlag defines the number of times to retry a failed gRPC request.
GRPCRetriesFlag = &cli.UintFlag{
Name: "grpc-retries",
Usage: "Number of attempts to retry gRPC requests.",
Value: 5,
}
// GrpcRetryDelayFlag defines the interval to retry a failed gRPC request.
GrpcRetryDelayFlag = &cli.DurationFlag{
// GRPCRetryDelayFlag defines the interval to retry a failed gRPC request.
GRPCRetryDelayFlag = &cli.DurationFlag{
Name: "grpc-retry-delay",
Usage: "Amount of time between gRPC retry requests.",
Value: 1 * time.Second,
}
// GrpcHeadersFlag defines a list of headers to send with all gRPC requests.
GrpcHeadersFlag = &cli.StringFlag{
// GRPCHeadersFlag defines a list of headers to send with all gRPC requests.
GRPCHeadersFlag = &cli.StringFlag{
Name: "grpc-headers",
Usage: `Comma separated list of key value pairs to pass as gRPC headers for all gRPC calls.
Example: --grpc-headers=key=value`,
@@ -121,8 +121,8 @@ var (
Usage: "Enables gRPC gateway for JSON requests.",
Value: 7500,
}
// GPRCGatewayCorsDomain serves preflight requests when serving gRPC JSON gateway.
GPRCGatewayCorsDomain = &cli.StringFlag{
// GRPCGatewayCorsDomain serves preflight requests when serving gRPC JSON gateway.
GRPCGatewayCorsDomain = &cli.StringFlag{
Name: "grpc-gateway-corsdomain",
Usage: `Comma separated list of domains from which to accept cross origin requests (browser enforced).
This flag has no effect if not used with --grpc-gateway-port.
@@ -142,7 +142,6 @@ var (
Value: filepath.Join(filepath.Join(DefaultValidatorDir(), WalletDefaultDirName), api.AuthTokenFileName),
Aliases: []string{"validator-api-bearer-file"},
}
// WalletDirFlag defines the path to a wallet directory for Prysm accounts.
WalletDirFlag = &cli.StringFlag{
Name: "wallet-dir",
@@ -184,7 +183,6 @@ var (
Name: "mnemonic-language",
Usage: "Allows specifying mnemonic language. Supported languages are: english|chinese_traditional|chinese_simplified|czech|french|japanese|korean|italian|spanish.",
}
// ShowPrivateKeysFlag for accounts.
ShowPrivateKeysFlag = &cli.BoolFlag{
Name: "show-private-keys",
@@ -236,14 +234,15 @@ var (
Name: "force-exit",
Usage: "Exits without displaying the confirmation prompt.",
}
VoluntaryExitJSONOutputPath = &cli.StringFlag{
// VoluntaryExitJSONOutputPathFlag to write voluntary exits as JSON files instead of broadcasting them.
VoluntaryExitJSONOutputPathFlag = &cli.StringFlag{
Name: "exit-json-output-dir",
Usage: "Output directory to write voluntary exits as individual unencrypted JSON " +
"files. If this flag is provided, voluntary exits will be written to the provided " +
"directory and will not be broadcasted.",
}
// BackupPasswordFile for encrypting accounts a user wishes to back up.
BackupPasswordFile = &cli.StringFlag{
// BackupPasswordFileFlag for encrypting accounts a user wishes to back up.
BackupPasswordFileFlag = &cli.StringFlag{
Name: "backup-password-file",
Usage: "Path to a plain-text, .txt file containing the desired password for your backed up accounts.",
Value: "",
@@ -264,7 +263,6 @@ var (
Name: "keys-dir",
Usage: "Path to a directory where keystores to be imported are stored.",
}
// RemoteSignerCertPathFlag defines the path to a client.crt file for a wallet to connect to
// a secure signer via TLS and gRPC.
RemoteSignerCertPathFlag = &cli.StringFlag{
@@ -294,7 +292,6 @@ var (
Usage: "URL for consensys' web3signer software to use with the Prysm validator client.",
Value: "",
}
// Web3SignerPublicValidatorKeysFlag defines a comma-separated list of hex string public keys or external url for web3signer to use for validator signing.
// example with external url: --validators-external-signer-public-keys= https://web3signer.com/api/v1/eth2/publicKeys
// example with public key: --validators-external-signer-public-keys=0xa99a...e44c,0xb89b...4a0b
@@ -303,7 +300,6 @@ var (
Name: "validators-external-signer-public-keys",
Usage: "Comma separated list of public keys OR an external url endpoint for the validator to retrieve public keys from for usage with web3signer.",
}
// KeymanagerKindFlag defines the kind of keymanager desired by a user during wallet creation.
KeymanagerKindFlag = &cli.StringFlag{
Name: "keymanager-kind",
@@ -348,7 +344,6 @@ var (
fee recipient and gas limit. File format found in docs`,
Value: "",
}
// SuggestedFeeRecipientFlag defines the address of the fee recipient.
SuggestedFeeRecipientFlag = &cli.StringFlag{
Name: "suggested-fee-recipient",
@@ -358,7 +353,6 @@ var (
--` + ProposerSettingsFlag.Name + " or --" + ProposerSettingsURLFlag.Name + " flags.",
Value: params.BeaconConfig().EthBurnAddressHex,
}
// EnableBuilderFlag enables the periodic validator registration API calls that will update the custom builder with validator settings.
EnableBuilderFlag = &cli.BoolFlag{
Name: "enable-builder",
@@ -368,21 +362,18 @@ var (
Value: false,
Aliases: []string{"enable-validator-registration"},
}
// BuilderGasLimitFlag defines the gas limit for the builder to use for constructing a payload.
BuilderGasLimitFlag = &cli.StringFlag{
Name: "suggested-gas-limit",
Usage: "Sets gas limit for the builder to use for constructing a payload for all the validators.",
Value: fmt.Sprint(params.BeaconConfig().DefaultBuilderGasLimit),
}
// ValidatorsRegistrationBatchSizeFlag sets the maximum size for one batch of validator registrations. Use a non-positive value to disable batching.
ValidatorsRegistrationBatchSizeFlag = &cli.IntFlag{
Name: "validators-registration-batch-size",
Usage: "Sets the maximum size for one batch of validator registrations. Use a non-positive value to disable batching.",
Value: 0,
}
// EnableDistributed enables the usage of prysm validator client in a Distributed Validator Cluster.
EnableDistributed = &cli.BoolFlag{
Name: "distributed",

View File

@@ -62,10 +62,10 @@ var appFlags = []cli.Flag{
flags.RPCPort,
flags.GRPCGatewayPort,
flags.GRPCGatewayHost,
flags.GrpcRetriesFlag,
flags.GrpcRetryDelayFlag,
flags.GrpcHeadersFlag,
flags.GPRCGatewayCorsDomain,
flags.GRPCRetriesFlag,
flags.GRPCRetryDelayFlag,
flags.GRPCHeadersFlag,
flags.GRPCGatewayCorsDomain,
flags.DisableAccountMetricsFlag,
flags.MonitoringPortFlag,
flags.SlasherRPCProviderFlag,

View File

@@ -56,6 +56,8 @@ var appHelpFlagGroups = []flagGroup{
cmd.E2EConfigFlag,
cmd.VerbosityFlag,
cmd.DataDirFlag,
flags.WalletDirFlag,
flags.WalletPasswordFileFlag,
cmd.ClearDB,
cmd.ForceClearDB,
cmd.EnableBackupWebhookFlag,
@@ -90,38 +92,56 @@ var appHelpFlagGroups = []flagGroup{
},
},
{
Name: "validator",
Name: "rpc",
Flags: []cli.Flag{
flags.CertFlag,
flags.BeaconRPCProviderFlag,
flags.BeaconRPCGatewayProviderFlag,
flags.BeaconRESTApiProviderFlag,
flags.CertFlag,
flags.EnableWebFlag,
flags.DisablePenaltyRewardLogFlag,
flags.GraffitiFlag,
flags.EnableRPCFlag,
flags.RPCHost,
flags.RPCPort,
flags.GRPCGatewayPort,
flags.GRPCGatewayHost,
flags.GrpcRetriesFlag,
flags.GrpcRetryDelayFlag,
flags.GPRCGatewayCorsDomain,
flags.GrpcHeadersFlag,
flags.SlasherRPCProviderFlag,
flags.SlasherCertFlag,
flags.DisableAccountMetricsFlag,
flags.WalletDirFlag,
flags.WalletPasswordFileFlag,
flags.GraffitiFileFlag,
flags.Web3SignerURLFlag,
flags.Web3SignerPublicValidatorKeysFlag,
flags.GRPCRetriesFlag,
flags.GRPCRetryDelayFlag,
flags.GRPCGatewayCorsDomain,
flags.GRPCHeadersFlag,
flags.BeaconRESTApiProviderFlag,
},
},
{
Name: "proposer",
Flags: []cli.Flag{
flags.ProposerSettingsFlag,
flags.ProposerSettingsURLFlag,
flags.SuggestedFeeRecipientFlag,
flags.EnableBuilderFlag,
flags.BuilderGasLimitFlag,
flags.ValidatorsRegistrationBatchSizeFlag,
flags.GraffitiFlag,
flags.GraffitiFileFlag,
},
},
{
Name: "remote signer",
Flags: []cli.Flag{
flags.Web3SignerURLFlag,
flags.Web3SignerPublicValidatorKeysFlag,
},
},
{
Name: "slasher",
Flags: []cli.Flag{
flags.SlasherRPCProviderFlag,
flags.SlasherCertFlag,
},
},
{
Name: "misc",
Flags: []cli.Flag{
flags.EnableWebFlag,
flags.DisablePenaltyRewardLogFlag,
flags.DisableAccountMetricsFlag,
flags.EnableDistributed,
flags.AuthTokenPathFlag,
},

View File

@@ -10,7 +10,7 @@ import (
func TestAllFlagsExistInHelp(t *testing.T) {
// If this test is failing, it is because you've recently added/removed a
// flag in beacon chain main.go, but did not add/remove it to the usage.go
// flag in main.go, but did not add/remove it to the usage.go
// flag grouping (appHelpFlagGroups).
var helpFlags []cli.Flag

View File

@@ -68,7 +68,7 @@ func SetupWalletCtx(
set.String(flags.DeletePublicKeysFlag.Name, cfg.deletePublicKeys, "")
set.String(flags.VoluntaryExitPublicKeysFlag.Name, cfg.voluntaryExitPublicKeys, "")
set.String(flags.BackupDirFlag.Name, cfg.backupDir, "")
set.String(flags.BackupPasswordFile.Name, cfg.backupPasswordFile, "")
set.String(flags.BackupPasswordFileFlag.Name, cfg.backupPasswordFile, "")
set.String(flags.BackupPublicKeysFlag.Name, cfg.backupPublicKeys, "")
set.String(flags.WalletPasswordFileFlag.Name, cfg.walletPasswordFile, "")
set.String(flags.AccountPasswordFileFlag.Name, cfg.accountPasswordFile, "")
@@ -76,7 +76,7 @@ func SetupWalletCtx(
set.Bool(flags.SkipDepositConfirmationFlag.Name, cfg.skipDepositConfirm, "")
set.Bool(flags.SkipMnemonic25thWordCheckFlag.Name, true, "")
set.Bool(flags.ExitAllFlag.Name, cfg.exitAll, "")
set.String(flags.GrpcHeadersFlag.Name, cfg.grpcHeaders, "")
set.String(flags.GRPCHeadersFlag.Name, cfg.grpcHeaders, "")
if cfg.privateKeyFile != "" {
set.String(flags.ImportPrivateKeyFileFlag.Name, cfg.privateKeyFile, "")
@@ -90,13 +90,13 @@ func SetupWalletCtx(
assert.NoError(tb, set.Set(flags.VoluntaryExitPublicKeysFlag.Name, cfg.voluntaryExitPublicKeys))
assert.NoError(tb, set.Set(flags.BackupDirFlag.Name, cfg.backupDir))
assert.NoError(tb, set.Set(flags.BackupPublicKeysFlag.Name, cfg.backupPublicKeys))
assert.NoError(tb, set.Set(flags.BackupPasswordFile.Name, cfg.backupPasswordFile))
assert.NoError(tb, set.Set(flags.BackupPasswordFileFlag.Name, cfg.backupPasswordFile))
assert.NoError(tb, set.Set(flags.WalletPasswordFileFlag.Name, cfg.walletPasswordFile))
assert.NoError(tb, set.Set(flags.AccountPasswordFileFlag.Name, cfg.accountPasswordFile))
assert.NoError(tb, set.Set(flags.NumAccountsFlag.Name, strconv.Itoa(int(cfg.numAccounts))))
assert.NoError(tb, set.Set(flags.SkipDepositConfirmationFlag.Name, strconv.FormatBool(cfg.skipDepositConfirm)))
assert.NoError(tb, set.Set(flags.ExitAllFlag.Name, strconv.FormatBool(cfg.exitAll)))
assert.NoError(tb, set.Set(flags.GrpcHeadersFlag.Name, cfg.grpcHeaders))
assert.NoError(tb, set.Set(flags.GRPCHeadersFlag.Name, cfg.grpcHeaders))
return cli.NewContext(&app, set, nil)
}

View File

@@ -3,6 +3,8 @@ load("@prysm//tools/go:def.bzl", "go_library", "go_test")
go_library(
name = "go_default_library",
srcs = [
"committee_bits_mainnet.go",
"committee_bits_minimal.go", # keep
"committee_index.go",
"domain.go",
"epoch.go",
@@ -20,6 +22,7 @@ go_library(
deps = [
"//math:go_default_library",
"@com_github_prysmaticlabs_fastssz//:go_default_library",
"@com_github_prysmaticlabs_go_bitfield//:go_default_library",
],
)

View File

@@ -0,0 +1,9 @@
//go:build !minimal
package primitives
import "github.com/prysmaticlabs/go-bitfield"
func NewAttestationCommitteeBits() bitfield.Bitvector64 {
return bitfield.NewBitvector64()
}

View File

@@ -0,0 +1,9 @@
//go:build minimal
package primitives
import "github.com/prysmaticlabs/go-bitfield"
func NewAttestationCommitteeBits() bitfield.Bitvector4 {
return bitfield.NewBitvector4()
}

185
deps.bzl
View File

@@ -705,8 +705,8 @@ def prysm_deps():
go_repository(
name = "com_github_decred_dcrd_dcrec_secp256k1_v4",
importpath = "github.com/decred/dcrd/dcrec/secp256k1/v4",
sum = "h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs=",
version = "v4.2.0",
sum = "h1:rpfIENRNNilwHwZeG5+P150SMrnNEcHYvcCuK6dPZSg=",
version = "v4.3.0",
)
go_repository(
name = "com_github_deepmap_oapi_codegen",
@@ -1295,8 +1295,8 @@ def prysm_deps():
importpath = "github.com/golang/protobuf",
patch_args = ["-p1"],
patches = ["@io_bazel_rules_go//third_party:com_github_golang_protobuf-extras.patch"],
sum = "h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=",
version = "v1.5.3",
sum = "h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=",
version = "v1.5.4",
)
go_repository(
name = "com_github_golang_snappy",
@@ -1607,14 +1607,14 @@ def prysm_deps():
go_repository(
name = "com_github_hashicorp_golang_lru_arc_v2",
importpath = "github.com/hashicorp/golang-lru/arc/v2",
sum = "h1:l2zaLDubNhW4XO3LnliVj0GXO3+/CGNJAg1dcN2Fpfw=",
version = "v2.0.5",
sum = "h1:QxkVTxwColcduO+LP7eJO56r2hFiG8zEbfAAzRv52KQ=",
version = "v2.0.7",
)
go_repository(
name = "com_github_hashicorp_golang_lru_v2",
importpath = "github.com/hashicorp/golang-lru/v2",
sum = "h1:wW7h1TG88eUIJ2i69gaE3uNVtEPIagzhGvHgwfx2Vm4=",
version = "v2.0.5",
sum = "h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=",
version = "v2.0.7",
)
go_repository(
name = "com_github_hashicorp_hcl",
@@ -1975,8 +1975,8 @@ def prysm_deps():
go_repository(
name = "com_github_klauspost_compress",
importpath = "github.com/klauspost/compress",
sum = "h1:60eq2E/jlfwQXtvZEeBUYADs+BwKBWURIY+Gj2eRGjI=",
version = "v1.17.6",
sum = "h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0NAMnU=",
version = "v1.17.8",
)
go_repository(
name = "com_github_klauspost_cpuid",
@@ -2105,8 +2105,8 @@ def prysm_deps():
],
build_file_proto_mode = "disable_global",
importpath = "github.com/libp2p/go-libp2p",
sum = "h1:tvJl9b9M6nSLBtZSXSguq+/lRhRj2oLRkyhBmQNMFLA=",
version = "v0.33.1",
sum = "h1:1xS1Bkr9X7GtdvV6ntLnDV9xB1kNjHK1lZ0eaO6gnhc=",
version = "v0.35.0",
)
go_repository(
name = "com_github_libp2p_go_libp2p_asn_util",
@@ -2124,8 +2124,8 @@ def prysm_deps():
name = "com_github_libp2p_go_libp2p_pubsub",
build_file_proto_mode = "disable_global",
importpath = "github.com/libp2p/go-libp2p-pubsub",
sum = "h1:/RqOZpEtAolsr8/9CC8KqROJSOZeu7lK7fPftn4MwNg=",
version = "v0.10.1",
sum = "h1:+JvS8Kty0OiyUiN0i8H5JbaCgjnJTRnTHe4rU88dLFc=",
version = "v0.11.0",
)
go_repository(
name = "com_github_libp2p_go_libp2p_testing",
@@ -2448,8 +2448,8 @@ def prysm_deps():
go_repository(
name = "com_github_multiformats_go_multiaddr",
importpath = "github.com/multiformats/go-multiaddr",
sum = "h1:9G9sTY/wCYajKa9lyfWPmpZAwe6oV+Wb1zcmMS1HG24=",
version = "v0.12.2",
sum = "h1:rrKqpY9h+n80EwhhC/kkcunCZZ7URIF8yN1WEUt2Hvc=",
version = "v0.12.4",
)
go_repository(
name = "com_github_multiformats_go_multiaddr_dns",
@@ -2577,8 +2577,8 @@ def prysm_deps():
go_repository(
name = "com_github_nxadm_tail",
importpath = "github.com/nxadm/tail",
sum = "h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=",
version = "v1.4.8",
sum = "h1:8feyoE3OzPrcshW5/MJ4sGESc5cqmGkGCWlco4l0bqY=",
version = "v1.4.11",
)
go_repository(
name = "com_github_nytimes_gziphandler",
@@ -2787,26 +2787,26 @@ def prysm_deps():
go_repository(
name = "com_github_pion_datachannel",
importpath = "github.com/pion/datachannel",
sum = "h1:10ef4kwdjije+M9d7Xm9im2Y3O6A6ccQb0zcqZcJew8=",
version = "v1.5.5",
sum = "h1:1IxKJntfSlYkpUj8LlYRSWpYiTTC02nUrOE8T3DqGeg=",
version = "v1.5.6",
)
go_repository(
name = "com_github_pion_dtls_v2",
importpath = "github.com/pion/dtls/v2",
sum = "h1:BUroldfiIbV9jSnC6cKOMnyiORRWrWWpV11JUyEu5OA=",
version = "v2.2.8",
sum = "h1:9U/dpCYl1ySttROPWJgqWKEylUdT0fXp/xst6JwY5Ks=",
version = "v2.2.11",
)
go_repository(
name = "com_github_pion_ice_v2",
importpath = "github.com/pion/ice/v2",
sum = "h1:rZjVmUwyT55cmN8ySMpL7rsS8KYsJERsrxJLLxpKhdw=",
version = "v2.3.11",
sum = "h1:RYgzhH/u5lH0XO+ABatVKCtRd+4U1GEaCXSMjNr13tI=",
version = "v2.3.24",
)
go_repository(
name = "com_github_pion_interceptor",
importpath = "github.com/pion/interceptor",
sum = "h1:pwY9r7P6ToQ3+IF0bajN0xmk/fNw/suTgaTdlwTDmhc=",
version = "v0.1.25",
sum = "h1:39fsnlP1U8gw2JzOFWdfCU82vHvhW9o0rZnZF56wF+M=",
version = "v0.1.29",
)
go_repository(
name = "com_github_pion_logging",
@@ -2817,8 +2817,8 @@ def prysm_deps():
go_repository(
name = "com_github_pion_mdns",
importpath = "github.com/pion/mdns",
sum = "h1:7Ue5KZsqq8EuqStnpPWV33vYYEH0+skdDN5L7EiEsI4=",
version = "v0.0.9",
sum = "h1:CiMYlY+O0azojWDmxdNr7ADGrnZ+V6Ilfner+6mSVK8=",
version = "v0.0.12",
)
go_repository(
name = "com_github_pion_randutil",
@@ -2829,26 +2829,26 @@ def prysm_deps():
go_repository(
name = "com_github_pion_rtcp",
importpath = "github.com/pion/rtcp",
sum = "h1:+EQijuisKwm/8VBs8nWllr0bIndR7Lf7cZG200mpbNo=",
version = "v1.2.13",
sum = "h1:KCkGV3vJ+4DAJmvP0vaQShsb0xkRfWkO540Gy102KyE=",
version = "v1.2.14",
)
go_repository(
name = "com_github_pion_rtp",
importpath = "github.com/pion/rtp",
sum = "h1:VEHxqzSVQxCkKDSHro5/4IUUG1ea+MFdqR2R3xSpNU8=",
version = "v1.8.3",
sum = "h1:MTmn/b0aWWsAzux2AmP8WGllusBVw4NPYPVFFd7jUPw=",
version = "v1.8.6",
)
go_repository(
name = "com_github_pion_sctp",
importpath = "github.com/pion/sctp",
sum = "h1:TP5ZVxV5J7rz7uZmbyvnUvsn7EJ2x/5q9uhsTtXbI3g=",
version = "v1.8.9",
sum = "h1:PKrMs+o9EMLRvFfXq59WFsC+V8mN1wnKzqrv+3D/gYY=",
version = "v1.8.16",
)
go_repository(
name = "com_github_pion_sdp_v3",
importpath = "github.com/pion/sdp/v3",
sum = "h1:WuDLhtuFUUVpTfus9ILC4HRyHsW6TdugjEX/QY9OiUw=",
version = "v3.0.6",
sum = "h1:pX++dCHoHUwq43kuwf3PyJfHlwIj4hXA7Vrifiq0IJY=",
version = "v3.0.9",
)
go_repository(
name = "com_github_pion_srtp_v2",
@@ -2865,20 +2865,26 @@ def prysm_deps():
go_repository(
name = "com_github_pion_transport_v2",
importpath = "github.com/pion/transport/v2",
sum = "h1:41JJK6DZQYSeVLxILA2+F4ZkKb4Xd/tFJZRFZQ9QAlo=",
version = "v2.2.4",
sum = "h1:iyi25i/21gQck4hfRhomF6SktmUQjRsRW4WJdhfc3Kc=",
version = "v2.2.5",
)
go_repository(
name = "com_github_pion_transport_v3",
importpath = "github.com/pion/transport/v3",
sum = "h1:r+40RJR25S9w3jbA6/5uEPTzcdn7ncyU44RWCbHkLg4=",
version = "v3.0.2",
)
go_repository(
name = "com_github_pion_turn_v2",
importpath = "github.com/pion/turn/v2",
sum = "h1:2xn8rduI5W6sCZQkEnIUDAkrBQNl2eYIBCHMZ3QMmP8=",
version = "v2.1.4",
sum = "h1:Xr2niVsiPTB0FPtt+yAWKFUkU1eotQbGgpTIld4x1Gc=",
version = "v2.1.6",
)
go_repository(
name = "com_github_pion_webrtc_v3",
importpath = "github.com/pion/webrtc/v3",
sum = "h1:GbqEuxBbVLFhXk0GwxKAoaIJYiEa9TyoZPEZC+2HZxM=",
version = "v3.2.23",
sum = "h1:Wtfi6AZMQg+624cvCXUuSmrKWepSB7zfgYDOYqsSOVU=",
version = "v3.2.40",
)
go_repository(
name = "com_github_pkg_diff",
@@ -2925,20 +2931,20 @@ def prysm_deps():
go_repository(
name = "com_github_prometheus_client_golang",
importpath = "github.com/prometheus/client_golang",
sum = "h1:HzFfmkOzH5Q8L8G+kSJKUx5dtG87sewO+FoDDqP5Tbk=",
version = "v1.18.0",
sum = "h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE=",
version = "v1.19.1",
)
go_repository(
name = "com_github_prometheus_client_model",
importpath = "github.com/prometheus/client_model",
sum = "h1:k1v3CzpSRUTrKMppY35TLwPvxHqBu0bYgxZzqGIgaos=",
version = "v0.6.0",
sum = "h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=",
version = "v0.6.1",
)
go_repository(
name = "com_github_prometheus_common",
importpath = "github.com/prometheus/common",
sum = "h1:p5Cz0FNHo7SnWOmWmoRozVcjEp0bIVU8cV7OShpjL1k=",
version = "v0.47.0",
sum = "h1:QO8U2CdOzSn1BBsmXJXduaaW+dY/5QLjfB8svtSzKKE=",
version = "v0.48.0",
)
go_repository(
name = "com_github_prometheus_procfs",
@@ -3015,15 +3021,6 @@ def prysm_deps():
sum = "h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo=",
version = "v0.4.0",
)
go_repository(
name = "com_github_quic_go_qtls_go1_20",
build_directives = [
"gazelle:exclude generate_cert.go",
],
importpath = "github.com/quic-go/qtls-go1-20",
sum = "h1:MfFAPULvst4yoMgY9QmtpYmfij/em7O8UUi+bNVm7Cg=",
version = "v0.3.4",
)
go_repository(
name = "com_github_quic_go_quic_go",
build_directives = [
@@ -3031,14 +3028,14 @@ def prysm_deps():
"gazelle:exclude tools.go",
],
importpath = "github.com/quic-go/quic-go",
sum = "h1:uSfdap0eveIl8KXnipv9K7nlwZ5IqLlYOpJ58u5utpM=",
version = "v0.42.0",
sum = "h1:So5wOr7jyO4vzL2sd8/pD9Kesciv91zSk8BoFngItQ0=",
version = "v0.44.0",
)
go_repository(
name = "com_github_quic_go_webtransport_go",
importpath = "github.com/quic-go/webtransport-go",
sum = "h1:CvNsKqc4W2HljHJnoT+rMmbRJybShZ0YPFDD3NxaZLY=",
version = "v0.6.0",
sum = "h1:HxSrwun11U+LlmwpgM1kEqIqH90IT4N8auv/cD7QFJg=",
version = "v0.8.0",
)
go_repository(
name = "com_github_raulk_go_watchdog",
@@ -3128,6 +3125,12 @@ def prysm_deps():
sum = "h1:nMinx+JaEm/zJz4cEyClQeAw5rsYSB5th3xv+5lV6Vg=",
version = "v3.3.4",
)
go_repository(
name = "com_github_sclevine_agouti",
importpath = "github.com/sclevine/agouti",
sum = "h1:8IBJS6PWz3uTlMP3YBIR5f+KAldcGuOeFkFbUWfBgK4=",
version = "v3.0.0+incompatible",
)
go_repository(
name = "com_github_sean_seed",
importpath = "github.com/sean-/seed",
@@ -3407,14 +3410,14 @@ def prysm_deps():
go_repository(
name = "com_github_stretchr_objx",
importpath = "github.com/stretchr/objx",
sum = "h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=",
version = "v0.5.0",
sum = "h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=",
version = "v0.5.2",
)
go_repository(
name = "com_github_stretchr_testify",
importpath = "github.com/stretchr/testify",
sum = "h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=",
version = "v1.8.4",
sum = "h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=",
version = "v1.9.0",
)
go_repository(
name = "com_github_subosito_gotenv",
@@ -4783,8 +4786,8 @@ def prysm_deps():
go_repository(
name = "org_golang_google_protobuf",
importpath = "google.golang.org/protobuf",
sum = "h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I=",
version = "v1.32.0",
sum = "h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg=",
version = "v1.34.1",
)
go_repository(
name = "org_golang_x_build",
@@ -4795,14 +4798,14 @@ def prysm_deps():
go_repository(
name = "org_golang_x_crypto",
importpath = "golang.org/x/crypto",
sum = "h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo=",
version = "v0.19.0",
sum = "h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=",
version = "v0.23.0",
)
go_repository(
name = "org_golang_x_exp",
importpath = "golang.org/x/exp",
sum = "h1:HinSgX1tJRX3KsL//Gxynpw5CTOAIPhgL4W8PNiIpVE=",
version = "v0.0.0-20240213143201-ec583247a57a",
sum = "h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM=",
version = "v0.0.0-20240506185415-9bf2ced13842",
)
go_repository(
name = "org_golang_x_exp_typeparams",
@@ -4831,14 +4834,14 @@ def prysm_deps():
go_repository(
name = "org_golang_x_mod",
importpath = "golang.org/x/mod",
sum = "h1:SernR4v+D55NyBH2QiEQrlBAnj1ECL6AGrA5+dPaMY8=",
version = "v0.15.0",
sum = "h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA=",
version = "v0.17.0",
)
go_repository(
name = "org_golang_x_net",
importpath = "golang.org/x/net",
sum = "h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4=",
version = "v0.21.0",
sum = "h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=",
version = "v0.25.0",
)
go_repository(
name = "org_golang_x_oauth2",
@@ -4855,32 +4858,32 @@ def prysm_deps():
go_repository(
name = "org_golang_x_sync",
importpath = "golang.org/x/sync",
sum = "h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=",
version = "v0.6.0",
sum = "h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=",
version = "v0.7.0",
)
go_repository(
name = "org_golang_x_sys",
importpath = "golang.org/x/sys",
sum = "h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y=",
version = "v0.17.0",
sum = "h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=",
version = "v0.20.0",
)
go_repository(
name = "org_golang_x_telemetry",
importpath = "golang.org/x/telemetry",
sum = "h1:+Kc94D8UVEVxJnLXp/+FMfqQARZtWHfVrcRtcG8aT3g=",
version = "v0.0.0-20240208230135-b75ee8823808",
sum = "h1:IRJeR9r1pYWsHKTRe/IInb7lYvbBVIqOgsX/u0mbOWY=",
version = "v0.0.0-20240228155512-f48c80bd79b2",
)
go_repository(
name = "org_golang_x_term",
importpath = "golang.org/x/term",
sum = "h1:mkTF7LCd6WGJNL3K1Ad7kwxNfYAW6a8a8QqtMblp/4U=",
version = "v0.17.0",
sum = "h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw=",
version = "v0.20.0",
)
go_repository(
name = "org_golang_x_text",
importpath = "golang.org/x/text",
sum = "h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=",
version = "v0.14.0",
sum = "h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk=",
version = "v0.15.0",
)
go_repository(
name = "org_golang_x_time",
@@ -4891,8 +4894,8 @@ def prysm_deps():
go_repository(
name = "org_golang_x_tools",
importpath = "golang.org/x/tools",
sum = "h1:k8NLag8AGHnn+PHbl7g43CtqZAwG60vZkLqgyZgIHgQ=",
version = "v0.18.0",
sum = "h1:qc0xYgIbsSDt9EyWz05J5wfa7LOVW0YTLOXrqdLAWIw=",
version = "v0.21.0",
)
go_repository(
name = "org_golang_x_xerrors",
@@ -4903,8 +4906,8 @@ def prysm_deps():
go_repository(
name = "org_uber_go_atomic",
importpath = "go.uber.org/atomic",
sum = "h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=",
version = "v1.11.0",
sum = "h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=",
version = "v1.7.0",
)
go_repository(
name = "org_uber_go_automaxprocs",
@@ -4926,8 +4929,8 @@ def prysm_deps():
go_repository(
name = "org_uber_go_fx",
importpath = "go.uber.org/fx",
sum = "h1:zVwVQGS8zYvhh9Xxcu4w1M6ESyeMzebzj2NbSayZ4Mk=",
version = "v1.20.1",
sum = "h1:RqBh3cYdzZS0uqwVeEjOX2p73dddLpym315myy/Bpb0=",
version = "v1.21.1",
)
go_repository(
name = "org_uber_go_goleak",

68
go.mod
View File

@@ -25,7 +25,7 @@ require (
github.com/gogo/protobuf v1.3.2
github.com/golang-jwt/jwt/v4 v4.5.0
github.com/golang/gddo v0.0.0-20200528160355-8d077c1d8f4c
github.com/golang/protobuf v1.5.3
github.com/golang/protobuf v1.5.4
github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb
github.com/google/go-cmp v0.6.0
github.com/google/gofuzz v1.2.0
@@ -45,9 +45,9 @@ require (
github.com/json-iterator/go v1.1.12
github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213
github.com/kr/pretty v0.3.1
github.com/libp2p/go-libp2p v0.33.1
github.com/libp2p/go-libp2p v0.35.0
github.com/libp2p/go-libp2p-mplex v0.9.0
github.com/libp2p/go-libp2p-pubsub v0.10.1
github.com/libp2p/go-libp2p-pubsub v0.11.0
github.com/libp2p/go-mplex v0.7.0
github.com/logrusorgru/aurora v2.0.3+incompatible
github.com/manifoldco/promptui v0.7.0
@@ -55,15 +55,15 @@ require (
github.com/minio/highwayhash v1.0.2
github.com/minio/sha256-simd v1.0.1
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826
github.com/multiformats/go-multiaddr v0.12.2
github.com/multiformats/go-multiaddr v0.12.4
github.com/onsi/ginkgo v1.16.5
github.com/onsi/gomega v1.30.0
github.com/patrickmn/go-cache v2.1.0+incompatible
github.com/paulbellamy/ratecounter v0.2.0
github.com/pborman/uuid v1.2.1
github.com/pkg/errors v0.9.1
github.com/prometheus/client_golang v1.18.0
github.com/prometheus/client_model v0.6.0
github.com/prometheus/client_golang v1.19.1
github.com/prometheus/client_model v0.6.1
github.com/prometheus/prom2json v1.3.0
github.com/prysmaticlabs/fastssz v0.0.0-20221107182844-78142813af44
github.com/prysmaticlabs/go-bitfield v0.0.0-20210809151128-385d8c5e3fb7
@@ -74,7 +74,7 @@ require (
github.com/sirupsen/logrus v1.9.0
github.com/spf13/afero v1.10.0
github.com/status-im/keycard-go v0.2.0
github.com/stretchr/testify v1.8.4
github.com/stretchr/testify v1.9.0
github.com/supranational/blst v0.3.11
github.com/thomaso-mirodin/intmath v0.0.0-20160323211736-5dc6d854e46e
github.com/trailofbits/go-mutexasserts v0.0.0-20230328101604-8cdbc5f3d279
@@ -88,14 +88,14 @@ require (
go.opencensus.io v0.24.0
go.uber.org/automaxprocs v1.5.2
go.uber.org/mock v0.4.0
golang.org/x/crypto v0.21.0
golang.org/x/exp v0.0.0-20240213143201-ec583247a57a
golang.org/x/mod v0.15.0
golang.org/x/sync v0.6.0
golang.org/x/tools v0.18.0
golang.org/x/crypto v0.23.0
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842
golang.org/x/mod v0.17.0
golang.org/x/sync v0.7.0
golang.org/x/tools v0.21.0
google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1
google.golang.org/grpc v1.56.3
google.golang.org/protobuf v1.32.0
google.golang.org/protobuf v1.34.1
gopkg.in/d4l3k/messagediff.v1 v1.2.1
gopkg.in/yaml.v2 v2.4.0
gopkg.in/yaml.v3 v3.0.1
@@ -128,7 +128,7 @@ require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect
github.com/deckarep/golang-set/v2 v2.5.0 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect
github.com/deepmap/oapi-codegen v1.8.2 // indirect
github.com/dlclark/regexp2 v1.7.0 // indirect
github.com/docker/go-units v0.5.0 // indirect
@@ -152,7 +152,7 @@ require (
github.com/gorilla/websocket v1.5.1 // indirect
github.com/graph-gophers/graphql-go v1.3.0 // indirect
github.com/hashicorp/go-bexpr v0.1.10 // indirect
github.com/hashicorp/golang-lru/v2 v2.0.5 // indirect
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
github.com/holiman/billy v0.0.0-20230718173358-1c7e68d277a7 // indirect
github.com/holiman/bloomfilter/v2 v2.0.3 // indirect
github.com/holiman/goevmlab v0.0.0-20231201084119-c73b3c97929c // indirect
@@ -165,7 +165,7 @@ require (
github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect
github.com/juju/ansiterm v0.0.0-20180109212912-720a0952cc2a // indirect
github.com/karalabe/usb v0.0.3-0.20230711191512-61db3e06439c // indirect
github.com/klauspost/compress v1.17.6 // indirect
github.com/klauspost/compress v1.17.8 // indirect
github.com/klauspost/cpuid/v2 v2.2.7 // indirect
github.com/koron/go-ssdp v0.0.4 // indirect
github.com/kr/text v0.2.0 // indirect
@@ -203,25 +203,41 @@ require (
github.com/multiformats/go-multihash v0.2.3 // indirect
github.com/multiformats/go-multistream v0.5.0 // indirect
github.com/multiformats/go-varint v0.0.7 // indirect
github.com/nxadm/tail v1.4.8 // indirect
github.com/nxadm/tail v1.4.11 // indirect
github.com/olekukonko/tablewriter v0.0.5 // indirect
github.com/onsi/ginkgo/v2 v2.15.0 // indirect
github.com/opencontainers/runtime-spec v1.2.0 // indirect
github.com/opentracing/opentracing-go v1.2.0 // indirect
github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect
github.com/pion/datachannel v1.5.6 // indirect
github.com/pion/dtls/v2 v2.2.11 // indirect
github.com/pion/ice/v2 v2.3.24 // indirect
github.com/pion/interceptor v0.1.29 // indirect
github.com/pion/logging v0.2.2 // indirect
github.com/pion/mdns v0.0.12 // indirect
github.com/pion/randutil v0.1.0 // indirect
github.com/pion/rtcp v1.2.14 // indirect
github.com/pion/rtp v1.8.6 // indirect
github.com/pion/sctp v1.8.16 // indirect
github.com/pion/sdp/v3 v3.0.9 // indirect
github.com/pion/srtp/v2 v2.0.18 // indirect
github.com/pion/stun v0.6.1 // indirect
github.com/pion/transport/v2 v2.2.5 // indirect
github.com/pion/turn/v2 v2.1.6 // indirect
github.com/pion/webrtc/v3 v3.2.40 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/prometheus/common v0.47.0 // indirect
github.com/prometheus/common v0.48.0 // indirect
github.com/prometheus/procfs v0.12.0 // indirect
github.com/quic-go/qpack v0.4.0 // indirect
github.com/quic-go/quic-go v0.42.0 // indirect
github.com/quic-go/webtransport-go v0.6.0 // indirect
github.com/quic-go/quic-go v0.44.0 // indirect
github.com/quic-go/webtransport-go v0.8.0 // indirect
github.com/raulk/go-watchdog v1.3.0 // indirect
github.com/rivo/uniseg v0.4.4 // indirect
github.com/rogpeppe/go-internal v1.11.0 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/shirou/gopsutil v3.21.11+incompatible // indirect
github.com/spaolacci/murmur3 v1.1.0 // indirect
github.com/stretchr/objx v0.5.0 // indirect
github.com/stretchr/objx v0.5.2 // indirect
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect
github.com/tklauser/go-sysconf v0.3.13 // indirect
github.com/tklauser/numcpus v0.7.0 // indirect
@@ -230,14 +246,14 @@ require (
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
github.com/yusufpapurcu/wmi v1.2.3 // indirect
go.uber.org/dig v1.17.1 // indirect
go.uber.org/fx v1.20.1 // indirect
go.uber.org/fx v1.21.1 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.27.0 // indirect
golang.org/x/exp/typeparams v0.0.0-20231108232855-2478ac86f678 // indirect
golang.org/x/net v0.23.0 // indirect
golang.org/x/net v0.25.0 // indirect
golang.org/x/oauth2 v0.16.0 // indirect
golang.org/x/term v0.18.0 // indirect
golang.org/x/text v0.14.0 // indirect
golang.org/x/term v0.20.0 // indirect
golang.org/x/text v0.15.0 // indirect
golang.org/x/time v0.5.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect
@@ -257,7 +273,7 @@ require (
github.com/go-playground/validator/v10 v10.13.0
github.com/peterh/liner v1.2.0 // indirect
github.com/prysmaticlabs/gohashtree v0.0.4-beta
golang.org/x/sys v0.18.0 // indirect
golang.org/x/sys v0.20.0 // indirect
google.golang.org/api v0.44.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
k8s.io/klog/v2 v2.80.0 // indirect

179
go.sum
View File

@@ -215,8 +215,8 @@ github.com/deckarep/golang-set/v2 v2.5.0 h1:hn6cEZtQ0h3J8kFrHR/NrzyOoTnjgW1+FmNJ
github.com/deckarep/golang-set/v2 v2.5.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4=
github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y=
github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 h1:rpfIENRNNilwHwZeG5+P150SMrnNEcHYvcCuK6dPZSg=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0=
github.com/deepmap/oapi-codegen v1.6.0/go.mod h1:ryDa9AgbELGeB+YEXE1dR53yAjHwFvE9iAUlWl9Al3M=
github.com/deepmap/oapi-codegen v1.8.2 h1:SegyeYGcdi0jLLrpbCMoJxnUUn8GBXHsvr4rbzjuhfU=
github.com/deepmap/oapi-codegen v1.8.2/go.mod h1:YLgSKSDv/bZQB7N4ws6luhozi3cEdRktEqrX88CvjIw=
@@ -405,8 +405,8 @@ github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
github.com/golang/snappy v0.0.0-20170215233205-553a64147049/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
@@ -462,6 +462,7 @@ github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4=
github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY=
@@ -521,8 +522,8 @@ github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d h1:dg1dEPuWpEqDnvIw251EVy4zlP8gWbsGj4BsUKCRpYs=
github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
github.com/hashicorp/golang-lru/v2 v2.0.5 h1:wW7h1TG88eUIJ2i69gaE3uNVtEPIagzhGvHgwfx2Vm4=
github.com/hashicorp/golang-lru/v2 v2.0.5/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=
github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
github.com/hashicorp/hcl v0.0.0-20170914154624-68e816d1c783/go.mod h1:oZtUIOe8dh44I2q6ScRibXws4Ajl+d+nod3AaR9vL5w=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
@@ -597,8 +598,8 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o
github.com/klauspost/compress v1.9.8/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
github.com/klauspost/compress v1.10.1/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/klauspost/compress v1.17.6 h1:60eq2E/jlfwQXtvZEeBUYADs+BwKBWURIY+Gj2eRGjI=
github.com/klauspost/compress v1.17.6/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM=
github.com/klauspost/compress v1.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0NAMnU=
github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
github.com/klauspost/cpuid v1.2.3/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM=
github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
@@ -635,14 +636,14 @@ github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6
github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg=
github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM=
github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro=
github.com/libp2p/go-libp2p v0.33.1 h1:tvJl9b9M6nSLBtZSXSguq+/lRhRj2oLRkyhBmQNMFLA=
github.com/libp2p/go-libp2p v0.33.1/go.mod h1:zOUTMjG4I7TXwMndNyOBn/CNtVBLlvBlnxfi+8xzx+E=
github.com/libp2p/go-libp2p v0.35.0 h1:1xS1Bkr9X7GtdvV6ntLnDV9xB1kNjHK1lZ0eaO6gnhc=
github.com/libp2p/go-libp2p v0.35.0/go.mod h1:snyJQix4ET6Tj+LeI0VPjjxTtdWpeOhYt5lEY0KirkQ=
github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl950SO9L6n94=
github.com/libp2p/go-libp2p-asn-util v0.4.1/go.mod h1:d/NI6XZ9qxw67b4e+NgpQexCIiFYJjErASrYW4PFDN8=
github.com/libp2p/go-libp2p-mplex v0.9.0 h1:R58pDRAmuBXkYugbSSXR9wrTX3+1pFM1xP2bLuodIq8=
github.com/libp2p/go-libp2p-mplex v0.9.0/go.mod h1:ro1i4kuwiFT+uMPbIDIFkcLs1KRbNp0QwnUXM+P64Og=
github.com/libp2p/go-libp2p-pubsub v0.10.1 h1:/RqOZpEtAolsr8/9CC8KqROJSOZeu7lK7fPftn4MwNg=
github.com/libp2p/go-libp2p-pubsub v0.10.1/go.mod h1:1OxbaT/pFRO5h+Dpze8hdHQ63R0ke55XTs6b6NwLLkw=
github.com/libp2p/go-libp2p-pubsub v0.11.0 h1:+JvS8Kty0OiyUiN0i8H5JbaCgjnJTRnTHe4rU88dLFc=
github.com/libp2p/go-libp2p-pubsub v0.11.0/go.mod h1:QEb+hEV9WL9wCiUAnpY29FZR6W3zK8qYlaml8R4q6gQ=
github.com/libp2p/go-libp2p-testing v0.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUIK5WDu6iPUA=
github.com/libp2p/go-libp2p-testing v0.12.0/go.mod h1:KcGDRXyN7sQCllucn1cOOS+Dmm7ujhfEyXQL5lvkcPg=
github.com/libp2p/go-mplex v0.7.0 h1:BDhFZdlk5tbr0oyFq/xv/NPGfjbnrsDam1EvutpBDbY=
@@ -758,8 +759,8 @@ github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9
github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a1UV0xHgWc0hkp4=
github.com/multiformats/go-multiaddr v0.1.1/go.mod h1:aMKBKNEYmzmDmxfX88/vz+J5IU55txyt0p4aiWVohjo=
github.com/multiformats/go-multiaddr v0.2.0/go.mod h1:0nO36NvPpyV4QzvTLi/lafl2y95ncPj0vFwVF6k6wJ4=
github.com/multiformats/go-multiaddr v0.12.2 h1:9G9sTY/wCYajKa9lyfWPmpZAwe6oV+Wb1zcmMS1HG24=
github.com/multiformats/go-multiaddr v0.12.2/go.mod h1:GKyaTYjZRdcUhyOetrxTk9z0cW+jA/YrnqTOvKgi44M=
github.com/multiformats/go-multiaddr v0.12.4 h1:rrKqpY9h+n80EwhhC/kkcunCZZ7URIF8yN1WEUt2Hvc=
github.com/multiformats/go-multiaddr v0.12.4/go.mod h1:sBXrNzucqkFJhvKOiwwLyqamGa/P5EIXNPLovyhQCII=
github.com/multiformats/go-multiaddr-dns v0.3.1 h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A=
github.com/multiformats/go-multiaddr-dns v0.3.1/go.mod h1:G/245BRQ6FJGmryJCrOuTdB37AMA5AMOVuO6NY3JwTk=
github.com/multiformats/go-multiaddr-fmt v0.1.0 h1:WLEFClPycPkp4fnIzoFoV9FVd49/eQsuaL3/CWe167E=
@@ -791,8 +792,9 @@ github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJE
github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM=
github.com/nishanths/predeclared v0.0.0-20200524104333-86fad755b4d3/go.mod h1:nt3d53pc1VYcphSCIaYAJtnPYnr3Zyn8fMq2wvPGPso=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
github.com/nxadm/tail v1.4.11 h1:8feyoE3OzPrcshW5/MJ4sGESc5cqmGkGCWlco4l0bqY=
github.com/nxadm/tail v1.4.11/go.mod h1:OTaG3NK980DZzxbRq6lEuzgU+mug70nY11sMd4JXXHc=
github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs=
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
@@ -861,6 +863,50 @@ github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi
github.com/pierrec/lz4 v2.4.1+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4=
github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8=
github.com/pion/datachannel v1.5.6 h1:1IxKJntfSlYkpUj8LlYRSWpYiTTC02nUrOE8T3DqGeg=
github.com/pion/datachannel v1.5.6/go.mod h1:1eKT6Q85pRnr2mHiWHxJwO50SfZRtWHTsNIVb/NfGW4=
github.com/pion/dtls/v2 v2.2.7/go.mod h1:8WiMkebSHFD0T+dIU+UeBaoV7kDhOW5oDCzZ7WZ/F9s=
github.com/pion/dtls/v2 v2.2.11 h1:9U/dpCYl1ySttROPWJgqWKEylUdT0fXp/xst6JwY5Ks=
github.com/pion/dtls/v2 v2.2.11/go.mod h1:d9SYc9fch0CqK90mRk1dC7AkzzpwJj6u2GU3u+9pqFE=
github.com/pion/ice/v2 v2.3.24 h1:RYgzhH/u5lH0XO+ABatVKCtRd+4U1GEaCXSMjNr13tI=
github.com/pion/ice/v2 v2.3.24/go.mod h1:KXJJcZK7E8WzrBEYnV4UtqEZsGeWfHxsNqhVcVvgjxw=
github.com/pion/interceptor v0.1.29 h1:39fsnlP1U8gw2JzOFWdfCU82vHvhW9o0rZnZF56wF+M=
github.com/pion/interceptor v0.1.29/go.mod h1:ri+LGNjRUc5xUNtDEPzfdkmSqISixVTBF/z/Zms/6T4=
github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY=
github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms=
github.com/pion/mdns v0.0.12 h1:CiMYlY+O0azojWDmxdNr7ADGrnZ+V6Ilfner+6mSVK8=
github.com/pion/mdns v0.0.12/go.mod h1:VExJjv8to/6Wqm1FXK+Ii/Z9tsVk/F5sD/N70cnYFbk=
github.com/pion/randutil v0.1.0 h1:CFG1UdESneORglEsnimhUjf33Rwjubwj6xfiOXBa3mA=
github.com/pion/randutil v0.1.0/go.mod h1:XcJrSMMbbMRhASFVOlj/5hQial/Y8oH/HVo7TBZq+j8=
github.com/pion/rtcp v1.2.12/go.mod h1:sn6qjxvnwyAkkPzPULIbVqSKI5Dv54Rv7VG0kNxh9L4=
github.com/pion/rtcp v1.2.14 h1:KCkGV3vJ+4DAJmvP0vaQShsb0xkRfWkO540Gy102KyE=
github.com/pion/rtcp v1.2.14/go.mod h1:sn6qjxvnwyAkkPzPULIbVqSKI5Dv54Rv7VG0kNxh9L4=
github.com/pion/rtp v1.8.3/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU=
github.com/pion/rtp v1.8.6 h1:MTmn/b0aWWsAzux2AmP8WGllusBVw4NPYPVFFd7jUPw=
github.com/pion/rtp v1.8.6/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU=
github.com/pion/sctp v1.8.13/go.mod h1:YKSgO/bO/6aOMP9LCie1DuD7m+GamiK2yIiPM6vH+GA=
github.com/pion/sctp v1.8.16 h1:PKrMs+o9EMLRvFfXq59WFsC+V8mN1wnKzqrv+3D/gYY=
github.com/pion/sctp v1.8.16/go.mod h1:P6PbDVA++OJMrVNg2AL3XtYHV4uD6dvfyOovCgMs0PE=
github.com/pion/sdp/v3 v3.0.9 h1:pX++dCHoHUwq43kuwf3PyJfHlwIj4hXA7Vrifiq0IJY=
github.com/pion/sdp/v3 v3.0.9/go.mod h1:B5xmvENq5IXJimIO4zfp6LAe1fD9N+kFv+V/1lOdz8M=
github.com/pion/srtp/v2 v2.0.18 h1:vKpAXfawO9RtTRKZJbG4y0v1b11NZxQnxRl85kGuUlo=
github.com/pion/srtp/v2 v2.0.18/go.mod h1:0KJQjA99A6/a0DOVTu1PhDSw0CXF2jTkqOoMg3ODqdA=
github.com/pion/stun v0.6.1 h1:8lp6YejULeHBF8NmV8e2787BogQhduZugh5PdhDyyN4=
github.com/pion/stun v0.6.1/go.mod h1:/hO7APkX4hZKu/D0f2lHzNyvdkTGtIy3NDmLR7kSz/8=
github.com/pion/transport/v2 v2.2.1/go.mod h1:cXXWavvCnFF6McHTft3DWS9iic2Mftcz1Aq29pGcU5g=
github.com/pion/transport/v2 v2.2.2/go.mod h1:OJg3ojoBJopjEeECq2yJdXH9YVrUJ1uQ++NjXLOUorc=
github.com/pion/transport/v2 v2.2.3/go.mod h1:q2U/tf9FEfnSBGSW6w5Qp5PFWRLRj3NjLhCCgpRK4p0=
github.com/pion/transport/v2 v2.2.4/go.mod h1:q2U/tf9FEfnSBGSW6w5Qp5PFWRLRj3NjLhCCgpRK4p0=
github.com/pion/transport/v2 v2.2.5 h1:iyi25i/21gQck4hfRhomF6SktmUQjRsRW4WJdhfc3Kc=
github.com/pion/transport/v2 v2.2.5/go.mod h1:q2U/tf9FEfnSBGSW6w5Qp5PFWRLRj3NjLhCCgpRK4p0=
github.com/pion/transport/v3 v3.0.1/go.mod h1:UY7kiITrlMv7/IKgd5eTUcaahZx5oUN3l9SzK5f5xE0=
github.com/pion/transport/v3 v3.0.2 h1:r+40RJR25S9w3jbA6/5uEPTzcdn7ncyU44RWCbHkLg4=
github.com/pion/transport/v3 v3.0.2/go.mod h1:nIToODoOlb5If2jF9y2Igfx3PFYWfuXi37m0IlWa/D0=
github.com/pion/turn/v2 v2.1.3/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY=
github.com/pion/turn/v2 v2.1.6 h1:Xr2niVsiPTB0FPtt+yAWKFUkU1eotQbGgpTIld4x1Gc=
github.com/pion/turn/v2 v2.1.6/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY=
github.com/pion/webrtc/v3 v3.2.40 h1:Wtfi6AZMQg+624cvCXUuSmrKWepSB7zfgYDOYqsSOVU=
github.com/pion/webrtc/v3 v3.2.40/go.mod h1:M1RAe3TNTD1tzyvqHrbVODfwdPGSXOUo/OgpoGGJqFY=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
@@ -885,16 +931,16 @@ github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeD
github.com/prometheus/client_golang v1.4.1/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU=
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
github.com/prometheus/client_golang v1.9.0/go.mod h1:FqZLKOZnGdFAhOK4nqGHa7D66IdsO+O441Eve7ptJDU=
github.com/prometheus/client_golang v1.18.0 h1:HzFfmkOzH5Q8L8G+kSJKUx5dtG87sewO+FoDDqP5Tbk=
github.com/prometheus/client_golang v1.18.0/go.mod h1:T+GXkCk5wSJyOqMIzVgvvjFDlkOQntgjkJWKrN5txjA=
github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE=
github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.6.0 h1:k1v3CzpSRUTrKMppY35TLwPvxHqBu0bYgxZzqGIgaos=
github.com/prometheus/client_model v0.6.0/go.mod h1:NTQHnmxFpouOD0DpvP4XujX3CdOAGQPoaGhyTchlyt8=
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
@@ -904,8 +950,8 @@ github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt2
github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4=
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
github.com/prometheus/common v0.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s=
github.com/prometheus/common v0.47.0 h1:p5Cz0FNHo7SnWOmWmoRozVcjEp0bIVU8cV7OShpjL1k=
github.com/prometheus/common v0.47.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc=
github.com/prometheus/common v0.48.0 h1:QO8U2CdOzSn1BBsmXJXduaaW+dY/5QLjfB8svtSzKKE=
github.com/prometheus/common v0.48.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc=
github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
@@ -935,10 +981,10 @@ github.com/prysmaticlabs/protoc-gen-go-cast v0.0.0-20230228205207-28762a7b9294 h
github.com/prysmaticlabs/protoc-gen-go-cast v0.0.0-20230228205207-28762a7b9294/go.mod h1:ZVEbRdnMkGhp/pu35zq4SXxtvUwWK0J1MATtekZpH2Y=
github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo=
github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A=
github.com/quic-go/quic-go v0.42.0 h1:uSfdap0eveIl8KXnipv9K7nlwZ5IqLlYOpJ58u5utpM=
github.com/quic-go/quic-go v0.42.0/go.mod h1:132kz4kL3F9vxhW3CtQJLDVwcFe5wdWeJXXijhsO57M=
github.com/quic-go/webtransport-go v0.6.0 h1:CvNsKqc4W2HljHJnoT+rMmbRJybShZ0YPFDD3NxaZLY=
github.com/quic-go/webtransport-go v0.6.0/go.mod h1:9KjU4AEBqEQidGHNDkZrb8CAa1abRaosM2yGOyiikEc=
github.com/quic-go/quic-go v0.44.0 h1:So5wOr7jyO4vzL2sd8/pD9Kesciv91zSk8BoFngItQ0=
github.com/quic-go/quic-go v0.44.0/go.mod h1:z4cx/9Ny9UtGITIPzmPTXh1ULfOyWh4qGQlpnPcWmek=
github.com/quic-go/webtransport-go v0.8.0 h1:HxSrwun11U+LlmwpgM1kEqIqH90IT4N8auv/cD7QFJg=
github.com/quic-go/webtransport-go v0.8.0/go.mod h1:N99tjprW432Ut5ONql/aUhSLT0YVSlwHohQsuac9WaM=
github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk=
github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtDqv66NfsMU=
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
@@ -1034,8 +1080,9 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
@@ -1046,8 +1093,10 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
github.com/supranational/blst v0.3.11 h1:LyU6FolezeWAhvQk0k6O/d49jqgO52MSDDfYgbeoEm4=
github.com/supranational/blst v0.3.11/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw=
@@ -1135,14 +1184,12 @@ go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
go.uber.org/automaxprocs v1.5.2 h1:2LxUOGiR3O6tw8ui5sZa2LAaHnsviZdVOUZw4fvbnME=
go.uber.org/automaxprocs v1.5.2/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0=
go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc=
go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE=
go.uber.org/fx v1.20.1 h1:zVwVQGS8zYvhh9Xxcu4w1M6ESyeMzebzj2NbSayZ4Mk=
go.uber.org/fx v1.20.1/go.mod h1:iSYNbHf2y55acNCwCXKx7LbWb5WG1Bnue5RDXz1OREg=
go.uber.org/fx v1.21.1 h1:RqBh3cYdzZS0uqwVeEjOX2p73dddLpym315myy/Bpb0=
go.uber.org/fx v1.21.1/go.mod h1:HT2M7d7RHo+ebKGh9NRcrsrHHfpZ60nW3QRubMRfv48=
go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
@@ -1185,8 +1232,14 @@ golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA=
golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE=
golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio=
golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@@ -1198,8 +1251,8 @@ golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u0
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw=
golang.org/x/exp v0.0.0-20240213143201-ec583247a57a h1:HinSgX1tJRX3KsL//Gxynpw5CTOAIPhgL4W8PNiIpVE=
golang.org/x/exp v0.0.0-20240213143201-ec583247a57a/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc=
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM=
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc=
golang.org/x/exp/typeparams v0.0.0-20231108232855-2478ac86f678 h1:1P7xPZEwZMoBoz0Yze5Nx2/4pxj6nw9ZqHWXqP0iRgQ=
golang.org/x/exp/typeparams v0.0.0-20231108232855-2478ac86f678/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
@@ -1228,8 +1281,9 @@ golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.15.0 h1:SernR4v+D55NyBH2QiEQrlBAnj1ECL6AGrA5+dPaMY8=
golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA=
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -1282,8 +1336,16 @@ golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLd
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs=
golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.13.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI=
golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
golang.org/x/oauth2 v0.0.0-20170912212905-13449ad91cb2/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
@@ -1316,8 +1378,9 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -1409,14 +1472,30 @@ golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY=
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o=
golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU=
golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY=
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58=
golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw=
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -1427,8 +1506,13 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk=
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/time v0.0.0-20170424234030-8be79e1e0910/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@@ -1506,8 +1590,9 @@ golang.org/x/tools v0.1.1-0.20210205202024-ef80cdb6ec6d/go.mod h1:9bzcO0MWcOuT0t
golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.18.0 h1:k8NLag8AGHnn+PHbl7g43CtqZAwG60vZkLqgyZgIHgQ=
golang.org/x/tools v0.18.0/go.mod h1:GL7B4CwcLLeo59yx/9UWWuNOW1n3VZ4f5axWfML7Lcg=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.21.0 h1:qc0xYgIbsSDt9EyWz05J5wfa7LOVW0YTLOXrqdLAWIw=
golang.org/x/tools v0.21.0/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -1649,8 +1734,8 @@ google.golang.org/protobuf v1.25.1-0.20200805231151-a709e31e5d12/go.mod h1:9JNX7
google.golang.org/protobuf v1.25.1-0.20201208041424-160c7477e0e8/go.mod h1:hFxJC2f0epmp1elRCiEGJTKAWbwxZ2nvqZdHl3FQXCY=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I=
google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg=
google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/bsm/ratelimit.v1 v1.0.0-20160220154919-db14e161995a/go.mod h1:KF9sEfUPAXdG8Oev9e99iLGnl2uJMjc5B+4y3O7x610=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

View File

@@ -27,8 +27,8 @@ done
# github.com/prysmaticlabs/prysm/v5/validator/client/iface
# --------------------------------------------------------
iface_mocks=(
"$iface_mock_path/beacon_chain_client_mock.go BeaconChainClient"
"$iface_mock_path/prysm_beacon_chain_client_mock.go PrysmBeaconChainClient"
"$iface_mock_path/chain_client_mock.go ChainClient"
"$iface_mock_path/prysm_chain_client_mock.go PrysmChainClient"
"$iface_mock_path/node_client_mock.go NodeClient"
"$iface_mock_path/validator_client_mock.go ValidatorClient"
)

View File

@@ -48,12 +48,19 @@ func ConvertToIndexed(ctx context.Context, attestation ethpb.Att, committees ...
sort.Slice(attIndices, func(i, j int) bool {
return attIndices[i] < attIndices[j]
})
inAtt := &ethpb.IndexedAttestation{
if attestation.Version() >= version.Electra {
return &ethpb.IndexedAttestationElectra{
Data: attestation.GetData(),
Signature: attestation.GetSignature(),
AttestingIndices: attIndices,
}, nil
}
return &ethpb.IndexedAttestation{
Data: attestation.GetData(),
Signature: attestation.GetSignature(),
AttestingIndices: attIndices,
}
return inAtt, err
}, nil
}
// AttestingIndices returns the attesting participants indices from the attestation data.

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