From c3cd54a8e0dac3c2ad893156e17c739c9f9fab79 Mon Sep 17 00:00:00 2001 From: Anton Kaliaev Date: Wed, 6 May 2020 11:02:20 +0400 Subject: [PATCH] blockchain: change validator set sorting method (#91) * abci: specify sorting of RequestInitChain.Validators * blockchain: change validator sorting method Refs https://github.com/tendermint/tendermint/issues/2478 --- spec/abci/abci.md | 10 +++++----- spec/blockchain/blockchain.md | 4 ++-- spec/blockchain/state.md | 5 +++-- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/spec/abci/abci.md b/spec/abci/abci.md index 8137138e0..5fb1d3902 100644 --- a/spec/abci/abci.md +++ b/spec/abci/abci.md @@ -216,17 +216,17 @@ Commit are included in the header of the next block. - `Time (google.protobuf.Timestamp)`: Genesis time. - `ChainID (string)`: ID of the blockchain. - `ConsensusParams (ConsensusParams)`: Initial consensus-critical parameters. - - `Validators ([]ValidatorUpdate)`: Initial genesis validators. + - `Validators ([]ValidatorUpdate)`: Initial genesis validators, sorted by voting power. - `AppStateBytes ([]byte)`: Serialized initial application state. Amino-encoded JSON bytes. - **Response**: - `ConsensusParams (ConsensusParams)`: Initial - consensus-critical parameters. - - `Validators ([]ValidatorUpdate)`: Initial validator set (if non empty). + consensus-critical parameters (optional). + - `Validators ([]ValidatorUpdate)`: Initial validator set (optional). - **Usage**: - Called once upon genesis. - If ResponseInitChain.Validators is empty, the initial validator set will be the RequestInitChain.Validators - - If ResponseInitChain.Validators is not empty, the initial validator set will be the - ResponseInitChain.Validators (regardless of what is in RequestInitChain.Validators). + - If ResponseInitChain.Validators is not empty, it will be the initial + validator set (regardless of what is in RequestInitChain.Validators). - This allows the app to decide if it wants to accept the initial validator set proposed by tendermint (ie. in the genesis file), or if it wants to use a different one (perhaps computed based on some application specific diff --git a/spec/blockchain/blockchain.md b/spec/blockchain/blockchain.md index 39802bcd5..6f29186dd 100644 --- a/spec/blockchain/blockchain.md +++ b/spec/blockchain/blockchain.md @@ -343,7 +343,7 @@ block.ValidatorsHash == MerkleRoot(state.Validators) MerkleRoot of the current validator set that is committing the block. This can be used to validate the `LastCommit` included in the next block. -Note the validators are sorted by their address before computing the MerkleRoot. +Note the validators are sorted by their voting power before computing the MerkleRoot. ### NextValidatorsHash @@ -354,7 +354,7 @@ block.NextValidatorsHash == MerkleRoot(state.NextValidators) MerkleRoot of the next validator set that will be the validator set that commits the next block. This is included so that the current validator set gets a chance to sign the next validator sets Merkle root. -Note the validators are sorted by their address before computing the MerkleRoot. +Note the validators are sorted by their voting power before computing the MerkleRoot. ### ConsensusHash diff --git a/spec/blockchain/state.md b/spec/blockchain/state.md index 01f430c15..7a2a899d1 100644 --- a/spec/blockchain/state.md +++ b/spec/blockchain/state.md @@ -62,8 +62,9 @@ type Validator struct { When hashing the Validator struct, the address is not included, because it is redundant with the pubkey. -The `state.Validators`, `state.LastValidators`, and `state.NextValidators`, must always be sorted by validator address, -so that there is a canonical order for computing the MerkleRoot. +The `state.Validators`, `state.LastValidators`, and `state.NextValidators`, +must always be sorted by voting power, so that there is a canonical order for +computing the MerkleRoot. We also define a `TotalVotingPower` function, to return the total voting power: