github.com/anjalikarhana/fabric@v2.1.1+incompatible/orderer/common/msgprocessor/systemchannel_test.go (about)

     1  /*
     2  Copyright IBM Corp. 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  	cb "github.com/hyperledger/fabric-protos-go/common"
    15  	"github.com/hyperledger/fabric-protos-go/orderer"
    16  	"github.com/hyperledger/fabric/bccsp/sw"
    17  	"github.com/hyperledger/fabric/common/capabilities"
    18  	"github.com/hyperledger/fabric/common/channelconfig"
    19  	"github.com/hyperledger/fabric/core/config/configtest"
    20  	"github.com/hyperledger/fabric/internal/configtxgen/encoder"
    21  	"github.com/hyperledger/fabric/internal/configtxgen/genesisconfig"
    22  	"github.com/hyperledger/fabric/internal/pkg/identity"
    23  	"github.com/hyperledger/fabric/orderer/common/msgprocessor/mocks"
    24  	"github.com/hyperledger/fabric/protoutil"
    25  	"github.com/pkg/errors"
    26  	"github.com/stretchr/testify/assert"
    27  	"github.com/stretchr/testify/require"
    28  )
    29  
    30  type mockSystemChannelSupport struct {
    31  	NewChannelConfigVal *mocks.ConfigTXValidator
    32  	NewChannelConfigErr error
    33  }
    34  
    35  func newMockConfigTXValidator(err error) *mocks.ConfigTXValidator {
    36  	mockValidator := &mocks.ConfigTXValidator{}
    37  	mockValidator.ProposeConfigUpdateReturns(&cb.ConfigEnvelope{}, err)
    38  	return mockValidator
    39  }
    40  
    41  func (mscs *mockSystemChannelSupport) NewChannelConfig(env *cb.Envelope) (channelconfig.Resources, error) {
    42  	mockResources := &mocks.Resources{}
    43  	mockResources.ConfigtxValidatorReturns(mscs.NewChannelConfigVal)
    44  	return mockResources, mscs.NewChannelConfigErr
    45  }
    46  
    47  func TestProcessSystemChannelNormalMsg(t *testing.T) {
    48  	t.Run("Missing header", func(t *testing.T) {
    49  		mscs := &mockSystemChannelSupport{}
    50  		ms := &mockSystemChannelFilterSupport{
    51  			OrdererConfigVal: &mocks.OrdererConfig{},
    52  		}
    53  		cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
    54  		assert.NoError(t, err)
    55  		_, err = NewSystemChannel(ms, mscs, nil, cryptoProvider).ProcessNormalMsg(&cb.Envelope{})
    56  		assert.NotNil(t, err)
    57  		assert.Regexp(t, "header not set", err.Error())
    58  	})
    59  	t.Run("Mismatched channel ID", func(t *testing.T) {
    60  		mscs := &mockSystemChannelSupport{}
    61  		ms := &mockSystemChannelFilterSupport{
    62  			OrdererConfigVal: &mocks.OrdererConfig{},
    63  		}
    64  		cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
    65  		assert.NoError(t, err)
    66  		_, err = NewSystemChannel(ms, mscs, nil, cryptoProvider).ProcessNormalMsg(&cb.Envelope{
    67  			Payload: protoutil.MarshalOrPanic(&cb.Payload{
    68  				Header: &cb.Header{
    69  					ChannelHeader: protoutil.MarshalOrPanic(&cb.ChannelHeader{
    70  						ChannelId: testChannelID + ".different",
    71  					}),
    72  				},
    73  			}),
    74  		})
    75  		assert.Equal(t, ErrChannelDoesNotExist, err)
    76  	})
    77  	t.Run("Good", func(t *testing.T) {
    78  		mscs := &mockSystemChannelSupport{}
    79  		ms := &mockSystemChannelFilterSupport{
    80  			SequenceVal:      7,
    81  			OrdererConfigVal: newMockOrdererConfig(true, orderer.ConsensusType_STATE_NORMAL),
    82  		}
    83  		cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
    84  		assert.NoError(t, err)
    85  		cs, err := NewSystemChannel(ms, mscs, NewRuleSet([]Rule{AcceptRule}), cryptoProvider).ProcessNormalMsg(&cb.Envelope{
    86  			Payload: protoutil.MarshalOrPanic(&cb.Payload{
    87  				Header: &cb.Header{
    88  					ChannelHeader: protoutil.MarshalOrPanic(&cb.ChannelHeader{
    89  						ChannelId: testChannelID,
    90  					}),
    91  				},
    92  			}),
    93  		})
    94  		assert.Nil(t, err)
    95  		assert.Equal(t, ms.SequenceVal, cs)
    96  
    97  	})
    98  }
    99  
   100  func TestSystemChannelConfigUpdateMsg(t *testing.T) {
   101  	t.Run("Missing header", func(t *testing.T) {
   102  		mscs := &mockSystemChannelSupport{}
   103  		ms := &mockSystemChannelFilterSupport{
   104  			OrdererConfigVal: &mocks.OrdererConfig{},
   105  		}
   106  		cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
   107  		assert.NoError(t, err)
   108  		_, _, err = NewSystemChannel(ms, mscs, NewRuleSet([]Rule{AcceptRule}), cryptoProvider).ProcessConfigUpdateMsg(&cb.Envelope{})
   109  		assert.NotNil(t, err)
   110  		assert.Regexp(t, "header not set", err.Error())
   111  	})
   112  	t.Run("NormalUpdate", func(t *testing.T) {
   113  		mscs := &mockSystemChannelSupport{}
   114  		ms := &mockSystemChannelFilterSupport{
   115  			SequenceVal:            7,
   116  			ProposeConfigUpdateVal: &cb.ConfigEnvelope{},
   117  			OrdererConfigVal:       newMockOrdererConfig(true, orderer.ConsensusType_STATE_NORMAL),
   118  		}
   119  		cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
   120  		assert.NoError(t, err)
   121  		sysChan := NewSystemChannel(ms, mscs, NewRuleSet([]Rule{AcceptRule}), cryptoProvider)
   122  		sysChan.maintenanceFilter = AcceptRule
   123  		config, cs, err := sysChan.ProcessConfigUpdateMsg(&cb.Envelope{
   124  			Payload: protoutil.MarshalOrPanic(&cb.Payload{
   125  				Header: &cb.Header{
   126  					ChannelHeader: protoutil.MarshalOrPanic(&cb.ChannelHeader{
   127  						ChannelId: testChannelID,
   128  					}),
   129  				},
   130  			}),
   131  		})
   132  		assert.NotNil(t, config)
   133  		assert.Equal(t, cs, ms.SequenceVal)
   134  		assert.Nil(t, err)
   135  	})
   136  	t.Run("BadNewChannelConfig", func(t *testing.T) {
   137  		mscs := &mockSystemChannelSupport{
   138  			NewChannelConfigErr: fmt.Errorf("An error"),
   139  		}
   140  		ms := &mockSystemChannelFilterSupport{
   141  			ProposeConfigUpdateVal: &cb.ConfigEnvelope{},
   142  			OrdererConfigVal:       &mocks.OrdererConfig{},
   143  		}
   144  		cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
   145  		assert.NoError(t, err)
   146  		_, _, err = NewSystemChannel(ms, mscs, NewRuleSet([]Rule{AcceptRule}), cryptoProvider).ProcessConfigUpdateMsg(&cb.Envelope{
   147  			Payload: protoutil.MarshalOrPanic(&cb.Payload{
   148  				Header: &cb.Header{
   149  					ChannelHeader: protoutil.MarshalOrPanic(&cb.ChannelHeader{
   150  						ChannelId: testChannelID + "different",
   151  					}),
   152  				},
   153  			}),
   154  		})
   155  		assert.Equal(t, mscs.NewChannelConfigErr, err)
   156  	})
   157  	t.Run("BadProposedUpdate", func(t *testing.T) {
   158  		mscs := &mockSystemChannelSupport{
   159  			NewChannelConfigVal: newMockConfigTXValidator(fmt.Errorf("An error")),
   160  		}
   161  		ms := &mockSystemChannelFilterSupport{
   162  			ProposeConfigUpdateVal: &cb.ConfigEnvelope{},
   163  			OrdererConfigVal:       &mocks.OrdererConfig{},
   164  		}
   165  		cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
   166  		assert.NoError(t, err)
   167  		_, _, err = NewSystemChannel(ms, mscs, NewRuleSet([]Rule{AcceptRule}), cryptoProvider).ProcessConfigUpdateMsg(&cb.Envelope{
   168  			Payload: protoutil.MarshalOrPanic(&cb.Payload{
   169  				Header: &cb.Header{
   170  					ChannelHeader: protoutil.MarshalOrPanic(&cb.ChannelHeader{
   171  						ChannelId: testChannelID + "different",
   172  					}),
   173  				},
   174  			}),
   175  		})
   176  		assert.EqualError(t, err, "error validating channel creation transaction for new channel 'foodifferent', could not successfully apply update to template configuration: An error")
   177  	})
   178  	t.Run("BadSignEnvelope", func(t *testing.T) {
   179  		mscs := &mockSystemChannelSupport{
   180  			NewChannelConfigVal: &mocks.ConfigTXValidator{},
   181  		}
   182  		ms := &mockSystemChannelFilterSupport{
   183  			ProposeConfigUpdateVal: &cb.ConfigEnvelope{},
   184  			OrdererConfigVal:       &mocks.OrdererConfig{},
   185  		}
   186  		cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
   187  		assert.NoError(t, err)
   188  		_, _, err = NewSystemChannel(ms, mscs, NewRuleSet([]Rule{AcceptRule}), cryptoProvider).ProcessConfigUpdateMsg(&cb.Envelope{
   189  			Payload: protoutil.MarshalOrPanic(&cb.Payload{
   190  				Header: &cb.Header{
   191  					ChannelHeader: protoutil.MarshalOrPanic(&cb.ChannelHeader{
   192  						ChannelId: testChannelID + "different",
   193  					}),
   194  				},
   195  			}),
   196  		})
   197  		assert.Regexp(t, "Marshal called with nil", err)
   198  	})
   199  	t.Run("BadByFilter", func(t *testing.T) {
   200  		mscs := &mockSystemChannelSupport{
   201  			NewChannelConfigVal: newMockConfigTXValidator(nil),
   202  		}
   203  		ms := &mockSystemChannelFilterSupport{
   204  			SequenceVal:            7,
   205  			ProposeConfigUpdateVal: &cb.ConfigEnvelope{},
   206  			OrdererConfigVal:       &mocks.OrdererConfig{},
   207  		}
   208  		cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
   209  		assert.NoError(t, err)
   210  		_, _, err = NewSystemChannel(ms, mscs, NewRuleSet([]Rule{RejectRule}), cryptoProvider).ProcessConfigUpdateMsg(&cb.Envelope{
   211  			Payload: protoutil.MarshalOrPanic(&cb.Payload{
   212  				Header: &cb.Header{
   213  					ChannelHeader: protoutil.MarshalOrPanic(&cb.ChannelHeader{
   214  						ChannelId: testChannelID + "different",
   215  					}),
   216  				},
   217  			}),
   218  		})
   219  		assert.Equal(t, RejectRule.Apply(nil), err)
   220  	})
   221  	t.Run("RejectByMaintenance", func(t *testing.T) {
   222  		mscs := &mockSystemChannelSupport{
   223  			NewChannelConfigVal: newMockConfigTXValidator(nil),
   224  		}
   225  		ms := &mockSystemChannelFilterSupport{
   226  			SequenceVal:            7,
   227  			ProposeConfigUpdateVal: &cb.ConfigEnvelope{},
   228  			OrdererConfigVal:       &mocks.OrdererConfig{},
   229  		}
   230  		cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
   231  		assert.NoError(t, err)
   232  		sysChan := NewSystemChannel(ms, mscs, NewRuleSet([]Rule{AcceptRule}), cryptoProvider)
   233  		sysChan.maintenanceFilter = RejectRule
   234  		_, _, err = sysChan.ProcessConfigUpdateMsg(&cb.Envelope{
   235  			Payload: protoutil.MarshalOrPanic(&cb.Payload{
   236  				Header: &cb.Header{
   237  					ChannelHeader: protoutil.MarshalOrPanic(&cb.ChannelHeader{
   238  						ChannelId: testChannelID,
   239  					}),
   240  				},
   241  			}),
   242  		})
   243  		assert.Equal(t, RejectRule.Apply(nil), errors.Cause(err))
   244  	})
   245  	t.Run("Good", func(t *testing.T) {
   246  		mscs := &mockSystemChannelSupport{
   247  			NewChannelConfigVal: newMockConfigTXValidator(nil),
   248  		}
   249  		ms := &mockSystemChannelFilterSupport{
   250  			SequenceVal:            7,
   251  			ProposeConfigUpdateVal: &cb.ConfigEnvelope{},
   252  			OrdererConfigVal:       &mocks.OrdererConfig{},
   253  		}
   254  		cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
   255  		assert.NoError(t, err)
   256  		config, cs, err := NewSystemChannel(ms, mscs, NewRuleSet([]Rule{AcceptRule}), cryptoProvider).ProcessConfigUpdateMsg(&cb.Envelope{
   257  			Payload: protoutil.MarshalOrPanic(&cb.Payload{
   258  				Header: &cb.Header{
   259  					ChannelHeader: protoutil.MarshalOrPanic(&cb.ChannelHeader{
   260  						ChannelId: testChannelID + "different",
   261  					}),
   262  				},
   263  			}),
   264  		})
   265  		assert.Equal(t, cs, ms.SequenceVal)
   266  		assert.NotNil(t, config)
   267  		assert.Nil(t, err)
   268  	})
   269  }
   270  
   271  func TestSystemChannelConfigMsg(t *testing.T) {
   272  	t.Run("ConfigMsg", func(t *testing.T) {
   273  		t.Run("BadPayloadData", func(t *testing.T) {
   274  			mscs := &mockSystemChannelSupport{
   275  				NewChannelConfigVal: newMockConfigTXValidator(nil),
   276  			}
   277  			ms := &mockSystemChannelFilterSupport{
   278  				SequenceVal:            7,
   279  				ProposeConfigUpdateVal: &cb.ConfigEnvelope{},
   280  				OrdererConfigVal:       &mocks.OrdererConfig{},
   281  			}
   282  			cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
   283  			assert.NoError(t, err)
   284  			_, _, err = NewSystemChannel(ms, mscs, NewRuleSet([]Rule{AcceptRule}), cryptoProvider).ProcessConfigMsg(&cb.Envelope{
   285  				Payload: protoutil.MarshalOrPanic(&cb.Payload{
   286  					Header: &cb.Header{
   287  						ChannelHeader: protoutil.MarshalOrPanic(&cb.ChannelHeader{
   288  							ChannelId: testChannelID,
   289  							Type:      int32(cb.HeaderType_CONFIG),
   290  						}),
   291  					},
   292  					Data: []byte("hello"),
   293  				}),
   294  			})
   295  			assert.Error(t, err)
   296  		})
   297  
   298  		t.Run("Good", func(t *testing.T) {
   299  			mscs := &mockSystemChannelSupport{
   300  				NewChannelConfigVal: newMockConfigTXValidator(nil),
   301  			}
   302  			ms := &mockSystemChannelFilterSupport{
   303  				SequenceVal:            7,
   304  				ProposeConfigUpdateVal: &cb.ConfigEnvelope{},
   305  				OrdererConfigVal:       newMockOrdererConfig(false, orderer.ConsensusType_STATE_NORMAL),
   306  			}
   307  			cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
   308  			assert.NoError(t, err)
   309  			sysChan := NewSystemChannel(ms, mscs, NewRuleSet([]Rule{AcceptRule}), cryptoProvider)
   310  			sysChan.maintenanceFilter = AcceptRule
   311  			config, seq, err := sysChan.ProcessConfigMsg(&cb.Envelope{
   312  				Payload: protoutil.MarshalOrPanic(&cb.Payload{
   313  					Header: &cb.Header{
   314  						ChannelHeader: protoutil.MarshalOrPanic(&cb.ChannelHeader{
   315  							ChannelId: testChannelID,
   316  							Type:      int32(cb.HeaderType_CONFIG),
   317  						}),
   318  					},
   319  				}),
   320  			})
   321  			assert.Equal(t, seq, ms.SequenceVal)
   322  			assert.NotNil(t, config)
   323  			assert.Nil(t, err)
   324  			hdr, err := protoutil.ChannelHeader(config)
   325  			require.NoError(t, err)
   326  			assert.Equal(
   327  				t,
   328  				int32(cb.HeaderType_CONFIG),
   329  				hdr.Type,
   330  				"Expect type of returned envelope to be %d, but got %d", cb.HeaderType_CONFIG, hdr.Type)
   331  		})
   332  	})
   333  
   334  	t.Run("OrdererTxMsg", func(t *testing.T) {
   335  		t.Run("BadPayloadData", func(t *testing.T) {
   336  			mscs := &mockSystemChannelSupport{
   337  				NewChannelConfigVal: newMockConfigTXValidator(nil),
   338  			}
   339  			ms := &mockSystemChannelFilterSupport{
   340  				SequenceVal:            7,
   341  				ProposeConfigUpdateVal: &cb.ConfigEnvelope{},
   342  				OrdererConfigVal:       &mocks.OrdererConfig{},
   343  			}
   344  			cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
   345  			assert.NoError(t, err)
   346  			_, _, err = NewSystemChannel(ms, mscs, NewRuleSet([]Rule{AcceptRule}), cryptoProvider).ProcessConfigMsg(&cb.Envelope{
   347  				Payload: protoutil.MarshalOrPanic(&cb.Payload{
   348  					Header: &cb.Header{
   349  						ChannelHeader: protoutil.MarshalOrPanic(&cb.ChannelHeader{
   350  							ChannelId: testChannelID,
   351  							Type:      int32(cb.HeaderType_ORDERER_TRANSACTION),
   352  						}),
   353  					},
   354  					Data: []byte("hello"),
   355  				}),
   356  			})
   357  			assert.Error(t, err)
   358  		})
   359  
   360  		t.Run("WrongEnvelopeType", func(t *testing.T) {
   361  			mscs := &mockSystemChannelSupport{
   362  				NewChannelConfigVal: newMockConfigTXValidator(nil),
   363  			}
   364  			ms := &mockSystemChannelFilterSupport{
   365  				SequenceVal:            7,
   366  				ProposeConfigUpdateVal: &cb.ConfigEnvelope{},
   367  				OrdererConfigVal:       &mocks.OrdererConfig{},
   368  			}
   369  			cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
   370  			assert.NoError(t, err)
   371  			_, _, err = NewSystemChannel(ms, mscs, NewRuleSet([]Rule{AcceptRule}), cryptoProvider).ProcessConfigMsg(&cb.Envelope{
   372  				Payload: protoutil.MarshalOrPanic(&cb.Payload{
   373  					Header: &cb.Header{
   374  						ChannelHeader: protoutil.MarshalOrPanic(&cb.ChannelHeader{
   375  							ChannelId: testChannelID,
   376  							Type:      int32(cb.HeaderType_ORDERER_TRANSACTION),
   377  						}),
   378  					},
   379  					Data: protoutil.MarshalOrPanic(&cb.Envelope{
   380  						Payload: protoutil.MarshalOrPanic(&cb.Payload{
   381  							Header: &cb.Header{
   382  								ChannelHeader: protoutil.MarshalOrPanic(&cb.ChannelHeader{
   383  									ChannelId: testChannelID,
   384  									Type:      int32(cb.HeaderType_MESSAGE),
   385  								}),
   386  							},
   387  						}),
   388  					}),
   389  				}),
   390  			})
   391  			assert.Error(t, err)
   392  		})
   393  
   394  		t.Run("GoodConfigMsg", func(t *testing.T) {
   395  			mscs := &mockSystemChannelSupport{
   396  				NewChannelConfigVal: newMockConfigTXValidator(nil),
   397  			}
   398  			ms := &mockSystemChannelFilterSupport{
   399  				SequenceVal:            7,
   400  				ProposeConfigUpdateVal: &cb.ConfigEnvelope{},
   401  				OrdererConfigVal:       &mocks.OrdererConfig{},
   402  			}
   403  			cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
   404  			assert.NoError(t, err)
   405  			config, seq, err := NewSystemChannel(ms, mscs, NewRuleSet([]Rule{AcceptRule}), cryptoProvider).ProcessConfigMsg(&cb.Envelope{
   406  				Payload: protoutil.MarshalOrPanic(&cb.Payload{
   407  					Header: &cb.Header{
   408  						ChannelHeader: protoutil.MarshalOrPanic(&cb.ChannelHeader{
   409  							ChannelId: testChannelID,
   410  							Type:      int32(cb.HeaderType_ORDERER_TRANSACTION),
   411  						}),
   412  					},
   413  					Data: protoutil.MarshalOrPanic(&cb.Envelope{
   414  						Payload: protoutil.MarshalOrPanic(&cb.Payload{
   415  							Header: &cb.Header{
   416  								ChannelHeader: protoutil.MarshalOrPanic(&cb.ChannelHeader{
   417  									ChannelId: testChannelID,
   418  									Type:      int32(cb.HeaderType_CONFIG),
   419  								}),
   420  							},
   421  							Data: protoutil.MarshalOrPanic(&cb.ConfigEnvelope{
   422  								LastUpdate: &cb.Envelope{
   423  									Payload: protoutil.MarshalOrPanic(&cb.Payload{
   424  										Header: &cb.Header{
   425  											ChannelHeader: protoutil.MarshalOrPanic(&cb.ChannelHeader{
   426  												ChannelId: testChannelID + "different",
   427  												Type:      int32(cb.HeaderType_CONFIG_UPDATE),
   428  											}),
   429  										},
   430  									}),
   431  								},
   432  							}),
   433  						}),
   434  					}),
   435  				}),
   436  			})
   437  			assert.Equal(t, seq, ms.SequenceVal)
   438  			assert.NotNil(t, config)
   439  			assert.Nil(t, err)
   440  			hdr, err := protoutil.ChannelHeader(config)
   441  			assert.Equal(
   442  				t,
   443  				int32(cb.HeaderType_ORDERER_TRANSACTION),
   444  				hdr.Type,
   445  				"Expect type of returned envelope to be %d, but got %d", cb.HeaderType_ORDERER_TRANSACTION, hdr.Type)
   446  		})
   447  	})
   448  
   449  	t.Run("OtherMsgType", func(t *testing.T) {
   450  		mscs := &mockSystemChannelSupport{
   451  			NewChannelConfigVal: newMockConfigTXValidator(nil),
   452  		}
   453  		ms := &mockSystemChannelFilterSupport{
   454  			SequenceVal:            7,
   455  			ProposeConfigUpdateVal: &cb.ConfigEnvelope{},
   456  			OrdererConfigVal:       &mocks.OrdererConfig{},
   457  		}
   458  		cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
   459  		assert.NoError(t, err)
   460  		_, _, err = NewSystemChannel(ms, mscs, NewRuleSet([]Rule{AcceptRule}), cryptoProvider).ProcessConfigMsg(&cb.Envelope{
   461  			Payload: protoutil.MarshalOrPanic(&cb.Payload{
   462  				Header: &cb.Header{
   463  					ChannelHeader: protoutil.MarshalOrPanic(&cb.ChannelHeader{
   464  						ChannelId: testChannelID,
   465  						Type:      int32(cb.HeaderType_MESSAGE),
   466  					}),
   467  				},
   468  			}),
   469  		})
   470  		assert.Error(t, err)
   471  	})
   472  }
   473  
   474  type mockDefaultTemplatorSupport struct {
   475  	channelconfig.Resources
   476  }
   477  
   478  func (mdts *mockDefaultTemplatorSupport) Signer() identity.SignerSerializer {
   479  	return nil
   480  }
   481  
   482  func TestNewChannelConfig(t *testing.T) {
   483  	channelID := "foo"
   484  	gConf := genesisconfig.Load(genesisconfig.SampleSingleMSPSoloProfile, configtest.GetDevConfigDir())
   485  	gConf.Orderer.Capabilities = map[string]bool{
   486  		capabilities.OrdererV2_0: true,
   487  	}
   488  	channelGroup, err := encoder.NewChannelGroup(gConf)
   489  	assert.NoError(t, err)
   490  
   491  	cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
   492  	assert.NoError(t, err)
   493  	ctxm, err := channelconfig.NewBundle(channelID, &cb.Config{ChannelGroup: channelGroup}, cryptoProvider)
   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  		assert.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 unmarshaling 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 unmarshaling 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 unmarshaling 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 a member 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  			if assert.Error(t, err) {
   744  				assert.Regexp(t, tc.regex, err.Error())
   745  			}
   746  		})
   747  	}
   748  
   749  	// Successful
   750  	t.Run("Success", func(t *testing.T) {
   751  		createTx, err := encoder.MakeChannelCreationTransaction("foo", nil, genesisconfig.Load(genesisconfig.SampleSingleMSPChannelProfile, configtest.GetDevConfigDir()))
   752  		assert.Nil(t, err)
   753  		res, err := templator.NewChannelConfig(createTx)
   754  		assert.Nil(t, err)
   755  		assert.NotEmpty(t, res.ConfigtxValidator().ConfigProto().ChannelGroup.ModPolicy)
   756  		assert.True(t, proto.Equal(originalCG, ctxm.ConfigtxValidator().ConfigProto().ChannelGroup), "Underlying system channel config proto was mutated")
   757  	})
   758  
   759  	// Successful new channel config type
   760  	t.Run("SuccessWithNewCreateType", func(t *testing.T) {
   761  		createTx, err := encoder.MakeChannelCreationTransactionWithSystemChannelContext(
   762  			"foo",
   763  			nil,
   764  			genesisconfig.Load(genesisconfig.SampleSingleMSPChannelProfile, configtest.GetDevConfigDir()),
   765  			genesisconfig.Load(genesisconfig.SampleSingleMSPSoloProfile, configtest.GetDevConfigDir()),
   766  		)
   767  		assert.Nil(t, err)
   768  		_, err = templator.NewChannelConfig(createTx)
   769  		assert.Nil(t, err)
   770  	})
   771  }
   772  
   773  func TestZeroVersions(t *testing.T) {
   774  	data := &cb.ConfigGroup{
   775  		Version: 7,
   776  		Groups: map[string]*cb.ConfigGroup{
   777  			"foo": {
   778  				Version: 6,
   779  			},
   780  			"bar": {
   781  				Values: map[string]*cb.ConfigValue{
   782  					"foo": {
   783  						Version: 3,
   784  					},
   785  				},
   786  				Policies: map[string]*cb.ConfigPolicy{
   787  					"bar": {
   788  						Version: 5,
   789  					},
   790  				},
   791  			},
   792  		},
   793  		Values: map[string]*cb.ConfigValue{
   794  			"foo": {
   795  				Version: 3,
   796  			},
   797  			"bar": {
   798  				Version: 9,
   799  			},
   800  		},
   801  		Policies: map[string]*cb.ConfigPolicy{
   802  			"foo": {
   803  				Version: 4,
   804  			},
   805  			"bar": {
   806  				Version: 5,
   807  			},
   808  		},
   809  	}
   810  
   811  	expected := &cb.ConfigGroup{
   812  		Groups: map[string]*cb.ConfigGroup{
   813  			"foo": {},
   814  			"bar": {
   815  				Values: map[string]*cb.ConfigValue{
   816  					"foo": {},
   817  				},
   818  				Policies: map[string]*cb.ConfigPolicy{
   819  					"bar": {},
   820  				},
   821  			},
   822  		},
   823  		Values: map[string]*cb.ConfigValue{
   824  			"foo": {},
   825  			"bar": {},
   826  		},
   827  		Policies: map[string]*cb.ConfigPolicy{
   828  			"foo": {},
   829  			"bar": {},
   830  		},
   831  	}
   832  
   833  	zeroVersions(data)
   834  
   835  	assert.True(t, proto.Equal(expected, data))
   836  }