-
Notifications
You must be signed in to change notification settings - Fork 323
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
[staking] CandidateCenter Support for Missing and Changes of Self-Stake Bucket #4060
Changes from all commits
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 |
---|---|---|
|
@@ -15,6 +15,9 @@ import ( | |
|
||
// testEqual verifies m contains exactly the list | ||
func testEqual(m *CandidateCenter, l CandidateList) bool { | ||
if m.All().Len() != len(l) { | ||
return false | ||
} | ||
for _, v := range l { | ||
d := m.GetByOwner(v.Owner) | ||
if d == nil { | ||
|
@@ -33,10 +36,10 @@ func testEqual(m *CandidateCenter, l CandidateList) bool { | |
} | ||
|
||
d = m.GetBySelfStakingIndex(v.SelfStakeBucketIdx) | ||
if d == nil { | ||
if d == nil && v.isSelfStakeBucketSettled() { | ||
return false | ||
} | ||
if !v.Equal(d) { | ||
if d != nil && !v.Equal(d) { | ||
return false | ||
} | ||
} | ||
|
@@ -429,6 +432,138 @@ func TestFixAlias(t *testing.T) { | |
} | ||
} | ||
|
||
func TestMultipleNonStakingCandidate(t *testing.T) { | ||
r := require.New(t) | ||
|
||
candStaked := &Candidate{ | ||
Owner: identityset.Address(1), | ||
Operator: identityset.Address(11), | ||
Reward: identityset.Address(3), | ||
Name: "self-staked", | ||
Votes: unit.ConvertIotxToRau(1200000), | ||
SelfStakeBucketIdx: 1, | ||
SelfStake: unit.ConvertIotxToRau(1200000), | ||
} | ||
candNonStaked1 := &Candidate{ | ||
Owner: identityset.Address(2), | ||
Operator: identityset.Address(12), | ||
Reward: identityset.Address(3), | ||
Name: "non-self-staked1", | ||
Votes: big.NewInt(0), | ||
SelfStakeBucketIdx: candidateNoSelfStakeBucketIndex, | ||
SelfStake: big.NewInt(0), | ||
} | ||
candNonStaked2 := &Candidate{ | ||
Owner: identityset.Address(3), | ||
Operator: identityset.Address(13), | ||
Reward: identityset.Address(3), | ||
Name: "non-self-staked2", | ||
Votes: big.NewInt(0), | ||
SelfStakeBucketIdx: candidateNoSelfStakeBucketIndex, | ||
SelfStake: big.NewInt(0), | ||
} | ||
candNonStaked1ColOwner := &Candidate{ | ||
Owner: identityset.Address(2), | ||
Operator: identityset.Address(22), | ||
Reward: identityset.Address(3), | ||
Name: "non-self-staked1-col-owner", | ||
Votes: big.NewInt(0), | ||
SelfStakeBucketIdx: candidateNoSelfStakeBucketIndex, | ||
SelfStake: big.NewInt(0), | ||
} | ||
candNonStaked1ColOpt := &Candidate{ | ||
Owner: identityset.Address(20), | ||
Operator: identityset.Address(12), | ||
Reward: identityset.Address(3), | ||
Name: "non-self-staked1-col-opt", | ||
Votes: big.NewInt(0), | ||
SelfStakeBucketIdx: candidateNoSelfStakeBucketIndex, | ||
SelfStake: big.NewInt(0), | ||
} | ||
candNonStaked1ColName := &Candidate{ | ||
Owner: identityset.Address(21), | ||
Operator: identityset.Address(23), | ||
Reward: identityset.Address(3), | ||
Name: "non-self-staked1", | ||
Votes: big.NewInt(0), | ||
SelfStakeBucketIdx: candidateNoSelfStakeBucketIndex, | ||
SelfStake: big.NewInt(0), | ||
} | ||
candStakedColBucket := &Candidate{ | ||
Owner: identityset.Address(4), | ||
Operator: identityset.Address(14), | ||
Reward: identityset.Address(3), | ||
Name: "self-staked-col-bucket", | ||
Votes: unit.ConvertIotxToRau(1200000), | ||
SelfStakeBucketIdx: 1, | ||
SelfStake: unit.ConvertIotxToRau(1200000), | ||
} | ||
|
||
checkCandidates := func(candcenter *CandidateCenter, cands []*Candidate) { | ||
r.True(testEqual(candcenter, CandidateList(cands))) | ||
// commit | ||
r.NoError(candcenter.Commit()) | ||
r.True(testEqual(candcenter, CandidateList(cands))) | ||
// from state manager | ||
dk := protocol.NewDock() | ||
view := protocol.View{} | ||
r.NoError(view.Write(_protocolID, candcenter)) | ||
dk.Reset() | ||
candcenter = candCenterFromNewCandidateStateManager(r, view, dk) | ||
r.True(testEqual(candcenter, CandidateList(cands))) | ||
} | ||
t.Run("nonstaked candidate not collision on bucket", func(t *testing.T) { | ||
candcenter, err := NewCandidateCenter(nil) | ||
r.NoError(err) | ||
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. add a valid candidate |
||
r.NoError(candcenter.Upsert(candNonStaked1)) | ||
r.NoError(candcenter.Upsert(candNonStaked2)) | ||
checkCandidates(candcenter, []*Candidate{candNonStaked1, candNonStaked2}) | ||
}) | ||
t.Run("staked candidate collision on bucket", func(t *testing.T) { | ||
candcenter, err := NewCandidateCenter(nil) | ||
r.NoError(err) | ||
r.NoError(candcenter.Upsert(candStaked)) | ||
r.ErrorIs(candcenter.Upsert(candStakedColBucket), ErrInvalidSelfStkIndex) | ||
checkCandidates(candcenter, []*Candidate{candStaked}) | ||
}) | ||
t.Run("nonstaked candidate collision on operator", func(t *testing.T) { | ||
candcenter, err := NewCandidateCenter(nil) | ||
r.NoError(err) | ||
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. add a valid candidate |
||
r.NoError(candcenter.Upsert(candNonStaked1)) | ||
r.ErrorIs(candcenter.Upsert(candNonStaked1ColOpt), ErrInvalidOperator) | ||
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. can combine the next test into here by just adding 1 line: |
||
checkCandidates(candcenter, []*Candidate{candNonStaked1}) | ||
}) | ||
t.Run("nonstaked candidate collision on name", func(t *testing.T) { | ||
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. merge into previous test |
||
candcenter, err := NewCandidateCenter(nil) | ||
r.NoError(err) | ||
r.NoError(candcenter.Upsert(candNonStaked1)) | ||
r.ErrorIs(candcenter.Upsert(candNonStaked1ColName), action.ErrInvalidCanName) | ||
checkCandidates(candcenter, []*Candidate{candNonStaked1}) | ||
}) | ||
t.Run("nonstaked candidate update on owner", func(t *testing.T) { | ||
candcenter, err := NewCandidateCenter(nil) | ||
r.NoError(err) | ||
r.NoError(candcenter.Upsert(candNonStaked1)) | ||
r.NoError(candcenter.Upsert(candNonStaked1ColOwner)) | ||
checkCandidates(candcenter, []*Candidate{candNonStaked1ColOwner}) | ||
}) | ||
t.Run("change bucket", func(t *testing.T) { | ||
candcenter, err := NewCandidateCenter(nil) | ||
r.NoError(err) | ||
r.NoError(candcenter.Upsert(candNonStaked1)) | ||
// settle self-stake bucket | ||
candStaked := candNonStaked1.Clone() | ||
candStaked.SelfStakeBucketIdx = 1 | ||
candStaked.SelfStake = unit.ConvertIotxToRau(1200000) | ||
r.NoError(candcenter.Upsert(candStaked)) | ||
// change self-stake bucket | ||
candUpdated := candStaked.Clone() | ||
candUpdated.SelfStakeBucketIdx = 2 | ||
r.NoError(candcenter.Upsert(candUpdated)) | ||
checkCandidates(candcenter, []*Candidate{candUpdated}) | ||
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.
|
||
}) | ||
} | ||
|
||
func candCenterFromNewCandidateStateManager(r *require.Assertions, view protocol.View, dk protocol.Dock) *CandidateCenter { | ||
// get cand center: csm.ConstructBaseView | ||
v, err := view.Read(_protocolID) | ||
|
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.
candidateNoSelfStakeBucketIndex is a special value?
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, it means candidate has not already been self-staked
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.
rename to `_candidateNoSelfStakeBucketIndex``
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.
what does it mean a self stake bucket is settled?
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 method is used to wrap the code
d.SelfStakeBucketIdx != candidateNoSelfStakeBucketIndex
to avoid making this judgement in multiple places.Basically, it returns
true
in three cases: