* ADR-060 accepted -> proposed Signed-off-by: Thane Thomson <connect@thanethomson.com> * ADR-061 accepted -> proposed Signed-off-by: Thane Thomson <connect@thanethomson.com> * ADR-062 implemented -> proposed Signed-off-by: Thane Thomson <connect@thanethomson.com> * ADR-063 implemented -> accepted Signed-off-by: Thane Thomson <connect@thanethomson.com> * ADR-077: Update title and status to reflect current reality Signed-off-by: Thane Thomson <connect@thanethomson.com> * ADR-078: Update status to reflect current reality Signed-off-by: Thane Thomson <connect@thanethomson.com> * ADR-079: accepted Signed-off-by: Thane Thomson <connect@thanethomson.com> * ADR-068 and ADR-080: proposed Signed-off-by: Thane Thomson <connect@thanethomson.com> * ADR-065: implemented Signed-off-by: Thane Thomson <connect@thanethomson.com> * ADR-076: implemented Signed-off-by: Thane Thomson <connect@thanethomson.com> Signed-off-by: Thane Thomson <connect@thanethomson.com>
3.5 KiB
ADR 078: Non-Zero Genesis
Changelog
- 2020-07-26: Initial draft (@erikgrinaker)
- 2020-07-28: Use weak chain linking, i.e.
predecessorfield (@erikgrinaker) - 2020-07-31: Drop chain linking (@erikgrinaker)
- 2020-08-03: Add
State.InitialHeight(@erikgrinaker) - 2021-02-11: Migrate to tendermint repo (Originally RFC 002)
Author(s)
- Erik Grinaker (@erikgrinaker)
Context
The recommended upgrade path for block protocol-breaking upgrades is currently to hard fork the
chain (see e.g. cosmoshub-3 upgrade.
This is done by halting all validators at a predetermined height, exporting the application
state via application-specific tooling, and creating an entirely new chain using the exported
application state.
As far as Tendermint is concerned, the upgraded chain is a completely separate chain, with e.g. a new chain ID and genesis file. Notably, the new chain starts at height 1, and has none of the old chain's block history. This causes problems for integrators, e.g. coin exchanges and wallets, that assume a monotonically increasing height for a given blockchain. Users also find it confusing that a given height can now refer to distinct states depending on the chain version.
An ideal solution would be to always retain block backwards compatibility in such a way that chain history is never lost on upgrades. However, this may require a significant amount of engineering work that is not viable for the planned Stargate release (Tendermint 0.34), and may prove too restrictive for future development.
As a first step, allowing the new chain to start from an initial height specified in the genesis file would at least provide monotonically increasing heights. There was a proposal to include the last block header of the previous chain as well, but since the genesis file is not verified and hashed (only specific fields are) this would not be trustworthy.
External tooling will be required to map historical heights onto e.g. archive nodes that contain blocks from previous chain version. Tendermint will not include any such functionality.
Proposal
Tendermint will allow chains to start from an arbitrary initial height:
-
A new field
initial_heightis added to the genesis file, defaulting to1. It can be set to any non-negative integer, and0is considered equivalent to1. -
A new field
InitialHeightis added to the ABCIRequestInitChainmessage, with the same value and semantics as the genesis field. -
A new field
InitialHeightis added to thestate.Statestruct, where0is considered invalid. Including the field here simplifies implementation, since the genesis value does not have to be propagated throughout the code base separately, but it is not strictly necessary.
ABCI applications may have to be updated to handle arbitrary initial heights, otherwise the initial block may fail.
Status
Implemented
Consequences
Positive
- Heights can be unique throughout the history of a "logical" chain, across hard fork upgrades.
Negative
-
Upgrades still cause loss of block history.
-
Integrators will have to map height ranges to specific archive nodes/networks to query history.
Neutral
- There is no explicit link to the last block of the previous chain.