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
Add PreviousList to peersAccount/validatorInfo/shardValidatorInfo #4961
Conversation
Codecov Report
📣 This organization is not using Codecov’s GitHub App Integration. We recommend you install it so Codecov can continue to function properly for your repositories. Learn more Additional details and impacted files@@ Coverage Diff @@
## feat/staking-v4 #4961 +/- ##
==================================================
Coverage ? 70.87%
==================================================
Files ? 662
Lines ? 86501
Branches ? 0
==================================================
Hits ? 61304
Misses ? 20647
Partials ? 4550 Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here. ☔ View full report at Codecov. |
@@ -52,4 +52,5 @@ message PeerAccountData { | |||
uint32 TotalValidatorIgnoredSignaturesRate = 16 [(gogoproto.jsontag) = "totalValidatorIgnoredSignaturesRate"]; | |||
uint64 Nonce = 17 [(gogoproto.jsontag) = "nonce"]; | |||
uint32 UnStakedEpoch = 18 [(gogoproto.jsontag) = "unStakedEpoch"]; | |||
string PreviousList = 19 [(gogoproto.jsontag) = "previousList,omitempty"]; |
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 not backward compatible. peerAccount is written into the validator statistics trie.
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.
I did some searching and testing and it seems it is backwards compatible.
According to this source:
maintaining backwards compatibility is crucial. Protocol buffers allow for the seamless support of changes, including the addition of new fields and the deletion of existing fields, to any protocol buffer without breaking existing services
New code will also transparently read old messages. New fields will not be present in old messages; in these cases protocol buffers provide a reasonable default value.
Also, I did a unit test which confirms this:
func TestDsa(t *testing.T) {
str1 := &ShardValidatorInfo{
PublicKey: []byte("pk"),
ShardId: 4,
List: "list",
Index: 5,
TempRating: 6,
PreviousList: "",
}
str2 := &ShardValidatorInfo2{
PublicKey: []byte("pk"),
ShardId: 4,
List: "list",
Index: 5,
TempRating: 6,
}
marshaller := &marshal.GogoProtoMarshalizer{}
bytesStr1, err := marshaller.Marshal(str1)
require.Nil(t, err)
bytesStr2, err := marshaller.Marshal(str2)
require.Nil(t, err)
require.Equal(t, bytesStr1, bytesStr2)
}
Both versions return the same marshalled byte array:
ShardValidatorInfo
hasPreviousList
fieldShardValidatorInfo2
is the old version, without added field
state/peerAccount.go
Outdated
@@ -108,7 +108,11 @@ func (pa *peerAccount) SetTempRating(rating uint32) { | |||
} | |||
|
|||
// SetListAndIndex will update the peer's list (eligible, waiting) and the index inside it with journal | |||
func (pa *peerAccount) SetListAndIndex(shardID uint32, list string, index uint32) { | |||
func (pa *peerAccount) SetListAndIndex(shardID uint32, list string, index uint32, updatePreviousList bool) { | |||
if updatePreviousList { |
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.
I think it is better to have a peerAccountV2 - where this update is true - and leave the old code as it is.
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.
And you do not need to push the boolean in the argument list.
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.
I would leave the existing structure with extension field instead of creating a new struct. This is also related to my comment above.
// TODO: compare with previous nodesConfig if exists | ||
newNodesConfig, err := ihnc.computeNodesConfigFromList(copiedPrevious, allValidatorInfo) | ||
newNodesConfig, err := ihnc.computeNodesConfigFromList(allValidatorInfo) |
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.
how can this be backward compatible ? it you have no information ?
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.
It is backwards compatible, since the previousConfig
was never used on mainnet. It was supposed to be enabled with FixWaitingListEnableEpoch
, which I've deleted in a previous PR.
Old version compatibility is maintained in addValidatorToPreviousMap
:
if !ihnc.flagStakingV4Started.IsSet() {
eligibleMap[shardId] = append(eligibleMap[shardId], currentValidator)
return
}
Here, eligibleMap
is not the one from previousEpoch
, is actually the received list from peerMiniBlocks
pa.PreviousList = pa.List | ||
pa.PreviousIndexInList = pa.IndexInList |
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.
We don't need also a variable to hold PreviousShardID ?
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.
Apparently, every time SetListAndIndex (jailed/leaving) is called, it uses the same shardID, so that doesn't change.
Also, for our use-case (leaving), I don't think there will be any future use-case where a leaving unstaked validator would be set with a different shard ID.
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.
Ok
@@ -290,7 +290,7 @@ func (s *legacySystemSCProcessor) unStakeNodesWithNotEnoughFunds( | |||
} | |||
|
|||
validatorLeaving := validatorInfo.ShallowClone() | |||
validatorLeaving.SetList(string(common.LeavingList)) | |||
validatorLeaving.SetList(string(common.LeavingList), s.enableEpochsHandler.IsStakingV4Started()) |
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.
you don't need to set the index as well?
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.
Yes, very good catch.
Updated index as well
b0eb486
Reasoning behind the pull request
indexHashedNodesCoordinator
when computing the new nodes config from current epoch.previousConfig
was actually using the nodes config from epoch 0.previousConfig
would be used to make nodes remain eligibile (wrongful nodes)Proposed changes
PreviousList
in peersAccount/validatorInfo/shardValidatorInfo and changed their used interfaces + regenerated proto files.updatePreviousList
, e.g.:SetList(list string, updatePreviousList bool)
, which will be called withStakingV4StartedFlag
- meaning this fix will be enabled only with stakingV4previousConfig
fromindexHashedNodesCoordinator
and usedPreviousList
to compute new nodes configTesting procedure
Pre-requisites
Based on the Contributing Guidelines the PR author and the reviewers must check the following requirements are met:
feat
branch created?feat
branch merging, do all satellite projects have a proper tag insidego.mod
?