Skip to content
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

Merged

Conversation

Aharonee
Copy link
Contributor

@Aharonee Aharonee commented Mar 14, 2022

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.

@Aharonee Aharonee changed the title Add a new caching mechanism for the ledger - latest 512 block headers Algod: Add a new caching mechanism for the ledger - latest 512 block headers Mar 14, 2022
@Aharonee Aharonee force-pushed the stateproof-add_block_headers_cache branch from 9345ada to eae7e56 Compare March 16, 2022 09:27
Copy link
Contributor

@id-ms id-ms left a 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

ledger/blockHeadersCache.go Outdated Show resolved Hide resolved
ledger/blockHeaderCache.go Outdated Show resolved Hide resolved
ledger/blockHeaderCache_test.go Outdated Show resolved Hide resolved
ledger/blockHeaderCache_test.go Show resolved Hide resolved
Copy link
Contributor

@algonautshant algonautshant left a 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.

ledger/blockHeaderCache.go Outdated Show resolved Hide resolved
ledger/blockHeaderCache.go Outdated Show resolved Hide resolved
ledger/blockHeaderCache.go Outdated Show resolved Hide resolved
ledger/blockHeaderCache.go Outdated Show resolved Hide resolved
ledger/blockHeaderCache.go Outdated Show resolved Hide resolved
ledger/blockHeaderCache.go Outdated Show resolved Hide resolved
ledger/blockHeaderCache.go Outdated Show resolved Hide resolved
ledger/blockHeaderCache.go Outdated Show resolved Hide resolved
"github.com/algorand/go-deadlock"
)

const cacheSize = 512
Copy link
Contributor

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.

Copy link
Contributor

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.

Copy link
Contributor

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 -;)

  1. change the variable name to so that it would not potentially conflict. i.e. blockHeadersSlidingWindowCacheSize or similar.
  2. 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.

generating the stateproof message will be sequential in memory.
Might improve performance in terms of CPU caching.
*/
idx := basics.SubSaturate(uint64(round), 1) % cacheSize
Copy link
Contributor

@tsachiherman tsachiherman Mar 17, 2022

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.

Copy link
Contributor

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.

Copy link
Contributor

@id-ms id-ms Mar 17, 2022

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?

Copy link
Contributor

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.

Copy link
Contributor

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

Copy link
Contributor

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-commenter
Copy link

codecov-commenter commented Mar 20, 2022

Codecov Report

Merging #3765 (fcd14b0) into feature/stateproofs (f9a8d27) will increase coverage by 0.00%.
The diff coverage is 100.00%.

@@                 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     
Impacted Files Coverage Δ
ledger/blockHeaderCache.go 100.00% <100.00%> (ø)
ledger/ledger.go 59.53% <100.00%> (-0.14%) ⬇️
crypto/merkletrie/trie.go 66.42% <0.00%> (-2.19%) ⬇️
node/node.go 23.48% <0.00%> (-1.87%) ⬇️
crypto/merkletrie/node.go 91.62% <0.00%> (-1.87%) ⬇️
network/requestTracker.go 70.25% <0.00%> (-0.87%) ⬇️
network/wsNetwork.go 62.79% <0.00%> (ø)
catchup/service.go 70.12% <0.00%> (+0.74%) ⬆️
util/metrics/counter.go 80.95% <0.00%> (+2.38%) ⬆️
util/metrics/gauge.go 70.66% <0.00%> (+2.66%) ⬆️
... and 1 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update f9a8d27...fcd14b0. Read the comment docs.

@Aharonee Aharonee force-pushed the stateproof-add_block_headers_cache branch from fcd14b0 to 1dc3caf Compare March 20, 2022 14:41
@id-ms id-ms merged commit 3dd4c6b into algorand:feature/stateproofs Mar 20, 2022
@jannotti
Copy link
Contributor

jannotti commented Oct 11, 2022 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants