Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: apply calculation of voter count #92

Merged
merged 16 commits into from
Jun 22, 2020
4 changes: 4 additions & 0 deletions CHANGELOG_PENDING.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@

### BREAKING CHANGES:

- State
- [state] [\#92](https://github.com/line/tendermint/pull/92) Genesis state

- CLI/RPC/Config

- Apps
Expand All @@ -18,6 +21,7 @@
### FEATURES:
- [rpc] [\#78](https://github.com/line/tendermint/pull/78) Add `Voters` rpc
- [consensus] [\#83](https://github.com/line/tendermint/pull/83) Selection voters using random sampling without replacement
- [consensus] [\#92](https://github.com/line/tendermint/pull/92) Apply calculation of voter count

### IMPROVEMENTS:

Expand Down
1 change: 0 additions & 1 deletion blockchain/v1/reactor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,6 @@ func (conR *consensusReactorTest) SwitchToConsensus(state sm.State, blocksSynced
}

func TestFastSyncNoBlockResponse(t *testing.T) {

config = cfg.ResetTestRoot("blockchain_new_reactor_test")
defer os.RemoveAll(config.RootDir)
genDoc, privVals := randGenesisDoc(1, false, 30)
Expand Down
1 change: 0 additions & 1 deletion blockchain/v2/reactor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,6 @@ func TestReactorHelperMode(t *testing.T) {
var (
channelID = byte(0x40)
)

config := cfg.ResetTestRoot("blockchain_reactor_v2_test")
defer os.RemoveAll(config.RootDir)
genDoc, privVals := randGenesisDoc(config.ChainID(), 1, false, 30)
Expand Down
1 change: 1 addition & 0 deletions cmd/tendermint/commands/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ func initFilesWithConfig(config *cfg.Config) error {
ChainID: fmt.Sprintf("test-chain-%v", tmrand.Str(6)),
GenesisTime: tmtime.Now(),
ConsensusParams: types.DefaultConsensusParams(),
VoterParams: types.DefaultVoterParams(),
}
pubKey, err := pv.GetPubKey()
if err != nil {
Expand Down
4 changes: 2 additions & 2 deletions consensus/replay.go
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,7 @@ func (h *Handshaker) ReplayBlocks(
state.Voters = types.ToVoterAll(state.Validators.Validators)
// Should sync it with MakeGenesisState()
state.NextValidators = types.NewValidatorSet(vals)
state.NextVoters = types.SelectVoter(state.NextValidators, h.genDoc.Hash())
state.NextVoters = types.SelectVoter(state.NextValidators, h.genDoc.Hash(), state.VoterParams)
} else if len(h.genDoc.Validators) == 0 {
// If validator set is not set in genesis and still empty after InitChain, exit.
return nil, fmt.Errorf("validator set is nil in genesis and still empty after InitChain")
Expand Down Expand Up @@ -450,7 +450,7 @@ func (h *Handshaker) replayBlocks(
assertAppHashEqualsOneFromBlock(appHash, block)
}

appHash, err = sm.ExecCommitBlock(proxyApp.Consensus(), block, h.logger, h.stateDB)
appHash, err = sm.ExecCommitBlock(proxyApp.Consensus(), block, h.logger, h.stateDB, state.VoterParams)
if err != nil {
return nil, err
}
Expand Down
3 changes: 1 addition & 2 deletions consensus/replay_file.go
Original file line number Diff line number Diff line change
Expand Up @@ -314,8 +314,7 @@ func newConsensusStateForReplay(config cfg.BaseConfig, csConfig *cfg.ConsensusCo
mempool, evpool := mock.Mempool{}, sm.MockEvidencePool{}
blockExec := sm.NewBlockExecutor(stateDB, log.TestingLogger(), proxyApp.Consensus(), mempool, evpool)

consensusState := NewState(csConfig, state.Copy(), blockExec,
blockStore, mempool, evpool)
consensusState := NewState(csConfig, state.Copy(), blockExec, blockStore, mempool, evpool)

consensusState.SetEventBus(eventBus)
return consensusState
Expand Down
4 changes: 1 addition & 3 deletions consensus/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -1462,9 +1462,7 @@ func (cs *State) finalizeCommit(height int64) {
var err error
var retainHeight int64
stateCopy, retainHeight, err = cs.blockExec.ApplyBlock(
stateCopy,
types.BlockID{Hash: block.Hash(), PartsHeader: blockParts.Header()},
block)
stateCopy, types.BlockID{Hash: block.Hash(), PartsHeader: blockParts.Header()}, block)
if err != nil {
cs.Logger.Error("Error on ApplyBlock. Did the application crash? Please restart tendermint", "err", err)
err := tmos.Kill()
Expand Down
2 changes: 1 addition & 1 deletion evidence/pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ func (evpool *Pool) AddEvidence(evidence types.Evidence) error {

// fetch the validator and return its voting power as its priority
// TODO: something better ?
valSet, _, err := sm.LoadValidators(evpool.stateDB, evidence.Height())
valSet, err := sm.LoadValidators(evpool.stateDB, evidence.Height())
if err != nil {
return err
}
Expand Down
2 changes: 0 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,7 @@ require (
github.com/tendermint/tm-db v0.5.1
github.com/yahoo/coname v0.0.0-20170609175141-84592ddf8673 // indirect
golang.org/x/crypto v0.0.0-20200406173513-056763e48d71
golang.org/x/mod v0.3.0 // indirect
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e
golang.org/x/tools v0.0.0-20200519205726-57a9e4404bf7 // indirect
google.golang.org/grpc v1.28.1
gopkg.in/yaml.v3 v3.0.0-20200506231410-2ff61e1afc86
)
7 changes: 4 additions & 3 deletions rpc/core/consensus.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,12 @@ import (
//
// More: https://docs.tendermint.com/master/rpc/#/Info/validators
func Voters(ctx *rpctypes.Context, heightPtr *int64, page, perPage int) (*ctypes.ResultVoters, error) {
return voters(ctx, heightPtr, page, perPage, sm.LoadValidators)
return voters(ctx, heightPtr, page, perPage, sm.LoadVoters)
}

func voters(ctx *rpctypes.Context, heightPtr *int64, page, perPage int,
loadFunc func(db dbm.DB, height int64) (*types.ValidatorSet, *types.VoterSet, error)) (*ctypes.ResultVoters, error) {
loadFunc func(db dbm.DB, height int64, voterParams *types.VoterParams) (*types.VoterSet, error)) (
*ctypes.ResultVoters, error) {
// The latest validator that we know is the
// NextValidator of the last block.
height := consensusState.GetState().LastBlockHeight + 1
Expand All @@ -31,7 +32,7 @@ func voters(ctx *rpctypes.Context, heightPtr *int64, page, perPage int,
return nil, err
}

_, voters, err := loadFunc(stateDB, height)
voters, err := loadFunc(stateDB, height, consensusState.GetState().VoterParams)
if err != nil {
return nil, err
}
Expand Down
2 changes: 1 addition & 1 deletion rpc/core/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ func validatorAtHeight(h int64) *types.Validator {
// If we've moved to the next height, retrieve the validator set from DB.
if lastBlockHeight > h {
// ValidatorOrVoter: validator
vals, _, err := sm.LoadValidators(stateDB, h)
vals, err := sm.LoadValidators(stateDB, h)
if err != nil {
return nil // should not happen
}
Expand Down
19 changes: 12 additions & 7 deletions state/execution.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,8 @@ func (blockExec *BlockExecutor) ApplyBlock(
}

startTime := time.Now().UnixNano()
abciResponses, err := execBlockOnProxyApp(blockExec.logger, blockExec.proxyApp, block, blockExec.db)
abciResponses, err := execBlockOnProxyApp(blockExec.logger, blockExec.proxyApp, block, blockExec.db,
state.VoterParams)
endTime := time.Now().UnixNano()
blockExec.metrics.BlockProcessingTime.Observe(float64(endTime-startTime) / 1000000)
if err != nil {
Expand Down Expand Up @@ -257,6 +258,7 @@ func execBlockOnProxyApp(
proxyAppConn proxy.AppConnConsensus,
block *types.Block,
stateDB dbm.DB,
voterParams *types.VoterParams,
) (*ABCIResponses, error) {
var validTxs, invalidTxs = 0, 0

Expand All @@ -282,7 +284,7 @@ func execBlockOnProxyApp(
}
proxyAppConn.SetResponseCallback(proxyCb)

commitInfo, byzVals := getBeginBlockValidatorInfo(block, stateDB)
commitInfo, byzVals := getBeginBlockValidatorInfo(block, stateDB, voterParams)

// Begin block
var err error
Expand Down Expand Up @@ -317,13 +319,14 @@ func execBlockOnProxyApp(
return abciResponses, nil
}

func getBeginBlockValidatorInfo(block *types.Block, stateDB dbm.DB) (abci.LastCommitInfo, []abci.Evidence) {
func getBeginBlockValidatorInfo(block *types.Block, stateDB dbm.DB, voterParams *types.VoterParams) (
abci.LastCommitInfo, []abci.Evidence) {
voteInfos := make([]abci.VoteInfo, block.LastCommit.Size())
// block.Height=1 -> LastCommitInfo.Votes are empty.
// Remember that the first LastCommit is intentionally empty, so it makes
// sense for LastCommitInfo.Votes to also be empty.
if block.Height > 1 {
_, lastVoterSet, err := LoadValidators(stateDB, block.Height-1)
lastVoterSet, err := LoadVoters(stateDB, block.Height-1, voterParams)
if err != nil {
panic(err)
}
Expand Down Expand Up @@ -354,7 +357,7 @@ func getBeginBlockValidatorInfo(block *types.Block, stateDB dbm.DB) (abci.LastCo
// We need the validator set. We already did this in validateBlock.
// TODO: Should we instead cache the valset in the evidence itself and add
// `SetValidatorSet()` and `ToABCI` methods ?
_, voterSet, err := LoadValidators(stateDB, ev.Height())
voterSet, err := LoadVoters(stateDB, ev.Height(), voterParams)
if err != nil {
panic(err)
}
Expand Down Expand Up @@ -438,13 +441,14 @@ func updateState(
return state, fmt.Errorf("error get proof of hash: %v", err)
}

nextVoters := types.SelectVoter(nValSet, proofHash)
nextVoters := types.SelectVoter(nValSet, proofHash, state.VoterParams)

// NOTE: the AppHash has not been populated.
// It will be filled on state.Save.
return State{
Version: nextVersion,
ChainID: state.ChainID,
VoterParams: state.VoterParams,
LastBlockHeight: header.Height,
LastBlockID: blockID,
LastBlockTime: header.Time,
Expand Down Expand Up @@ -509,8 +513,9 @@ func ExecCommitBlock(
block *types.Block,
logger log.Logger,
stateDB dbm.DB,
voterParams *types.VoterParams,
) ([]byte, error) {
_, err := execBlockOnProxyApp(logger, appConnConsensus, block, stateDB)
_, err := execBlockOnProxyApp(logger, appConnConsensus, block, stateDB, voterParams)
if err != nil {
logger.Error("Error executing block on proxy app", "height", block.Height, "err", err)
return nil, err
Expand Down
4 changes: 2 additions & 2 deletions state/execution_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ func TestBeginBlockValidators(t *testing.T) {
// block for height 2
block, _ := state.MakeBlock(2, makeTxs(2), lastCommit, nil, proposer.Address, 0, proof)

_, err = sm.ExecCommitBlock(proxyApp.Consensus(), block, log.TestingLogger(), stateDB)
_, err = sm.ExecCommitBlock(proxyApp.Consensus(), block, log.TestingLogger(), stateDB, state.VoterParams)
require.Nil(t, err, tc.desc)

// -> app receives a list of validators with a bool indicating if they signed
Expand Down Expand Up @@ -169,7 +169,7 @@ func TestBeginBlockByzantineValidators(t *testing.T) {
block, _ := state.MakeBlock(10, makeTxs(2), lastCommit, nil, proposer.Address, 0, proof)
block.Time = now
block.Evidence.Evidence = tc.evidence
_, err = sm.ExecCommitBlock(proxyApp.Consensus(), block, log.TestingLogger(), stateDB)
_, err = sm.ExecCommitBlock(proxyApp.Consensus(), block, log.TestingLogger(), stateDB, state.VoterParams)
require.Nil(t, err, tc.desc)

// -> app must receive an index of the byzantine validator
Expand Down
17 changes: 10 additions & 7 deletions state/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ import (
"github.com/tendermint/tendermint/version"
)

// database keys
var (
// database keys
stateKey = []byte("stateKey")
)

Expand Down Expand Up @@ -53,7 +53,8 @@ type State struct {
Version Version

// immutable
ChainID string
ChainID string
VoterParams *types.VoterParams

// LastBlockHeight=0 at genesis (ie. block(H=0) does not exist)
LastBlockHeight int64
Expand Down Expand Up @@ -95,8 +96,9 @@ func (state State) MakeHashMessage(round int) []byte {
// Copy makes a copy of the State for mutating.
func (state State) Copy() State {
return State{
Version: state.Version,
ChainID: state.ChainID,
Version: state.Version,
ChainID: state.ChainID,
VoterParams: state.VoterParams,

LastBlockHeight: state.LastBlockHeight,
LastBlockID: state.LastBlockID,
Expand Down Expand Up @@ -249,8 +251,9 @@ func MakeGenesisState(genDoc *types.GenesisDoc) (State, error) {
}

return State{
Version: initStateVersion,
ChainID: genDoc.ChainID,
Version: initStateVersion,
ChainID: genDoc.ChainID,
VoterParams: genDoc.VoterParams,

LastBlockHeight: 0,
LastBlockID: types.BlockID{},
Expand All @@ -260,7 +263,7 @@ func MakeGenesisState(genDoc *types.GenesisDoc) (State, error) {
LastProofHash: genDoc.Hash(),

NextValidators: nextValidatorSet,
NextVoters: types.SelectVoter(nextValidatorSet, genDoc.Hash()),
NextVoters: types.SelectVoter(nextValidatorSet, genDoc.Hash(), genDoc.VoterParams),
Validators: validatorSet,
Voters: types.ToVoterAll(validatorSet.Validators),
LastVoters: &types.VoterSet{},
Expand Down
20 changes: 10 additions & 10 deletions state/state_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,16 +185,16 @@ func TestValidatorSimpleSaveLoad(t *testing.T) {
assert := assert.New(t)

// Can't load anything for height 0.
_, _, err := sm.LoadValidators(stateDB, 0)
_, err := sm.LoadVoters(stateDB, 0, state.VoterParams)
assert.IsType(sm.ErrNoValSetForHeight{}, err, "expected err at height 0")

// Should be able to load for height 1.
_, v, err := sm.LoadValidators(stateDB, 1)
v, err := sm.LoadVoters(stateDB, 1, state.VoterParams)
assert.Nil(err, "expected no err at height 1")
assert.Equal(v.Hash(), state.Validators.Hash(), "expected validator hashes to match")

// Should be able to load for height 2.
_, v, err = sm.LoadValidators(stateDB, 2)
v, err = sm.LoadVoters(stateDB, 2, state.VoterParams)
assert.Nil(err, "expected no err at height 2")
assert.Equal(v.Hash(), state.NextValidators.Hash(), "expected validator hashes to match")

Expand All @@ -203,9 +203,9 @@ func TestValidatorSimpleSaveLoad(t *testing.T) {
nextHeight := state.LastBlockHeight + 1
sm.SaveValidatorsInfo(stateDB, nextHeight+1, state.LastHeightValidatorsChanged,
state.LastProofHash, state.NextValidators)
_, vp0, err := sm.LoadValidators(stateDB, nextHeight+0)
vp0, err := sm.LoadVoters(stateDB, nextHeight+0, state.VoterParams)
assert.Nil(err, "expected no err")
_, vp1, err := sm.LoadValidators(stateDB, nextHeight+1)
vp1, err := sm.LoadVoters(stateDB, nextHeight+1, state.VoterParams)
assert.Nil(err, "expected no err")
assert.Equal(vp0.Hash(), state.Validators.Hash(), "expected validator hashes to match")
assert.Equal(vp1.Hash(), state.NextValidators.Hash(), "expected next validator hashes to match")
Expand Down Expand Up @@ -259,7 +259,7 @@ func TestOneValidatorChangesSaveLoad(t *testing.T) {
}

for i, power := range testCases {
_, v, err := sm.LoadValidators(stateDB, int64(i+1+1)) // +1 because vset changes delayed by 1 block.
v, err := sm.LoadVoters(stateDB, int64(i+1+1), state.VoterParams) // +1 because vset changes delayed by 1 block.
assert.Nil(t, err, fmt.Sprintf("expected no err at height %d", i))
assert.Equal(t, v.Size(), 1, "validator set size is greater than 1: %d", v.Size())
_, val := v.GetByIndex(0)
Expand Down Expand Up @@ -863,11 +863,11 @@ func TestStoreLoadValidatorsIncrementsProposerPriority(t *testing.T) {

nextHeight := state.LastBlockHeight + 1

v0, _, err := sm.LoadValidators(stateDB, nextHeight)
v0, err := sm.LoadValidators(stateDB, nextHeight)
assert.Nil(t, err)
acc0 := v0.Validators[0].ProposerPriority

v1, _, err := sm.LoadValidators(stateDB, nextHeight+1)
v1, err := sm.LoadValidators(stateDB, nextHeight+1)
assert.Nil(t, err)
acc1 := v1.Validators[0].ProposerPriority

Expand Down Expand Up @@ -906,7 +906,7 @@ func TestManyValidatorChangesSaveLoad(t *testing.T) {
state.LastProofHash, state.NextValidators)

// Load nextheight, it should be the oldpubkey.
v0, _, err := sm.LoadValidators(stateDB, nextHeight)
v0, err := sm.LoadValidators(stateDB, nextHeight)
assert.Nil(t, err)
assert.Equal(t, valSetSize, v0.Size())
index, val := v0.GetByAddress(pubkeyOld.Address())
Expand All @@ -916,7 +916,7 @@ func TestManyValidatorChangesSaveLoad(t *testing.T) {
}

// Load nextheight+1, it should be the new pubkey.
v1, _, err := sm.LoadValidators(stateDB, nextHeight+1)
v1, err := sm.LoadValidators(stateDB, nextHeight+1)
assert.Nil(t, err)
assert.Equal(t, valSetSize, v1.Size())
index, val = v1.GetByAddress(pubkey.Address())
Expand Down
Loading