-
Notifications
You must be signed in to change notification settings - Fork 471
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
Algod: Add a new caching mechanism for the ledger - latest 512 block headers #3765
Algod: Add a new caching mechanism for the ledger - latest 512 block headers #3765
Conversation
b59ab51
to
41277ab
Compare
9345ada
to
eae7e56
Compare
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.
overall looks pretty good!
just a few minor changes
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.
Looks great.
Some optimizations and questions.
Also, the PR is missing explanation: please add a few words about the purpose of this.
Co-authored-by: Shant Karakashian <[email protected]>
Co-authored-by: Shant Karakashian <[email protected]>
ledger/blockHeaderCache.go
Outdated
"github.com/algorand/go-deadlock" | ||
) | ||
|
||
const cacheSize = 512 |
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 isn't a great name for a global variable. But more important, I don't think that it should be a const anyway.
I believe that what you intended to have here is the CompactCertRounds * 2, and if so, we should make it depending on that value. Given that you need a constant value here, you could create a MaxCompactCertRounds
in the config package and use it 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.
currently, we have a test that breaks if this number is not optimal for the current CompactCertRounds
.
I'm not sure I like this value to be implicitly changed if the CompactCertRounds
changes.
From my perspective, we should have a test that breaks and someone explicitly changes it if 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.
That's fine - in that case, I have two requests -;)
- change the variable name to so that it would not potentially conflict. i.e.
blockHeadersSlidingWindowCacheSize
or similar. - add a comment on top of this constant, describing why this value was selected, and specifying the name of the unit test that validate the correctness of this value.
ledger/blockHeaderCache.go
Outdated
generating the stateproof message will be sequential in memory. | ||
Might improve performance in terms of CPU caching. | ||
*/ | ||
idx := basics.SubSaturate(uint64(round), 1) % cacheSize |
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 think that the basics.SubSaturate
here ( and below ) isn't required. I agree that sequential ordering is good, but it doesn't really matter if you shift the array by one or not.
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.
idx := (round - 1 ) % latestCacheSize
should be the same in my opinion.
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.
round -1 might overflow and I don't really like it. that's why I suggested using basics.SubSaturate
. @tsachiherman do you have a suggestion of how to keep the blockheaders sequentially in memory and not use the -1?
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, just use idx := round % cacheSize
. It would still keep the sequential ordering, but would not "rotate" the array. It doesn't really give you any advantage to shift it as long as you're doing it symmetrically.
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.
In order to construct stateproof message for interval 512 (for example) we need to gather all the headers for rounds : [ 257, 258 ... 512]. If we use idx := round % cacheSize
we end up with the last round (512) placed in index 0 in the cache. I would like the order of the cache to reflect the order of fetching the message
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.
Ah - I see. I think that when you'll get to the point of actually getting these headers, you'll see that it won't help you.
i.e. you can't return a slice of [257:] since the backing array might get changed. Instead, you'll need to create a copy of the backing array... and if you're creating a copy of the backing array, the index plays a smaller part.
Also, you could calculate the index in a more "branchless" way:
idx := (round + cacheSize - 1) % cacheSize
either way, I'd encourage you to implement all the methods you would need on this cache as well as to document the rationale for non-trivial indexing choices.
Codecov Report
@@ Coverage Diff @@
## feature/stateproofs #3765 +/- ##
====================================================
Coverage 49.61% 49.61%
====================================================
Files 391 392 +1
Lines 68529 68553 +24
====================================================
+ Hits 33998 34011 +13
- Misses 30787 30804 +17
+ Partials 3744 3738 -6
Continue to review full report at Codecov.
|
fcd14b0
to
1dc3caf
Compare
There are couple other places we need (or will need) access to old
headers. AVM code should be allowed to access the LatestTimestamp from
previous headers, and an upcoming opcode, `block_seed` should be able to as
well. They will need to look back at least MaxTxLiftetime (1000). (Maybe
longer to support catchup.). It would be nice if all of these use cases use
the same mechanism.
…On Mon, Mar 14, 2022 at 8:15 AM Or Aharonee ***@***.***> wrote:
------------------------------
You can view, comment on, or merge this pull request online at:
#3765
Commit Summary
- 530fbde
<530fbde>
Implemented a new caching mechanism for the ledger - latest 512 block
headers.
- 7fc60af
<7fc60af>
Fix small bug and add init for cache
- de60364
<de60364>
Add unit tests
File Changes
(3 files <https://github.com/algorand/go-algorand/pull/3765/files>)
- *A* ledger/blockHeadersCache.go
<https://github.com/algorand/go-algorand/pull/3765/files#diff-529321c786df1373ae8db05dc01aa97468f8600939ddc3abb1deea06c510ea03>
(87)
- *A* ledger/blockHeadersCache_test.go
<https://github.com/algorand/go-algorand/pull/3765/files#diff-606048023c00fdc6ef18f3be13d0ee3d449dd5d4c58ef8f2dd8f23bee1fe1137>
(73)
- *M* ledger/ledger.go
<https://github.com/algorand/go-algorand/pull/3765/files#diff-362fe6e8cc259e0660b63453dc0c87f2e19be9f4a31b056be34d692eb138cba0>
(7)
Patch Links:
- https://github.com/algorand/go-algorand/pull/3765.patch
- https://github.com/algorand/go-algorand/pull/3765.diff
—
Reply to this email directly, view it on GitHub
<#3765>, or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AADL7TZQE4PCKY5UYXKXAE3U74UUXANCNFSM5QVKZXLA>
.
You are receiving this because you are subscribed to this thread.Message
ID: ***@***.***>
|
Generating the State Proof message periodically requires building a merkle tree from the previous 256 (and in the future perhaps 64) block headers.
This cache will keep recent block headers in memory, improving the time required for fetching them by an order of magnitude.