mirror of
https://github.com/fluencelabs/tendermint
synced 2025-06-24 10:11:48 +00:00
* Refactor updateState #2865 * Apply suggestions from code review Co-Authored-By: danil-lashin <danil-lashin@yandex.ru> * Apply suggestions from code review
This commit is contained in:
committed by
Ethan Buchman
parent
ef9902e602
commit
7213869fc6
@ -107,8 +107,18 @@ func (blockExec *BlockExecutor) ApplyBlock(state State, blockID types.BlockID, b
|
|||||||
|
|
||||||
fail.Fail() // XXX
|
fail.Fail() // XXX
|
||||||
|
|
||||||
|
// these are tendermint types now
|
||||||
|
validatorUpdates, err := types.PB2TM.ValidatorUpdates(abciResponses.EndBlock.ValidatorUpdates)
|
||||||
|
if err != nil {
|
||||||
|
return state, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(validatorUpdates) > 0 {
|
||||||
|
blockExec.logger.Info("Updates to validators", "updates", makeValidatorUpdatesLogString(validatorUpdates))
|
||||||
|
}
|
||||||
|
|
||||||
// Update the state with the block and responses.
|
// Update the state with the block and responses.
|
||||||
state, err = updateState(blockExec.logger, state, blockID, &block.Header, abciResponses)
|
state, err = updateState(state, blockID, &block.Header, abciResponses, validatorUpdates)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return state, fmt.Errorf("Commit failed for application: %v", err)
|
return state, fmt.Errorf("Commit failed for application: %v", err)
|
||||||
}
|
}
|
||||||
@ -132,7 +142,7 @@ func (blockExec *BlockExecutor) ApplyBlock(state State, blockID types.BlockID, b
|
|||||||
|
|
||||||
// Events are fired after everything else.
|
// Events are fired after everything else.
|
||||||
// NOTE: if we crash between Commit and Save, events wont be fired during replay
|
// NOTE: if we crash between Commit and Save, events wont be fired during replay
|
||||||
fireEvents(blockExec.logger, blockExec.eventBus, block, abciResponses)
|
fireEvents(blockExec.logger, blockExec.eventBus, block, abciResponses, validatorUpdates)
|
||||||
|
|
||||||
return state, nil
|
return state, nil
|
||||||
}
|
}
|
||||||
@ -311,16 +321,10 @@ func getBeginBlockValidatorInfo(block *types.Block, lastValSet *types.ValidatorS
|
|||||||
// If more or equal than 1/3 of total voting power changed in one block, then
|
// If more or equal than 1/3 of total voting power changed in one block, then
|
||||||
// a light client could never prove the transition externally. See
|
// a light client could never prove the transition externally. See
|
||||||
// ./lite/doc.go for details on how a light client tracks validators.
|
// ./lite/doc.go for details on how a light client tracks validators.
|
||||||
func updateValidators(currentSet *types.ValidatorSet, abciUpdates []abci.ValidatorUpdate) ([]*types.Validator, error) {
|
func updateValidators(currentSet *types.ValidatorSet, updates []*types.Validator) error {
|
||||||
updates, err := types.PB2TM.ValidatorUpdates(abciUpdates)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// these are tendermint types now
|
|
||||||
for _, valUpdate := range updates {
|
for _, valUpdate := range updates {
|
||||||
if valUpdate.VotingPower < 0 {
|
if valUpdate.VotingPower < 0 {
|
||||||
return nil, fmt.Errorf("Voting power can't be negative %v", valUpdate)
|
return fmt.Errorf("Voting power can't be negative %v", valUpdate)
|
||||||
}
|
}
|
||||||
|
|
||||||
address := valUpdate.Address
|
address := valUpdate.Address
|
||||||
@ -329,32 +333,32 @@ func updateValidators(currentSet *types.ValidatorSet, abciUpdates []abci.Validat
|
|||||||
// remove val
|
// remove val
|
||||||
_, removed := currentSet.Remove(address)
|
_, removed := currentSet.Remove(address)
|
||||||
if !removed {
|
if !removed {
|
||||||
return nil, fmt.Errorf("Failed to remove validator %X", address)
|
return fmt.Errorf("Failed to remove validator %X", address)
|
||||||
}
|
}
|
||||||
} else if val == nil {
|
} else if val == nil {
|
||||||
// add val
|
// add val
|
||||||
added := currentSet.Add(valUpdate)
|
added := currentSet.Add(valUpdate)
|
||||||
if !added {
|
if !added {
|
||||||
return nil, fmt.Errorf("Failed to add new validator %v", valUpdate)
|
return fmt.Errorf("Failed to add new validator %v", valUpdate)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// update val
|
// update val
|
||||||
updated := currentSet.Update(valUpdate)
|
updated := currentSet.Update(valUpdate)
|
||||||
if !updated {
|
if !updated {
|
||||||
return nil, fmt.Errorf("Failed to update validator %X to %v", address, valUpdate)
|
return fmt.Errorf("Failed to update validator %X to %v", address, valUpdate)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return updates, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// updateState returns a new State updated according to the header and responses.
|
// updateState returns a new State updated according to the header and responses.
|
||||||
func updateState(
|
func updateState(
|
||||||
logger log.Logger,
|
|
||||||
state State,
|
state State,
|
||||||
blockID types.BlockID,
|
blockID types.BlockID,
|
||||||
header *types.Header,
|
header *types.Header,
|
||||||
abciResponses *ABCIResponses,
|
abciResponses *ABCIResponses,
|
||||||
|
validatorUpdates []*types.Validator,
|
||||||
) (State, error) {
|
) (State, error) {
|
||||||
|
|
||||||
// Copy the valset so we can apply changes from EndBlock
|
// Copy the valset so we can apply changes from EndBlock
|
||||||
@ -364,14 +368,12 @@ func updateState(
|
|||||||
// Update the validator set with the latest abciResponses.
|
// Update the validator set with the latest abciResponses.
|
||||||
lastHeightValsChanged := state.LastHeightValidatorsChanged
|
lastHeightValsChanged := state.LastHeightValidatorsChanged
|
||||||
if len(abciResponses.EndBlock.ValidatorUpdates) > 0 {
|
if len(abciResponses.EndBlock.ValidatorUpdates) > 0 {
|
||||||
validatorUpdates, err := updateValidators(nValSet, abciResponses.EndBlock.ValidatorUpdates)
|
err := updateValidators(nValSet, validatorUpdates)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return state, fmt.Errorf("Error changing validator set: %v", err)
|
return state, fmt.Errorf("Error changing validator set: %v", err)
|
||||||
}
|
}
|
||||||
// Change results from this height but only applies to the next next height.
|
// Change results from this height but only applies to the next next height.
|
||||||
lastHeightValsChanged = header.Height + 1 + 1
|
lastHeightValsChanged = header.Height + 1 + 1
|
||||||
|
|
||||||
logger.Info("Updates to validators", "updates", makeValidatorUpdatesLogString(validatorUpdates))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update validator accums and set state variables.
|
// Update validator accums and set state variables.
|
||||||
@ -417,7 +419,7 @@ func updateState(
|
|||||||
// Fire NewBlock, NewBlockHeader.
|
// Fire NewBlock, NewBlockHeader.
|
||||||
// Fire TxEvent for every tx.
|
// Fire TxEvent for every tx.
|
||||||
// NOTE: if Tendermint crashes before commit, some or all of these events may be published again.
|
// NOTE: if Tendermint crashes before commit, some or all of these events may be published again.
|
||||||
func fireEvents(logger log.Logger, eventBus types.BlockEventPublisher, block *types.Block, abciResponses *ABCIResponses) {
|
func fireEvents(logger log.Logger, eventBus types.BlockEventPublisher, block *types.Block, abciResponses *ABCIResponses, validatorUpdates []*types.Validator) {
|
||||||
eventBus.PublishEventNewBlock(types.EventDataNewBlock{
|
eventBus.PublishEventNewBlock(types.EventDataNewBlock{
|
||||||
Block: block,
|
Block: block,
|
||||||
ResultBeginBlock: *abciResponses.BeginBlock,
|
ResultBeginBlock: *abciResponses.BeginBlock,
|
||||||
@ -438,12 +440,9 @@ func fireEvents(logger log.Logger, eventBus types.BlockEventPublisher, block *ty
|
|||||||
}})
|
}})
|
||||||
}
|
}
|
||||||
|
|
||||||
abciValUpdates := abciResponses.EndBlock.ValidatorUpdates
|
if len(validatorUpdates) > 0 {
|
||||||
if len(abciValUpdates) > 0 {
|
|
||||||
// if there were an error, we would've stopped in updateValidators
|
|
||||||
updates, _ := types.PB2TM.ValidatorUpdates(abciValUpdates)
|
|
||||||
eventBus.PublishEventValidatorSetUpdates(
|
eventBus.PublishEventValidatorSetUpdates(
|
||||||
types.EventDataValidatorSetUpdates{ValidatorUpdates: updates})
|
types.EventDataValidatorSetUpdates{ValidatorUpdates: validatorUpdates})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -218,7 +218,9 @@ func TestUpdateValidators(t *testing.T) {
|
|||||||
|
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
t.Run(tc.name, func(t *testing.T) {
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
_, err := updateValidators(tc.currentSet, tc.abciUpdates)
|
updates, err := types.PB2TM.ValidatorUpdates(tc.abciUpdates)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
err = updateValidators(tc.currentSet, updates)
|
||||||
if tc.shouldErr {
|
if tc.shouldErr {
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
} else {
|
} else {
|
||||||
|
@ -5,12 +5,11 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/tendermint/tendermint/libs/log"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
abci "github.com/tendermint/tendermint/abci/types"
|
abci "github.com/tendermint/tendermint/abci/types"
|
||||||
crypto "github.com/tendermint/tendermint/crypto"
|
"github.com/tendermint/tendermint/crypto"
|
||||||
"github.com/tendermint/tendermint/crypto/ed25519"
|
"github.com/tendermint/tendermint/crypto/ed25519"
|
||||||
cmn "github.com/tendermint/tendermint/libs/common"
|
cmn "github.com/tendermint/tendermint/libs/common"
|
||||||
dbm "github.com/tendermint/tendermint/libs/db"
|
dbm "github.com/tendermint/tendermint/libs/db"
|
||||||
@ -223,6 +222,7 @@ func TestOneValidatorChangesSaveLoad(t *testing.T) {
|
|||||||
_, val := state.Validators.GetByIndex(0)
|
_, val := state.Validators.GetByIndex(0)
|
||||||
power := val.VotingPower
|
power := val.VotingPower
|
||||||
var err error
|
var err error
|
||||||
|
var validatorUpdates []*types.Validator
|
||||||
for i := int64(1); i < highestHeight; i++ {
|
for i := int64(1); i < highestHeight; i++ {
|
||||||
// When we get to a change height, use the next pubkey.
|
// When we get to a change height, use the next pubkey.
|
||||||
if changeIndex < len(changeHeights) && i == changeHeights[changeIndex] {
|
if changeIndex < len(changeHeights) && i == changeHeights[changeIndex] {
|
||||||
@ -230,8 +230,10 @@ func TestOneValidatorChangesSaveLoad(t *testing.T) {
|
|||||||
power++
|
power++
|
||||||
}
|
}
|
||||||
header, blockID, responses := makeHeaderPartsResponsesValPowerChange(state, i, power)
|
header, blockID, responses := makeHeaderPartsResponsesValPowerChange(state, i, power)
|
||||||
state, err = updateState(log.TestingLogger(), state, blockID, &header, responses)
|
validatorUpdates, err = types.PB2TM.ValidatorUpdates(responses.EndBlock.ValidatorUpdates)
|
||||||
assert.Nil(t, err)
|
require.NoError(t, err)
|
||||||
|
state, err = updateState(state, blockID, &header, responses, validatorUpdates)
|
||||||
|
require.NoError(t, err)
|
||||||
nextHeight := state.LastBlockHeight + 1
|
nextHeight := state.LastBlockHeight + 1
|
||||||
saveValidatorsInfo(stateDB, nextHeight+1, state.LastHeightValidatorsChanged, state.NextValidators)
|
saveValidatorsInfo(stateDB, nextHeight+1, state.LastHeightValidatorsChanged, state.NextValidators)
|
||||||
}
|
}
|
||||||
@ -303,7 +305,10 @@ func TestManyValidatorChangesSaveLoad(t *testing.T) {
|
|||||||
|
|
||||||
// Save state etc.
|
// Save state etc.
|
||||||
var err error
|
var err error
|
||||||
state, err = updateState(log.TestingLogger(), state, blockID, &header, responses)
|
var validatorUpdates []*types.Validator
|
||||||
|
validatorUpdates, err = types.PB2TM.ValidatorUpdates(responses.EndBlock.ValidatorUpdates)
|
||||||
|
require.NoError(t, err)
|
||||||
|
state, err = updateState(state, blockID, &header, responses, validatorUpdates)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
nextHeight := state.LastBlockHeight + 1
|
nextHeight := state.LastBlockHeight + 1
|
||||||
saveValidatorsInfo(stateDB, nextHeight+1, state.LastHeightValidatorsChanged, state.NextValidators)
|
saveValidatorsInfo(stateDB, nextHeight+1, state.LastHeightValidatorsChanged, state.NextValidators)
|
||||||
@ -375,6 +380,7 @@ func TestConsensusParamsChangesSaveLoad(t *testing.T) {
|
|||||||
changeIndex := 0
|
changeIndex := 0
|
||||||
cp := params[changeIndex]
|
cp := params[changeIndex]
|
||||||
var err error
|
var err error
|
||||||
|
var validatorUpdates []*types.Validator
|
||||||
for i := int64(1); i < highestHeight; i++ {
|
for i := int64(1); i < highestHeight; i++ {
|
||||||
// When we get to a change height, use the next params.
|
// When we get to a change height, use the next params.
|
||||||
if changeIndex < len(changeHeights) && i == changeHeights[changeIndex] {
|
if changeIndex < len(changeHeights) && i == changeHeights[changeIndex] {
|
||||||
@ -382,7 +388,9 @@ func TestConsensusParamsChangesSaveLoad(t *testing.T) {
|
|||||||
cp = params[changeIndex]
|
cp = params[changeIndex]
|
||||||
}
|
}
|
||||||
header, blockID, responses := makeHeaderPartsResponsesParams(state, i, cp)
|
header, blockID, responses := makeHeaderPartsResponsesParams(state, i, cp)
|
||||||
state, err = updateState(log.TestingLogger(), state, blockID, &header, responses)
|
validatorUpdates, err = types.PB2TM.ValidatorUpdates(responses.EndBlock.ValidatorUpdates)
|
||||||
|
require.NoError(t, err)
|
||||||
|
state, err = updateState(state, blockID, &header, responses, validatorUpdates)
|
||||||
|
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
nextHeight := state.LastBlockHeight + 1
|
nextHeight := state.LastBlockHeight + 1
|
||||||
|
Reference in New Issue
Block a user