Skip to content

Commit

Permalink
Merge 4ab8f36 into 7a09f4b
Browse files Browse the repository at this point in the history
  • Loading branch information
envestcc authored Aug 24, 2023
2 parents 7a09f4b + 4ab8f36 commit e8343f2
Show file tree
Hide file tree
Showing 12 changed files with 668 additions and 269 deletions.
12 changes: 6 additions & 6 deletions action/protocol/staking/contractstake_indexer.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,16 @@ type (
ContractStakingIndexer interface {
// CandidateVotes returns the total staked votes of a candidate
// candidate identified by owner address
CandidateVotes(ownerAddr address.Address) *big.Int
CandidateVotes(ownerAddr address.Address, height uint64) (*big.Int, error)
// Buckets returns active buckets
Buckets() ([]*VoteBucket, error)
Buckets(height uint64) ([]*VoteBucket, error)
// BucketsByIndices returns active buckets by indices
BucketsByIndices([]uint64) ([]*VoteBucket, error)
BucketsByIndices([]uint64, uint64) ([]*VoteBucket, error)
// BucketsByCandidate returns active buckets by candidate
BucketsByCandidate(ownerAddr address.Address) ([]*VoteBucket, error)
BucketsByCandidate(ownerAddr address.Address, height uint64) ([]*VoteBucket, error)
// TotalBucketCount returns the total number of buckets including burned buckets
TotalBucketCount() uint64
TotalBucketCount(height uint64) (uint64, error)
// BucketTypes returns the active bucket types
BucketTypes() ([]*ContractStakingBucketType, error)
BucketTypes(height uint64) ([]*ContractStakingBucketType, error)
}
)
54 changes: 28 additions & 26 deletions action/protocol/staking/contractstake_indexer_mock.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 12 additions & 1 deletion action/protocol/staking/protocol.go
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,10 @@ func (p *Protocol) Validate(ctx context.Context, act action.Action, sr protocol.

// ActiveCandidates returns all active candidates in candidate center
func (p *Protocol) ActiveCandidates(ctx context.Context, sr protocol.StateReader, height uint64) (state.CandidateList, error) {
srHeight, err := sr.Height()
if err != nil {
return nil, errors.Wrap(err, "failed to get StateReader height")
}
c, err := ConstructBaseView(sr)
if err != nil {
return nil, errors.Wrap(err, "failed to get ActiveCandidates")
Expand All @@ -476,7 +480,14 @@ func (p *Protocol) ActiveCandidates(ctx context.Context, sr protocol.StateReader
featureCtx := protocol.MustGetFeatureCtx(ctx)
for i := range list {
if p.contractStakingIndexer != nil && featureCtx.AddContractStakingVotes {
list[i].Votes.Add(list[i].Votes, p.contractStakingIndexer.CandidateVotes(list[i].Owner))
// specifying the height param instead of query latest from indexer directly, aims to cause error when indexer falls behind
// currently there are two possible sr (i.e. factory or workingSet), it means the height could be chain height or current block height
// using height-1 will cover the two scenario while detect whether the indexer is lagging behind
contractVotes, err := p.contractStakingIndexer.CandidateVotes(list[i].Owner, srHeight-1)
if err != nil {
return nil, errors.Wrap(err, "failed to get CandidateVotes from contractStakingIndexer")
}
list[i].Votes.Add(list[i].Votes, contractVotes)
}
if list[i].SelfStake.Cmp(p.config.RegistrationConsts.MinSelfStake) >= 0 {
cand = append(cand, list[i])
Expand Down
69 changes: 69 additions & 0 deletions action/protocol/staking/protocol_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -394,3 +394,72 @@ func Test_CreateGenesisStates(t *testing.T) {
}
}
}

func TestProtocol_ActiveCandidates(t *testing.T) {
require := require.New(t)
ctrl := gomock.NewController(t)
sm := testdb.NewMockStateManagerWithoutHeightFunc(ctrl)
csIndexer := NewMockContractStakingIndexer(ctrl)

selfStake, _ := new(big.Int).SetString("1200000000000000000000000", 10)
cfg := genesis.Default.Staking
cfg.BootstrapCandidates = []genesis.BootstrapCandidate{
{
OwnerAddress: identityset.Address(22).String(),
OperatorAddress: identityset.Address(23).String(),
RewardAddress: identityset.Address(23).String(),
Name: "test1",
SelfStakingTokens: selfStake.String(),
},
}
p, err := NewProtocol(nil, &BuilderConfig{
Staking: cfg,
PersistStakingPatchBlock: math.MaxUint64,
}, nil, csIndexer, genesis.Default.GreenlandBlockHeight)
require.NoError(err)

blkHeight := genesis.Default.QuebecBlockHeight + 1
ctx := protocol.WithBlockCtx(
genesis.WithGenesisContext(context.Background(), genesis.Default),
protocol.BlockCtx{
BlockHeight: blkHeight,
},
)
ctx = protocol.WithFeatureCtx(protocol.WithFeatureWithHeightCtx(ctx))
sm.EXPECT().Height().Return(blkHeight, nil).AnyTimes()

v, err := p.Start(ctx, sm)
require.NoError(err)
require.NoError(sm.WriteView(_protocolID, v))

err = p.CreateGenesisStates(ctx, sm)
require.NoError(err)

var csIndexerHeight, csVotes uint64
csIndexer.EXPECT().CandidateVotes(gomock.Any(), gomock.Any()).DoAndReturn(func(ownerAddr address.Address, height uint64) (*big.Int, error) {
if height != csIndexerHeight {
return nil, errors.Errorf("invalid height")
}
return big.NewInt(int64(csVotes)), nil
}).AnyTimes()

t.Run("contract staking indexer falls behind", func(t *testing.T) {
csIndexerHeight = 10
_, err := p.ActiveCandidates(ctx, sm, 0)
require.ErrorContains(err, "invalid height")
})

t.Run("contract staking indexer up to date", func(t *testing.T) {
csIndexerHeight = blkHeight - 1
csVotes = 0
cands, err := p.ActiveCandidates(ctx, sm, 0)
require.NoError(err)
require.Len(cands, 1)
originCandVotes := cands[0].Votes
csVotes = 100
cands, err = p.ActiveCandidates(ctx, sm, 0)
require.NoError(err)
require.Len(cands, 1)
require.EqualValues(100, cands[0].Votes.Sub(cands[0].Votes, originCandVotes).Uint64())
})
}
37 changes: 23 additions & 14 deletions action/protocol/staking/staking_statereader.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ func (c *compositeStakingStateReader) readStateBuckets(ctx context.Context, req
}

// read LSD buckets
lsdBuckets, err := c.contractIndexer.Buckets()
lsdBuckets, err := c.contractIndexer.Buckets(inputHeight)
if err != nil {
return nil, 0, err
}
Expand All @@ -99,7 +99,7 @@ func (c *compositeStakingStateReader) readStateBucketsByVoter(ctx context.Contex
}

// read LSD buckets
lsdBuckets, err := c.contractIndexer.Buckets()
lsdBuckets, err := c.contractIndexer.Buckets(height)
if err != nil {
return nil, 0, err
}
Expand Down Expand Up @@ -131,7 +131,7 @@ func (c *compositeStakingStateReader) readStateBucketsByCandidate(ctx context.Co
if candidate == nil {
return &iotextypes.VoteBucketList{}, height, nil

Check warning on line 132 in action/protocol/staking/staking_statereader.go

View check run for this annotation

Codecov / codecov/patch

action/protocol/staking/staking_statereader.go#L132

Added line #L132 was not covered by tests
}
lsdBuckets, err := c.contractIndexer.BucketsByCandidate(candidate.Owner)
lsdBuckets, err := c.contractIndexer.BucketsByCandidate(candidate.Owner, height)
if err != nil {
return nil, 0, err
}
Expand All @@ -156,7 +156,7 @@ func (c *compositeStakingStateReader) readStateBucketByIndices(ctx context.Conte
}

// read LSD buckets
lsdBuckets, err := c.contractIndexer.BucketsByIndices(req.GetIndex())
lsdBuckets, err := c.contractIndexer.BucketsByIndices(req.GetIndex(), height)
if err != nil {
return nil, 0, err
}
Expand All @@ -177,12 +177,16 @@ func (c *compositeStakingStateReader) readStateBucketCount(ctx context.Context,
if !c.isContractStakingEnabled() {
return bucketCnt, height, nil

Check warning on line 178 in action/protocol/staking/staking_statereader.go

View check run for this annotation

Codecov / codecov/patch

action/protocol/staking/staking_statereader.go#L178

Added line #L178 was not covered by tests
}
buckets, err := c.contractIndexer.Buckets()
buckets, err := c.contractIndexer.Buckets(height)
if err != nil {
return nil, 0, err
}
bucketCnt.Active += uint64(len(buckets))
bucketCnt.Total += c.contractIndexer.TotalBucketCount()
tbc, err := c.contractIndexer.TotalBucketCount(height)
if err != nil {
return nil, 0, err
}
bucketCnt.Total += tbc
return bucketCnt, height, nil
}

Expand Down Expand Up @@ -220,7 +224,7 @@ func (c *compositeStakingStateReader) readStateCandidates(ctx context.Context, r
return candidates, height, nil

Check warning on line 224 in action/protocol/staking/staking_statereader.go

View check run for this annotation

Codecov / codecov/patch

action/protocol/staking/staking_statereader.go#L224

Added line #L224 was not covered by tests
}
for _, candidate := range candidates.Candidates {
if err = addContractStakingVotes(candidate, c.contractIndexer); err != nil {
if err = addContractStakingVotes(candidate, c.contractIndexer, height); err != nil {
return nil, 0, err
}
}
Expand All @@ -238,7 +242,7 @@ func (c *compositeStakingStateReader) readStateCandidateByName(ctx context.Conte
if !protocol.MustGetFeatureCtx(ctx).AddContractStakingVotes {
return candidate, height, nil

Check warning on line 243 in action/protocol/staking/staking_statereader.go

View check run for this annotation

Codecov / codecov/patch

action/protocol/staking/staking_statereader.go#L243

Added line #L243 was not covered by tests
}
if err := addContractStakingVotes(candidate, c.contractIndexer); err != nil {
if err := addContractStakingVotes(candidate, c.contractIndexer, height); err != nil {
return nil, 0, err
}
return candidate, height, nil
Expand All @@ -255,7 +259,7 @@ func (c *compositeStakingStateReader) readStateCandidateByAddress(ctx context.Co
if !protocol.MustGetFeatureCtx(ctx).AddContractStakingVotes {
return candidate, height, nil

Check warning on line 260 in action/protocol/staking/staking_statereader.go

View check run for this annotation

Codecov / codecov/patch

action/protocol/staking/staking_statereader.go#L260

Added line #L260 was not covered by tests
}
if err := addContractStakingVotes(candidate, c.contractIndexer); err != nil {
if err := addContractStakingVotes(candidate, c.contractIndexer, height); err != nil {
return nil, 0, err
}
return candidate, height, nil
Expand All @@ -275,7 +279,7 @@ func (c *compositeStakingStateReader) readStateTotalStakingAmount(ctx context.Co
return accountMeta, height, nil

Check warning on line 279 in action/protocol/staking/staking_statereader.go

View check run for this annotation

Codecov / codecov/patch

action/protocol/staking/staking_statereader.go#L279

Added line #L279 was not covered by tests
}
// add contract staking amount
buckets, err := c.contractIndexer.Buckets()
buckets, err := c.contractIndexer.Buckets(height)
if err != nil {
return nil, 0, err
}
Expand All @@ -291,7 +295,8 @@ func (c *compositeStakingStateReader) readStateContractStakingBucketTypes(ctx co
if !c.isContractStakingEnabled() {
return &iotextypes.ContractStakingBucketTypeList{}, c.nativeSR.Height(), nil

Check warning on line 296 in action/protocol/staking/staking_statereader.go

View check run for this annotation

Codecov / codecov/patch

action/protocol/staking/staking_statereader.go#L294-L296

Added lines #L294 - L296 were not covered by tests
}
bts, err := c.contractIndexer.BucketTypes()
height := c.nativeSR.Height()
bts, err := c.contractIndexer.BucketTypes(height)
if err != nil {

Check warning on line 300 in action/protocol/staking/staking_statereader.go

View check run for this annotation

Codecov / codecov/patch

action/protocol/staking/staking_statereader.go#L298-L300

Added lines #L298 - L300 were not covered by tests
return nil, 0, err
}
Expand All @@ -302,14 +307,14 @@ func (c *compositeStakingStateReader) readStateContractStakingBucketTypes(ctx co
StakedDuration: uint32(bt.Duration),
})

Check warning on line 308 in action/protocol/staking/staking_statereader.go

View check run for this annotation

Codecov / codecov/patch

action/protocol/staking/staking_statereader.go#L303-L308

Added lines #L303 - L308 were not covered by tests
}
return &iotextypes.ContractStakingBucketTypeList{BucketTypes: pbBts}, c.nativeSR.Height(), nil
return &iotextypes.ContractStakingBucketTypeList{BucketTypes: pbBts}, height, nil

Check warning on line 310 in action/protocol/staking/staking_statereader.go

View check run for this annotation

Codecov / codecov/patch

action/protocol/staking/staking_statereader.go#L310

Added line #L310 was not covered by tests
}

func (c *compositeStakingStateReader) isContractStakingEnabled() bool {
return c.contractIndexer != nil
}

func addContractStakingVotes(candidate *iotextypes.CandidateV2, contractStakingSR ContractStakingIndexer) error {
func addContractStakingVotes(candidate *iotextypes.CandidateV2, contractStakingSR ContractStakingIndexer, height uint64) error {
votes, ok := big.NewInt(0).SetString(candidate.TotalWeightedVotes, 10)
if !ok {
return errors.Errorf("invalid total weighted votes %s", candidate.TotalWeightedVotes)

Check warning on line 320 in action/protocol/staking/staking_statereader.go

View check run for this annotation

Codecov / codecov/patch

action/protocol/staking/staking_statereader.go#L320

Added line #L320 was not covered by tests
Expand All @@ -318,7 +323,11 @@ func addContractStakingVotes(candidate *iotextypes.CandidateV2, contractStakingS
if err != nil {
return err
}
votes.Add(votes, contractStakingSR.CandidateVotes(addr))
contractVotes, err := contractStakingSR.CandidateVotes(addr, height)
if err != nil {
return err
}
votes.Add(votes, contractVotes)
candidate.TotalWeightedVotes = votes.String()
return nil
}
Expand Down
Loading

0 comments on commit e8343f2

Please sign in to comment.