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
rpc: Fix response time grow over time #3438
Conversation
valInfo.LastHeightChanged, | ||
height, | ||
), | ||
) | ||
} | ||
valInfo2.ValidatorSet.IncrementProposerPriority(int(height - valInfo.LastHeightChanged)) // mutate | ||
valInfo = valInfo2 |
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.
A much simpler solution here might be saving/memoizing valInfo2 saveValidatorsInfo(db, height, valInfo2)
instead of the whole shebang with the blockstore. Thoughts?
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.
A much simpler solution here might be saving/memoizing valInfo2
saveValidatorsInfo(db, height, valInfo2)
instead of the whole shebang with the blockstore. Thoughts?
Ofcourse, if we can save all validatorInfo. The previous implement only save whole validatorInfo of latest 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.
A much simpler solution here might be saving/memoizing valInfo2
saveValidatorsInfo(db, height, valInfo2)
instead of the whole shebang with the blockstore. Thoughts?
so should I modify code to saveValidatorsInfo(db, height, valInfo2)
, since it store redundant information ? @melekes updated. you may have a review.
Codecov Report
@@ Coverage Diff @@
## develop #3438 +/- ##
===========================================
+ Coverage 64.2% 64.21% +0.01%
===========================================
Files 213 213
Lines 17362 17325 -37
===========================================
- Hits 11147 11126 -21
+ Misses 5290 5278 -12
+ Partials 925 921 -4
|
state/store.go
Outdated
) | ||
} | ||
valInfo2.ValidatorSet.IncrementProposerPriority(int(height - valInfo.LastHeightChanged)) // mutate | ||
valInfo = valInfo2 |
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 thought we'd save valInfo2 here, not save for every height! I.e. we only call save once somebody tries to access it.
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 thought we'd save valInfo2 here, not save for every height! I.e. we only call save once somebody tries to access it.
But the replay result is not correct when there are two or more rounds at one 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.
How so? If we're using int(height - valInfo.LastHeightChanged)
difference
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.
But the replay result is not correct when there are two or more rounds at one height.
Is that because we call IncrementProposerPriority
per round for the same height (several times) then? Can you give an example (ideally a test) which clearly shows what you mean by "not correct" here @guagualvcha? That would be awesome.
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.
Note that the per-height proposer selection is independent of the per-round proposer selection. So the proposer at height=1 round=1 is the same as the proposer for height=2 round=0. Ie. see #3044
Maybe we need a second implementation of the IncrementProposerPriority for when we know the validator set hasn't changed that can be computed much more quickly for this use case. cc @ancazamfir |
Great, that would be the final solution. |
h1 - the height of previous validator set change if h == h2 we could get the set from the state; else we have to do IncrementProposerPriority(h-h1) and I can't think of a much better way to compute it faster and still be accurate wrt proposer priorities. Maybe something like this:
May still be costly for high total voting power values. Alternatively we could save the valInfo every N blocks and then call Increment with max N times.
@melekes - could you please clarify? There may be a lot of accesses for different heights, isn't memory usage a concern? |
@melekes @ancazamfir updated as ancazamfir said. Please have a review. |
yes, but not big though comparing to DoS attack vector. |
@guagualvcha please refrain from doing a rebase & force-push next time. When/if you do |
@guagualvcha Have you tested this? What is the response time now? What about with 1<<14 or 15? |
Closing in favor of #3537 |
@@ -9,6 +9,10 @@ import ( | |||
"github.com/tendermint/tendermint/types" | |||
) | |||
|
|||
const ( | |||
ValidatorSetStoreInterval = 1 << 10 |
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 don't think we need to expose it
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.
let's rename to valSetStoreInterval
and add a comment persist validator set every valSetStoreInterval blocks to avoid LoadValidators taking too much time. Refs https://github.com/tendermint/tendermint/pull/3438
if valInfo.ValidatorSet == nil { | ||
valInfo2 := loadValidatorsInfo(db, valInfo.LastHeightChanged) | ||
queryHeight := valInfo.LastHeightChanged |
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.
let's create a var called lastStoreHeight := height - height%valSetStoreInterval
/validators rpc response time grow with time.
Steps To Reproduce:
2.
time curl 127.0.0.1:26657/validators
, it takes 0.005stime curl 127.0.0.1:26857/validators
, it takes 1.25sThe api consumes cpu resouces, in the long run, a small scale of DDOS can make the node
a zombie process.
Acturally the logic to do
IncrementProposerPriority
byheight - valInfo.LastHeightChanged
times will not replay the exactlyProposerPriority
once there are two or more round.