mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-10 13:58:09 -05:00
Compare commits
18 Commits
v4.0.4
...
release-v4
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
aa7d0df7ff | ||
|
|
0a213d70e8 | ||
|
|
b84dd40ba9 | ||
|
|
aeaa72fdc2 | ||
|
|
ddc1e48e05 | ||
|
|
f91159337b | ||
|
|
537236e1c9 | ||
|
|
73e4bdccbb | ||
|
|
f54bd64bdd | ||
|
|
d907cae595 | ||
|
|
be23773924 | ||
|
|
29f6de1e96 | ||
|
|
955a21fea4 | ||
|
|
b4f1fea029 | ||
|
|
f1b88d005d | ||
|
|
ee612d958a | ||
|
|
09e22538f9 | ||
|
|
3b9e974a45 |
@@ -4,14 +4,14 @@
|
||||
[](https://goreportcard.com/report/github.com/prysmaticlabs/prysm)
|
||||
[](https://github.com/ethereum/consensus-specs/tree/v1.3.0)
|
||||
[](https://github.com/ethereum/execution-apis/tree/v1.0.0-beta.2/src/engine)
|
||||
[](https://discord.gg/CTYGPUJ)
|
||||
[](https://discord.gg/prysmaticlabs)
|
||||
[](https://www.gitpoap.io/gh/prysmaticlabs/prysm)
|
||||
|
||||
This is the core repository for Prysm, a [Golang](https://golang.org/) implementation of the [Ethereum Consensus](https://ethereum.org/en/eth2/) specification, developed by [Prysmatic Labs](https://prysmaticlabs.com). See the [Changelog](https://github.com/prysmaticlabs/prysm/releases) for details of the latest releases and upcoming breaking changes.
|
||||
|
||||
### Getting Started
|
||||
|
||||
A detailed set of installation and usage instructions as well as breakdowns of each individual component are available in the [official documentation portal](https://docs.prylabs.network). If you still have questions, feel free to stop by our [Discord](https://discord.gg/CTYGPUJ).
|
||||
A detailed set of installation and usage instructions as well as breakdowns of each individual component are available in the [official documentation portal](https://docs.prylabs.network). If you still have questions, feel free to stop by our [Discord](https://discord.gg/prysmaticlabs).
|
||||
|
||||
### Staking on Mainnet
|
||||
|
||||
|
||||
@@ -69,7 +69,7 @@ func (s *Service) getAttPreState(ctx context.Context, c *ethpb.Checkpoint) (stat
|
||||
return nil, errors.Wrap(err, "could not check checkpoint condition in forkchoice")
|
||||
}
|
||||
if !ok {
|
||||
return nil, ErrNotCheckpoint
|
||||
return nil, errors.Wrap(ErrNotCheckpoint, fmt.Sprintf("epoch %d root %#x", c.Epoch, c.Root))
|
||||
}
|
||||
|
||||
// Fallback to state regeneration.
|
||||
|
||||
@@ -180,7 +180,7 @@ func TestStore_SaveCheckpointState(t *testing.T) {
|
||||
require.NoError(t, service.cfg.BeaconDB.SaveStateSummary(ctx, ðpb.StateSummary{Root: bytesutil.PadTo([]byte{'B'}, fieldparams.RootLength)}))
|
||||
|
||||
s2, err := service.getAttPreState(ctx, cp2)
|
||||
require.ErrorIs(t, ErrNotCheckpoint, err)
|
||||
require.ErrorContains(t, "epoch 2 root 0x4200000000000000000000000000000000000000000000000000000000000000: not a checkpoint in forkchoice", err)
|
||||
|
||||
st, root, err = prepareForkchoiceState(ctx, 33, [32]byte(cp2.Root), [32]byte(cp1.Root), [32]byte{'R'}, cp2, cp2)
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -130,9 +130,15 @@ func performValidatorStateMigration(ctx context.Context, bar *progressbar.Progre
|
||||
return err
|
||||
}
|
||||
item := enc
|
||||
if hasAltairKey(item) {
|
||||
switch {
|
||||
case hasAltairKey(enc):
|
||||
item = item[len(altairKey):]
|
||||
case hasBellatrixKey(enc):
|
||||
item = item[len(bellatrixKey):]
|
||||
case hasCapellaKey(enc):
|
||||
item = item[len(capellaKey):]
|
||||
}
|
||||
|
||||
detector, err := detect.FromState(item)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -165,9 +171,14 @@ func performValidatorStateMigration(ctx context.Context, bar *progressbar.Progre
|
||||
return err
|
||||
}
|
||||
var stateBytes []byte
|
||||
if hasAltairKey(enc) {
|
||||
switch {
|
||||
case hasAltairKey(enc):
|
||||
stateBytes = snappy.Encode(nil, append(altairKey, rawObj...))
|
||||
} else {
|
||||
case hasBellatrixKey(enc):
|
||||
stateBytes = snappy.Encode(nil, append(bellatrixKey, rawObj...))
|
||||
case hasCapellaKey(enc):
|
||||
stateBytes = snappy.Encode(nil, append(capellaKey, rawObj...))
|
||||
default:
|
||||
stateBytes = snappy.Encode(nil, rawObj)
|
||||
}
|
||||
if stateErr := stateBkt.Put(keys[index], stateBytes); stateErr != nil {
|
||||
|
||||
@@ -313,3 +313,217 @@ func Test_migrateAltairStateValidators(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_migrateBellatrixStateValidators(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
setup func(t *testing.T, dbStore *Store, state state.BeaconState, vals []*v1alpha1.Validator)
|
||||
eval func(t *testing.T, dbStore *Store, state state.BeaconState, vals []*v1alpha1.Validator)
|
||||
}{
|
||||
{
|
||||
name: "migrates validators and adds them to new buckets",
|
||||
setup: func(t *testing.T, dbStore *Store, state state.BeaconState, vals []*v1alpha1.Validator) {
|
||||
// create some new buckets that should be present for this migration
|
||||
err := dbStore.db.Update(func(tx *bbolt.Tx) error {
|
||||
_, err := tx.CreateBucketIfNotExists(stateValidatorsBucket)
|
||||
assert.NoError(t, err)
|
||||
_, err = tx.CreateBucketIfNotExists(blockRootValidatorHashesBucket)
|
||||
assert.NoError(t, err)
|
||||
return nil
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
},
|
||||
eval: func(t *testing.T, dbStore *Store, state state.BeaconState, vals []*v1alpha1.Validator) {
|
||||
// check whether the new buckets are present
|
||||
err := dbStore.db.View(func(tx *bbolt.Tx) error {
|
||||
valBkt := tx.Bucket(stateValidatorsBucket)
|
||||
assert.NotNil(t, valBkt)
|
||||
idxBkt := tx.Bucket(blockRootValidatorHashesBucket)
|
||||
assert.NotNil(t, idxBkt)
|
||||
return nil
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
|
||||
// check if the migration worked
|
||||
blockRoot := [32]byte{'A'}
|
||||
rcvdState, err := dbStore.State(context.Background(), blockRoot)
|
||||
assert.NoError(t, err)
|
||||
require.DeepSSZEqual(t, rcvdState.ToProtoUnsafe(), state.ToProtoUnsafe(), "saved state with validators and retrieved state are not matching")
|
||||
|
||||
// find hashes of the validators that are set as part of the state
|
||||
var hashes []byte
|
||||
var individualHashes [][]byte
|
||||
for _, val := range vals {
|
||||
hash, hashErr := val.HashTreeRoot()
|
||||
assert.NoError(t, hashErr)
|
||||
hashes = append(hashes, hash[:]...)
|
||||
individualHashes = append(individualHashes, hash[:])
|
||||
}
|
||||
|
||||
// check if all the validators that were in the state, are stored properly in the validator bucket
|
||||
pbState, err := state_native.ProtobufBeaconStateBellatrix(rcvdState.ToProtoUnsafe())
|
||||
assert.NoError(t, err)
|
||||
validatorsFoundCount := 0
|
||||
for _, val := range pbState.Validators {
|
||||
hash, hashErr := val.HashTreeRoot()
|
||||
assert.NoError(t, hashErr)
|
||||
found := false
|
||||
for _, h := range individualHashes {
|
||||
if bytes.Equal(hash[:], h) {
|
||||
found = true
|
||||
}
|
||||
}
|
||||
require.Equal(t, true, found)
|
||||
validatorsFoundCount++
|
||||
}
|
||||
require.Equal(t, len(vals), validatorsFoundCount)
|
||||
|
||||
// check if the state validator indexes are stored properly
|
||||
err = dbStore.db.View(func(tx *bbolt.Tx) error {
|
||||
rcvdValhashBytes := tx.Bucket(blockRootValidatorHashesBucket).Get(blockRoot[:])
|
||||
rcvdValHashes, sErr := snappy.Decode(nil, rcvdValhashBytes)
|
||||
assert.NoError(t, sErr)
|
||||
require.DeepEqual(t, hashes, rcvdValHashes)
|
||||
return nil
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
dbStore := setupDB(t)
|
||||
|
||||
// add a state with the given validators
|
||||
vals := validators(10)
|
||||
blockRoot := [32]byte{'A'}
|
||||
st, _ := util.DeterministicGenesisStateBellatrix(t, 20)
|
||||
err := st.SetFork(&v1alpha1.Fork{
|
||||
PreviousVersion: params.BeaconConfig().AltairForkVersion,
|
||||
CurrentVersion: params.BeaconConfig().BellatrixForkVersion,
|
||||
Epoch: 0,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.NoError(t, st.SetSlot(100))
|
||||
assert.NoError(t, st.SetValidators(vals))
|
||||
assert.NoError(t, dbStore.SaveState(context.Background(), st, blockRoot))
|
||||
|
||||
// enable historical state representation flag to test this
|
||||
resetCfg := features.InitWithReset(&features.Flags{
|
||||
EnableHistoricalSpaceRepresentation: true,
|
||||
})
|
||||
defer resetCfg()
|
||||
|
||||
tt.setup(t, dbStore, st, vals)
|
||||
assert.NoError(t, migrateStateValidators(context.Background(), dbStore.db), "migrateArchivedIndex(tx) error")
|
||||
tt.eval(t, dbStore, st, vals)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_migrateCapellaStateValidators(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
setup func(t *testing.T, dbStore *Store, state state.BeaconState, vals []*v1alpha1.Validator)
|
||||
eval func(t *testing.T, dbStore *Store, state state.BeaconState, vals []*v1alpha1.Validator)
|
||||
}{
|
||||
{
|
||||
name: "migrates validators and adds them to new buckets",
|
||||
setup: func(t *testing.T, dbStore *Store, state state.BeaconState, vals []*v1alpha1.Validator) {
|
||||
// create some new buckets that should be present for this migration
|
||||
err := dbStore.db.Update(func(tx *bbolt.Tx) error {
|
||||
_, err := tx.CreateBucketIfNotExists(stateValidatorsBucket)
|
||||
assert.NoError(t, err)
|
||||
_, err = tx.CreateBucketIfNotExists(blockRootValidatorHashesBucket)
|
||||
assert.NoError(t, err)
|
||||
return nil
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
},
|
||||
eval: func(t *testing.T, dbStore *Store, state state.BeaconState, vals []*v1alpha1.Validator) {
|
||||
// check whether the new buckets are present
|
||||
err := dbStore.db.View(func(tx *bbolt.Tx) error {
|
||||
valBkt := tx.Bucket(stateValidatorsBucket)
|
||||
assert.NotNil(t, valBkt)
|
||||
idxBkt := tx.Bucket(blockRootValidatorHashesBucket)
|
||||
assert.NotNil(t, idxBkt)
|
||||
return nil
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
|
||||
// check if the migration worked
|
||||
blockRoot := [32]byte{'A'}
|
||||
rcvdState, err := dbStore.State(context.Background(), blockRoot)
|
||||
assert.NoError(t, err)
|
||||
require.DeepSSZEqual(t, rcvdState.ToProtoUnsafe(), state.ToProtoUnsafe(), "saved state with validators and retrieved state are not matching")
|
||||
|
||||
// find hashes of the validators that are set as part of the state
|
||||
var hashes []byte
|
||||
var individualHashes [][]byte
|
||||
for _, val := range vals {
|
||||
hash, hashErr := val.HashTreeRoot()
|
||||
assert.NoError(t, hashErr)
|
||||
hashes = append(hashes, hash[:]...)
|
||||
individualHashes = append(individualHashes, hash[:])
|
||||
}
|
||||
|
||||
// check if all the validators that were in the state, are stored properly in the validator bucket
|
||||
pbState, err := state_native.ProtobufBeaconStateCapella(rcvdState.ToProtoUnsafe())
|
||||
assert.NoError(t, err)
|
||||
validatorsFoundCount := 0
|
||||
for _, val := range pbState.Validators {
|
||||
hash, hashErr := val.HashTreeRoot()
|
||||
assert.NoError(t, hashErr)
|
||||
found := false
|
||||
for _, h := range individualHashes {
|
||||
if bytes.Equal(hash[:], h) {
|
||||
found = true
|
||||
}
|
||||
}
|
||||
require.Equal(t, true, found)
|
||||
validatorsFoundCount++
|
||||
}
|
||||
require.Equal(t, len(vals), validatorsFoundCount)
|
||||
|
||||
// check if the state validator indexes are stored properly
|
||||
err = dbStore.db.View(func(tx *bbolt.Tx) error {
|
||||
rcvdValhashBytes := tx.Bucket(blockRootValidatorHashesBucket).Get(blockRoot[:])
|
||||
rcvdValHashes, sErr := snappy.Decode(nil, rcvdValhashBytes)
|
||||
assert.NoError(t, sErr)
|
||||
require.DeepEqual(t, hashes, rcvdValHashes)
|
||||
return nil
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
dbStore := setupDB(t)
|
||||
|
||||
// add a state with the given validators
|
||||
vals := validators(10)
|
||||
blockRoot := [32]byte{'A'}
|
||||
st, _ := util.DeterministicGenesisStateCapella(t, 20)
|
||||
err := st.SetFork(&v1alpha1.Fork{
|
||||
PreviousVersion: params.BeaconConfig().BellatrixForkVersion,
|
||||
CurrentVersion: params.BeaconConfig().CapellaForkVersion,
|
||||
Epoch: 0,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.NoError(t, st.SetSlot(100))
|
||||
assert.NoError(t, st.SetValidators(vals))
|
||||
assert.NoError(t, dbStore.SaveState(context.Background(), st, blockRoot))
|
||||
|
||||
// enable historical state representation flag to test this
|
||||
resetCfg := features.InitWithReset(&features.Flags{
|
||||
EnableHistoricalSpaceRepresentation: true,
|
||||
})
|
||||
defer resetCfg()
|
||||
|
||||
tt.setup(t, dbStore, st, vals)
|
||||
assert.NoError(t, migrateStateValidators(context.Background(), dbStore.db), "migrateArchivedIndex(tx) error")
|
||||
tt.eval(t, dbStore, st, vals)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,19 +114,11 @@ func (s *Service) Start() {
|
||||
"ValidatorIndices": tracked,
|
||||
}).Info("Starting service")
|
||||
|
||||
stateChannel := make(chan *feed.Event, 1)
|
||||
stateSub := s.config.StateNotifier.StateFeed().Subscribe(stateChannel)
|
||||
|
||||
go s.run(stateChannel, stateSub)
|
||||
go s.run()
|
||||
}
|
||||
|
||||
// run waits until the beacon is synced and starts the monitoring system.
|
||||
func (s *Service) run(stateChannel chan *feed.Event, stateSub event.Subscription) {
|
||||
if stateChannel == nil {
|
||||
log.Error("State state is nil")
|
||||
return
|
||||
}
|
||||
|
||||
func (s *Service) run() {
|
||||
if err := s.waitForSync(s.config.InitialSyncComplete); err != nil {
|
||||
log.WithError(err)
|
||||
return
|
||||
@@ -154,6 +146,8 @@ func (s *Service) run(stateChannel chan *feed.Event, stateSub event.Subscription
|
||||
s.isLogging = true
|
||||
s.Unlock()
|
||||
|
||||
stateChannel := make(chan *feed.Event, 1)
|
||||
stateSub := s.config.StateNotifier.StateFeed().Subscribe(stateChannel)
|
||||
s.monitorRoutine(stateChannel, stateSub)
|
||||
}
|
||||
|
||||
|
||||
@@ -271,11 +271,9 @@ func TestWaitForSyncCanceled(t *testing.T) {
|
||||
func TestRun(t *testing.T) {
|
||||
hook := logTest.NewGlobal()
|
||||
s := setupService(t)
|
||||
stateChannel := make(chan *feed.Event, 1)
|
||||
stateSub := s.config.StateNotifier.StateFeed().Subscribe(stateChannel)
|
||||
|
||||
go func() {
|
||||
s.run(stateChannel, stateSub)
|
||||
s.run()
|
||||
}()
|
||||
close(s.config.InitialSyncComplete)
|
||||
|
||||
|
||||
@@ -581,7 +581,8 @@ func (b *BeaconNode) fetchBuilderService() *builder.Service {
|
||||
|
||||
func (b *BeaconNode) registerAttestationPool() error {
|
||||
s, err := attestations.NewService(b.ctx, &attestations.Config{
|
||||
Pool: b.attestationPool,
|
||||
Pool: b.attestationPool,
|
||||
InitialSyncComplete: b.initialSyncComplete,
|
||||
})
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not register atts pool service")
|
||||
@@ -742,6 +743,7 @@ func (b *BeaconNode) registerSlasherService() error {
|
||||
SlashingPoolInserter: b.slashingsPool,
|
||||
SyncChecker: syncService,
|
||||
HeadStateFetcher: chainService,
|
||||
ClockWaiter: b.clockWaiter,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -18,6 +18,7 @@ go_library(
|
||||
deps = [
|
||||
"//beacon-chain/operations/attestations/kv:go_default_library",
|
||||
"//cache/lru:go_default_library",
|
||||
"//config/features:go_default_library",
|
||||
"//config/params:go_default_library",
|
||||
"//consensus-types/primitives:go_default_library",
|
||||
"//crypto/hash:go_default_library",
|
||||
|
||||
@@ -53,27 +53,25 @@ func (c *AttCaches) aggregateUnaggregatedAttestations(ctx context.Context, unagg
|
||||
// Track the unaggregated attestations that aren't able to aggregate.
|
||||
leftOverUnaggregatedAtt := make(map[[32]byte]bool)
|
||||
for _, atts := range attsByDataRoot {
|
||||
aggregatedAtts := make([]*ethpb.Attestation, 0, len(atts))
|
||||
processedAtts, err := attaggregation.Aggregate(atts)
|
||||
aggregated, err := attaggregation.AggregateDisjointOneBitAtts(atts)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.Wrap(err, "could not aggregate unaggregated attestations")
|
||||
}
|
||||
for _, att := range processedAtts {
|
||||
if helpers.IsAggregated(att) {
|
||||
aggregatedAtts = append(aggregatedAtts, att)
|
||||
} else {
|
||||
h, err := hashFn(att)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
leftOverUnaggregatedAtt[h] = true
|
||||
if aggregated == nil {
|
||||
return errors.New("could not aggregate unaggregated attestations")
|
||||
}
|
||||
if helpers.IsAggregated(aggregated) {
|
||||
if err := c.SaveAggregatedAttestations([]*ethpb.Attestation{aggregated}); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err := c.SaveAggregatedAttestations(aggregatedAtts); err != nil {
|
||||
return err
|
||||
} else {
|
||||
h, err := hashFn(aggregated)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
leftOverUnaggregatedAtt[h] = true
|
||||
}
|
||||
}
|
||||
|
||||
// Remove the unaggregated attestations from the pool that were successfully aggregated.
|
||||
for _, att := range unaggregatedAtts {
|
||||
h, err := hashFn(att)
|
||||
@@ -87,7 +85,6 @@ func (c *AttCaches) aggregateUnaggregatedAttestations(ctx context.Context, unagg
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -30,6 +30,20 @@ var (
|
||||
Name: "expired_block_atts_total",
|
||||
Help: "The number of expired and deleted block attestations in the pool.",
|
||||
})
|
||||
batchForkChoiceAttsT1 = promauto.NewHistogram(
|
||||
prometheus.HistogramOpts{
|
||||
Name: "aggregate_attestations_t1",
|
||||
Help: "Captures times of attestation aggregation in milliseconds during the first interval per slot",
|
||||
Buckets: []float64{100, 200, 500, 1000, 1500, 2000, 2500, 3500},
|
||||
},
|
||||
)
|
||||
batchForkChoiceAttsT2 = promauto.NewHistogram(
|
||||
prometheus.HistogramOpts{
|
||||
Name: "aggregate_attestations_t2",
|
||||
Help: "Captures times of attestation aggregation in milliseconds during the second interval per slot",
|
||||
Buckets: []float64{10, 40, 100, 200, 600},
|
||||
},
|
||||
)
|
||||
)
|
||||
|
||||
func (s *Service) updateMetrics() {
|
||||
|
||||
@@ -7,6 +7,8 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/prysmaticlabs/go-bitfield"
|
||||
"github.com/prysmaticlabs/prysm/v4/config/features"
|
||||
"github.com/prysmaticlabs/prysm/v4/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v4/crypto/hash"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
|
||||
attaggregation "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1/attestation/aggregation/attestations"
|
||||
@@ -14,20 +16,34 @@ import (
|
||||
"go.opencensus.io/trace"
|
||||
)
|
||||
|
||||
// Prepare attestations for fork choice three times per slot.
|
||||
var prepareForkChoiceAttsPeriod = slots.DivideSlotBy(3 /* times-per-slot */)
|
||||
|
||||
// This prepares fork choice attestations by running batchForkChoiceAtts
|
||||
// every prepareForkChoiceAttsPeriod.
|
||||
func (s *Service) prepareForkChoiceAtts() {
|
||||
ticker := time.NewTicker(prepareForkChoiceAttsPeriod)
|
||||
defer ticker.Stop()
|
||||
intervals := features.Get().AggregateIntervals
|
||||
slotDuration := time.Duration(params.BeaconConfig().SecondsPerSlot) * time.Second
|
||||
// Adjust intervals for networks with a lower slot duration (Hive, e2e, etc)
|
||||
for {
|
||||
if intervals[len(intervals)-1] >= slotDuration {
|
||||
for i, offset := range intervals {
|
||||
intervals[i] = offset / 2
|
||||
}
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
ticker := slots.NewSlotTickerWithIntervals(time.Unix(int64(s.genesisTime), 0), intervals[:])
|
||||
for {
|
||||
select {
|
||||
case <-ticker.C:
|
||||
case <-ticker.C():
|
||||
t := time.Now()
|
||||
if err := s.batchForkChoiceAtts(s.ctx); err != nil {
|
||||
log.WithError(err).Error("Could not prepare attestations for fork choice")
|
||||
}
|
||||
if slots.TimeIntoSlot(s.genesisTime) < intervals[1] {
|
||||
batchForkChoiceAttsT1.Observe(float64(time.Since(t).Milliseconds()))
|
||||
} else if slots.TimeIntoSlot(s.genesisTime) < intervals[2] {
|
||||
batchForkChoiceAttsT2.Observe(float64(time.Since(t).Milliseconds()))
|
||||
}
|
||||
case <-s.ctx.Done():
|
||||
log.Debug("Context closed, exiting routine")
|
||||
return
|
||||
|
||||
@@ -5,6 +5,7 @@ package attestations
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
lru "github.com/hashicorp/golang-lru"
|
||||
@@ -26,8 +27,9 @@ type Service struct {
|
||||
|
||||
// Config options for the service.
|
||||
type Config struct {
|
||||
Pool Pool
|
||||
pruneInterval time.Duration
|
||||
Pool Pool
|
||||
pruneInterval time.Duration
|
||||
InitialSyncComplete chan struct{}
|
||||
}
|
||||
|
||||
// NewService instantiates a new attestation pool service instance that will
|
||||
@@ -51,10 +53,24 @@ func NewService(ctx context.Context, cfg *Config) (*Service, error) {
|
||||
|
||||
// Start an attestation pool service's main event loop.
|
||||
func (s *Service) Start() {
|
||||
if err := s.waitForSync(s.cfg.InitialSyncComplete); err != nil {
|
||||
log.WithError(err).Error("failed to wait for initial sync")
|
||||
return
|
||||
}
|
||||
go s.prepareForkChoiceAtts()
|
||||
go s.pruneAttsPool()
|
||||
}
|
||||
|
||||
// waitForSync waits until the beacon node is synced to the latest head.
|
||||
func (s *Service) waitForSync(syncChan chan struct{}) error {
|
||||
select {
|
||||
case <-syncChan:
|
||||
return nil
|
||||
case <-s.ctx.Done():
|
||||
return errors.New("context closed, exiting goroutine")
|
||||
}
|
||||
}
|
||||
|
||||
// Stop the beacon block attestation pool service's main event loop
|
||||
// and associated goroutines.
|
||||
func (s *Service) Stop() error {
|
||||
|
||||
@@ -30,8 +30,22 @@ func (s *Store) SaveSyncCommitteeMessage(msg *ethpb.SyncCommitteeMessage) error
|
||||
return errors.New("not typed []ethpb.SyncCommitteeMessage")
|
||||
}
|
||||
|
||||
messages = append(messages, copied)
|
||||
savedSyncCommitteeMessageTotal.Inc()
|
||||
idx := -1
|
||||
for i, msg := range messages {
|
||||
if msg.ValidatorIndex == copied.ValidatorIndex {
|
||||
idx = i
|
||||
break
|
||||
}
|
||||
}
|
||||
if idx >= 0 {
|
||||
// Override the existing messages with a new one
|
||||
messages[idx] = copied
|
||||
} else {
|
||||
// Append the new message
|
||||
messages = append(messages, copied)
|
||||
savedSyncCommitteeMessageTotal.Inc()
|
||||
}
|
||||
|
||||
return s.messageCache.Push(&queue.Item{
|
||||
Key: syncCommitteeKey(msg.Slot),
|
||||
Value: messages,
|
||||
|
||||
@@ -55,6 +55,7 @@ go_library(
|
||||
"//beacon-chain/p2p/types:go_default_library",
|
||||
"//beacon-chain/startup:go_default_library",
|
||||
"//cmd/beacon-chain/flags:go_default_library",
|
||||
"//config/features:go_default_library",
|
||||
"//config/params:go_default_library",
|
||||
"//consensus-types/primitives:go_default_library",
|
||||
"//consensus-types/wrapper:go_default_library",
|
||||
|
||||
@@ -6,12 +6,14 @@ import (
|
||||
"net"
|
||||
|
||||
"github.com/libp2p/go-libp2p"
|
||||
"github.com/libp2p/go-libp2p/core/network"
|
||||
"github.com/libp2p/go-libp2p/core/peer"
|
||||
"github.com/libp2p/go-libp2p/p2p/muxer/mplex"
|
||||
"github.com/libp2p/go-libp2p/p2p/security/noise"
|
||||
"github.com/libp2p/go-libp2p/p2p/transport/tcp"
|
||||
ma "github.com/multiformats/go-multiaddr"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/v4/config/features"
|
||||
ecdsaprysm "github.com/prysmaticlabs/prysm/v4/crypto/ecdsa"
|
||||
"github.com/prysmaticlabs/prysm/v4/runtime/version"
|
||||
)
|
||||
@@ -99,6 +101,9 @@ func (s *Service) buildOptions(ip net.IP, priKey *ecdsa.PrivateKey) []libp2p.Opt
|
||||
}
|
||||
// Disable Ping Service.
|
||||
options = append(options, libp2p.Ping(false))
|
||||
if features.Get().DisableResourceManager {
|
||||
options = append(options, libp2p.ResourceManager(&network.NullResourceManager{}))
|
||||
}
|
||||
return options
|
||||
}
|
||||
|
||||
|
||||
@@ -1183,7 +1183,7 @@ func TestServer_SubmitAttestations_InvalidAttestationGRPCHeader(t *testing.T) {
|
||||
require.Equal(t, true, ok, "could not retrieve custom error metadata value")
|
||||
assert.DeepEqual(
|
||||
t,
|
||||
[]string{"{\"failures\":[{\"index\":0,\"message\":\"Incorrect attestation signature: signature must be 96 bytes\"}]}"},
|
||||
[]string{"{\"failures\":[{\"index\":0,\"message\":\"Incorrect attestation signature: could not create signature from byte slice: signature must be 96 bytes\"}]}"},
|
||||
v,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -125,6 +125,14 @@ var (
|
||||
Help: "Time to verify gossiped blocks",
|
||||
},
|
||||
)
|
||||
|
||||
// Sync committee verification performance.
|
||||
syncMessagesForUnknownBlocks = promauto.NewCounter(
|
||||
prometheus.CounterOpts{
|
||||
Name: "sync_committee_messages_unknown_root",
|
||||
Help: "The number of sync committee messages that are checked against DB to see if there vote is for an unknown root",
|
||||
},
|
||||
)
|
||||
)
|
||||
|
||||
func (s *Service) updateMetrics() {
|
||||
|
||||
@@ -90,7 +90,7 @@ func (s *Service) validateSyncCommitteeMessage(
|
||||
ctx,
|
||||
ignoreEmptyCommittee(committeeIndices),
|
||||
s.rejectIncorrectSyncCommittee(committeeIndices, *msg.Topic),
|
||||
s.ignoreHasSeenSyncMsg(m, committeeIndices),
|
||||
s.ignoreHasSeenSyncMsg(ctx, m, committeeIndices),
|
||||
s.rejectInvalidSyncCommitteeSignature(m),
|
||||
); result != pubsub.ValidationAccept {
|
||||
return result, err
|
||||
@@ -123,24 +123,45 @@ func (s *Service) markSyncCommitteeMessagesSeen(committeeIndices []primitives.Co
|
||||
subCommitteeSize := params.BeaconConfig().SyncCommitteeSize / params.BeaconConfig().SyncCommitteeSubnetCount
|
||||
for _, idx := range committeeIndices {
|
||||
subnet := uint64(idx) / subCommitteeSize
|
||||
s.setSeenSyncMessageIndexSlot(m.Slot, m.ValidatorIndex, subnet)
|
||||
s.setSeenSyncMessageIndexSlot(m, subnet)
|
||||
}
|
||||
}
|
||||
|
||||
// Returns true if the node has received sync committee for the validator with index and slot.
|
||||
func (s *Service) hasSeenSyncMessageIndexSlot(slot primitives.Slot, valIndex primitives.ValidatorIndex, subCommitteeIndex uint64) bool {
|
||||
func (s *Service) hasSeenSyncMessageIndexSlot(ctx context.Context, m *ethpb.SyncCommitteeMessage, subCommitteeIndex uint64) bool {
|
||||
s.seenSyncMessageLock.RLock()
|
||||
defer s.seenSyncMessageLock.RUnlock()
|
||||
_, seen := s.seenSyncMessageCache.Get(seenSyncCommitteeKey(slot, valIndex, subCommitteeIndex))
|
||||
return seen
|
||||
rt, seen := s.seenSyncMessageCache.Get(seenSyncCommitteeKey(m.Slot, m.ValidatorIndex, subCommitteeIndex))
|
||||
if !seen {
|
||||
// return early if this is the first message
|
||||
return false
|
||||
}
|
||||
root, ok := rt.([32]byte)
|
||||
if !ok {
|
||||
return true // Impossible. Return true to be safe
|
||||
}
|
||||
if !s.cfg.chain.InForkchoice(root) && !s.cfg.beaconDB.HasBlock(ctx, root) {
|
||||
syncMessagesForUnknownBlocks.Inc()
|
||||
return true
|
||||
}
|
||||
msgRoot := [32]byte(m.BlockRoot)
|
||||
if !s.cfg.chain.InForkchoice(msgRoot) && !s.cfg.beaconDB.HasBlock(ctx, msgRoot) {
|
||||
syncMessagesForUnknownBlocks.Inc()
|
||||
return false
|
||||
}
|
||||
headRoot := s.cfg.chain.CachedHeadRoot()
|
||||
if root == headRoot {
|
||||
return true
|
||||
}
|
||||
return msgRoot != headRoot
|
||||
}
|
||||
|
||||
// Set sync committee message validator index and slot as seen.
|
||||
func (s *Service) setSeenSyncMessageIndexSlot(slot primitives.Slot, valIndex primitives.ValidatorIndex, subCommitteeIndex uint64) {
|
||||
func (s *Service) setSeenSyncMessageIndexSlot(m *ethpb.SyncCommitteeMessage, subCommitteeIndex uint64) {
|
||||
s.seenSyncMessageLock.Lock()
|
||||
defer s.seenSyncMessageLock.Unlock()
|
||||
key := seenSyncCommitteeKey(slot, valIndex, subCommitteeIndex)
|
||||
s.seenSyncMessageCache.Add(key, true)
|
||||
key := seenSyncCommitteeKey(m.Slot, m.ValidatorIndex, subCommitteeIndex)
|
||||
s.seenSyncMessageCache.Add(key, [32]byte(m.BlockRoot))
|
||||
}
|
||||
|
||||
// The `subnet_id` is valid for the given validator. This implies the validator is part of the broader
|
||||
@@ -184,7 +205,7 @@ func (s *Service) rejectIncorrectSyncCommittee(
|
||||
// There has been no other valid sync committee signature for the declared `slot`, `validator_index`,
|
||||
// and `subcommittee_index`. In the event of `validator_index` belongs to multiple subnets, as long
|
||||
// as one subnet has not been seen, we should let it in.
|
||||
func (s *Service) ignoreHasSeenSyncMsg(
|
||||
func (s *Service) ignoreHasSeenSyncMsg(ctx context.Context,
|
||||
m *ethpb.SyncCommitteeMessage, committeeIndices []primitives.CommitteeIndex,
|
||||
) validationFn {
|
||||
return func(ctx context.Context) (pubsub.ValidationResult, error) {
|
||||
@@ -192,7 +213,7 @@ func (s *Service) ignoreHasSeenSyncMsg(
|
||||
subCommitteeSize := params.BeaconConfig().SyncCommitteeSize / params.BeaconConfig().SyncCommitteeSubnetCount
|
||||
for _, idx := range committeeIndices {
|
||||
subnet := uint64(idx) / subCommitteeSize
|
||||
if !s.hasSeenSyncMessageIndexSlot(m.Slot, m.ValidatorIndex, subnet) {
|
||||
if !s.hasSeenSyncMessageIndexSlot(ctx, m, subnet) {
|
||||
isValid = true
|
||||
break
|
||||
}
|
||||
|
||||
@@ -144,8 +144,12 @@ func TestService_ValidateSyncCommitteeMessage(t *testing.T) {
|
||||
s.cfg.stateGen = stategen.New(beaconDB, doublylinkedtree.New())
|
||||
s.cfg.beaconDB = beaconDB
|
||||
s.initCaches()
|
||||
|
||||
s.setSeenSyncMessageIndexSlot(1, 1, 0)
|
||||
m := ðpb.SyncCommitteeMessage{
|
||||
Slot: 1,
|
||||
ValidatorIndex: 1,
|
||||
BlockRoot: params.BeaconConfig().ZeroHash[:],
|
||||
}
|
||||
s.setSeenSyncMessageIndexSlot(m, 0)
|
||||
return s, topic, startup.NewClock(time.Now(), [32]byte{})
|
||||
},
|
||||
args: args{
|
||||
@@ -441,10 +445,15 @@ func TestService_ignoreHasSeenSyncMsg(t *testing.T) {
|
||||
name: "has seen",
|
||||
setupSvc: func(s *Service, msg *ethpb.SyncCommitteeMessage, topic string) (*Service, string) {
|
||||
s.initCaches()
|
||||
s.setSeenSyncMessageIndexSlot(1, 0, 0)
|
||||
m := ðpb.SyncCommitteeMessage{
|
||||
Slot: 1,
|
||||
BlockRoot: params.BeaconConfig().ZeroHash[:],
|
||||
}
|
||||
s.setSeenSyncMessageIndexSlot(m, 0)
|
||||
return s, ""
|
||||
},
|
||||
msg: ðpb.SyncCommitteeMessage{ValidatorIndex: 0, Slot: 1},
|
||||
msg: ðpb.SyncCommitteeMessage{ValidatorIndex: 0, Slot: 1,
|
||||
BlockRoot: params.BeaconConfig().ZeroHash[:]},
|
||||
committee: []primitives.CommitteeIndex{1, 2, 3},
|
||||
want: pubsub.ValidationIgnore,
|
||||
},
|
||||
@@ -452,19 +461,26 @@ func TestService_ignoreHasSeenSyncMsg(t *testing.T) {
|
||||
name: "has not seen",
|
||||
setupSvc: func(s *Service, msg *ethpb.SyncCommitteeMessage, topic string) (*Service, string) {
|
||||
s.initCaches()
|
||||
s.setSeenSyncMessageIndexSlot(1, 0, 0)
|
||||
m := ðpb.SyncCommitteeMessage{
|
||||
Slot: 1,
|
||||
BlockRoot: params.BeaconConfig().ZeroHash[:],
|
||||
}
|
||||
s.setSeenSyncMessageIndexSlot(m, 0)
|
||||
return s, ""
|
||||
},
|
||||
msg: ðpb.SyncCommitteeMessage{ValidatorIndex: 1, Slot: 1},
|
||||
msg: ðpb.SyncCommitteeMessage{ValidatorIndex: 1, Slot: 1,
|
||||
BlockRoot: bytesutil.PadTo([]byte{'A'}, 32)},
|
||||
committee: []primitives.CommitteeIndex{1, 2, 3},
|
||||
want: pubsub.ValidationAccept,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
s := &Service{}
|
||||
s := &Service{
|
||||
cfg: &config{chain: &mockChain.ChainService{}},
|
||||
}
|
||||
s, _ = tt.setupSvc(s, tt.msg, "")
|
||||
f := s.ignoreHasSeenSyncMsg(tt.msg, tt.committee)
|
||||
f := s.ignoreHasSeenSyncMsg(context.Background(), tt.msg, tt.committee)
|
||||
result, err := f(context.Background())
|
||||
_ = err
|
||||
require.Equal(t, tt.want, result)
|
||||
|
||||
@@ -60,6 +60,7 @@ type Flags struct {
|
||||
SaveFullExecutionPayloads bool // Save full beacon blocks with execution payloads in the database.
|
||||
EnableStartOptimistic bool // EnableStartOptimistic treats every block as optimistic at startup.
|
||||
|
||||
DisableResourceManager bool // Disables running the node with libp2p's resource manager.
|
||||
DisableStakinContractCheck bool // Disables check for deposit contract when proposing blocks
|
||||
|
||||
EnableVerboseSigVerification bool // EnableVerboseSigVerification specifies whether to verify individual signature if batch verification fails
|
||||
@@ -72,6 +73,9 @@ type Flags struct {
|
||||
// KeystoreImportDebounceInterval specifies the time duration the validator waits to reload new keys if they have
|
||||
// changed on disk. This feature is for advanced use cases only.
|
||||
KeystoreImportDebounceInterval time.Duration
|
||||
|
||||
// AggregateIntervals specifies the time durations at which we aggregate attestations preparing for forkchoice.
|
||||
AggregateIntervals [3]time.Duration
|
||||
}
|
||||
|
||||
var featureConfig *Flags
|
||||
@@ -214,10 +218,16 @@ func ConfigureBeaconChain(ctx *cli.Context) error {
|
||||
logEnabled(prepareAllPayloads)
|
||||
cfg.PrepareAllPayloads = true
|
||||
}
|
||||
if ctx.IsSet(buildBlockParallel.Name) {
|
||||
logEnabled(buildBlockParallel)
|
||||
cfg.BuildBlockParallel = true
|
||||
cfg.BuildBlockParallel = true
|
||||
if ctx.IsSet(disableBuildBlockParallel.Name) {
|
||||
logEnabled(disableBuildBlockParallel)
|
||||
cfg.BuildBlockParallel = false
|
||||
}
|
||||
if ctx.IsSet(disableResourceManager.Name) {
|
||||
logEnabled(disableResourceManager)
|
||||
cfg.DisableResourceManager = true
|
||||
}
|
||||
cfg.AggregateIntervals = [3]time.Duration{aggregateFirstInterval.Value, aggregateSecondInterval.Value, aggregateThirdInterval.Value}
|
||||
Init(cfg)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -32,6 +32,11 @@ var (
|
||||
Usage: deprecatedUsage,
|
||||
Hidden: true,
|
||||
}
|
||||
deprecatedBuildBlockParallel = &cli.BoolFlag{
|
||||
Name: "build-block-parallel",
|
||||
Usage: deprecatedUsage,
|
||||
Hidden: true,
|
||||
}
|
||||
)
|
||||
|
||||
// Deprecated flags for both the beacon node and validator client.
|
||||
@@ -41,6 +46,7 @@ var deprecatedFlags = []cli.Flag{
|
||||
deprecatedDisableVecHTR,
|
||||
deprecatedEnableReorgLateBlocks,
|
||||
deprecatedDisableGossipBatchAggregation,
|
||||
deprecatedBuildBlockParallel,
|
||||
}
|
||||
|
||||
// deprecatedBeaconFlags contains flags that are still used by other components
|
||||
|
||||
@@ -50,6 +50,24 @@ var (
|
||||
Usage: "(Danger): Writes the wallet password to the wallet directory on completing Prysm web onboarding. " +
|
||||
"We recommend against this flag unless you are an advanced user.",
|
||||
}
|
||||
aggregateFirstInterval = &cli.DurationFlag{
|
||||
Name: "aggregate-first-interval",
|
||||
Usage: "(Advanced): Specifies the first interval in which attestations are aggregated in the slot (typically unnaggregated attestations are aggregated in this interval)",
|
||||
Value: 6500 * time.Millisecond,
|
||||
Hidden: true,
|
||||
}
|
||||
aggregateSecondInterval = &cli.DurationFlag{
|
||||
Name: "aggregate-second-interval",
|
||||
Usage: "(Advanced): Specifies the second interval in which attestations are aggregated in the slot",
|
||||
Value: 9500 * time.Millisecond,
|
||||
Hidden: true,
|
||||
}
|
||||
aggregateThirdInterval = &cli.DurationFlag{
|
||||
Name: "aggregate-third-interval",
|
||||
Usage: "(Advanced): Specifies the third interval in which attestations are aggregated in the slot",
|
||||
Value: 11800 * time.Millisecond,
|
||||
Hidden: true,
|
||||
}
|
||||
dynamicKeyReloadDebounceInterval = &cli.DurationFlag{
|
||||
Name: "dynamic-key-reload-debounce-interval",
|
||||
Usage: "(Advanced): Specifies the time duration the validator waits to reload new keys if they have " +
|
||||
@@ -118,9 +136,13 @@ var (
|
||||
Name: "prepare-all-payloads",
|
||||
Usage: "Informs the engine to prepare all local payloads. Useful for relayers and builders",
|
||||
}
|
||||
buildBlockParallel = &cli.BoolFlag{
|
||||
Name: "build-block-parallel",
|
||||
Usage: "Builds a beacon block in parallel for consensus and execution. It results in faster block construction time",
|
||||
disableBuildBlockParallel = &cli.BoolFlag{
|
||||
Name: "disable-build-block-parallel",
|
||||
Usage: "Disables building a beacon block in parallel for consensus and execution",
|
||||
}
|
||||
disableResourceManager = &cli.BoolFlag{
|
||||
Name: "disable-resource-manager",
|
||||
Usage: "Disables running the libp2p resource manager",
|
||||
}
|
||||
)
|
||||
|
||||
@@ -168,7 +190,11 @@ var BeaconChainFlags = append(deprecatedBeaconFlags, append(deprecatedFlags, []c
|
||||
enableVerboseSigVerification,
|
||||
enableOptionalEngineMethods,
|
||||
prepareAllPayloads,
|
||||
buildBlockParallel,
|
||||
disableBuildBlockParallel,
|
||||
aggregateFirstInterval,
|
||||
aggregateSecondInterval,
|
||||
aggregateThirdInterval,
|
||||
disableResourceManager,
|
||||
}...)...)
|
||||
|
||||
// E2EBeaconChainFlags contains a list of the beacon chain feature flags to be tested in E2E.
|
||||
|
||||
@@ -1,12 +1,32 @@
|
||||
load("@prysm//tools/go:def.bzl", "go_library")
|
||||
load("@prysm//tools/go:def.bzl", "go_library", "go_test")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["proposer-settings.go"],
|
||||
srcs = ["proposer_settings.go"],
|
||||
importpath = "github.com/prysmaticlabs/prysm/v4/config/validator/service",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//config/fieldparams:go_default_library",
|
||||
"//consensus-types/validator:go_default_library",
|
||||
"//encoding/bytesutil:go_default_library",
|
||||
"//proto/prysm/v1alpha1/validator-client:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//common:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//common/hexutil:go_default_library",
|
||||
"@com_github_pkg_errors//:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["proposer_settings_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//config/fieldparams:go_default_library",
|
||||
"//config/params:go_default_library",
|
||||
"//consensus-types/validator:go_default_library",
|
||||
"//encoding/bytesutil:go_default_library",
|
||||
"//testing/require:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//common:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//common/hexutil:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -1,79 +0,0 @@
|
||||
package validator_service_config
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
fieldparams "github.com/prysmaticlabs/prysm/v4/config/fieldparams"
|
||||
)
|
||||
|
||||
// ProposerSettingsPayload is the struct representation of the JSON or YAML payload set in the validator through the CLI.
|
||||
// ProposerConfig is the map of validator address to fee recipient options all in hex format.
|
||||
// DefaultConfig is the default fee recipient address for all validators unless otherwise specified in the propose config.required.
|
||||
type ProposerSettingsPayload struct {
|
||||
ProposerConfig map[string]*ProposerOptionPayload `json:"proposer_config" yaml:"proposer_config"`
|
||||
DefaultConfig *ProposerOptionPayload `json:"default_config" yaml:"default_config"`
|
||||
}
|
||||
|
||||
// ProposerOptionPayload is the struct representation of the JSON config file set in the validator through the CLI.
|
||||
// FeeRecipient is set to an eth address in hex string format with 0x prefix.
|
||||
type ProposerOptionPayload struct {
|
||||
FeeRecipient string `json:"fee_recipient" yaml:"fee_recipient"`
|
||||
BuilderConfig *BuilderConfig `json:"builder" yaml:"builder"`
|
||||
}
|
||||
|
||||
// BuilderConfig is the struct representation of the JSON config file set in the validator through the CLI.
|
||||
// GasLimit is a number set to help the network decide on the maximum gas in each block.
|
||||
type BuilderConfig struct {
|
||||
Enabled bool `json:"enabled" yaml:"enabled"`
|
||||
GasLimit Uint64 `json:"gas_limit,omitempty" yaml:"gas_limit,omitempty"`
|
||||
Relays []string `json:"relays" yaml:"relays"`
|
||||
}
|
||||
|
||||
type Uint64 uint64
|
||||
|
||||
func (u *Uint64) UnmarshalJSON(bs []byte) error {
|
||||
str := string(bs) // Parse plain numbers directly.
|
||||
if bs[0] == '"' && bs[len(bs)-1] == '"' {
|
||||
// Unwrap the quotes from string numbers.
|
||||
str = string(bs[1 : len(bs)-1])
|
||||
}
|
||||
x, err := strconv.ParseUint(str, 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*u = Uint64(x)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u *Uint64) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
||||
var str string
|
||||
err := unmarshal(&str)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
x, err := strconv.ParseUint(str, 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*u = Uint64(x)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ProposerSettings is a Prysm internal representation of the fee recipient config on the validator client.
|
||||
// ProposerSettingsPayload maps to ProposerSettings on import through the CLI.
|
||||
type ProposerSettings struct {
|
||||
ProposeConfig map[[fieldparams.BLSPubkeyLength]byte]*ProposerOption
|
||||
DefaultConfig *ProposerOption
|
||||
}
|
||||
|
||||
type FeeRecipientConfig struct {
|
||||
FeeRecipient common.Address
|
||||
}
|
||||
|
||||
// ProposerOption is a Prysm internal representation of the ProposerOptionPayload on the validator client in bytes format instead of hex.
|
||||
type ProposerOption struct {
|
||||
FeeRecipientConfig *FeeRecipientConfig
|
||||
BuilderConfig *BuilderConfig
|
||||
}
|
||||
206
config/validator/service/proposer_settings.go
Normal file
206
config/validator/service/proposer_settings.go
Normal file
@@ -0,0 +1,206 @@
|
||||
package validator_service_config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/pkg/errors"
|
||||
fieldparams "github.com/prysmaticlabs/prysm/v4/config/fieldparams"
|
||||
"github.com/prysmaticlabs/prysm/v4/consensus-types/validator"
|
||||
"github.com/prysmaticlabs/prysm/v4/encoding/bytesutil"
|
||||
validatorpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1/validator-client"
|
||||
)
|
||||
|
||||
// ToSettings converts struct to ProposerSettings
|
||||
func ToSettings(ps *validatorpb.ProposerSettingsPayload) (*ProposerSettings, error) {
|
||||
settings := &ProposerSettings{}
|
||||
if ps.ProposerConfig != nil {
|
||||
settings.ProposeConfig = make(map[[fieldparams.BLSPubkeyLength]byte]*ProposerOption)
|
||||
for key, optionPayload := range ps.ProposerConfig {
|
||||
if optionPayload.FeeRecipient == "" {
|
||||
continue
|
||||
}
|
||||
b, err := hexutil.Decode(key)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, fmt.Sprintf("cannot decode public key %s", key))
|
||||
}
|
||||
p := &ProposerOption{
|
||||
FeeRecipientConfig: &FeeRecipientConfig{
|
||||
FeeRecipient: common.HexToAddress(optionPayload.FeeRecipient),
|
||||
},
|
||||
}
|
||||
if optionPayload.Builder != nil {
|
||||
p.BuilderConfig = ToBuilderConfig(optionPayload.Builder)
|
||||
}
|
||||
settings.ProposeConfig[bytesutil.ToBytes48(b)] = p
|
||||
}
|
||||
}
|
||||
if ps.DefaultConfig != nil {
|
||||
d := &ProposerOption{}
|
||||
if ps.DefaultConfig.FeeRecipient != "" {
|
||||
d.FeeRecipientConfig = &FeeRecipientConfig{
|
||||
FeeRecipient: common.HexToAddress(ps.DefaultConfig.FeeRecipient),
|
||||
}
|
||||
}
|
||||
if ps.DefaultConfig.Builder != nil {
|
||||
d.BuilderConfig = ToBuilderConfig(ps.DefaultConfig.Builder)
|
||||
}
|
||||
settings.DefaultConfig = d
|
||||
}
|
||||
return settings, nil
|
||||
}
|
||||
|
||||
// BuilderConfig is the struct representation of the JSON config file set in the validator through the CLI.
|
||||
// GasLimit is a number set to help the network decide on the maximum gas in each block.
|
||||
type BuilderConfig struct {
|
||||
Enabled bool `json:"enabled" yaml:"enabled"`
|
||||
GasLimit validator.Uint64 `json:"gas_limit,omitempty" yaml:"gas_limit,omitempty"`
|
||||
Relays []string `json:"relays,omitempty" yaml:"relays,omitempty"`
|
||||
}
|
||||
|
||||
// ToBuilderConfig converts protobuf to a builder config used in inmemory storage
|
||||
func ToBuilderConfig(from *validatorpb.BuilderConfig) *BuilderConfig {
|
||||
if from == nil {
|
||||
return nil
|
||||
}
|
||||
config := &BuilderConfig{
|
||||
Enabled: from.Enabled,
|
||||
GasLimit: from.GasLimit,
|
||||
}
|
||||
if from.Relays != nil {
|
||||
relays := make([]string, len(from.Relays))
|
||||
copy(relays, from.Relays)
|
||||
config.Relays = relays
|
||||
}
|
||||
|
||||
return config
|
||||
}
|
||||
|
||||
// ProposerSettings is a Prysm internal representation of the fee recipient config on the validator client.
|
||||
// validatorpb.ProposerSettingsPayload maps to ProposerSettings on import through the CLI.
|
||||
type ProposerSettings struct {
|
||||
ProposeConfig map[[fieldparams.BLSPubkeyLength]byte]*ProposerOption
|
||||
DefaultConfig *ProposerOption
|
||||
}
|
||||
|
||||
// ToPayload converts struct to ProposerSettingsPayload
|
||||
func (ps *ProposerSettings) ToPayload() *validatorpb.ProposerSettingsPayload {
|
||||
if ps == nil {
|
||||
return nil
|
||||
}
|
||||
payload := &validatorpb.ProposerSettingsPayload{}
|
||||
if ps.ProposeConfig != nil {
|
||||
payload.ProposerConfig = make(map[string]*validatorpb.ProposerOptionPayload)
|
||||
for key, option := range ps.ProposeConfig {
|
||||
p := &validatorpb.ProposerOptionPayload{}
|
||||
if option.FeeRecipientConfig != nil {
|
||||
p.FeeRecipient = option.FeeRecipientConfig.FeeRecipient.Hex()
|
||||
}
|
||||
if option.BuilderConfig != nil {
|
||||
p.Builder = option.BuilderConfig.ToPayload()
|
||||
}
|
||||
payload.ProposerConfig[hexutil.Encode(key[:])] = p
|
||||
}
|
||||
}
|
||||
if ps.DefaultConfig != nil {
|
||||
p := &validatorpb.ProposerOptionPayload{}
|
||||
if ps.DefaultConfig.FeeRecipientConfig != nil {
|
||||
p.FeeRecipient = ps.DefaultConfig.FeeRecipientConfig.FeeRecipient.Hex()
|
||||
}
|
||||
if ps.DefaultConfig.BuilderConfig != nil {
|
||||
p.Builder = ps.DefaultConfig.BuilderConfig.ToPayload()
|
||||
}
|
||||
payload.DefaultConfig = p
|
||||
}
|
||||
return payload
|
||||
}
|
||||
|
||||
// FeeRecipientConfig is a prysm internal representation to see if the fee recipient was set.
|
||||
type FeeRecipientConfig struct {
|
||||
FeeRecipient common.Address
|
||||
}
|
||||
|
||||
// ProposerOption is a Prysm internal representation of the ProposerOptionPayload on the validator client in bytes format instead of hex.
|
||||
type ProposerOption struct {
|
||||
FeeRecipientConfig *FeeRecipientConfig
|
||||
BuilderConfig *BuilderConfig
|
||||
}
|
||||
|
||||
// Clone creates a deep copy of the proposer settings
|
||||
func (ps *ProposerSettings) Clone() *ProposerSettings {
|
||||
if ps == nil {
|
||||
return nil
|
||||
}
|
||||
clone := &ProposerSettings{}
|
||||
if ps.DefaultConfig != nil {
|
||||
clone.DefaultConfig = ps.DefaultConfig.Clone()
|
||||
}
|
||||
if ps.ProposeConfig != nil {
|
||||
clone.ProposeConfig = make(map[[fieldparams.BLSPubkeyLength]byte]*ProposerOption)
|
||||
for k, v := range ps.ProposeConfig {
|
||||
keyCopy := k
|
||||
valCopy := v.Clone()
|
||||
clone.ProposeConfig[keyCopy] = valCopy
|
||||
}
|
||||
}
|
||||
|
||||
return clone
|
||||
}
|
||||
|
||||
// Clone creates a deep copy of fee recipient config
|
||||
func (fo *FeeRecipientConfig) Clone() *FeeRecipientConfig {
|
||||
if fo == nil {
|
||||
return nil
|
||||
}
|
||||
return &FeeRecipientConfig{fo.FeeRecipient}
|
||||
}
|
||||
|
||||
// Clone creates a deep copy of builder config
|
||||
func (bc *BuilderConfig) Clone() *BuilderConfig {
|
||||
if bc == nil {
|
||||
return nil
|
||||
}
|
||||
config := &BuilderConfig{}
|
||||
config.Enabled = bc.Enabled
|
||||
config.GasLimit = bc.GasLimit
|
||||
var relays []string
|
||||
if bc.Relays != nil {
|
||||
relays = make([]string, len(bc.Relays))
|
||||
copy(relays, bc.Relays)
|
||||
config.Relays = relays
|
||||
}
|
||||
return config
|
||||
}
|
||||
|
||||
// ToPayload converts Builder Config to the protobuf object
|
||||
func (bc *BuilderConfig) ToPayload() *validatorpb.BuilderConfig {
|
||||
if bc == nil {
|
||||
return nil
|
||||
}
|
||||
config := &validatorpb.BuilderConfig{}
|
||||
config.Enabled = bc.Enabled
|
||||
var relays []string
|
||||
if bc.Relays != nil {
|
||||
relays = make([]string, len(bc.Relays))
|
||||
copy(relays, bc.Relays)
|
||||
config.Relays = relays
|
||||
}
|
||||
config.GasLimit = bc.GasLimit
|
||||
return config
|
||||
}
|
||||
|
||||
// Clone creates a deep copy of proposer option
|
||||
func (po *ProposerOption) Clone() *ProposerOption {
|
||||
if po == nil {
|
||||
return nil
|
||||
}
|
||||
p := &ProposerOption{}
|
||||
if po.FeeRecipientConfig != nil {
|
||||
p.FeeRecipientConfig = po.FeeRecipientConfig.Clone()
|
||||
}
|
||||
if po.BuilderConfig != nil {
|
||||
p.BuilderConfig = po.BuilderConfig.Clone()
|
||||
}
|
||||
return p
|
||||
}
|
||||
100
config/validator/service/proposer_settings_test.go
Normal file
100
config/validator/service/proposer_settings_test.go
Normal file
@@ -0,0 +1,100 @@
|
||||
package validator_service_config
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
fieldparams "github.com/prysmaticlabs/prysm/v4/config/fieldparams"
|
||||
"github.com/prysmaticlabs/prysm/v4/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v4/consensus-types/validator"
|
||||
"github.com/prysmaticlabs/prysm/v4/encoding/bytesutil"
|
||||
"github.com/prysmaticlabs/prysm/v4/testing/require"
|
||||
)
|
||||
|
||||
func Test_Proposer_Setting_Cloning(t *testing.T) {
|
||||
key1hex := "0xa057816155ad77931185101128655c0191bd0214c201ca48ed887f6c4c6adf334070efcd75140eada5ac83a92506dd7a"
|
||||
key1, err := hexutil.Decode(key1hex)
|
||||
require.NoError(t, err)
|
||||
settings := &ProposerSettings{
|
||||
ProposeConfig: map[[fieldparams.BLSPubkeyLength]byte]*ProposerOption{
|
||||
bytesutil.ToBytes48(key1): {
|
||||
FeeRecipientConfig: &FeeRecipientConfig{
|
||||
FeeRecipient: common.HexToAddress("0x50155530FCE8a85ec7055A5F8b2bE214B3DaeFd3"),
|
||||
},
|
||||
BuilderConfig: &BuilderConfig{
|
||||
Enabled: true,
|
||||
GasLimit: validator.Uint64(40000000),
|
||||
Relays: []string{"https://example-relay.com"},
|
||||
},
|
||||
},
|
||||
},
|
||||
DefaultConfig: &ProposerOption{
|
||||
FeeRecipientConfig: &FeeRecipientConfig{
|
||||
FeeRecipient: common.HexToAddress("0x6e35733c5af9B61374A128e6F85f553aF09ff89A"),
|
||||
},
|
||||
BuilderConfig: &BuilderConfig{
|
||||
Enabled: false,
|
||||
GasLimit: validator.Uint64(params.BeaconConfig().DefaultBuilderGasLimit),
|
||||
Relays: []string{"https://example-relay.com"},
|
||||
},
|
||||
},
|
||||
}
|
||||
t.Run("Happy Path Cloning", func(t *testing.T) {
|
||||
clone := settings.Clone()
|
||||
require.DeepEqual(t, settings, clone)
|
||||
option, ok := settings.ProposeConfig[bytesutil.ToBytes48(key1)]
|
||||
require.Equal(t, true, ok)
|
||||
newFeeRecipient := "0x44455530FCE8a85ec7055A5F8b2bE214B3DaeFd3"
|
||||
option.FeeRecipientConfig.FeeRecipient = common.HexToAddress(newFeeRecipient)
|
||||
coption, k := clone.ProposeConfig[bytesutil.ToBytes48(key1)]
|
||||
require.Equal(t, true, k)
|
||||
require.NotEqual(t, option.FeeRecipientConfig.FeeRecipient.Hex(), coption.FeeRecipientConfig.FeeRecipient.Hex())
|
||||
require.Equal(t, "0x50155530FCE8a85ec7055A5F8b2bE214B3DaeFd3", coption.FeeRecipientConfig.FeeRecipient.Hex())
|
||||
})
|
||||
t.Run("Happy Path Cloning Builder config", func(t *testing.T) {
|
||||
clone := settings.DefaultConfig.BuilderConfig.Clone()
|
||||
require.DeepEqual(t, settings.DefaultConfig.BuilderConfig, clone)
|
||||
settings.DefaultConfig.BuilderConfig.GasLimit = 1
|
||||
require.NotEqual(t, settings.DefaultConfig.BuilderConfig.GasLimit, clone.GasLimit)
|
||||
})
|
||||
|
||||
t.Run("Happy Path ToBuilderConfig", func(t *testing.T) {
|
||||
clone := settings.DefaultConfig.BuilderConfig.Clone()
|
||||
config := ToBuilderConfig(clone.ToPayload())
|
||||
require.DeepEqual(t, config.Relays, clone.Relays)
|
||||
require.Equal(t, config.Enabled, clone.Enabled)
|
||||
require.Equal(t, config.GasLimit, clone.GasLimit)
|
||||
})
|
||||
t.Run("To Payload and ToSettings", func(t *testing.T) {
|
||||
payload := settings.ToPayload()
|
||||
option, ok := settings.ProposeConfig[bytesutil.ToBytes48(key1)]
|
||||
require.Equal(t, true, ok)
|
||||
fee := option.FeeRecipientConfig.FeeRecipient.Hex()
|
||||
potion, pok := payload.ProposerConfig[key1hex]
|
||||
require.Equal(t, true, pok)
|
||||
require.Equal(t, option.FeeRecipientConfig.FeeRecipient.Hex(), potion.FeeRecipient)
|
||||
require.Equal(t, settings.DefaultConfig.FeeRecipientConfig.FeeRecipient.Hex(), payload.DefaultConfig.FeeRecipient)
|
||||
require.Equal(t, settings.DefaultConfig.BuilderConfig.Enabled, payload.DefaultConfig.Builder.Enabled)
|
||||
potion.FeeRecipient = ""
|
||||
newSettings, err := ToSettings(payload)
|
||||
require.NoError(t, err)
|
||||
|
||||
// when converting to settings if a fee recipient is empty string then it will be skipped
|
||||
noption, ok := newSettings.ProposeConfig[bytesutil.ToBytes48(key1)]
|
||||
require.Equal(t, false, ok)
|
||||
require.Equal(t, true, noption == nil)
|
||||
require.DeepEqual(t, newSettings.DefaultConfig, settings.DefaultConfig)
|
||||
|
||||
// if fee recipient is set it will not skip
|
||||
potion.FeeRecipient = fee
|
||||
newSettings, err = ToSettings(payload)
|
||||
require.NoError(t, err)
|
||||
noption, ok = newSettings.ProposeConfig[bytesutil.ToBytes48(key1)]
|
||||
require.Equal(t, true, ok)
|
||||
require.Equal(t, option.FeeRecipientConfig.FeeRecipient.Hex(), noption.FeeRecipientConfig.FeeRecipient.Hex())
|
||||
require.Equal(t, option.BuilderConfig.GasLimit, option.BuilderConfig.GasLimit)
|
||||
require.Equal(t, option.BuilderConfig.Enabled, option.BuilderConfig.Enabled)
|
||||
|
||||
})
|
||||
}
|
||||
18
consensus-types/validator/BUILD.bazel
Normal file
18
consensus-types/validator/BUILD.bazel
Normal file
@@ -0,0 +1,18 @@
|
||||
load("@prysm//tools/go:def.bzl", "go_library", "go_test")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["custom_types.go"],
|
||||
importpath = "github.com/prysmaticlabs/prysm/v4/consensus-types/validator",
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["custom_types_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//testing/require:go_default_library",
|
||||
"@io_k8s_apimachinery//pkg/util/yaml:go_default_library",
|
||||
],
|
||||
)
|
||||
41
consensus-types/validator/custom_types.go
Normal file
41
consensus-types/validator/custom_types.go
Normal file
@@ -0,0 +1,41 @@
|
||||
package validator
|
||||
|
||||
import "strconv"
|
||||
|
||||
// Uint64 custom uint64 to be unmarshallable
|
||||
type Uint64 uint64
|
||||
|
||||
// UnmarshalJSON custom unmarshal function for json
|
||||
func (u *Uint64) UnmarshalJSON(bs []byte) error {
|
||||
str := string(bs) // Parse plain numbers directly.
|
||||
if str == "" {
|
||||
*u = Uint64(0)
|
||||
return nil
|
||||
}
|
||||
if len(bs) >= 3 && bs[0] == '"' && bs[len(bs)-1] == '"' {
|
||||
// Unwrap the quotes from string numbers.
|
||||
str = string(bs[1 : len(bs)-1])
|
||||
}
|
||||
x, err := strconv.ParseUint(str, 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*u = Uint64(x)
|
||||
return nil
|
||||
}
|
||||
|
||||
// UnmarshalYAML custom unmarshal function for yaml
|
||||
func (u *Uint64) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
||||
var str string
|
||||
err := unmarshal(&str)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
x, err := strconv.ParseUint(str, 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*u = Uint64(x)
|
||||
|
||||
return nil
|
||||
}
|
||||
58
consensus-types/validator/custom_types_test.go
Normal file
58
consensus-types/validator/custom_types_test.go
Normal file
@@ -0,0 +1,58 @@
|
||||
package validator
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/prysmaticlabs/prysm/v4/testing/require"
|
||||
"k8s.io/apimachinery/pkg/util/yaml"
|
||||
)
|
||||
|
||||
func Test_customUint_UnmarshalJSON(t *testing.T) {
|
||||
type Custom struct {
|
||||
Test Uint64 `json:"test"`
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
jsonString string
|
||||
number uint64
|
||||
wantUnmarshalErr string
|
||||
}{
|
||||
{
|
||||
name: "Happy Path string",
|
||||
jsonString: `{"test": "123441"}`,
|
||||
number: 123441,
|
||||
},
|
||||
{
|
||||
name: "Happy Path number",
|
||||
jsonString: `{"test": 123441}`,
|
||||
number: 123441,
|
||||
},
|
||||
{
|
||||
name: "empty",
|
||||
jsonString: `{"test":""}`,
|
||||
wantUnmarshalErr: "error unmarshaling JSON",
|
||||
},
|
||||
{
|
||||
name: "digits more than uint64",
|
||||
jsonString: `{"test":"8888888888888888888888888888888888888888888888888888888888888"}`,
|
||||
wantUnmarshalErr: "error unmarshaling JSON",
|
||||
},
|
||||
{
|
||||
name: "not a uint64",
|
||||
jsonString: `{"test":"one hundred"}`,
|
||||
wantUnmarshalErr: "error unmarshaling JSON",
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
var to Custom
|
||||
err := yaml.Unmarshal([]byte(tt.jsonString), &to)
|
||||
if tt.wantUnmarshalErr != "" {
|
||||
require.ErrorContains(t, tt.wantUnmarshalErr, err)
|
||||
} else {
|
||||
require.NoError(t, err)
|
||||
}
|
||||
require.Equal(t, tt.number, uint64(to.Test))
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -24,6 +24,13 @@ func PublicKeyFromBytes(pubKey []byte) (PublicKey, error) {
|
||||
return blst.PublicKeyFromBytes(pubKey)
|
||||
}
|
||||
|
||||
// SignatureFromBytesNoValidation creates a BLS signature from a LittleEndian byte slice.
|
||||
// It does not check validity of the signature, use only when the byte slice has
|
||||
// already been verified
|
||||
func SignatureFromBytesNoValidation(sig []byte) (Signature, error) {
|
||||
return blst.SignatureFromBytesNoValidation(sig)
|
||||
}
|
||||
|
||||
// SignatureFromBytes creates a BLS signature from a LittleEndian byte slice.
|
||||
func SignatureFromBytes(sig []byte) (Signature, error) {
|
||||
return blst.SignatureFromBytes(sig)
|
||||
|
||||
@@ -24,8 +24,9 @@ type Signature struct {
|
||||
s *blstSignature
|
||||
}
|
||||
|
||||
// SignatureFromBytes creates a BLS signature from a LittleEndian byte slice.
|
||||
func SignatureFromBytes(sig []byte) (common.Signature, error) {
|
||||
// signatureFromBytesNoValidation creates a BLS signature from a LittleEndian
|
||||
// byte slice. It does not validate that the signature is in the BLS group
|
||||
func signatureFromBytesNoValidation(sig []byte) (*blstSignature, error) {
|
||||
if len(sig) != fieldparams.BLSSignatureLength {
|
||||
return nil, fmt.Errorf("signature must be %d bytes", fieldparams.BLSSignatureLength)
|
||||
}
|
||||
@@ -33,6 +34,25 @@ func SignatureFromBytes(sig []byte) (common.Signature, error) {
|
||||
if signature == nil {
|
||||
return nil, errors.New("could not unmarshal bytes into signature")
|
||||
}
|
||||
return signature, nil
|
||||
}
|
||||
|
||||
// SignatureFromBytesNoValidation creates a BLS signature from a LittleEndian
|
||||
// byte slice. It does not validate that the signature is in the BLS group
|
||||
func SignatureFromBytesNoValidation(sig []byte) (common.Signature, error) {
|
||||
signature, err := signatureFromBytesNoValidation(sig)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not create signature from byte slice")
|
||||
}
|
||||
return &Signature{s: signature}, nil
|
||||
}
|
||||
|
||||
// SignatureFromBytes creates a BLS signature from a LittleEndian byte slice.
|
||||
func SignatureFromBytes(sig []byte) (common.Signature, error) {
|
||||
signature, err := signatureFromBytesNoValidation(sig)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not create signature from byte slice")
|
||||
}
|
||||
// Group check signature. Do not check for infinity since an aggregated signature
|
||||
// could be infinite.
|
||||
if !signature.SigValidate(false) {
|
||||
|
||||
@@ -207,6 +207,11 @@ func TestSignatureFromBytes(t *testing.T) {
|
||||
input: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
err: errors.New("could not unmarshal bytes into signature"),
|
||||
},
|
||||
{
|
||||
input: []byte{0xac, 0xb0, 0x12, 0x4c, 0x75, 0x74, 0xf2, 0x81, 0xa2, 0x93, 0xf4, 0x18, 0x5c, 0xad, 0x3c, 0xb2, 0x26, 0x81, 0xd5, 0x20, 0x91, 0x7c, 0xe4, 0x66, 0x65, 0x24, 0x3e, 0xac, 0xb0, 0x51, 0x00, 0x0d, 0x8b, 0xac, 0xf7, 0x5e, 0x14, 0x51, 0x87, 0x0c, 0xa6, 0xb3, 0xb9, 0xe6, 0xc9, 0xd4, 0x1a, 0x7b, 0x02, 0xea, 0xd2, 0x68, 0x5a, 0x84, 0x18, 0x8a, 0x4f, 0xaf, 0xd3, 0x82, 0x5d, 0xaf, 0x6a, 0x98, 0x96, 0x25, 0xd7, 0x19, 0xcc, 0xd2, 0xd8, 0x3a, 0x40, 0x10, 0x1f, 0x4a, 0x45, 0x3f, 0xca, 0x62, 0x87, 0x8c, 0x89, 0x0e, 0xca, 0x62, 0x23, 0x63, 0xf9, 0xdd, 0xb8, 0xf3, 0x67, 0xa9, 0x1e, 0x84},
|
||||
name: "Not in group",
|
||||
err: errors.New("signature not in group"),
|
||||
},
|
||||
{
|
||||
name: "Good",
|
||||
input: []byte{0xab, 0xb0, 0x12, 0x4c, 0x75, 0x74, 0xf2, 0x81, 0xa2, 0x93, 0xf4, 0x18, 0x5c, 0xad, 0x3c, 0xb2, 0x26, 0x81, 0xd5, 0x20, 0x91, 0x7c, 0xe4, 0x66, 0x65, 0x24, 0x3e, 0xac, 0xb0, 0x51, 0x00, 0x0d, 0x8b, 0xac, 0xf7, 0x5e, 0x14, 0x51, 0x87, 0x0c, 0xa6, 0xb3, 0xb9, 0xe6, 0xc9, 0xd4, 0x1a, 0x7b, 0x02, 0xea, 0xd2, 0x68, 0x5a, 0x84, 0x18, 0x8a, 0x4f, 0xaf, 0xd3, 0x82, 0x5d, 0xaf, 0x6a, 0x98, 0x96, 0x25, 0xd7, 0x19, 0xcc, 0xd2, 0xd8, 0x3a, 0x40, 0x10, 0x1f, 0x4a, 0x45, 0x3f, 0xca, 0x62, 0x87, 0x8c, 0x89, 0x0e, 0xca, 0x62, 0x23, 0x63, 0xf9, 0xdd, 0xb8, 0xf3, 0x67, 0xa9, 0x1e, 0x84},
|
||||
@@ -227,6 +232,60 @@ func TestSignatureFromBytes(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestSignatureFromBytesNoValidation(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
input []byte
|
||||
err error
|
||||
}{
|
||||
{
|
||||
name: "Nil",
|
||||
err: errors.New("signature must be 96 bytes"),
|
||||
},
|
||||
{
|
||||
name: "Empty",
|
||||
input: []byte{},
|
||||
err: errors.New("signature must be 96 bytes"),
|
||||
},
|
||||
{
|
||||
name: "Short",
|
||||
input: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
err: errors.New("signature must be 96 bytes"),
|
||||
},
|
||||
{
|
||||
name: "Long",
|
||||
input: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
err: errors.New("signature must be 96 bytes"),
|
||||
},
|
||||
{
|
||||
name: "Bad",
|
||||
input: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
err: errors.New("could not unmarshal bytes into signature"),
|
||||
},
|
||||
{
|
||||
name: "Not in group",
|
||||
input: []byte{0xac, 0xb0, 0x12, 0x4c, 0x75, 0x74, 0xf2, 0x81, 0xa2, 0x93, 0xf4, 0x18, 0x5c, 0xad, 0x3c, 0xb2, 0x26, 0x81, 0xd5, 0x20, 0x91, 0x7c, 0xe4, 0x66, 0x65, 0x24, 0x3e, 0xac, 0xb0, 0x51, 0x00, 0x0d, 0x8b, 0xac, 0xf7, 0x5e, 0x14, 0x51, 0x87, 0x0c, 0xa6, 0xb3, 0xb9, 0xe6, 0xc9, 0xd4, 0x1a, 0x7b, 0x02, 0xea, 0xd2, 0x68, 0x5a, 0x84, 0x18, 0x8a, 0x4f, 0xaf, 0xd3, 0x82, 0x5d, 0xaf, 0x6a, 0x98, 0x96, 0x25, 0xd7, 0x19, 0xcc, 0xd2, 0xd8, 0x3a, 0x40, 0x10, 0x1f, 0x4a, 0x45, 0x3f, 0xca, 0x62, 0x87, 0x8c, 0x89, 0x0e, 0xca, 0x62, 0x23, 0x63, 0xf9, 0xdd, 0xb8, 0xf3, 0x67, 0xa9, 0x1e, 0x84},
|
||||
},
|
||||
{
|
||||
name: "Good",
|
||||
input: []byte{0xab, 0xb0, 0x12, 0x4c, 0x75, 0x74, 0xf2, 0x81, 0xa2, 0x93, 0xf4, 0x18, 0x5c, 0xad, 0x3c, 0xb2, 0x26, 0x81, 0xd5, 0x20, 0x91, 0x7c, 0xe4, 0x66, 0x65, 0x24, 0x3e, 0xac, 0xb0, 0x51, 0x00, 0x0d, 0x8b, 0xac, 0xf7, 0x5e, 0x14, 0x51, 0x87, 0x0c, 0xa6, 0xb3, 0xb9, 0xe6, 0xc9, 0xd4, 0x1a, 0x7b, 0x02, 0xea, 0xd2, 0x68, 0x5a, 0x84, 0x18, 0x8a, 0x4f, 0xaf, 0xd3, 0x82, 0x5d, 0xaf, 0x6a, 0x98, 0x96, 0x25, 0xd7, 0x19, 0xcc, 0xd2, 0xd8, 0x3a, 0x40, 0x10, 0x1f, 0x4a, 0x45, 0x3f, 0xca, 0x62, 0x87, 0x8c, 0x89, 0x0e, 0xca, 0x62, 0x23, 0x63, 0xf9, 0xdd, 0xb8, 0xf3, 0x67, 0xa9, 0x1e, 0x84},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
res, err := SignatureFromBytesNoValidation(test.input)
|
||||
if test.err != nil {
|
||||
assert.NotEqual(t, nil, err, "No error returned")
|
||||
assert.ErrorContains(t, test.err.Error(), err, "Unexpected error returned")
|
||||
} else {
|
||||
assert.NoError(t, err)
|
||||
assert.DeepEqual(t, 0, bytes.Compare(res.Marshal(), test.input))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestMultipleSignatureFromBytes(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
|
||||
@@ -84,7 +84,7 @@ func TestVerifyVerbosely_VerificationThrowsError(t *testing.T) {
|
||||
valid, err := set.VerifyVerbosely()
|
||||
assert.Equal(t, false, valid, "SignatureSet is expected to be invalid")
|
||||
assert.StringContains(t, "signature 'signature of bad0' is invalid", err.Error())
|
||||
assert.StringContains(t, "error: could not unmarshal bytes into signature", err.Error())
|
||||
assert.StringContains(t, "could not unmarshal bytes into signature", err.Error())
|
||||
assert.StringNotContains(t, "signature 'signature of good0' is invalid", err.Error())
|
||||
}
|
||||
|
||||
|
||||
2
go.mod
2
go.mod
@@ -91,6 +91,7 @@ require (
|
||||
gopkg.in/d4l3k/messagediff.v1 v1.2.1
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
k8s.io/apimachinery v0.20.0
|
||||
k8s.io/client-go v0.20.0
|
||||
)
|
||||
|
||||
@@ -233,7 +234,6 @@ require (
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
|
||||
k8s.io/apimachinery v0.20.0 // indirect
|
||||
lukechampine.com/blake3 v1.1.7 // indirect
|
||||
nhooyr.io/websocket v1.8.7 // indirect
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.0.2 // indirect
|
||||
|
||||
@@ -18,3 +18,7 @@ latest_version_tag=$(./hack/latest_version_tag.sh)
|
||||
echo "STABLE_VERSION_TAG $latest_version_tag"
|
||||
echo "STABLE_COMMIT_SHA $commit_sha"
|
||||
echo "STABLE_GIT_TAG $latest_version_tag"
|
||||
|
||||
echo DOCKER_TAG "$(git rev-parse --abbrev-ref HEAD)-$(git rev-parse --short=6 HEAD)"
|
||||
echo DATE "$(date --rfc-3339=seconds --utc)"
|
||||
echo DATE_UNIX "$(date --utc +%s)"
|
||||
|
||||
@@ -15,7 +15,7 @@ type attList []*ethpb.Attestation
|
||||
// significantly more expensive than the inner logic of AggregateAttestations so they must be
|
||||
// substituted for benchmarks which analyze AggregateAttestations.
|
||||
var aggregateSignatures = bls.AggregateSignatures
|
||||
var signatureFromBytes = bls.SignatureFromBytes
|
||||
var signatureFromBytes = bls.SignatureFromBytesNoValidation
|
||||
|
||||
var _ = logrus.WithField("prefix", "aggregation.attestations")
|
||||
|
||||
@@ -36,6 +36,43 @@ func Aggregate(atts []*ethpb.Attestation) ([]*ethpb.Attestation, error) {
|
||||
return MaxCoverAttestationAggregation(atts)
|
||||
}
|
||||
|
||||
// AggregateDisjointOneBitAtts aggregates unaggregated attestations with the
|
||||
// exact same attestation data.
|
||||
func AggregateDisjointOneBitAtts(atts []*ethpb.Attestation) (*ethpb.Attestation, error) {
|
||||
if len(atts) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
if len(atts) == 1 {
|
||||
return atts[0], nil
|
||||
}
|
||||
coverage, err := atts[0].AggregationBits.ToBitlist64()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not get aggregation bits")
|
||||
}
|
||||
for _, att := range atts[1:] {
|
||||
bits, err := att.AggregationBits.ToBitlist64()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not get aggregation bits")
|
||||
}
|
||||
err = coverage.NoAllocOr(bits, coverage)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not get aggregation bits")
|
||||
}
|
||||
}
|
||||
keys := make([]int, len(atts))
|
||||
for i := 0; i < len(atts); i++ {
|
||||
keys[i] = i
|
||||
}
|
||||
idx, err := aggregateAttestations(atts, keys, coverage)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not aggregate attestations")
|
||||
}
|
||||
if idx != 0 {
|
||||
return nil, errors.New("could not aggregate attestations, obtained non zero index")
|
||||
}
|
||||
return atts[0], nil
|
||||
}
|
||||
|
||||
// AggregatePair aggregates pair of attestations a1 and a2 together.
|
||||
func AggregatePair(a1, a2 *ethpb.Attestation) (*ethpb.Attestation, error) {
|
||||
o, err := a1.AggregationBits.Overlaps(a2.AggregationBits)
|
||||
|
||||
@@ -54,6 +54,7 @@ go_proto_library(
|
||||
"@com_github_grpc_ecosystem_grpc_gateway_v2//protoc-gen-openapiv2/options:options_go_proto",
|
||||
"@com_github_prysmaticlabs_go_bitfield//:go_default_library",
|
||||
"//consensus-types/primitives:go_default_library",
|
||||
"//consensus-types/validator:go_default_library",
|
||||
"@go_googleapis//google/api:annotations_go_proto",
|
||||
"@org_golang_google_protobuf//reflect/protoreflect:go_default_library",
|
||||
"@org_golang_google_protobuf//runtime/protoimpl:go_default_library",
|
||||
|
||||
395
proto/prysm/v1alpha1/validator-client/keymanager.pb.go
generated
395
proto/prysm/v1alpha1/validator-client/keymanager.pb.go
generated
@@ -13,6 +13,7 @@ import (
|
||||
|
||||
empty "github.com/golang/protobuf/ptypes/empty"
|
||||
github_com_prysmaticlabs_prysm_v4_consensus_types_primitives "github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
|
||||
github_com_prysmaticlabs_prysm_v4_consensus_types_validator "github.com/prysmaticlabs/prysm/v4/consensus-types/validator"
|
||||
_ "github.com/prysmaticlabs/prysm/v4/proto/eth/ext"
|
||||
v1alpha1 "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
|
||||
_ "google.golang.org/genproto/googleapis/api/annotations"
|
||||
@@ -479,6 +480,179 @@ func (x *SignResponse) GetStatus() SignResponse_Status {
|
||||
return SignResponse_UNKNOWN
|
||||
}
|
||||
|
||||
type ProposerOptionPayload struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
FeeRecipient string `protobuf:"bytes,1,opt,name=fee_recipient,json=feeRecipient,proto3" json:"fee_recipient,omitempty"`
|
||||
Builder *BuilderConfig `protobuf:"bytes,2,opt,name=builder,proto3" json:"builder,omitempty"`
|
||||
}
|
||||
|
||||
func (x *ProposerOptionPayload) Reset() {
|
||||
*x = ProposerOptionPayload{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_proto_prysm_v1alpha1_validator_client_keymanager_proto_msgTypes[3]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *ProposerOptionPayload) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ProposerOptionPayload) ProtoMessage() {}
|
||||
|
||||
func (x *ProposerOptionPayload) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_proto_prysm_v1alpha1_validator_client_keymanager_proto_msgTypes[3]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use ProposerOptionPayload.ProtoReflect.Descriptor instead.
|
||||
func (*ProposerOptionPayload) Descriptor() ([]byte, []int) {
|
||||
return file_proto_prysm_v1alpha1_validator_client_keymanager_proto_rawDescGZIP(), []int{3}
|
||||
}
|
||||
|
||||
func (x *ProposerOptionPayload) GetFeeRecipient() string {
|
||||
if x != nil {
|
||||
return x.FeeRecipient
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *ProposerOptionPayload) GetBuilder() *BuilderConfig {
|
||||
if x != nil {
|
||||
return x.Builder
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type BuilderConfig struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Enabled bool `protobuf:"varint,1,opt,name=enabled,proto3" json:"enabled,omitempty"`
|
||||
GasLimit github_com_prysmaticlabs_prysm_v4_consensus_types_validator.Uint64 `protobuf:"varint,2,opt,name=gas_limit,json=gasLimit,proto3" json:"gas_limit,omitempty" cast-type:"github.com/prysmaticlabs/prysm/v4/consensus-types/validator.Uint64"`
|
||||
Relays []string `protobuf:"bytes,3,rep,name=relays,proto3" json:"relays,omitempty"`
|
||||
}
|
||||
|
||||
func (x *BuilderConfig) Reset() {
|
||||
*x = BuilderConfig{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_proto_prysm_v1alpha1_validator_client_keymanager_proto_msgTypes[4]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *BuilderConfig) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*BuilderConfig) ProtoMessage() {}
|
||||
|
||||
func (x *BuilderConfig) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_proto_prysm_v1alpha1_validator_client_keymanager_proto_msgTypes[4]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use BuilderConfig.ProtoReflect.Descriptor instead.
|
||||
func (*BuilderConfig) Descriptor() ([]byte, []int) {
|
||||
return file_proto_prysm_v1alpha1_validator_client_keymanager_proto_rawDescGZIP(), []int{4}
|
||||
}
|
||||
|
||||
func (x *BuilderConfig) GetEnabled() bool {
|
||||
if x != nil {
|
||||
return x.Enabled
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (x *BuilderConfig) GetGasLimit() github_com_prysmaticlabs_prysm_v4_consensus_types_validator.Uint64 {
|
||||
if x != nil {
|
||||
return x.GasLimit
|
||||
}
|
||||
return github_com_prysmaticlabs_prysm_v4_consensus_types_validator.Uint64(0)
|
||||
}
|
||||
|
||||
func (x *BuilderConfig) GetRelays() []string {
|
||||
if x != nil {
|
||||
return x.Relays
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type ProposerSettingsPayload struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
ProposerConfig map[string]*ProposerOptionPayload `protobuf:"bytes,1,rep,name=proposer_config,json=proposerConfig,proto3" json:"proposer_config,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
|
||||
DefaultConfig *ProposerOptionPayload `protobuf:"bytes,2,opt,name=default_config,json=defaultConfig,proto3" json:"default_config,omitempty"`
|
||||
}
|
||||
|
||||
func (x *ProposerSettingsPayload) Reset() {
|
||||
*x = ProposerSettingsPayload{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_proto_prysm_v1alpha1_validator_client_keymanager_proto_msgTypes[5]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *ProposerSettingsPayload) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ProposerSettingsPayload) ProtoMessage() {}
|
||||
|
||||
func (x *ProposerSettingsPayload) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_proto_prysm_v1alpha1_validator_client_keymanager_proto_msgTypes[5]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use ProposerSettingsPayload.ProtoReflect.Descriptor instead.
|
||||
func (*ProposerSettingsPayload) Descriptor() ([]byte, []int) {
|
||||
return file_proto_prysm_v1alpha1_validator_client_keymanager_proto_rawDescGZIP(), []int{5}
|
||||
}
|
||||
|
||||
func (x *ProposerSettingsPayload) GetProposerConfig() map[string]*ProposerOptionPayload {
|
||||
if x != nil {
|
||||
return x.ProposerConfig
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *ProposerSettingsPayload) GetDefaultConfig() *ProposerOptionPayload {
|
||||
if x != nil {
|
||||
return x.DefaultConfig
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var File_proto_prysm_v1alpha1_validator_client_keymanager_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_proto_prysm_v1alpha1_validator_client_keymanager_proto_rawDesc = []byte{
|
||||
@@ -620,39 +794,80 @@ var file_proto_prysm_v1alpha1_validator_client_keymanager_proto_rawDesc = []byte
|
||||
0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x53,
|
||||
0x55, 0x43, 0x43, 0x45, 0x45, 0x44, 0x45, 0x44, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x44, 0x45,
|
||||
0x4e, 0x49, 0x45, 0x44, 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44,
|
||||
0x10, 0x03, 0x32, 0xa7, 0x02, 0x0a, 0x0c, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x53, 0x69, 0x67,
|
||||
0x6e, 0x65, 0x72, 0x12, 0x90, 0x01, 0x0a, 0x18, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x61, 0x6c, 0x69,
|
||||
0x64, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x73,
|
||||
0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
|
||||
0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x36, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72,
|
||||
0x65, 0x75, 0x6d, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x61, 0x63,
|
||||
0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x75,
|
||||
0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
|
||||
0x22, 0x24, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1e, 0x12, 0x1c, 0x2f, 0x61, 0x63, 0x63, 0x6f, 0x75,
|
||||
0x6e, 0x74, 0x73, 0x2f, 0x76, 0x32, 0x2f, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x2f, 0x61, 0x63,
|
||||
0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x12, 0x83, 0x01, 0x0a, 0x04, 0x53, 0x69, 0x67, 0x6e, 0x12,
|
||||
0x2b, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64,
|
||||
0x61, 0x74, 0x6f, 0x72, 0x2e, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x32,
|
||||
0x2e, 0x53, 0x69, 0x67, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x65,
|
||||
0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f,
|
||||
0x72, 0x2e, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x69,
|
||||
0x67, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x20, 0x82, 0xd3, 0xe4, 0x93,
|
||||
0x02, 0x1a, 0x22, 0x18, 0x2f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2f, 0x76, 0x32,
|
||||
0x2f, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x2f, 0x73, 0x69, 0x67, 0x6e, 0x42, 0xce, 0x01, 0x0a,
|
||||
0x22, 0x6f, 0x72, 0x67, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x76, 0x61,
|
||||
0x10, 0x03, 0x22, 0x85, 0x01, 0x0a, 0x15, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, 0x72, 0x4f,
|
||||
0x70, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x23, 0x0a, 0x0d,
|
||||
0x66, 0x65, 0x65, 0x5f, 0x72, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x0c, 0x66, 0x65, 0x65, 0x52, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e,
|
||||
0x74, 0x12, 0x47, 0x0a, 0x07, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01,
|
||||
0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x76, 0x61,
|
||||
0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73,
|
||||
0x2e, 0x76, 0x32, 0x42, 0x0f, 0x4b, 0x65, 0x79, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x50,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x53, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63,
|
||||
0x6f, 0x6d, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x6c, 0x61, 0x62, 0x73,
|
||||
0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x34, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f,
|
||||
0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x76,
|
||||
0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2d, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x3b,
|
||||
0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x70, 0x62, 0xaa, 0x02, 0x1e, 0x45, 0x74,
|
||||
0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72,
|
||||
0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2e, 0x56, 0x32, 0xca, 0x02, 0x1e, 0x45,
|
||||
0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x5c, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f,
|
||||
0x72, 0x5c, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x5c, 0x56, 0x32, 0x62, 0x06, 0x70,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
0x2e, 0x76, 0x32, 0x2e, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69,
|
||||
0x67, 0x52, 0x07, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x22, 0xa6, 0x01, 0x0a, 0x0d, 0x42,
|
||||
0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x18, 0x0a, 0x07,
|
||||
0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65,
|
||||
0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x63, 0x0a, 0x09, 0x67, 0x61, 0x73, 0x5f, 0x6c, 0x69,
|
||||
0x6d, 0x69, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x42, 0x46, 0x82, 0xb5, 0x18, 0x42, 0x67,
|
||||
0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x61,
|
||||
0x74, 0x69, 0x63, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x34,
|
||||
0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x73,
|
||||
0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x55, 0x69, 0x6e, 0x74, 0x36,
|
||||
0x34, 0x52, 0x08, 0x67, 0x61, 0x73, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x72,
|
||||
0x65, 0x6c, 0x61, 0x79, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x6c,
|
||||
0x61, 0x79, 0x73, 0x22, 0xe7, 0x02, 0x0a, 0x17, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, 0x72,
|
||||
0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12,
|
||||
0x74, 0x0a, 0x0f, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x6e, 0x66,
|
||||
0x69, 0x67, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x4b, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72,
|
||||
0x65, 0x75, 0x6d, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x61, 0x63,
|
||||
0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x32, 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73,
|
||||
0x65, 0x72, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61,
|
||||
0x64, 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
|
||||
0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0e, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, 0x72, 0x43,
|
||||
0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x5c, 0x0a, 0x0e, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74,
|
||||
0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x35, 0x2e,
|
||||
0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74,
|
||||
0x6f, 0x72, 0x2e, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x32, 0x2e, 0x50,
|
||||
0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, 0x72, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x79,
|
||||
0x6c, 0x6f, 0x61, 0x64, 0x52, 0x0d, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x43, 0x6f, 0x6e,
|
||||
0x66, 0x69, 0x67, 0x1a, 0x78, 0x0a, 0x13, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, 0x72, 0x43,
|
||||
0x6f, 0x6e, 0x66, 0x69, 0x67, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65,
|
||||
0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x4b, 0x0a, 0x05,
|
||||
0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x65, 0x74,
|
||||
0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72,
|
||||
0x2e, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x32, 0x2e, 0x50, 0x72, 0x6f,
|
||||
0x70, 0x6f, 0x73, 0x65, 0x72, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x79, 0x6c, 0x6f,
|
||||
0x61, 0x64, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x32, 0xa7, 0x02,
|
||||
0x0a, 0x0c, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x12, 0x90,
|
||||
0x01, 0x0a, 0x18, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6e,
|
||||
0x67, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x16, 0x2e, 0x67, 0x6f,
|
||||
0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d,
|
||||
0x70, 0x74, 0x79, 0x1a, 0x36, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x76,
|
||||
0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74,
|
||||
0x73, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b,
|
||||
0x65, 0x79, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x24, 0x82, 0xd3, 0xe4,
|
||||
0x93, 0x02, 0x1e, 0x12, 0x1c, 0x2f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2f, 0x76,
|
||||
0x32, 0x2f, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x2f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74,
|
||||
0x73, 0x12, 0x83, 0x01, 0x0a, 0x04, 0x53, 0x69, 0x67, 0x6e, 0x12, 0x2b, 0x2e, 0x65, 0x74, 0x68,
|
||||
0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2e,
|
||||
0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x69, 0x67, 0x6e,
|
||||
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65,
|
||||
0x75, 0x6d, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x61, 0x63, 0x63,
|
||||
0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x52, 0x65, 0x73,
|
||||
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x20, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1a, 0x22, 0x18, 0x2f,
|
||||
0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2f, 0x76, 0x32, 0x2f, 0x72, 0x65, 0x6d, 0x6f,
|
||||
0x74, 0x65, 0x2f, 0x73, 0x69, 0x67, 0x6e, 0x42, 0xce, 0x01, 0x0a, 0x22, 0x6f, 0x72, 0x67, 0x2e,
|
||||
0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74,
|
||||
0x6f, 0x72, 0x2e, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x32, 0x42, 0x0f,
|
||||
0x4b, 0x65, 0x79, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50,
|
||||
0x01, 0x5a, 0x53, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x72,
|
||||
0x79, 0x73, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x70, 0x72, 0x79, 0x73,
|
||||
0x6d, 0x2f, 0x76, 0x34, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d,
|
||||
0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61,
|
||||
0x74, 0x6f, 0x72, 0x2d, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x3b, 0x76, 0x61, 0x6c, 0x69, 0x64,
|
||||
0x61, 0x74, 0x6f, 0x72, 0x70, 0x62, 0xaa, 0x02, 0x1e, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75,
|
||||
0x6d, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x41, 0x63, 0x63, 0x6f,
|
||||
0x75, 0x6e, 0x74, 0x73, 0x2e, 0x56, 0x32, 0xca, 0x02, 0x1e, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65,
|
||||
0x75, 0x6d, 0x5c, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x5c, 0x41, 0x63, 0x63,
|
||||
0x6f, 0x75, 0x6e, 0x74, 0x73, 0x5c, 0x56, 0x32, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -668,49 +883,57 @@ func file_proto_prysm_v1alpha1_validator_client_keymanager_proto_rawDescGZIP() [
|
||||
}
|
||||
|
||||
var file_proto_prysm_v1alpha1_validator_client_keymanager_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
|
||||
var file_proto_prysm_v1alpha1_validator_client_keymanager_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
|
||||
var file_proto_prysm_v1alpha1_validator_client_keymanager_proto_msgTypes = make([]protoimpl.MessageInfo, 7)
|
||||
var file_proto_prysm_v1alpha1_validator_client_keymanager_proto_goTypes = []interface{}{
|
||||
(SignResponse_Status)(0), // 0: ethereum.validator.accounts.v2.SignResponse.Status
|
||||
(*ListPublicKeysResponse)(nil), // 1: ethereum.validator.accounts.v2.ListPublicKeysResponse
|
||||
(*SignRequest)(nil), // 2: ethereum.validator.accounts.v2.SignRequest
|
||||
(*SignResponse)(nil), // 3: ethereum.validator.accounts.v2.SignResponse
|
||||
(*v1alpha1.BeaconBlock)(nil), // 4: ethereum.eth.v1alpha1.BeaconBlock
|
||||
(*v1alpha1.AttestationData)(nil), // 5: ethereum.eth.v1alpha1.AttestationData
|
||||
(*v1alpha1.AggregateAttestationAndProof)(nil), // 6: ethereum.eth.v1alpha1.AggregateAttestationAndProof
|
||||
(*v1alpha1.VoluntaryExit)(nil), // 7: ethereum.eth.v1alpha1.VoluntaryExit
|
||||
(*v1alpha1.BeaconBlockAltair)(nil), // 8: ethereum.eth.v1alpha1.BeaconBlockAltair
|
||||
(*v1alpha1.SyncAggregatorSelectionData)(nil), // 9: ethereum.eth.v1alpha1.SyncAggregatorSelectionData
|
||||
(*v1alpha1.ContributionAndProof)(nil), // 10: ethereum.eth.v1alpha1.ContributionAndProof
|
||||
(*v1alpha1.BeaconBlockBellatrix)(nil), // 11: ethereum.eth.v1alpha1.BeaconBlockBellatrix
|
||||
(*v1alpha1.BlindedBeaconBlockBellatrix)(nil), // 12: ethereum.eth.v1alpha1.BlindedBeaconBlockBellatrix
|
||||
(*v1alpha1.ValidatorRegistrationV1)(nil), // 13: ethereum.eth.v1alpha1.ValidatorRegistrationV1
|
||||
(*v1alpha1.BeaconBlockCapella)(nil), // 14: ethereum.eth.v1alpha1.BeaconBlockCapella
|
||||
(*v1alpha1.BlindedBeaconBlockCapella)(nil), // 15: ethereum.eth.v1alpha1.BlindedBeaconBlockCapella
|
||||
(*empty.Empty)(nil), // 16: google.protobuf.Empty
|
||||
(*ProposerOptionPayload)(nil), // 4: ethereum.validator.accounts.v2.ProposerOptionPayload
|
||||
(*BuilderConfig)(nil), // 5: ethereum.validator.accounts.v2.BuilderConfig
|
||||
(*ProposerSettingsPayload)(nil), // 6: ethereum.validator.accounts.v2.ProposerSettingsPayload
|
||||
nil, // 7: ethereum.validator.accounts.v2.ProposerSettingsPayload.ProposerConfigEntry
|
||||
(*v1alpha1.BeaconBlock)(nil), // 8: ethereum.eth.v1alpha1.BeaconBlock
|
||||
(*v1alpha1.AttestationData)(nil), // 9: ethereum.eth.v1alpha1.AttestationData
|
||||
(*v1alpha1.AggregateAttestationAndProof)(nil), // 10: ethereum.eth.v1alpha1.AggregateAttestationAndProof
|
||||
(*v1alpha1.VoluntaryExit)(nil), // 11: ethereum.eth.v1alpha1.VoluntaryExit
|
||||
(*v1alpha1.BeaconBlockAltair)(nil), // 12: ethereum.eth.v1alpha1.BeaconBlockAltair
|
||||
(*v1alpha1.SyncAggregatorSelectionData)(nil), // 13: ethereum.eth.v1alpha1.SyncAggregatorSelectionData
|
||||
(*v1alpha1.ContributionAndProof)(nil), // 14: ethereum.eth.v1alpha1.ContributionAndProof
|
||||
(*v1alpha1.BeaconBlockBellatrix)(nil), // 15: ethereum.eth.v1alpha1.BeaconBlockBellatrix
|
||||
(*v1alpha1.BlindedBeaconBlockBellatrix)(nil), // 16: ethereum.eth.v1alpha1.BlindedBeaconBlockBellatrix
|
||||
(*v1alpha1.ValidatorRegistrationV1)(nil), // 17: ethereum.eth.v1alpha1.ValidatorRegistrationV1
|
||||
(*v1alpha1.BeaconBlockCapella)(nil), // 18: ethereum.eth.v1alpha1.BeaconBlockCapella
|
||||
(*v1alpha1.BlindedBeaconBlockCapella)(nil), // 19: ethereum.eth.v1alpha1.BlindedBeaconBlockCapella
|
||||
(*empty.Empty)(nil), // 20: google.protobuf.Empty
|
||||
}
|
||||
var file_proto_prysm_v1alpha1_validator_client_keymanager_proto_depIdxs = []int32{
|
||||
4, // 0: ethereum.validator.accounts.v2.SignRequest.block:type_name -> ethereum.eth.v1alpha1.BeaconBlock
|
||||
5, // 1: ethereum.validator.accounts.v2.SignRequest.attestation_data:type_name -> ethereum.eth.v1alpha1.AttestationData
|
||||
6, // 2: ethereum.validator.accounts.v2.SignRequest.aggregate_attestation_and_proof:type_name -> ethereum.eth.v1alpha1.AggregateAttestationAndProof
|
||||
7, // 3: ethereum.validator.accounts.v2.SignRequest.exit:type_name -> ethereum.eth.v1alpha1.VoluntaryExit
|
||||
8, // 4: ethereum.validator.accounts.v2.SignRequest.block_altair:type_name -> ethereum.eth.v1alpha1.BeaconBlockAltair
|
||||
9, // 5: ethereum.validator.accounts.v2.SignRequest.sync_aggregator_selection_data:type_name -> ethereum.eth.v1alpha1.SyncAggregatorSelectionData
|
||||
10, // 6: ethereum.validator.accounts.v2.SignRequest.contribution_and_proof:type_name -> ethereum.eth.v1alpha1.ContributionAndProof
|
||||
11, // 7: ethereum.validator.accounts.v2.SignRequest.block_bellatrix:type_name -> ethereum.eth.v1alpha1.BeaconBlockBellatrix
|
||||
12, // 8: ethereum.validator.accounts.v2.SignRequest.blinded_block_bellatrix:type_name -> ethereum.eth.v1alpha1.BlindedBeaconBlockBellatrix
|
||||
13, // 9: ethereum.validator.accounts.v2.SignRequest.registration:type_name -> ethereum.eth.v1alpha1.ValidatorRegistrationV1
|
||||
14, // 10: ethereum.validator.accounts.v2.SignRequest.block_capella:type_name -> ethereum.eth.v1alpha1.BeaconBlockCapella
|
||||
15, // 11: ethereum.validator.accounts.v2.SignRequest.blinded_block_capella:type_name -> ethereum.eth.v1alpha1.BlindedBeaconBlockCapella
|
||||
8, // 0: ethereum.validator.accounts.v2.SignRequest.block:type_name -> ethereum.eth.v1alpha1.BeaconBlock
|
||||
9, // 1: ethereum.validator.accounts.v2.SignRequest.attestation_data:type_name -> ethereum.eth.v1alpha1.AttestationData
|
||||
10, // 2: ethereum.validator.accounts.v2.SignRequest.aggregate_attestation_and_proof:type_name -> ethereum.eth.v1alpha1.AggregateAttestationAndProof
|
||||
11, // 3: ethereum.validator.accounts.v2.SignRequest.exit:type_name -> ethereum.eth.v1alpha1.VoluntaryExit
|
||||
12, // 4: ethereum.validator.accounts.v2.SignRequest.block_altair:type_name -> ethereum.eth.v1alpha1.BeaconBlockAltair
|
||||
13, // 5: ethereum.validator.accounts.v2.SignRequest.sync_aggregator_selection_data:type_name -> ethereum.eth.v1alpha1.SyncAggregatorSelectionData
|
||||
14, // 6: ethereum.validator.accounts.v2.SignRequest.contribution_and_proof:type_name -> ethereum.eth.v1alpha1.ContributionAndProof
|
||||
15, // 7: ethereum.validator.accounts.v2.SignRequest.block_bellatrix:type_name -> ethereum.eth.v1alpha1.BeaconBlockBellatrix
|
||||
16, // 8: ethereum.validator.accounts.v2.SignRequest.blinded_block_bellatrix:type_name -> ethereum.eth.v1alpha1.BlindedBeaconBlockBellatrix
|
||||
17, // 9: ethereum.validator.accounts.v2.SignRequest.registration:type_name -> ethereum.eth.v1alpha1.ValidatorRegistrationV1
|
||||
18, // 10: ethereum.validator.accounts.v2.SignRequest.block_capella:type_name -> ethereum.eth.v1alpha1.BeaconBlockCapella
|
||||
19, // 11: ethereum.validator.accounts.v2.SignRequest.blinded_block_capella:type_name -> ethereum.eth.v1alpha1.BlindedBeaconBlockCapella
|
||||
0, // 12: ethereum.validator.accounts.v2.SignResponse.status:type_name -> ethereum.validator.accounts.v2.SignResponse.Status
|
||||
16, // 13: ethereum.validator.accounts.v2.RemoteSigner.ListValidatingPublicKeys:input_type -> google.protobuf.Empty
|
||||
2, // 14: ethereum.validator.accounts.v2.RemoteSigner.Sign:input_type -> ethereum.validator.accounts.v2.SignRequest
|
||||
1, // 15: ethereum.validator.accounts.v2.RemoteSigner.ListValidatingPublicKeys:output_type -> ethereum.validator.accounts.v2.ListPublicKeysResponse
|
||||
3, // 16: ethereum.validator.accounts.v2.RemoteSigner.Sign:output_type -> ethereum.validator.accounts.v2.SignResponse
|
||||
15, // [15:17] is the sub-list for method output_type
|
||||
13, // [13:15] is the sub-list for method input_type
|
||||
13, // [13:13] is the sub-list for extension type_name
|
||||
13, // [13:13] is the sub-list for extension extendee
|
||||
0, // [0:13] is the sub-list for field type_name
|
||||
5, // 13: ethereum.validator.accounts.v2.ProposerOptionPayload.builder:type_name -> ethereum.validator.accounts.v2.BuilderConfig
|
||||
7, // 14: ethereum.validator.accounts.v2.ProposerSettingsPayload.proposer_config:type_name -> ethereum.validator.accounts.v2.ProposerSettingsPayload.ProposerConfigEntry
|
||||
4, // 15: ethereum.validator.accounts.v2.ProposerSettingsPayload.default_config:type_name -> ethereum.validator.accounts.v2.ProposerOptionPayload
|
||||
4, // 16: ethereum.validator.accounts.v2.ProposerSettingsPayload.ProposerConfigEntry.value:type_name -> ethereum.validator.accounts.v2.ProposerOptionPayload
|
||||
20, // 17: ethereum.validator.accounts.v2.RemoteSigner.ListValidatingPublicKeys:input_type -> google.protobuf.Empty
|
||||
2, // 18: ethereum.validator.accounts.v2.RemoteSigner.Sign:input_type -> ethereum.validator.accounts.v2.SignRequest
|
||||
1, // 19: ethereum.validator.accounts.v2.RemoteSigner.ListValidatingPublicKeys:output_type -> ethereum.validator.accounts.v2.ListPublicKeysResponse
|
||||
3, // 20: ethereum.validator.accounts.v2.RemoteSigner.Sign:output_type -> ethereum.validator.accounts.v2.SignResponse
|
||||
19, // [19:21] is the sub-list for method output_type
|
||||
17, // [17:19] is the sub-list for method input_type
|
||||
17, // [17:17] is the sub-list for extension type_name
|
||||
17, // [17:17] is the sub-list for extension extendee
|
||||
0, // [0:17] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_proto_prysm_v1alpha1_validator_client_keymanager_proto_init() }
|
||||
@@ -755,6 +978,42 @@ func file_proto_prysm_v1alpha1_validator_client_keymanager_proto_init() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_proto_prysm_v1alpha1_validator_client_keymanager_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*ProposerOptionPayload); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_proto_prysm_v1alpha1_validator_client_keymanager_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*BuilderConfig); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_proto_prysm_v1alpha1_validator_client_keymanager_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*ProposerSettingsPayload); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
file_proto_prysm_v1alpha1_validator_client_keymanager_proto_msgTypes[1].OneofWrappers = []interface{}{
|
||||
(*SignRequest_Block)(nil),
|
||||
@@ -779,7 +1038,7 @@ func file_proto_prysm_v1alpha1_validator_client_keymanager_proto_init() {
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_proto_prysm_v1alpha1_validator_client_keymanager_proto_rawDesc,
|
||||
NumEnums: 1,
|
||||
NumMessages: 3,
|
||||
NumMessages: 7,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
|
||||
@@ -107,3 +107,22 @@ message SignResponse {
|
||||
// same conventions.
|
||||
Status status = 2;
|
||||
}
|
||||
|
||||
// ProposerOptionPayload is a property of ProposerSettingsPayload
|
||||
message ProposerOptionPayload {
|
||||
string fee_recipient = 1;
|
||||
BuilderConfig builder = 2;
|
||||
}
|
||||
|
||||
// BuilderConfig is a property of ProposerOptionPayload
|
||||
message BuilderConfig {
|
||||
bool enabled = 1;
|
||||
uint64 gas_limit = 2 [(ethereum.eth.ext.cast_type) = "github.com/prysmaticlabs/prysm/v4/consensus-types/validator.Uint64"];
|
||||
repeated string relays = 3;
|
||||
}
|
||||
|
||||
// ProposerSettingsPayload is used to unmarshal files sent from the validator flag as well as safe to bolt db bucket
|
||||
message ProposerSettingsPayload {
|
||||
map<string, ProposerOptionPayload> proposer_config = 1;
|
||||
ProposerOptionPayload default_config = 2;
|
||||
}
|
||||
@@ -29,9 +29,9 @@ go_library(
|
||||
"//config/features:go_default_library",
|
||||
"//config/fieldparams:go_default_library",
|
||||
"//config/params:go_default_library",
|
||||
"//config/validator/service:go_default_library",
|
||||
"//crypto/bls:go_default_library",
|
||||
"//io/file:go_default_library",
|
||||
"//proto/prysm/v1alpha1/validator-client:go_default_library",
|
||||
"//runtime/interop:go_default_library",
|
||||
"//testing/endtoend/helpers:go_default_library",
|
||||
"//testing/endtoend/params:go_default_library",
|
||||
|
||||
@@ -268,6 +268,8 @@ func (node *BeaconNode) Start(ctx context.Context) error {
|
||||
fmt.Sprintf("--%s=%s", cmdshared.VerbosityFlag.Name, "debug"),
|
||||
fmt.Sprintf("--%s=%d", flags.BlockBatchLimitBurstFactor.Name, 8),
|
||||
fmt.Sprintf("--%s=%s", cmdshared.ChainConfigFileFlag.Name, cfgPath),
|
||||
"--" + cmdshared.ValidatorMonitorIndicesFlag.Name + "=1",
|
||||
"--" + cmdshared.ValidatorMonitorIndicesFlag.Name + "=2",
|
||||
"--" + cmdshared.ForceClearDB.Name,
|
||||
"--" + cmdshared.AcceptTosFlag.Name,
|
||||
"--" + flags.EnableDebugRPCEndpoints.Name,
|
||||
|
||||
@@ -20,8 +20,8 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/v4/config/features"
|
||||
fieldparams "github.com/prysmaticlabs/prysm/v4/config/fieldparams"
|
||||
"github.com/prysmaticlabs/prysm/v4/config/params"
|
||||
validator_service_config "github.com/prysmaticlabs/prysm/v4/config/validator/service"
|
||||
"github.com/prysmaticlabs/prysm/v4/io/file"
|
||||
validatorpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1/validator-client"
|
||||
"github.com/prysmaticlabs/prysm/v4/runtime/interop"
|
||||
"github.com/prysmaticlabs/prysm/v4/testing/endtoend/helpers"
|
||||
e2e "github.com/prysmaticlabs/prysm/v4/testing/endtoend/params"
|
||||
@@ -244,8 +244,9 @@ func (v *ValidatorNode) Start(ctx context.Context) error {
|
||||
beaconRestApiPort = e2e.TestParams.Ports.PrysmBeaconNodeGatewayPort
|
||||
}
|
||||
|
||||
args = append(args, fmt.Sprintf("--%s=http://localhost:%d", flags.BeaconRESTApiProviderFlag.Name, beaconRestApiPort))
|
||||
args = append(args, fmt.Sprintf("--%s", features.EnableBeaconRESTApi.Name))
|
||||
args = append(args,
|
||||
fmt.Sprintf("--%s=http://localhost:%d", flags.BeaconRESTApiProviderFlag.Name, beaconRestApiPort),
|
||||
fmt.Sprintf("--%s", features.EnableBeaconRESTApi.Name))
|
||||
}
|
||||
|
||||
// Only apply e2e flags to the current branch. New flags may not exist in previous release.
|
||||
@@ -253,10 +254,11 @@ func (v *ValidatorNode) Start(ctx context.Context) error {
|
||||
args = append(args, features.E2EValidatorFlags...)
|
||||
}
|
||||
if v.config.UseWeb3RemoteSigner {
|
||||
args = append(args, fmt.Sprintf("--%s=http://localhost:%d", flags.Web3SignerURLFlag.Name, Web3RemoteSignerPort))
|
||||
// Write the pubkeys as comma separated hex strings with 0x prefix.
|
||||
// See: https://docs.teku.consensys.net/en/latest/HowTo/External-Signer/Use-External-Signer/
|
||||
args = append(args, fmt.Sprintf("--%s=%s", flags.Web3SignerPublicValidatorKeysFlag.Name, strings.Join(validatorHexPubKeys, ",")))
|
||||
args = append(args,
|
||||
fmt.Sprintf("--%s=http://localhost:%d", flags.Web3SignerURLFlag.Name, Web3RemoteSignerPort),
|
||||
fmt.Sprintf("--%s=%s", flags.Web3SignerPublicValidatorKeysFlag.Name, strings.Join(validatorHexPubKeys, ",")))
|
||||
} else {
|
||||
// When not using remote key signer, use interop keys.
|
||||
args = append(args,
|
||||
@@ -338,17 +340,16 @@ func createProposerSettingsPath(pubkeys []string, nodeIdx int) (string, error) {
|
||||
if len(pubkeys) == 0 {
|
||||
return "", errors.New("number of validators must be greater than 0")
|
||||
}
|
||||
var proposerSettingsPayload validator_service_config.ProposerSettingsPayload
|
||||
config := make(map[string]*validator_service_config.ProposerOptionPayload)
|
||||
config := make(map[string]*validatorpb.ProposerOptionPayload)
|
||||
|
||||
for i, pubkey := range pubkeys {
|
||||
config[pubkeys[i]] = &validator_service_config.ProposerOptionPayload{
|
||||
config[pubkeys[i]] = &validatorpb.ProposerOptionPayload{
|
||||
FeeRecipient: FeeRecipientFromPubkey(pubkey),
|
||||
}
|
||||
}
|
||||
proposerSettingsPayload = validator_service_config.ProposerSettingsPayload{
|
||||
proposerSettingsPayload := &validatorpb.ProposerSettingsPayload{
|
||||
ProposerConfig: config,
|
||||
DefaultConfig: &validator_service_config.ProposerOptionPayload{
|
||||
DefaultConfig: &validatorpb.ProposerOptionPayload{
|
||||
FeeRecipient: DefaultFeeRecipientAddress,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -37,5 +37,6 @@ go_test(
|
||||
"//time:go_default_library",
|
||||
"@com_github_sirupsen_logrus//:go_default_library",
|
||||
"@com_github_sirupsen_logrus//hooks/test:go_default_library",
|
||||
"@com_github_stretchr_testify//require:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -4,6 +4,7 @@ package slots
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/prysmaticlabs/prysm/v4/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
|
||||
prysmTime "github.com/prysmaticlabs/prysm/v4/time"
|
||||
)
|
||||
@@ -104,3 +105,65 @@ func (s *SlotTicker) start(
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
// startWithIntervals starts a ticker that emits a tick every slot at the
|
||||
// prescribed intervals. The caller is responsible to make these intervals increasing and
|
||||
// less than secondsPerSlot
|
||||
func (s *SlotTicker) startWithIntervals(
|
||||
genesisTime time.Time,
|
||||
until func(time.Time) time.Duration,
|
||||
after func(time.Duration) <-chan time.Time,
|
||||
intervals []time.Duration) {
|
||||
go func() {
|
||||
slot := Since(genesisTime)
|
||||
slot++
|
||||
interval := 0
|
||||
nextTickTime := startFromTime(genesisTime, slot).Add(intervals[0])
|
||||
|
||||
for {
|
||||
waitTime := until(nextTickTime)
|
||||
select {
|
||||
case <-after(waitTime):
|
||||
s.c <- slot
|
||||
interval++
|
||||
if interval == len(intervals) {
|
||||
interval = 0
|
||||
slot++
|
||||
}
|
||||
nextTickTime = startFromTime(genesisTime, slot).Add(intervals[interval])
|
||||
case <-s.done:
|
||||
return
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
// NewSlotTickerWithIntervals starts and returns a SlotTicker instance that allows
|
||||
// several offsets of time from genesis,
|
||||
// Caller is responsible to input the intervals in increasing order and none bigger or equal than
|
||||
// SecondsPerSlot
|
||||
func NewSlotTickerWithIntervals(genesisTime time.Time, intervals []time.Duration) *SlotTicker {
|
||||
if genesisTime.Unix() == 0 {
|
||||
panic("zero genesis time")
|
||||
}
|
||||
if len(intervals) == 0 {
|
||||
panic("at least one interval has to be entered")
|
||||
}
|
||||
slotDuration := time.Duration(params.BeaconConfig().SecondsPerSlot) * time.Second
|
||||
lastOffset := time.Duration(0)
|
||||
for _, offset := range intervals {
|
||||
if offset < lastOffset {
|
||||
panic("invalid decreasing offsets")
|
||||
}
|
||||
if offset >= slotDuration {
|
||||
panic("invalid ticker offset")
|
||||
}
|
||||
lastOffset = offset
|
||||
}
|
||||
ticker := &SlotTicker{
|
||||
c: make(chan primitives.Slot),
|
||||
done: make(chan struct{}),
|
||||
}
|
||||
ticker.startWithIntervals(genesisTime, prysmTime.Until, time.After, intervals)
|
||||
return ticker
|
||||
}
|
||||
|
||||
@@ -4,7 +4,9 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/prysmaticlabs/prysm/v4/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
var _ Ticker = (*SlotTicker)(nil)
|
||||
@@ -136,3 +138,49 @@ func TestGetSlotTickerWithOffset_OK(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetSlotTickerWitIntervals(t *testing.T) {
|
||||
genesisTime := time.Now()
|
||||
offset := time.Duration(params.BeaconConfig().SecondsPerSlot) * time.Second / 3
|
||||
intervals := []time.Duration{offset, 2 * offset}
|
||||
|
||||
intervalTicker := NewSlotTickerWithIntervals(genesisTime, intervals)
|
||||
normalTicker := NewSlotTicker(genesisTime, params.BeaconConfig().SecondsPerSlot)
|
||||
|
||||
firstTicked := 0
|
||||
for {
|
||||
select {
|
||||
case <-intervalTicker.C():
|
||||
// interval ticks starts in second slot
|
||||
if firstTicked < 2 {
|
||||
t.Fatal("Expected other ticker to tick first")
|
||||
}
|
||||
return
|
||||
case <-normalTicker.C():
|
||||
if firstTicked > 1 {
|
||||
t.Fatal("Expected normal ticker to tick first")
|
||||
}
|
||||
firstTicked++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSlotTickerWithIntervalsInputValidation(t *testing.T) {
|
||||
var genesisTime time.Time
|
||||
offset := time.Duration(params.BeaconConfig().SecondsPerSlot) * time.Second / 3
|
||||
intervals := make([]time.Duration, 0)
|
||||
panicCall := func() {
|
||||
NewSlotTickerWithIntervals(genesisTime, intervals)
|
||||
}
|
||||
require.Panics(t, panicCall, "zero genesis time")
|
||||
genesisTime = time.Now()
|
||||
require.Panics(t, panicCall, "at least one interval has to be entered")
|
||||
intervals = []time.Duration{2 * offset, offset}
|
||||
require.Panics(t, panicCall, "invalid decreasing offsets")
|
||||
intervals = []time.Duration{offset, 4 * offset}
|
||||
require.Panics(t, panicCall, "invalid ticker offset")
|
||||
intervals = []time.Duration{4 * offset, offset}
|
||||
require.Panics(t, panicCall, "invalid ticker offset")
|
||||
intervals = []time.Duration{offset, 2 * offset}
|
||||
require.NotPanics(t, panicCall)
|
||||
}
|
||||
|
||||
@@ -16,12 +16,17 @@ import (
|
||||
// incoming objects. (24 mins with mainnet spec)
|
||||
const MaxSlotBuffer = uint64(1 << 7)
|
||||
|
||||
// startFromTime returns the slot start in terms of genesis time.Time
|
||||
func startFromTime(genesis time.Time, slot primitives.Slot) time.Time {
|
||||
duration := time.Second * time.Duration(slot.Mul(params.BeaconConfig().SecondsPerSlot))
|
||||
return genesis.Add(duration) // lint:ignore uintcast -- Genesis timestamp will not exceed int64 in your lifetime.
|
||||
}
|
||||
|
||||
// StartTime returns the start time in terms of its unix epoch
|
||||
// value.
|
||||
func StartTime(genesis uint64, slot primitives.Slot) time.Time {
|
||||
duration := time.Second * time.Duration(slot.Mul(params.BeaconConfig().SecondsPerSlot))
|
||||
startTime := time.Unix(int64(genesis), 0).Add(duration) // lint:ignore uintcast -- Genesis timestamp will not exceed int64 in your lifetime.
|
||||
return startTime
|
||||
genesisTime := time.Unix(int64(genesis), 0) // lint:ignore uintcast -- Genesis timestamp will not exceed int64 in your lifetime.
|
||||
return startFromTime(genesisTime, slot)
|
||||
}
|
||||
|
||||
// SinceGenesis returns the number of slots since
|
||||
@@ -247,3 +252,9 @@ func SecondsSinceSlotStart(s primitives.Slot, genesisTime, timeStamp uint64) (ui
|
||||
}
|
||||
return timeStamp - genesisTime - uint64(s)*params.BeaconConfig().SecondsPerSlot, nil
|
||||
}
|
||||
|
||||
// TimeIntoSlot returns the time duration elapsed between the current time and
|
||||
// the start of the current slot
|
||||
func TimeIntoSlot(genesisTime uint64) time.Duration {
|
||||
return time.Since(StartTime(genesisTime, CurrentSlot(genesisTime)))
|
||||
}
|
||||
|
||||
@@ -563,3 +563,9 @@ func TestDuration(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestTimeIntoSlot(t *testing.T) {
|
||||
genesisTime := uint64(time.Now().Add(-37 * time.Second).Unix())
|
||||
require.Equal(t, true, TimeIntoSlot(genesisTime) > 900*time.Millisecond)
|
||||
require.Equal(t, true, TimeIntoSlot(genesisTime) < 3000*time.Millisecond)
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"flag"
|
||||
"fmt"
|
||||
"math"
|
||||
"time"
|
||||
|
||||
"github.com/prysmaticlabs/prysm/v4/config/params"
|
||||
@@ -25,7 +26,7 @@ func main() {
|
||||
flag.Parse()
|
||||
ctx := context.Background()
|
||||
|
||||
cc, err := grpc.DialContext(ctx, *beacon, grpc.WithInsecure())
|
||||
cc, err := grpc.DialContext(ctx, *beacon, grpc.WithInsecure(), grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(math.MaxInt64)))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@@ -82,6 +83,8 @@ func wrapBlock(b *v1alpha1.BeaconBlockContainer) interfaces.ReadOnlyBeaconBlock
|
||||
wb, err = blocks.NewSignedBeaconBlock(bb.AltairBlock)
|
||||
case *v1alpha1.BeaconBlockContainer_BellatrixBlock:
|
||||
wb, err = blocks.NewSignedBeaconBlock(bb.BellatrixBlock)
|
||||
case *v1alpha1.BeaconBlockContainer_CapellaBlock:
|
||||
wb, err = blocks.NewSignedBeaconBlock(bb.CapellaBlock)
|
||||
}
|
||||
if err != nil {
|
||||
panic("no block")
|
||||
|
||||
@@ -128,6 +128,7 @@ go_test(
|
||||
"//consensus-types/blocks/testing:go_default_library",
|
||||
"//consensus-types/interfaces:go_default_library",
|
||||
"//consensus-types/primitives:go_default_library",
|
||||
"//consensus-types/validator:go_default_library",
|
||||
"//crypto/bls:go_default_library",
|
||||
"//crypto/bls/common/mock:go_default_library",
|
||||
"//encoding/bytesutil:go_default_library",
|
||||
|
||||
@@ -53,6 +53,7 @@ func run(ctx context.Context, v iface.Validator) {
|
||||
log.WithError(err).Fatal("Could not get keymanager")
|
||||
}
|
||||
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"+
|
||||
@@ -117,7 +118,7 @@ func run(ctx context.Context, v iface.Validator) {
|
||||
|
||||
if slots.IsEpochStart(slot) && v.ProposerSettings() != nil {
|
||||
go func() {
|
||||
//deadline set for end of epoch
|
||||
// deadline set for end of epoch
|
||||
epochDeadline := v.SlotDeadline(slot + params.BeaconConfig().SlotsPerEpoch - 1)
|
||||
if err := v.PushProposerSettings(ctx, km, slot, epochDeadline); err != nil {
|
||||
log.WithError(err).Warn("Failed to update proposer settings")
|
||||
|
||||
@@ -188,10 +188,21 @@ func (v *ValidatorService) Start() {
|
||||
return
|
||||
}
|
||||
|
||||
// checks db if proposer settings exist if none is provided.
|
||||
if v.proposerSettings == nil {
|
||||
settings, err := v.db.ProposerSettings(v.ctx)
|
||||
if err == nil {
|
||||
v.proposerSettings = settings
|
||||
}
|
||||
}
|
||||
|
||||
validatorClient := validatorClientFactory.NewValidatorClient(v.conn)
|
||||
beaconClient := beaconChainClientFactory.NewBeaconChainClient(v.conn)
|
||||
|
||||
valStruct := &validator{
|
||||
db: v.db,
|
||||
validatorClient: validatorClientFactory.NewValidatorClient(v.conn),
|
||||
beaconClient: beaconChainClientFactory.NewBeaconChainClient(v.conn),
|
||||
validatorClient: validatorClient,
|
||||
beaconClient: beaconClient,
|
||||
slashingProtectionClient: slasherClientFactory.NewSlasherClient(v.conn),
|
||||
node: nodeClientFactory.NewNodeClient(v.conn),
|
||||
graffiti: v.graffiti,
|
||||
@@ -218,6 +229,7 @@ func (v *ValidatorService) Start() {
|
||||
proposerSettings: v.proposerSettings,
|
||||
walletInitializedChannel: make(chan *wallet.Wallet, 1),
|
||||
}
|
||||
|
||||
// To resolve a race condition at startup due to the interface
|
||||
// nature of the abstracted block type. We initialize
|
||||
// the inner type of the feed before hand. So that
|
||||
@@ -255,17 +267,31 @@ func (v *ValidatorService) InteropKeysConfig() *local.InteropKeymanagerConfig {
|
||||
return v.interopKeysConfig
|
||||
}
|
||||
|
||||
// Keymanager returns the underlying keymanager in the validator
|
||||
func (v *ValidatorService) Keymanager() (keymanager.IKeymanager, error) {
|
||||
return v.validator.Keymanager()
|
||||
}
|
||||
|
||||
// ProposerSettings returns a deep copy of the underlying proposer settings in the validator
|
||||
func (v *ValidatorService) ProposerSettings() *validatorserviceconfig.ProposerSettings {
|
||||
return v.validator.ProposerSettings()
|
||||
settings := v.validator.ProposerSettings()
|
||||
if settings != nil {
|
||||
return settings.Clone()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (v *ValidatorService) SetProposerSettings(settings *validatorserviceconfig.ProposerSettings) {
|
||||
// SetProposerSettings sets the proposer settings on the validator service as well as the underlying validator
|
||||
func (v *ValidatorService) SetProposerSettings(ctx context.Context, settings *validatorserviceconfig.ProposerSettings) error {
|
||||
if v.db == nil {
|
||||
return errors.New("db is not set")
|
||||
}
|
||||
if err := v.db.SaveProposerSettings(ctx, settings); err != nil {
|
||||
return err
|
||||
}
|
||||
v.proposerSettings = settings
|
||||
v.validator.SetProposerSettings(settings)
|
||||
return nil
|
||||
}
|
||||
|
||||
// ConstructDialOptions constructs a list of grpc dial options
|
||||
|
||||
@@ -22,6 +22,7 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/v4/config/params"
|
||||
validatorserviceconfig "github.com/prysmaticlabs/prysm/v4/config/validator/service"
|
||||
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
|
||||
validatorType "github.com/prysmaticlabs/prysm/v4/consensus-types/validator"
|
||||
"github.com/prysmaticlabs/prysm/v4/crypto/bls"
|
||||
blsmock "github.com/prysmaticlabs/prysm/v4/crypto/bls/common/mock"
|
||||
"github.com/prysmaticlabs/prysm/v4/encoding/bytesutil"
|
||||
@@ -1672,7 +1673,7 @@ func TestValidator_PushProposerSettings(t *testing.T) {
|
||||
},
|
||||
BuilderConfig: &validatorserviceconfig.BuilderConfig{
|
||||
Enabled: true,
|
||||
GasLimit: validatorserviceconfig.Uint64(params.BeaconConfig().DefaultBuilderGasLimit),
|
||||
GasLimit: validatorType.Uint64(params.BeaconConfig().DefaultBuilderGasLimit),
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
@@ -5,9 +5,10 @@ go_library(
|
||||
srcs = ["interface.go"],
|
||||
importpath = "github.com/prysmaticlabs/prysm/v4/validator/db/iface",
|
||||
# Other packages must use github.com/prysmaticlabs/prysm/v4/validator/db.Database alias.
|
||||
visibility = ["//validator/db:__subpackages__"],
|
||||
visibility = ["//validator:__subpackages__"],
|
||||
deps = [
|
||||
"//config/fieldparams:go_default_library",
|
||||
"//config/validator/service:go_default_library",
|
||||
"//consensus-types/primitives:go_default_library",
|
||||
"//monitoring/backup:go_default_library",
|
||||
"//proto/prysm/v1alpha1:go_default_library",
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"io"
|
||||
|
||||
fieldparams "github.com/prysmaticlabs/prysm/v4/config/fieldparams"
|
||||
validatorServiceConfig "github.com/prysmaticlabs/prysm/v4/config/validator/service"
|
||||
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
|
||||
"github.com/prysmaticlabs/prysm/v4/monitoring/backup"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
|
||||
@@ -62,4 +63,11 @@ type ValidatorDB interface {
|
||||
// Graffiti ordered index related methods
|
||||
SaveGraffitiOrderedIndex(ctx context.Context, index uint64) error
|
||||
GraffitiOrderedIndex(ctx context.Context, fileHash [32]byte) (uint64, error)
|
||||
|
||||
// ProposerSettings related methods
|
||||
ProposerSettings(context.Context) (*validatorServiceConfig.ProposerSettings, error)
|
||||
ProposerSettingsExists(ctx context.Context) (bool, error)
|
||||
UpdateProposerSettingsDefault(context.Context, *validatorServiceConfig.ProposerOption) error
|
||||
UpdateProposerSettingsForPubkey(context.Context, [fieldparams.BLSPubkeyLength]byte, *validatorServiceConfig.ProposerOption) error
|
||||
SaveProposerSettings(ctx context.Context, settings *validatorServiceConfig.ProposerSettings) error
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ go_library(
|
||||
"migration_optimal_attester_protection.go",
|
||||
"migration_source_target_epochs_bucket.go",
|
||||
"proposer_protection.go",
|
||||
"proposer_settings.go",
|
||||
"prune_attester_protection.go",
|
||||
"schema.go",
|
||||
],
|
||||
@@ -29,6 +30,7 @@ go_library(
|
||||
"//config/features:go_default_library",
|
||||
"//config/fieldparams:go_default_library",
|
||||
"//config/params:go_default_library",
|
||||
"//config/validator/service:go_default_library",
|
||||
"//consensus-types/primitives:go_default_library",
|
||||
"//encoding/bytesutil:go_default_library",
|
||||
"//io/file:go_default_library",
|
||||
@@ -36,6 +38,7 @@ go_library(
|
||||
"//monitoring/tracing:go_default_library",
|
||||
"//proto/prysm/v1alpha1:go_default_library",
|
||||
"//proto/prysm/v1alpha1/slashings:go_default_library",
|
||||
"//proto/prysm/v1alpha1/validator-client:go_default_library",
|
||||
"//time/slots:go_default_library",
|
||||
"@com_github_pkg_errors//:go_default_library",
|
||||
"@com_github_prometheus_client_golang//prometheus:go_default_library",
|
||||
@@ -43,6 +46,7 @@ go_library(
|
||||
"@com_github_sirupsen_logrus//:go_default_library",
|
||||
"@io_etcd_go_bbolt//:go_default_library",
|
||||
"@io_opencensus_go//trace:go_default_library",
|
||||
"@org_golang_google_protobuf//proto:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -59,18 +63,23 @@ go_test(
|
||||
"migration_optimal_attester_protection_test.go",
|
||||
"migration_source_target_epochs_bucket_test.go",
|
||||
"proposer_protection_test.go",
|
||||
"proposer_settings_test.go",
|
||||
"prune_attester_protection_test.go",
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//config/fieldparams:go_default_library",
|
||||
"//config/params:go_default_library",
|
||||
"//config/validator/service:go_default_library",
|
||||
"//consensus-types/primitives:go_default_library",
|
||||
"//consensus-types/validator:go_default_library",
|
||||
"//crypto/hash:go_default_library",
|
||||
"//encoding/bytesutil:go_default_library",
|
||||
"//proto/prysm/v1alpha1:go_default_library",
|
||||
"//testing/assert:go_default_library",
|
||||
"//testing/require:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//common: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",
|
||||
"@io_etcd_go_bbolt//:go_default_library",
|
||||
|
||||
@@ -152,6 +152,7 @@ func NewKVStore(ctx context.Context, dirPath string, config *Config) (*Store, er
|
||||
pubKeysBucket,
|
||||
migrationsBucket,
|
||||
graffitiBucket,
|
||||
proposerSettingsBucket,
|
||||
)
|
||||
}); err != nil {
|
||||
return nil, err
|
||||
|
||||
132
validator/db/kv/proposer_settings.go
Normal file
132
validator/db/kv/proposer_settings.go
Normal file
@@ -0,0 +1,132 @@
|
||||
package kv
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
fieldparams "github.com/prysmaticlabs/prysm/v4/config/fieldparams"
|
||||
validatorServiceConfig "github.com/prysmaticlabs/prysm/v4/config/validator/service"
|
||||
validatorpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1/validator-client"
|
||||
bolt "go.etcd.io/bbolt"
|
||||
"go.opencensus.io/trace"
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
// NoProposerSettingsFound is an error thrown when no settings are found in bucket
|
||||
var NoProposerSettingsFound = errors.New("no proposer settings found in bucket")
|
||||
|
||||
// UpdateProposerSettingsForPubkey updates the existing settings for an internal representation of the proposers settings file at a particular public key
|
||||
func (s *Store) UpdateProposerSettingsForPubkey(ctx context.Context, pubkey [fieldparams.BLSPubkeyLength]byte, options *validatorServiceConfig.ProposerOption) error {
|
||||
_, span := trace.StartSpan(ctx, "validator.db.UpdateProposerSettingsForPubkey")
|
||||
defer span.End()
|
||||
err := s.db.Update(func(tx *bolt.Tx) error {
|
||||
bkt := tx.Bucket(proposerSettingsBucket)
|
||||
b := bkt.Get(proposerSettingsKey)
|
||||
if len(b) == 0 {
|
||||
return fmt.Errorf("no proposer settings found in bucket")
|
||||
}
|
||||
to := &validatorpb.ProposerSettingsPayload{}
|
||||
if err := proto.Unmarshal(b, to); err != nil {
|
||||
return errors.Wrap(err, "failed to unmarshal proposer settings")
|
||||
}
|
||||
settings, err := validatorServiceConfig.ToSettings(to)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to convert payload to proposer settings")
|
||||
}
|
||||
if settings.ProposeConfig == nil {
|
||||
settings.ProposeConfig = make(map[[fieldparams.BLSPubkeyLength]byte]*validatorServiceConfig.ProposerOption)
|
||||
}
|
||||
settings.ProposeConfig[pubkey] = options
|
||||
m, err := proto.Marshal(settings.ToPayload())
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to marshal proposer settings")
|
||||
}
|
||||
return bkt.Put(proposerSettingsKey, m)
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
// UpdateProposerSettingsDefault updates the existing default settings for proposer settings
|
||||
func (s *Store) UpdateProposerSettingsDefault(ctx context.Context, options *validatorServiceConfig.ProposerOption) error {
|
||||
_, span := trace.StartSpan(ctx, "validator.db.UpdateProposerSettingsDefault")
|
||||
defer span.End()
|
||||
if options == nil {
|
||||
return errors.New("proposer settings option was empty")
|
||||
}
|
||||
if options.FeeRecipientConfig == nil {
|
||||
return errors.New("fee recipient cannot be empty")
|
||||
}
|
||||
err := s.db.Update(func(tx *bolt.Tx) error {
|
||||
bkt := tx.Bucket(proposerSettingsBucket)
|
||||
b := bkt.Get(proposerSettingsKey)
|
||||
if len(b) == 0 {
|
||||
return NoProposerSettingsFound
|
||||
}
|
||||
to := &validatorpb.ProposerSettingsPayload{}
|
||||
if err := proto.Unmarshal(b, to); err != nil {
|
||||
return errors.Wrap(err, "failed to unmarshal proposer settings")
|
||||
}
|
||||
settings, err := validatorServiceConfig.ToSettings(to)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to convert payload to proposer settings")
|
||||
}
|
||||
settings.DefaultConfig = options
|
||||
m, err := proto.Marshal(settings.ToPayload())
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to marshal proposer settings")
|
||||
}
|
||||
return bkt.Put(proposerSettingsKey, m)
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
// ProposerSettings gets the current proposer settings
|
||||
func (s *Store) ProposerSettings(ctx context.Context) (*validatorServiceConfig.ProposerSettings, error) {
|
||||
_, span := trace.StartSpan(ctx, "validator.db.ProposerSettings")
|
||||
defer span.End()
|
||||
to := &validatorpb.ProposerSettingsPayload{}
|
||||
if err := s.db.View(func(tx *bolt.Tx) error {
|
||||
bkt := tx.Bucket(proposerSettingsBucket)
|
||||
b := bkt.Get(proposerSettingsKey)
|
||||
if len(b) == 0 {
|
||||
return NoProposerSettingsFound
|
||||
}
|
||||
if err := proto.Unmarshal(b, to); err != nil {
|
||||
return errors.Wrap(err, "failed to unmarshal proposer settings")
|
||||
}
|
||||
return nil
|
||||
}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return validatorServiceConfig.ToSettings(to)
|
||||
}
|
||||
|
||||
// ProposerSettingsExists returns true or false if the settings exist or not
|
||||
func (s *Store) ProposerSettingsExists(ctx context.Context) (bool, error) {
|
||||
ps, err := s.ProposerSettings(ctx)
|
||||
if err != nil {
|
||||
if errors.Is(err, NoProposerSettingsFound) {
|
||||
return false, nil
|
||||
}
|
||||
return false, err
|
||||
}
|
||||
if ps == nil {
|
||||
return false, nil
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// SaveProposerSettings saves the entire proposer setting overriding the existing settings
|
||||
func (s *Store) SaveProposerSettings(ctx context.Context, settings *validatorServiceConfig.ProposerSettings) error {
|
||||
_, span := trace.StartSpan(ctx, "validator.db.SaveProposerSettings")
|
||||
defer span.End()
|
||||
return s.db.Update(func(tx *bolt.Tx) error {
|
||||
bkt := tx.Bucket(proposerSettingsBucket)
|
||||
m, err := proto.Marshal(settings.ToPayload())
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to marshal proposer settings")
|
||||
}
|
||||
return bkt.Put(proposerSettingsKey, m)
|
||||
})
|
||||
}
|
||||
106
validator/db/kv/proposer_settings_test.go
Normal file
106
validator/db/kv/proposer_settings_test.go
Normal file
@@ -0,0 +1,106 @@
|
||||
package kv
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
fieldparams "github.com/prysmaticlabs/prysm/v4/config/fieldparams"
|
||||
"github.com/prysmaticlabs/prysm/v4/config/params"
|
||||
validatorServiceConfig "github.com/prysmaticlabs/prysm/v4/config/validator/service"
|
||||
"github.com/prysmaticlabs/prysm/v4/consensus-types/validator"
|
||||
"github.com/prysmaticlabs/prysm/v4/encoding/bytesutil"
|
||||
"github.com/prysmaticlabs/prysm/v4/testing/require"
|
||||
)
|
||||
|
||||
func TestStore_ProposerSettings_ReadAndWrite(t *testing.T) {
|
||||
t.Run("save to db in full", func(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
db := setupDB(t, [][fieldparams.BLSPubkeyLength]byte{})
|
||||
key1, err := hexutil.Decode("0xa057816155ad77931185101128655c0191bd0214c201ca48ed887f6c4c6adf334070efcd75140eada5ac83a92506dd7a")
|
||||
require.NoError(t, err)
|
||||
settings := &validatorServiceConfig.ProposerSettings{
|
||||
ProposeConfig: map[[fieldparams.BLSPubkeyLength]byte]*validatorServiceConfig.ProposerOption{
|
||||
bytesutil.ToBytes48(key1): {
|
||||
FeeRecipientConfig: &validatorServiceConfig.FeeRecipientConfig{
|
||||
FeeRecipient: common.HexToAddress("0x50155530FCE8a85ec7055A5F8b2bE214B3DaeFd3"),
|
||||
},
|
||||
BuilderConfig: &validatorServiceConfig.BuilderConfig{
|
||||
Enabled: true,
|
||||
GasLimit: validator.Uint64(40000000),
|
||||
},
|
||||
},
|
||||
},
|
||||
DefaultConfig: &validatorServiceConfig.ProposerOption{
|
||||
FeeRecipientConfig: &validatorServiceConfig.FeeRecipientConfig{
|
||||
FeeRecipient: common.HexToAddress("0x6e35733c5af9B61374A128e6F85f553aF09ff89A"),
|
||||
},
|
||||
BuilderConfig: &validatorServiceConfig.BuilderConfig{
|
||||
Enabled: false,
|
||||
GasLimit: validator.Uint64(params.BeaconConfig().DefaultBuilderGasLimit),
|
||||
},
|
||||
},
|
||||
}
|
||||
err = db.SaveProposerSettings(ctx, settings)
|
||||
require.NoError(t, err)
|
||||
|
||||
dbSettings, err := db.ProposerSettings(ctx)
|
||||
require.NoError(t, err)
|
||||
require.DeepEqual(t, settings, dbSettings)
|
||||
})
|
||||
t.Run("update default settings then update at specific key", func(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
db := setupDB(t, [][fieldparams.BLSPubkeyLength]byte{})
|
||||
key1, err := hexutil.Decode("0xa057816155ad77931185101128655c0191bd0214c201ca48ed887f6c4c6adf334070efcd75140eada5ac83a92506dd7a")
|
||||
require.NoError(t, err)
|
||||
settings := &validatorServiceConfig.ProposerSettings{
|
||||
DefaultConfig: &validatorServiceConfig.ProposerOption{
|
||||
FeeRecipientConfig: &validatorServiceConfig.FeeRecipientConfig{
|
||||
FeeRecipient: common.HexToAddress("0x6e35733c5af9B61374A128e6F85f553aF09ff89A"),
|
||||
},
|
||||
BuilderConfig: &validatorServiceConfig.BuilderConfig{
|
||||
Enabled: false,
|
||||
GasLimit: validator.Uint64(params.BeaconConfig().DefaultBuilderGasLimit),
|
||||
},
|
||||
},
|
||||
}
|
||||
err = db.SaveProposerSettings(ctx, settings)
|
||||
require.NoError(t, err)
|
||||
upatedDefault := &validatorServiceConfig.ProposerOption{
|
||||
FeeRecipientConfig: &validatorServiceConfig.FeeRecipientConfig{
|
||||
FeeRecipient: common.HexToAddress("0x9995733c5af9B61374A128e6F85f553aF09ff89B"),
|
||||
},
|
||||
BuilderConfig: &validatorServiceConfig.BuilderConfig{
|
||||
Enabled: true,
|
||||
GasLimit: validator.Uint64(params.BeaconConfig().DefaultBuilderGasLimit),
|
||||
},
|
||||
}
|
||||
err = db.UpdateProposerSettingsDefault(ctx, upatedDefault)
|
||||
require.NoError(t, err)
|
||||
|
||||
dbSettings, err := db.ProposerSettings(ctx)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, dbSettings)
|
||||
require.DeepEqual(t, dbSettings.DefaultConfig, upatedDefault)
|
||||
option := &validatorServiceConfig.ProposerOption{
|
||||
FeeRecipientConfig: &validatorServiceConfig.FeeRecipientConfig{
|
||||
FeeRecipient: common.HexToAddress("0x50155530FCE8a85ec7055A5F8b2bE214B3DaeFd3"),
|
||||
},
|
||||
BuilderConfig: &validatorServiceConfig.BuilderConfig{
|
||||
Enabled: true,
|
||||
GasLimit: validator.Uint64(40000000),
|
||||
},
|
||||
}
|
||||
err = db.UpdateProposerSettingsForPubkey(ctx, bytesutil.ToBytes48(key1), option)
|
||||
require.NoError(t, err)
|
||||
|
||||
newSettings, err := db.ProposerSettings(ctx)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, newSettings)
|
||||
require.DeepEqual(t, newSettings.DefaultConfig, upatedDefault)
|
||||
op, ok := newSettings.ProposeConfig[bytesutil.ToBytes48(key1)]
|
||||
require.Equal(t, ok, true)
|
||||
require.DeepEqual(t, op, option)
|
||||
})
|
||||
}
|
||||
@@ -37,4 +37,8 @@ var (
|
||||
// Graffiti ordered index and hash keys
|
||||
graffitiOrderedIndexKey = []byte("graffiti-ordered-index")
|
||||
graffitiFileHashKey = []byte("graffiti-file-hash")
|
||||
|
||||
// ProposerSettings stores the encoded proposer settings file
|
||||
proposerSettingsBucket = []byte("proposer-settings-bucket")
|
||||
proposerSettingsKey = []byte("proposer-settings")
|
||||
)
|
||||
|
||||
@@ -11,10 +11,12 @@ go_test(
|
||||
"//config/fieldparams:go_default_library",
|
||||
"//config/params:go_default_library",
|
||||
"//config/validator/service:go_default_library",
|
||||
"//consensus-types/validator:go_default_library",
|
||||
"//encoding/bytesutil:go_default_library",
|
||||
"//testing/assert:go_default_library",
|
||||
"//testing/require:go_default_library",
|
||||
"//validator/accounts:go_default_library",
|
||||
"//validator/db/testing:go_default_library",
|
||||
"//validator/keymanager:go_default_library",
|
||||
"//validator/keymanager/remote-web3signer:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//common:go_default_library",
|
||||
@@ -45,6 +47,7 @@ go_library(
|
||||
"//config/fieldparams:go_default_library",
|
||||
"//config/params:go_default_library",
|
||||
"//config/validator/service:go_default_library",
|
||||
"//consensus-types/validator:go_default_library",
|
||||
"//container/slice:go_default_library",
|
||||
"//encoding/bytesutil:go_default_library",
|
||||
"//io/file:go_default_library",
|
||||
@@ -60,6 +63,7 @@ go_library(
|
||||
"//runtime/version:go_default_library",
|
||||
"//validator/accounts/wallet:go_default_library",
|
||||
"//validator/client:go_default_library",
|
||||
"//validator/db/iface:go_default_library",
|
||||
"//validator/db/kv:go_default_library",
|
||||
"//validator/graffiti:go_default_library",
|
||||
"//validator/keymanager/local:go_default_library",
|
||||
@@ -75,7 +79,7 @@ go_library(
|
||||
"@com_github_prysmaticlabs_fastssz//:go_default_library",
|
||||
"@com_github_sirupsen_logrus//:go_default_library",
|
||||
"@com_github_urfave_cli_v2//:go_default_library",
|
||||
"@in_gopkg_yaml_v2//:go_default_library",
|
||||
"@io_k8s_apimachinery//pkg/util/yaml:go_default_library",
|
||||
"@org_golang_google_protobuf//encoding/protojson:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -35,6 +35,7 @@ import (
|
||||
fieldparams "github.com/prysmaticlabs/prysm/v4/config/fieldparams"
|
||||
"github.com/prysmaticlabs/prysm/v4/config/params"
|
||||
validatorServiceConfig "github.com/prysmaticlabs/prysm/v4/config/validator/service"
|
||||
"github.com/prysmaticlabs/prysm/v4/consensus-types/validator"
|
||||
"github.com/prysmaticlabs/prysm/v4/container/slice"
|
||||
"github.com/prysmaticlabs/prysm/v4/encoding/bytesutil"
|
||||
"github.com/prysmaticlabs/prysm/v4/io/file"
|
||||
@@ -50,6 +51,7 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/v4/runtime/version"
|
||||
"github.com/prysmaticlabs/prysm/v4/validator/accounts/wallet"
|
||||
"github.com/prysmaticlabs/prysm/v4/validator/client"
|
||||
"github.com/prysmaticlabs/prysm/v4/validator/db/iface"
|
||||
"github.com/prysmaticlabs/prysm/v4/validator/db/kv"
|
||||
g "github.com/prysmaticlabs/prysm/v4/validator/graffiti"
|
||||
"github.com/prysmaticlabs/prysm/v4/validator/keymanager/local"
|
||||
@@ -60,7 +62,7 @@ import (
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/urfave/cli/v2"
|
||||
"google.golang.org/protobuf/encoding/protojson"
|
||||
"gopkg.in/yaml.v2"
|
||||
"k8s.io/apimachinery/pkg/util/yaml"
|
||||
)
|
||||
|
||||
// ValidatorClient defines an instance of an Ethereum validator that manages
|
||||
@@ -406,7 +408,7 @@ func (c *ValidatorClient) registerValidatorService(cliCtx *cli.Context) error {
|
||||
return err
|
||||
}
|
||||
|
||||
bpc, err := proposerSettings(c.cliCtx)
|
||||
bpc, err := proposerSettings(c.cliCtx, c.db)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -488,8 +490,8 @@ func Web3SignerConfig(cliCtx *cli.Context) (*remoteweb3signer.SetupConfig, error
|
||||
return web3signerConfig, nil
|
||||
}
|
||||
|
||||
func proposerSettings(cliCtx *cli.Context) (*validatorServiceConfig.ProposerSettings, error) {
|
||||
var fileConfig *validatorServiceConfig.ProposerSettingsPayload
|
||||
func proposerSettings(cliCtx *cli.Context, db iface.ValidatorDB) (*validatorServiceConfig.ProposerSettings, error) {
|
||||
var fileConfig *validatorpb.ProposerSettingsPayload
|
||||
|
||||
if cliCtx.IsSet(flags.ProposerSettingsFlag.Name) && cliCtx.IsSet(flags.ProposerSettingsURLFlag.Name) {
|
||||
return nil, errors.New("cannot specify both " + flags.ProposerSettingsFlag.Name + " and " + flags.ProposerSettingsURLFlag.Name)
|
||||
@@ -504,11 +506,11 @@ func proposerSettings(cliCtx *cli.Context) (*validatorServiceConfig.ProposerSett
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fileConfig = &validatorServiceConfig.ProposerSettingsPayload{
|
||||
fileConfig = &validatorpb.ProposerSettingsPayload{
|
||||
ProposerConfig: nil,
|
||||
DefaultConfig: &validatorServiceConfig.ProposerOptionPayload{
|
||||
FeeRecipient: suggestedFee,
|
||||
BuilderConfig: builderConfig,
|
||||
DefaultConfig: &validatorpb.ProposerOptionPayload{
|
||||
FeeRecipient: suggestedFee,
|
||||
Builder: builderConfig.ToPayload(),
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -541,7 +543,10 @@ func proposerSettings(cliCtx *cli.Context) (*validatorServiceConfig.ProposerSett
|
||||
if !common.IsHexAddress(fileConfig.DefaultConfig.FeeRecipient) {
|
||||
return nil, errors.New("default fileConfig fee recipient is not a valid eth1 address")
|
||||
}
|
||||
|
||||
psExists, err := db.ProposerSettingsExists(cliCtx.Context)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := warnNonChecksummedAddress(fileConfig.DefaultConfig.FeeRecipient); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -549,7 +554,7 @@ func proposerSettings(cliCtx *cli.Context) (*validatorServiceConfig.ProposerSett
|
||||
FeeRecipientConfig: &validatorServiceConfig.FeeRecipientConfig{
|
||||
FeeRecipient: common.HexToAddress(fileConfig.DefaultConfig.FeeRecipient),
|
||||
},
|
||||
BuilderConfig: fileConfig.DefaultConfig.BuilderConfig,
|
||||
BuilderConfig: validatorServiceConfig.ToBuilderConfig(fileConfig.DefaultConfig.Builder),
|
||||
}
|
||||
if vpSettings.DefaultConfig.BuilderConfig == nil {
|
||||
builderConfig, err := BuilderSettingsFromFlags(cliCtx)
|
||||
@@ -563,6 +568,13 @@ func proposerSettings(cliCtx *cli.Context) (*validatorServiceConfig.ProposerSett
|
||||
vpSettings.DefaultConfig.BuilderConfig.GasLimit = reviewGasLimit(vpSettings.DefaultConfig.BuilderConfig.GasLimit)
|
||||
}
|
||||
|
||||
if psExists {
|
||||
// if settings exist update the default
|
||||
if err := db.UpdateProposerSettingsDefault(cliCtx.Context, vpSettings.DefaultConfig); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if fileConfig.ProposerConfig != nil {
|
||||
vpSettings.ProposeConfig = make(map[[fieldparams.BLSPubkeyLength]byte]*validatorServiceConfig.ProposerOption)
|
||||
for key, option := range fileConfig.ProposerConfig {
|
||||
@@ -582,30 +594,43 @@ func proposerSettings(cliCtx *cli.Context) (*validatorServiceConfig.ProposerSett
|
||||
if err := warnNonChecksummedAddress(option.FeeRecipient); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if option.BuilderConfig != nil {
|
||||
option.BuilderConfig.GasLimit = reviewGasLimit(option.BuilderConfig.GasLimit)
|
||||
if option.Builder != nil {
|
||||
option.Builder.GasLimit = reviewGasLimit(option.Builder.GasLimit)
|
||||
} else {
|
||||
builderConfig, err := BuilderSettingsFromFlags(cliCtx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
option.BuilderConfig = builderConfig
|
||||
option.Builder = builderConfig.ToPayload()
|
||||
}
|
||||
vpSettings.ProposeConfig[bytesutil.ToBytes48(decodedKey)] = &validatorServiceConfig.ProposerOption{
|
||||
o := &validatorServiceConfig.ProposerOption{
|
||||
FeeRecipientConfig: &validatorServiceConfig.FeeRecipientConfig{
|
||||
FeeRecipient: common.HexToAddress(option.FeeRecipient),
|
||||
},
|
||||
BuilderConfig: option.BuilderConfig,
|
||||
BuilderConfig: validatorServiceConfig.ToBuilderConfig(option.Builder),
|
||||
}
|
||||
pubkeyB := bytesutil.ToBytes48(decodedKey)
|
||||
vpSettings.ProposeConfig[pubkeyB] = o
|
||||
}
|
||||
if psExists {
|
||||
// override the existing saved settings if providing values via fileConfig.ProposerConfig
|
||||
if err := db.SaveProposerSettings(cliCtx.Context, vpSettings); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !psExists {
|
||||
// if no proposer settings ever existed in the db just save the settings
|
||||
if err := db.SaveProposerSettings(cliCtx.Context, vpSettings); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return vpSettings, nil
|
||||
}
|
||||
|
||||
func BuilderSettingsFromFlags(cliCtx *cli.Context) (*validatorServiceConfig.BuilderConfig, error) {
|
||||
if cliCtx.Bool(flags.EnableBuilderFlag.Name) {
|
||||
gasLimit := validatorServiceConfig.Uint64(params.BeaconConfig().DefaultBuilderGasLimit)
|
||||
gasLimit := validator.Uint64(params.BeaconConfig().DefaultBuilderGasLimit)
|
||||
sgl := cliCtx.String(flags.BuilderGasLimitFlag.Name)
|
||||
|
||||
if sgl != "" {
|
||||
@@ -613,7 +638,7 @@ func BuilderSettingsFromFlags(cliCtx *cli.Context) (*validatorServiceConfig.Buil
|
||||
if err != nil {
|
||||
return nil, errors.New("Gas Limit is not a uint64")
|
||||
}
|
||||
gasLimit = reviewGasLimit(validatorServiceConfig.Uint64(gl))
|
||||
gasLimit = reviewGasLimit(validator.Uint64(gl))
|
||||
}
|
||||
return &validatorServiceConfig.BuilderConfig{
|
||||
Enabled: true,
|
||||
@@ -637,10 +662,10 @@ func warnNonChecksummedAddress(feeRecipient string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func reviewGasLimit(gasLimit validatorServiceConfig.Uint64) validatorServiceConfig.Uint64 {
|
||||
func reviewGasLimit(gasLimit validator.Uint64) validator.Uint64 {
|
||||
// sets gas limit to default if not defined or set to 0
|
||||
if gasLimit == 0 {
|
||||
return validatorServiceConfig.Uint64(params.BeaconConfig().DefaultBuilderGasLimit)
|
||||
return validator.Uint64(params.BeaconConfig().DefaultBuilderGasLimit)
|
||||
}
|
||||
// TODO(10810): add in warning for ranges
|
||||
return gasLimit
|
||||
|
||||
@@ -16,10 +16,12 @@ import (
|
||||
fieldparams "github.com/prysmaticlabs/prysm/v4/config/fieldparams"
|
||||
"github.com/prysmaticlabs/prysm/v4/config/params"
|
||||
validatorserviceconfig "github.com/prysmaticlabs/prysm/v4/config/validator/service"
|
||||
"github.com/prysmaticlabs/prysm/v4/consensus-types/validator"
|
||||
"github.com/prysmaticlabs/prysm/v4/encoding/bytesutil"
|
||||
"github.com/prysmaticlabs/prysm/v4/testing/assert"
|
||||
"github.com/prysmaticlabs/prysm/v4/testing/require"
|
||||
"github.com/prysmaticlabs/prysm/v4/validator/accounts"
|
||||
dbTest "github.com/prysmaticlabs/prysm/v4/validator/db/testing"
|
||||
"github.com/prysmaticlabs/prysm/v4/validator/keymanager"
|
||||
remoteweb3signer "github.com/prysmaticlabs/prysm/v4/validator/keymanager/remote-web3signer"
|
||||
logtest "github.com/sirupsen/logrus/hooks/test"
|
||||
@@ -279,7 +281,7 @@ func TestProposerSettings(t *testing.T) {
|
||||
},
|
||||
BuilderConfig: &validatorserviceconfig.BuilderConfig{
|
||||
Enabled: true,
|
||||
GasLimit: validatorserviceconfig.Uint64(params.BeaconConfig().DefaultBuilderGasLimit),
|
||||
GasLimit: validator.Uint64(params.BeaconConfig().DefaultBuilderGasLimit),
|
||||
},
|
||||
},
|
||||
bytesutil.ToBytes48(key2): {
|
||||
@@ -288,7 +290,7 @@ func TestProposerSettings(t *testing.T) {
|
||||
},
|
||||
BuilderConfig: &validatorserviceconfig.BuilderConfig{
|
||||
Enabled: true,
|
||||
GasLimit: validatorserviceconfig.Uint64(35000000),
|
||||
GasLimit: validator.Uint64(35000000),
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -298,7 +300,7 @@ func TestProposerSettings(t *testing.T) {
|
||||
},
|
||||
BuilderConfig: &validatorserviceconfig.BuilderConfig{
|
||||
Enabled: true,
|
||||
GasLimit: validatorserviceconfig.Uint64(40000000),
|
||||
GasLimit: validator.Uint64(40000000),
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -364,7 +366,7 @@ func TestProposerSettings(t *testing.T) {
|
||||
},
|
||||
BuilderConfig: &validatorserviceconfig.BuilderConfig{
|
||||
Enabled: false,
|
||||
GasLimit: validatorserviceconfig.Uint64(params.BeaconConfig().DefaultBuilderGasLimit),
|
||||
GasLimit: validator.Uint64(params.BeaconConfig().DefaultBuilderGasLimit),
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -410,7 +412,7 @@ func TestProposerSettings(t *testing.T) {
|
||||
},
|
||||
BuilderConfig: &validatorserviceconfig.BuilderConfig{
|
||||
Enabled: true,
|
||||
GasLimit: validatorserviceconfig.Uint64(params.BeaconConfig().DefaultBuilderGasLimit),
|
||||
GasLimit: validator.Uint64(params.BeaconConfig().DefaultBuilderGasLimit),
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -494,7 +496,7 @@ func TestProposerSettings(t *testing.T) {
|
||||
},
|
||||
BuilderConfig: &validatorserviceconfig.BuilderConfig{
|
||||
Enabled: true,
|
||||
GasLimit: validatorserviceconfig.Uint64(params.BeaconConfig().DefaultBuilderGasLimit),
|
||||
GasLimit: validator.Uint64(params.BeaconConfig().DefaultBuilderGasLimit),
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -504,7 +506,7 @@ func TestProposerSettings(t *testing.T) {
|
||||
},
|
||||
BuilderConfig: &validatorserviceconfig.BuilderConfig{
|
||||
Enabled: true,
|
||||
GasLimit: validatorserviceconfig.Uint64(params.BeaconConfig().DefaultBuilderGasLimit),
|
||||
GasLimit: validator.Uint64(params.BeaconConfig().DefaultBuilderGasLimit),
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -532,7 +534,7 @@ func TestProposerSettings(t *testing.T) {
|
||||
},
|
||||
BuilderConfig: &validatorserviceconfig.BuilderConfig{
|
||||
Enabled: true,
|
||||
GasLimit: validatorserviceconfig.Uint64(params.BeaconConfig().DefaultBuilderGasLimit),
|
||||
GasLimit: validator.Uint64(params.BeaconConfig().DefaultBuilderGasLimit),
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -542,7 +544,7 @@ func TestProposerSettings(t *testing.T) {
|
||||
},
|
||||
BuilderConfig: &validatorserviceconfig.BuilderConfig{
|
||||
Enabled: true,
|
||||
GasLimit: validatorserviceconfig.Uint64(params.BeaconConfig().DefaultBuilderGasLimit),
|
||||
GasLimit: validator.Uint64(params.BeaconConfig().DefaultBuilderGasLimit),
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -569,7 +571,7 @@ func TestProposerSettings(t *testing.T) {
|
||||
},
|
||||
BuilderConfig: &validatorserviceconfig.BuilderConfig{
|
||||
Enabled: true,
|
||||
GasLimit: validatorserviceconfig.Uint64(40000000),
|
||||
GasLimit: validator.Uint64(40000000),
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -579,7 +581,7 @@ func TestProposerSettings(t *testing.T) {
|
||||
},
|
||||
BuilderConfig: &validatorserviceconfig.BuilderConfig{
|
||||
Enabled: false,
|
||||
GasLimit: validatorserviceconfig.Uint64(params.BeaconConfig().DefaultBuilderGasLimit),
|
||||
GasLimit: validator.Uint64(params.BeaconConfig().DefaultBuilderGasLimit),
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -677,7 +679,8 @@ func TestProposerSettings(t *testing.T) {
|
||||
set.Bool(flags.EnableBuilderFlag.Name, true, "")
|
||||
}
|
||||
cliCtx := cli.NewContext(&app, set, nil)
|
||||
got, err := proposerSettings(cliCtx)
|
||||
validatorDB := dbTest.SetupDB(t, [][fieldparams.BLSPubkeyLength]byte{})
|
||||
got, err := proposerSettings(cliCtx, validatorDB)
|
||||
if tt.wantErr != "" {
|
||||
require.ErrorContains(t, tt.wantErr, err)
|
||||
return
|
||||
@@ -695,10 +698,11 @@ func TestProposerSettings(t *testing.T) {
|
||||
|
||||
// return an error if the user is using builder settings without any default fee recipient
|
||||
func TestProposerSettings_EnableBuilder_noFeeRecipient(t *testing.T) {
|
||||
validatorDB := dbTest.SetupDB(t, [][fieldparams.BLSPubkeyLength]byte{})
|
||||
app := cli.App{}
|
||||
set := flag.NewFlagSet("test", 0)
|
||||
set.Bool(flags.EnableBuilderFlag.Name, true, "")
|
||||
cliCtx := cli.NewContext(&app, set, nil)
|
||||
_, err := proposerSettings(cliCtx)
|
||||
_, err := proposerSettings(cliCtx, validatorDB)
|
||||
require.ErrorContains(t, "can only be used when a default fee recipient is present on the validator client", err)
|
||||
}
|
||||
|
||||
3
validator/node/testdata/someotherfile.json
vendored
Normal file
3
validator/node/testdata/someotherfile.json
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"test": "123441"
|
||||
}
|
||||
@@ -28,6 +28,7 @@ go_library(
|
||||
"//config/fieldparams:go_default_library",
|
||||
"//config/params:go_default_library",
|
||||
"//config/validator/service:go_default_library",
|
||||
"//consensus-types/validator:go_default_library",
|
||||
"//crypto/bls:go_default_library",
|
||||
"//crypto/rand:go_default_library",
|
||||
"//encoding/bytesutil:go_default_library",
|
||||
@@ -101,6 +102,7 @@ go_test(
|
||||
"//config/fieldparams:go_default_library",
|
||||
"//config/params:go_default_library",
|
||||
"//config/validator/service:go_default_library",
|
||||
"//consensus-types/validator:go_default_library",
|
||||
"//crypto/bls:go_default_library",
|
||||
"//crypto/rand:go_default_library",
|
||||
"//encoding/bytesutil:go_default_library",
|
||||
@@ -117,6 +119,7 @@ go_test(
|
||||
"//validator/accounts/wallet:go_default_library",
|
||||
"//validator/client:go_default_library",
|
||||
"//validator/db/kv:go_default_library",
|
||||
"//validator/db/testing:go_default_library",
|
||||
"//validator/keymanager:go_default_library",
|
||||
"//validator/keymanager/derived:go_default_library",
|
||||
"//validator/keymanager/remote-web3signer:go_default_library",
|
||||
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
fieldparams "github.com/prysmaticlabs/prysm/v4/config/fieldparams"
|
||||
"github.com/prysmaticlabs/prysm/v4/config/params"
|
||||
validatorServiceConfig "github.com/prysmaticlabs/prysm/v4/config/validator/service"
|
||||
"github.com/prysmaticlabs/prysm/v4/consensus-types/validator"
|
||||
"github.com/prysmaticlabs/prysm/v4/encoding/bytesutil"
|
||||
ethpbservice "github.com/prysmaticlabs/prysm/v4/proto/eth/service"
|
||||
eth "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
|
||||
@@ -403,14 +404,15 @@ func (s *Server) GetGasLimit(_ context.Context, req *ethpbservice.PubkeyRequest)
|
||||
Pubkey: validatorKey,
|
||||
},
|
||||
}
|
||||
if s.validatorService.ProposerSettings() != nil {
|
||||
proposerOption, found := s.validatorService.ProposerSettings().ProposeConfig[bytesutil.ToBytes48(validatorKey)]
|
||||
settings := s.validatorService.ProposerSettings()
|
||||
if settings != nil {
|
||||
proposerOption, found := settings.ProposeConfig[bytesutil.ToBytes48(validatorKey)]
|
||||
if found {
|
||||
if proposerOption.BuilderConfig != nil {
|
||||
resp.Data.GasLimit = uint64(proposerOption.BuilderConfig.GasLimit)
|
||||
return resp, nil
|
||||
}
|
||||
} else if s.validatorService.ProposerSettings().DefaultConfig != nil && s.validatorService.ProposerSettings().DefaultConfig.BuilderConfig != nil {
|
||||
} else if settings.DefaultConfig != nil && settings.DefaultConfig.BuilderConfig != nil {
|
||||
resp.Data.GasLimit = uint64(s.validatorService.ProposerSettings().DefaultConfig.BuilderConfig.GasLimit)
|
||||
return resp, nil
|
||||
}
|
||||
@@ -424,63 +426,43 @@ func (s *Server) SetGasLimit(ctx context.Context, req *ethpbservice.SetGasLimitR
|
||||
if s.validatorService == nil {
|
||||
return nil, status.Error(codes.FailedPrecondition, "Validator service not ready")
|
||||
}
|
||||
|
||||
validatorKey := req.Pubkey
|
||||
|
||||
if err := validatePublicKey(validatorKey); err != nil {
|
||||
return nil, status.Error(codes.FailedPrecondition, err.Error())
|
||||
}
|
||||
|
||||
var pBuilderConfig *validatorServiceConfig.BuilderConfig
|
||||
|
||||
if s.validatorService.ProposerSettings() != nil &&
|
||||
s.validatorService.ProposerSettings().DefaultConfig != nil &&
|
||||
s.validatorService.ProposerSettings().DefaultConfig.BuilderConfig != nil {
|
||||
// Make a copy of BuilderConfig from DefaultConfig (thus "*" then "&"), so when we change GasLimit, we do not mess up with
|
||||
// "DefaultConfig.BuilderConfig".
|
||||
bo := *s.validatorService.ProposerSettings().DefaultConfig.BuilderConfig
|
||||
pBuilderConfig = &bo
|
||||
pBuilderConfig.GasLimit = validatorServiceConfig.Uint64(req.GasLimit)
|
||||
} else {
|
||||
// No default BuilderConfig to copy from, just create one and set "GasLimit", but keep "Enabled" to "false".
|
||||
pBuilderConfig = &validatorServiceConfig.BuilderConfig{
|
||||
Enabled: false,
|
||||
GasLimit: validatorServiceConfig.Uint64(req.GasLimit),
|
||||
Relays: []string{},
|
||||
settings := s.validatorService.ProposerSettings()
|
||||
if settings == nil {
|
||||
return &empty.Empty{}, status.Errorf(codes.FailedPrecondition, "no proposer settings were found to update")
|
||||
} else if settings.ProposeConfig == nil {
|
||||
if settings.DefaultConfig == nil || settings.DefaultConfig.BuilderConfig == nil || !settings.DefaultConfig.BuilderConfig.Enabled {
|
||||
return &empty.Empty{}, status.Errorf(codes.FailedPrecondition, "gas limit changes only apply when builder is enabled")
|
||||
}
|
||||
}
|
||||
|
||||
pOption := validatorServiceConfig.ProposerOption{
|
||||
FeeRecipientConfig: nil,
|
||||
BuilderConfig: pBuilderConfig,
|
||||
}
|
||||
|
||||
if s.validatorService.ProposerSettings() == nil {
|
||||
s.validatorService.SetProposerSettings(&validatorServiceConfig.ProposerSettings{
|
||||
ProposeConfig: map[[fieldparams.BLSPubkeyLength]byte]*validatorServiceConfig.ProposerOption{
|
||||
bytesutil.ToBytes48(validatorKey): &pOption,
|
||||
},
|
||||
DefaultConfig: nil,
|
||||
})
|
||||
} else if s.validatorService.ProposerSettings().ProposeConfig == nil {
|
||||
settings := s.validatorService.ProposerSettings()
|
||||
settings.ProposeConfig = make(map[[fieldparams.BLSPubkeyLength]byte]*validatorServiceConfig.ProposerOption)
|
||||
settings.ProposeConfig[bytesutil.ToBytes48(validatorKey)] = &pOption
|
||||
s.validatorService.SetProposerSettings(settings)
|
||||
option := settings.DefaultConfig.Clone()
|
||||
option.BuilderConfig.GasLimit = validator.Uint64(req.GasLimit)
|
||||
settings.ProposeConfig[bytesutil.ToBytes48(validatorKey)] = option
|
||||
} else {
|
||||
proposerOption, found := s.validatorService.ProposerSettings().ProposeConfig[bytesutil.ToBytes48(validatorKey)]
|
||||
|
||||
proposerOption, found := settings.ProposeConfig[bytesutil.ToBytes48(validatorKey)]
|
||||
if found {
|
||||
if proposerOption.BuilderConfig == nil {
|
||||
proposerOption.BuilderConfig = pBuilderConfig
|
||||
if proposerOption.BuilderConfig == nil || !proposerOption.BuilderConfig.Enabled {
|
||||
return &empty.Empty{}, status.Errorf(codes.FailedPrecondition, "gas limit changes only apply when builder is enabled")
|
||||
} else {
|
||||
proposerOption.BuilderConfig.GasLimit = validatorServiceConfig.Uint64(req.GasLimit)
|
||||
proposerOption.BuilderConfig.GasLimit = validator.Uint64(req.GasLimit)
|
||||
}
|
||||
} else {
|
||||
s.validatorService.ProposerSettings().ProposeConfig[bytesutil.ToBytes48(validatorKey)] = &pOption
|
||||
if settings.DefaultConfig == nil {
|
||||
return &empty.Empty{}, status.Errorf(codes.FailedPrecondition, "gas limit changes only apply when builder is enabled")
|
||||
}
|
||||
option := settings.DefaultConfig.Clone()
|
||||
option.BuilderConfig.GasLimit = validator.Uint64(req.GasLimit)
|
||||
settings.ProposeConfig[bytesutil.ToBytes48(validatorKey)] = option
|
||||
}
|
||||
}
|
||||
|
||||
// save the settings
|
||||
if err := s.validatorService.SetProposerSettings(ctx, settings); err != nil {
|
||||
return &empty.Empty{}, status.Errorf(codes.Internal, "Could not set proposer settings: %v", err)
|
||||
}
|
||||
// override the 200 success with 202 according to the specs
|
||||
if err := grpc.SetHeader(ctx, metadata.Pairs("x-http-code", "202")); err != nil {
|
||||
return &empty.Empty{}, status.Errorf(codes.Internal, "Could not set custom success code header: %v", err)
|
||||
@@ -507,7 +489,11 @@ func (s *Server) DeleteGasLimit(ctx context.Context, req *ethpbservice.DeleteGas
|
||||
proposerOption.BuilderConfig.GasLimit = proposerSettings.DefaultConfig.BuilderConfig.GasLimit
|
||||
} else {
|
||||
// Fallback to using global default.
|
||||
proposerOption.BuilderConfig.GasLimit = validatorServiceConfig.Uint64(params.BeaconConfig().DefaultBuilderGasLimit)
|
||||
proposerOption.BuilderConfig.GasLimit = validator.Uint64(params.BeaconConfig().DefaultBuilderGasLimit)
|
||||
}
|
||||
// save the settings
|
||||
if err := s.validatorService.SetProposerSettings(ctx, proposerSettings); err != nil {
|
||||
return &empty.Empty{}, status.Errorf(codes.Internal, "Could not set proposer settings: %v", err)
|
||||
}
|
||||
// Successfully deleted gas limit (reset to proposer config default or global default).
|
||||
// Return with success http code "204".
|
||||
@@ -553,11 +539,11 @@ func (s *Server) ListFeeRecipientByPubkey(ctx context.Context, req *ethpbservice
|
||||
|
||||
// If fee recipient is defined in default configuration, use it
|
||||
if proposerSettings != nil && proposerSettings.DefaultConfig != nil && proposerSettings.DefaultConfig.FeeRecipientConfig != nil {
|
||||
finalResp.Data.Ethaddress = s.validatorService.ProposerSettings().DefaultConfig.FeeRecipientConfig.FeeRecipient.Bytes()
|
||||
finalResp.Data.Ethaddress = proposerSettings.DefaultConfig.FeeRecipientConfig.FeeRecipient.Bytes()
|
||||
return finalResp, nil
|
||||
}
|
||||
|
||||
// Else, use the one defined in beacon node
|
||||
// Else, use the one defined in beacon node TODO: remove this with db removal
|
||||
resp, err := s.beaconNodeValidatorClient.GetFeeRecipientByPubKey(ctx, ð.FeeRecipientByPubKeyRequest{
|
||||
PublicKey: validatorKey,
|
||||
})
|
||||
@@ -593,10 +579,10 @@ func (s *Server) SetFeeRecipientByPubkey(ctx context.Context, req *ethpbservice.
|
||||
return nil, status.Error(
|
||||
codes.InvalidArgument, "Fee recipient is not a valid Ethereum address")
|
||||
}
|
||||
|
||||
settings := s.validatorService.ProposerSettings()
|
||||
switch {
|
||||
case s.validatorService.ProposerSettings() == nil:
|
||||
s.validatorService.SetProposerSettings(&validatorServiceConfig.ProposerSettings{
|
||||
case settings == nil:
|
||||
settings = &validatorServiceConfig.ProposerSettings{
|
||||
ProposeConfig: map[[fieldparams.BLSPubkeyLength]byte]*validatorServiceConfig.ProposerOption{
|
||||
bytesutil.ToBytes48(validatorKey): {
|
||||
FeeRecipientConfig: &validatorServiceConfig.FeeRecipientConfig{
|
||||
@@ -606,15 +592,12 @@ func (s *Server) SetFeeRecipientByPubkey(ctx context.Context, req *ethpbservice.
|
||||
},
|
||||
},
|
||||
DefaultConfig: nil,
|
||||
})
|
||||
case s.validatorService.ProposerSettings().ProposeConfig == nil:
|
||||
builderConfig := &validatorServiceConfig.BuilderConfig{}
|
||||
settings := s.validatorService.ProposerSettings()
|
||||
|
||||
if settings.DefaultConfig != nil {
|
||||
builderConfig = settings.DefaultConfig.BuilderConfig
|
||||
}
|
||||
|
||||
case settings.ProposeConfig == nil:
|
||||
var builderConfig *validatorServiceConfig.BuilderConfig
|
||||
if settings.DefaultConfig != nil {
|
||||
builderConfig = settings.DefaultConfig.BuilderConfig.Clone()
|
||||
}
|
||||
settings.ProposeConfig = map[[fieldparams.BLSPubkeyLength]byte]*validatorServiceConfig.ProposerOption{
|
||||
bytesutil.ToBytes48(validatorKey): {
|
||||
FeeRecipientConfig: &validatorServiceConfig.FeeRecipientConfig{
|
||||
@@ -623,34 +606,29 @@ func (s *Server) SetFeeRecipientByPubkey(ctx context.Context, req *ethpbservice.
|
||||
BuilderConfig: builderConfig,
|
||||
},
|
||||
}
|
||||
|
||||
s.validatorService.SetProposerSettings(settings)
|
||||
default:
|
||||
proposerOption, found := s.validatorService.ProposerSettings().ProposeConfig[bytesutil.ToBytes48(validatorKey)]
|
||||
|
||||
proposerOption, found := settings.ProposeConfig[bytesutil.ToBytes48(validatorKey)]
|
||||
if found && proposerOption != nil {
|
||||
proposerOption.FeeRecipientConfig = &validatorServiceConfig.FeeRecipientConfig{
|
||||
FeeRecipient: feeRecipient,
|
||||
}
|
||||
} else {
|
||||
settings := s.validatorService.ProposerSettings()
|
||||
|
||||
var builderConfig = &validatorServiceConfig.BuilderConfig{}
|
||||
|
||||
if settings.DefaultConfig != nil {
|
||||
builderConfig = settings.DefaultConfig.BuilderConfig
|
||||
builderConfig = settings.DefaultConfig.BuilderConfig.Clone()
|
||||
}
|
||||
|
||||
settings.ProposeConfig[bytesutil.ToBytes48(validatorKey)] = &validatorServiceConfig.ProposerOption{
|
||||
FeeRecipientConfig: &validatorServiceConfig.FeeRecipientConfig{
|
||||
FeeRecipient: feeRecipient,
|
||||
},
|
||||
BuilderConfig: builderConfig,
|
||||
}
|
||||
|
||||
s.validatorService.SetProposerSettings(settings)
|
||||
}
|
||||
}
|
||||
// save the settings
|
||||
if err := s.validatorService.SetProposerSettings(ctx, settings); err != nil {
|
||||
return &empty.Empty{}, status.Errorf(codes.Internal, "Could not set proposer settings: %v", err)
|
||||
}
|
||||
// override the 200 success with 202 according to the specs
|
||||
if err := grpc.SetHeader(ctx, metadata.Pairs("x-http-code", "202")); err != nil {
|
||||
return &empty.Empty{}, status.Errorf(codes.Internal, "Could not set custom success code header: %v", err)
|
||||
@@ -679,6 +657,11 @@ func (s *Server) DeleteFeeRecipientByPubkey(ctx context.Context, req *ethpbservi
|
||||
}
|
||||
}
|
||||
|
||||
// save the settings
|
||||
if err := s.validatorService.SetProposerSettings(ctx, settings); err != nil {
|
||||
return &empty.Empty{}, status.Errorf(codes.Internal, "Could not set proposer settings: %v", err)
|
||||
}
|
||||
|
||||
// override the 200 success with 204 according to the specs
|
||||
if err := grpc.SetHeader(ctx, metadata.Pairs("x-http-code", "204")); err != nil {
|
||||
return &empty.Empty{}, status.Errorf(codes.Internal, "Could not set custom success code header: %v", err)
|
||||
|
||||
@@ -17,6 +17,7 @@ import (
|
||||
fieldparams "github.com/prysmaticlabs/prysm/v4/config/fieldparams"
|
||||
"github.com/prysmaticlabs/prysm/v4/config/params"
|
||||
validatorserviceconfig "github.com/prysmaticlabs/prysm/v4/config/validator/service"
|
||||
"github.com/prysmaticlabs/prysm/v4/consensus-types/validator"
|
||||
"github.com/prysmaticlabs/prysm/v4/crypto/bls"
|
||||
"github.com/prysmaticlabs/prysm/v4/encoding/bytesutil"
|
||||
ethpbservice "github.com/prysmaticlabs/prysm/v4/proto/eth/service"
|
||||
@@ -31,6 +32,7 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/v4/validator/accounts/wallet"
|
||||
"github.com/prysmaticlabs/prysm/v4/validator/client"
|
||||
"github.com/prysmaticlabs/prysm/v4/validator/db/kv"
|
||||
dbtest "github.com/prysmaticlabs/prysm/v4/validator/db/testing"
|
||||
"github.com/prysmaticlabs/prysm/v4/validator/keymanager"
|
||||
"github.com/prysmaticlabs/prysm/v4/validator/keymanager/derived"
|
||||
remoteweb3signer "github.com/prysmaticlabs/prysm/v4/validator/keymanager/remote-web3signer"
|
||||
@@ -998,15 +1000,18 @@ func TestServer_FeeRecipientByPubkey(t *testing.T) {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
m := &mock.MockValidator{}
|
||||
m.SetProposerSettings(tt.proposerSettings)
|
||||
validatorDB := dbtest.SetupDB(t, [][fieldparams.BLSPubkeyLength]byte{})
|
||||
|
||||
// save a default here
|
||||
vs, err := client.NewValidatorService(ctx, &client.Config{
|
||||
Validator: m,
|
||||
ValDB: validatorDB,
|
||||
})
|
||||
|
||||
require.NoError(t, err)
|
||||
s := &Server{
|
||||
validatorService: vs,
|
||||
beaconNodeValidatorClient: beaconClient,
|
||||
valDB: validatorDB,
|
||||
}
|
||||
|
||||
_, err = s.SetFeeRecipientByPubkey(ctx, ðpbservice.SetFeeRecipientByPubkeyRequest{Pubkey: byteval, Ethaddress: common.HexToAddress(tt.args).Bytes()})
|
||||
@@ -1097,12 +1102,15 @@ func TestServer_DeleteFeeRecipientByPubkey(t *testing.T) {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
m := &mock.MockValidator{}
|
||||
m.SetProposerSettings(tt.proposerSettings)
|
||||
validatorDB := dbtest.SetupDB(t, [][fieldparams.BLSPubkeyLength]byte{})
|
||||
vs, err := client.NewValidatorService(ctx, &client.Config{
|
||||
Validator: m,
|
||||
ValDB: validatorDB,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
s := &Server{
|
||||
validatorService: vs,
|
||||
valDB: validatorDB,
|
||||
}
|
||||
_, err = s.DeleteFeeRecipientByPubkey(ctx, ðpbservice.PubkeyRequest{Pubkey: byteval})
|
||||
require.NoError(t, err)
|
||||
@@ -1207,7 +1215,6 @@ func TestServer_GetGasLimit(t *testing.T) {
|
||||
func TestServer_SetGasLimit(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
|
||||
beaconClient := validatormock.NewMockValidatorClient(ctrl)
|
||||
ctx := grpc.NewContextWithServerTransportStream(context.Background(), &runtime.ServerTransportStream{})
|
||||
|
||||
@@ -1231,20 +1238,16 @@ func TestServer_SetGasLimit(t *testing.T) {
|
||||
pubkey []byte
|
||||
newGasLimit uint64
|
||||
proposerSettings *validatorserviceconfig.ProposerSettings
|
||||
w []want
|
||||
w []*want
|
||||
beaconReturn *beaconResp
|
||||
wantErr string
|
||||
}{
|
||||
{
|
||||
name: "ProposerSettings is nil",
|
||||
pubkey: pubkey1,
|
||||
newGasLimit: 9999,
|
||||
proposerSettings: nil,
|
||||
w: []want{
|
||||
{
|
||||
pubkey: pubkey1,
|
||||
gaslimit: 9999,
|
||||
},
|
||||
},
|
||||
wantErr: "no proposer settings were found to update",
|
||||
},
|
||||
{
|
||||
name: "ProposerSettings.ProposeConfig is nil AND ProposerSettings.DefaultConfig is nil",
|
||||
@@ -1254,12 +1257,7 @@ func TestServer_SetGasLimit(t *testing.T) {
|
||||
ProposeConfig: nil,
|
||||
DefaultConfig: nil,
|
||||
},
|
||||
w: []want{
|
||||
{
|
||||
pubkey: pubkey1,
|
||||
gaslimit: 9999,
|
||||
},
|
||||
},
|
||||
wantErr: "gas limit changes only apply when builder is enabled",
|
||||
},
|
||||
{
|
||||
name: "ProposerSettings.ProposeConfig is nil AND ProposerSettings.DefaultConfig.BuilderConfig is nil",
|
||||
@@ -1271,12 +1269,7 @@ func TestServer_SetGasLimit(t *testing.T) {
|
||||
BuilderConfig: nil,
|
||||
},
|
||||
},
|
||||
w: []want{
|
||||
{
|
||||
pubkey: pubkey1,
|
||||
gaslimit: 9999,
|
||||
},
|
||||
},
|
||||
wantErr: "gas limit changes only apply when builder is enabled",
|
||||
},
|
||||
{
|
||||
name: "ProposerSettings.ProposeConfig is defined for pubkey, BuilderConfig is nil AND ProposerSettings.DefaultConfig is nil",
|
||||
@@ -1290,12 +1283,7 @@ func TestServer_SetGasLimit(t *testing.T) {
|
||||
},
|
||||
DefaultConfig: nil,
|
||||
},
|
||||
w: []want{
|
||||
{
|
||||
pubkey: pubkey1,
|
||||
gaslimit: 9999,
|
||||
},
|
||||
},
|
||||
wantErr: "gas limit changes only apply when builder is enabled",
|
||||
},
|
||||
{
|
||||
name: "ProposerSettings.ProposeConfig is defined for pubkey, BuilderConfig is defined AND ProposerSettings.DefaultConfig is nil",
|
||||
@@ -1309,12 +1297,7 @@ func TestServer_SetGasLimit(t *testing.T) {
|
||||
},
|
||||
DefaultConfig: nil,
|
||||
},
|
||||
w: []want{
|
||||
{
|
||||
pubkey: pubkey1,
|
||||
gaslimit: 9999,
|
||||
},
|
||||
},
|
||||
wantErr: "gas limit changes only apply when builder is enabled",
|
||||
},
|
||||
{
|
||||
name: "ProposerSettings.ProposeConfig is NOT defined for pubkey, BuilderConfig is defined AND ProposerSettings.DefaultConfig is nil",
|
||||
@@ -1322,23 +1305,19 @@ func TestServer_SetGasLimit(t *testing.T) {
|
||||
newGasLimit: 9999,
|
||||
proposerSettings: &validatorserviceconfig.ProposerSettings{
|
||||
ProposeConfig: map[[48]byte]*validatorserviceconfig.ProposerOption{
|
||||
bytesutil.ToBytes48(pubkey1): {
|
||||
bytesutil.ToBytes48(pubkey2): {
|
||||
BuilderConfig: &validatorserviceconfig.BuilderConfig{
|
||||
Enabled: true,
|
||||
GasLimit: 12345,
|
||||
},
|
||||
},
|
||||
},
|
||||
DefaultConfig: nil,
|
||||
},
|
||||
w: []want{
|
||||
{
|
||||
pubkey: pubkey1,
|
||||
gaslimit: 12345,
|
||||
},
|
||||
{
|
||||
pubkey: pubkey2,
|
||||
gaslimit: 9999,
|
||||
},
|
||||
w: []*want{{
|
||||
pubkey2,
|
||||
9999,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -1347,19 +1326,20 @@ func TestServer_SetGasLimit(t *testing.T) {
|
||||
newGasLimit: 9999,
|
||||
proposerSettings: &validatorserviceconfig.ProposerSettings{
|
||||
ProposeConfig: map[[48]byte]*validatorserviceconfig.ProposerOption{
|
||||
bytesutil.ToBytes48(pubkey1): {
|
||||
bytesutil.ToBytes48(pubkey2): {
|
||||
BuilderConfig: nil,
|
||||
},
|
||||
},
|
||||
DefaultConfig: &validatorserviceconfig.ProposerOption{
|
||||
BuilderConfig: &validatorserviceconfig.BuilderConfig{},
|
||||
BuilderConfig: &validatorserviceconfig.BuilderConfig{
|
||||
Enabled: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
w: []want{
|
||||
{
|
||||
pubkey: pubkey1,
|
||||
gaslimit: 9999,
|
||||
},
|
||||
w: []*want{{
|
||||
pubkey1,
|
||||
9999,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -1367,15 +1347,17 @@ func TestServer_SetGasLimit(t *testing.T) {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
m := &mock.MockValidator{}
|
||||
m.SetProposerSettings(tt.proposerSettings)
|
||||
|
||||
validatorDB := dbtest.SetupDB(t, [][fieldparams.BLSPubkeyLength]byte{})
|
||||
vs, err := client.NewValidatorService(ctx, &client.Config{
|
||||
Validator: m,
|
||||
ValDB: validatorDB,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
s := &Server{
|
||||
validatorService: vs,
|
||||
beaconNodeValidatorClient: beaconClient,
|
||||
valDB: validatorDB,
|
||||
}
|
||||
|
||||
if tt.beaconReturn != nil {
|
||||
@@ -1386,10 +1368,13 @@ func TestServer_SetGasLimit(t *testing.T) {
|
||||
}
|
||||
|
||||
_, err = s.SetGasLimit(ctx, ðpbservice.SetGasLimitRequest{Pubkey: tt.pubkey, GasLimit: tt.newGasLimit})
|
||||
require.NoError(t, err)
|
||||
|
||||
for _, w := range tt.w {
|
||||
assert.Equal(t, w.gaslimit, uint64(s.validatorService.ProposerSettings().ProposeConfig[bytesutil.ToBytes48(w.pubkey)].BuilderConfig.GasLimit))
|
||||
if tt.wantErr != "" {
|
||||
require.ErrorContains(t, tt.wantErr, err)
|
||||
} else {
|
||||
require.NoError(t, err)
|
||||
for _, w := range tt.w {
|
||||
assert.Equal(t, w.gaslimit, uint64(s.validatorService.ProposerSettings().ProposeConfig[bytesutil.ToBytes48(w.pubkey)].BuilderConfig.GasLimit))
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -1432,11 +1417,11 @@ func TestServer_DeleteGasLimit(t *testing.T) {
|
||||
params.BeaconConfig().DefaultBuilderGasLimit = originBeaconChainGasLimit
|
||||
}()
|
||||
|
||||
globalDefaultGasLimit := validatorserviceconfig.Uint64(0xbbdd)
|
||||
globalDefaultGasLimit := validator.Uint64(0xbbdd)
|
||||
|
||||
type want struct {
|
||||
pubkey []byte
|
||||
gaslimit validatorserviceconfig.Uint64
|
||||
gaslimit validator.Uint64
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
@@ -1452,14 +1437,14 @@ func TestServer_DeleteGasLimit(t *testing.T) {
|
||||
proposerSettings: &validatorserviceconfig.ProposerSettings{
|
||||
ProposeConfig: map[[48]byte]*validatorserviceconfig.ProposerOption{
|
||||
bytesutil.ToBytes48(pubkey1): {
|
||||
BuilderConfig: &validatorserviceconfig.BuilderConfig{GasLimit: validatorserviceconfig.Uint64(987654321)},
|
||||
BuilderConfig: &validatorserviceconfig.BuilderConfig{GasLimit: validator.Uint64(987654321)},
|
||||
},
|
||||
bytesutil.ToBytes48(pubkey2): {
|
||||
BuilderConfig: &validatorserviceconfig.BuilderConfig{GasLimit: validatorserviceconfig.Uint64(123456789)},
|
||||
BuilderConfig: &validatorserviceconfig.BuilderConfig{GasLimit: validator.Uint64(123456789)},
|
||||
},
|
||||
},
|
||||
DefaultConfig: &validatorserviceconfig.ProposerOption{
|
||||
BuilderConfig: &validatorserviceconfig.BuilderConfig{GasLimit: validatorserviceconfig.Uint64(5555)},
|
||||
BuilderConfig: &validatorserviceconfig.BuilderConfig{GasLimit: validator.Uint64(5555)},
|
||||
},
|
||||
},
|
||||
wantError: nil,
|
||||
@@ -1467,11 +1452,11 @@ func TestServer_DeleteGasLimit(t *testing.T) {
|
||||
{
|
||||
pubkey: pubkey1,
|
||||
// After deletion, use DefaultConfig.BuilderConfig.GasLimit.
|
||||
gaslimit: validatorserviceconfig.Uint64(5555),
|
||||
gaslimit: validator.Uint64(5555),
|
||||
},
|
||||
{
|
||||
pubkey: pubkey2,
|
||||
gaslimit: validatorserviceconfig.Uint64(123456789),
|
||||
gaslimit: validator.Uint64(123456789),
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -1481,10 +1466,10 @@ func TestServer_DeleteGasLimit(t *testing.T) {
|
||||
proposerSettings: &validatorserviceconfig.ProposerSettings{
|
||||
ProposeConfig: map[[48]byte]*validatorserviceconfig.ProposerOption{
|
||||
bytesutil.ToBytes48(pubkey1): {
|
||||
BuilderConfig: &validatorserviceconfig.BuilderConfig{GasLimit: validatorserviceconfig.Uint64(987654321)},
|
||||
BuilderConfig: &validatorserviceconfig.BuilderConfig{GasLimit: validator.Uint64(987654321)},
|
||||
},
|
||||
bytesutil.ToBytes48(pubkey2): {
|
||||
BuilderConfig: &validatorserviceconfig.BuilderConfig{GasLimit: validatorserviceconfig.Uint64(123456789)},
|
||||
BuilderConfig: &validatorserviceconfig.BuilderConfig{GasLimit: validator.Uint64(123456789)},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -1497,7 +1482,7 @@ func TestServer_DeleteGasLimit(t *testing.T) {
|
||||
},
|
||||
{
|
||||
pubkey: pubkey2,
|
||||
gaslimit: validatorserviceconfig.Uint64(123456789),
|
||||
gaslimit: validator.Uint64(123456789),
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -1507,7 +1492,7 @@ func TestServer_DeleteGasLimit(t *testing.T) {
|
||||
proposerSettings: &validatorserviceconfig.ProposerSettings{
|
||||
ProposeConfig: map[[48]byte]*validatorserviceconfig.ProposerOption{
|
||||
bytesutil.ToBytes48(pubkey1): {
|
||||
BuilderConfig: &validatorserviceconfig.BuilderConfig{GasLimit: validatorserviceconfig.Uint64(987654321)},
|
||||
BuilderConfig: &validatorserviceconfig.BuilderConfig{GasLimit: validator.Uint64(987654321)},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -1516,7 +1501,7 @@ func TestServer_DeleteGasLimit(t *testing.T) {
|
||||
// pubkey1's gaslimit is unaffected
|
||||
{
|
||||
pubkey: pubkey1,
|
||||
gaslimit: validatorserviceconfig.Uint64(987654321),
|
||||
gaslimit: validator.Uint64(987654321),
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -1531,12 +1516,15 @@ func TestServer_DeleteGasLimit(t *testing.T) {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
m := &mock.MockValidator{}
|
||||
m.SetProposerSettings(tt.proposerSettings)
|
||||
validatorDB := dbtest.SetupDB(t, [][fieldparams.BLSPubkeyLength]byte{})
|
||||
vs, err := client.NewValidatorService(ctx, &client.Config{
|
||||
Validator: m,
|
||||
ValDB: validatorDB,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
s := &Server{
|
||||
validatorService: vs,
|
||||
valDB: validatorDB,
|
||||
}
|
||||
// Set up global default value for builder gas limit.
|
||||
params.BeaconConfig().DefaultBuilderGasLimit = uint64(globalDefaultGasLimit)
|
||||
|
||||
Reference in New Issue
Block a user