-
Notifications
You must be signed in to change notification settings - Fork 11.8k
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
Optimize votes lookups for recent checkpoints #3673
Conversation
In the provided graph, we can see the transition from the "lookup is recent and cheap" to "lookup is older and more expensive" when the offset reaches 7. Yes you say K=16. Do you have an explanation for that ? I would expect the transition to appen around K |
I think I may have been mistaken and the chart was for K=8. I've now modified the PR to use K=sqrt(N). |
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.
Code looks good, but wee need better coverrage.
Added tests and coverage is good now. |
This PR optimizes
getPastVotes
so that for recent checkpoints it has lower gas cost than the worst case.The worst case runs in O(log n) time, but delegates can have large numbers of checkpoints: a quick search led us to find one with 8500 checkpoints, which adds around 43k gas to a vote.
In the context of governance, since there is a voting period,
getPastVotes
will be invoked with a relatively recent block which will be near the end of the checkpoints array.We modify
getPastVotes
so that it first checks to see if the sought checkpoint is a recent checkpoint, if so does a binary search among those, and otherwise does a binary search on the rest of the array. We define the recent checkpoints as the last sqrt(n), where n is the number of checkpoints. Thus, the best case cost ofgetPastVotes
is half that of the worst case, though it remains logarithmic.Some other changes bundled here:
getAtRecentBlock
togetAtProbablyRecentBlock
, to indicate that the function works even for non-recent blocks.upperLookupRecent
for other Trace/Checkpoints types, since we won't be using it and if the keys are not block numbers or timestamps it is not clear that they are worth it.