mirror of
https://gitlab.com/pulsechaincom/prysm-pulse.git
synced 2024-12-22 03:30:35 +00:00
5a66807989
* First take at updating everything to v5 * Patch gRPC gateway to use prysm v5 Fix patch * Update go ssz --------- Co-authored-by: Preston Van Loon <pvanloon@offchainlabs.com>
153 lines
5.2 KiB
Go
153 lines
5.2 KiB
Go
package client
|
|
|
|
import (
|
|
"context"
|
|
"strings"
|
|
|
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
|
"github.com/pkg/errors"
|
|
"github.com/prysmaticlabs/prysm/v5/beacon-chain/builder"
|
|
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/signing"
|
|
"github.com/prysmaticlabs/prysm/v5/config/params"
|
|
"github.com/prysmaticlabs/prysm/v5/encoding/bytesutil"
|
|
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
|
validatorpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1/validator-client"
|
|
"github.com/prysmaticlabs/prysm/v5/validator/client/iface"
|
|
"go.opencensus.io/trace"
|
|
)
|
|
|
|
// SubmitValidatorRegistrations signs validator registration objects and submits it to the beacon node by batch of validatorRegsBatchSize size maximum.
|
|
// If at least one error occurs during a registration call to the beacon node, the last error is returned.
|
|
func SubmitValidatorRegistrations(
|
|
ctx context.Context,
|
|
validatorClient iface.ValidatorClient,
|
|
signedRegs []*ethpb.SignedValidatorRegistrationV1,
|
|
validatorRegsBatchSize int,
|
|
) error {
|
|
ctx, span := trace.StartSpan(ctx, "validator.SubmitValidatorRegistrations")
|
|
defer span.End()
|
|
|
|
if len(signedRegs) == 0 {
|
|
return nil
|
|
}
|
|
|
|
chunks := chunkSignedValidatorRegistrationV1(signedRegs, validatorRegsBatchSize)
|
|
var lastErr error
|
|
|
|
for _, chunk := range chunks {
|
|
innerSignerRegs := ethpb.SignedValidatorRegistrationsV1{
|
|
Messages: chunk,
|
|
}
|
|
|
|
if _, err := validatorClient.SubmitValidatorRegistrations(ctx, &innerSignerRegs); err != nil {
|
|
lastErr = errors.Wrap(err, "could not submit signed registrations to beacon node")
|
|
|
|
if strings.Contains(err.Error(), builder.ErrNoBuilder.Error()) {
|
|
log.Warnln("Beacon node does not utilize a custom builder via the --http-mev-relay flag. Validator registration skipped.")
|
|
|
|
// We stop early the loop here, since if the builder endpoint is not configured for this chunk, it is useless to check the following chunks
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
if lastErr == nil {
|
|
log.Infoln("Submitted builder validator registration settings for custom builders")
|
|
} else {
|
|
log.WithError(lastErr).Warn("Could not submit all signed registrations to beacon node")
|
|
}
|
|
|
|
return lastErr
|
|
}
|
|
|
|
// Sings validator registration obj with the proposer domain and private key.
|
|
func signValidatorRegistration(ctx context.Context, signer iface.SigningFunc, reg *ethpb.ValidatorRegistrationV1) ([]byte, error) {
|
|
// Per spec, we want the fork version and genesis validator to be nil.
|
|
// Which is genesis value and zero by default.
|
|
d, err := signing.ComputeDomain(
|
|
params.BeaconConfig().DomainApplicationBuilder,
|
|
nil, /* fork version */
|
|
nil /* genesis val root */)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
r, err := signing.ComputeSigningRoot(reg, d)
|
|
if err != nil {
|
|
return nil, errors.Wrap(err, signingRootErr)
|
|
}
|
|
|
|
sig, err := signer(ctx, &validatorpb.SignRequest{
|
|
PublicKey: reg.Pubkey,
|
|
SigningRoot: r[:],
|
|
SignatureDomain: d,
|
|
Object: &validatorpb.SignRequest_Registration{Registration: reg},
|
|
})
|
|
if err != nil {
|
|
return nil, errors.Wrap(err, "could not sign validator registration")
|
|
}
|
|
return sig.Marshal(), nil
|
|
}
|
|
|
|
// SignValidatorRegistrationRequest compares and returns either the cached validator registration request or signs a new one.
|
|
func (v *validator) SignValidatorRegistrationRequest(ctx context.Context, signer iface.SigningFunc, newValidatorRegistration *ethpb.ValidatorRegistrationV1) (*ethpb.SignedValidatorRegistrationV1, error) {
|
|
signedReg, ok := v.signedValidatorRegistrations[bytesutil.ToBytes48(newValidatorRegistration.Pubkey)]
|
|
if ok && isValidatorRegistrationSame(signedReg.Message, newValidatorRegistration) {
|
|
return signedReg, nil
|
|
} else {
|
|
sig, err := signValidatorRegistration(ctx, signer, newValidatorRegistration)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
newRequest := ðpb.SignedValidatorRegistrationV1{
|
|
Message: newValidatorRegistration,
|
|
Signature: sig,
|
|
}
|
|
v.signedValidatorRegistrations[bytesutil.ToBytes48(newValidatorRegistration.Pubkey)] = newRequest
|
|
return newRequest, nil
|
|
}
|
|
}
|
|
|
|
func isValidatorRegistrationSame(cachedVR *ethpb.ValidatorRegistrationV1, newVR *ethpb.ValidatorRegistrationV1) bool {
|
|
isSame := true
|
|
if cachedVR.GasLimit != newVR.GasLimit {
|
|
isSame = false
|
|
}
|
|
if hexutil.Encode(cachedVR.FeeRecipient) != hexutil.Encode(newVR.FeeRecipient) {
|
|
isSame = false
|
|
}
|
|
return isSame
|
|
}
|
|
|
|
// chunkSignedValidatorRegistrationV1 chunks regs into chunks of size chunkSize (the last chunk may be smaller). If chunkSize is non-positive, returns only one chunk.
|
|
func chunkSignedValidatorRegistrationV1(regs []*ethpb.SignedValidatorRegistrationV1, chunkSize int) [][]*ethpb.SignedValidatorRegistrationV1 {
|
|
if chunkSize <= 0 {
|
|
chunkSize = len(regs)
|
|
}
|
|
|
|
regsCount := len(regs)
|
|
|
|
chunksCount := (regsCount + chunkSize - 1) / chunkSize
|
|
lastChunkSize := regsCount % chunkSize
|
|
|
|
if lastChunkSize == 0 {
|
|
lastChunkSize = chunkSize
|
|
}
|
|
|
|
chunks := make([][]*ethpb.SignedValidatorRegistrationV1, chunksCount)
|
|
|
|
for i := 0; i < chunksCount-1; i++ {
|
|
chunks[i] = make([]*ethpb.SignedValidatorRegistrationV1, chunkSize)
|
|
}
|
|
|
|
chunks[chunksCount-1] = make([]*ethpb.SignedValidatorRegistrationV1, lastChunkSize)
|
|
|
|
for i, reg := range regs {
|
|
chunkIndex := i / chunkSize
|
|
chunkOffset := i % chunkSize
|
|
chunks[chunkIndex][chunkOffset] = reg
|
|
}
|
|
|
|
return chunks
|
|
}
|