mirror of
https://gitlab.com/pulsechaincom/prysm-pulse.git
synced 2024-12-25 04:47:18 +00:00
Save and Delete Validators Pubkey - Idx
Post Chainstart (#1873)
* starting tests * added tests * fixed comments * gaz * make sure key is using EntryExitEffectEpoch
This commit is contained in:
parent
9999b3280a
commit
dd40320a1c
@ -12,6 +12,7 @@ go_library(
|
||||
"//beacon-chain/core/blocks:go_default_library",
|
||||
"//beacon-chain/core/helpers:go_default_library",
|
||||
"//beacon-chain/core/state:go_default_library",
|
||||
"//beacon-chain/core/validators:go_default_library",
|
||||
"//beacon-chain/db:go_default_library",
|
||||
"//beacon-chain/powchain:go_default_library",
|
||||
"//proto/beacon/p2p/v1:go_default_library",
|
||||
@ -36,6 +37,7 @@ go_test(
|
||||
"//beacon-chain/core/blocks:go_default_library",
|
||||
"//beacon-chain/core/helpers:go_default_library",
|
||||
"//beacon-chain/core/state:go_default_library",
|
||||
"//beacon-chain/core/validators:go_default_library",
|
||||
"//beacon-chain/db:go_default_library",
|
||||
"//beacon-chain/internal:go_default_library",
|
||||
"//beacon-chain/powchain:go_default_library",
|
||||
|
@ -11,7 +11,9 @@ import (
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
gethTypes "github.com/ethereum/go-ethereum/core/types"
|
||||
b "github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/state"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/validators"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/db"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/powchain"
|
||||
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
||||
@ -347,6 +349,14 @@ func (c *ChainService) ReceiveBlock(block *pb.BeaconBlock, beaconState *pb.Beaco
|
||||
"slotsSinceGenesis", beaconState.Slot-params.BeaconConfig().GenesisSlot,
|
||||
).Info("Block transition successfully processed")
|
||||
if (beaconState.Slot+1)%params.BeaconConfig().SlotsPerEpoch == 0 {
|
||||
// Save activated validators of this epoch to public key -> index DB.
|
||||
if err := c.saveValidatorIdx(beaconState); err != nil {
|
||||
return nil, fmt.Errorf("could not save validator index: %v", err)
|
||||
}
|
||||
// Delete exited validators of this epoch to public key -> index DB.
|
||||
if err := c.deleteValidatorIdx(beaconState); err != nil {
|
||||
return nil, fmt.Errorf("could not delete validator index: %v", err)
|
||||
}
|
||||
log.WithField(
|
||||
"SlotsSinceGenesis", beaconState.Slot-params.BeaconConfig().GenesisSlot,
|
||||
).Info("Epoch transition successfully processed")
|
||||
@ -380,3 +390,31 @@ func (c *ChainService) isBlockReadyForProcessing(block *pb.BeaconBlock, beaconSt
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// saveValidatorIdx saves the validators public key to index mapping in DB, these
|
||||
// validators were activated from current epoch. After it saves, current epoch key
|
||||
// is deleted from ActivatedValidators mapping.
|
||||
func (c *ChainService) saveValidatorIdx(state *pb.BeaconState) error {
|
||||
for _, idx := range validators.ActivatedValidators[helpers.CurrentEpoch(state)] {
|
||||
pubKey := state.ValidatorRegistry[idx].Pubkey
|
||||
if err := c.beaconDB.SaveValidatorIndex(pubKey, int(idx)); err != nil {
|
||||
return fmt.Errorf("could not save validator index: %v", err)
|
||||
}
|
||||
}
|
||||
delete(validators.ActivatedValidators, helpers.CurrentEpoch(state))
|
||||
return nil
|
||||
}
|
||||
|
||||
// deleteValidatorIdx deletes the validators public key to index mapping in DB, the
|
||||
// validators were exited from current epoch. After it deletes, current epoch key
|
||||
// is deleted from ExitedValidators mapping.
|
||||
func (c *ChainService) deleteValidatorIdx(state *pb.BeaconState) error {
|
||||
for _, idx := range validators.ExitedValidators[helpers.CurrentEpoch(state)] {
|
||||
pubKey := state.ValidatorRegistry[idx].Pubkey
|
||||
if err := c.beaconDB.DeleteValidatorIndex(pubKey); err != nil {
|
||||
return fmt.Errorf("could not delete validator index: %v", err)
|
||||
}
|
||||
}
|
||||
delete(validators.ExitedValidators, helpers.CurrentEpoch(state))
|
||||
return nil
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ import (
|
||||
b "github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/state"
|
||||
v "github.com/prysmaticlabs/prysm/beacon-chain/core/validators"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/db"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/internal"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/powchain"
|
||||
@ -709,3 +710,83 @@ func TestIsBlockReadyForProcessing_ValidBlock(t *testing.T) {
|
||||
t.Fatalf("block processing failed despite being a valid block: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeleteValidatorIdx_DeleteWorks(t *testing.T) {
|
||||
db := internal.SetupDB(t)
|
||||
defer internal.TeardownDB(t, db)
|
||||
epoch := uint64(2)
|
||||
v.ActivatedValidators[epoch] = []uint64{0, 1, 2}
|
||||
v.ExitedValidators[epoch] = []uint64{0, 2}
|
||||
var validators []*pb.Validator
|
||||
for i := 0; i < 3; i++ {
|
||||
pubKeyBuf := make([]byte, params.BeaconConfig().BLSPubkeyLength)
|
||||
binary.PutUvarint(pubKeyBuf, uint64(i))
|
||||
validators = append(validators, &pb.Validator{
|
||||
Pubkey: pubKeyBuf,
|
||||
})
|
||||
}
|
||||
state := &pb.BeaconState{
|
||||
ValidatorRegistry: validators,
|
||||
Slot: epoch * params.BeaconConfig().SlotsPerEpoch,
|
||||
}
|
||||
chainService := setupBeaconChain(t, false, db, true)
|
||||
if err := chainService.saveValidatorIdx(state); err != nil {
|
||||
t.Fatalf("Could not save validator idx: %v", err)
|
||||
}
|
||||
if err := chainService.deleteValidatorIdx(state); err != nil {
|
||||
t.Fatalf("Could not delete validator idx: %v", err)
|
||||
}
|
||||
wantedIdx := uint64(1)
|
||||
idx, err := chainService.beaconDB.ValidatorIndex(validators[wantedIdx].Pubkey)
|
||||
if err != nil {
|
||||
t.Fatalf("Could not get validator index: %v", err)
|
||||
}
|
||||
if wantedIdx != idx {
|
||||
t.Errorf("Wanted: %d, got: %d", wantedIdx, idx)
|
||||
}
|
||||
|
||||
wantedIdx = uint64(2)
|
||||
if chainService.beaconDB.HasValidator(validators[wantedIdx].Pubkey) {
|
||||
t.Errorf("Validator index %d should have been deleted", wantedIdx)
|
||||
}
|
||||
|
||||
if _, ok := v.ExitedValidators[epoch]; ok {
|
||||
t.Errorf("Activated validators mapping for epoch %d still there", epoch)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSaveValidatorIdx_SaveRetrieveWorks(t *testing.T) {
|
||||
db := internal.SetupDB(t)
|
||||
defer internal.TeardownDB(t, db)
|
||||
epoch := uint64(1)
|
||||
v.ActivatedValidators[epoch] = []uint64{0, 1, 2}
|
||||
var validators []*pb.Validator
|
||||
for i := 0; i < 3; i++ {
|
||||
pubKeyBuf := make([]byte, params.BeaconConfig().BLSPubkeyLength)
|
||||
binary.PutUvarint(pubKeyBuf, uint64(i))
|
||||
validators = append(validators, &pb.Validator{
|
||||
Pubkey: pubKeyBuf,
|
||||
})
|
||||
}
|
||||
state := &pb.BeaconState{
|
||||
ValidatorRegistry: validators,
|
||||
Slot: epoch * params.BeaconConfig().SlotsPerEpoch,
|
||||
}
|
||||
chainService := setupBeaconChain(t, false, db, true)
|
||||
if err := chainService.saveValidatorIdx(state); err != nil {
|
||||
t.Fatalf("Could not save validator idx: %v", err)
|
||||
}
|
||||
|
||||
wantedIdx := uint64(2)
|
||||
idx, err := chainService.beaconDB.ValidatorIndex(validators[wantedIdx].Pubkey)
|
||||
if err != nil {
|
||||
t.Fatalf("Could not get validator index: %v", err)
|
||||
}
|
||||
if wantedIdx != idx {
|
||||
t.Errorf("Wanted: %d, got: %d", wantedIdx, idx)
|
||||
}
|
||||
|
||||
if _, ok := v.ActivatedValidators[epoch]; ok {
|
||||
t.Errorf("Activated validators mapping for epoch %d still there", epoch)
|
||||
}
|
||||
}
|
||||
|
@ -15,6 +15,15 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/shared/sliceutil"
|
||||
)
|
||||
|
||||
var (
|
||||
// ActivatedValidators is a mapping that tracks epoch to activated validators indexes.
|
||||
// Where key is epoch, value is a list of activated validator indexes.
|
||||
ActivatedValidators = make(map[uint64][]uint64)
|
||||
// ExitedValidators is a mapping that tracks epoch to excited validators indexes.
|
||||
// Where key is epoch, value is a list of exited validator indexes.
|
||||
ExitedValidators = make(map[uint64][]uint64)
|
||||
)
|
||||
|
||||
// ValidatorIndices returns all the validator indices from the input attestations
|
||||
// and state.
|
||||
//
|
||||
@ -279,6 +288,7 @@ func SlashValidator(state *pb.BeaconState, idx uint64) (*pb.BeaconState, error)
|
||||
// state.validator_registry_update_epoch = current_epoch
|
||||
func UpdateRegistry(state *pb.BeaconState) (*pb.BeaconState, error) {
|
||||
currentEpoch := helpers.CurrentEpoch(state)
|
||||
updatedEpoch := helpers.EntryExitEffectEpoch(currentEpoch)
|
||||
activeValidatorIndices := helpers.ActiveValidatorIndices(
|
||||
state.ValidatorRegistry, currentEpoch)
|
||||
|
||||
@ -301,6 +311,7 @@ func UpdateRegistry(state *pb.BeaconState) (*pb.BeaconState, error) {
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not activate validator %d: %v", idx, err)
|
||||
}
|
||||
ActivatedValidators[updatedEpoch] = append(ActivatedValidators[updatedEpoch], uint64(idx))
|
||||
}
|
||||
}
|
||||
|
||||
@ -314,6 +325,7 @@ func UpdateRegistry(state *pb.BeaconState) (*pb.BeaconState, error) {
|
||||
break
|
||||
}
|
||||
state = ExitValidator(state, uint64(idx))
|
||||
ExitedValidators[updatedEpoch] = append(ExitedValidators[updatedEpoch], uint64(idx))
|
||||
}
|
||||
}
|
||||
state.ValidatorRegistryUpdateEpoch = currentEpoch
|
||||
|
Loading…
Reference in New Issue
Block a user