本系列目录:超级账本源码(V1.3)解析目录
当peer收到leader发来的block后,需要进行VSCC、MVCC、commit三步操作。
上一篇博客里我们讲了【VSCC】这个过程,下面分析MVCC的核心代码(HLF v1.3)。
CommitWithPvtData主要做了三件事情:1,MVCC(ValidateAndPrepare);2,存储block(CommitWithPvtData);3,更新world state数据库(l.txtmgmt.Commit)。(可选的4,更新history数据库l.historyDB.Commit)
在core/ledger/kvledger/txmgmt/txmgr/lockbasedtxmgr/lockbased_txmgr.go的ValidateAndPrepare函数中:
a. 调用txmgr.pvtdataPurgeMgr.WaitForPrepareToFinish()(TODO)
b. 调用core/ledger/kvledger/txmgmt/validator/valimpl/default_impl.go的ValidateAndPrepareBatch函数(核心),
c. 调用invokeNamespaceListeners (TODO)
在ValidateAndPrepareBatch函数中,
a. 先调用preprocessProtoBlock函数对待验证的block做了预处理,包括去掉了VSCC过程中被标记为无效的TX,验证了有效TX的write set的有效性;
b. 然后调用了core/ledger/kvledger/txmgmt/validator/statebasedval/state_based_validator.go中的ValidateAndPrepareBatch函数,该函数对每一个TX调用了validateEndorserTX验证读写集,检查通过的TX将读写集合并到batch一起返回,最后更新了txmgr.current = ¤t{block: block, batch: batch}用于【Commit】阶段更新world state DB.
c. 接着调用了validateAndPreparePvtBatch验证了private read/write set 的哈希的版本
d. 最后根据MVCC的验证结果更新了block的metadata(tx是否有效)
在validateEndorserTX函数中,实际调用了validateTx进行验证。validateTx首先检查了read set的版本,然后检查了range query的key的版本,最后检查了private reads的hash的版本。