update privValidatorIndex on valset change
This commit is contained in:
parent
e1e2c1c740
commit
e0db20c0cf
|
@ -262,7 +262,6 @@ func randConsensusNet(nValidators int) []*ConsensusState {
|
|||
thisConfig := tendermint_test.ResetConfig(Fmt("consensus_reactor_test_%d", i))
|
||||
EnsureDir(thisConfig.GetString("cs_wal_dir"), 0700) // dir for wal
|
||||
css[i] = newConsensusStateWithConfig(thisConfig, state, privVals[i], counter.NewCounterApplication(true))
|
||||
css[i].SetPrivValidatorIndex(i)
|
||||
}
|
||||
return css
|
||||
}
|
||||
|
|
|
@ -226,8 +226,8 @@ type ConsensusState struct {
|
|||
blockStore *bc.BlockStore
|
||||
mempool *mempl.Mempool
|
||||
|
||||
privValidator PrivValidator
|
||||
privValidatorIndex int // TODO: update if validator set changes
|
||||
privValidator PrivValidator // for signing votes
|
||||
privValidatorIndex int // cached index; updated if validators added/removed to validator set
|
||||
|
||||
mtx sync.Mutex
|
||||
RoundState
|
||||
|
@ -320,13 +320,7 @@ func (cs *ConsensusState) SetPrivValidator(priv PrivValidator) {
|
|||
cs.mtx.Lock()
|
||||
defer cs.mtx.Unlock()
|
||||
cs.privValidator = priv
|
||||
}
|
||||
|
||||
// Caches the index of our privValidator in the validator set to use when voting
|
||||
func (cs *ConsensusState) SetPrivValidatorIndex(index int) {
|
||||
cs.mtx.Lock()
|
||||
defer cs.mtx.Unlock()
|
||||
cs.privValidatorIndex = index
|
||||
cs.setPrivValidatorIndex()
|
||||
}
|
||||
|
||||
func (cs *ConsensusState) LoadCommit(height int) *types.Commit {
|
||||
|
@ -585,10 +579,24 @@ func (cs *ConsensusState) updateToState(state *sm.State) {
|
|||
|
||||
cs.state = state
|
||||
|
||||
if cs.state.ValidatorAddedOrRemoved() {
|
||||
cs.setPrivValidatorIndex()
|
||||
}
|
||||
|
||||
// Finally, broadcast RoundState
|
||||
cs.newStep()
|
||||
}
|
||||
|
||||
func (cs *ConsensusState) setPrivValidatorIndex() {
|
||||
// TODO: just return -1 for not found
|
||||
valIdx, val := cs.state.Validators.GetByAddress(cs.privValidator.GetAddress())
|
||||
if val == nil {
|
||||
cs.privValidatorIndex = -1
|
||||
} else {
|
||||
cs.privValidatorIndex = valIdx
|
||||
}
|
||||
}
|
||||
|
||||
func (cs *ConsensusState) newStep() {
|
||||
rs := cs.RoundStateEvent()
|
||||
cs.wal.Save(rs)
|
||||
|
|
|
@ -103,13 +103,6 @@ func NewNode(config cfg.Config, privValidator *types.PrivValidator, clientCreato
|
|||
consensusState := consensus.NewConsensusState(config, state.Copy(), proxyApp.Consensus(), blockStore, mempool)
|
||||
if privValidator != nil {
|
||||
consensusState.SetPrivValidator(privValidator)
|
||||
// TODO: just return -1 for not found
|
||||
valIdx, val := state.Validators.GetByAddress(privValidator.GetAddress())
|
||||
if val == nil {
|
||||
consensusState.SetPrivValidatorIndex(-1)
|
||||
} else {
|
||||
consensusState.SetPrivValidatorIndex(valIdx)
|
||||
}
|
||||
}
|
||||
consensusReactor := consensus.NewConsensusReactor(consensusState, fastSync)
|
||||
|
||||
|
|
|
@ -43,7 +43,8 @@ func (s *State) ExecBlock(eventCache types.Fireable, proxyAppConn proxy.AppConnC
|
|||
}
|
||||
|
||||
// update the validator set
|
||||
if err := updateValidators(nextValSet, changedValidators); err != nil {
|
||||
s.valAddedOrRemoved, err = updateValidators(nextValSet, changedValidators)
|
||||
if err != nil {
|
||||
log.Warn("Error changing validator set", "error", err)
|
||||
// TODO: err or carry on?
|
||||
}
|
||||
|
@ -131,20 +132,22 @@ func execBlockOnProxyApp(eventCache types.Fireable, proxyAppConn proxy.AppConnCo
|
|||
return changedValidators, nil
|
||||
}
|
||||
|
||||
func updateValidators(validators *types.ValidatorSet, changedValidators []*tmsp.Validator) error {
|
||||
func updateValidators(validators *types.ValidatorSet, changedValidators []*tmsp.Validator) (bool, error) {
|
||||
// TODO: prevent change of 1/3+ at once
|
||||
|
||||
var addedOrRemoved bool
|
||||
|
||||
for _, v := range changedValidators {
|
||||
pubkey, err := crypto.PubKeyFromBytes(v.PubKey) // NOTE: expects go-wire encoded pubkey
|
||||
if err != nil {
|
||||
return err
|
||||
return false, err
|
||||
}
|
||||
|
||||
address := pubkey.Address()
|
||||
power := int64(v.Power)
|
||||
// mind the overflow from uint64
|
||||
if power < 0 {
|
||||
return errors.New(Fmt("Power (%d) overflows int64", v.Power))
|
||||
return false, errors.New(Fmt("Power (%d) overflows int64", v.Power))
|
||||
}
|
||||
|
||||
_, val := validators.GetByAddress(address)
|
||||
|
@ -152,24 +155,26 @@ func updateValidators(validators *types.ValidatorSet, changedValidators []*tmsp.
|
|||
// add val
|
||||
added := validators.Add(types.NewValidator(pubkey, power))
|
||||
if !added {
|
||||
return errors.New(Fmt("Failed to add new validator %X with voting power %d", address, power))
|
||||
return false, errors.New(Fmt("Failed to add new validator %X with voting power %d", address, power))
|
||||
}
|
||||
addedOrRemoved = true
|
||||
} else if v.Power == 0 {
|
||||
// remove val
|
||||
_, removed := validators.Remove(address)
|
||||
if !removed {
|
||||
return errors.New(Fmt("Failed to remove validator %X)"))
|
||||
return false, errors.New(Fmt("Failed to remove validator %X)"))
|
||||
}
|
||||
addedOrRemoved = true
|
||||
} else {
|
||||
// update val
|
||||
val.VotingPower = power
|
||||
updated := validators.Update(val)
|
||||
if !updated {
|
||||
return errors.New(Fmt("Failed to update validator %X with voting power %d", address, power))
|
||||
return false, errors.New(Fmt("Failed to update validator %X with voting power %d", address, power))
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
return addedOrRemoved, nil
|
||||
}
|
||||
|
||||
// return a bit array of validators that signed the last commit
|
||||
|
|
|
@ -40,6 +40,8 @@ type State struct {
|
|||
// it's stale after ExecBlock and before Commit
|
||||
Stale bool
|
||||
AppHash []byte
|
||||
|
||||
valAddedOrRemoved bool // true if a validator was added or removed
|
||||
}
|
||||
|
||||
func LoadState(db dbm.DB) *State {
|
||||
|
@ -105,6 +107,10 @@ func (s *State) SetBlockAndValidators(header *types.Header, blockPartsHeader typ
|
|||
s.Stale = true
|
||||
}
|
||||
|
||||
func (s *State) ValidatorAddedOrRemoved() bool {
|
||||
return s.valAddedOrRemoved
|
||||
}
|
||||
|
||||
func (s *State) GetValidators() (*types.ValidatorSet, *types.ValidatorSet) {
|
||||
return s.LastValidators, s.Validators
|
||||
}
|
||||
|
|
|
@ -155,8 +155,8 @@ type Header struct {
|
|||
NumTxs int `json:"num_txs"`
|
||||
LastBlockID BlockID `json:"last_block_id"`
|
||||
LastCommitHash []byte `json:"last_commit_hash"` // commit from validators from the last block
|
||||
ValidatorsHash []byte `json:"validators_hash"` // validators for the current block
|
||||
DataHash []byte `json:"data_hash"` // transactions
|
||||
ValidatorsHash []byte `json:"validators_hash"` // validators for the current block
|
||||
AppHash []byte `json:"app_hash"` // state after txs from the previous block
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue