github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/orderer/common/msgprocessor/systemchannel_test.go (about)

     1  /*
     2  Copyright hechain. 2017 All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package msgprocessor
     8  
     9  import (
    10  	"fmt"
    11  	"testing"
    12  
    13  	"github.com/golang/protobuf/proto"
    14  	"github.com/hechain20/hechain/bccsp/sw"
    15  	"github.com/hechain20/hechain/common/capabilities"
    16  	"github.com/hechain20/hechain/common/channelconfig"
    17  	"github.com/hechain20/hechain/core/config/configtest"
    18  	"github.com/hechain20/hechain/internal/configtxgen/encoder"
    19  	"github.com/hechain20/hechain/internal/configtxgen/genesisconfig"
    20  	"github.com/hechain20/hechain/internal/pkg/identity"
    21  	"github.com/hechain20/hechain/orderer/common/msgprocessor/mocks"
    22  	"github.com/hechain20/hechain/protoutil"
    23  	cb "github.com/hyperledger/fabric-protos-go/common"
    24  	"github.com/hyperledger/fabric-protos-go/orderer"
    25  	"github.com/pkg/errors"
    26  	"github.com/stretchr/testify/require"
    27  )
    28  
    29  type mockSystemChannelSupport struct {
    30  	NewChannelConfigVal *mocks.ConfigTXValidator
    31  	NewChannelConfigErr error
    32  }
    33  
    34  func newMockConfigTXValidator(err error) *mocks.ConfigTXValidator {
    35  	mockValidator := &mocks.ConfigTXValidator{}
    36  	mockValidator.ProposeConfigUpdateReturns(&cb.ConfigEnvelope{}, err)
    37  	return mockValidator
    38  }
    39  
    40  func (mscs *mockSystemChannelSupport) NewChannelConfig(env *cb.Envelope) (channelconfig.Resources, error) {
    41  	mockResources := &mocks.Resources{}
    42  	mockResources.ConfigtxValidatorReturns(mscs.NewChannelConfigVal)
    43  	return mockResources, mscs.NewChannelConfigErr
    44  }
    45  
    46  func TestProcessSystemChannelNormalMsg(t *testing.T) {
    47  	t.Run("Missing header", func(t *testing.T) {
    48  		mscs := &mockSystemChannelSupport{}
    49  		ms := &mockSystemChannelFilterSupport{
    50  			OrdererConfigVal: &mocks.OrdererConfig{},
    51  		}
    52  		cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
    53  		require.NoError(t, err)
    54  		_, err = NewSystemChannel(ms, mscs, nil, cryptoProvider).ProcessNormalMsg(&cb.Envelope{})
    55  		require.NotNil(t, err)
    56  		require.Regexp(t, "header not set", err.Error())
    57  	})
    58  	t.Run("Mismatched channel ID", func(t *testing.T) {
    59  		mscs := &mockSystemChannelSupport{}
    60  		ms := &mockSystemChannelFilterSupport{
    61  			OrdererConfigVal: &mocks.OrdererConfig{},
    62  		}
    63  		cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
    64  		require.NoError(t, err)
    65  		_, err = NewSystemChannel(ms, mscs, nil, cryptoProvider).ProcessNormalMsg(&cb.Envelope{
    66  			Payload: protoutil.MarshalOrPanic(&cb.Payload{
    67  				Header: &cb.Header{
    68  					ChannelHeader: protoutil.MarshalOrPanic(&cb.ChannelHeader{
    69  						ChannelId: testChannelID + ".different",
    70  					}),
    71  				},
    72  			}),
    73  		})
    74  		require.Equal(t, ErrChannelDoesNotExist, err)
    75  	})
    76  	t.Run("Good", func(t *testing.T) {
    77  		mscs := &mockSystemChannelSupport{}
    78  		ms := &mockSystemChannelFilterSupport{
    79  			SequenceVal:      7,
    80  			OrdererConfigVal: newMockOrdererConfig(true, orderer.ConsensusType_STATE_NORMAL),
    81  		}
    82  		cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
    83  		require.NoError(t, err)
    84  		cs, err := NewSystemChannel(ms, mscs, NewRuleSet([]Rule{AcceptRule}), cryptoProvider).ProcessNormalMsg(&cb.Envelope{
    85  			Payload: protoutil.MarshalOrPanic(&cb.Payload{
    86  				Header: &cb.Header{
    87  					ChannelHeader: protoutil.MarshalOrPanic(&cb.ChannelHeader{
    88  						ChannelId: testChannelID,
    89  					}),
    90  				},
    91  			}),
    92  		})
    93  		require.Nil(t, err)
    94  		require.Equal(t, ms.SequenceVal, cs)
    95  	})
    96  }
    97  
    98  func TestSystemChannelConfigUpdateMsg(t *testing.T) {
    99  	t.Run("Missing header", func(t *testing.T) {
   100  		mscs := &mockSystemChannelSupport{}
   101  		ms := &mockSystemChannelFilterSupport{
   102  			OrdererConfigVal: &mocks.OrdererConfig{},
   103  		}
   104  		cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
   105  		require.NoError(t, err)
   106  		_, _, err = NewSystemChannel(ms, mscs, NewRuleSet([]Rule{AcceptRule}), cryptoProvider).ProcessConfigUpdateMsg(&cb.Envelope{})
   107  		require.NotNil(t, err)
   108  		require.Regexp(t, "header not set", err.Error())
   109  	})
   110  	t.Run("NormalUpdate", func(t *testing.T) {
   111  		mscs := &mockSystemChannelSupport{}
   112  		ms := &mockSystemChannelFilterSupport{
   113  			SequenceVal:            7,
   114  			ProposeConfigUpdateVal: &cb.ConfigEnvelope{},
   115  			OrdererConfigVal:       newMockOrdererConfig(true, orderer.ConsensusType_STATE_NORMAL),
   116  		}
   117  		cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
   118  		require.NoError(t, err)
   119  		sysChan := NewSystemChannel(ms, mscs, NewRuleSet([]Rule{AcceptRule}), cryptoProvider)
   120  		sysChan.maintenanceFilter = AcceptRule
   121  		config, cs, err := sysChan.ProcessConfigUpdateMsg(&cb.Envelope{
   122  			Payload: protoutil.MarshalOrPanic(&cb.Payload{
   123  				Header: &cb.Header{
   124  					ChannelHeader: protoutil.MarshalOrPanic(&cb.ChannelHeader{
   125  						ChannelId: testChannelID,
   126  					}),
   127  				},
   128  			}),
   129  		})
   130  		require.NotNil(t, config)
   131  		require.Equal(t, cs, ms.SequenceVal)
   132  		require.Nil(t, err)
   133  	})
   134  	t.Run("BadNewChannelConfig", func(t *testing.T) {
   135  		mscs := &mockSystemChannelSupport{
   136  			NewChannelConfigErr: fmt.Errorf("An error"),
   137  		}
   138  		ms := &mockSystemChannelFilterSupport{
   139  			ProposeConfigUpdateVal: &cb.ConfigEnvelope{},
   140  			OrdererConfigVal:       &mocks.OrdererConfig{},
   141  		}
   142  		cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
   143  		require.NoError(t, err)
   144  		_, _, err = NewSystemChannel(ms, mscs, NewRuleSet([]Rule{AcceptRule}), cryptoProvider).ProcessConfigUpdateMsg(&cb.Envelope{
   145  			Payload: protoutil.MarshalOrPanic(&cb.Payload{
   146  				Header: &cb.Header{
   147  					ChannelHeader: protoutil.MarshalOrPanic(&cb.ChannelHeader{
   148  						ChannelId: testChannelID + "different",
   149  					}),
   150  				},
   151  			}),
   152  		})
   153  		require.Equal(t, mscs.NewChannelConfigErr, err)
   154  	})
   155  	t.Run("BadProposedUpdate", func(t *testing.T) {
   156  		mscs := &mockSystemChannelSupport{
   157  			NewChannelConfigVal: newMockConfigTXValidator(fmt.Errorf("An error")),
   158  		}
   159  		ms := &mockSystemChannelFilterSupport{
   160  			ProposeConfigUpdateVal: &cb.ConfigEnvelope{},
   161  			OrdererConfigVal:       &mocks.OrdererConfig{},
   162  		}
   163  		cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
   164  		require.NoError(t, err)
   165  		_, _, err = NewSystemChannel(ms, mscs, NewRuleSet([]Rule{AcceptRule}), cryptoProvider).ProcessConfigUpdateMsg(&cb.Envelope{
   166  			Payload: protoutil.MarshalOrPanic(&cb.Payload{
   167  				Header: &cb.Header{
   168  					ChannelHeader: protoutil.MarshalOrPanic(&cb.ChannelHeader{
   169  						ChannelId: testChannelID + "different",
   170  					}),
   171  				},
   172  			}),
   173  		})
   174  		require.EqualError(t, err, "error validating channel creation transaction for new channel 'foodifferent', could not successfully apply update to template configuration: An error")
   175  	})
   176  	t.Run("BadSignEnvelope", func(t *testing.T) {
   177  		mscs := &mockSystemChannelSupport{
   178  			NewChannelConfigVal: &mocks.ConfigTXValidator{},
   179  		}
   180  		ms := &mockSystemChannelFilterSupport{
   181  			ProposeConfigUpdateVal: &cb.ConfigEnvelope{},
   182  			OrdererConfigVal:       &mocks.OrdererConfig{},
   183  		}
   184  		cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
   185  		require.NoError(t, err)
   186  		_, _, err = NewSystemChannel(ms, mscs, NewRuleSet([]Rule{AcceptRule}), cryptoProvider).ProcessConfigUpdateMsg(&cb.Envelope{
   187  			Payload: protoutil.MarshalOrPanic(&cb.Payload{
   188  				Header: &cb.Header{
   189  					ChannelHeader: protoutil.MarshalOrPanic(&cb.ChannelHeader{
   190  						ChannelId: testChannelID + "different",
   191  					}),
   192  				},
   193  			}),
   194  		})
   195  		require.Regexp(t, "Marshal called with nil", err)
   196  	})
   197  	t.Run("BadByFilter", func(t *testing.T) {
   198  		mscs := &mockSystemChannelSupport{
   199  			NewChannelConfigVal: newMockConfigTXValidator(nil),
   200  		}
   201  		ms := &mockSystemChannelFilterSupport{
   202  			SequenceVal:            7,
   203  			ProposeConfigUpdateVal: &cb.ConfigEnvelope{},
   204  			OrdererConfigVal:       &mocks.OrdererConfig{},
   205  		}
   206  		cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
   207  		require.NoError(t, err)
   208  		_, _, err = NewSystemChannel(ms, mscs, NewRuleSet([]Rule{RejectRule}), cryptoProvider).ProcessConfigUpdateMsg(&cb.Envelope{
   209  			Payload: protoutil.MarshalOrPanic(&cb.Payload{
   210  				Header: &cb.Header{
   211  					ChannelHeader: protoutil.MarshalOrPanic(&cb.ChannelHeader{
   212  						ChannelId: testChannelID + "different",
   213  					}),
   214  				},
   215  			}),
   216  		})
   217  		require.Equal(t, RejectRule.Apply(nil), err)
   218  	})
   219  	t.Run("RejectByMaintenance", func(t *testing.T) {
   220  		mscs := &mockSystemChannelSupport{
   221  			NewChannelConfigVal: newMockConfigTXValidator(nil),
   222  		}
   223  		ms := &mockSystemChannelFilterSupport{
   224  			SequenceVal:            7,
   225  			ProposeConfigUpdateVal: &cb.ConfigEnvelope{},
   226  			OrdererConfigVal:       &mocks.OrdererConfig{},
   227  		}
   228  		cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
   229  		require.NoError(t, err)
   230  		sysChan := NewSystemChannel(ms, mscs, NewRuleSet([]Rule{AcceptRule}), cryptoProvider)
   231  		sysChan.maintenanceFilter = RejectRule
   232  		_, _, err = sysChan.ProcessConfigUpdateMsg(&cb.Envelope{
   233  			Payload: protoutil.MarshalOrPanic(&cb.Payload{
   234  				Header: &cb.Header{
   235  					ChannelHeader: protoutil.MarshalOrPanic(&cb.ChannelHeader{
   236  						ChannelId: testChannelID,
   237  					}),
   238  				},
   239  			}),
   240  		})
   241  		require.Equal(t, RejectRule.Apply(nil), errors.Cause(err))
   242  	})
   243  	t.Run("Good", func(t *testing.T) {
   244  		mscs := &mockSystemChannelSupport{
   245  			NewChannelConfigVal: newMockConfigTXValidator(nil),
   246  		}
   247  		ms := &mockSystemChannelFilterSupport{
   248  			SequenceVal:            7,
   249  			ProposeConfigUpdateVal: &cb.ConfigEnvelope{},
   250  			OrdererConfigVal:       &mocks.OrdererConfig{},
   251  		}
   252  		cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
   253  		require.NoError(t, err)
   254  		config, cs, err := NewSystemChannel(ms, mscs, NewRuleSet([]Rule{AcceptRule}), cryptoProvider).ProcessConfigUpdateMsg(&cb.Envelope{
   255  			Payload: protoutil.MarshalOrPanic(&cb.Payload{
   256  				Header: &cb.Header{
   257  					ChannelHeader: protoutil.MarshalOrPanic(&cb.ChannelHeader{
   258  						ChannelId: testChannelID + "different",
   259  					}),
   260  				},
   261  			}),
   262  		})
   263  		require.Equal(t, cs, ms.SequenceVal)
   264  		require.NotNil(t, config)
   265  		require.Nil(t, err)
   266  	})
   267  }
   268  
   269  func TestSystemChannelConfigMsg(t *testing.T) {
   270  	t.Run("ConfigMsg", func(t *testing.T) {
   271  		t.Run("BadPayloadData", func(t *testing.T) {
   272  			mscs := &mockSystemChannelSupport{
   273  				NewChannelConfigVal: newMockConfigTXValidator(nil),
   274  			}
   275  			ms := &mockSystemChannelFilterSupport{
   276  				SequenceVal:            7,
   277  				ProposeConfigUpdateVal: &cb.ConfigEnvelope{},
   278  				OrdererConfigVal:       &mocks.OrdererConfig{},
   279  			}
   280  			cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
   281  			require.NoError(t, err)
   282  			_, _, err = NewSystemChannel(ms, mscs, NewRuleSet([]Rule{AcceptRule}), cryptoProvider).ProcessConfigMsg(&cb.Envelope{
   283  				Payload: protoutil.MarshalOrPanic(&cb.Payload{
   284  					Header: &cb.Header{
   285  						ChannelHeader: protoutil.MarshalOrPanic(&cb.ChannelHeader{
   286  							ChannelId: testChannelID,
   287  							Type:      int32(cb.HeaderType_CONFIG),
   288  						}),
   289  					},
   290  					Data: []byte("hello"),
   291  				}),
   292  			})
   293  			require.Error(t, err)
   294  		})
   295  
   296  		t.Run("Good", func(t *testing.T) {
   297  			mscs := &mockSystemChannelSupport{
   298  				NewChannelConfigVal: newMockConfigTXValidator(nil),
   299  			}
   300  			ms := &mockSystemChannelFilterSupport{
   301  				SequenceVal:            7,
   302  				ProposeConfigUpdateVal: &cb.ConfigEnvelope{},
   303  				OrdererConfigVal:       newMockOrdererConfig(false, orderer.ConsensusType_STATE_NORMAL),
   304  			}
   305  			cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
   306  			require.NoError(t, err)
   307  			sysChan := NewSystemChannel(ms, mscs, NewRuleSet([]Rule{AcceptRule}), cryptoProvider)
   308  			sysChan.maintenanceFilter = AcceptRule
   309  			config, seq, err := sysChan.ProcessConfigMsg(&cb.Envelope{
   310  				Payload: protoutil.MarshalOrPanic(&cb.Payload{
   311  					Header: &cb.Header{
   312  						ChannelHeader: protoutil.MarshalOrPanic(&cb.ChannelHeader{
   313  							ChannelId: testChannelID,
   314  							Type:      int32(cb.HeaderType_CONFIG),
   315  						}),
   316  					},
   317  				}),
   318  			})
   319  			require.Equal(t, seq, ms.SequenceVal)
   320  			require.NotNil(t, config)
   321  			require.Nil(t, err)
   322  			hdr, err := protoutil.ChannelHeader(config)
   323  			require.NoError(t, err)
   324  			require.Equal(
   325  				t,
   326  				int32(cb.HeaderType_CONFIG),
   327  				hdr.Type,
   328  				"Expect type of returned envelope to be %d, but got %d", cb.HeaderType_CONFIG, hdr.Type)
   329  		})
   330  	})
   331  
   332  	t.Run("OrdererTxMsg", func(t *testing.T) {
   333  		t.Run("BadPayloadData", func(t *testing.T) {
   334  			mscs := &mockSystemChannelSupport{
   335  				NewChannelConfigVal: newMockConfigTXValidator(nil),
   336  			}
   337  			ms := &mockSystemChannelFilterSupport{
   338  				SequenceVal:            7,
   339  				ProposeConfigUpdateVal: &cb.ConfigEnvelope{},
   340  				OrdererConfigVal:       &mocks.OrdererConfig{},
   341  			}
   342  			cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
   343  			require.NoError(t, err)
   344  			_, _, err = NewSystemChannel(ms, mscs, NewRuleSet([]Rule{AcceptRule}), cryptoProvider).ProcessConfigMsg(&cb.Envelope{
   345  				Payload: protoutil.MarshalOrPanic(&cb.Payload{
   346  					Header: &cb.Header{
   347  						ChannelHeader: protoutil.MarshalOrPanic(&cb.ChannelHeader{
   348  							ChannelId: testChannelID,
   349  							Type:      int32(cb.HeaderType_ORDERER_TRANSACTION),
   350  						}),
   351  					},
   352  					Data: []byte("hello"),
   353  				}),
   354  			})
   355  			require.Error(t, err)
   356  		})
   357  
   358  		t.Run("WrongEnvelopeType", func(t *testing.T) {
   359  			mscs := &mockSystemChannelSupport{
   360  				NewChannelConfigVal: newMockConfigTXValidator(nil),
   361  			}
   362  			ms := &mockSystemChannelFilterSupport{
   363  				SequenceVal:            7,
   364  				ProposeConfigUpdateVal: &cb.ConfigEnvelope{},
   365  				OrdererConfigVal:       &mocks.OrdererConfig{},
   366  			}
   367  			cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
   368  			require.NoError(t, err)
   369  			_, _, err = NewSystemChannel(ms, mscs, NewRuleSet([]Rule{AcceptRule}), cryptoProvider).ProcessConfigMsg(&cb.Envelope{
   370  				Payload: protoutil.MarshalOrPanic(&cb.Payload{
   371  					Header: &cb.Header{
   372  						ChannelHeader: protoutil.MarshalOrPanic(&cb.ChannelHeader{
   373  							ChannelId: testChannelID,
   374  							Type:      int32(cb.HeaderType_ORDERER_TRANSACTION),
   375  						}),
   376  					},
   377  					Data: protoutil.MarshalOrPanic(&cb.Envelope{
   378  						Payload: protoutil.MarshalOrPanic(&cb.Payload{
   379  							Header: &cb.Header{
   380  								ChannelHeader: protoutil.MarshalOrPanic(&cb.ChannelHeader{
   381  									ChannelId: testChannelID,
   382  									Type:      int32(cb.HeaderType_MESSAGE),
   383  								}),
   384  							},
   385  						}),
   386  					}),
   387  				}),
   388  			})
   389  			require.Error(t, err)
   390  		})
   391  
   392  		t.Run("GoodConfigMsg", func(t *testing.T) {
   393  			mscs := &mockSystemChannelSupport{
   394  				NewChannelConfigVal: newMockConfigTXValidator(nil),
   395  			}
   396  			ms := &mockSystemChannelFilterSupport{
   397  				SequenceVal:            7,
   398  				ProposeConfigUpdateVal: &cb.ConfigEnvelope{},
   399  				OrdererConfigVal:       &mocks.OrdererConfig{},
   400  			}
   401  			cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
   402  			require.NoError(t, err)
   403  			config, seq, err := NewSystemChannel(ms, mscs, NewRuleSet([]Rule{AcceptRule}), cryptoProvider).ProcessConfigMsg(&cb.Envelope{
   404  				Payload: protoutil.MarshalOrPanic(&cb.Payload{
   405  					Header: &cb.Header{
   406  						ChannelHeader: protoutil.MarshalOrPanic(&cb.ChannelHeader{
   407  							ChannelId: testChannelID,
   408  							Type:      int32(cb.HeaderType_ORDERER_TRANSACTION),
   409  						}),
   410  					},
   411  					Data: protoutil.MarshalOrPanic(&cb.Envelope{
   412  						Payload: protoutil.MarshalOrPanic(&cb.Payload{
   413  							Header: &cb.Header{
   414  								ChannelHeader: protoutil.MarshalOrPanic(&cb.ChannelHeader{
   415  									ChannelId: testChannelID,
   416  									Type:      int32(cb.HeaderType_CONFIG),
   417  								}),
   418  							},
   419  							Data: protoutil.MarshalOrPanic(&cb.ConfigEnvelope{
   420  								LastUpdate: &cb.Envelope{
   421  									Payload: protoutil.MarshalOrPanic(&cb.Payload{
   422  										Header: &cb.Header{
   423  											ChannelHeader: protoutil.MarshalOrPanic(&cb.ChannelHeader{
   424  												ChannelId: testChannelID + "different",
   425  												Type:      int32(cb.HeaderType_CONFIG_UPDATE),
   426  											}),
   427  										},
   428  									}),
   429  								},
   430  							}),
   431  						}),
   432  					}),
   433  				}),
   434  			})
   435  			require.Equal(t, seq, ms.SequenceVal)
   436  			require.NotNil(t, config)
   437  			require.Nil(t, err)
   438  			hdr, err := protoutil.ChannelHeader(config)
   439  			require.NoError(t, err)
   440  			require.Equal(
   441  				t,
   442  				int32(cb.HeaderType_ORDERER_TRANSACTION),
   443  				hdr.Type,
   444  				"Expect type of returned envelope to be %d, but got %d", cb.HeaderType_ORDERER_TRANSACTION, hdr.Type)
   445  		})
   446  	})
   447  
   448  	t.Run("OtherMsgType", func(t *testing.T) {
   449  		mscs := &mockSystemChannelSupport{
   450  			NewChannelConfigVal: newMockConfigTXValidator(nil),
   451  		}
   452  		ms := &mockSystemChannelFilterSupport{
   453  			SequenceVal:            7,
   454  			ProposeConfigUpdateVal: &cb.ConfigEnvelope{},
   455  			OrdererConfigVal:       &mocks.OrdererConfig{},
   456  		}
   457  		cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
   458  		require.NoError(t, err)
   459  		_, _, err = NewSystemChannel(ms, mscs, NewRuleSet([]Rule{AcceptRule}), cryptoProvider).ProcessConfigMsg(&cb.Envelope{
   460  			Payload: protoutil.MarshalOrPanic(&cb.Payload{
   461  				Header: &cb.Header{
   462  					ChannelHeader: protoutil.MarshalOrPanic(&cb.ChannelHeader{
   463  						ChannelId: testChannelID,
   464  						Type:      int32(cb.HeaderType_MESSAGE),
   465  					}),
   466  				},
   467  			}),
   468  		})
   469  		require.Error(t, err)
   470  	})
   471  }
   472  
   473  type mockDefaultTemplatorSupport struct {
   474  	channelconfig.Resources
   475  }
   476  
   477  func (mdts *mockDefaultTemplatorSupport) Signer() identity.SignerSerializer {
   478  	return nil
   479  }
   480  
   481  func TestNewChannelConfig(t *testing.T) {
   482  	channelID := "foo"
   483  	gConf := genesisconfig.Load(genesisconfig.SampleSingleMSPSoloProfile, configtest.GetDevConfigDir())
   484  	gConf.Orderer.Capabilities = map[string]bool{
   485  		capabilities.OrdererV2_0: true,
   486  	}
   487  	channelGroup, err := encoder.NewChannelGroup(gConf)
   488  	require.NoError(t, err)
   489  
   490  	cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
   491  	require.NoError(t, err)
   492  	ctxm, err := channelconfig.NewBundle(channelID, &cb.Config{ChannelGroup: channelGroup}, cryptoProvider)
   493  	require.NoError(t, err)
   494  
   495  	originalCG := proto.Clone(ctxm.ConfigtxValidator().ConfigProto().ChannelGroup).(*cb.ConfigGroup)
   496  
   497  	templator := NewDefaultTemplator(&mockDefaultTemplatorSupport{
   498  		Resources: ctxm,
   499  	}, cryptoProvider)
   500  
   501  	t.Run("BadPayload", func(t *testing.T) {
   502  		_, err := templator.NewChannelConfig(&cb.Envelope{Payload: []byte("bad payload")})
   503  		require.Error(t, err, "Should not be able to create new channel config from bad payload.")
   504  	})
   505  
   506  	for _, tc := range []struct {
   507  		name    string
   508  		payload *cb.Payload
   509  		regex   string
   510  	}{
   511  		{
   512  			"BadPayloadData",
   513  			&cb.Payload{
   514  				Data: []byte("bad payload data"),
   515  			},
   516  			"^Failing initial channel config creation because of config update envelope unmarshalling error:",
   517  		},
   518  		{
   519  			"BadConfigUpdate",
   520  			&cb.Payload{
   521  				Header: &cb.Header{ChannelHeader: protoutil.MarshalOrPanic(protoutil.MakeChannelHeader(cb.HeaderType_CONFIG_UPDATE, 0, "", epoch))},
   522  				Data: protoutil.MarshalOrPanic(&cb.ConfigUpdateEnvelope{
   523  					ConfigUpdate: []byte("bad config update envelope data"),
   524  				}),
   525  			},
   526  			"^Failing initial channel config creation because of config update unmarshalling error:",
   527  		},
   528  		{
   529  			"MismatchedChannelID",
   530  			&cb.Payload{
   531  				Header: &cb.Header{ChannelHeader: protoutil.MarshalOrPanic(protoutil.MakeChannelHeader(cb.HeaderType_CONFIG_UPDATE, 0, "", epoch))},
   532  				Data: protoutil.MarshalOrPanic(&cb.ConfigUpdateEnvelope{
   533  					ConfigUpdate: protoutil.MarshalOrPanic(
   534  						&cb.ConfigUpdate{
   535  							ChannelId: "foo",
   536  						},
   537  					),
   538  				}),
   539  			},
   540  			"mismatched channel IDs",
   541  		},
   542  		{
   543  			"EmptyConfigUpdateWriteSet",
   544  			&cb.Payload{
   545  				Header: &cb.Header{ChannelHeader: protoutil.MarshalOrPanic(protoutil.MakeChannelHeader(cb.HeaderType_CONFIG_UPDATE, 0, "", epoch))},
   546  				Data: protoutil.MarshalOrPanic(&cb.ConfigUpdateEnvelope{
   547  					ConfigUpdate: protoutil.MarshalOrPanic(
   548  						&cb.ConfigUpdate{},
   549  					),
   550  				}),
   551  			},
   552  			"^Config update has an empty writeset$",
   553  		},
   554  		{
   555  			"WriteSetNoGroups",
   556  			&cb.Payload{
   557  				Header: &cb.Header{ChannelHeader: protoutil.MarshalOrPanic(protoutil.MakeChannelHeader(cb.HeaderType_CONFIG_UPDATE, 0, "", epoch))},
   558  				Data: protoutil.MarshalOrPanic(&cb.ConfigUpdateEnvelope{
   559  					ConfigUpdate: protoutil.MarshalOrPanic(
   560  						&cb.ConfigUpdate{
   561  							WriteSet: &cb.ConfigGroup{},
   562  						},
   563  					),
   564  				}),
   565  			},
   566  			"^Config update has missing application group$",
   567  		},
   568  		{
   569  			"WriteSetNoApplicationGroup",
   570  			&cb.Payload{
   571  				Header: &cb.Header{ChannelHeader: protoutil.MarshalOrPanic(protoutil.MakeChannelHeader(cb.HeaderType_CONFIG_UPDATE, 0, "", epoch))},
   572  				Data: protoutil.MarshalOrPanic(&cb.ConfigUpdateEnvelope{
   573  					ConfigUpdate: protoutil.MarshalOrPanic(
   574  						&cb.ConfigUpdate{
   575  							WriteSet: &cb.ConfigGroup{
   576  								Groups: map[string]*cb.ConfigGroup{},
   577  							},
   578  						},
   579  					),
   580  				}),
   581  			},
   582  			"^Config update has missing application group$",
   583  		},
   584  		{
   585  			"BadWriteSetApplicationGroupVersion",
   586  			&cb.Payload{
   587  				Header: &cb.Header{ChannelHeader: protoutil.MarshalOrPanic(protoutil.MakeChannelHeader(cb.HeaderType_CONFIG_UPDATE, 0, "", epoch))},
   588  				Data: protoutil.MarshalOrPanic(&cb.ConfigUpdateEnvelope{
   589  					ConfigUpdate: protoutil.MarshalOrPanic(
   590  						&cb.ConfigUpdate{
   591  							WriteSet: &cb.ConfigGroup{
   592  								Groups: map[string]*cb.ConfigGroup{
   593  									channelconfig.ApplicationGroupKey: {
   594  										Version: 100,
   595  									},
   596  								},
   597  							},
   598  						},
   599  					),
   600  				}),
   601  			},
   602  			"^Config update for channel creation does not set application group version to 1,",
   603  		},
   604  		{
   605  			"MissingWriteSetConsortiumValue",
   606  			&cb.Payload{
   607  				Header: &cb.Header{ChannelHeader: protoutil.MarshalOrPanic(protoutil.MakeChannelHeader(cb.HeaderType_CONFIG_UPDATE, 0, "", epoch))},
   608  				Data: protoutil.MarshalOrPanic(&cb.ConfigUpdateEnvelope{
   609  					ConfigUpdate: protoutil.MarshalOrPanic(
   610  						&cb.ConfigUpdate{
   611  							WriteSet: &cb.ConfigGroup{
   612  								Groups: map[string]*cb.ConfigGroup{
   613  									channelconfig.ApplicationGroupKey: {
   614  										Version: 1,
   615  									},
   616  								},
   617  								Values: map[string]*cb.ConfigValue{},
   618  							},
   619  						},
   620  					),
   621  				}),
   622  			},
   623  			"^Consortium config value missing$",
   624  		},
   625  		{
   626  			"BadWriteSetConsortiumValueValue",
   627  			&cb.Payload{
   628  				Header: &cb.Header{ChannelHeader: protoutil.MarshalOrPanic(protoutil.MakeChannelHeader(cb.HeaderType_CONFIG_UPDATE, 0, "", epoch))},
   629  				Data: protoutil.MarshalOrPanic(&cb.ConfigUpdateEnvelope{
   630  					ConfigUpdate: protoutil.MarshalOrPanic(
   631  						&cb.ConfigUpdate{
   632  							WriteSet: &cb.ConfigGroup{
   633  								Groups: map[string]*cb.ConfigGroup{
   634  									channelconfig.ApplicationGroupKey: {
   635  										Version: 1,
   636  									},
   637  								},
   638  								Values: map[string]*cb.ConfigValue{
   639  									channelconfig.ConsortiumKey: {
   640  										Value: []byte("bad consortium value"),
   641  									},
   642  								},
   643  							},
   644  						},
   645  					),
   646  				}),
   647  			},
   648  			"^Error reading unmarshalling consortium name:",
   649  		},
   650  		{
   651  			"UnknownConsortiumName",
   652  			&cb.Payload{
   653  				Header: &cb.Header{ChannelHeader: protoutil.MarshalOrPanic(protoutil.MakeChannelHeader(cb.HeaderType_CONFIG_UPDATE, 0, "", epoch))},
   654  				Data: protoutil.MarshalOrPanic(&cb.ConfigUpdateEnvelope{
   655  					ConfigUpdate: protoutil.MarshalOrPanic(
   656  						&cb.ConfigUpdate{
   657  							WriteSet: &cb.ConfigGroup{
   658  								Groups: map[string]*cb.ConfigGroup{
   659  									channelconfig.ApplicationGroupKey: {
   660  										Version: 1,
   661  									},
   662  								},
   663  								Values: map[string]*cb.ConfigValue{
   664  									channelconfig.ConsortiumKey: {
   665  										Value: protoutil.MarshalOrPanic(
   666  											&cb.Consortium{
   667  												Name: "NotTheNameYouAreLookingFor",
   668  											},
   669  										),
   670  									},
   671  								},
   672  							},
   673  						},
   674  					),
   675  				}),
   676  			},
   677  			"^Unknown consortium name:",
   678  		},
   679  		{
   680  			"Missing consortium members",
   681  			&cb.Payload{
   682  				Header: &cb.Header{ChannelHeader: protoutil.MarshalOrPanic(protoutil.MakeChannelHeader(cb.HeaderType_CONFIG_UPDATE, 0, "", epoch))},
   683  				Data: protoutil.MarshalOrPanic(&cb.ConfigUpdateEnvelope{
   684  					ConfigUpdate: protoutil.MarshalOrPanic(
   685  						&cb.ConfigUpdate{
   686  							WriteSet: &cb.ConfigGroup{
   687  								Groups: map[string]*cb.ConfigGroup{
   688  									channelconfig.ApplicationGroupKey: {
   689  										Version: 1,
   690  									},
   691  								},
   692  								Values: map[string]*cb.ConfigValue{
   693  									channelconfig.ConsortiumKey: {
   694  										Value: protoutil.MarshalOrPanic(
   695  											&cb.Consortium{
   696  												Name: genesisconfig.SampleConsortiumName,
   697  											},
   698  										),
   699  									},
   700  								},
   701  							},
   702  						},
   703  					),
   704  				}),
   705  			},
   706  			"Proposed configuration has no application group members, but consortium contains members",
   707  		},
   708  		{
   709  			"Member not in consortium",
   710  			&cb.Payload{
   711  				Header: &cb.Header{ChannelHeader: protoutil.MarshalOrPanic(protoutil.MakeChannelHeader(cb.HeaderType_CONFIG_UPDATE, 0, "", epoch))},
   712  				Data: protoutil.MarshalOrPanic(&cb.ConfigUpdateEnvelope{
   713  					ConfigUpdate: protoutil.MarshalOrPanic(
   714  						&cb.ConfigUpdate{
   715  							WriteSet: &cb.ConfigGroup{
   716  								Groups: map[string]*cb.ConfigGroup{
   717  									channelconfig.ApplicationGroupKey: {
   718  										Version: 1,
   719  										Groups: map[string]*cb.ConfigGroup{
   720  											"BadOrgName": {},
   721  										},
   722  									},
   723  								},
   724  								Values: map[string]*cb.ConfigValue{
   725  									channelconfig.ConsortiumKey: {
   726  										Value: protoutil.MarshalOrPanic(
   727  											&cb.Consortium{
   728  												Name: genesisconfig.SampleConsortiumName,
   729  											},
   730  										),
   731  									},
   732  								},
   733  							},
   734  						},
   735  					),
   736  				}),
   737  			},
   738  			"Attempted to include member BadOrgName which is not in the consortium",
   739  		},
   740  	} {
   741  		t.Run(tc.name, func(t *testing.T) {
   742  			_, err := templator.NewChannelConfig(&cb.Envelope{Payload: protoutil.MarshalOrPanic(tc.payload)})
   743  			require.Error(t, err)
   744  			require.Regexp(t, tc.regex, err.Error())
   745  		})
   746  	}
   747  
   748  	// Successful
   749  	t.Run("Success", func(t *testing.T) {
   750  		createTx, err := encoder.MakeChannelCreationTransaction("foo", nil, genesisconfig.Load(genesisconfig.SampleSingleMSPChannelProfile, configtest.GetDevConfigDir()))
   751  		require.Nil(t, err)
   752  		res, err := templator.NewChannelConfig(createTx)
   753  		require.Nil(t, err)
   754  		require.NotEmpty(t, res.ConfigtxValidator().ConfigProto().ChannelGroup.ModPolicy)
   755  		require.True(t, proto.Equal(originalCG, ctxm.ConfigtxValidator().ConfigProto().ChannelGroup), "Underlying system channel config proto was mutated")
   756  	})
   757  
   758  	// Successful new channel config type
   759  	t.Run("SuccessWithNewCreateType", func(t *testing.T) {
   760  		createTx, err := encoder.MakeChannelCreationTransactionWithSystemChannelContext(
   761  			"foo",
   762  			nil,
   763  			genesisconfig.Load(genesisconfig.SampleSingleMSPChannelProfile, configtest.GetDevConfigDir()),
   764  			genesisconfig.Load(genesisconfig.SampleSingleMSPSoloProfile, configtest.GetDevConfigDir()),
   765  		)
   766  		require.Nil(t, err)
   767  		_, err = templator.NewChannelConfig(createTx)
   768  		require.Nil(t, err)
   769  	})
   770  }
   771  
   772  func TestZeroVersions(t *testing.T) {
   773  	data := &cb.ConfigGroup{
   774  		Version: 7,
   775  		Groups: map[string]*cb.ConfigGroup{
   776  			"foo": {
   777  				Version: 6,
   778  			},
   779  			"bar": {
   780  				Values: map[string]*cb.ConfigValue{
   781  					"foo": {
   782  						Version: 3,
   783  					},
   784  				},
   785  				Policies: map[string]*cb.ConfigPolicy{
   786  					"bar": {
   787  						Version: 5,
   788  					},
   789  				},
   790  			},
   791  		},
   792  		Values: map[string]*cb.ConfigValue{
   793  			"foo": {
   794  				Version: 3,
   795  			},
   796  			"bar": {
   797  				Version: 9,
   798  			},
   799  		},
   800  		Policies: map[string]*cb.ConfigPolicy{
   801  			"foo": {
   802  				Version: 4,
   803  			},
   804  			"bar": {
   805  				Version: 5,
   806  			},
   807  		},
   808  	}
   809  
   810  	expected := &cb.ConfigGroup{
   811  		Groups: map[string]*cb.ConfigGroup{
   812  			"foo": {},
   813  			"bar": {
   814  				Values: map[string]*cb.ConfigValue{
   815  					"foo": {},
   816  				},
   817  				Policies: map[string]*cb.ConfigPolicy{
   818  					"bar": {},
   819  				},
   820  			},
   821  		},
   822  		Values: map[string]*cb.ConfigValue{
   823  			"foo": {},
   824  			"bar": {},
   825  		},
   826  		Policies: map[string]*cb.ConfigPolicy{
   827  			"foo": {},
   828  			"bar": {},
   829  		},
   830  	}
   831  
   832  	zeroVersions(data)
   833  
   834  	require.True(t, proto.Equal(expected, data))
   835  }