github.com/osdi23p228/fabric@v0.0.0-20221218062954-77808885f5db/orderer/common/multichannel/util_test.go (about) 1 /* 2 Copyright IBM Corp. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package multichannel 8 9 import ( 10 "errors" 11 "fmt" 12 13 cb "github.com/hyperledger/fabric-protos-go/common" 14 "github.com/osdi23p228/fabric/common/capabilities" 15 "github.com/osdi23p228/fabric/common/channelconfig" 16 "github.com/osdi23p228/fabric/common/configtx" 17 "github.com/osdi23p228/fabric/core/config/configtest" 18 "github.com/osdi23p228/fabric/internal/configtxgen/encoder" 19 "github.com/osdi23p228/fabric/internal/configtxgen/genesisconfig" 20 "github.com/osdi23p228/fabric/orderer/common/blockcutter" 21 "github.com/osdi23p228/fabric/orderer/common/msgprocessor" 22 "github.com/osdi23p228/fabric/orderer/common/types" 23 "github.com/osdi23p228/fabric/orderer/consensus" 24 "github.com/osdi23p228/fabric/protoutil" 25 ) 26 27 type mockConsenter struct { 28 cluster bool 29 } 30 31 func (mc *mockConsenter) HandleChain(support consensus.ConsenterSupport, metadata *cb.Metadata) (consensus.Chain, error) { 32 chain := &mockChain{ 33 queue: make(chan *cb.Envelope), 34 cutter: support.BlockCutter(), 35 support: support, 36 metadata: metadata, 37 done: make(chan struct{}), 38 } 39 40 if mc.cluster { 41 clusterChain := &mockChainCluster{} 42 clusterChain.mockChain = chain 43 return clusterChain, nil 44 } 45 46 return chain, nil 47 } 48 49 func (mc *mockConsenter) JoinChain(support consensus.ConsenterSupport, joinBlock *cb.Block) (consensus.Chain, error) { 50 //TODO 51 return nil, errors.New("not implemented") 52 } 53 54 type mockChainCluster struct { 55 *mockChain 56 } 57 58 func (c *mockChainCluster) StatusReport() (types.ClusterRelation, types.Status) { 59 return types.ClusterRelationMember, types.StatusActive 60 } 61 62 type mockChain struct { 63 queue chan *cb.Envelope 64 cutter blockcutter.Receiver 65 support consensus.ConsenterSupport 66 metadata *cb.Metadata 67 done chan struct{} 68 } 69 70 func (mch *mockChain) Errored() <-chan struct{} { 71 return nil 72 } 73 74 func (mch *mockChain) Order(env *cb.Envelope, configSeq uint64) error { 75 mch.queue <- env 76 return nil 77 } 78 79 func (mch *mockChain) Configure(config *cb.Envelope, configSeq uint64) error { 80 mch.queue <- config 81 return nil 82 } 83 84 func (mch *mockChain) WaitReady() error { 85 return nil 86 } 87 88 func (mch *mockChain) Start() { 89 go func() { 90 defer close(mch.done) 91 for { 92 msg, ok := <-mch.queue 93 if !ok { 94 return 95 } 96 97 chdr, err := protoutil.ChannelHeader(msg) 98 if err != nil { 99 logger.Panicf("If a message has arrived to this point, it should already have had header inspected once: %s", err) 100 } 101 102 class := mch.support.ClassifyMsg(chdr) 103 switch class { 104 case msgprocessor.ConfigMsg: 105 batch := mch.support.BlockCutter().Cut() 106 if batch != nil { 107 block := mch.support.CreateNextBlock(batch) 108 mch.support.WriteBlock(block, nil) 109 } 110 111 _, err := mch.support.ProcessNormalMsg(msg) 112 if err != nil { 113 logger.Warningf("Discarding bad config message: %s", err) 114 continue 115 } 116 block := mch.support.CreateNextBlock([]*cb.Envelope{msg}) 117 mch.support.WriteConfigBlock(block, nil) 118 case msgprocessor.NormalMsg: 119 batches, _ := mch.support.BlockCutter().Ordered(msg) 120 for _, batch := range batches { 121 block := mch.support.CreateNextBlock(batch) 122 mch.support.WriteBlock(block, nil) 123 } 124 case msgprocessor.ConfigUpdateMsg: 125 logger.Panicf("Not expecting msg class ConfigUpdateMsg here") 126 default: 127 logger.Panicf("Unsupported msg classification: %v", class) 128 } 129 } 130 }() 131 } 132 133 func (mch *mockChain) Halt() { 134 close(mch.queue) 135 } 136 137 func makeConfigTx(chainID string, i int) *cb.Envelope { 138 group := protoutil.NewConfigGroup() 139 group.Groups[channelconfig.OrdererGroupKey] = protoutil.NewConfigGroup() 140 group.Groups[channelconfig.OrdererGroupKey].Values[fmt.Sprintf("%d", i)] = &cb.ConfigValue{ 141 Value: []byte(fmt.Sprintf("%d", i)), 142 } 143 return makeConfigTxFromConfigUpdateEnvelope(chainID, &cb.ConfigUpdateEnvelope{ 144 ConfigUpdate: protoutil.MarshalOrPanic(&cb.ConfigUpdate{ 145 WriteSet: group, 146 }), 147 }) 148 } 149 150 func makeConfigTxFull(chainID string, i int) *cb.Envelope { 151 gConf := genesisconfig.Load(genesisconfig.SampleInsecureSoloProfile, configtest.GetDevConfigDir()) 152 gConf.Orderer.Capabilities = map[string]bool{ 153 capabilities.OrdererV2_0: true, 154 } 155 gConf.Orderer.MaxChannels = 10 156 channelGroup, err := encoder.NewChannelGroup(gConf) 157 if err != nil { 158 return nil 159 } 160 161 return makeConfigTxFromConfigUpdateEnvelope(chainID, &cb.ConfigUpdateEnvelope{ 162 ConfigUpdate: protoutil.MarshalOrPanic(&cb.ConfigUpdate{ 163 WriteSet: channelGroup, 164 }), 165 }) 166 } 167 168 func makeConfigTxMig(chainID string, i int) *cb.Envelope { 169 gConf := genesisconfig.Load(genesisconfig.SampleInsecureSoloProfile, configtest.GetDevConfigDir()) 170 gConf.Orderer.Capabilities = map[string]bool{ 171 capabilities.OrdererV2_0: true, 172 } 173 gConf.Orderer.OrdererType = "kafka" 174 channelGroup, err := encoder.NewChannelGroup(gConf) 175 if err != nil { 176 return nil 177 } 178 179 return makeConfigTxFromConfigUpdateEnvelope(chainID, &cb.ConfigUpdateEnvelope{ 180 ConfigUpdate: protoutil.MarshalOrPanic(&cb.ConfigUpdate{ 181 WriteSet: channelGroup, 182 }), 183 }) 184 } 185 186 func wrapConfigTx(env *cb.Envelope) *cb.Envelope { 187 result, err := protoutil.CreateSignedEnvelope(cb.HeaderType_ORDERER_TRANSACTION, "testchannelid", mockCrypto(), env, msgVersion, epoch) 188 if err != nil { 189 panic(err) 190 } 191 return result 192 } 193 194 func makeConfigTxFromConfigUpdateEnvelope(chainID string, configUpdateEnv *cb.ConfigUpdateEnvelope) *cb.Envelope { 195 configUpdateTx, err := protoutil.CreateSignedEnvelope(cb.HeaderType_CONFIG_UPDATE, chainID, mockCrypto(), configUpdateEnv, msgVersion, epoch) 196 if err != nil { 197 panic(err) 198 } 199 configTx, err := protoutil.CreateSignedEnvelope(cb.HeaderType_CONFIG, chainID, mockCrypto(), &cb.ConfigEnvelope{ 200 Config: &cb.Config{Sequence: 1, ChannelGroup: configtx.UnmarshalConfigUpdateOrPanic(configUpdateEnv.ConfigUpdate).WriteSet}, 201 LastUpdate: configUpdateTx}, 202 msgVersion, epoch) 203 if err != nil { 204 panic(err) 205 } 206 return configTx 207 } 208 209 func makeNormalTx(chainID string, i int) *cb.Envelope { 210 payload := &cb.Payload{ 211 Header: &cb.Header{ 212 ChannelHeader: protoutil.MarshalOrPanic(&cb.ChannelHeader{ 213 Type: int32(cb.HeaderType_ENDORSER_TRANSACTION), 214 ChannelId: chainID, 215 }), 216 SignatureHeader: protoutil.MarshalOrPanic(&cb.SignatureHeader{}), 217 }, 218 Data: []byte(fmt.Sprintf("%d", i)), 219 } 220 return &cb.Envelope{ 221 Payload: protoutil.MarshalOrPanic(payload), 222 } 223 }