github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/core/ledger/kvledger/benchmark/chainmgmt/block_gen.go (about)

     1  /*
     2  Copyright hechain. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package chainmgmt
     8  
     9  import (
    10  	"sync"
    11  
    12  	"github.com/golang/protobuf/proto"
    13  	"github.com/hechain20/hechain/internal/pkg/txflags"
    14  	"github.com/hechain20/hechain/protoutil"
    15  	"github.com/hyperledger/fabric-protos-go/common"
    16  	"github.com/hyperledger/fabric-protos-go/peer"
    17  )
    18  
    19  const (
    20  	numConcurrentTxEnvCreators = 30
    21  )
    22  
    23  type txEnvBytes []byte
    24  
    25  // blkGenerator generates blocks in sequence. One instance of blkGenerator is maintained for each chain
    26  type blkGenerator struct {
    27  	batchConf         *BatchConf
    28  	blockNum          uint64
    29  	previousBlockHash []byte
    30  
    31  	srQueue chan SimulationResult
    32  	txQueue chan txEnvBytes
    33  	wg      *sync.WaitGroup
    34  }
    35  
    36  func newBlkGenerator(batchConf *BatchConf, startingBlockNum uint64, previousBlockHash []byte) *blkGenerator {
    37  	bg := &blkGenerator{
    38  		batchConf,
    39  		startingBlockNum,
    40  		previousBlockHash,
    41  		make(chan SimulationResult, batchConf.BatchSize),
    42  		make(chan txEnvBytes, batchConf.BatchSize),
    43  		&sync.WaitGroup{},
    44  	}
    45  	bg.startTxEnvCreators()
    46  	return bg
    47  }
    48  
    49  func (bg *blkGenerator) startTxEnvCreators() {
    50  	for i := 0; i < numConcurrentTxEnvCreators; i++ {
    51  		go bg.startTxEnvCreator()
    52  	}
    53  }
    54  
    55  func (bg *blkGenerator) startTxEnvCreator() {
    56  	bg.wg.Add(1)
    57  	for sr := range bg.srQueue {
    58  		txEnv, err := createTxEnv(sr)
    59  		panicOnError(err)
    60  		txEnvBytes, err := proto.Marshal(txEnv)
    61  		panicOnError(err)
    62  		bg.txQueue <- txEnvBytes
    63  	}
    64  	bg.wg.Done()
    65  }
    66  
    67  func (bg *blkGenerator) addTx(sr SimulationResult) {
    68  	bg.srQueue <- sr
    69  }
    70  
    71  func (bg *blkGenerator) nextBlock() *common.Block {
    72  	block := protoutil.NewBlock(bg.blockNum, bg.previousBlockHash)
    73  	numTx := 0
    74  	for txEnvBytes := range bg.txQueue {
    75  		numTx++
    76  		block.Data.Data = append(block.Data.Data, txEnvBytes)
    77  		if numTx == bg.batchConf.BatchSize {
    78  			break
    79  		}
    80  	}
    81  	// close() has been called and no pending tx
    82  	if len(block.Data.Data) == 0 {
    83  		return nil
    84  	}
    85  	block.Header.DataHash = protoutil.BlockDataHash(block.Data)
    86  	block.Header.Number = bg.blockNum
    87  	block.Header.PreviousHash = bg.previousBlockHash
    88  	txsfltr := txflags.NewWithValues(len(block.Data.Data), peer.TxValidationCode_VALID)
    89  	block.Metadata.Metadata[common.BlockMetadataIndex_TRANSACTIONS_FILTER] = txsfltr
    90  
    91  	bg.blockNum++
    92  	bg.previousBlockHash = protoutil.BlockHeaderHash(block.Header)
    93  	return block
    94  }
    95  
    96  func (bg *blkGenerator) close() {
    97  	close(bg.srQueue)
    98  	bg.wg.Wait()
    99  	close(bg.txQueue)
   100  }