文章目录
- 前置
- MVCC
本系列目录:超级账本源码(V1.3)解析目录
当peer收到leader发来的block后,需要进行VSCC、MVCC、commit三步操作。
上一篇博客里我们讲了【VSCC】这个过程,下面分析MVCC的核心代码(HLF v1.3)。
前置
- 在
gossip/state/state.go
的listen
函数中收到payload(其中有block和private data),通过queueNewMessage
将其放入payloads
中等待后续处理。 - 然后在
deliverPayloads
函数中开始处理payloads
中的payload,得到block和pvtData后,做了一些简单的检查,之后调用commitBlock
函数。 - 在
commitBblock
中,调用了gossip/privdata/coordinator.go
中的StoreBlock
函数和UpdateLedgerHeight函数(TODO)。 - 在
StoreBlock
函数中,先进行了【VSCC】,然后调用core/ledger/kvledger/lv_ledger.go
中的CommitWithPvtData
函数,该函数第一步就是先做MVCC。
MVCC
-
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一起返回c. 接着调用了
validateAndPreparePvtBatch
验证了private read/write set 的哈希的版本d. 最后根据MVCC的验证结果更新了block的metadata(tx是否有效)
-
在
validateEndorserTX
函数中,实际调用了validateTx
进行验证。validateTx
首先检查了read set的版本,然后检查了range query的key的版本,最后检查了private reads的hash的版本。