tendermint的proposer節(jié)點選舉
概述:
tendermint的proposer節(jié)點選舉過程不需要網(wǎng)絡通信清笨,而是根據(jù)config目錄下的genesis.json而決定的寒波。genesis.json文件中有一個配置項是“validators”,這個key對應的是一個validator的列表金麸,包含validator的pub_key和power。pub_key確定是哪個tendermint節(jié)點,power決定這個節(jié)點被選舉為proposer節(jié)點的頻率矗烛。
選舉算法詳解
- 加載并解析genesis.json玫镐,獲取每個節(jié)點的pub_key和power倒戏,power解析后保存在VotingPower中。
- 對每個validator的Accum進行賦值恐似,Accum的值為驗證節(jié)點的權重值杜跷。
validatorsHeap := cmn.NewHeap()
for _, val := range vals.Validators {
// Check for overflow both multiplication and sum.
val.Accum = safeAddClip(val.Accum, safeMulClip(val.VotingPower, int64(times)))
validatorsHeap.PushComparable(val, accumComparable{val})
}
- 選擇當次Accum值最大的為提議節(jié)點,同時對提議節(jié)點的的Accum值減去TotalVotinPower(所有驗證節(jié)點power的總和)
for i := 0; i < times; i++ {
mostest := validatorsHeap.Peek().(*Validator)
// mind underflow
mostest.Accum = safeSubClip(mostest.Accum, vals.TotalVotingPower())
if i == times-1 {
vals.Proposer = mostest
} else {
validatorsHeap.Update(mostest, accumComparable{mostest})
}
}
上面的代碼中都有一個times變量矫夷,這個變量在正常運行中都是1葛闷。如果當前節(jié)點中途崩潰重啟過,則times是它落后于集群的選舉次數(shù)双藕。
- 示例
在這里假定genesis.json文件配置了三個驗證節(jié)點v1(192.168.1.110)淑趾、v2(192.168.1.111)、v3(192.168.1.112)忧陪,對應的power值分別為30扣泊、20近范、10,則power總量total=60延蟹。
- 第一次選舉提議節(jié)點:
v1.Accum : 30 (v1.Accum += v1.power)
v2.Accum : 20 (v2.Accum += v2.power)
v3.Accum : 10 (v3.Accum += v3.power)
v1.Accum最大评矩,為本次proposer節(jié)點,同時v1.Accum -= 60
最終v1.Accum : -30 - 第二次提議階段選舉
v1.Accum : 0 (v1.Accum += v1.power)
v2.Accum : 40 (v2.Accum += v2.power)
v3.Accum : 20 (v3.Accum += v3.power)
v2.Accum最大阱飘,為本次proposer節(jié)點稚照,同時v2.Accum -= 60
最終v2.Accum : -20 - 第三次提議階段選舉
v1.Accum : 30 (v1.Accum += v1.power)
v2.Accum : 0 (v2.Accum += v2.power)
v3.Accum : 30 (v3.Accum += v3.power)
v1.Accum最大,為本次proposer節(jié)點(Accum值一樣大則按照地址有小到大排序)俯萌,同時v1.Accum -= 60
最終v1.Accum : -30
轉(zhuǎn)載請注明出處