-
Notifications
You must be signed in to change notification settings - Fork 106
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
Chain State Design #682
Comments
What do we mean by "state" in these lines? |
I'm not sure I'm understanding the design for the in memory chain state so let me try describing my understanding of how I figured it would work and we can figure out how close it is to your design. Assuming the state service is storing the last 100 heights worth of blocks in memory and not commiting them to the disk here's how I'd expect it to be represented and modified.
|
The info we need to verify the next block and all its transactions. And any info we need to do any other tasks, such as wallet support. (In later releases.) |
okay but you say the "the chain state for each block" , so does that mean just "the entire chain that leads up to a given block" |
You described the kind of design I was thinking of. But there are a few tweaks that make the algorithm and data structures a bit simpler.
I don't think we need to explicitly track heights or lists of blocks. We can key blocks by hash, because the parent hash field points to a unique block. This map is what I called the "block pool". (If we subtract one from the height to find the parent height, there can be multiple blocks at that height. But we just want the unique parent block. And we don't need to check the child block's height at this stage, because it has already been checked as part of verification.) The map's state value contains whatever information we need to verify a child block. For example, the unspent transaction outputs and note commitment tree. We might also keep a copy of the data we use to calculate the time and difficulty medians, but we could also iterate back through the parent blocks for that info. (Unlike the transaction state, the depth of the medians is limited.)
A block add is the same operation, regardless of the chain structure:
Since forks can happen in the middle of a chain, we need to keep state for every block that could potentially fork. (The zcashd reorg limit is 100 blocks, blocks can't fork after that limit.)
The main chain consensus rule is "the chain with the greatest proof of work, breaking ties with the block this node received first". It's usually the longest chain, but that's not guaranteed. After every update, we modify the set of chain tips, which is a standard mutable set data structure. We also keep a best tip. We can track tips using Arc references to their chain states. Here's how updates work:
Requiring a strictly greater proof of work breaks ties using the first block that the node verified. Since the tie-breaker is non-deterministic, we can use "verified time" rather than "downloaded time", and still converge with other zcashd and zebrad instances. (The ordering will almost always be the same, except if the earlier block is very slow to verify.) The zcashd pruning rule is "288 blocks behind the best tip". But I think zebrad can prune much earlier, because we can just go fetch the blocks from disk as needed. (And we don't need to fetch the state from disk.) Here's how pruning old block states works:
After a chain reorg, there could be zero, one, or many mature blocks. Some may be child blocks of other mature blocks. So the algorithm has to be generic. |
We can use this network upgrade to implement different consensus rules and chain context handling for genesis blocks. Part of the chain state design in ZcashFoundation#682.
We can use this network upgrade to implement different consensus rules and chain context handling for genesis blocks. Part of the chain state design in #682.
We're doing this through the RFC process now. |
Update: See #763 for the latest design.
This description is outdated:
Open Questions:
The text was updated successfully, but these errors were encountered: