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  }