diff --git a/consensus/reactor.go b/consensus/reactor.go index 818f8a6e..6190fc52 100644 --- a/consensus/reactor.go +++ b/consensus/reactor.go @@ -111,7 +111,6 @@ func (conR *ConsensusReactor) GetChannels() []*p2p.ChannelDescriptor { // Implements Reactor func (conR *ConsensusReactor) AddPeer(peer *p2p.Peer) { - log.Info("ADDING PEER") if !conR.IsRunning() { return } diff --git a/consensus/state.go b/consensus/state.go index 73192944..bef286e1 100644 --- a/consensus/state.go +++ b/consensus/state.go @@ -226,8 +226,7 @@ type ConsensusState struct { blockStore *bc.BlockStore mempool *mempl.Mempool - privValidator PrivValidator // for signing votes - privValidatorIndex int // cached index; updated if validators added/removed to validator set + privValidator PrivValidator // for signing votes mtx sync.Mutex RoundState @@ -320,7 +319,6 @@ func (cs *ConsensusState) SetPrivValidator(priv PrivValidator) { cs.mtx.Lock() defer cs.mtx.Unlock() cs.privValidator = priv - cs.setPrivValidatorIndex() } func (cs *ConsensusState) LoadCommit(height int) *types.Commit { @@ -579,26 +577,10 @@ 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() { - if cs.privValidator != nil { - // 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) @@ -1520,9 +1502,11 @@ func (cs *ConsensusState) addVote(vote *types.Vote, peerKey string) (added bool, } func (cs *ConsensusState) signVote(type_ byte, hash []byte, header types.PartSetHeader) (*types.Vote, error) { + addr := cs.privValidator.GetAddress() + valIndex, _ := cs.Validators.GetByAddress(addr) vote := &types.Vote{ - ValidatorAddress: cs.privValidator.GetAddress(), - ValidatorIndex: cs.privValidatorIndex, + ValidatorAddress: addr, + ValidatorIndex: valIndex, Height: cs.Height, Round: cs.Round, Type: type_, @@ -1535,7 +1519,7 @@ func (cs *ConsensusState) signVote(type_ byte, hash []byte, header types.PartSet // sign the vote and publish on internalMsgQueue func (cs *ConsensusState) signAddVote(type_ byte, hash []byte, header types.PartSetHeader) *types.Vote { // if we don't have a key or we're not in the validator set, do nothing - if cs.privValidator == nil || cs.privValidatorIndex < 0 { + if cs.privValidator == nil || !cs.Validators.HasAddress(cs.privValidator.GetAddress()) { return nil } vote, err := cs.signVote(type_, hash, header) diff --git a/state/execution.go b/state/execution.go index 268a87d4..07466c77 100644 --- a/state/execution.go +++ b/state/execution.go @@ -43,7 +43,7 @@ func (s *State) ExecBlock(eventCache types.Fireable, proxyAppConn proxy.AppConnC } // update the validator set - s.valAddedOrRemoved, err = updateValidators(nextValSet, changedValidators) + err = updateValidators(nextValSet, changedValidators) if err != nil { log.Warn("Error changing validator set", "error", err) // TODO: err or carry on? @@ -135,22 +135,20 @@ func execBlockOnProxyApp(eventCache types.Fireable, proxyAppConn proxy.AppConnCo return changedValidators, nil } -func updateValidators(validators *types.ValidatorSet, changedValidators []*tmsp.Validator) (bool, error) { +func updateValidators(validators *types.ValidatorSet, changedValidators []*tmsp.Validator) 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 false, err + return err } address := pubkey.Address() power := int64(v.Power) // mind the overflow from uint64 if power < 0 { - return false, errors.New(Fmt("Power (%d) overflows int64", v.Power)) + return errors.New(Fmt("Power (%d) overflows int64", v.Power)) } _, val := validators.GetByAddress(address) @@ -158,26 +156,24 @@ func updateValidators(validators *types.ValidatorSet, changedValidators []*tmsp. // add val added := validators.Add(types.NewValidator(pubkey, power)) if !added { - return false, errors.New(Fmt("Failed to add new validator %X with voting power %d", address, power)) + return 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 false, errors.New(Fmt("Failed to remove validator %X)")) + return errors.New(Fmt("Failed to remove validator %X)")) } - addedOrRemoved = true } else { // update val val.VotingPower = power updated := validators.Update(val) if !updated { - return false, errors.New(Fmt("Failed to update validator %X with voting power %d", address, power)) + return errors.New(Fmt("Failed to update validator %X with voting power %d", address, power)) } } } - return addedOrRemoved, nil + return nil } // return a bit array of validators that signed the last commit @@ -363,8 +359,8 @@ func (h *Handshaker) ReplayBlocks(appHash []byte, appBlockHeight int, appConnCon // if we crashed between Commit and SaveState, // the state's app hash is stale // otherwise we're synced - if h.state.Stale { - h.state.Stale = false + if h.state.AppHashIsStale { + h.state.AppHashIsStale = false h.state.AppHash = appHash } return nil diff --git a/state/state.go b/state/state.go index 980f2798..f8b5dfc2 100644 --- a/state/state.go +++ b/state/state.go @@ -38,10 +38,8 @@ type State struct { // AppHash is updated after Commit; // it's stale after ExecBlock and before Commit - Stale bool - AppHash []byte - - valAddedOrRemoved bool // true if a validator was added or removed + AppHashIsStale bool + AppHash []byte } func LoadState(db dbm.DB) *State { @@ -62,6 +60,9 @@ func LoadState(db dbm.DB) *State { } func (s *State) Copy() *State { + if s.AppHashIsStale { + PanicSanity(Fmt("App hash is stale: %v", s)) + } return &State{ db: s.db, GenesisDoc: s.GenesisDoc, @@ -71,7 +72,7 @@ func (s *State) Copy() *State { LastBlockTime: s.LastBlockTime, Validators: s.Validators.Copy(), LastValidators: s.LastValidators.Copy(), - Stale: s.Stale, // XXX: but really state shouldnt be copied while its stale + AppHashIsStale: false, AppHash: s.AppHash, } } @@ -96,7 +97,7 @@ func (s *State) Bytes() []byte { } // Mutate state variables to match block and validators -// Since we don't have the new AppHash yet, we set s.Stale=true +// Since we don't have the new AppHash yet, we set s.AppHashIsStale=true func (s *State) SetBlockAndValidators(header *types.Header, blockPartsHeader types.PartSetHeader, prevValSet, nextValSet *types.ValidatorSet) { s.LastBlockHeight = header.Height s.LastBlockID = types.BlockID{header.Hash(), blockPartsHeader} @@ -104,11 +105,7 @@ func (s *State) SetBlockAndValidators(header *types.Header, blockPartsHeader typ s.Validators = nextValSet s.LastValidators = prevValSet - s.Stale = true -} - -func (s *State) ValidatorAddedOrRemoved() bool { - return s.valAddedOrRemoved + s.AppHashIsStale = true } func (s *State) GetValidators() (*types.ValidatorSet, *types.ValidatorSet) {