refactor Payload Id caches (#12987)

* init

- getLocalPayload does not use the proposer ID from the cache but takes
  it from the block

- Fixed tests in blockchain package
- Fixed tests in the RPC package
- Fixed spectests

EpochProposers takes 256 bytes that can be avoided to be copied, but
this optimization is not clear to be worth it.

assginmentStatus can be optimized to use the cached version from the
TrackedValidatorsCache

We shouldn't cache the proposer duties when calling getDuties but when
we update the epoch boundary instead

* track validators on prepare proposers

* more rpc tests

* more rpc tests

* initialize grpc caches

* Add back fcu log

Also fix two existing bugs wrong parent hash on pre Capella and wrong
blockhashes on altair

* use beacon default fee recipient if there is none in the vc

* fix validator test

* radek's review

* push always proposer settings even if no flag is specified in the VC

* Only register with the builder if the VC flag is set

Great find by @terencechain

* add regression test

* Radek's review

* change signature of registration builder
This commit is contained in:
Potuz
2023-12-22 15:47:51 -03:00
committed by GitHub
parent 7d64104003
commit b7e0819f00
42 changed files with 533 additions and 553 deletions

View File

@@ -32,7 +32,6 @@ go_library(
"//beacon-chain/core/altair:go_default_library",
"//beacon-chain/core/signing:go_default_library",
"//cache/lru:go_default_library",
"//cmd/validator/flags:go_default_library",
"//config/features:go_default_library",
"//config/fieldparams:go_default_library",
"//config/params:go_default_library",

View File

@@ -7,7 +7,6 @@ import (
"time"
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/v4/cmd/validator/flags"
fieldparams "github.com/prysmaticlabs/prysm/v4/config/fieldparams"
"github.com/prysmaticlabs/prysm/v4/config/params"
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
@@ -55,25 +54,20 @@ func run(ctx context.Context, v iface.Validator) {
sub := km.SubscribeAccountChanges(accountsChangedChan)
// check if proposer settings is still nil
// Set properties on the beacon node like the fee recipient for validators that are being used & active.
if v.ProposerSettings() != nil {
log.Infof("Validator client started with provided proposer settings that sets options such as fee recipient"+
" and will periodically update the beacon node and custom builder (if --%s)", flags.EnableBuilderFlag.Name)
deadline := time.Now().Add(5 * time.Minute)
if err := v.PushProposerSettings(ctx, km, headSlot, deadline); err != nil {
if errors.Is(err, ErrBuilderValidatorRegistration) {
log.WithError(err).Warn("Push proposer settings error")
} else {
log.WithError(err).Fatal("Failed to update proposer settings") // allow fatal. skipcq
}
}
} else {
if v.ProposerSettings() == nil {
log.Warn("Validator client started without proposer settings such as fee recipient" +
" and will continue to use settings provided in the beacon node.")
}
deadline := time.Now().Add(5 * time.Minute)
if err := v.PushProposerSettings(ctx, km, headSlot, deadline); err != nil {
if errors.Is(err, ErrBuilderValidatorRegistration) {
log.WithError(err).Warn("Push proposer settings error")
} else {
log.WithError(err).Fatal("Failed to update proposer settings") // allow fatal. skipcq
}
}
for {
ctx, span := trace.StartSpan(ctx, "validator.processSlot")
select {
case <-ctx.Done():
log.Info("Context canceled, stopping validator")
@@ -108,7 +102,7 @@ func run(ctx context.Context, v iface.Validator) {
// call push proposer setting at the start of each epoch to account for the following edge case:
// proposer is activated at the start of epoch and tries to propose immediately
if slots.IsEpochStart(slot) && v.ProposerSettings() != nil {
if slots.IsEpochStart(slot) {
go func() {
// deadline set for 1 epoch from call to not overlap.
epochDeadline := v.SlotDeadline(slot + params.BeaconConfig().SlotsPerEpoch - 1)

View File

@@ -1028,14 +1028,10 @@ func (v *validator) PushProposerSettings(ctx context.Context, km keymanager.IKey
return err
}
signedRegReqs, err := v.buildSignedRegReqs(ctx, filteredKeys, km.Sign)
if err != nil {
return err
}
signedRegReqs := v.buildSignedRegReqs(ctx, filteredKeys, km.Sign)
if err := SubmitValidatorRegistrations(ctx, v.validatorClient, signedRegReqs, v.validatorRegBatchSize); err != nil {
return errors.Wrap(ErrBuilderValidatorRegistration, err.Error())
}
return nil
}
@@ -1089,12 +1085,10 @@ func (v *validator) buildPrepProposerReqs(ctx context.Context, pubkeys [][fieldp
for _, k := range pubkeys {
// Default case: Define fee recipient to burn address
var feeRecipient common.Address
isFeeRecipientDefined := false
// If fee recipient is defined in default configuration, use it
if v.ProposerSettings() != nil && v.ProposerSettings().DefaultConfig != nil && v.ProposerSettings().DefaultConfig.FeeRecipientConfig != nil {
feeRecipient = v.ProposerSettings().DefaultConfig.FeeRecipientConfig.FeeRecipient // Use cli config for fee recipient.
isFeeRecipientDefined = true
}
// If fee recipient is defined for this specific pubkey in proposer configuration, use it
@@ -1103,7 +1097,6 @@ func (v *validator) buildPrepProposerReqs(ctx context.Context, pubkeys [][fieldp
if ok && config != nil && config.FeeRecipientConfig != nil {
feeRecipient = config.FeeRecipientConfig.FeeRecipient // Use file config for fee recipient.
isFeeRecipientDefined = true
}
}
@@ -1112,29 +1105,22 @@ func (v *validator) buildPrepProposerReqs(ctx context.Context, pubkeys [][fieldp
continue
}
if isFeeRecipientDefined {
prepareProposerReqs = append(prepareProposerReqs, &ethpb.PrepareBeaconProposerRequest_FeeRecipientContainer{
ValidatorIndex: validatorIndex,
FeeRecipient: feeRecipient[:],
})
if hexutil.Encode(feeRecipient.Bytes()) == params.BeaconConfig().EthBurnAddressHex {
log.WithFields(logrus.Fields{
"validatorIndex": validatorIndex,
"feeRecipient": feeRecipient,
}).Warn("Fee recipient is burn address")
}
}
prepareProposerReqs = append(prepareProposerReqs, &ethpb.PrepareBeaconProposerRequest_FeeRecipientContainer{
ValidatorIndex: validatorIndex,
FeeRecipient: feeRecipient[:],
})
}
return prepareProposerReqs, nil
}
func (v *validator) buildSignedRegReqs(ctx context.Context, pubkeys [][fieldparams.BLSPubkeyLength]byte /* only active pubkeys */, signer iface.SigningFunc) ([]*ethpb.SignedValidatorRegistrationV1, error) {
func (v *validator) buildSignedRegReqs(ctx context.Context, pubkeys [][fieldparams.BLSPubkeyLength]byte /* only active pubkeys */, signer iface.SigningFunc) []*ethpb.SignedValidatorRegistrationV1 {
var signedValRegRegs []*ethpb.SignedValidatorRegistrationV1
if v.ProposerSettings() == nil {
return signedValRegRegs
}
// if the timestamp is pre-genesis, don't create registrations
if v.genesisTime > uint64(time.Now().UTC().Unix()) {
return signedValRegRegs, nil
return signedValRegRegs
}
for i, k := range pubkeys {
feeRecipient := common.HexToAddress(params.BeaconConfig().EthBurnAddressHex)
@@ -1203,7 +1189,7 @@ func (v *validator) buildSignedRegReqs(ctx context.Context, pubkeys [][fieldpara
}).Warn("Fee recipient is burn address")
}
}
return signedValRegRegs, nil
return signedValRegRegs
}
func (v *validator) validatorIndex(ctx context.Context, pubkey [fieldparams.BLSPubkeyLength]byte) (primitives.ValidatorIndex, bool, error) {

View File

@@ -1862,8 +1862,7 @@ func TestValidator_PushProposerSettings(t *testing.T) {
if tt.feeRecipientMap != nil {
feeRecipients, err := v.buildPrepProposerReqs(ctx, pubkeys)
require.NoError(t, err)
signedRegisterValidatorRequests, err := v.buildSignedRegReqs(ctx, pubkeys, km.Sign)
require.NoError(t, err)
signedRegisterValidatorRequests := v.buildSignedRegReqs(ctx, pubkeys, km.Sign)
for _, recipient := range feeRecipients {
require.Equal(t, strings.ToLower(tt.feeRecipientMap[recipient.ValidatorIndex]), strings.ToLower(hexutil.Encode(recipient.FeeRecipient)))
}
@@ -1935,6 +1934,7 @@ func TestValidator_buildPrepProposerReqs_WithoutDefaultConfig(t *testing.T) {
feeRecipient1 := getFeeRecipientFromString(t, "0x1111111111111111111111111111111111111111")
feeRecipient2 := getFeeRecipientFromString(t, "0x0000000000000000000000000000000000000000")
feeRecipient3 := getFeeRecipientFromString(t, "0x3333333333333333333333333333333333333333")
feeRecipient4 := common.Address{}
ctrl := gomock.NewController(t)
defer ctrl.Finish()
@@ -1984,6 +1984,11 @@ func TestValidator_buildPrepProposerReqs_WithoutDefaultConfig(t *testing.T) {
FeeRecipient: feeRecipient3,
},
},
pubkey4: {
FeeRecipientConfig: &validatorserviceconfig.FeeRecipientConfig{
FeeRecipient: feeRecipient4,
},
},
},
},
pubkeyToValidatorIndex: map[[48]byte]primitives.ValidatorIndex{
@@ -2003,6 +2008,10 @@ func TestValidator_buildPrepProposerReqs_WithoutDefaultConfig(t *testing.T) {
ValidatorIndex: 2,
FeeRecipient: feeRecipient2[:],
},
{
ValidatorIndex: 4,
FeeRecipient: feeRecipient4[:],
},
}
filteredKeys, err := v.filterAndCacheActiveKeys(ctx, pubkeys, 0)
require.NoError(t, err)
@@ -2256,8 +2265,7 @@ func TestValidator_buildSignedRegReqs_DefaultConfigDisabled(t *testing.T) {
v.pubkeyToValidatorIndex[pubkey1] = primitives.ValidatorIndex(1)
v.pubkeyToValidatorIndex[pubkey2] = primitives.ValidatorIndex(2)
v.pubkeyToValidatorIndex[pubkey3] = primitives.ValidatorIndex(3)
actual, err := v.buildSignedRegReqs(ctx, pubkeys, signer)
require.NoError(t, err)
actual := v.buildSignedRegReqs(ctx, pubkeys, signer)
assert.Equal(t, 1, len(actual))
assert.DeepEqual(t, feeRecipient1[:], actual[0].Message.FeeRecipient)
@@ -2342,8 +2350,7 @@ func TestValidator_buildSignedRegReqs_DefaultConfigEnabled(t *testing.T) {
v.pubkeyToValidatorIndex[pubkey1] = primitives.ValidatorIndex(1)
v.pubkeyToValidatorIndex[pubkey2] = primitives.ValidatorIndex(2)
v.pubkeyToValidatorIndex[pubkey3] = primitives.ValidatorIndex(3)
actual, err := v.buildSignedRegReqs(ctx, pubkeys, signer)
require.NoError(t, err)
actual := v.buildSignedRegReqs(ctx, pubkeys, signer)
assert.Equal(t, 2, len(actual))
@@ -2391,9 +2398,7 @@ func TestValidator_buildSignedRegReqs_SignerOnError(t *testing.T) {
return nil, errors.New("custom error")
}
actual, err := v.buildSignedRegReqs(ctx, pubkeys, signer)
require.NoError(t, err)
actual := v.buildSignedRegReqs(ctx, pubkeys, signer)
assert.Equal(t, 0, len(actual))
}
@@ -2449,8 +2454,6 @@ func TestValidator_buildSignedRegReqs_TimestampBeforeGenesis(t *testing.T) {
return signature, nil
}
v.pubkeyToValidatorIndex[pubkey1] = primitives.ValidatorIndex(1)
actual, err := v.buildSignedRegReqs(ctx, pubkeys, signer)
require.NoError(t, err)
actual := v.buildSignedRegReqs(ctx, pubkeys, signer)
assert.Equal(t, 0, len(actual))
}