Tendermint
Table of Contents
1. Tendermint 简介
Tendermint 是一个区块链开发平台,它包括 core 和 ABCI(Application Blockchain Interface)两个部分: core 为核心模块,由共识引擎和网络模块组成,ABCI 为应用程序接口。
Tendermint 大大简化了区块链的开发工作,Cosmos、Binance Chain、Terra 等区块链项目都使用了 Tendermint 。
2. Tendermint 共识引擎
假设已经选择了 Proposer(节 2.1 会介绍如何选择一个 Proposer),图 1(摘自:https://docs.tendermint.com/v0.35/introduction/what-is-tendermint.html#consensus-overview )介绍了 Tendermint 通过多轮投票来产生新的区块的过程。
Figure 1: Tendermint Consensus Logic
简单的说,Tendermint 通过多轮投票来产生新的块,每一个工作循环包括了三个步骤:
- Propose(提议)
- Prevote(预投票)
- Precommit(预提交)
正常情况下的流程如下: 节点收到 Propose 后,通过验证后,对其它节点广播 Prevote 消息;如果节点收到了超过 2/3 节点发来的 Prevote 消息,则会广播 Precommit 消息;如果节点收到了超过 2/3 节点发来的 Precommit 消息,则写入这个区块到本地。
2.1. Proposer 的选择
Tendermint 使用 PoS(Proof of Stake),要想成为 Proposer,必须抵押资产。Proposer 的选择采用 Weighted Round Robin 算法,详情参考:https://github.com/tendermint/tendermint/blob/master/spec/consensus/proposer-selection.md
2.2. 不分叉
在 Ethereum 中,短暂分叉(Chain Reorganizations)是很常见的。
在 Tendermint 中,只要恶意节点不超过 1/3,就不会分叉。这是利用“锁机制”来实现的,详情可参考:https://zhuanlan.zhihu.com/p/111770050
2.3. Tendermint 和 PBFT 的比较
Tendermint 和 PBFT 很像,比如都最多容忍不超过 1/3 的恶意节点;比如都是三阶段提交,Tendermint 中使用术语 propose/prevote/precommit,这和 PBFT 的三个阶段 pre-prepare/prepare/commit 一一对应。
Tendermint 和 PBFT 的不同如表 1(摘自:https://zhuanlan.zhihu.com/p/111770050 )所示。
比较点 | PBFT | Tendermint BFT |
---|---|---|
节点权力 | 一致 | 根据资产权重有投票权区分 |
打包节点的选取 | 顺序轮换 | POS 算法选取,根据资产轮换 |
超时处理 | pbft 在执行超时会触发 view-change 机制,进行 view 的轮换 | 发现 proposer 超时时产生空快,但是不计入区块链,依靠正常流程轮换主节点 |
共识数据处理 | pbft 为节省硬盘空间会在一定时候清理共识消息,并引入 checkpoint 的概念,完成共识后再清除 | 数据全部放入区块中 |
总结:可以认为 Tendermint 是 PBFT 的简化版本。
3. ABCI
上层应用可以通过 ABCI 和底层进行交互,下面是 ABCI 所支持的函数:
// From: https://github.com/tendermint/tendermint/blob/master/abci/types/application.go // Application is an interface that enables any finite, deterministic state machine // to be driven by a blockchain-based replication engine via the ABCI. // All methods take a RequestXxx argument and return a ResponseXxx argument, // except CheckTx/DeliverTx, which take `tx []byte`, and `Commit`, which takes nothing. type Application interface { // Info/Query Connection Info(RequestInfo) ResponseInfo // Return application info Query(RequestQuery) ResponseQuery // Query for state // Mempool Connection CheckTx(RequestCheckTx) ResponseCheckTx // Validate a tx for the mempool // Consensus Connection InitChain(RequestInitChain) ResponseInitChain // Initialize blockchain w validators/other info from TendermintCore PrepareProposal(RequestPrepareProposal) ResponsePrepareProposal ProcessProposal(RequestProcessProposal) ResponseProcessProposal // Commit the state and return the application Merkle root hash Commit() ResponseCommit // Create application specific vote extension ExtendVote(RequestExtendVote) ResponseExtendVote // Verify application's vote extension data VerifyVoteExtension(RequestVerifyVoteExtension) ResponseVerifyVoteExtension // Deliver the decided block with its txs to the Application FinalizeBlock(RequestFinalizeBlock) ResponseFinalizeBlock // State Sync Connection ListSnapshots(RequestListSnapshots) ResponseListSnapshots // List available snapshots OfferSnapshot(RequestOfferSnapshot) ResponseOfferSnapshot // Offer a snapshot to the application LoadSnapshotChunk(RequestLoadSnapshotChunk) ResponseLoadSnapshotChunk // Load a snapshot chunk ApplySnapshotChunk(RequestApplySnapshotChunk) ResponseApplySnapshotChunk // Apply a snapshot chunk }
4. 参考
Tendermint 论文:The latest gossip on BFT consensus
Tendermint Core documentation: https://docs.tendermint.com/
Tendermint Specifications: https://github.com/tendermint/tendermint/tree/master/spec