Skip to content
This repository has been archived by the owner on Aug 2, 2022. It is now read-only.

Refactor block_header_state #6588

Merged
merged 4 commits into from
Jan 28, 2019

Conversation

arhag
Copy link
Contributor

@arhag arhag commented Jan 11, 2019

This PR refactors how block_header_state is updated as new blocks are processed.

The previous system had two alternative paths to go from the block_header_state for block N to the block_header_state for block N+1. One of the paths made the transition directly in one step using the block header of block N+1 as an input. However, this path is not possible when producing a block (including speculative production). So an alternative path was present that first generated a tentative (but incorrect) instance of block_header_state using only the block header state of block N and the timestamp of block N+1 as the inputs. Then mutators were called to mutate the instance as more information was made available during block generation until eventually the instance had the appropriate state to reflect a final block header state for block N+1.

This PR changes the way transitions are calculated (but without actually changing any of the consensus rules) to make it conceptually simpler to understand what is happening and to leverage the C++ type system to reduce the likelihood of errors. A new type pending_block_header_state is introduce which is computed from the previous block's block_header_state and the current block's timestamp. Then, another function transitions from the pending_block_header_state of block N+1 to block_header_state of block N+1 by taking the block header of block N+1 as input. Both the pending_block_header_state and block_header_state instances are immutable, so there is no complication introduced by possible mutations of header state after instantiation. The direct path is implemented by simply making the transition from block_header_state of block N to pending_block_header_state of block N+1 and then immediately making the transitioning from pending_block_header_state of block N+1 to block_header_state of block N+1. The path during block generate also follows the exact same path except that there is a pause in between the two transitions which is the time during which pending transactions to be included in the new block are processed. The state in pending_block_header_state along with an optional new pending producer schedule (tracked separately in controller) provides enough information to satisfy the requirements to correctly process pending transactions.

This refactor helps prepare for the later changes that will be made to block_header_state to introduce the field tracking the currently activated protocol features (which is not yet included in this change).

I am aware that this change will break both snapshots and the serialization format of forkdb.dat. This is the first part of a larger sequence of other refactors and further changes towards building the foundations that enable consensus protocol upgrade features. With those later changes, the forkdb.dat format will officially change and the new format will be stored with proper versioning in a file fork_db.dat. Furthermore, the later changes would introduce a second version of the chain snapshot and nodeos will not support reading from the first version of chain snapshots. These eventual changes will force a replay from genesis, which is desired behavior to support one of the protocol features planned.

@arhag arhag mentioned this pull request Jan 17, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants