tendermint源码解析
一、最基礎(chǔ)的默認配置
源碼文件:tendermint/tendermint/config/config.go
這里定義了tendermint的默認配置存放的目錄和文件名,在執(zhí)行tendermint的init命令時會調(diào)用。
二、生成默認配置文件
命令:
源碼文件:tendermint/cmd/tendermint/commands/init.go
觸發(fā)的函數(shù)調(diào)用關(guān)系
initFiles -> initFilesWithConfig
結(jié)果生成兩個配置文件:
private validator
genesis file
node_key.json
三、核心配置文件
config.toml由tendermint node命令生成
源碼文件:
tendermint/cmd/tendermint/main.go
tendermint/cmd/tendermint/commands/root.go
tendermint/config/toml.go
調(diào)用關(guān)系:
main() -> RootCmd -> ParseConfig() -> EnsureRoot() -> writeDefaultConfigFile() -> DefaultConfig()
tendermint每次運行時,都會檢查config.toml,找不到就會自動生成一個。
四、編譯文件
這句代碼的作用強制轉(zhuǎn)換一個空指針到一個unused的變量。
官方注釋(看不懂)
GOLANG注釋
This post is about a little-known way to make compile-time assertions in Go. You probably shouldn’t use it, but it is interesting to know about.As a warm-up, here’s a fairly well-known form of compile-time assertions in Go: Interface satisfaction checks.In this code (playground), the var _ = line ensures that type W is a stringWriter, as checked for by io.WriteString.五、RPC測試
1.RPC配置
源碼文件:tendermint/config/config.go
Unsafe是針對ListenAddress和GRPCListenAddress都起作用的配置項。ListenAddress和GRPCListenAddress的關(guān)系一看就是完全對等的。既然這兩種連接是對等的,那么MaxOpenConnections和GRPCMaxOpenConnections也應(yīng)該是獨立計數(shù)的。
從源碼看出,ListenAddress在社區(qū)中稱為RPC,支持兩種協(xié)議,Http和Websocket,這兩種協(xié)議可以共用一個端口,源于websockt與 HTTP 協(xié)議有著良好的兼容性,tendermint中使用一個特殊的路徑來做區(qū)分,下面是部分源碼。
mux := http.NewServeMux() wm := rpcserver.NewWebsocketManager(rpccore.Routes, coreCodec, rpcserver.EventSubscriber(n.eventBus))wm.SetLogger(rpcLogger.With("protocol", "websocket"))mux.HandleFunc("/websocket", wm.WebsocketHandler)2.RPC測試
tendermint在連接ABCI服務(wù)端的時候,扮演的是一個客戶端;當JSON-RPC連接tendermint的時候扮演的是一個服務(wù)端的角色。
Tendermint 支持下面三種RPC協(xié)議:
- URI over HTTP
- JSONRPC over HTTP
- JSONRPC over websockets
同時,tendermint也提供了GRPC監(jiān)聽接口,下面是相關(guān)代碼
從代碼注釋可以看出,目前gRPC接口只是用來方便開發(fā)者,并不帶算實際生產(chǎn)中使用。
交易流程
在我們調(diào)用 broadcast_tx_commit 的時候,會先調(diào)用 CheckTx,驗證通過后會把 TX 加入到 mempool 里。在 kvstore 示例中沒有對 transaction 做檢查,直接通過:
放到 mempool 里的 TX 會被定期廣播到所有節(jié)點。當 Tendermint 選出了 Proposal 節(jié)點后,它便會從 mempool 里選出一系列的 TXs,將它們組成一個 Block,廣播給所有的節(jié)點。節(jié)點在收到 Block 后,會對 Block 里的所有 TX 執(zhí)行 DeliverTX 操作,同時對 Block 執(zhí)行 Commit 操作。
我們調(diào)用 broadcast_tx_commit 返回的結(jié)果其實就是 DeliverTX 返回的結(jié)果
可以看出它會從輸入?yún)?shù)中解析出 key 和 value,最后保存在應(yīng)用的 State 中。
當所有的 TX 被處理完之后需要調(diào)用 Commit 來更新整個區(qū)塊的狀態(tài),包括高度加 1 等:
tendermint的proposer節(jié)點選舉
概述
endermint的proposer節(jié)點選舉過程不需要網(wǎng)絡(luò)通信,而是根據(jù)config目錄下的genesis.json而決定的。genesis.json文件中有一個配置項是“validators”,這個key對應(yīng)的是一個validator的列表,包含validator的pub_key和power。pub_key確定是哪個tendermint節(jié)點,power決定這個節(jié)點被選舉為proposer節(jié)點的頻率。
選舉算法詳解
1)加載并解析genesis.json,獲取每個節(jié)點的pub_key和power,power解析后保存在VotingPower中。
2)對每個validator的Accum進行賦值,Accum的值為驗證節(jié)點的權(quán)重值。
3)選擇當次Accum值最大的為提議節(jié)點,同時對提議節(jié)點的的Accum值減去TotalVotinPower(所有驗證節(jié)點power的總和)
for i := 0; i < times; i++ {mostest := validatorsHeap.Peek().(*Validator)// mind underflowmostest.Accum = safeSubClip(mostest.Accum, vals.TotalVotingPower())if i == times-1 {vals.Proposer = mostest} else {validatorsHeap.Update(mostest, accumComparable{mostest})}}注:上面的代碼中都有一個times變量,這個變量在正常運行中都是1。如果當前節(jié)點中途崩潰重啟過,則times是它落后于集群的選舉次數(shù)。
Tendermint Networks
Tendermint 網(wǎng)絡(luò)中節(jié)點有兩種類型:validator node 和 non-validator node。
If we want to add more nodes to the network, we have two choices: we can add a new validator node, who will also participate in the consensus by proposing blocks and voting on them, or we can add a new non-validator node, who will not participate directly, but will verify and keep up with the consensus protocol.
當 tendermint core 收到一個 rpc 交易請求,并完成共識之后,會給 app server 發(fā)送請求。
消息通訊
P2P模塊初始化的時候,也會初始化mempool reactor、blockchain reactor、consensus reactor、evidence reactor(還有上面講述的pex reactor),然后add到p2p模塊,不同的reactor帶不同的channel id
當mempool、blockchain、consensus、evidence模塊發(fā)送消息的時候,調(diào)用p2p模塊的send,參數(shù)有channel id
對端節(jié)點p2p模塊收到消息后,會根據(jù)channel id把消息轉(zhuǎn)發(fā)給對應(yīng)的模塊
總結(jié)
以上是生活随笔為你收集整理的tendermint源码解析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 苹果开发者账号管理后台developer
- 下一篇: java助记词反向_GitHub - g