mirror of
https://github.com/fluencelabs/tendermint
synced 2025-06-26 03:01:42 +00:00
remove privValIndex; Stale->AppHashIsStale
This commit is contained in:
@ -111,7 +111,6 @@ func (conR *ConsensusReactor) GetChannels() []*p2p.ChannelDescriptor {
|
|||||||
|
|
||||||
// Implements Reactor
|
// Implements Reactor
|
||||||
func (conR *ConsensusReactor) AddPeer(peer *p2p.Peer) {
|
func (conR *ConsensusReactor) AddPeer(peer *p2p.Peer) {
|
||||||
log.Info("ADDING PEER")
|
|
||||||
if !conR.IsRunning() {
|
if !conR.IsRunning() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -226,8 +226,7 @@ type ConsensusState struct {
|
|||||||
blockStore *bc.BlockStore
|
blockStore *bc.BlockStore
|
||||||
mempool *mempl.Mempool
|
mempool *mempl.Mempool
|
||||||
|
|
||||||
privValidator PrivValidator // for signing votes
|
privValidator PrivValidator // for signing votes
|
||||||
privValidatorIndex int // cached index; updated if validators added/removed to validator set
|
|
||||||
|
|
||||||
mtx sync.Mutex
|
mtx sync.Mutex
|
||||||
RoundState
|
RoundState
|
||||||
@ -320,7 +319,6 @@ func (cs *ConsensusState) SetPrivValidator(priv PrivValidator) {
|
|||||||
cs.mtx.Lock()
|
cs.mtx.Lock()
|
||||||
defer cs.mtx.Unlock()
|
defer cs.mtx.Unlock()
|
||||||
cs.privValidator = priv
|
cs.privValidator = priv
|
||||||
cs.setPrivValidatorIndex()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cs *ConsensusState) LoadCommit(height int) *types.Commit {
|
func (cs *ConsensusState) LoadCommit(height int) *types.Commit {
|
||||||
@ -579,26 +577,10 @@ func (cs *ConsensusState) updateToState(state *sm.State) {
|
|||||||
|
|
||||||
cs.state = state
|
cs.state = state
|
||||||
|
|
||||||
if cs.state.ValidatorAddedOrRemoved() {
|
|
||||||
cs.setPrivValidatorIndex()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Finally, broadcast RoundState
|
// Finally, broadcast RoundState
|
||||||
cs.newStep()
|
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() {
|
func (cs *ConsensusState) newStep() {
|
||||||
rs := cs.RoundStateEvent()
|
rs := cs.RoundStateEvent()
|
||||||
cs.wal.Save(rs)
|
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) {
|
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{
|
vote := &types.Vote{
|
||||||
ValidatorAddress: cs.privValidator.GetAddress(),
|
ValidatorAddress: addr,
|
||||||
ValidatorIndex: cs.privValidatorIndex,
|
ValidatorIndex: valIndex,
|
||||||
Height: cs.Height,
|
Height: cs.Height,
|
||||||
Round: cs.Round,
|
Round: cs.Round,
|
||||||
Type: type_,
|
Type: type_,
|
||||||
@ -1535,7 +1519,7 @@ func (cs *ConsensusState) signVote(type_ byte, hash []byte, header types.PartSet
|
|||||||
// sign the vote and publish on internalMsgQueue
|
// sign the vote and publish on internalMsgQueue
|
||||||
func (cs *ConsensusState) signAddVote(type_ byte, hash []byte, header types.PartSetHeader) *types.Vote {
|
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 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
|
return nil
|
||||||
}
|
}
|
||||||
vote, err := cs.signVote(type_, hash, header)
|
vote, err := cs.signVote(type_, hash, header)
|
||||||
|
@ -43,7 +43,7 @@ func (s *State) ExecBlock(eventCache types.Fireable, proxyAppConn proxy.AppConnC
|
|||||||
}
|
}
|
||||||
|
|
||||||
// update the validator set
|
// update the validator set
|
||||||
s.valAddedOrRemoved, err = updateValidators(nextValSet, changedValidators)
|
err = updateValidators(nextValSet, changedValidators)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warn("Error changing validator set", "error", err)
|
log.Warn("Error changing validator set", "error", err)
|
||||||
// TODO: err or carry on?
|
// TODO: err or carry on?
|
||||||
@ -135,22 +135,20 @@ func execBlockOnProxyApp(eventCache types.Fireable, proxyAppConn proxy.AppConnCo
|
|||||||
return changedValidators, nil
|
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
|
// TODO: prevent change of 1/3+ at once
|
||||||
|
|
||||||
var addedOrRemoved bool
|
|
||||||
|
|
||||||
for _, v := range changedValidators {
|
for _, v := range changedValidators {
|
||||||
pubkey, err := crypto.PubKeyFromBytes(v.PubKey) // NOTE: expects go-wire encoded pubkey
|
pubkey, err := crypto.PubKeyFromBytes(v.PubKey) // NOTE: expects go-wire encoded pubkey
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
address := pubkey.Address()
|
address := pubkey.Address()
|
||||||
power := int64(v.Power)
|
power := int64(v.Power)
|
||||||
// mind the overflow from uint64
|
// mind the overflow from uint64
|
||||||
if power < 0 {
|
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)
|
_, val := validators.GetByAddress(address)
|
||||||
@ -158,26 +156,24 @@ func updateValidators(validators *types.ValidatorSet, changedValidators []*tmsp.
|
|||||||
// add val
|
// add val
|
||||||
added := validators.Add(types.NewValidator(pubkey, power))
|
added := validators.Add(types.NewValidator(pubkey, power))
|
||||||
if !added {
|
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 {
|
} else if v.Power == 0 {
|
||||||
// remove val
|
// remove val
|
||||||
_, removed := validators.Remove(address)
|
_, removed := validators.Remove(address)
|
||||||
if !removed {
|
if !removed {
|
||||||
return false, errors.New(Fmt("Failed to remove validator %X)"))
|
return errors.New(Fmt("Failed to remove validator %X)"))
|
||||||
}
|
}
|
||||||
addedOrRemoved = true
|
|
||||||
} else {
|
} else {
|
||||||
// update val
|
// update val
|
||||||
val.VotingPower = power
|
val.VotingPower = power
|
||||||
updated := validators.Update(val)
|
updated := validators.Update(val)
|
||||||
if !updated {
|
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
|
// 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,
|
// if we crashed between Commit and SaveState,
|
||||||
// the state's app hash is stale
|
// the state's app hash is stale
|
||||||
// otherwise we're synced
|
// otherwise we're synced
|
||||||
if h.state.Stale {
|
if h.state.AppHashIsStale {
|
||||||
h.state.Stale = false
|
h.state.AppHashIsStale = false
|
||||||
h.state.AppHash = appHash
|
h.state.AppHash = appHash
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -38,10 +38,8 @@ type State struct {
|
|||||||
|
|
||||||
// AppHash is updated after Commit;
|
// AppHash is updated after Commit;
|
||||||
// it's stale after ExecBlock and before Commit
|
// it's stale after ExecBlock and before Commit
|
||||||
Stale bool
|
AppHashIsStale bool
|
||||||
AppHash []byte
|
AppHash []byte
|
||||||
|
|
||||||
valAddedOrRemoved bool // true if a validator was added or removed
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func LoadState(db dbm.DB) *State {
|
func LoadState(db dbm.DB) *State {
|
||||||
@ -62,6 +60,9 @@ func LoadState(db dbm.DB) *State {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *State) Copy() *State {
|
func (s *State) Copy() *State {
|
||||||
|
if s.AppHashIsStale {
|
||||||
|
PanicSanity(Fmt("App hash is stale: %v", s))
|
||||||
|
}
|
||||||
return &State{
|
return &State{
|
||||||
db: s.db,
|
db: s.db,
|
||||||
GenesisDoc: s.GenesisDoc,
|
GenesisDoc: s.GenesisDoc,
|
||||||
@ -71,7 +72,7 @@ func (s *State) Copy() *State {
|
|||||||
LastBlockTime: s.LastBlockTime,
|
LastBlockTime: s.LastBlockTime,
|
||||||
Validators: s.Validators.Copy(),
|
Validators: s.Validators.Copy(),
|
||||||
LastValidators: s.LastValidators.Copy(),
|
LastValidators: s.LastValidators.Copy(),
|
||||||
Stale: s.Stale, // XXX: but really state shouldnt be copied while its stale
|
AppHashIsStale: false,
|
||||||
AppHash: s.AppHash,
|
AppHash: s.AppHash,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -96,7 +97,7 @@ func (s *State) Bytes() []byte {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Mutate state variables to match block and validators
|
// 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) {
|
func (s *State) SetBlockAndValidators(header *types.Header, blockPartsHeader types.PartSetHeader, prevValSet, nextValSet *types.ValidatorSet) {
|
||||||
s.LastBlockHeight = header.Height
|
s.LastBlockHeight = header.Height
|
||||||
s.LastBlockID = types.BlockID{header.Hash(), blockPartsHeader}
|
s.LastBlockID = types.BlockID{header.Hash(), blockPartsHeader}
|
||||||
@ -104,11 +105,7 @@ func (s *State) SetBlockAndValidators(header *types.Header, blockPartsHeader typ
|
|||||||
s.Validators = nextValSet
|
s.Validators = nextValSet
|
||||||
s.LastValidators = prevValSet
|
s.LastValidators = prevValSet
|
||||||
|
|
||||||
s.Stale = true
|
s.AppHashIsStale = true
|
||||||
}
|
|
||||||
|
|
||||||
func (s *State) ValidatorAddedOrRemoved() bool {
|
|
||||||
return s.valAddedOrRemoved
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *State) GetValidators() (*types.ValidatorSet, *types.ValidatorSet) {
|
func (s *State) GetValidators() (*types.ValidatorSet, *types.ValidatorSet) {
|
||||||
|
Reference in New Issue
Block a user