Compare commits

...

10 Commits

Author SHA1 Message Date
Saolyn
6c5147215d revert + add transport 2025-02-14 17:19:31 +01:00
Sammy Rosso
d5596589ec Merge branch 'develop' into otel-tracing 2025-02-12 10:01:25 +01:00
james-prysm
15025837bb fix: gocognit on publish block and fixing publish blinded block header check (#14913)
* refactored code and added in checks for blinded endpoints

* changelog

* cleaning up some comments and error messages

* fixing linting

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

* service

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

* changelog
2025-02-11 15:04:22 +00:00
Saolyn
25e5b7a1a8 mess 2025-02-06 17:07:28 +01:00
Saolyn
2504a637e4 go.mod cleanup 2025-01-24 19:20:50 +01:00
Saolyn
ad1d124a4a gaz 2025-01-24 19:18:43 +01:00
Saolyn
6a90a29b93 Add otel middleware to client 2025-01-24 19:16:33 +01:00
22 changed files with 1190 additions and 1197 deletions

View File

@@ -9,7 +9,10 @@ go_library(
],
importpath = "github.com/prysmaticlabs/prysm/v5/api/client",
visibility = ["//visibility:public"],
deps = ["@com_github_pkg_errors//:go_default_library"],
deps = [
"@com_github_pkg_errors//:go_default_library",
"@io_opentelemetry_go_contrib_instrumentation_net_http_otelhttp//:go_default_library",
],
)
go_test(

View File

@@ -25,6 +25,7 @@ import (
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v5/runtime/version"
log "github.com/sirupsen/logrus"
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
)
const (
@@ -108,7 +109,9 @@ func NewClient(host string, opts ...ClientOpt) (*Client, error) {
return nil, err
}
c := &Client{
hc: &http.Client{},
hc: &http.Client{
Transport: otelhttp.NewTransport(http.DefaultTransport),
},
baseURL: u,
}
for _, o := range opts {

View File

@@ -8,6 +8,7 @@ import (
"net/url"
"github.com/pkg/errors"
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
)
const (
@@ -32,8 +33,10 @@ func NewClient(host string, opts ...ClientOpt) (*Client, error) {
if err != nil {
return nil, err
}
c := &Client{
hc: &http.Client{},
var c = &Client{
hc: &http.Client{
Transport: otelhttp.NewTransport(http.DefaultTransport),
},
baseURL: u,
maxBodySize: MaxBodySize,
}

View File

@@ -6,8 +6,8 @@ go_library(
"doc.go",
"log.go",
"metrics.go",
"pool.go",
"service.go",
"service_new.go",
"types.go",
],
importpath = "github.com/prysmaticlabs/prysm/v5/beacon-chain/operations/slashings",

View File

@@ -0,0 +1,324 @@
package slashings
import (
"context"
"fmt"
"sort"
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/blocks"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/helpers"
coretime "github.com/prysmaticlabs/prysm/v5/beacon-chain/core/time"
"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/container/slice"
"github.com/prysmaticlabs/prysm/v5/monitoring/tracing/trace"
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v5/runtime/version"
"github.com/trailofbits/go-mutexasserts"
)
// NewPool returns an initialized attester slashing and proposer slashing pool.
func NewPool() *Pool {
return &Pool{
pendingProposerSlashing: make([]*ethpb.ProposerSlashing, 0),
pendingAttesterSlashing: make([]*PendingAttesterSlashing, 0),
included: make(map[primitives.ValidatorIndex]bool),
}
}
// PendingAttesterSlashings returns attester slashings that are able to be included into a block.
// This method will return the amount of pending attester slashings for a block transition unless parameter `noLimit` is true
// to indicate the request is for noLimit pending items.
func (p *Pool) PendingAttesterSlashings(ctx context.Context, state state.ReadOnlyBeaconState, noLimit bool) []ethpb.AttSlashing {
p.lock.Lock()
defer p.lock.Unlock()
_, span := trace.StartSpan(ctx, "operations.PendingAttesterSlashing")
defer span.End()
// Update prom metric.
numPendingAttesterSlashings.Set(float64(len(p.pendingAttesterSlashing)))
included := make(map[primitives.ValidatorIndex]bool)
// Allocate pending slice with a capacity of maxAttesterSlashings or len(p.pendingAttesterSlashing)) depending on the request.
maxSlashings := params.BeaconConfig().MaxAttesterSlashings
// EIP-7549: Beginning from Electra, the max attester slashings is reduced to 1.
if state.Version() >= version.Electra {
maxSlashings = params.BeaconConfig().MaxAttesterSlashingsElectra
}
if noLimit {
maxSlashings = uint64(len(p.pendingAttesterSlashing))
}
pending := make([]ethpb.AttSlashing, 0, maxSlashings)
for i := 0; i < len(p.pendingAttesterSlashing); i++ {
if uint64(len(pending)) >= maxSlashings {
break
}
slashing := p.pendingAttesterSlashing[i]
valid, err := p.validatorSlashingPreconditionCheck(state, slashing.validatorToSlash)
if err != nil {
log.WithError(err).Error("could not validate attester slashing")
continue
}
if included[slashing.validatorToSlash] || !valid {
p.pendingAttesterSlashing = append(p.pendingAttesterSlashing[:i], p.pendingAttesterSlashing[i+1:]...)
i--
continue
}
attSlashing := slashing.attesterSlashing
slashedVal := slice.IntersectionUint64(
attSlashing.FirstAttestation().GetAttestingIndices(),
attSlashing.SecondAttestation().GetAttestingIndices(),
)
for _, idx := range slashedVal {
included[primitives.ValidatorIndex(idx)] = true
}
pending = append(pending, attSlashing)
}
return pending
}
// PendingProposerSlashings returns proposer slashings that are able to be included into a block.
// This method will return the amount of pending proposer slashings for a block transition unless the `noLimit` parameter
// is set to true to indicate the request is for noLimit pending items.
func (p *Pool) PendingProposerSlashings(ctx context.Context, state state.ReadOnlyBeaconState, noLimit bool) []*ethpb.ProposerSlashing {
p.lock.Lock()
defer p.lock.Unlock()
_, span := trace.StartSpan(ctx, "operations.PendingProposerSlashing")
defer span.End()
// Update prom metric.
numPendingProposerSlashings.Set(float64(len(p.pendingProposerSlashing)))
// Allocate pending slice with a capacity of len(p.pendingProposerSlashing) or maxProposerSlashings depending on the request.
maxSlashings := params.BeaconConfig().MaxProposerSlashings
if noLimit {
maxSlashings = uint64(len(p.pendingProposerSlashing))
}
pending := make([]*ethpb.ProposerSlashing, 0, maxSlashings)
for i := 0; i < len(p.pendingProposerSlashing); i++ {
if uint64(len(pending)) >= maxSlashings {
break
}
slashing := p.pendingProposerSlashing[i]
valid, err := p.validatorSlashingPreconditionCheck(state, slashing.Header_1.Header.ProposerIndex)
if err != nil {
log.WithError(err).Error("could not validate proposer slashing")
continue
}
if !valid {
p.pendingProposerSlashing = append(p.pendingProposerSlashing[:i], p.pendingProposerSlashing[i+1:]...)
i--
continue
}
pending = append(pending, slashing)
}
return pending
}
// InsertAttesterSlashing into the pool. This method is a no-op if the attester slashing already exists in the pool,
// has been included into a block recently, or the validator is already exited.
func (p *Pool) InsertAttesterSlashing(
ctx context.Context,
state state.ReadOnlyBeaconState,
slashing ethpb.AttSlashing,
) error {
p.lock.Lock()
defer p.lock.Unlock()
ctx, span := trace.StartSpan(ctx, "operations.InsertAttesterSlashing")
defer span.End()
if err := blocks.VerifyAttesterSlashing(ctx, state, slashing); err != nil {
return errors.Wrap(err, "could not verify attester slashing")
}
slashedVal := slice.IntersectionUint64(slashing.FirstAttestation().GetAttestingIndices(), slashing.SecondAttestation().GetAttestingIndices())
cantSlash := make([]uint64, 0, len(slashedVal))
slashingReason := ""
for _, val := range slashedVal {
// Has this validator index been included recently?
ok, err := p.validatorSlashingPreconditionCheck(state, primitives.ValidatorIndex(val))
if err != nil {
return err
}
// If the validator has already exited, has already been slashed, or if its index
// has been recently included in the pool of slashings, skip including this indice.
if !ok {
slashingReason = "validator already exited/slashed or already recently included in slashings pool"
cantSlash = append(cantSlash, val)
continue
}
// Check if the validator already exists in the list of slashings.
// Use binary search to find the answer.
found := sort.Search(len(p.pendingAttesterSlashing), func(i int) bool {
return uint64(p.pendingAttesterSlashing[i].validatorToSlash) >= val
})
if found != len(p.pendingAttesterSlashing) && uint64(p.pendingAttesterSlashing[found].validatorToSlash) == val {
slashingReason = "validator already exist in list of pending slashings, no need to attempt to slash again"
cantSlash = append(cantSlash, val)
continue
}
pendingSlashing := &PendingAttesterSlashing{
attesterSlashing: slashing,
validatorToSlash: primitives.ValidatorIndex(val),
}
// Insert into pending list and sort again.
p.pendingAttesterSlashing = append(p.pendingAttesterSlashing, pendingSlashing)
sort.Slice(p.pendingAttesterSlashing, func(i, j int) bool {
return p.pendingAttesterSlashing[i].validatorToSlash < p.pendingAttesterSlashing[j].validatorToSlash
})
numPendingAttesterSlashings.Set(float64(len(p.pendingAttesterSlashing)))
}
if len(cantSlash) == len(slashedVal) {
return fmt.Errorf(
"could not slash any of %d validators in submitted slashing: %s",
len(slashedVal),
slashingReason,
)
}
return nil
}
// InsertProposerSlashing into the pool. This method is a no-op if the pending slashing already exists,
// has been included recently, the validator is already exited, or the validator was already slashed.
func (p *Pool) InsertProposerSlashing(
ctx context.Context,
state state.ReadOnlyBeaconState,
slashing *ethpb.ProposerSlashing,
) error {
p.lock.Lock()
defer p.lock.Unlock()
_, span := trace.StartSpan(ctx, "operations.InsertProposerSlashing")
defer span.End()
if err := blocks.VerifyProposerSlashing(state, slashing); err != nil {
return errors.Wrap(err, "could not verify proposer slashing")
}
idx := slashing.Header_1.Header.ProposerIndex
ok, err := p.validatorSlashingPreconditionCheck(state, idx)
if err != nil {
return err
}
// If the validator has already exited, has already been slashed, or if its index
// has been recently included in the pool of slashings, do not process this new
// slashing.
if !ok {
return fmt.Errorf("validator at index %d cannot be slashed", idx)
}
// Check if the validator already exists in the list of slashings.
// Use binary search to find the answer.
found := sort.Search(len(p.pendingProposerSlashing), func(i int) bool {
return p.pendingProposerSlashing[i].Header_1.Header.ProposerIndex >= slashing.Header_1.Header.ProposerIndex
})
if found != len(p.pendingProposerSlashing) && p.pendingProposerSlashing[found].Header_1.Header.ProposerIndex ==
slashing.Header_1.Header.ProposerIndex {
return errors.New("slashing object already exists in pending proposer slashings")
}
// Insert into pending list and sort again.
p.pendingProposerSlashing = append(p.pendingProposerSlashing, slashing)
sort.Slice(p.pendingProposerSlashing, func(i, j int) bool {
return p.pendingProposerSlashing[i].Header_1.Header.ProposerIndex < p.pendingProposerSlashing[j].Header_1.Header.ProposerIndex
})
numPendingProposerSlashings.Set(float64(len(p.pendingProposerSlashing)))
return nil
}
// MarkIncludedAttesterSlashing is used when an attester slashing has been included in a beacon block.
// Every block seen by this node that contains proposer slashings should call this method to include
// the proposer slashings.
func (p *Pool) MarkIncludedAttesterSlashing(as ethpb.AttSlashing) {
p.lock.Lock()
defer p.lock.Unlock()
slashedVal := slice.IntersectionUint64(as.FirstAttestation().GetAttestingIndices(), as.SecondAttestation().GetAttestingIndices())
for _, val := range slashedVal {
i := sort.Search(len(p.pendingAttesterSlashing), func(i int) bool {
return uint64(p.pendingAttesterSlashing[i].validatorToSlash) >= val
})
if i != len(p.pendingAttesterSlashing) && uint64(p.pendingAttesterSlashing[i].validatorToSlash) == val {
p.pendingAttesterSlashing = append(p.pendingAttesterSlashing[:i], p.pendingAttesterSlashing[i+1:]...)
}
p.included[primitives.ValidatorIndex(val)] = true
numAttesterSlashingsIncluded.Inc()
}
}
// MarkIncludedProposerSlashing is used when an proposer slashing has been included in a beacon block.
// Every block seen by this node that contains proposer slashings should call this method to include
// the proposer slashings.
func (p *Pool) MarkIncludedProposerSlashing(ps *ethpb.ProposerSlashing) {
p.lock.Lock()
defer p.lock.Unlock()
i := sort.Search(len(p.pendingProposerSlashing), func(i int) bool {
return p.pendingProposerSlashing[i].Header_1.Header.ProposerIndex >= ps.Header_1.Header.ProposerIndex
})
if i != len(p.pendingProposerSlashing) && p.pendingProposerSlashing[i].Header_1.Header.ProposerIndex == ps.Header_1.Header.ProposerIndex {
p.pendingProposerSlashing = append(p.pendingProposerSlashing[:i], p.pendingProposerSlashing[i+1:]...)
}
p.included[ps.Header_1.Header.ProposerIndex] = true
numProposerSlashingsIncluded.Inc()
}
// ConvertToElectra converts all Phase0 attester slashings to Electra attester slashings.
// This functionality is needed at the time of the Electra fork.
func (p *Pool) ConvertToElectra() {
p.lock.Lock()
defer p.lock.Unlock()
for _, pas := range p.pendingAttesterSlashing {
if pas.attesterSlashing.Version() == version.Phase0 {
first := pas.attesterSlashing.FirstAttestation()
second := pas.attesterSlashing.SecondAttestation()
pas.attesterSlashing = &ethpb.AttesterSlashingElectra{
Attestation_1: &ethpb.IndexedAttestationElectra{
AttestingIndices: first.GetAttestingIndices(),
Data: first.GetData(),
Signature: first.GetSignature(),
},
Attestation_2: &ethpb.IndexedAttestationElectra{
AttestingIndices: second.GetAttestingIndices(),
Data: second.GetData(),
Signature: second.GetSignature(),
},
}
}
}
}
// this function checks a few items about a validator before proceeding with inserting
// a proposer/attester slashing into the pool. First, it checks if the validator
// has been recently included in the pool, then it checks if the validator is slashable.
// Note: this method requires caller to hold the lock.
func (p *Pool) validatorSlashingPreconditionCheck(
state state.ReadOnlyBeaconState,
valIdx primitives.ValidatorIndex,
) (bool, error) {
if !mutexasserts.RWMutexLocked(&p.lock) && !mutexasserts.RWMutexRLocked(&p.lock) {
return false, errors.New("pool.validatorSlashingPreconditionCheck: caller must hold read/write lock")
}
// Check if the validator index has been included recently.
if p.included[valIdx] {
return false, nil
}
validator, err := state.ValidatorAtIndexReadOnly(valIdx)
if err != nil {
return false, err
}
// Checking if the validator is slashable.
if !helpers.IsSlashableValidatorUsingTrie(validator, coretime.CurrentEpoch(state)) {
return false, nil
}
return true, nil
}

View File

@@ -2,323 +2,102 @@ package slashings
import (
"context"
"fmt"
"sort"
"time"
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/blocks"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/helpers"
coretime "github.com/prysmaticlabs/prysm/v5/beacon-chain/core/time"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/state"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/startup"
"github.com/prysmaticlabs/prysm/v5/config/params"
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
"github.com/prysmaticlabs/prysm/v5/container/slice"
"github.com/prysmaticlabs/prysm/v5/monitoring/tracing/trace"
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v5/runtime/version"
"github.com/trailofbits/go-mutexasserts"
"github.com/prysmaticlabs/prysm/v5/time/slots"
)
// NewPool returns an initialized attester slashing and proposer slashing pool.
func NewPool() *Pool {
return &Pool{
pendingProposerSlashing: make([]*ethpb.ProposerSlashing, 0),
pendingAttesterSlashing: make([]*PendingAttesterSlashing, 0),
included: make(map[primitives.ValidatorIndex]bool),
// WithElectraTimer includes functional options for the blockchain service related to CLI flags.
func WithElectraTimer(cw startup.ClockWaiter, currentSlotFn func() primitives.Slot) Option {
return func(p *PoolService) error {
p.runElectraTimer = true
p.cw = cw
p.currentSlotFn = currentSlotFn
return nil
}
}
// PendingAttesterSlashings returns attester slashings that are able to be included into a block.
// This method will return the amount of pending attester slashings for a block transition unless parameter `noLimit` is true
// to indicate the request is for noLimit pending items.
func (p *Pool) PendingAttesterSlashings(ctx context.Context, state state.ReadOnlyBeaconState, noLimit bool) []ethpb.AttSlashing {
p.lock.Lock()
defer p.lock.Unlock()
_, span := trace.StartSpan(ctx, "operations.PendingAttesterSlashing")
defer span.End()
// Update prom metric.
numPendingAttesterSlashings.Set(float64(len(p.pendingAttesterSlashing)))
included := make(map[primitives.ValidatorIndex]bool)
// Allocate pending slice with a capacity of maxAttesterSlashings or len(p.pendingAttesterSlashing)) depending on the request.
maxSlashings := params.BeaconConfig().MaxAttesterSlashings
// EIP-7549: Beginning from Electra, the max attester slashings is reduced to 1.
if state.Version() >= version.Electra {
maxSlashings = params.BeaconConfig().MaxAttesterSlashingsElectra
}
if noLimit {
maxSlashings = uint64(len(p.pendingAttesterSlashing))
}
pending := make([]ethpb.AttSlashing, 0, maxSlashings)
for i := 0; i < len(p.pendingAttesterSlashing); i++ {
if uint64(len(pending)) >= maxSlashings {
break
}
slashing := p.pendingAttesterSlashing[i]
valid, err := p.validatorSlashingPreconditionCheck(state, slashing.validatorToSlash)
if err != nil {
log.WithError(err).Error("could not validate attester slashing")
continue
}
if included[slashing.validatorToSlash] || !valid {
p.pendingAttesterSlashing = append(p.pendingAttesterSlashing[:i], p.pendingAttesterSlashing[i+1:]...)
i--
continue
}
attSlashing := slashing.attesterSlashing
slashedVal := slice.IntersectionUint64(
attSlashing.FirstAttestation().GetAttestingIndices(),
attSlashing.SecondAttestation().GetAttestingIndices(),
)
for _, idx := range slashedVal {
included[primitives.ValidatorIndex(idx)] = true
}
pending = append(pending, attSlashing)
// NewPoolService returns a service that manages the Pool.
func NewPoolService(ctx context.Context, pool PoolManager, opts ...Option) *PoolService {
ctx, cancel := context.WithCancel(ctx)
p := &PoolService{
ctx: ctx,
cancel: cancel,
poolManager: pool,
}
return pending
for _, opt := range opts {
if err := opt(p); err != nil {
return nil
}
}
return p
}
// PendingProposerSlashings returns proposer slashings that are able to be included into a block.
// This method will return the amount of pending proposer slashings for a block transition unless the `noLimit` parameter
// is set to true to indicate the request is for noLimit pending items.
func (p *Pool) PendingProposerSlashings(ctx context.Context, state state.ReadOnlyBeaconState, noLimit bool) []*ethpb.ProposerSlashing {
p.lock.Lock()
defer p.lock.Unlock()
_, span := trace.StartSpan(ctx, "operations.PendingProposerSlashing")
defer span.End()
// Update prom metric.
numPendingProposerSlashings.Set(float64(len(p.pendingProposerSlashing)))
// Allocate pending slice with a capacity of len(p.pendingProposerSlashing) or maxProposerSlashings depending on the request.
maxSlashings := params.BeaconConfig().MaxProposerSlashings
if noLimit {
maxSlashings = uint64(len(p.pendingProposerSlashing))
}
pending := make([]*ethpb.ProposerSlashing, 0, maxSlashings)
for i := 0; i < len(p.pendingProposerSlashing); i++ {
if uint64(len(pending)) >= maxSlashings {
break
}
slashing := p.pendingProposerSlashing[i]
valid, err := p.validatorSlashingPreconditionCheck(state, slashing.Header_1.Header.ProposerIndex)
if err != nil {
log.WithError(err).Error("could not validate proposer slashing")
continue
}
if !valid {
p.pendingProposerSlashing = append(p.pendingProposerSlashing[:i], p.pendingProposerSlashing[i+1:]...)
i--
continue
}
pending = append(pending, slashing)
}
return pending
// Start the slashing pool service.
func (p *PoolService) Start() {
go p.run()
}
// InsertAttesterSlashing into the pool. This method is a no-op if the attester slashing already exists in the pool,
// has been included into a block recently, or the validator is already exited.
func (p *Pool) InsertAttesterSlashing(
ctx context.Context,
state state.ReadOnlyBeaconState,
slashing ethpb.AttSlashing,
) error {
p.lock.Lock()
defer p.lock.Unlock()
ctx, span := trace.StartSpan(ctx, "operations.InsertAttesterSlashing")
defer span.End()
if err := blocks.VerifyAttesterSlashing(ctx, state, slashing); err != nil {
return errors.Wrap(err, "could not verify attester slashing")
func (p *PoolService) run() {
if !p.runElectraTimer {
return
}
slashedVal := slice.IntersectionUint64(slashing.FirstAttestation().GetAttestingIndices(), slashing.SecondAttestation().GetAttestingIndices())
cantSlash := make([]uint64, 0, len(slashedVal))
slashingReason := ""
for _, val := range slashedVal {
// Has this validator index been included recently?
ok, err := p.validatorSlashingPreconditionCheck(state, primitives.ValidatorIndex(val))
if err != nil {
return err
}
// If the validator has already exited, has already been slashed, or if its index
// has been recently included in the pool of slashings, skip including this indice.
if !ok {
slashingReason = "validator already exited/slashed or already recently included in slashings pool"
cantSlash = append(cantSlash, val)
continue
}
// Check if the validator already exists in the list of slashings.
// Use binary search to find the answer.
found := sort.Search(len(p.pendingAttesterSlashing), func(i int) bool {
return uint64(p.pendingAttesterSlashing[i].validatorToSlash) >= val
})
if found != len(p.pendingAttesterSlashing) && uint64(p.pendingAttesterSlashing[found].validatorToSlash) == val {
slashingReason = "validator already exist in list of pending slashings, no need to attempt to slash again"
cantSlash = append(cantSlash, val)
continue
}
pendingSlashing := &PendingAttesterSlashing{
attesterSlashing: slashing,
validatorToSlash: primitives.ValidatorIndex(val),
}
// Insert into pending list and sort again.
p.pendingAttesterSlashing = append(p.pendingAttesterSlashing, pendingSlashing)
sort.Slice(p.pendingAttesterSlashing, func(i, j int) bool {
return p.pendingAttesterSlashing[i].validatorToSlash < p.pendingAttesterSlashing[j].validatorToSlash
})
numPendingAttesterSlashings.Set(float64(len(p.pendingAttesterSlashing)))
electraSlot, err := slots.EpochStart(params.BeaconConfig().ElectraForkEpoch)
if err != nil {
return
}
if len(cantSlash) == len(slashedVal) {
return fmt.Errorf(
"could not slash any of %d validators in submitted slashing: %s",
len(slashedVal),
slashingReason,
)
// If run() is executed after the transition to Electra has already happened,
// there is nothing to convert because the slashing pool is empty at startup.
if p.currentSlotFn() >= electraSlot {
return
}
p.waitForChainInitialization()
electraTime, err := slots.ToTime(uint64(p.clock.GenesisTime().Unix()), electraSlot)
if err != nil {
return
}
t := time.NewTimer(electraTime.Sub(p.clock.Now()))
defer t.Stop()
select {
case <-t.C:
log.Info("Converting Phase0 slashings to Electra slashings")
p.poolManager.ConvertToElectra()
return
case <-p.ctx.Done():
log.Warn("Context cancelled, ConvertToElectra timer will not execute")
return
}
}
func (p *PoolService) waitForChainInitialization() {
clock, err := p.cw.WaitForClock(p.ctx)
if err != nil {
log.WithError(err).Error("Could not receive chain start notification")
}
p.clock = clock
log.WithField("genesisTime", clock.GenesisTime()).Info(
"Slashing pool service received chain initialization event",
)
}
// Stop the slashing pool service.
func (p *PoolService) Stop() error {
p.cancel()
return nil
}
// InsertProposerSlashing into the pool. This method is a no-op if the pending slashing already exists,
// has been included recently, the validator is already exited, or the validator was already slashed.
func (p *Pool) InsertProposerSlashing(
ctx context.Context,
state state.ReadOnlyBeaconState,
slashing *ethpb.ProposerSlashing,
) error {
p.lock.Lock()
defer p.lock.Unlock()
_, span := trace.StartSpan(ctx, "operations.InsertProposerSlashing")
defer span.End()
if err := blocks.VerifyProposerSlashing(state, slashing); err != nil {
return errors.Wrap(err, "could not verify proposer slashing")
}
idx := slashing.Header_1.Header.ProposerIndex
ok, err := p.validatorSlashingPreconditionCheck(state, idx)
if err != nil {
return err
}
// If the validator has already exited, has already been slashed, or if its index
// has been recently included in the pool of slashings, do not process this new
// slashing.
if !ok {
return fmt.Errorf("validator at index %d cannot be slashed", idx)
}
// Check if the validator already exists in the list of slashings.
// Use binary search to find the answer.
found := sort.Search(len(p.pendingProposerSlashing), func(i int) bool {
return p.pendingProposerSlashing[i].Header_1.Header.ProposerIndex >= slashing.Header_1.Header.ProposerIndex
})
if found != len(p.pendingProposerSlashing) && p.pendingProposerSlashing[found].Header_1.Header.ProposerIndex ==
slashing.Header_1.Header.ProposerIndex {
return errors.New("slashing object already exists in pending proposer slashings")
}
// Insert into pending list and sort again.
p.pendingProposerSlashing = append(p.pendingProposerSlashing, slashing)
sort.Slice(p.pendingProposerSlashing, func(i, j int) bool {
return p.pendingProposerSlashing[i].Header_1.Header.ProposerIndex < p.pendingProposerSlashing[j].Header_1.Header.ProposerIndex
})
numPendingProposerSlashings.Set(float64(len(p.pendingProposerSlashing)))
// Status of the slashing pool service.
func (p *PoolService) Status() error {
return nil
}
// MarkIncludedAttesterSlashing is used when an attester slashing has been included in a beacon block.
// Every block seen by this node that contains proposer slashings should call this method to include
// the proposer slashings.
func (p *Pool) MarkIncludedAttesterSlashing(as ethpb.AttSlashing) {
p.lock.Lock()
defer p.lock.Unlock()
slashedVal := slice.IntersectionUint64(as.FirstAttestation().GetAttestingIndices(), as.SecondAttestation().GetAttestingIndices())
for _, val := range slashedVal {
i := sort.Search(len(p.pendingAttesterSlashing), func(i int) bool {
return uint64(p.pendingAttesterSlashing[i].validatorToSlash) >= val
})
if i != len(p.pendingAttesterSlashing) && uint64(p.pendingAttesterSlashing[i].validatorToSlash) == val {
p.pendingAttesterSlashing = append(p.pendingAttesterSlashing[:i], p.pendingAttesterSlashing[i+1:]...)
}
p.included[primitives.ValidatorIndex(val)] = true
numAttesterSlashingsIncluded.Inc()
}
}
// MarkIncludedProposerSlashing is used when an proposer slashing has been included in a beacon block.
// Every block seen by this node that contains proposer slashings should call this method to include
// the proposer slashings.
func (p *Pool) MarkIncludedProposerSlashing(ps *ethpb.ProposerSlashing) {
p.lock.Lock()
defer p.lock.Unlock()
i := sort.Search(len(p.pendingProposerSlashing), func(i int) bool {
return p.pendingProposerSlashing[i].Header_1.Header.ProposerIndex >= ps.Header_1.Header.ProposerIndex
})
if i != len(p.pendingProposerSlashing) && p.pendingProposerSlashing[i].Header_1.Header.ProposerIndex == ps.Header_1.Header.ProposerIndex {
p.pendingProposerSlashing = append(p.pendingProposerSlashing[:i], p.pendingProposerSlashing[i+1:]...)
}
p.included[ps.Header_1.Header.ProposerIndex] = true
numProposerSlashingsIncluded.Inc()
}
// ConvertToElectra converts all Phase0 attester slashings to Electra attester slashings.
// This functionality is needed at the time of the Electra fork.
func (p *Pool) ConvertToElectra() {
p.lock.Lock()
defer p.lock.Unlock()
for _, pas := range p.pendingAttesterSlashing {
if pas.attesterSlashing.Version() == version.Phase0 {
first := pas.attesterSlashing.FirstAttestation()
second := pas.attesterSlashing.SecondAttestation()
pas.attesterSlashing = &ethpb.AttesterSlashingElectra{
Attestation_1: &ethpb.IndexedAttestationElectra{
AttestingIndices: first.GetAttestingIndices(),
Data: first.GetData(),
Signature: first.GetSignature(),
},
Attestation_2: &ethpb.IndexedAttestationElectra{
AttestingIndices: second.GetAttestingIndices(),
Data: second.GetData(),
Signature: second.GetSignature(),
},
}
}
}
}
// this function checks a few items about a validator before proceeding with inserting
// a proposer/attester slashing into the pool. First, it checks if the validator
// has been recently included in the pool, then it checks if the validator is slashable.
// Note: this method requires caller to hold the lock.
func (p *Pool) validatorSlashingPreconditionCheck(
state state.ReadOnlyBeaconState,
valIdx primitives.ValidatorIndex,
) (bool, error) {
if !mutexasserts.RWMutexLocked(&p.lock) && !mutexasserts.RWMutexRLocked(&p.lock) {
return false, errors.New("pool.validatorSlashingPreconditionCheck: caller must hold read/write lock")
}
// Check if the validator index has been included recently.
if p.included[valIdx] {
return false, nil
}
validator, err := state.ValidatorAtIndexReadOnly(valIdx)
if err != nil {
return false, err
}
// Checking if the validator is slashable.
if !helpers.IsSlashableValidatorUsingTrie(validator, coretime.CurrentEpoch(state)) {
return false, nil
}
return true, nil
}

View File

@@ -1,103 +0,0 @@
package slashings
import (
"context"
"time"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/startup"
"github.com/prysmaticlabs/prysm/v5/config/params"
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
"github.com/prysmaticlabs/prysm/v5/time/slots"
)
// WithElectraTimer includes functional options for the blockchain service related to CLI flags.
func WithElectraTimer(cw startup.ClockWaiter, currentSlotFn func() primitives.Slot) Option {
return func(p *PoolService) error {
p.runElectraTimer = true
p.cw = cw
p.currentSlotFn = currentSlotFn
return nil
}
}
// NewPoolService returns a service that manages the Pool.
func NewPoolService(ctx context.Context, pool PoolManager, opts ...Option) *PoolService {
ctx, cancel := context.WithCancel(ctx)
p := &PoolService{
ctx: ctx,
cancel: cancel,
poolManager: pool,
}
for _, opt := range opts {
if err := opt(p); err != nil {
return nil
}
}
return p
}
// Start the slashing pool service.
func (p *PoolService) Start() {
go p.run()
}
func (p *PoolService) run() {
if !p.runElectraTimer {
return
}
electraSlot, err := slots.EpochStart(params.BeaconConfig().ElectraForkEpoch)
if err != nil {
return
}
// If run() is executed after the transition to Electra has already happened,
// there is nothing to convert because the slashing pool is empty at startup.
if p.currentSlotFn() >= electraSlot {
return
}
p.waitForChainInitialization()
electraTime, err := slots.ToTime(uint64(p.clock.GenesisTime().Unix()), electraSlot)
if err != nil {
return
}
t := time.NewTimer(electraTime.Sub(p.clock.Now()))
defer t.Stop()
select {
case <-t.C:
log.Info("Converting Phase0 slashings to Electra slashings")
p.poolManager.ConvertToElectra()
return
case <-p.ctx.Done():
log.Warn("Context cancelled, ConvertToElectra timer will not execute")
return
}
}
func (p *PoolService) waitForChainInitialization() {
clock, err := p.cw.WaitForClock(p.ctx)
if err != nil {
log.WithError(err).Error("Could not receive chain start notification")
}
p.clock = clock
log.WithField("genesisTime", clock.GenesisTime()).Info(
"Slashing pool service received chain initialization event",
)
}
// Stop the slashing pool service.
func (p *PoolService) Stop() error {
p.cancel()
return nil
}
// Status of the slashing pool service.
func (p *PoolService) Status() error {
return nil
}

File diff suppressed because it is too large Load Diff

View File

@@ -1528,7 +1528,7 @@ func TestPublishBlock(t *testing.T) {
writer.Body = &bytes.Buffer{}
server.PublishBlock(writer, request)
assert.Equal(t, http.StatusBadRequest, writer.Code)
assert.StringContains(t, fmt.Sprintf("Could not decode request body into %s consensus block", version.String(version.Phase0)), writer.Body.String())
assert.StringContains(t, fmt.Sprintf("could not decode request body into %s consensus block", version.String(version.Phase0)), writer.Body.String())
})
t.Run("Fulu", func(t *testing.T) {
v1alpha1Server := mock2.NewMockBeaconNodeValidatorServer(ctrl)
@@ -1564,7 +1564,7 @@ func TestPublishBlock(t *testing.T) {
writer.Body = &bytes.Buffer{}
server.PublishBlock(writer, request)
assert.Equal(t, http.StatusBadRequest, writer.Code)
assert.StringContains(t, fmt.Sprintf("Could not decode request body into %s consensus block", version.String(version.Bellatrix)), writer.Body.String())
assert.StringContains(t, fmt.Sprintf("could not decode request body into %s consensus block", version.String(version.Bellatrix)), writer.Body.String())
})
t.Run("wrong version header", func(t *testing.T) {
server := &Server{
@@ -1577,7 +1577,7 @@ func TestPublishBlock(t *testing.T) {
writer.Body = &bytes.Buffer{}
server.PublishBlock(writer, request)
assert.Equal(t, http.StatusBadRequest, writer.Code)
assert.StringContains(t, fmt.Sprintf("Could not decode request body into %s consensus block", version.String(version.Capella)), writer.Body.String())
assert.StringContains(t, fmt.Sprintf("could not decode request body into %s consensus block", version.String(version.Capella)), writer.Body.String())
})
t.Run("syncing", func(t *testing.T) {
chainService := &chainMock.ChainService{}
@@ -1612,6 +1612,20 @@ func TestVersionHeaderFromRequest(t *testing.T) {
require.NoError(t, err)
require.Equal(t, version.String(version.Fulu), versionHead)
})
t.Run("Blinded Fulu block returns fulu header", func(t *testing.T) {
cfg := params.BeaconConfig().Copy()
cfg.FuluForkEpoch = 7
params.OverrideBeaconConfig(cfg)
params.SetupTestConfigCleanup(t)
var signedblock *structs.SignedBlindedBeaconBlockFulu
require.NoError(t, json.Unmarshal([]byte(rpctesting.BlindedFuluBlock), &signedblock))
signedblock.Message.Slot = fmt.Sprintf("%d", uint64(params.BeaconConfig().SlotsPerEpoch)*uint64(params.BeaconConfig().FuluForkEpoch))
newBlock, err := json.Marshal(signedblock)
require.NoError(t, err)
versionHead, err := versionHeaderFromRequest(newBlock)
require.NoError(t, err)
require.Equal(t, version.String(version.Fulu), versionHead)
})
t.Run("Electra block contents returns electra header", func(t *testing.T) {
cfg := params.BeaconConfig().Copy()
cfg.ElectraForkEpoch = 6
@@ -1626,6 +1640,20 @@ func TestVersionHeaderFromRequest(t *testing.T) {
require.NoError(t, err)
require.Equal(t, version.String(version.Electra), versionHead)
})
t.Run("Blinded Electra block returns electra header", func(t *testing.T) {
cfg := params.BeaconConfig().Copy()
cfg.ElectraForkEpoch = 6
params.OverrideBeaconConfig(cfg)
params.SetupTestConfigCleanup(t)
var signedblock *structs.SignedBlindedBeaconBlockElectra
require.NoError(t, json.Unmarshal([]byte(rpctesting.BlindedElectraBlock), &signedblock))
signedblock.Message.Slot = fmt.Sprintf("%d", uint64(params.BeaconConfig().SlotsPerEpoch)*uint64(params.BeaconConfig().ElectraForkEpoch))
newBlock, err := json.Marshal(signedblock)
require.NoError(t, err)
versionHead, err := versionHeaderFromRequest(newBlock)
require.NoError(t, err)
require.Equal(t, version.String(version.Electra), versionHead)
})
t.Run("Deneb block contents returns deneb header", func(t *testing.T) {
cfg := params.BeaconConfig().Copy()
cfg.DenebForkEpoch = 5
@@ -1640,7 +1668,21 @@ func TestVersionHeaderFromRequest(t *testing.T) {
require.NoError(t, err)
require.Equal(t, version.String(version.Deneb), versionHead)
})
t.Run("Capella block returns capella header", func(t *testing.T) {
t.Run("Blinded Deneb block returns Deneb header", func(t *testing.T) {
cfg := params.BeaconConfig().Copy()
cfg.DenebForkEpoch = 5
params.OverrideBeaconConfig(cfg)
params.SetupTestConfigCleanup(t)
var signedblock *structs.SignedBlindedBeaconBlockDeneb
require.NoError(t, json.Unmarshal([]byte(rpctesting.BlindedDenebBlock), &signedblock))
signedblock.Message.Slot = fmt.Sprintf("%d", uint64(params.BeaconConfig().SlotsPerEpoch)*uint64(params.BeaconConfig().DenebForkEpoch))
newBlock, err := json.Marshal(signedblock)
require.NoError(t, err)
versionHead, err := versionHeaderFromRequest(newBlock)
require.NoError(t, err)
require.Equal(t, version.String(version.Deneb), versionHead)
})
t.Run("Capella block returns Capella header", func(t *testing.T) {
cfg := params.BeaconConfig().Copy()
cfg.CapellaForkEpoch = 4
params.OverrideBeaconConfig(cfg)
@@ -1654,6 +1696,20 @@ func TestVersionHeaderFromRequest(t *testing.T) {
require.NoError(t, err)
require.Equal(t, version.String(version.Capella), versionHead)
})
t.Run("Blinded Capella block returns Capella header", func(t *testing.T) {
cfg := params.BeaconConfig().Copy()
cfg.CapellaForkEpoch = 4
params.OverrideBeaconConfig(cfg)
params.SetupTestConfigCleanup(t)
var signedblock *structs.SignedBlindedBeaconBlockCapella
require.NoError(t, json.Unmarshal([]byte(rpctesting.BlindedCapellaBlock), &signedblock))
signedblock.Message.Slot = fmt.Sprintf("%d", uint64(params.BeaconConfig().SlotsPerEpoch)*uint64(params.BeaconConfig().CapellaForkEpoch))
newBlock, err := json.Marshal(signedblock)
require.NoError(t, err)
versionHead, err := versionHeaderFromRequest(newBlock)
require.NoError(t, err)
require.Equal(t, version.String(version.Capella), versionHead)
})
t.Run("Bellatrix block returns capella header", func(t *testing.T) {
cfg := params.BeaconConfig().Copy()
cfg.BellatrixForkEpoch = 3
@@ -1668,6 +1724,20 @@ func TestVersionHeaderFromRequest(t *testing.T) {
require.NoError(t, err)
require.Equal(t, version.String(version.Bellatrix), versionHead)
})
t.Run("Blinded Capella block returns Capella header", func(t *testing.T) {
cfg := params.BeaconConfig().Copy()
cfg.BellatrixForkEpoch = 3
params.OverrideBeaconConfig(cfg)
params.SetupTestConfigCleanup(t)
var signedblock *structs.SignedBlindedBeaconBlockBellatrix
require.NoError(t, json.Unmarshal([]byte(rpctesting.BlindedBellatrixBlock), &signedblock))
signedblock.Message.Slot = fmt.Sprintf("%d", uint64(params.BeaconConfig().SlotsPerEpoch)*uint64(params.BeaconConfig().BellatrixForkEpoch))
newBlock, err := json.Marshal(signedblock)
require.NoError(t, err)
versionHead, err := versionHeaderFromRequest(newBlock)
require.NoError(t, err)
require.Equal(t, version.String(version.Bellatrix), versionHead)
})
t.Run("Altair block returns capella header", func(t *testing.T) {
cfg := params.BeaconConfig().Copy()
cfg.AltairForkEpoch = 2
@@ -1909,7 +1979,7 @@ func TestPublishBlockSSZ(t *testing.T) {
writer.Body = &bytes.Buffer{}
server.PublishBlock(writer, request)
assert.Equal(t, http.StatusBadRequest, writer.Code)
assert.StringContains(t, fmt.Sprintf("Could not decode request body into %s consensus block", version.String(version.Bellatrix)), writer.Body.String())
assert.StringContains(t, fmt.Sprintf("could not decode request body into %s consensus block", version.String(version.Bellatrix)), writer.Body.String())
})
t.Run("wrong version header", func(t *testing.T) {
server := &Server{
@@ -1930,7 +2000,7 @@ func TestPublishBlockSSZ(t *testing.T) {
writer.Body = &bytes.Buffer{}
server.PublishBlock(writer, request)
assert.Equal(t, http.StatusBadRequest, writer.Code)
assert.StringContains(t, fmt.Sprintf("Could not decode request body into %s consensus block", version.String(version.Capella)), writer.Body.String())
assert.StringContains(t, fmt.Sprintf("could not decode request body into %s consensus block", version.String(version.Capella)), writer.Body.String())
})
t.Run("syncing", func(t *testing.T) {
chainService := &chainMock.ChainService{}
@@ -2072,12 +2142,11 @@ func TestPublishBlindedBlock(t *testing.T) {
t.Run("Blinded Electra", func(t *testing.T) {
v1alpha1Server := mock2.NewMockBeaconNodeValidatorServer(ctrl)
v1alpha1Server.EXPECT().ProposeBeaconBlock(gomock.Any(), mock.MatchedBy(func(req *eth.GenericSignedBeaconBlock) bool {
// Convert back Fulu to Electra when there is at least one difference between Electra and Fulu blocks.
block, ok := req.Block.(*eth.GenericSignedBeaconBlock_BlindedFulu)
converted, err := structs.BlindedBeaconBlockFuluFromConsensus(block.BlindedFulu.Message)
block, ok := req.Block.(*eth.GenericSignedBeaconBlock_BlindedElectra)
converted, err := structs.BlindedBeaconBlockElectraFromConsensus(block.BlindedElectra.Message)
require.NoError(t, err)
var signedblock *structs.SignedBlindedBeaconBlockFulu
err = json.Unmarshal([]byte(rpctesting.BlindedFuluBlock), &signedblock)
var signedblock *structs.SignedBlindedBeaconBlockElectra
err = json.Unmarshal([]byte(rpctesting.BlindedElectraBlock), &signedblock)
require.NoError(t, err)
require.DeepEqual(t, converted, signedblock.Message)
return ok
@@ -2094,6 +2163,52 @@ func TestPublishBlindedBlock(t *testing.T) {
server.PublishBlindedBlock(writer, request)
assert.Equal(t, http.StatusOK, writer.Code)
})
t.Run("Blinded Electra block without version header succeeds", func(t *testing.T) {
cfg := params.BeaconConfig().Copy()
cfg.ElectraForkEpoch = 6
params.OverrideBeaconConfig(cfg)
params.SetupTestConfigCleanup(t)
var signedblock *structs.SignedBlindedBeaconBlockElectra
require.NoError(t, json.Unmarshal([]byte(rpctesting.BlindedElectraBlock), &signedblock))
signedblock.Message.Slot = fmt.Sprintf("%d", uint64(params.BeaconConfig().SlotsPerEpoch)*uint64(params.BeaconConfig().ElectraForkEpoch))
newBlock, err := json.Marshal(signedblock)
require.NoError(t, err)
v1alpha1Server := mock2.NewMockBeaconNodeValidatorServer(ctrl)
v1alpha1Server.EXPECT().ProposeBeaconBlock(gomock.Any(), mock.MatchedBy(func(req *eth.GenericSignedBeaconBlock) bool {
block, ok := req.Block.(*eth.GenericSignedBeaconBlock_BlindedElectra)
converted, err := structs.BlindedBeaconBlockElectraFromConsensus(block.BlindedElectra.Message)
require.NoError(t, err)
var signedblock *structs.SignedBlindedBeaconBlockElectra
err = json.Unmarshal(newBlock, &signedblock)
require.NoError(t, err)
require.DeepEqual(t, converted, signedblock.Message)
return ok
}))
server := &Server{
V1Alpha1ValidatorServer: v1alpha1Server,
SyncChecker: &mockSync.Sync{IsSyncing: false},
}
request := httptest.NewRequest(http.MethodPost, "http://foo.example", bytes.NewReader(newBlock))
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
server.PublishBlindedBlock(writer, request)
assert.Equal(t, http.StatusOK, writer.Code)
})
t.Run("Blinded Electra block without version header on wrong fork", func(t *testing.T) {
v1alpha1Server := mock2.NewMockBeaconNodeValidatorServer(ctrl)
server := &Server{
V1Alpha1ValidatorServer: v1alpha1Server,
SyncChecker: &mockSync.Sync{IsSyncing: false},
}
request := httptest.NewRequest(http.MethodPost, "http://foo.example", bytes.NewReader([]byte(rpctesting.BlindedElectraBlock)))
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
server.PublishBlindedBlock(writer, request)
assert.Equal(t, http.StatusBadRequest, writer.Code)
// block is sent with slot == 1 which means it's in the phase0 fork
assert.StringContains(t, fmt.Sprintf("could not decode request body into %s consensus block", version.String(version.Phase0)), writer.Body.String())
})
t.Run("Blinded Fulu", func(t *testing.T) {
v1alpha1Server := mock2.NewMockBeaconNodeValidatorServer(ctrl)
v1alpha1Server.EXPECT().ProposeBeaconBlock(gomock.Any(), mock.MatchedBy(func(req *eth.GenericSignedBeaconBlock) bool {
@@ -2129,7 +2244,7 @@ func TestPublishBlindedBlock(t *testing.T) {
writer.Body = &bytes.Buffer{}
server.PublishBlindedBlock(writer, request)
assert.Equal(t, http.StatusBadRequest, writer.Code)
assert.StringContains(t, fmt.Sprintf("Could not decode request body into %s consensus block", version.String(version.Bellatrix)), writer.Body.String())
assert.StringContains(t, fmt.Sprintf("could not decode request body into %s consensus block", version.String(version.Bellatrix)), writer.Body.String())
})
t.Run("wrong version header", func(t *testing.T) {
server := &Server{
@@ -2142,7 +2257,7 @@ func TestPublishBlindedBlock(t *testing.T) {
writer.Body = &bytes.Buffer{}
server.PublishBlindedBlock(writer, request)
assert.Equal(t, http.StatusBadRequest, writer.Code)
assert.StringContains(t, fmt.Sprintf("Could not decode request body into %s consensus block", version.String(version.Capella)), writer.Body.String())
assert.StringContains(t, fmt.Sprintf("could not decode request body into %s consensus block", version.String(version.Capella)), writer.Body.String())
})
t.Run("syncing", func(t *testing.T) {
chainService := &chainMock.ChainService{}
@@ -2366,7 +2481,7 @@ func TestPublishBlindedBlockSSZ(t *testing.T) {
writer.Body = &bytes.Buffer{}
server.PublishBlindedBlock(writer, request)
assert.Equal(t, http.StatusBadRequest, writer.Code)
assert.StringContains(t, fmt.Sprintf("Could not decode request body into %s consensus block", version.String(version.Bellatrix)), writer.Body.String())
assert.StringContains(t, fmt.Sprintf("could not decode request body into %s consensus block", version.String(version.Bellatrix)), writer.Body.String())
})
t.Run("wrong version header", func(t *testing.T) {
server := &Server{
@@ -2387,7 +2502,7 @@ func TestPublishBlindedBlockSSZ(t *testing.T) {
writer.Body = &bytes.Buffer{}
server.PublishBlindedBlock(writer, request)
assert.Equal(t, http.StatusBadRequest, writer.Code)
assert.StringContains(t, fmt.Sprintf("Could not decode request body into %s consensus block", version.String(version.Capella)), writer.Body.String())
assert.StringContains(t, fmt.Sprintf("could not decode request body into %s consensus block", version.String(version.Capella)), writer.Body.String())
})
t.Run("syncing", func(t *testing.T) {
chainService := &chainMock.ChainService{}
@@ -2585,7 +2700,7 @@ func TestPublishBlockV2(t *testing.T) {
writer.Body = &bytes.Buffer{}
server.PublishBlockV2(writer, request)
assert.Equal(t, http.StatusBadRequest, writer.Code)
assert.StringContains(t, fmt.Sprintf("Could not decode request body into %s consensus block:", version.String(version.Bellatrix)), writer.Body.String())
assert.StringContains(t, fmt.Sprintf("could not decode request body into %s consensus block:", version.String(version.Bellatrix)), writer.Body.String())
})
t.Run("wrong version header", func(t *testing.T) {
server := &Server{
@@ -2598,7 +2713,7 @@ func TestPublishBlockV2(t *testing.T) {
writer.Body = &bytes.Buffer{}
server.PublishBlockV2(writer, request)
assert.Equal(t, http.StatusBadRequest, writer.Code)
assert.StringContains(t, fmt.Sprintf("Could not decode request body into %s consensus block:", version.String(version.Capella)), writer.Body.String())
assert.StringContains(t, fmt.Sprintf("could not decode request body into %s consensus block:", version.String(version.Capella)), writer.Body.String())
})
t.Run("missing version header", func(t *testing.T) {
server := &Server{
@@ -2842,7 +2957,7 @@ func TestPublishBlockV2SSZ(t *testing.T) {
writer.Body = &bytes.Buffer{}
server.PublishBlockV2(writer, request)
assert.Equal(t, http.StatusBadRequest, writer.Code)
assert.StringContains(t, fmt.Sprintf("Could not decode request body into %s consensus block", version.String(version.Bellatrix)), writer.Body.String())
assert.StringContains(t, fmt.Sprintf("could not decode request body into %s consensus block", version.String(version.Bellatrix)), writer.Body.String())
})
t.Run("wrong version header", func(t *testing.T) {
server := &Server{
@@ -2863,7 +2978,7 @@ func TestPublishBlockV2SSZ(t *testing.T) {
writer.Body = &bytes.Buffer{}
server.PublishBlockV2(writer, request)
assert.Equal(t, http.StatusBadRequest, writer.Code)
assert.StringContains(t, fmt.Sprintf("Could not decode request body into %s consensus block", version.String(version.Capella)), writer.Body.String())
assert.StringContains(t, fmt.Sprintf("could not decode request body into %s consensus block", version.String(version.Capella)), writer.Body.String())
})
t.Run("missing version header", func(t *testing.T) {
server := &Server{
@@ -3018,12 +3133,11 @@ func TestPublishBlindedBlockV2(t *testing.T) {
t.Run("Blinded Electra", func(t *testing.T) {
v1alpha1Server := mock2.NewMockBeaconNodeValidatorServer(ctrl)
v1alpha1Server.EXPECT().ProposeBeaconBlock(gomock.Any(), mock.MatchedBy(func(req *eth.GenericSignedBeaconBlock) bool {
// Convert back Fulu to Electra when there is at least one difference between Electra and Fulu blocks.
block, ok := req.Block.(*eth.GenericSignedBeaconBlock_BlindedFulu)
converted, err := structs.BlindedBeaconBlockFuluFromConsensus(block.BlindedFulu.Message)
block, ok := req.Block.(*eth.GenericSignedBeaconBlock_BlindedElectra)
converted, err := structs.BlindedBeaconBlockElectraFromConsensus(block.BlindedElectra.Message)
require.NoError(t, err)
var signedblock *structs.SignedBlindedBeaconBlockFulu
err = json.Unmarshal([]byte(rpctesting.BlindedFuluBlock), &signedblock)
var signedblock *structs.SignedBlindedBeaconBlockElectra
err = json.Unmarshal([]byte(rpctesting.BlindedElectraBlock), &signedblock)
require.NoError(t, err)
require.DeepEqual(t, converted, signedblock.Message)
return ok
@@ -3075,7 +3189,7 @@ func TestPublishBlindedBlockV2(t *testing.T) {
writer.Body = &bytes.Buffer{}
server.PublishBlindedBlockV2(writer, request)
assert.Equal(t, http.StatusBadRequest, writer.Code)
assert.StringContains(t, fmt.Sprintf("Could not decode request body into %s consensus block:", version.String(version.Bellatrix)), writer.Body.String())
assert.StringContains(t, fmt.Sprintf("could not decode request body into %s consensus block:", version.String(version.Bellatrix)), writer.Body.String())
})
t.Run("wrong version header", func(t *testing.T) {
server := &Server{
@@ -3088,7 +3202,7 @@ func TestPublishBlindedBlockV2(t *testing.T) {
writer.Body = &bytes.Buffer{}
server.PublishBlindedBlockV2(writer, request)
assert.Equal(t, http.StatusBadRequest, writer.Code)
assert.StringContains(t, fmt.Sprintf("Could not decode request body into %s consensus block", version.String(version.Capella)), writer.Body.String())
assert.StringContains(t, fmt.Sprintf("could not decode request body into %s consensus block", version.String(version.Capella)), writer.Body.String())
})
t.Run("missing version header", func(t *testing.T) {
server := &Server{
@@ -3324,7 +3438,7 @@ func TestPublishBlindedBlockV2SSZ(t *testing.T) {
writer.Body = &bytes.Buffer{}
server.PublishBlindedBlockV2(writer, request)
assert.Equal(t, http.StatusBadRequest, writer.Code)
assert.StringContains(t, fmt.Sprintf("Could not decode request body into %s consensus block", version.String(version.Bellatrix)), writer.Body.String())
assert.StringContains(t, fmt.Sprintf("could not decode request body into %s consensus block", version.String(version.Bellatrix)), writer.Body.String())
})
t.Run("wrong version header", func(t *testing.T) {
server := &Server{
@@ -3345,7 +3459,7 @@ func TestPublishBlindedBlockV2SSZ(t *testing.T) {
writer.Body = &bytes.Buffer{}
server.PublishBlindedBlockV2(writer, request)
assert.Equal(t, http.StatusBadRequest, writer.Code)
assert.StringContains(t, fmt.Sprintf("Could not decode request body into %s consensus block", version.String(version.Capella)), writer.Body.String())
assert.StringContains(t, fmt.Sprintf("could not decode request body into %s consensus block", version.String(version.Capella)), writer.Body.String())
})
t.Run("missing version header", func(t *testing.T) {
server := &Server{

View File

@@ -810,4 +810,70 @@ func TestSendBlobsByRangeRequest(t *testing.T) {
assert.NoError(t, err)
assert.Equal(t, int(totalExpectedBlobs), len(blobs))
})
t.Run("Starting from Electra", func(t *testing.T) {
cfg := params.BeaconConfig()
cfg.ElectraForkEpoch = cfg.DenebForkEpoch + 1
undo, err := params.SetActiveWithUndo(cfg)
require.NoError(t, err)
defer func() {
require.NoError(t, undo())
}()
s := uint64(slots.UnsafeEpochStart(params.BeaconConfig().ElectraForkEpoch)) * params.BeaconConfig().SecondsPerSlot
clock := startup.NewClock(time.Now().Add(-time.Second*time.Duration(s)), [32]byte{})
ctxByte, err := ContextByteVersionsForValRoot(clock.GenesisValidatorsRoot())
require.NoError(t, err)
// Setup peers
p1 := p2ptest.NewTestP2P(t)
p2 := p2ptest.NewTestP2P(t)
p1.Connect(p2)
slot := slots.UnsafeEpochStart(params.BeaconConfig().ElectraForkEpoch)
// Create a simple handler that will return a valid response.
p2.SetStreamHandler(topic, func(stream network.Stream) {
defer func() {
assert.NoError(t, stream.Close())
}()
req := &ethpb.BlobSidecarsByRangeRequest{}
assert.NoError(t, p2.Encoding().DecodeWithMaxLength(stream, req))
assert.Equal(t, slot, req.StartSlot)
assert.Equal(t, uint64(params.BeaconConfig().SlotsPerEpoch)*3, req.Count)
// Create a sequential set of blobs with the appropriate header information.
var prevRoot [32]byte
for i := req.StartSlot; i < req.StartSlot+primitives.Slot(req.Count); i++ {
maxBlobsForSlot := cfg.MaxBlobsPerBlock(i)
parentRoot := prevRoot
header := util.HydrateSignedBeaconHeader(&ethpb.SignedBeaconBlockHeader{})
header.Header.Slot = i
header.Header.ParentRoot = parentRoot[:]
bRoot, err := header.Header.HashTreeRoot()
require.NoError(t, err)
prevRoot = bRoot
// Send the maximum possible blobs per slot.
for j := 0; j < maxBlobsForSlot; j++ {
b := util.HydrateBlobSidecar(&ethpb.BlobSidecar{})
b.SignedBlockHeader = header
b.Index = uint64(j)
ro, err := blocks.NewROBlob(b)
require.NoError(t, err)
vro := blocks.NewVerifiedROBlob(ro)
assert.NoError(t, WriteBlobSidecarChunk(stream, clock, p2.Encoding(), vro))
}
}
})
req := &ethpb.BlobSidecarsByRangeRequest{
StartSlot: slot,
Count: uint64(params.BeaconConfig().SlotsPerEpoch) * 3,
}
maxElectraBlobs := cfg.MaxBlobsPerBlockAtEpoch(cfg.ElectraForkEpoch)
totalElectraBlobs := primitives.Slot(maxElectraBlobs) * 3 * params.BeaconConfig().SlotsPerEpoch
blobs, err := SendBlobsByRangeRequest(ctx, clock, p1, p2.PeerID(), ctxByte, req)
assert.NoError(t, err)
assert.Equal(t, int(totalElectraBlobs), len(blobs))
})
}

View File

@@ -0,0 +1,4 @@
### Fixed
- refactored publish block and block ssz functions to fix gocognit
- refactored publish blinded block and blinded block ssz to correctly deal with version headers and sent blocks

View File

@@ -0,0 +1,3 @@
### Fixed
- fixed max and target blob per block from static to dynamic values

View File

@@ -0,0 +1,3 @@
### Ignored
- Rename files in `beacon-chain/operations/slashings`.

View File

@@ -0,0 +1,3 @@
### Ignored
- Add blobs by range electra test

View File

@@ -387,7 +387,7 @@ func (b *BeaconChainConfig) MaximumGossipClockDisparityDuration() time.Duration
// TargetBlobsPerBlock returns the target number of blobs per block for the given slot,
// accounting for changes introduced by the Electra fork.
func (b *BeaconChainConfig) TargetBlobsPerBlock(slot primitives.Slot) int {
if primitives.Epoch(slot.DivSlot(32)) >= b.ElectraForkEpoch {
if primitives.Epoch(slot.DivSlot(b.SlotsPerEpoch)) >= b.ElectraForkEpoch {
return b.DeprecatedTargetBlobsPerBlockElectra
}
return b.DeprecatedMaxBlobsPerBlock / 2
@@ -396,7 +396,7 @@ func (b *BeaconChainConfig) TargetBlobsPerBlock(slot primitives.Slot) int {
// MaxBlobsPerBlock returns the maximum number of blobs per block for the given slot,
// adjusting for the Electra fork.
func (b *BeaconChainConfig) MaxBlobsPerBlock(slot primitives.Slot) int {
if primitives.Epoch(slot.DivSlot(32)) >= b.ElectraForkEpoch {
if primitives.Epoch(slot.DivSlot(b.SlotsPerEpoch)) >= b.ElectraForkEpoch {
return b.DeprecatedMaxBlobsPerBlockElectra
}
return b.DeprecatedMaxBlobsPerBlock

View File

@@ -793,6 +793,12 @@ def prysm_deps():
sum = "h1:VvyZxILNuCiUCSXtPtYmmtGvb65nqXh2QFWc0Wpf2/g=",
version = "v0.9.3",
)
go_repository(
name = "com_github_felixge_httpsnoop",
importpath = "github.com/felixge/httpsnoop",
sum = "h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=",
version = "v1.0.4",
)
go_repository(
name = "com_github_ferranbt_fastssz",
importpath = "github.com/ferranbt/fastssz",
@@ -2895,8 +2901,8 @@ def prysm_deps():
go_repository(
name = "com_github_rogpeppe_go_internal",
importpath = "github.com/rogpeppe/go-internal",
sum = "h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=",
version = "v1.12.0",
sum = "h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=",
version = "v1.13.1",
)
go_repository(
name = "com_github_rs_cors",
@@ -3237,8 +3243,8 @@ def prysm_deps():
go_repository(
name = "com_github_stretchr_testify",
importpath = "github.com/stretchr/testify",
sum = "h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=",
version = "v1.9.0",
sum = "h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=",
version = "v1.10.0",
)
go_repository(
name = "com_github_syndtr_goleveldb",
@@ -4537,11 +4543,23 @@ def prysm_deps():
sum = "h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=",
version = "v0.24.0",
)
go_repository(
name = "io_opentelemetry_go_auto_sdk",
importpath = "go.opentelemetry.io/auto/sdk",
sum = "h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=",
version = "v1.1.0",
)
go_repository(
name = "io_opentelemetry_go_contrib_instrumentation_net_http_otelhttp",
importpath = "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp",
sum = "h1:CV7UdSGJt/Ao6Gp4CXckLxVRRsRgDHoI8XjbL3PDl8s=",
version = "v0.59.0",
)
go_repository(
name = "io_opentelemetry_go_otel",
importpath = "go.opentelemetry.io/otel",
sum = "h1:PdomN/Al4q/lN6iBJEN3AwPvUiHPMlt93c8bqTG5Llw=",
version = "v1.29.0",
sum = "h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY=",
version = "v1.34.0",
)
go_repository(
name = "io_opentelemetry_go_otel_exporters_jaeger",
@@ -4552,8 +4570,8 @@ def prysm_deps():
go_repository(
name = "io_opentelemetry_go_otel_metric",
importpath = "go.opentelemetry.io/otel/metric",
sum = "h1:vPf/HFWTNkPu1aYeIsc98l4ktOQaL6LeSoeV2g+8YLc=",
version = "v1.29.0",
sum = "h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ=",
version = "v1.34.0",
)
go_repository(
name = "io_opentelemetry_go_otel_sdk",
@@ -4564,8 +4582,8 @@ def prysm_deps():
go_repository(
name = "io_opentelemetry_go_otel_trace",
importpath = "go.opentelemetry.io/otel/trace",
sum = "h1:J/8ZNK4XgR7a21DZUAsbF8pZ5Jcw1VhACmnYt39JTi4=",
version = "v1.29.0",
sum = "h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k=",
version = "v1.34.0",
)
go_repository(
name = "io_rsc_binaryregexp",

13
go.mod
View File

@@ -68,7 +68,7 @@ require (
github.com/sirupsen/logrus v1.9.3
github.com/spf13/afero v1.10.0
github.com/status-im/keycard-go v0.2.0
github.com/stretchr/testify v1.9.0
github.com/stretchr/testify v1.10.0
github.com/supranational/blst v0.3.13
github.com/thomaso-mirodin/intmath v0.0.0-20160323211736-5dc6d854e46e
github.com/trailofbits/go-mutexasserts v0.0.0-20230328101604-8cdbc5f3d279
@@ -80,10 +80,11 @@ require (
github.com/wealdtech/go-eth2-wallet-encryptor-keystorev4 v1.1.3
go.etcd.io/bbolt v1.3.6
go.opencensus.io v0.24.0
go.opentelemetry.io/otel v1.29.0
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0
go.opentelemetry.io/otel v1.34.0
go.opentelemetry.io/otel/exporters/jaeger v1.17.0
go.opentelemetry.io/otel/sdk v1.29.0
go.opentelemetry.io/otel/trace v1.29.0
go.opentelemetry.io/otel/trace v1.34.0
go.uber.org/automaxprocs v1.5.2
go.uber.org/mock v0.4.0
golang.org/x/crypto v0.32.0
@@ -135,6 +136,7 @@ require (
github.com/elastic/gosigar v0.14.3 // indirect
github.com/ethereum/c-kzg-4844 v1.0.0 // indirect
github.com/ethereum/go-verkle v0.2.2 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/ferranbt/fastssz v0.1.3 // indirect
github.com/flynn/noise v1.1.0 // indirect
github.com/francoispqt/gojay v1.2.13 // indirect
@@ -232,7 +234,7 @@ require (
github.com/quic-go/webtransport-go v0.8.1-0.20241018022711-4ac2c9250e66 // indirect
github.com/raulk/go-watchdog v1.3.0 // indirect
github.com/rivo/uniseg v0.4.7 // indirect
github.com/rogpeppe/go-internal v1.12.0 // indirect
github.com/rogpeppe/go-internal v1.13.1 // 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
@@ -244,7 +246,8 @@ require (
github.com/wlynxg/anet v0.0.4 // indirect
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
github.com/yusufpapurcu/wmi v1.2.3 // indirect
go.opentelemetry.io/otel/metric v1.29.0 // indirect
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
go.opentelemetry.io/otel/metric v1.34.0 // indirect
go.uber.org/dig v1.18.0 // indirect
go.uber.org/fx v1.22.2 // indirect
go.uber.org/multierr v1.11.0 // indirect

25
go.sum
View File

@@ -242,6 +242,8 @@ github.com/ethereum/go-verkle v0.2.2/go.mod h1:M3b90YRnzqKyyzBEWJGqj8Qff4IDeXnzF
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=
github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE=
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/ferranbt/fastssz v0.0.0-20210120143747-11b9eff30ea9/go.mod h1:DyEu2iuLBnb/T51BlsiO3yLYdJC6UbGMrIkqK1KmQxM=
github.com/ferranbt/fastssz v0.1.3 h1:ZI+z3JH05h4kgmFXdHuR1aWYsgrg7o+Fw7/NCzM16Mo=
github.com/ferranbt/fastssz v0.1.3/go.mod h1:0Y9TEd/9XuFlh7mskMPfXiI2Dkw4Ddg9EyXt1W7MRvE=
@@ -921,8 +923,8 @@ github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6So
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik=
github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
@@ -1009,8 +1011,9 @@ github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
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/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/supranational/blst v0.3.13 h1:AYeSxdOMacwu7FBmpfloBz5pbFXDmJL33RuwnKtmTjk=
github.com/supranational/blst v0.3.13/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw=
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY=
@@ -1091,16 +1094,20 @@ go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
go.opentelemetry.io/otel v1.29.0 h1:PdomN/Al4q/lN6iBJEN3AwPvUiHPMlt93c8bqTG5Llw=
go.opentelemetry.io/otel v1.29.0/go.mod h1:N/WtXPs1CNCUEx+Agz5uouwCba+i+bJGFicT8SR4NP8=
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0 h1:CV7UdSGJt/Ao6Gp4CXckLxVRRsRgDHoI8XjbL3PDl8s=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0/go.mod h1:FRmFuRJfag1IZ2dPkHnEoSFVgTVPUd2qf5Vi69hLb8I=
go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY=
go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI=
go.opentelemetry.io/otel/exporters/jaeger v1.17.0 h1:D7UpUy2Xc2wsi1Ras6V40q806WM07rqoCWzXu7Sqy+4=
go.opentelemetry.io/otel/exporters/jaeger v1.17.0/go.mod h1:nPCqOnEH9rNLKqH/+rrUjiMzHJdV1BlpKcTwRTyKkKI=
go.opentelemetry.io/otel/metric v1.29.0 h1:vPf/HFWTNkPu1aYeIsc98l4ktOQaL6LeSoeV2g+8YLc=
go.opentelemetry.io/otel/metric v1.29.0/go.mod h1:auu/QWieFVWx+DmQOUMgj0F8LHWdgalxXqvp7BII/W8=
go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ=
go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE=
go.opentelemetry.io/otel/sdk v1.29.0 h1:vkqKjk7gwhS8VaWb0POZKmIEDimRCMsopNYnriHyryo=
go.opentelemetry.io/otel/sdk v1.29.0/go.mod h1:pM8Dx5WKnvxLCb+8lG1PRNIDxu9g9b9g59Qr7hfAAok=
go.opentelemetry.io/otel/trace v1.29.0 h1:J/8ZNK4XgR7a21DZUAsbF8pZ5Jcw1VhACmnYt39JTi4=
go.opentelemetry.io/otel/trace v1.29.0/go.mod h1:eHl3w0sp3paPkYstJOmAimxhiFXPg+MMTlEh3nsQgWQ=
go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k=
go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE=
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
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=

View File

@@ -24,6 +24,7 @@ import (
"github.com/prysmaticlabs/prysm/v5/runtime/interop"
e2e "github.com/prysmaticlabs/prysm/v5/testing/endtoend/params"
e2etypes "github.com/prysmaticlabs/prysm/v5/testing/endtoend/types"
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
"gopkg.in/yaml.v2"
)
@@ -140,7 +141,9 @@ func (w *Web3RemoteSigner) Stop() error {
// monitorStart by polling server until it returns a 200 at /upcheck.
func (w *Web3RemoteSigner) monitorStart() {
client := &http.Client{}
client := &http.Client{
Transport: otelhttp.NewTransport(http.DefaultTransport),
}
for {
req, err := http.NewRequestWithContext(w.ctx, http.MethodGet, fmt.Sprintf("http://localhost:%d/upcheck", Web3RemoteSignerPort), nil)
if err != nil {

View File

@@ -37,6 +37,7 @@ import (
eth "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v5/runtime/version"
"github.com/sirupsen/logrus"
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
)
const (
@@ -907,7 +908,9 @@ func (p *Builder) sendHttpRequest(req *http.Request, requestBytes []byte) (*http
proxyReq.Header.Set("X-Forwarded-For", req.RemoteAddr)
proxyReq.Header.Set("Content-Type", "application/json")
client := &http.Client{}
client := &http.Client{
Transport: otelhttp.NewTransport(http.DefaultTransport),
}
if p.cfg.secret != "" {
client = network.NewHttpClientWithSecret(p.cfg.secret, "")
}

View File

@@ -18,6 +18,7 @@ import (
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/v5/network"
"github.com/sirupsen/logrus"
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
)
var (
@@ -246,7 +247,9 @@ func (p *Proxy) sendHttpRequest(req *http.Request, requestBytes []byte) (*http.R
proxyReq.Header.Set("X-Forwarded-For", req.RemoteAddr)
proxyReq.Header.Set("Content-Type", "application/json")
client := &http.Client{}
client := &http.Client{
Transport: otelhttp.NewTransport(http.DefaultTransport),
}
if p.cfg.secret != "" {
client = network.NewHttpClientWithSecret(p.cfg.secret, "")
}

View File

@@ -20,6 +20,7 @@ import (
"github.com/prysmaticlabs/prysm/v5/monitoring/tracing"
"github.com/prysmaticlabs/prysm/v5/monitoring/tracing/trace"
"github.com/sirupsen/logrus"
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
)
const (
@@ -55,8 +56,10 @@ func NewApiClient(baseEndpoint string) (*ApiClient, error) {
return nil, fmt.Errorf("web3signer url must be in the format of http(s)://host:port url used: %v", baseEndpoint)
}
return &ApiClient{
BaseURL: u,
RestClient: &http.Client{},
BaseURL: u,
RestClient: &http.Client{
Transport: otelhttp.NewTransport(http.DefaultTransport),
},
}, nil
}