-
Notifications
You must be signed in to change notification settings - Fork 324
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
[blockindex] restrict height for contract_staking_indexer during read operation #3927
Conversation
Codecov Report
@@ Coverage Diff @@
## master #3927 +/- ##
==========================================
+ Coverage 75.38% 76.04% +0.66%
==========================================
Files 303 328 +25
Lines 25923 27897 +1974
==========================================
+ Hits 19541 21215 +1674
- Misses 5360 5590 +230
- Partials 1022 1092 +70
... and 6 files with indirect coverage changes 📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more |
blockindex/contractstaking/cache.go
Outdated
return nil | ||
} | ||
// indexer only store latest height | ||
if height != s.height { |
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.
should be height > s.height
?
in action/protocol/poll/util.go
, it is called with epoch start height
func createPostSystemActions(ctx context.Context, sr protocol.StateReader, p Protocol) {
xxx
l, err := p.CalculateCandidatesByHeight(ctx, sr, epochHeight)
xxx
}
@@ -105,7 +105,7 @@ func (dirty *contractStakingDirty) finalize() (batch.KVStoreBatch, *contractStak | |||
|
|||
func (dirty *contractStakingDirty) finalizeBatch() batch.KVStoreBatch { | |||
dirty.once.Do(func() { | |||
total := dirty.clean.TotalBucketCount() + dirty.delta.AddedBucketCnt() | |||
total := dirty.clean.totalBucketCount + dirty.delta.AddedBucketCnt() |
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.
not needed?
TotalBucketCount() has a lock inside
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, use 0 height to query latest state
@@ -125,7 +125,7 @@ func (dirty *contractStakingDirty) matchBucketType(amount *big.Int, duration uin | |||
} | |||
|
|||
func (dirty *contractStakingDirty) getBucketTypeCount() uint64 { | |||
return dirty.clean.BucketTypeCount() + dirty.delta.AddedBucketTypeCnt() | |||
return uint64(len(dirty.clean.bucketTypeMap)) + dirty.delta.AddedBucketTypeCnt() |
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.
same as above
action/protocol/staking/protocol.go
Outdated
@@ -476,7 +476,11 @@ 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)) | |||
contractVotes, err := p.contractStakingIndexer.CandidateVotes(list[i].Owner, height) |
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.
height
here equals to the height of block to be committed, that is, current factory/indexer's height + 1
so should use height-1
? pls confirm
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.
should be covered by unit test
return errors.Wrapf(ErrInvalidHeight, "expected %d, actual %d", s.height, height) | ||
} | ||
return nil | ||
} |
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.
add test cases to test ErrInvalidHeight
@@ -1342,7 +1342,7 @@ func TestContractStaking(t *testing.T) { | |||
receipts, blk := writeContract(bc, sf, dao, ap, []*callParam{¶m}, r) | |||
r.Len(receipts, 1) | |||
r.EqualValues(iotextypes.ReceiptStatus_Success, receipts[0].Status) | |||
buckets, err := indexer.Buckets() | |||
buckets, err := indexer.Buckets(blk.Height()) |
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.
if blk.Height() == indexer height + 1
, it should fire an error here
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.
block has been committed after writeContract
action/protocol/staking/protocol.go
Outdated
@@ -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) { | |||
height, err := sr.Height() |
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.
height
will override the 3rd input param, use a diff name?
BucketTypes() ([]*ContractStakingBucketType, error) | ||
BucketTypes(height uint64) ([]*ContractStakingBucketType, error) | ||
// Height returns the indexer height | ||
Height() (uint64, error) |
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.
not needed?
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, forget to revert
noErr(indexer.Buckets(h)) | ||
noErr(indexer.BucketTypes(h)) | ||
noErr(indexer.BucketsByCandidate(delegate1, h)) | ||
noErr(indexer.BucketsByIndices([]uint64{1, 2, 3, 4, 5, 8}, h)) |
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.
just use r.NoErr()
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 does not work for function with multiple return values
noErr(indexer.Bucket(1, h)) | ||
noErr(indexer.TotalBucketCount(h)) | ||
} else { | ||
hasErr(indexer.Buckets(h)) |
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.
just use r.ErrorIs(err, ErrInvalidHeight)
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 can simplify the error checking only in one line
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.
not significant/necessary, other places also have similar test code
_, err := func(x, y, z)
r.Error(err)
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.
also, no need to test all these funcs, they just call the same validateHeight()
only need to call cache.validateHeight()
on these test cases
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 move to cache_test.go
SonarCloud Quality Gate failed. 0 Bugs No Coverage information Catch issues before they fail your Quality Gate with our IDE extension SonarLint |
return nil, false, err | ||
} | ||
bt, ok := s.getBucket(id) | ||
return bt, ok, nil |
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.
BucketInfo
and BucketType
without height?
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.
Currently, it is only necessary to add height restrictions to the indexer's API
Description
Motivation:
Strictly limiting the blocks during PutBlock can avoid block skipping issues
Specifying the height during queries can help detect errors in the indexer at an earlier stage
Fixes #(issue)
Type of change
Please delete options that are not relevant.
How Has This Been Tested?
Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration
Test Configuration:
Checklist: