github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/core/ledger/kvledger/tests/committer.go (about)

     1  /*
     2  Copyright hechain. 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/hechain20/hechain/core/ledger"
    14  	"github.com/hechain20/hechain/protoutil"
    15  	"github.com/hyperledger/fabric-protos-go/common"
    16  	"github.com/stretchr/testify/require"
    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 *require.Assertions
    24  }
    25  
    26  func newCommitter(lgr ledger.PeerLedger, t *testing.T) *committer {
    27  	return &committer{lgr, newBlockGenerator(lgr, t), require.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.TxMissingPvtData) *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.TxMissingPvtData) *ledger.BlockAndPvtData {
    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
    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{
    58  		Block: blkCopy, PvtData: blk.PvtData,
    59  		MissingPvtData: blk.MissingPvtData,
    60  	}
    61  }
    62  
    63  /////////////////   block generation code  ///////////////////////////////////////////
    64  // blkGenerator helps creating the next block for the ledger
    65  type blkGenerator struct {
    66  	lastNum  uint64
    67  	lastHash []byte
    68  	assert   *require.Assertions
    69  }
    70  
    71  // newBlockGenerator constructs a 'blkGenerator' and initializes the 'blkGenerator'
    72  // from the last block available in the ledger so that the next block can be populated
    73  // with the correct block number and previous block hash
    74  func newBlockGenerator(lgr ledger.PeerLedger, t *testing.T) *blkGenerator {
    75  	require := require.New(t)
    76  	info, err := lgr.GetBlockchainInfo()
    77  	require.NoError(err)
    78  	return &blkGenerator{info.Height - 1, info.CurrentBlockHash, require}
    79  }
    80  
    81  // nextBlockAndPvtdata cuts the next block
    82  func (g *blkGenerator) nextBlockAndPvtdata(trans []*txAndPvtdata, missingPvtData ledger.TxMissingPvtData) *ledger.BlockAndPvtData {
    83  	block := protoutil.NewBlock(g.lastNum+1, g.lastHash)
    84  	blockPvtdata := make(map[uint64]*ledger.TxPvtData)
    85  	for i, tran := range trans {
    86  		seq := uint64(i)
    87  		envelopeBytes, _ := proto.Marshal(tran.Envelope)
    88  		block.Data.Data = append(block.Data.Data, envelopeBytes)
    89  		if tran.Pvtws != nil {
    90  			blockPvtdata[seq] = &ledger.TxPvtData{SeqInBlock: seq, WriteSet: tran.Pvtws}
    91  		}
    92  	}
    93  	block.Header.DataHash = protoutil.BlockDataHash(block.Data)
    94  	g.lastNum++
    95  	g.lastHash = protoutil.BlockHeaderHash(block.Header)
    96  	setBlockFlagsToValid(block)
    97  	return &ledger.BlockAndPvtData{
    98  		Block: block, PvtData: blockPvtdata,
    99  		MissingPvtData: missingPvtData,
   100  	}
   101  }