github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/common/channelconfig/util_test.go (about) 1 /* 2 Copyright hechain. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package channelconfig 8 9 import ( 10 "bytes" 11 "fmt" 12 "io/ioutil" 13 "testing" 14 15 "github.com/golang/protobuf/proto" 16 "github.com/hechain20/hechain/bccsp/sw" 17 "github.com/hechain20/hechain/common/capabilities" 18 "github.com/hechain20/hechain/protoutil" 19 "github.com/hyperledger/fabric-config/protolator" 20 cb "github.com/hyperledger/fabric-protos-go/common" 21 mspprotos "github.com/hyperledger/fabric-protos-go/msp" 22 ab "github.com/hyperledger/fabric-protos-go/orderer" 23 "github.com/hyperledger/fabric-protos-go/orderer/etcdraft" 24 pb "github.com/hyperledger/fabric-protos-go/peer" 25 "github.com/stretchr/testify/require" 26 ) 27 28 // The tests in this file are all relatively pointless, as all of this function is exercised 29 // in the normal startup path and things will break horribly if they are broken. 30 // There's additionally really nothing to test without simply re-implementing the function 31 // in the test, which also provides no value. But, not including these produces an artificially 32 // low code coverage count, so here they are. 33 34 func basicTest(t *testing.T, sv *StandardConfigValue) { 35 require.NotNil(t, sv) 36 require.NotEmpty(t, sv.Key()) 37 require.NotNil(t, sv.Value()) 38 } 39 40 func TestUtilsBasic(t *testing.T) { 41 basicTest(t, ConsortiumValue("foo")) 42 basicTest(t, HashingAlgorithmValue()) 43 basicTest(t, BlockDataHashingStructureValue()) 44 basicTest(t, OrdererAddressesValue([]string{"foo:1", "bar:2"})) 45 basicTest(t, ConsensusTypeValue("foo", []byte("bar"))) 46 basicTest(t, BatchSizeValue(1, 2, 3)) 47 basicTest(t, BatchTimeoutValue("1s")) 48 basicTest(t, ChannelRestrictionsValue(7)) 49 basicTest(t, KafkaBrokersValue([]string{"foo:1", "bar:2"})) 50 basicTest(t, MSPValue(&mspprotos.MSPConfig{})) 51 basicTest(t, CapabilitiesValue(map[string]bool{"foo": true, "bar": false})) 52 basicTest(t, AnchorPeersValue([]*pb.AnchorPeer{{}, {}})) 53 basicTest(t, ChannelCreationPolicyValue(&cb.Policy{})) 54 basicTest(t, ACLValues(map[string]string{"foo": "fooval", "bar": "barval"})) 55 } 56 57 // createCfgBlockWithSupportedCapabilities will create a config block that contains valid capabilities and should be accepted by the peer 58 func createCfgBlockWithSupportedCapabilities(t *testing.T) *cb.Block { 59 // Create a config 60 config := &cb.Config{ 61 Sequence: 0, 62 ChannelGroup: protoutil.NewConfigGroup(), 63 } 64 65 // construct the config for top group 66 config.ChannelGroup.Version = 0 67 config.ChannelGroup.ModPolicy = AdminsPolicyKey 68 config.ChannelGroup.Values[BlockDataHashingStructureKey] = &cb.ConfigValue{ 69 Value: protoutil.MarshalOrPanic(&cb.BlockDataHashingStructure{ 70 Width: defaultBlockDataHashingStructureWidth, 71 }), 72 ModPolicy: AdminsPolicyKey, 73 } 74 topCapabilities := make(map[string]bool) 75 topCapabilities[capabilities.ChannelV1_1] = true 76 config.ChannelGroup.Values[CapabilitiesKey] = &cb.ConfigValue{ 77 Value: protoutil.MarshalOrPanic(CapabilitiesValue(topCapabilities).Value()), 78 ModPolicy: AdminsPolicyKey, 79 } 80 config.ChannelGroup.Values[ConsortiumKey] = &cb.ConfigValue{ 81 Value: protoutil.MarshalOrPanic(&cb.Consortium{ 82 Name: "testConsortium", 83 }), 84 ModPolicy: AdminsPolicyKey, 85 } 86 config.ChannelGroup.Values[HashingAlgorithmKey] = &cb.ConfigValue{ 87 Value: protoutil.MarshalOrPanic(&cb.HashingAlgorithm{ 88 Name: defaultHashingAlgorithm, 89 }), 90 ModPolicy: AdminsPolicyKey, 91 } 92 config.ChannelGroup.Values[OrdererAddressesKey] = &cb.ConfigValue{ 93 Value: protoutil.MarshalOrPanic(&cb.OrdererAddresses{ 94 Addresses: []string{"orderer.example.com"}, 95 }), 96 ModPolicy: AdminsPolicyKey, 97 } 98 99 // construct the config for Application group 100 config.ChannelGroup.Groups[ApplicationGroupKey] = protoutil.NewConfigGroup() 101 config.ChannelGroup.Groups[ApplicationGroupKey].Version = 0 102 config.ChannelGroup.Groups[ApplicationGroupKey].ModPolicy = AdminsPolicyKey 103 config.ChannelGroup.Groups[ApplicationGroupKey].Policies[ReadersPolicyKey] = &cb.ConfigPolicy{} 104 config.ChannelGroup.Groups[ApplicationGroupKey].Policies[WritersPolicyKey] = &cb.ConfigPolicy{} 105 config.ChannelGroup.Groups[ApplicationGroupKey].Policies[AdminsPolicyKey] = &cb.ConfigPolicy{} 106 appCapabilities := make(map[string]bool) 107 appCapabilities[capabilities.ApplicationV1_1] = true 108 config.ChannelGroup.Groups[ApplicationGroupKey].Values[CapabilitiesKey] = &cb.ConfigValue{ 109 Value: protoutil.MarshalOrPanic(CapabilitiesValue(appCapabilities).Value()), 110 ModPolicy: AdminsPolicyKey, 111 } 112 113 // construct the config for Orderer group 114 config.ChannelGroup.Groups[OrdererGroupKey] = protoutil.NewConfigGroup() 115 config.ChannelGroup.Groups[OrdererGroupKey].Version = 0 116 config.ChannelGroup.Groups[OrdererGroupKey].ModPolicy = AdminsPolicyKey 117 config.ChannelGroup.Groups[OrdererGroupKey].Policies[ReadersPolicyKey] = &cb.ConfigPolicy{} 118 config.ChannelGroup.Groups[OrdererGroupKey].Policies[WritersPolicyKey] = &cb.ConfigPolicy{} 119 config.ChannelGroup.Groups[OrdererGroupKey].Policies[AdminsPolicyKey] = &cb.ConfigPolicy{} 120 config.ChannelGroup.Groups[OrdererGroupKey].Values[BatchSizeKey] = &cb.ConfigValue{ 121 Value: protoutil.MarshalOrPanic( 122 &ab.BatchSize{ 123 MaxMessageCount: 65535, 124 AbsoluteMaxBytes: 1024000000, 125 PreferredMaxBytes: 1024000000, 126 }), 127 ModPolicy: AdminsPolicyKey, 128 } 129 config.ChannelGroup.Groups[OrdererGroupKey].Values[BatchTimeoutKey] = &cb.ConfigValue{ 130 Value: protoutil.MarshalOrPanic( 131 &ab.BatchTimeout{ 132 Timeout: "2s", 133 }), 134 ModPolicy: AdminsPolicyKey, 135 } 136 ordererCapabilities := make(map[string]bool) 137 ordererCapabilities[capabilities.OrdererV1_1] = true 138 config.ChannelGroup.Groups[OrdererGroupKey].Values[CapabilitiesKey] = &cb.ConfigValue{ 139 Value: protoutil.MarshalOrPanic(CapabilitiesValue(ordererCapabilities).Value()), 140 ModPolicy: AdminsPolicyKey, 141 } 142 config.ChannelGroup.Groups[OrdererGroupKey].Values[ConsensusTypeKey] = &cb.ConfigValue{ 143 Value: protoutil.MarshalOrPanic( 144 &ab.ConsensusType{ 145 Type: "solo", 146 }), 147 ModPolicy: AdminsPolicyKey, 148 } 149 150 env := &cb.Envelope{ 151 Payload: protoutil.MarshalOrPanic(&cb.Payload{ 152 Header: &cb.Header{ 153 ChannelHeader: protoutil.MarshalOrPanic(&cb.ChannelHeader{ 154 ChannelId: "testChain", 155 Type: int32(cb.HeaderType_CONFIG), 156 }), 157 }, 158 Data: protoutil.MarshalOrPanic(&cb.ConfigEnvelope{ 159 Config: config, 160 }), 161 }), 162 } 163 configBlock := &cb.Block{ 164 Data: &cb.BlockData{ 165 Data: [][]byte{[]byte(protoutil.MarshalOrPanic(env))}, 166 }, 167 } 168 return configBlock 169 } 170 171 // createCfgBlockWithUnSupportedCapabilities will create a config block that contains mismatched capabilities and should be rejected by the peer 172 func createCfgBlockWithUnsupportedCapabilities(t *testing.T) *cb.Block { 173 // Create a config 174 config := &cb.Config{ 175 Sequence: 0, 176 ChannelGroup: protoutil.NewConfigGroup(), 177 } 178 179 // construct the config for top group 180 config.ChannelGroup.Version = 0 181 config.ChannelGroup.ModPolicy = AdminsPolicyKey 182 config.ChannelGroup.Values[BlockDataHashingStructureKey] = &cb.ConfigValue{ 183 Value: protoutil.MarshalOrPanic(&cb.BlockDataHashingStructure{ 184 Width: defaultBlockDataHashingStructureWidth, 185 }), 186 ModPolicy: AdminsPolicyKey, 187 } 188 topCapabilities := make(map[string]bool) 189 topCapabilities["INCOMPATIBLE_CAPABILITIES"] = true 190 config.ChannelGroup.Values[CapabilitiesKey] = &cb.ConfigValue{ 191 Value: protoutil.MarshalOrPanic(CapabilitiesValue(topCapabilities).Value()), 192 ModPolicy: AdminsPolicyKey, 193 } 194 config.ChannelGroup.Values[ConsortiumKey] = &cb.ConfigValue{ 195 Value: protoutil.MarshalOrPanic(&cb.Consortium{ 196 Name: "testConsortium", 197 }), 198 ModPolicy: AdminsPolicyKey, 199 } 200 config.ChannelGroup.Values[HashingAlgorithmKey] = &cb.ConfigValue{ 201 Value: protoutil.MarshalOrPanic(&cb.HashingAlgorithm{ 202 Name: defaultHashingAlgorithm, 203 }), 204 ModPolicy: AdminsPolicyKey, 205 } 206 config.ChannelGroup.Values[OrdererAddressesKey] = &cb.ConfigValue{ 207 Value: protoutil.MarshalOrPanic(&cb.OrdererAddresses{ 208 Addresses: []string{"orderer.example.com"}, 209 }), 210 ModPolicy: AdminsPolicyKey, 211 } 212 213 // construct the config for Application group 214 config.ChannelGroup.Groups[ApplicationGroupKey] = protoutil.NewConfigGroup() 215 config.ChannelGroup.Groups[ApplicationGroupKey].Version = 0 216 config.ChannelGroup.Groups[ApplicationGroupKey].ModPolicy = AdminsPolicyKey 217 config.ChannelGroup.Groups[ApplicationGroupKey].Policies[ReadersPolicyKey] = &cb.ConfigPolicy{} 218 config.ChannelGroup.Groups[ApplicationGroupKey].Policies[WritersPolicyKey] = &cb.ConfigPolicy{} 219 config.ChannelGroup.Groups[ApplicationGroupKey].Policies[AdminsPolicyKey] = &cb.ConfigPolicy{} 220 appCapabilities := make(map[string]bool) 221 appCapabilities["INCOMPATIBLE_CAPABILITIES"] = true 222 config.ChannelGroup.Groups[ApplicationGroupKey].Values[CapabilitiesKey] = &cb.ConfigValue{ 223 Value: protoutil.MarshalOrPanic(CapabilitiesValue(appCapabilities).Value()), 224 ModPolicy: AdminsPolicyKey, 225 } 226 227 // construct the config for Orderer group 228 config.ChannelGroup.Groups[OrdererGroupKey] = protoutil.NewConfigGroup() 229 config.ChannelGroup.Groups[OrdererGroupKey].Version = 0 230 config.ChannelGroup.Groups[OrdererGroupKey].ModPolicy = AdminsPolicyKey 231 config.ChannelGroup.Groups[OrdererGroupKey].Policies[ReadersPolicyKey] = &cb.ConfigPolicy{} 232 config.ChannelGroup.Groups[OrdererGroupKey].Policies[WritersPolicyKey] = &cb.ConfigPolicy{} 233 config.ChannelGroup.Groups[OrdererGroupKey].Policies[AdminsPolicyKey] = &cb.ConfigPolicy{} 234 config.ChannelGroup.Groups[OrdererGroupKey].Values[BatchSizeKey] = &cb.ConfigValue{ 235 Value: protoutil.MarshalOrPanic( 236 &ab.BatchSize{ 237 MaxMessageCount: 65535, 238 AbsoluteMaxBytes: 1024000000, 239 PreferredMaxBytes: 1024000000, 240 }), 241 ModPolicy: AdminsPolicyKey, 242 } 243 config.ChannelGroup.Groups[OrdererGroupKey].Values[BatchTimeoutKey] = &cb.ConfigValue{ 244 Value: protoutil.MarshalOrPanic( 245 &ab.BatchTimeout{ 246 Timeout: "2s", 247 }), 248 ModPolicy: AdminsPolicyKey, 249 } 250 ordererCapabilities := make(map[string]bool) 251 ordererCapabilities["INCOMPATIBLE_CAPABILITIES"] = true 252 config.ChannelGroup.Groups[OrdererGroupKey].Values[CapabilitiesKey] = &cb.ConfigValue{ 253 Value: protoutil.MarshalOrPanic(CapabilitiesValue(ordererCapabilities).Value()), 254 ModPolicy: AdminsPolicyKey, 255 } 256 config.ChannelGroup.Groups[OrdererGroupKey].Values[ConsensusTypeKey] = &cb.ConfigValue{ 257 Value: protoutil.MarshalOrPanic( 258 &ab.ConsensusType{ 259 Type: "solo", 260 }), 261 ModPolicy: AdminsPolicyKey, 262 } 263 264 env := &cb.Envelope{ 265 Payload: protoutil.MarshalOrPanic(&cb.Payload{ 266 Header: &cb.Header{ 267 ChannelHeader: protoutil.MarshalOrPanic(&cb.ChannelHeader{ 268 ChannelId: "testChain", 269 Type: int32(cb.HeaderType_CONFIG), 270 }), 271 }, 272 Data: protoutil.MarshalOrPanic(&cb.ConfigEnvelope{ 273 Config: config, 274 }), 275 }), 276 } 277 configBlock := &cb.Block{ 278 Data: &cb.BlockData{ 279 Data: [][]byte{[]byte(protoutil.MarshalOrPanic(env))}, 280 }, 281 } 282 return configBlock 283 } 284 285 func TestValidateCapabilities(t *testing.T) { 286 cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore()) 287 require.NoError(t, err) 288 289 // Test config block with valid capabilities requirement 290 cfgBlock := createCfgBlockWithSupportedCapabilities(t) 291 err = ValidateCapabilities(cfgBlock, cryptoProvider) 292 require.NoError(t, err) 293 294 // Test config block with invalid capabilities requirement 295 cfgBlock = createCfgBlockWithUnsupportedCapabilities(t) 296 err = ValidateCapabilities(cfgBlock, cryptoProvider) 297 require.EqualError(t, err, "Channel capability INCOMPATIBLE_CAPABILITIES is required but not supported") 298 } 299 300 func TestExtractMSPIDsForApplicationOrgs(t *testing.T) { 301 // load test_configblock.json that contains the application group 302 // and other properties needed to build channel config and extract MSPIDs 303 blockData, err := ioutil.ReadFile("testdata/test_configblock.json") 304 require.NoError(t, err) 305 block := &cb.Block{} 306 protolator.DeepUnmarshalJSON(bytes.NewBuffer(blockData), block) 307 308 cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore()) 309 require.NoError(t, err) 310 mspids, err := ExtractMSPIDsForApplicationOrgs(block, cryptoProvider) 311 require.NoError(t, err) 312 require.ElementsMatch(t, mspids, []string{"Org1MSP", "Org2MSP"}) 313 } 314 315 func TestMarshalEtcdRaftMetadata(t *testing.T) { 316 md := &etcdraft.ConfigMetadata{ 317 Consenters: []*etcdraft.Consenter{ 318 { 319 Host: "node-1.example.com", 320 Port: 7050, 321 ClientTlsCert: []byte("testdata/tls-client-1.pem"), 322 ServerTlsCert: []byte("testdata/tls-server-1.pem"), 323 }, 324 { 325 Host: "node-2.example.com", 326 Port: 7050, 327 ClientTlsCert: []byte("testdata/tls-client-2.pem"), 328 ServerTlsCert: []byte("testdata/tls-server-2.pem"), 329 }, 330 { 331 Host: "node-3.example.com", 332 Port: 7050, 333 ClientTlsCert: []byte("testdata/tls-client-3.pem"), 334 ServerTlsCert: []byte("testdata/tls-server-3.pem"), 335 }, 336 }, 337 } 338 packed, err := MarshalEtcdRaftMetadata(md) 339 require.Nil(t, err, "marshalling should succeed") 340 require.NotNil(t, packed) 341 342 packed, err = MarshalEtcdRaftMetadata(md) 343 require.Nil(t, err, "marshalling should succeed a second time because we did not mutate ourselves") 344 require.NotNil(t, packed) 345 346 unpacked := &etcdraft.ConfigMetadata{} 347 require.Nil(t, proto.Unmarshal(packed, unpacked), "unmarshalling should succeed") 348 349 var outputCerts, inputCerts [3][]byte 350 for i := range unpacked.GetConsenters() { 351 outputCerts[i] = []byte(unpacked.GetConsenters()[i].GetClientTlsCert()) 352 inputCerts[i], _ = ioutil.ReadFile(fmt.Sprintf("testdata/tls-client-%d.pem", i+1)) 353 354 } 355 356 for i := 0; i < len(inputCerts)-1; i++ { 357 require.NotEqual(t, outputCerts[i+1], outputCerts[i], "expected extracted certs to differ from each other") 358 } 359 }