github.com/true-sqn/fabric@v2.1.1+incompatible/core/ledger/kvledger/benchmark/chainmgmt/block_gen.go (about) 1 /* 2 Copyright IBM Corp. 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/hyperledger/fabric-protos-go/common" 14 "github.com/hyperledger/fabric-protos-go/peer" 15 "github.com/hyperledger/fabric/core/ledger/util" 16 "github.com/hyperledger/fabric/protoutil" 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 := util.NewTxValidationFlagsSetValue(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 }