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  }