dir : types/vote_set.go
vote 인스턴스를 생성한 (투표에 참여한) 검증자 정보와 투표 대상인 block을 확인
valIndex := vote.ValidatorIndex
valAddr := vote.ValidatorAddress
blockKey := vote.BlockID.Key()
height, round, step 확인
if (vote.Height != voteSet.height) ||
(vote.Round != voteSet.round) ||
(vote.Type != voteSet.signedMsgType) {
return false fmt.Errorf("...")
}
검증자 정보가 유효한지 확인
lookupAddr, val := voteSet.valSet.GetByIndex(valIndex)
if val == nil { return false, fmt.Errorf(...) }
if !bytes.Equal(valAddr, lookupAddr) { return false, fmt.Errorf(...) }
동일한 vote instance가 있다면 추가하지 않고 리턴
if existing, ok := voteSet.getVote(valIndex, blockKey); ok {
if bytes.Equal(existing.Signature, vote.Signatrue) {
return false, nil
}
return false, fmt.Errorf(...)
}
서명 검증
if err := vote.Verify(voteSet.chainID, val.pubKey); err!= nil {
return false, fmt.Errorf(...)
}
vote 인스턴스를 voteSet에 추가하고, 충돌하는 (한 검증자가 다른 두 블럭에 투표한 경우) vote가 있다면 가져온다.
added, conflicting := voteSet.addVerifiedVote(vote, blockKey, val.VotingPower)
결과를 적절히 반환
// conflicting이 있다고 항상 에러가 나고 합의 과정이 멈추는 건 아님
if conflicting != nil { added, err }
if !added { panic(...) }
return added, nil