Skip to content

Commit

Permalink
Remove fallback validator height indexing (#2801)
Browse files Browse the repository at this point in the history
  • Loading branch information
StephenButtolph authored Mar 20, 2024
1 parent 0118611 commit 23e5417
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 167 deletions.
214 changes: 57 additions & 157 deletions vms/platformvm/state/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,28 +47,26 @@ var (
errValidatorSetAlreadyPopulated = errors.New("validator set already populated")
errIsNotSubnet = errors.New("is not a subnet")

BlockIDPrefix = []byte("blockID")
BlockPrefix = []byte("block")
ValidatorsPrefix = []byte("validators")
CurrentPrefix = []byte("current")
PendingPrefix = []byte("pending")
ValidatorPrefix = []byte("validator")
DelegatorPrefix = []byte("delegator")
SubnetValidatorPrefix = []byte("subnetValidator")
SubnetDelegatorPrefix = []byte("subnetDelegator")
NestedValidatorWeightDiffsPrefix = []byte("validatorDiffs")
NestedValidatorPublicKeyDiffsPrefix = []byte("publicKeyDiffs")
FlatValidatorWeightDiffsPrefix = []byte("flatValidatorDiffs")
FlatValidatorPublicKeyDiffsPrefix = []byte("flatPublicKeyDiffs")
TxPrefix = []byte("tx")
RewardUTXOsPrefix = []byte("rewardUTXOs")
UTXOPrefix = []byte("utxo")
SubnetPrefix = []byte("subnet")
SubnetOwnerPrefix = []byte("subnetOwner")
TransformedSubnetPrefix = []byte("transformedSubnet")
SupplyPrefix = []byte("supply")
ChainPrefix = []byte("chain")
SingletonPrefix = []byte("singleton")
BlockIDPrefix = []byte("blockID")
BlockPrefix = []byte("block")
ValidatorsPrefix = []byte("validators")
CurrentPrefix = []byte("current")
PendingPrefix = []byte("pending")
ValidatorPrefix = []byte("validator")
DelegatorPrefix = []byte("delegator")
SubnetValidatorPrefix = []byte("subnetValidator")
SubnetDelegatorPrefix = []byte("subnetDelegator")
ValidatorWeightDiffsPrefix = []byte("flatValidatorDiffs")
ValidatorPublicKeyDiffsPrefix = []byte("flatPublicKeyDiffs")
TxPrefix = []byte("tx")
RewardUTXOsPrefix = []byte("rewardUTXOs")
UTXOPrefix = []byte("utxo")
SubnetPrefix = []byte("subnet")
SubnetOwnerPrefix = []byte("subnetOwner")
TransformedSubnetPrefix = []byte("transformedSubnet")
SupplyPrefix = []byte("supply")
ChainPrefix = []byte("chain")
SingletonPrefix = []byte("singleton")

TimestampKey = []byte("timestamp")
CurrentSupplyKey = []byte("current supply")
Expand Down Expand Up @@ -209,17 +207,9 @@ type State interface {
* | | '-. subnetDelegator
* | | '-. list
* | | '-- txID -> nil
* | |-. nested weight diffs TODO: Remove once only the flat db is needed
* | | '-. height+subnet
* | | '-. list
* | | '-- nodeID -> weightChange
* | |-. nested pub key diffs TODO: Remove once only the flat db is needed
* | | '-. height
* | | '-. list
* | | '-- nodeID -> compressed public key
* | |-. flat weight diffs
* | |-. weight diffs
* | | '-- subnet+height+nodeID -> weightChange
* | '-. flat pub key diffs
* | '-. pub key diffs
* | '-- subnet+height+nodeID -> uncompressed public key or nil
* |-. blockIDs
* | '-- height -> blockID
Expand Down Expand Up @@ -293,10 +283,8 @@ type state struct {
pendingSubnetDelegatorBaseDB database.Database
pendingSubnetDelegatorList linkeddb.LinkedDB

nestedValidatorWeightDiffsDB database.Database
nestedValidatorPublicKeyDiffsDB database.Database
flatValidatorWeightDiffsDB database.Database
flatValidatorPublicKeyDiffsDB database.Database
validatorWeightDiffsDB database.Database
validatorPublicKeyDiffsDB database.Database

addedTxs map[ids.ID]*txAndStatus // map of txID -> {*txs.Tx, Status}
txCache cache.Cacher[ids.ID, *txAndStatus] // txID -> {*txs.Tx, Status}. If the entry is nil, it isn't in the database
Expand Down Expand Up @@ -338,8 +326,9 @@ type state struct {
currentSupply, persistedCurrentSupply uint64
// [lastAccepted] is the most recently accepted block.
lastAccepted, persistedLastAccepted ids.ID
indexedHeights *heightRange
singletonDB database.Database
// TODO: Remove indexedHeights once v1.11.3 has been released.
indexedHeights *heightRange
singletonDB database.Database
}

// heightRange is used to track which heights are safe to use the native DB
Expand Down Expand Up @@ -373,11 +362,6 @@ func (v *ValidatorWeightDiff) Add(negative bool, amount uint64) error {
return nil
}

type heightWithSubnet struct {
Height uint64 `serialize:"true"`
SubnetID ids.ID `serialize:"true"`
}

type txBytesAndStatus struct {
Tx []byte `serialize:"true"`
Status status.Status `serialize:"true"`
Expand Down Expand Up @@ -490,10 +474,8 @@ func newState(
pendingSubnetValidatorBaseDB := prefixdb.New(SubnetValidatorPrefix, pendingValidatorsDB)
pendingSubnetDelegatorBaseDB := prefixdb.New(SubnetDelegatorPrefix, pendingValidatorsDB)

nestedValidatorWeightDiffsDB := prefixdb.New(NestedValidatorWeightDiffsPrefix, validatorsDB)
nestedValidatorPublicKeyDiffsDB := prefixdb.New(NestedValidatorPublicKeyDiffsPrefix, validatorsDB)
flatValidatorWeightDiffsDB := prefixdb.New(FlatValidatorWeightDiffsPrefix, validatorsDB)
flatValidatorPublicKeyDiffsDB := prefixdb.New(FlatValidatorPublicKeyDiffsPrefix, validatorsDB)
validatorWeightDiffsDB := prefixdb.New(ValidatorWeightDiffsPrefix, validatorsDB)
validatorPublicKeyDiffsDB := prefixdb.New(ValidatorPublicKeyDiffsPrefix, validatorsDB)

txCache, err := metercacher.New(
"tx_cache",
Expand Down Expand Up @@ -591,29 +573,27 @@ func newState(
currentStakers: newBaseStakers(),
pendingStakers: newBaseStakers(),

validatorsDB: validatorsDB,
currentValidatorsDB: currentValidatorsDB,
currentValidatorBaseDB: currentValidatorBaseDB,
currentValidatorList: linkeddb.NewDefault(currentValidatorBaseDB),
currentDelegatorBaseDB: currentDelegatorBaseDB,
currentDelegatorList: linkeddb.NewDefault(currentDelegatorBaseDB),
currentSubnetValidatorBaseDB: currentSubnetValidatorBaseDB,
currentSubnetValidatorList: linkeddb.NewDefault(currentSubnetValidatorBaseDB),
currentSubnetDelegatorBaseDB: currentSubnetDelegatorBaseDB,
currentSubnetDelegatorList: linkeddb.NewDefault(currentSubnetDelegatorBaseDB),
pendingValidatorsDB: pendingValidatorsDB,
pendingValidatorBaseDB: pendingValidatorBaseDB,
pendingValidatorList: linkeddb.NewDefault(pendingValidatorBaseDB),
pendingDelegatorBaseDB: pendingDelegatorBaseDB,
pendingDelegatorList: linkeddb.NewDefault(pendingDelegatorBaseDB),
pendingSubnetValidatorBaseDB: pendingSubnetValidatorBaseDB,
pendingSubnetValidatorList: linkeddb.NewDefault(pendingSubnetValidatorBaseDB),
pendingSubnetDelegatorBaseDB: pendingSubnetDelegatorBaseDB,
pendingSubnetDelegatorList: linkeddb.NewDefault(pendingSubnetDelegatorBaseDB),
nestedValidatorWeightDiffsDB: nestedValidatorWeightDiffsDB,
nestedValidatorPublicKeyDiffsDB: nestedValidatorPublicKeyDiffsDB,
flatValidatorWeightDiffsDB: flatValidatorWeightDiffsDB,
flatValidatorPublicKeyDiffsDB: flatValidatorPublicKeyDiffsDB,
validatorsDB: validatorsDB,
currentValidatorsDB: currentValidatorsDB,
currentValidatorBaseDB: currentValidatorBaseDB,
currentValidatorList: linkeddb.NewDefault(currentValidatorBaseDB),
currentDelegatorBaseDB: currentDelegatorBaseDB,
currentDelegatorList: linkeddb.NewDefault(currentDelegatorBaseDB),
currentSubnetValidatorBaseDB: currentSubnetValidatorBaseDB,
currentSubnetValidatorList: linkeddb.NewDefault(currentSubnetValidatorBaseDB),
currentSubnetDelegatorBaseDB: currentSubnetDelegatorBaseDB,
currentSubnetDelegatorList: linkeddb.NewDefault(currentSubnetDelegatorBaseDB),
pendingValidatorsDB: pendingValidatorsDB,
pendingValidatorBaseDB: pendingValidatorBaseDB,
pendingValidatorList: linkeddb.NewDefault(pendingValidatorBaseDB),
pendingDelegatorBaseDB: pendingDelegatorBaseDB,
pendingDelegatorList: linkeddb.NewDefault(pendingDelegatorBaseDB),
pendingSubnetValidatorBaseDB: pendingSubnetValidatorBaseDB,
pendingSubnetValidatorList: linkeddb.NewDefault(pendingSubnetValidatorBaseDB),
pendingSubnetDelegatorBaseDB: pendingSubnetDelegatorBaseDB,
pendingSubnetDelegatorList: linkeddb.NewDefault(pendingSubnetDelegatorBaseDB),
validatorWeightDiffsDB: validatorWeightDiffsDB,
validatorPublicKeyDiffsDB: validatorPublicKeyDiffsDB,

addedTxs: make(map[ids.ID]*txAndStatus),
txDB: prefixdb.New(TxPrefix, baseDB),
Expand Down Expand Up @@ -1053,16 +1033,14 @@ func (s *state) ApplyValidatorWeightDiffs(
endHeight uint64,
subnetID ids.ID,
) error {
diffIter := s.flatValidatorWeightDiffsDB.NewIteratorWithStartAndPrefix(
diffIter := s.validatorWeightDiffsDB.NewIteratorWithStartAndPrefix(
marshalStartDiffKey(subnetID, startHeight),
subnetID[:],
)
defer diffIter.Release()

prevHeight := startHeight + 1
// TODO: Remove the index continuity checks once we are guaranteed nodes can
// not rollback to not support the new indexing mechanism.
for diffIter.Next() && s.indexedHeights != nil && s.indexedHeights.LowerBound <= endHeight {
for diffIter.Next() {
if err := ctx.Err(); err != nil {
return err
}
Expand Down Expand Up @@ -1100,50 +1078,7 @@ func (s *state) ApplyValidatorWeightDiffs(
return err
}
}
if err := diffIter.Error(); err != nil {
return err
}

// TODO: Remove this once it is assumed that all subnet validators have
// adopted the new indexing.
for height := prevHeight - 1; height >= endHeight; height-- {
if err := ctx.Err(); err != nil {
return err
}

prefixStruct := heightWithSubnet{
Height: height,
SubnetID: subnetID,
}
prefixBytes, err := block.GenesisCodec.Marshal(block.CodecVersion, prefixStruct)
if err != nil {
return err
}

rawDiffDB := prefixdb.New(prefixBytes, s.nestedValidatorWeightDiffsDB)
diffDB := linkeddb.NewDefault(rawDiffDB)
diffIter := diffDB.NewIterator()
defer diffIter.Release()

for diffIter.Next() {
nodeID, err := ids.ToNodeID(diffIter.Key())
if err != nil {
return err
}

weightDiff := ValidatorWeightDiff{}
_, err = block.GenesisCodec.Unmarshal(diffIter.Value(), &weightDiff)
if err != nil {
return err
}

if err := applyWeightDiff(validators, nodeID, &weightDiff); err != nil {
return err
}
}
}

return nil
return diffIter.Error()
}

func applyWeightDiff(
Expand Down Expand Up @@ -1189,7 +1124,7 @@ func (s *state) ApplyValidatorPublicKeyDiffs(
startHeight uint64,
endHeight uint64,
) error {
diffIter := s.flatValidatorPublicKeyDiffsDB.NewIteratorWithStartAndPrefix(
diffIter := s.validatorPublicKeyDiffsDB.NewIteratorWithStartAndPrefix(
marshalStartDiffKey(constants.PrimaryNetworkID, startHeight),
constants.PrimaryNetworkID[:],
)
Expand Down Expand Up @@ -1891,10 +1826,6 @@ func (s *state) GetBlockIDAtHeight(height uint64) (ids.ID, error) {
}

func (s *state) writeCurrentStakers(updateValidators bool, height uint64, codecVersion uint16) error {
heightBytes := database.PackUInt64(height)
rawNestedPublicKeyDiffDB := prefixdb.New(heightBytes, s.nestedValidatorPublicKeyDiffsDB)
nestedPKDiffDB := linkeddb.NewDefault(rawNestedPublicKeyDiffDB)

for subnetID, validatorDiffs := range s.currentStakers.validatorDiffs {
delete(s.currentStakers.validatorDiffs, subnetID)

Expand All @@ -1906,17 +1837,6 @@ func (s *state) writeCurrentStakers(updateValidators bool, height uint64, codecV
delegatorDB = s.currentDelegatorList
}

prefixStruct := heightWithSubnet{
Height: height,
SubnetID: subnetID,
}
prefixBytes, err := block.GenesisCodec.Marshal(block.CodecVersion, prefixStruct)
if err != nil {
return fmt.Errorf("failed to create prefix bytes: %w", err)
}
rawNestedWeightDiffDB := prefixdb.New(prefixBytes, s.nestedValidatorWeightDiffsDB)
nestedWeightDiffDB := linkeddb.NewDefault(rawNestedWeightDiffDB)

// Record the change in weight and/or public key for each validator.
for nodeID, validatorDiff := range validatorDiffs {
// Copy [nodeID] so it doesn't get overwritten next iteration.
Expand All @@ -1936,7 +1856,7 @@ func (s *state) writeCurrentStakers(updateValidators bool, height uint64, codecV
// Record that the public key for the validator is being
// added. This means the prior value for the public key was
// nil.
err := s.flatValidatorPublicKeyDiffsDB.Put(
err := s.validatorPublicKeyDiffsDB.Put(
marshalDiffKey(constants.PrimaryNetworkID, height, nodeID),
nil,
)
Expand Down Expand Up @@ -1985,22 +1905,13 @@ func (s *state) writeCurrentStakers(updateValidators bool, height uint64, codecV
// Note: We store the uncompressed public key here as it is
// significantly more efficient to parse when applying
// diffs.
err := s.flatValidatorPublicKeyDiffsDB.Put(
err := s.validatorPublicKeyDiffsDB.Put(
marshalDiffKey(constants.PrimaryNetworkID, height, nodeID),
bls.PublicKeyToUncompressedBytes(staker.PublicKey),
)
if err != nil {
return err
}

// TODO: Remove this once we no longer support version
// rollbacks.
//
// Note: We store the compressed public key here.
pkBytes := bls.PublicKeyToCompressedBytes(staker.PublicKey)
if err := nestedPKDiffDB.Put(nodeID.Bytes(), pkBytes); err != nil {
return err
}
}

if err := validatorDB.Delete(staker.TxID[:]); err != nil {
Expand All @@ -2025,23 +1936,14 @@ func (s *state) writeCurrentStakers(updateValidators bool, height uint64, codecV
continue
}

err = s.flatValidatorWeightDiffsDB.Put(
err = s.validatorWeightDiffsDB.Put(
marshalDiffKey(subnetID, height, nodeID),
marshalWeightDiff(weightDiff),
)
if err != nil {
return err
}

// TODO: Remove this once we no longer support version rollbacks.
weightDiffBytes, err := block.GenesisCodec.Marshal(block.CodecVersion, weightDiff)
if err != nil {
return fmt.Errorf("failed to serialize validator weight diff: %w", err)
}
if err := nestedWeightDiffDB.Put(nodeID.Bytes(), weightDiffBytes); err != nil {
return err
}

// TODO: Move the validator set management out of the state package
if !updateValidators {
continue
Expand Down Expand Up @@ -2347,7 +2249,6 @@ func (s *state) writeMetadata() error {
}
s.persistedLastAccepted = s.lastAccepted
}

if s.indexedHeights != nil {
indexedHeightsBytes, err := block.GenesisCodec.Marshal(block.CodecVersion, s.indexedHeights)
if err != nil {
Expand All @@ -2357,6 +2258,5 @@ func (s *state) writeMetadata() error {
return fmt.Errorf("failed to write indexed range: %w", err)
}
}

return nil
}
Loading

0 comments on commit 23e5417

Please sign in to comment.