github.com/osdi23p228/fabric@v0.0.0-20221218062954-77808885f5db/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/osdi23p228/fabric/bccsp/sw"
    17  	"github.com/osdi23p228/fabric/common/capabilities"
    18  	"github.com/osdi23p228/fabric/common/channelconfig"
    19  	"github.com/osdi23p228/fabric/core/config/configtest"
    20  	"github.com/osdi23p228/fabric/internal/configtxgen/encoder"
    21  	"github.com/osdi23p228/fabric/internal/configtxgen/genesisconfig"
    22  	"github.com/osdi23p228/fabric/internal/pkg/identity"
    23  	"github.com/osdi23p228/fabric/orderer/common/msgprocessor/mocks"
    24  	"github.com/osdi23p228/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.NoError(t, err)
   442  			assert.Equal(
   443  				t,
   444  				int32(cb.HeaderType_ORDERER_TRANSACTION),
   445  				hdr.Type,
   446  				"Expect type of returned envelope to be %d, but got %d", cb.HeaderType_ORDERER_TRANSACTION, hdr.Type)
   447  		})
   448  	})
   449  
   450  	t.Run("OtherMsgType", func(t *testing.T) {
   451  		mscs := &mockSystemChannelSupport{
   452  			NewChannelConfigVal: newMockConfigTXValidator(nil),
   453  		}
   454  		ms := &mockSystemChannelFilterSupport{
   455  			SequenceVal:            7,
   456  			ProposeConfigUpdateVal: &cb.ConfigEnvelope{},
   457  			OrdererConfigVal:       &mocks.OrdererConfig{},
   458  		}
   459  		cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
   460  		assert.NoError(t, err)
   461  		_, _, err = NewSystemChannel(ms, mscs, NewRuleSet([]Rule{AcceptRule}), cryptoProvider).ProcessConfigMsg(&cb.Envelope{
   462  			Payload: protoutil.MarshalOrPanic(&cb.Payload{
   463  				Header: &cb.Header{
   464  					ChannelHeader: protoutil.MarshalOrPanic(&cb.ChannelHeader{
   465  						ChannelId: testChannelID,
   466  						Type:      int32(cb.HeaderType_MESSAGE),
   467  					}),
   468  				},
   469  			}),
   470  		})
   471  		assert.Error(t, err)
   472  	})
   473  }
   474  
   475  type mockDefaultTemplatorSupport struct {
   476  	channelconfig.Resources
   477  }
   478  
   479  func (mdts *mockDefaultTemplatorSupport) Signer() identity.SignerSerializer {
   480  	return nil
   481  }
   482  
   483  func TestNewChannelConfig(t *testing.T) {
   484  	channelID := "foo"
   485  	gConf := genesisconfig.Load(genesisconfig.SampleSingleMSPSoloProfile, configtest.GetDevConfigDir())
   486  	gConf.Orderer.Capabilities = map[string]bool{
   487  		capabilities.OrdererV2_0: true,
   488  	}
   489  	channelGroup, err := encoder.NewChannelGroup(gConf)
   490  	assert.NoError(t, err)
   491  
   492  	cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
   493  	assert.NoError(t, err)
   494  	ctxm, err := channelconfig.NewBundle(channelID, &cb.Config{ChannelGroup: channelGroup}, cryptoProvider)
   495  	assert.NoError(t, err)
   496  
   497  	originalCG := proto.Clone(ctxm.ConfigtxValidator().ConfigProto().ChannelGroup).(*cb.ConfigGroup)
   498  
   499  	templator := NewDefaultTemplator(&mockDefaultTemplatorSupport{
   500  		Resources: ctxm,
   501  	}, cryptoProvider)
   502  
   503  	t.Run("BadPayload", func(t *testing.T) {
   504  		_, err := templator.NewChannelConfig(&cb.Envelope{Payload: []byte("bad payload")})
   505  		assert.Error(t, err, "Should not be able to create new channel config from bad payload.")
   506  	})
   507  
   508  	for _, tc := range []struct {
   509  		name    string
   510  		payload *cb.Payload
   511  		regex   string
   512  	}{
   513  		{
   514  			"BadPayloadData",
   515  			&cb.Payload{
   516  				Data: []byte("bad payload data"),
   517  			},
   518  			"^Failing initial channel config creation because of config update envelope unmarshaling error:",
   519  		},
   520  		{
   521  			"BadConfigUpdate",
   522  			&cb.Payload{
   523  				Header: &cb.Header{ChannelHeader: protoutil.MarshalOrPanic(protoutil.MakeChannelHeader(cb.HeaderType_CONFIG_UPDATE, 0, "", epoch))},
   524  				Data: protoutil.MarshalOrPanic(&cb.ConfigUpdateEnvelope{
   525  					ConfigUpdate: []byte("bad config update envelope data"),
   526  				}),
   527  			},
   528  			"^Failing initial channel config creation because of config update unmarshaling error:",
   529  		},
   530  		{
   531  			"MismatchedChannelID",
   532  			&cb.Payload{
   533  				Header: &cb.Header{ChannelHeader: protoutil.MarshalOrPanic(protoutil.MakeChannelHeader(cb.HeaderType_CONFIG_UPDATE, 0, "", epoch))},
   534  				Data: protoutil.MarshalOrPanic(&cb.ConfigUpdateEnvelope{
   535  					ConfigUpdate: protoutil.MarshalOrPanic(
   536  						&cb.ConfigUpdate{
   537  							ChannelId: "foo",
   538  						},
   539  					),
   540  				}),
   541  			},
   542  			"mismatched channel IDs",
   543  		},
   544  		{
   545  			"EmptyConfigUpdateWriteSet",
   546  			&cb.Payload{
   547  				Header: &cb.Header{ChannelHeader: protoutil.MarshalOrPanic(protoutil.MakeChannelHeader(cb.HeaderType_CONFIG_UPDATE, 0, "", epoch))},
   548  				Data: protoutil.MarshalOrPanic(&cb.ConfigUpdateEnvelope{
   549  					ConfigUpdate: protoutil.MarshalOrPanic(
   550  						&cb.ConfigUpdate{},
   551  					),
   552  				}),
   553  			},
   554  			"^Config update has an empty writeset$",
   555  		},
   556  		{
   557  			"WriteSetNoGroups",
   558  			&cb.Payload{
   559  				Header: &cb.Header{ChannelHeader: protoutil.MarshalOrPanic(protoutil.MakeChannelHeader(cb.HeaderType_CONFIG_UPDATE, 0, "", epoch))},
   560  				Data: protoutil.MarshalOrPanic(&cb.ConfigUpdateEnvelope{
   561  					ConfigUpdate: protoutil.MarshalOrPanic(
   562  						&cb.ConfigUpdate{
   563  							WriteSet: &cb.ConfigGroup{},
   564  						},
   565  					),
   566  				}),
   567  			},
   568  			"^Config update has missing application group$",
   569  		},
   570  		{
   571  			"WriteSetNoApplicationGroup",
   572  			&cb.Payload{
   573  				Header: &cb.Header{ChannelHeader: protoutil.MarshalOrPanic(protoutil.MakeChannelHeader(cb.HeaderType_CONFIG_UPDATE, 0, "", epoch))},
   574  				Data: protoutil.MarshalOrPanic(&cb.ConfigUpdateEnvelope{
   575  					ConfigUpdate: protoutil.MarshalOrPanic(
   576  						&cb.ConfigUpdate{
   577  							WriteSet: &cb.ConfigGroup{
   578  								Groups: map[string]*cb.ConfigGroup{},
   579  							},
   580  						},
   581  					),
   582  				}),
   583  			},
   584  			"^Config update has missing application group$",
   585  		},
   586  		{
   587  			"BadWriteSetApplicationGroupVersion",
   588  			&cb.Payload{
   589  				Header: &cb.Header{ChannelHeader: protoutil.MarshalOrPanic(protoutil.MakeChannelHeader(cb.HeaderType_CONFIG_UPDATE, 0, "", epoch))},
   590  				Data: protoutil.MarshalOrPanic(&cb.ConfigUpdateEnvelope{
   591  					ConfigUpdate: protoutil.MarshalOrPanic(
   592  						&cb.ConfigUpdate{
   593  							WriteSet: &cb.ConfigGroup{
   594  								Groups: map[string]*cb.ConfigGroup{
   595  									channelconfig.ApplicationGroupKey: {
   596  										Version: 100,
   597  									},
   598  								},
   599  							},
   600  						},
   601  					),
   602  				}),
   603  			},
   604  			"^Config update for channel creation does not set application group version to 1,",
   605  		},
   606  		{
   607  			"MissingWriteSetConsortiumValue",
   608  			&cb.Payload{
   609  				Header: &cb.Header{ChannelHeader: protoutil.MarshalOrPanic(protoutil.MakeChannelHeader(cb.HeaderType_CONFIG_UPDATE, 0, "", epoch))},
   610  				Data: protoutil.MarshalOrPanic(&cb.ConfigUpdateEnvelope{
   611  					ConfigUpdate: protoutil.MarshalOrPanic(
   612  						&cb.ConfigUpdate{
   613  							WriteSet: &cb.ConfigGroup{
   614  								Groups: map[string]*cb.ConfigGroup{
   615  									channelconfig.ApplicationGroupKey: {
   616  										Version: 1,
   617  									},
   618  								},
   619  								Values: map[string]*cb.ConfigValue{},
   620  							},
   621  						},
   622  					),
   623  				}),
   624  			},
   625  			"^Consortium config value missing$",
   626  		},
   627  		{
   628  			"BadWriteSetConsortiumValueValue",
   629  			&cb.Payload{
   630  				Header: &cb.Header{ChannelHeader: protoutil.MarshalOrPanic(protoutil.MakeChannelHeader(cb.HeaderType_CONFIG_UPDATE, 0, "", epoch))},
   631  				Data: protoutil.MarshalOrPanic(&cb.ConfigUpdateEnvelope{
   632  					ConfigUpdate: protoutil.MarshalOrPanic(
   633  						&cb.ConfigUpdate{
   634  							WriteSet: &cb.ConfigGroup{
   635  								Groups: map[string]*cb.ConfigGroup{
   636  									channelconfig.ApplicationGroupKey: {
   637  										Version: 1,
   638  									},
   639  								},
   640  								Values: map[string]*cb.ConfigValue{
   641  									channelconfig.ConsortiumKey: {
   642  										Value: []byte("bad consortium value"),
   643  									},
   644  								},
   645  							},
   646  						},
   647  					),
   648  				}),
   649  			},
   650  			"^Error reading unmarshaling consortium name:",
   651  		},
   652  		{
   653  			"UnknownConsortiumName",
   654  			&cb.Payload{
   655  				Header: &cb.Header{ChannelHeader: protoutil.MarshalOrPanic(protoutil.MakeChannelHeader(cb.HeaderType_CONFIG_UPDATE, 0, "", epoch))},
   656  				Data: protoutil.MarshalOrPanic(&cb.ConfigUpdateEnvelope{
   657  					ConfigUpdate: protoutil.MarshalOrPanic(
   658  						&cb.ConfigUpdate{
   659  							WriteSet: &cb.ConfigGroup{
   660  								Groups: map[string]*cb.ConfigGroup{
   661  									channelconfig.ApplicationGroupKey: {
   662  										Version: 1,
   663  									},
   664  								},
   665  								Values: map[string]*cb.ConfigValue{
   666  									channelconfig.ConsortiumKey: {
   667  										Value: protoutil.MarshalOrPanic(
   668  											&cb.Consortium{
   669  												Name: "NotTheNameYouAreLookingFor",
   670  											},
   671  										),
   672  									},
   673  								},
   674  							},
   675  						},
   676  					),
   677  				}),
   678  			},
   679  			"^Unknown consortium name:",
   680  		},
   681  		{
   682  			"Missing consortium members",
   683  			&cb.Payload{
   684  				Header: &cb.Header{ChannelHeader: protoutil.MarshalOrPanic(protoutil.MakeChannelHeader(cb.HeaderType_CONFIG_UPDATE, 0, "", epoch))},
   685  				Data: protoutil.MarshalOrPanic(&cb.ConfigUpdateEnvelope{
   686  					ConfigUpdate: protoutil.MarshalOrPanic(
   687  						&cb.ConfigUpdate{
   688  							WriteSet: &cb.ConfigGroup{
   689  								Groups: map[string]*cb.ConfigGroup{
   690  									channelconfig.ApplicationGroupKey: {
   691  										Version: 1,
   692  									},
   693  								},
   694  								Values: map[string]*cb.ConfigValue{
   695  									channelconfig.ConsortiumKey: {
   696  										Value: protoutil.MarshalOrPanic(
   697  											&cb.Consortium{
   698  												Name: genesisconfig.SampleConsortiumName,
   699  											},
   700  										),
   701  									},
   702  								},
   703  							},
   704  						},
   705  					),
   706  				}),
   707  			},
   708  			"Proposed configuration has no application group members, but consortium contains members",
   709  		},
   710  		{
   711  			"Member not in consortium",
   712  			&cb.Payload{
   713  				Header: &cb.Header{ChannelHeader: protoutil.MarshalOrPanic(protoutil.MakeChannelHeader(cb.HeaderType_CONFIG_UPDATE, 0, "", epoch))},
   714  				Data: protoutil.MarshalOrPanic(&cb.ConfigUpdateEnvelope{
   715  					ConfigUpdate: protoutil.MarshalOrPanic(
   716  						&cb.ConfigUpdate{
   717  							WriteSet: &cb.ConfigGroup{
   718  								Groups: map[string]*cb.ConfigGroup{
   719  									channelconfig.ApplicationGroupKey: {
   720  										Version: 1,
   721  										Groups: map[string]*cb.ConfigGroup{
   722  											"BadOrgName": {},
   723  										},
   724  									},
   725  								},
   726  								Values: map[string]*cb.ConfigValue{
   727  									channelconfig.ConsortiumKey: {
   728  										Value: protoutil.MarshalOrPanic(
   729  											&cb.Consortium{
   730  												Name: genesisconfig.SampleConsortiumName,
   731  											},
   732  										),
   733  									},
   734  								},
   735  							},
   736  						},
   737  					),
   738  				}),
   739  			},
   740  			"Attempted to include member BadOrgName which is not in the consortium",
   741  		},
   742  	} {
   743  		t.Run(tc.name, func(t *testing.T) {
   744  			_, err := templator.NewChannelConfig(&cb.Envelope{Payload: protoutil.MarshalOrPanic(tc.payload)})
   745  			if assert.Error(t, err) {
   746  				assert.Regexp(t, tc.regex, err.Error())
   747  			}
   748  		})
   749  	}
   750  
   751  	// Successful
   752  	t.Run("Success", func(t *testing.T) {
   753  		createTx, err := encoder.MakeChannelCreationTransaction("foo", nil, genesisconfig.Load(genesisconfig.SampleSingleMSPChannelProfile, configtest.GetDevConfigDir()))
   754  		assert.Nil(t, err)
   755  		res, err := templator.NewChannelConfig(createTx)
   756  		assert.Nil(t, err)
   757  		assert.NotEmpty(t, res.ConfigtxValidator().ConfigProto().ChannelGroup.ModPolicy)
   758  		assert.True(t, proto.Equal(originalCG, ctxm.ConfigtxValidator().ConfigProto().ChannelGroup), "Underlying system channel config proto was mutated")
   759  	})
   760  
   761  	// Successful new channel config type
   762  	t.Run("SuccessWithNewCreateType", func(t *testing.T) {
   763  		createTx, err := encoder.MakeChannelCreationTransactionWithSystemChannelContext(
   764  			"foo",
   765  			nil,
   766  			genesisconfig.Load(genesisconfig.SampleSingleMSPChannelProfile, configtest.GetDevConfigDir()),
   767  			genesisconfig.Load(genesisconfig.SampleSingleMSPSoloProfile, configtest.GetDevConfigDir()),
   768  		)
   769  		assert.Nil(t, err)
   770  		_, err = templator.NewChannelConfig(createTx)
   771  		assert.Nil(t, err)
   772  	})
   773  }
   774  
   775  func TestZeroVersions(t *testing.T) {
   776  	data := &cb.ConfigGroup{
   777  		Version: 7,
   778  		Groups: map[string]*cb.ConfigGroup{
   779  			"foo": {
   780  				Version: 6,
   781  			},
   782  			"bar": {
   783  				Values: map[string]*cb.ConfigValue{
   784  					"foo": {
   785  						Version: 3,
   786  					},
   787  				},
   788  				Policies: map[string]*cb.ConfigPolicy{
   789  					"bar": {
   790  						Version: 5,
   791  					},
   792  				},
   793  			},
   794  		},
   795  		Values: map[string]*cb.ConfigValue{
   796  			"foo": {
   797  				Version: 3,
   798  			},
   799  			"bar": {
   800  				Version: 9,
   801  			},
   802  		},
   803  		Policies: map[string]*cb.ConfigPolicy{
   804  			"foo": {
   805  				Version: 4,
   806  			},
   807  			"bar": {
   808  				Version: 5,
   809  			},
   810  		},
   811  	}
   812  
   813  	expected := &cb.ConfigGroup{
   814  		Groups: map[string]*cb.ConfigGroup{
   815  			"foo": {},
   816  			"bar": {
   817  				Values: map[string]*cb.ConfigValue{
   818  					"foo": {},
   819  				},
   820  				Policies: map[string]*cb.ConfigPolicy{
   821  					"bar": {},
   822  				},
   823  			},
   824  		},
   825  		Values: map[string]*cb.ConfigValue{
   826  			"foo": {},
   827  			"bar": {},
   828  		},
   829  		Policies: map[string]*cb.ConfigPolicy{
   830  			"foo": {},
   831  			"bar": {},
   832  		},
   833  	}
   834  
   835  	zeroVersions(data)
   836  
   837  	assert.True(t, proto.Equal(expected, data))
   838  }