From f3207cee52b182f64b0b6f8d9fd6190e2e172c44 Mon Sep 17 00:00:00 2001 From: Erik Grinaker Date: Thu, 13 Aug 2020 10:45:05 +0200 Subject: [PATCH] add description of arbitrary initial height (#135) --- spec/abci/abci.md | 6 +++--- spec/core/data_structures.md | 12 ++++++++---- spec/core/state.md | 10 ++++++++-- 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/spec/abci/abci.md b/spec/abci/abci.md index 8ce0bf815..afe3a4729 100644 --- a/spec/abci/abci.md +++ b/spec/abci/abci.md @@ -239,6 +239,7 @@ via light client. - `ConsensusParams (ConsensusParams)`: Initial consensus-critical parameters. - `Validators ([]ValidatorUpdate)`: Initial genesis validators, sorted by voting power. - `AppStateBytes ([]byte)`: Serialized initial application state. Amino-encoded JSON bytes. + - `InitialHeight (int64)`: Height of the initial block (typically `1`). - **Response**: - `ConsensusParams (ConsensusParams)`: Initial consensus-critical parameters (optional). @@ -498,9 +499,8 @@ via light client. - `ChainID (string)`: ID of the blockchain - `Height (int64)`: Height of the block in the chain - `Time (google.protobuf.Timestamp)`: Time of the previous block. - For heights > 1, it's the weighted median of the timestamps of the valid - votes in the block.LastCommit. - For height == 1, it's genesis time. + For most blocks it's the weighted median of the timestamps of the valid votes in the + block.LastCommit, except for the initial height where it's the genesis time. - `LastBlockID (BlockID)`: Hash of the previous (parent) block - `LastCommitHash ([]byte)`: Hash of the previous block's commit - `ValidatorsHash ([]byte)`: Hash of the validator set for this block diff --git a/spec/core/data_structures.md b/spec/core/data_structures.md index 3ced4de04..3ffcf3321 100644 --- a/spec/core/data_structures.md +++ b/spec/core/data_structures.md @@ -349,10 +349,11 @@ ChainID must be less than 50 bytes. ```go block.Header.Height > 0 +block.Header.Height >= state.InitialHeight block.Header.Height == prevBlock.Header.Height + 1 ``` -The height is an incrementing integer. The first block has `block.Header.Height == 1`. +The height is an incrementing integer. The first block has `block.Header.Height == state.InitialHeight`, derived from the genesis file. ### Time @@ -371,7 +372,7 @@ The timestamp of the first block must be equal to the genesis time (since there's no votes to compute the median). ``` -if block.Header.Height == 1 { +if block.Header.Height == state.InitialHeight { block.Header.Timestamp == genesisTime } ``` @@ -494,7 +495,7 @@ Arbitrary length array of arbitrary length byte-arrays. The first height is an exception - it requires the `LastCommit` to be empty: ```go -if block.Header.Height == 1 { +if block.Header.Height == state.InitialHeight { len(b.LastCommit) == 0 } ``` @@ -563,7 +564,7 @@ Once a block is validated, it can be executed against the state. The state follows this recursive equation: ```go -state(1) = InitialState +state(initialHeight) = InitialState state(h+1) <- Execute(state(h), ABCIApp, block(h)) ``` @@ -579,8 +580,11 @@ func Execute(s State, app ABCIApp, block Block) State { nextConsensusParams := UpdateConsensusParams(state.ConsensusParams, ConsensusParamChanges) return State{ + ChainID: state.ChainID, + InitialHeight: state.InitialHeight, LastResults: abciResponses.DeliverTxResults, AppHash: AppHash, + InitialHeight: state.InitialHeight, LastValidators: state.Validators, Validators: state.NextValidators, NextValidators: UpdateValidators(state.NextValidators, ValidatorChanges), diff --git a/spec/core/state.md b/spec/core/state.md index 09b583cb5..446a74be2 100644 --- a/spec/core/state.md +++ b/spec/core/state.md @@ -15,18 +15,24 @@ validation. ```go type State struct { + ChainID string + InitialHeight int64 + Version Version LastResults []Result - AppHash []byte + AppHash []byte LastValidators []Validator - Validators []Validator + Validators []Validator NextValidators []Validator ConsensusParams ConsensusParams } ``` +The chain ID and initial height are taken from the genesis file, and not changed again. The +initial height will be `1` in the typical case, `0` is an invalid value. + Note there is a hard-coded limit of 10000 validators. This is inherited from the limit on the number of votes in a commit.