github.com/kchristidis/fabric@v1.0.4-0.20171028114726-837acd08cde1/test/tools/LTE/chainmgmt/block_gen.go (about) 1 /* 2 Copyright IBM Corp. 2017 All Rights Reserved. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package chainmgmt 18 19 import ( 20 "sync" 21 22 "github.com/golang/protobuf/proto" 23 "github.com/hyperledger/fabric/protos/common" 24 benchcommon "github.com/hyperledger/fabric/test/tools/LTE/common" 25 ) 26 27 const ( 28 numConcurrentTxEnvCreators = 30 29 ) 30 31 type txEnvBytes []byte 32 33 // blkGenerator generates blocks in sequence. One instance of blkGenerator is maintained for each chain 34 type blkGenerator struct { 35 batchConf *BatchConf 36 blockNum uint64 37 previousBlockHash []byte 38 39 srQueue chan SimulationResult 40 txQueue chan txEnvBytes 41 wg *sync.WaitGroup 42 } 43 44 func newBlkGenerator(batchConf *BatchConf, startingBlockNum uint64, previousBlockHash []byte) *blkGenerator { 45 bg := &blkGenerator{ 46 batchConf, 47 startingBlockNum, 48 previousBlockHash, 49 make(chan SimulationResult, batchConf.BatchSize), 50 make(chan txEnvBytes, batchConf.BatchSize), 51 &sync.WaitGroup{}, 52 } 53 bg.startTxEnvCreators() 54 return bg 55 } 56 57 func (bg *blkGenerator) startTxEnvCreators() { 58 for i := 0; i < numConcurrentTxEnvCreators; i++ { 59 go bg.startTxEnvCreator() 60 } 61 } 62 63 func (bg *blkGenerator) startTxEnvCreator() { 64 bg.wg.Add(1) 65 for sr := range bg.srQueue { 66 txEnv, err := createTxEnv(sr) 67 benchcommon.PanicOnError(err) 68 txEnvBytes, err := proto.Marshal(txEnv) 69 benchcommon.PanicOnError(err) 70 bg.txQueue <- txEnvBytes 71 } 72 bg.wg.Done() 73 } 74 75 func (bg *blkGenerator) addTx(sr SimulationResult) { 76 bg.srQueue <- sr 77 } 78 79 func (bg *blkGenerator) nextBlock() *common.Block { 80 block := common.NewBlock(bg.blockNum, bg.previousBlockHash) 81 numTx := 0 82 for txEnvBytes := range bg.txQueue { 83 numTx++ 84 block.Data.Data = append(block.Data.Data, txEnvBytes) 85 if numTx == bg.batchConf.BatchSize { 86 break 87 } 88 } 89 // close() has been called and no pending tx 90 if len(block.Data.Data) == 0 { 91 return nil 92 } 93 block.Header.DataHash = block.Data.Hash() 94 block.Header.Number = bg.blockNum 95 block.Header.PreviousHash = bg.previousBlockHash 96 97 bg.blockNum++ 98 bg.previousBlockHash = block.Header.Hash() 99 return block 100 } 101 102 func (bg *blkGenerator) close() { 103 close(bg.srQueue) 104 bg.wg.Wait() 105 close(bg.txQueue) 106 }