diff --git a/rfc/002-nonzero-genesis.md b/rfc/002-nonzero-genesis.md new file mode 100644 index 000000000..a188ec455 --- /dev/null +++ b/rfc/002-nonzero-genesis.md @@ -0,0 +1,81 @@ +# RFC 002: Non-Zero Genesis + +## Changelog + +- 2020-07-26: Initial draft (@erikgrinaker) +- 2020-07-28: Use weak chain linking, i.e. `predecessor` field (@erikgrinaker) +- 2020-07-31: Drop chain linking (@erikgrinaker) +- 2020-08-03: Add `State.InitialHeight` (@erikgrinaker) + +## 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](https://blog.cosmos.network/cosmos-hub-3-upgrade-announcement-39c9da941aee)). +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_height` is added to the genesis file, defaulting to `1`. It can be set to any +non-negative integer, and `0` is considered equivalent to `1`. + +* A new field `InitialHeight` is added to the ABCI `RequestInitChain` message, with the same value +and semantics as the genesis field. + +* A new field `InitialHeight` is added to the `state.State` struct, where `0` is 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 + +Proposed + +## 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. + +## References + +- [#2543: Allow genesis file to start from non-zero height w/ prev block header](https://github.com/tendermint/tendermint/issues/2543) \ No newline at end of file