-
Notifications
You must be signed in to change notification settings - Fork 682
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Pull apart writeCurrentStakers method - Part 1 #2074
Changes from 4 commits
1c12d39
c5061a4
b0cd9cb
fe93ba1
34d5602
cddf51c
9b77852
407cb74
8caf284
96d0e56
112a2e2
460d5c9
14b33a0
590bb02
37d1d5e
6373786
3d7cc37
405632e
b281f22
3eaa5c0
25804f4
5bdd4f5
e5fd062
c809c46
4c3f70b
a30a7f8
22e9e57
47a0f8a
fd774e9
6723f87
1ce6610
348bbcd
38d21b1
a159219
5af4b8c
5289800
824c73d
189760b
a894112
eec2f0a
df3f29d
5127e47
5c737ad
c1f43fd
847818f
a3fa4a5
9db4ce5
cbc4b78
18c9c05
3c73950
b837541
f99dd6a
9a2f2c7
789670e
1731817
9fdd336
f528832
bee3ea3
4e915af
04cb730
7b0fe01
3c1bc14
56d9aa3
cb97bd7
7f666ed
5dd86b9
38a2e45
75a74da
6563d8b
fd8ca3f
e622e22
22f1462
c35754a
6794aa4
ed0f398
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -1672,10 +1672,17 @@ func (s *state) initValidatorSets() error { | |||||
} | ||||||
|
||||||
func (s *state) write(updateValidators bool, height uint64) error { | ||||||
weightDiffs, blsKeyDiffs, err := s.processCurrentStakers() | ||||||
if err != nil { | ||||||
return err | ||||||
} | ||||||
|
||||||
errs := wrappers.Errs{} | ||||||
errs.Add( | ||||||
s.writeBlocks(), | ||||||
s.writeCurrentStakers(updateValidators, height), | ||||||
s.writeCurrentStakers(updateValidators), | ||||||
s.writeWeightDiffs(height, weightDiffs), | ||||||
s.writeBlsKeyDiffs(height, blsKeyDiffs), | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. these are some of methods where we only write the information collected in processCurrentStakers |
||||||
s.writePendingStakers(), | ||||||
s.WriteValidatorMetadata(s.currentValidatorList, s.currentSubnetValidatorList), // Must be called after writeCurrentStakers | ||||||
s.writeTXs(), | ||||||
|
@@ -1690,6 +1697,155 @@ func (s *state) write(updateValidators bool, height uint64) error { | |||||
return errs.Err | ||||||
} | ||||||
|
||||||
func (s *state) writeWeightDiffs(height uint64, weightDiffs map[subnetNodePair]*ValidatorWeightDiff) error { | ||||||
for k, weightDiff := range weightDiffs { | ||||||
if weightDiff.Amount == 0 { | ||||||
continue | ||||||
} | ||||||
|
||||||
err := s.flatValidatorWeightDiffsDB.Put( | ||||||
marshalDiffKey(k.subnetID, height, k.nodeID), | ||||||
marshalWeightDiff(weightDiff), | ||||||
) | ||||||
if err != nil { | ||||||
return err | ||||||
} | ||||||
|
||||||
// TODO: Remove this once we no longer support version rollbacks. | ||||||
prefixStruct := heightWithSubnet{ | ||||||
Height: height, | ||||||
SubnetID: k.subnetID, | ||||||
} | ||||||
prefixBytes, err := block.GenesisCodec.Marshal(block.Version, prefixStruct) | ||||||
if err != nil { | ||||||
return fmt.Errorf("failed to create prefix bytes: %w", err) | ||||||
} | ||||||
rawNestedWeightDiffDB := prefixdb.New(prefixBytes, s.nestedValidatorWeightDiffsDB) | ||||||
nestedWeightDiffDB := linkeddb.NewDefault(rawNestedWeightDiffDB) | ||||||
|
||||||
weightDiffBytes, err := block.GenesisCodec.Marshal(block.Version, weightDiff) | ||||||
if err != nil { | ||||||
return fmt.Errorf("failed to serialize validator weight diff: %w", err) | ||||||
} | ||||||
if err := nestedWeightDiffDB.Put(k.nodeID[:], weightDiffBytes); err != nil { | ||||||
return err | ||||||
} | ||||||
} | ||||||
return nil | ||||||
} | ||||||
|
||||||
func (s *state) writeBlsKeyDiffs(height uint64, blsKeyDiffs map[ids.NodeID]*bls.PublicKey) error { | ||||||
for nodeID, blsKey := range blsKeyDiffs { | ||||||
key := marshalDiffKey(constants.PrimaryNetworkID, height, nodeID) | ||||||
blsKeyBytes := []byte{} | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit. Don't think this actually makes a difference, since we treat
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||||||
if blsKey != nil { | ||||||
// Note: in flatValidatorPublicKeyDiffsDB we store the | ||||||
// uncompressed public key here as it is | ||||||
// significantly more efficient to parse when applying diffs. | ||||||
blsKeyBytes = blsKey.Serialize() | ||||||
} | ||||||
if err := s.flatValidatorPublicKeyDiffsDB.Put(key, blsKeyBytes); err != nil { | ||||||
return fmt.Errorf("failed to add bls key diffs: %w", err) | ||||||
} | ||||||
|
||||||
// TODO: Remove this once we no longer support version rollbacks. | ||||||
if blsKey != nil { | ||||||
heightBytes := database.PackUInt64(height) | ||||||
rawNestedPublicKeyDiffDB := prefixdb.New(heightBytes, s.nestedValidatorPublicKeyDiffsDB) | ||||||
nestedPKDiffDB := linkeddb.NewDefault(rawNestedPublicKeyDiffDB) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We don't need to compute these every loop iteration There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. pulled out of the loop |
||||||
|
||||||
// Note: We store the compressed public key here. | ||||||
pkBytes := bls.PublicKeyToBytes(blsKey) | ||||||
if err := nestedPKDiffDB.Put(nodeID[:], pkBytes); err != nil { | ||||||
return err | ||||||
} | ||||||
} | ||||||
} | ||||||
return nil | ||||||
} | ||||||
|
||||||
type subnetNodePair struct { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe we can call this subnet validator? or just validator? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we got plenty of both 😅. How about |
||||||
subnetID ids.ID | ||||||
nodeID ids.NodeID | ||||||
} | ||||||
|
||||||
func (s *state) processCurrentStakers() ( | ||||||
map[subnetNodePair]*ValidatorWeightDiff, | ||||||
map[ids.NodeID]*bls.PublicKey, | ||||||
error, | ||||||
) { | ||||||
var ( | ||||||
outputWeights = make(map[subnetNodePair]*ValidatorWeightDiff) | ||||||
outputBlsKey = make(map[ids.NodeID]*bls.PublicKey) | ||||||
) | ||||||
|
||||||
for subnetID, subnetValidatorDiffs := range s.currentStakers.validatorDiffs { | ||||||
// for now, let writeCurrentStakers consume s.currentStakers.validatorDiffs | ||||||
for nodeID, validatorDiff := range subnetValidatorDiffs { | ||||||
weightKey := subnetNodePair{ | ||||||
subnetID: subnetID, | ||||||
nodeID: nodeID, | ||||||
} | ||||||
|
||||||
// make sure there is an entry for delegators even in case | ||||||
// there are no validators modified. | ||||||
outputWeights[weightKey] = &ValidatorWeightDiff{ | ||||||
Decrease: validatorDiff.validatorStatus == deleted, | ||||||
} | ||||||
|
||||||
switch validatorDiff.validatorStatus { | ||||||
case added: | ||||||
var ( | ||||||
weight = validatorDiff.validator.Weight | ||||||
blkKey = validatorDiff.validator.PublicKey | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is this supposed to be There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed |
||||||
) | ||||||
|
||||||
outputWeights[weightKey].Amount = weight | ||||||
|
||||||
if blkKey != nil { | ||||||
// Record that the public key for the validator is being | ||||||
// added. This means the prior value for the public key was | ||||||
// nil. | ||||||
outputBlsKey[nodeID] = nil | ||||||
} | ||||||
|
||||||
case deleted: | ||||||
var ( | ||||||
weight = validatorDiff.validator.Weight | ||||||
blkKey = validatorDiff.validator.PublicKey | ||||||
) | ||||||
outputWeights[weightKey].Amount = weight | ||||||
if blkKey != nil { | ||||||
// Record that the public key for the validator is being | ||||||
// removed. This means we must record the prior value of the | ||||||
// public key. | ||||||
outputBlsKey[nodeID] = blkKey | ||||||
} | ||||||
|
||||||
default: | ||||||
// nothing to do | ||||||
} | ||||||
|
||||||
addedDelegatorIterator := NewTreeIterator(validatorDiff.addedDelegators) | ||||||
defer addedDelegatorIterator.Release() | ||||||
for addedDelegatorIterator.Next() { | ||||||
staker := addedDelegatorIterator.Value() | ||||||
|
||||||
if err := outputWeights[weightKey].Add(false, staker.Weight); err != nil { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||||||
return nil, nil, fmt.Errorf("failed to increase node weight diff: %w", err) | ||||||
} | ||||||
} | ||||||
|
||||||
for _, staker := range validatorDiff.deletedDelegators { | ||||||
if err := outputWeights[weightKey].Add(true, staker.Weight); err != nil { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||||||
return nil, nil, fmt.Errorf("failed to decrease node weight diff: %w", err) | ||||||
} | ||||||
} | ||||||
} | ||||||
} | ||||||
return outputWeights, outputBlsKey, nil | ||||||
} | ||||||
|
||||||
func (s *state) Close() error { | ||||||
errs := wrappers.Errs{} | ||||||
errs.Add( | ||||||
|
@@ -1905,11 +2061,7 @@ func (s *state) GetBlockIDAtHeight(height uint64) (ids.ID, error) { | |||||
return blkID, nil | ||||||
} | ||||||
|
||||||
func (s *state) writeCurrentStakers(updateValidators bool, height uint64) error { | ||||||
heightBytes := database.PackUInt64(height) | ||||||
rawNestedPublicKeyDiffDB := prefixdb.New(heightBytes, s.nestedValidatorPublicKeyDiffsDB) | ||||||
nestedPKDiffDB := linkeddb.NewDefault(rawNestedPublicKeyDiffDB) | ||||||
|
||||||
func (s *state) writeCurrentStakers(updateValidators bool) error { | ||||||
for subnetID, validatorDiffs := range s.currentStakers.validatorDiffs { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As you suggest, the plan is to split writeCurrentStakers into two parts:
The "store it" component won't need to access s.currentStakers; it will only access pulled info, as you suggest. |
||||||
delete(s.currentStakers.validatorDiffs, subnetID) | ||||||
|
||||||
|
@@ -1921,17 +2073,6 @@ func (s *state) writeCurrentStakers(updateValidators bool, height uint64) error | |||||
delegatorDB = s.currentDelegatorList | ||||||
} | ||||||
|
||||||
prefixStruct := heightWithSubnet{ | ||||||
Height: height, | ||||||
SubnetID: subnetID, | ||||||
} | ||||||
prefixBytes, err := block.GenesisCodec.Marshal(block.Version, 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. | ||||||
|
@@ -1945,21 +2086,6 @@ func (s *state) writeCurrentStakers(updateValidators bool, height uint64) error | |||||
staker := validatorDiff.validator | ||||||
weightDiff.Amount = staker.Weight | ||||||
|
||||||
// Invariant: Only the Primary Network contains non-nil public | ||||||
// keys. | ||||||
if staker.PublicKey != nil { | ||||||
// 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( | ||||||
marshalDiffKey(constants.PrimaryNetworkID, height, nodeID), | ||||||
nil, | ||||||
) | ||||||
if err != nil { | ||||||
return err | ||||||
} | ||||||
} | ||||||
|
||||||
// The validator is being added. | ||||||
// | ||||||
// Invariant: It's impossible for a delegator to have been | ||||||
|
@@ -1988,34 +2114,6 @@ func (s *state) writeCurrentStakers(updateValidators bool, height uint64) error | |||||
staker := validatorDiff.validator | ||||||
weightDiff.Amount = staker.Weight | ||||||
|
||||||
// Invariant: Only the Primary Network contains non-nil public | ||||||
// keys. | ||||||
if staker.PublicKey != nil { | ||||||
// Record that the public key for the validator is being | ||||||
// removed. This means we must record the prior value of the | ||||||
// public key. | ||||||
// | ||||||
// Note: We store the uncompressed public key here as it is | ||||||
// significantly more efficient to parse when applying | ||||||
// diffs. | ||||||
err := s.flatValidatorPublicKeyDiffsDB.Put( | ||||||
marshalDiffKey(constants.PrimaryNetworkID, height, nodeID), | ||||||
staker.PublicKey.Serialize(), | ||||||
) | ||||||
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.PublicKeyToBytes(staker.PublicKey) | ||||||
if err := nestedPKDiffDB.Put(nodeID[:], pkBytes); err != nil { | ||||||
return err | ||||||
} | ||||||
} | ||||||
|
||||||
if err := validatorDB.Delete(staker.TxID[:]); err != nil { | ||||||
return fmt.Errorf("failed to delete current staker: %w", err) | ||||||
} | ||||||
|
@@ -2032,28 +2130,6 @@ func (s *state) writeCurrentStakers(updateValidators bool, height uint64) error | |||||
return err | ||||||
} | ||||||
|
||||||
if weightDiff.Amount == 0 { | ||||||
// No weight change to record; go to next validator. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Isn't this a behavior change? In the existing code, we continue here if the weight didn't change. In the new code, we call one of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @danlaine, you're right. I moved this condition to |
||||||
continue | ||||||
} | ||||||
|
||||||
err = s.flatValidatorWeightDiffsDB.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.Version, weightDiff) | ||||||
if err != nil { | ||||||
return fmt.Errorf("failed to serialize validator weight diff: %w", err) | ||||||
} | ||||||
if err := nestedWeightDiffDB.Put(nodeID[:], weightDiffBytes); err != nil { | ||||||
return err | ||||||
} | ||||||
|
||||||
// TODO: Move the validator set management out of the state package | ||||||
if !updateValidators { | ||||||
continue | ||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is the part where stakers-related content is scanned to extract specific information to be stored in different parts of the pchain state