Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions lib/db_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -538,9 +538,9 @@ type DBPrefixes struct {
PrefixSnapshotValidatorByPKID []byte `prefix_id:"[86]" is_state:"true"`

// PrefixSnapshotValidatorByStatusAndStake: Retrieve stake-ordered active ValidatorEntries by SnapshotAtEpochNumber.
// Prefix, <SnapshotAtEpochNumber uint64>, <Status uint8>, <TotalStakeAmountNanos *uint256.Int>, <ValidatorPKID [33]byte> -> nil
// Prefix, <SnapshotAtEpochNumber uint64>, <TotalStakeAmountNanos *uint256.Int>, <ValidatorPKID [33]byte> -> nil
// Note: we parse the ValidatorPKID from the key and the value is nil to save space.
PrefixSnapshotValidatorByStatusAndStake []byte `prefix_id:"[87]" is_state:"true"`
PrefixSnapshotValidatorByStake []byte `prefix_id:"[87]" is_state:"true"`

// PrefixSnapshotGlobalActiveStakeAmountNanos: Retrieve a snapshot GlobalActiveStakeAmountNanos by SnapshotAtEpochNumber.
// Prefix, <SnapshotAtEpochNumber uint64> -> *uint256.Int
Expand Down Expand Up @@ -779,7 +779,7 @@ func StatePrefixToDeSoEncoder(prefix []byte) (_isEncoder bool, _encoder DeSoEnco
} else if bytes.Equal(prefix, Prefixes.PrefixSnapshotValidatorByPKID) {
// prefix_id:"[86]"
return true, &ValidatorEntry{}
} else if bytes.Equal(prefix, Prefixes.PrefixSnapshotValidatorByStatusAndStake) {
} else if bytes.Equal(prefix, Prefixes.PrefixSnapshotValidatorByStake) {
// prefix_id:"[87]"
return false, nil
} else if bytes.Equal(prefix, Prefixes.PrefixSnapshotGlobalActiveStakeAmountNanos) {
Expand Down
14 changes: 10 additions & 4 deletions lib/pos_epoch_complete_hook.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,18 @@ func (bav *UtxoView) RunEpochCompleteHook(blockHeight uint64) error {
return errors.New("RunEpochCompleteHook: CurrentEpochEntry is nil, this should never happen")
}

currentGlobalParamsEntry := bav.GetCurrentGlobalParamsEntry()

// Snapshot the current GlobalParamsEntry.
bav._setSnapshotGlobalParamsEntry(bav.GlobalParamsEntry, currentEpochEntry.EpochNumber)

// Snapshot the current ValidatorEntries. This loops through all validators to snapshot them in O(n).
if err = bav.SnapshotCurrentValidators(currentEpochEntry.EpochNumber, blockHeight); err != nil {
return errors.Wrapf(err, "RunEpochCompleteHook: problem snapshotting validators: ")
// Snapshot the current top n active validators as the current validator set.
validatorSet, err := bav.GetTopActiveValidatorsByStake(currentGlobalParamsEntry.ValidatorSetMaxNumValidators)
if err != nil {
return errors.Wrapf(err, "RunEpochCompleteHook: error retrieving top ValidatorEntries: ")
}
for _, validatorEntry := range validatorSet {
bav._setSnapshotValidatorEntry(validatorEntry, currentEpochEntry.EpochNumber)
}

// Snapshot the current GlobalActiveStakeAmountNanos.
Expand All @@ -98,7 +104,7 @@ func (bav *UtxoView) RunEpochCompleteHook(blockHeight uint64) error {

// TODO: Delete old snapshots that are no longer used.

// Retrieve the SnapshotGlobalParamsEntry.EpochDurationNumBlocks.
// Retrieve the SnapshotGlobalParamsEntry.
snapshotGlobalParamsEntry, err := bav.GetSnapshotGlobalParamsEntry()
if err != nil {
return errors.Wrapf(err, "RunEpochCompleteHook: problem retrieving SnapshotGlobalParamsEntry: ")
Expand Down
23 changes: 8 additions & 15 deletions lib/pos_epoch_complete_hook_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ func TestRunEpochCompleteHook(t *testing.T) {
}

// Test SnapshotTopActiveValidatorsByStake is empty.
validatorEntries, err := utxoView().GetSnapshotTopActiveValidatorsByStake(10)
validatorEntries, err := utxoView().GetSnapshotValidatorSetByStake(10)
require.NoError(t, err)
require.Empty(t, validatorEntries)

Expand Down Expand Up @@ -303,7 +303,7 @@ func TestRunEpochCompleteHook(t *testing.T) {
}

// Test SnapshotTopActiveValidatorsByStake is populated.
validatorEntries, err := utxoView().GetSnapshotTopActiveValidatorsByStake(10)
validatorEntries, err := utxoView().GetSnapshotValidatorSetByStake(10)
require.NoError(t, err)
require.Len(t, validatorEntries, 7)
require.Equal(t, validatorEntries[0].ValidatorPKID, m6PKID)
Expand Down Expand Up @@ -397,7 +397,7 @@ func TestRunEpochCompleteHook(t *testing.T) {
// Test snapshotting changing validator set.

// m0 unregisters as a validator.
snapshotValidatorEntries, err := utxoView().GetSnapshotTopActiveValidatorsByStake(10)
snapshotValidatorEntries, err := utxoView().GetSnapshotValidatorSetByStake(10)
require.NoError(t, err)
require.Len(t, snapshotValidatorEntries, 7)

Expand All @@ -408,15 +408,15 @@ func TestRunEpochCompleteHook(t *testing.T) {
_runOnEpochCompleteHook()

// m0 is still in the snapshot validator set.
snapshotValidatorEntries, err = utxoView().GetSnapshotTopActiveValidatorsByStake(10)
snapshotValidatorEntries, err = utxoView().GetSnapshotValidatorSetByStake(10)
require.NoError(t, err)
require.Len(t, snapshotValidatorEntries, 7)

// Run OnEpochCompleteHook().
_runOnEpochCompleteHook()

// m0 is dropped from the snapshot validator set.
snapshotValidatorEntries, err = utxoView().GetSnapshotTopActiveValidatorsByStake(10)
snapshotValidatorEntries, err = utxoView().GetSnapshotValidatorSetByStake(10)
require.NoError(t, err)
require.Len(t, snapshotValidatorEntries, 6)
}
Expand Down Expand Up @@ -446,7 +446,7 @@ func TestRunEpochCompleteHook(t *testing.T) {
}

getNumSnapshotActiveValidators := func() int {
snapshotValidatorEntries, err := utxoView().GetSnapshotTopActiveValidatorsByStake(10)
snapshotValidatorEntries, err := utxoView().GetSnapshotValidatorSetByStake(10)
require.NoError(t, err)
return len(snapshotValidatorEntries)
}
Expand All @@ -457,12 +457,6 @@ func TestRunEpochCompleteHook(t *testing.T) {
return validatorEntry
}

getSnapshotValidator := func(validatorPKID *PKID) *ValidatorEntry {
snapshotValidatorEntry, err := utxoView().GetSnapshotValidatorByPKID(validatorPKID)
require.NoError(t, err)
return snapshotValidatorEntry
}

// In epoch 9, all registered validators have Status = Active.
require.Equal(t, getCurrentEpochNumber(), 9)
require.Equal(t, getNumCurrentActiveValidators(), 6)
Expand Down Expand Up @@ -508,11 +502,10 @@ func TestRunEpochCompleteHook(t *testing.T) {
_runOnEpochCompleteHook()

// In epoch 14, all current registered validators have Status = Jailed.
// In snapshot 12, all snapshot registered validators have Status = Jailed.
// In snapshot 12, the validator set is empty because all validators have Status = Jailed.

require.Equal(t, getCurrentEpochNumber(), 14)
require.Empty(t, getNumCurrentActiveValidators())
require.Empty(t, getNumSnapshotActiveValidators())
require.Equal(t, getSnapshotValidator(m6PKID).Status(), ValidatorStatusJailed)
require.Equal(t, getSnapshotValidator(m6PKID).JailedAtEpochNumber, uint64(11))
}
}
8 changes: 3 additions & 5 deletions lib/pos_leader_schedule.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package lib

import (
"crypto/sha256"

"github.com/holiman/uint256"
"github.com/pkg/errors"
)
Expand All @@ -14,13 +15,10 @@ func (bav *UtxoView) GenerateLeaderSchedule() ([]*PKID, error) {
}

// Retrieve the SnapshotGlobalParamsEntry.LeaderScheduleMaxNumValidators.
snapshotGlobalParamsEntry, err := bav.GetSnapshotGlobalParamsEntry()
if err != nil {
return nil, errors.Wrapf(err, "UtxoView.GenerateLeaderSchedule: error retrieving SnapshotGlobalParamsEntry: ")
}
currentGlobalParamsEntry := bav.GetCurrentGlobalParamsEntry()

// Retrieve top, active validators ordered by stake.
validatorEntries, err := bav.GetTopActiveValidatorsByStake(snapshotGlobalParamsEntry.LeaderScheduleMaxNumValidators)
validatorEntries, err := bav.GetTopActiveValidatorsByStake(currentGlobalParamsEntry.LeaderScheduleMaxNumValidators)
if err != nil {
return nil, errors.Wrapf(err, "UtxoView.GenerateLeaderSchedule: error retrieving top ValidatorEntries: ")
}
Expand Down
37 changes: 6 additions & 31 deletions lib/pos_snapshot_entries.go
Original file line number Diff line number Diff line change
Expand Up @@ -206,30 +206,6 @@ type SnapshotValidatorMapKey struct {
ValidatorPKID PKID
}

func (bav *UtxoView) SnapshotCurrentValidators(snapshotAtEpochNumber uint64, blockHeight uint64) error {
// First, snapshot any !isDeleted ValidatorEntries in the UtxoView.
var utxoViewValidatorPKIDs []*PKID
for _, validatorEntry := range bav.ValidatorPKIDToValidatorEntry {
if !validatorEntry.isDeleted {
// We only want to snapshot !isDeleted ValidatorEntries.
bav._setSnapshotValidatorEntry(validatorEntry, snapshotAtEpochNumber)
}

// We don't want to retrieve any ValidatorEntries from the db that are present in the UtxoView.
utxoViewValidatorPKIDs = append(utxoViewValidatorPKIDs, validatorEntry.ValidatorPKID)
}
// Second, snapshot the ValidatorEntries in the db (skipping any in the UtxoView).
dbValidatorEntries, err := DBEnumerateAllCurrentValidators(bav.Handle, utxoViewValidatorPKIDs)
if err != nil {
return errors.Wrapf(err, "SnapshotValidators: problem retrieving ValidatorEntries: ")
}
for _, validatorEntry := range dbValidatorEntries {
bav._setSnapshotValidatorEntry(validatorEntry, snapshotAtEpochNumber)

}
return nil
}

func (bav *UtxoView) GetSnapshotValidatorByPKID(pkid *PKID) (*ValidatorEntry, error) {
// Calculate the SnapshotEpochNumber.
snapshotAtEpochNumber, err := bav.GetSnapshotEpochNumber()
Expand All @@ -256,12 +232,13 @@ func (bav *UtxoView) GetSnapshotValidatorByPKID(pkid *PKID) (*ValidatorEntry, er
return validatorEntry, nil
}

func (bav *UtxoView) GetSnapshotTopActiveValidatorsByStake(limit uint64) ([]*ValidatorEntry, error) {
func (bav *UtxoView) GetSnapshotValidatorSetByStake(limit uint64) ([]*ValidatorEntry, error) {
// Calculate the SnapshotEpochNumber.
snapshotAtEpochNumber, err := bav.GetSnapshotEpochNumber()
if err != nil {
return nil, errors.Wrapf(err, "GetSnapshotTopActiveValidatorsByStake: problem calculating SnapshotEpochNumber: ")
return nil, errors.Wrapf(err, "GetSnapshotValidatorSetByStake: problem calculating SnapshotEpochNumber: ")
}

// Create a slice of all UtxoView ValidatorEntries to prevent pulling them from the db.
var utxoViewValidatorEntries []*ValidatorEntry
for mapKey, validatorEntry := range bav.SnapshotValidatorEntries {
Expand All @@ -276,7 +253,7 @@ func (bav *UtxoView) GetSnapshotTopActiveValidatorsByStake(limit uint64) ([]*Val
bav.Handle, bav.Snapshot, limit, snapshotAtEpochNumber, utxoViewValidatorEntries,
)
if err != nil {
return nil, errors.Wrapf(err, "GetSnapshotTopActiveValidatorsByStake: error retrieving entries from db: ")
return nil, errors.Wrapf(err, "GetSnapshotValidatorSetByStake: error retrieving entries from db: ")
}
// Cache top N active ValidatorEntries from the db in the UtxoView.
for _, validatorEntry := range dbValidatorEntries {
Expand Down Expand Up @@ -394,9 +371,8 @@ func DBKeyForSnapshotValidatorByPKID(validatorEntry *ValidatorEntry, snapshotAtE
}

func DBKeyForSnapshotValidatorByStake(validatorEntry *ValidatorEntry, snapshotAtEpochNumber uint64) []byte {
key := append([]byte{}, Prefixes.PrefixSnapshotValidatorByStatusAndStake...)
key := append([]byte{}, Prefixes.PrefixSnapshotValidatorByStake...)
key = append(key, EncodeUint64(snapshotAtEpochNumber)...)
key = append(key, EncodeUint8(uint8(validatorEntry.Status()))...)
key = append(key, FixedWidthEncodeUint256(validatorEntry.TotalStakeAmountNanos)...)
key = append(key, validatorEntry.ValidatorPKID.ToBytes()...)
return key
Expand Down Expand Up @@ -454,9 +430,8 @@ func DBGetSnapshotTopActiveValidatorsByStake(
}

// Retrieve top N active ValidatorEntry keys by stake.
key := append([]byte{}, Prefixes.PrefixSnapshotValidatorByStatusAndStake...)
key := append([]byte{}, Prefixes.PrefixSnapshotValidatorByStake...)
key = append(key, EncodeUint64(snapshotAtEpochNumber)...)
key = append(key, EncodeUint8(uint8(ValidatorStatusActive))...)
keysFound, _, err := EnumerateKeysForPrefixWithLimitOffsetOrder(
handle, key, int(limit), nil, true, validatorKeysToSkip,
)
Expand Down