1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
| func (l *kvLedger) CommitLegacy(pvtdataAndBlock *ledger.BlockAndPvtData, commitOpts *ledger.CommitOptions) error {
txstatsInfo, updateBatchBytes, err := l.txmgr.ValidateAndPrepare(pvtdataAndBlock, true)
// 提交区块
if err = l.commitToPvtAndBlockStore(pvtdataAndBlock); err != nil {
return err
}
// 提交到状态库(l.txmgr.current)
if err = l.txmgr.Commit(); err != nil {
panic(errors.WithMessage(err, "error during commit to txmgr"))
}
if l.historyDB != nil {
logger.Debugf("[%s] Committing block [%d] transactions to history database", l.ledgerID, blockNo)
if err := l.historyDB.Commit(block); err != nil {
panic(errors.WithMessage(err, "Error during commit to history db"))
}
}
l.updateBlockStats(
elapsedBlockProcessing,
elapsedBlockstorageAndPvtdataCommit,
elapsedCommitState,
txstatsInfo,
)
}
func (txmgr *LockBasedTxMgr) ValidateAndPrepare(blockAndPvtdata *ledger.BlockAndPvtData, doMVCCValidation bool) ([]*validation.TxStatInfo, []byte, error) {
batch, txstatsInfo, err := txmgr.commitBatchPreparer.ValidateAndPrepareBatch(blockAndPvtdata, doMVCCValidation)
if err != nil {
txmgr.reset()
return nil, nil, err
}
txmgr.current = ¤t{block: block, batch: batch}
if err := txmgr.invokeNamespaceListeners(); err != nil {
txmgr.reset()
return nil, nil, err
}
updateBytes, err := deterministicBytesForPubAndHashUpdates(batch)
return txstatsInfo, updateBytes, err
}
// * ValidateAndPrepareBatch performs validation of transactions in the block and prepares the batch of final writes
func (p *CommitBatchPreparer) ValidateAndPrepareBatch(blockAndPvtdata *ledger.BlockAndPvtData,
doMVCCValidation bool) (*privacyenabledstate.UpdateBatch, []*TxStatInfo, error) {
// 包含 MVCC 校验,校验通过的 tx 才会被加入 batch,最终被应用到状态数据库
if pubAndHashUpdates, err = p.validator.validateAndPrepareBatch(internalBlock, doMVCCValidation); err != nil {
return nil, nil, err
}
if pvtUpdates, err = validateAndPreparePvtBatch(
internalBlock,
p.db,
pubAndHashUpdates,
blockAndPvtdata.PvtData,
p.customTxProcessors,
); err != nil {
return nil, nil, err
}
txsFilter := txflags.ValidationFlags(blk.Metadata.Metadata[common.BlockMetadataIndex_TRANSACTIONS_FILTER]) // 类型转换
for i := range txsFilter {
txsStatInfo[i].ValidationCode = txsFilter.Flag(i)
}
return &privacyenabledstate.UpdateBatch{
PubUpdates: pubAndHashUpdates.publicUpdates,
HashUpdates: pubAndHashUpdates.hashUpdates,
PvtUpdates: pvtUpdates,
}, txsStatInfo, nil
}
|