-
Notifications
You must be signed in to change notification settings - Fork 992
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
Sync Performance: Support requesting kernel MMRs separate from the rest of TxHashSet #1968
Comments
It would also be interesting to have the rangeproofs be requested separately for a given set of output positions (possibly through a bloom filter). The idea would be to have a client request a random subset of range proofs of its choosing for validation. This would be useful for light clients that could validate range proofs statistically by getting say only 20% of them. We could even have some light clients not request any range proof at all and trust the miners have done that validation for them. |
So you're thinking an additional message for that? We would still be required to have a separate message that gets ALL of the non-pruned leaves for the outputs and rangeproofs, correct? |
I'm sure something similar has already been proposed, but I wanted to make a moderately concrete proposal for how to efficiently request and receive kernels, so I can get everyone's thoughts on it. PROPOSAL: Have 2 requests and 2 responses for kernel retrieval. We can worry about the names later, but for now: GetKernelRoots { KernelRoots { Kernel_mmr_roots could hold a merklish root for each, say, 512 TxKernels (leaves) in the kernel_mmr. So, for the kernels from leaf index 0 to leaf index 511, find the merklish root of those, and that would be the first hash in kernel_mmr_roots. Continue to do the same until you reach the final TxKernel/leaf in the kernel_mmr. GetKernels { Kernels { After first calling GetKernelRoots for 1 peer, you will have all of the merklish roots for each batch of kernels that are requested using the GetKernels message. This allows you to easily parallelize the calls to GetKernels, since you could request kernels 0-511 from Peer A, 512-1023 from Peer B, and so on. Also, you can validate each batch as it comes in (as part of a Kernels message), since you know what the merklish root of it should be. |
Just reading through this now.
You can validate that what you received is what the sender says they sent, but this won't actually validate that the kernels are "correct". To do this you must validate the kernel MMR root against the block headers. There are a couple of existing things we can leverage here -
We can potentially download in parallel from different peers, but to validate the kernels we can only do this sequentially, by appending the kernels to the "one true" kernel MMR and verifying the root at various MMR sizes (corresponding to various headers). Say header 1 committed to the kernel MMR root for a kernel MMR of size 7. In fact we currently do this, but in reverse order as part of the txhashset.zip validation. We "rewind" back through the header chain, verifying the kernel MMR root for each header. If we're going to rebuild locally from just the leaves then we can do both simultaneously - build it incrementally and verify it as we go. Make sense? |
As an example, assume there are 1024 kernels. The call to GetKernelRoots will produce a response in a KernelRoots message with something like Vec(kernel_mmr_roots) = ['123456...', 'abcde...']. You can then call GetKernels to request the first 512 kernels from Peer A, and request the next 512 kernels from Peer B. Peer A should respond with Kernels{'kernel_mmr_root'='123456...', kernels=['kern0...', 'kern1...', ..., 'kern511...']}. Peer B should respond with Kernels{'kernel_mmr_root'='abcde...', kernels=['kern0...', 'kern1...', ..., 'kern511...']}. Each of those should be verifiable independently. Does that make sense? |
@antiochp Just re-read the rest of your message. Why would we need to 'rewind' and check each header against the kernel_root individually? Shouldn't verifying against the most recent one be enough to know that you have the right kernels, since it's a cryptographically secure hash? Or am I missing something? |
the most recent kernel_root can be set to the mmr root of an arbitrary kernel mmr, not necessarily one consistent with historical kernels. |
I agree with this:
From the header chain, receiving those kernels by chunks, we can validate against the root hashes in the header chain as kernels come. We could even have some lookahead for download to introduce some parallelization as we also know exact kernel indices from the blocks headers. |
I agree with the suggestions, and am currently going with the following 2 messages for kernel sync: /// Request to get the kernels(leaves) from the kernel MMR up to the given block. /// Response to a Get kernels request containing the requested kernels. |
@yeastplume This issue can be closed since PIBD separates the kernel MMRs and the TxHashSet and downloads them from multiple peers |
Creating this issue to track progress on a subset of the proposals in #952. The current plan is to:
Related:
#1219
#952
#804
The text was updated successfully, but these errors were encountered: