github.com/true-sqn/fabric@v2.1.1+incompatible/core/ledger/kvledger/tests/committer.go (about) 1 /* 2 Copyright IBM Corp. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package tests 8 9 import ( 10 "testing" 11 12 "github.com/golang/protobuf/proto" 13 "github.com/hyperledger/fabric-protos-go/common" 14 "github.com/hyperledger/fabric/core/ledger" 15 "github.com/hyperledger/fabric/protoutil" 16 "github.com/stretchr/testify/assert" 17 ) 18 19 // committer helps in cutting a block and commits the block (with pvt data) to the ledger 20 type committer struct { 21 lgr ledger.PeerLedger 22 blkgen *blkGenerator 23 assert *assert.Assertions 24 } 25 26 func newCommitter(lgr ledger.PeerLedger, t *testing.T) *committer { 27 return &committer{lgr, newBlockGenerator(lgr, t), assert.New(t)} 28 } 29 30 // cutBlockAndCommitLegacy cuts the next block from the given 'txAndPvtdata' and commits the block (with pvt data) to the ledger 31 // This function return a copy of 'ledger.BlockAndPvtData' that was submitted to the ledger to commit. 32 // A copy is returned instead of the actual one because, ledger makes some changes to the submitted block before commit 33 // (such as setting the metadata) and the test code would want to have the exact copy of the block that was submitted to 34 // the ledger 35 func (c *committer) cutBlockAndCommitLegacy(trans []*txAndPvtdata, missingPvtData ledger.TxMissingPvtDataMap) *ledger.BlockAndPvtData { 36 blk := c.blkgen.nextBlockAndPvtdata(trans, missingPvtData) 37 blkCopy := c.copyOfBlockAndPvtdata(blk) 38 c.assert.NoError( 39 c.lgr.CommitLegacy(blk, &ledger.CommitOptions{}), 40 ) 41 return blkCopy 42 } 43 44 func (c *committer) cutBlockAndCommitExpectError(trans []*txAndPvtdata, missingPvtData ledger.TxMissingPvtDataMap) (*ledger.BlockAndPvtData, error) { 45 blk := c.blkgen.nextBlockAndPvtdata(trans, missingPvtData) 46 blkCopy := c.copyOfBlockAndPvtdata(blk) 47 err := c.lgr.CommitLegacy(blk, &ledger.CommitOptions{}) 48 c.assert.Error(err) 49 return blkCopy, err 50 } 51 52 func (c *committer) copyOfBlockAndPvtdata(blk *ledger.BlockAndPvtData) *ledger.BlockAndPvtData { 53 blkBytes, err := proto.Marshal(blk.Block) 54 c.assert.NoError(err) 55 blkCopy := &common.Block{} 56 c.assert.NoError(proto.Unmarshal(blkBytes, blkCopy)) 57 return &ledger.BlockAndPvtData{Block: blkCopy, PvtData: blk.PvtData, 58 MissingPvtData: blk.MissingPvtData} 59 } 60 61 ///////////////// block generation code /////////////////////////////////////////// 62 // blkGenerator helps creating the next block for the ledger 63 type blkGenerator struct { 64 lastNum uint64 65 lastHash []byte 66 assert *assert.Assertions 67 } 68 69 // newBlockGenerator constructs a 'blkGenerator' and initializes the 'blkGenerator' 70 // from the last block available in the ledger so that the next block can be populated 71 // with the correct block number and previous block hash 72 func newBlockGenerator(lgr ledger.PeerLedger, t *testing.T) *blkGenerator { 73 assert := assert.New(t) 74 info, err := lgr.GetBlockchainInfo() 75 assert.NoError(err) 76 return &blkGenerator{info.Height - 1, info.CurrentBlockHash, assert} 77 } 78 79 // nextBlockAndPvtdata cuts the next block 80 func (g *blkGenerator) nextBlockAndPvtdata(trans []*txAndPvtdata, missingPvtData ledger.TxMissingPvtDataMap) *ledger.BlockAndPvtData { 81 block := protoutil.NewBlock(g.lastNum+1, g.lastHash) 82 blockPvtdata := make(map[uint64]*ledger.TxPvtData) 83 for i, tran := range trans { 84 seq := uint64(i) 85 envelopeBytes, _ := proto.Marshal(tran.Envelope) 86 block.Data.Data = append(block.Data.Data, envelopeBytes) 87 if tran.Pvtws != nil { 88 blockPvtdata[seq] = &ledger.TxPvtData{SeqInBlock: seq, WriteSet: tran.Pvtws} 89 } 90 } 91 block.Header.DataHash = protoutil.BlockDataHash(block.Data) 92 g.lastNum++ 93 g.lastHash = protoutil.BlockHeaderHash(block.Header) 94 setBlockFlagsToValid(block) 95 return &ledger.BlockAndPvtData{Block: block, PvtData: blockPvtdata, 96 MissingPvtData: missingPvtData} 97 }