github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/core/scc/cscc/configure_test.go (about)

     1  /*
     2  Copyright hechain. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package cscc
     8  
     9  import (
    10  	"errors"
    11  	"io/ioutil"
    12  	"net"
    13  	"os"
    14  	"testing"
    15  	"time"
    16  
    17  	"github.com/golang/protobuf/proto"
    18  	"github.com/hechain20/hechain/bccsp/sw"
    19  	configtxtest "github.com/hechain20/hechain/common/configtx/test"
    20  	"github.com/hechain20/hechain/common/genesis"
    21  	"github.com/hechain20/hechain/common/metrics/disabled"
    22  	"github.com/hechain20/hechain/common/policies"
    23  	"github.com/hechain20/hechain/core/aclmgmt"
    24  	"github.com/hechain20/hechain/core/chaincode"
    25  	"github.com/hechain20/hechain/core/config/configtest"
    26  	"github.com/hechain20/hechain/core/deliverservice"
    27  	"github.com/hechain20/hechain/core/ledger"
    28  	"github.com/hechain20/hechain/core/ledger/ledgermgmt"
    29  	"github.com/hechain20/hechain/core/ledger/ledgermgmt/ledgermgmttest"
    30  	"github.com/hechain20/hechain/core/peer"
    31  	"github.com/hechain20/hechain/core/scc/cscc/mocks"
    32  	"github.com/hechain20/hechain/core/transientstore"
    33  	"github.com/hechain20/hechain/gossip/gossip"
    34  	gossipmetrics "github.com/hechain20/hechain/gossip/metrics"
    35  	"github.com/hechain20/hechain/gossip/privdata"
    36  	"github.com/hechain20/hechain/gossip/service"
    37  	"github.com/hechain20/hechain/internal/configtxgen/encoder"
    38  	"github.com/hechain20/hechain/internal/configtxgen/genesisconfig"
    39  	peergossip "github.com/hechain20/hechain/internal/peer/gossip"
    40  	"github.com/hechain20/hechain/msp/mgmt"
    41  	msptesttools "github.com/hechain20/hechain/msp/mgmt/testtools"
    42  	"github.com/hechain20/hechain/protoutil"
    43  	"github.com/hyperledger/fabric-chaincode-go/shim"
    44  	cb "github.com/hyperledger/fabric-protos-go/common"
    45  	pb "github.com/hyperledger/fabric-protos-go/peer"
    46  	"github.com/spf13/viper"
    47  	"github.com/stretchr/testify/require"
    48  	"google.golang.org/grpc"
    49  )
    50  
    51  //go:generate counterfeiter -o mocks/acl_provider.go --fake-name ACLProvider . aclProvider
    52  
    53  type aclProvider interface {
    54  	aclmgmt.ACLProvider
    55  }
    56  
    57  //go:generate counterfeiter -o mocks/chaincode_stub.go --fake-name ChaincodeStub . chaincodeStub
    58  
    59  type chaincodeStub interface {
    60  	shim.ChaincodeStubInterface
    61  }
    62  
    63  //go:generate counterfeiter -o mocks/channel_policy_manager_getter.go --fake-name ChannelPolicyManagerGetter . channelPolicyManagerGetter
    64  
    65  type channelPolicyManagerGetter interface {
    66  	policies.ChannelPolicyManagerGetter
    67  }
    68  
    69  //go:generate counterfeiter -o mocks/store_provider.go --fake-name StoreProvider . storeProvider
    70  
    71  type storeProvider interface {
    72  	transientstore.StoreProvider
    73  }
    74  
    75  func TestMain(m *testing.M) {
    76  	msptesttools.LoadMSPSetupForTesting()
    77  	rc := m.Run()
    78  	os.Exit(rc)
    79  }
    80  
    81  func TestConfigerInit(t *testing.T) {
    82  	mockACLProvider := &mocks.ACLProvider{}
    83  	mockStub := &mocks.ChaincodeStub{}
    84  	cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
    85  	require.NoError(t, err)
    86  	cscc := &PeerConfiger{
    87  		aclProvider: mockACLProvider,
    88  		bccsp:       cryptoProvider,
    89  	}
    90  	res := cscc.Init(mockStub)
    91  	require.Equal(t, int32(shim.OK), res.Status)
    92  }
    93  
    94  func TestConfigerInvokeInvalidParameters(t *testing.T) {
    95  	mockACLProvider := &mocks.ACLProvider{}
    96  	cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
    97  	require.NoError(t, err)
    98  	cscc := &PeerConfiger{
    99  		aclProvider: mockACLProvider,
   100  		bccsp:       cryptoProvider,
   101  	}
   102  	mockStub := &mocks.ChaincodeStub{}
   103  
   104  	mockStub.GetArgsReturns(nil)
   105  	mockStub.GetSignedProposalReturns(validSignedProposal(), nil)
   106  	res := cscc.Invoke(mockStub)
   107  	require.NotEqual(
   108  		t,
   109  		int32(shim.OK),
   110  		res.Status,
   111  		"cscc invoke expected to fail having zero arguments",
   112  	)
   113  	require.Equal(t, "Incorrect number of arguments, 0", res.Message)
   114  
   115  	mockACLProvider.CheckACLReturns(errors.New("Failed authorization"))
   116  	args := [][]byte{[]byte("GetChannels")}
   117  	mockStub.GetArgsReturns(args)
   118  	res = cscc.Invoke(mockStub)
   119  	require.NotEqual(
   120  		t,
   121  		int32(shim.OK),
   122  		res.Status,
   123  		"invoke expected to fail no signed proposal provided",
   124  	)
   125  	require.Equal(t, "access denied for [GetChannels]: Failed authorization", res.Message)
   126  
   127  	mockACLProvider.CheckACLReturns(nil)
   128  	args = [][]byte{[]byte("fooFunction"), []byte("testChannelID")}
   129  	mockStub.GetArgsReturns(args)
   130  	res = cscc.Invoke(mockStub)
   131  	require.NotEqual(
   132  		t,
   133  		int32(shim.OK),
   134  		res.Status,
   135  		"invoke invoke expected wrong function name provided",
   136  	)
   137  	require.Equal(t, "Requested function fooFunction not found.", res.Message)
   138  
   139  	mockACLProvider.CheckACLReturns(nil)
   140  	args = [][]byte{[]byte("GetConfigBlock"), []byte("testChannelID")}
   141  	mockStub.GetArgsReturns(args)
   142  	mockStub.GetSignedProposalReturns(&pb.SignedProposal{
   143  		ProposalBytes: []byte("garbage"),
   144  	}, nil)
   145  	res = cscc.Invoke(mockStub)
   146  	require.NotEqual(
   147  		t,
   148  		int32(shim.OK),
   149  		res.Status,
   150  		"invoke expected to fail in ccc2cc context",
   151  	)
   152  	require.Equal(
   153  		t,
   154  		"Failed to identify the called chaincode: could not unmarshal proposal: proto: can't skip unknown wire type 7",
   155  		res.Message,
   156  	)
   157  
   158  	mockACLProvider.CheckACLReturns(nil)
   159  	args = [][]byte{[]byte("GetConfigBlock"), []byte("testChannelID")}
   160  	mockStub.GetArgsReturns(args)
   161  	mockStub.GetSignedProposalReturns(&pb.SignedProposal{
   162  		ProposalBytes: protoutil.MarshalOrPanic(&pb.Proposal{
   163  			Payload: protoutil.MarshalOrPanic(&pb.ChaincodeProposalPayload{
   164  				Input: protoutil.MarshalOrPanic(&pb.ChaincodeInvocationSpec{
   165  					ChaincodeSpec: &pb.ChaincodeSpec{
   166  						ChaincodeId: &pb.ChaincodeID{
   167  							Name: "fake-cc2cc",
   168  						},
   169  					},
   170  				}),
   171  			}),
   172  		}),
   173  	}, nil)
   174  	res = cscc.Invoke(mockStub)
   175  	require.NotEqual(
   176  		t,
   177  		int32(shim.OK),
   178  		res.Status,
   179  		"invoke expected to fail in ccc2cc context",
   180  	)
   181  	require.Equal(
   182  		t,
   183  		"Rejecting invoke of CSCC from another chaincode, original invocation for 'fake-cc2cc'",
   184  		res.Message,
   185  	)
   186  
   187  	mockACLProvider.CheckACLReturns(errors.New("Failed authorization"))
   188  	mockStub.GetSignedProposalReturns(validSignedProposal(), nil)
   189  	args = [][]byte{[]byte("GetConfigBlock"), []byte("testChannelID")}
   190  	mockStub.GetArgsReturns(args)
   191  	res = cscc.Invoke(mockStub)
   192  	require.NotEqual(
   193  		t,
   194  		int32(shim.OK),
   195  		res.Status,
   196  		"invoke expected to fail no signed proposal provided",
   197  	)
   198  	require.Equal(
   199  		t,
   200  		"access denied for [GetConfigBlock][testChannelID]: Failed authorization",
   201  		res.Message,
   202  	)
   203  }
   204  
   205  func TestConfigerInvokeJoinChainMissingParams(t *testing.T) {
   206  	cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
   207  	require.NoError(t, err)
   208  	cscc := &PeerConfiger{
   209  		aclProvider: &mocks.ACLProvider{},
   210  		bccsp:       cryptoProvider,
   211  	}
   212  	mockStub := &mocks.ChaincodeStub{}
   213  	mockStub.GetArgsReturns([][]byte{[]byte("JoinChain")})
   214  	res := cscc.Invoke(mockStub)
   215  	require.NotEqual(
   216  		t,
   217  		int32(shim.OK),
   218  		res.Status,
   219  		"cscc invoke JoinChain should have failed with invalid number of args",
   220  	)
   221  }
   222  
   223  func TestConfigerInvokeJoinChainWrongParams(t *testing.T) {
   224  	cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
   225  	require.NoError(t, err)
   226  	cscc := &PeerConfiger{
   227  		aclProvider: &mocks.ACLProvider{},
   228  		bccsp:       cryptoProvider,
   229  	}
   230  	mockStub := &mocks.ChaincodeStub{}
   231  	mockStub.GetArgsReturns([][]byte{[]byte("JoinChain"), []byte("action")})
   232  	mockStub.GetSignedProposalReturns(validSignedProposal(), nil)
   233  	res := cscc.Invoke(mockStub)
   234  	require.NotEqual(
   235  		t,
   236  		int32(shim.OK),
   237  		res.Status,
   238  		"cscc invoke JoinChain should have failed with null genesis block",
   239  	)
   240  }
   241  
   242  func TestConfigerInvokeJoinChainCorrectParams(t *testing.T) {
   243  	testDir, err := ioutil.TempDir("", "cscc_test")
   244  	require.NoError(t, err, "error in creating test dir")
   245  	defer os.RemoveAll(testDir)
   246  
   247  	ledgerInitializer := ledgermgmttest.NewInitializer(testDir)
   248  	ledgerInitializer.CustomTxProcessors = map[cb.HeaderType]ledger.CustomTxProcessor{
   249  		cb.HeaderType_CONFIG: &peer.ConfigTxProcessor{},
   250  	}
   251  	ledgerMgr := ledgermgmt.NewLedgerMgr(ledgerInitializer)
   252  	defer ledgerMgr.Close()
   253  
   254  	listener, err := net.Listen("tcp", "127.0.0.1:")
   255  	require.NoError(t, err)
   256  	grpcServer := grpc.NewServer()
   257  
   258  	cscc := newPeerConfiger(t, ledgerMgr, grpcServer, listener.Addr().String())
   259  
   260  	go grpcServer.Serve(listener)
   261  	defer grpcServer.Stop()
   262  
   263  	mockACLProvider := cscc.aclProvider.(*mocks.ACLProvider)
   264  	mockStub := &mocks.ChaincodeStub{}
   265  
   266  	// Successful path for JoinChain
   267  	blockBytes := mockConfigBlock()
   268  	if blockBytes == nil {
   269  		t.Fatalf("cscc invoke JoinChain failed because invalid block")
   270  	}
   271  	args := [][]byte{[]byte("JoinChain"), blockBytes}
   272  	sProp := validSignedProposal()
   273  	sProp.Signature = sProp.ProposalBytes
   274  
   275  	// Try fail path with nil block
   276  	mockStub.GetArgsReturns([][]byte{[]byte("JoinChain"), nil})
   277  	mockStub.GetSignedProposalReturns(sProp, nil)
   278  	res := cscc.Invoke(mockStub)
   279  	// res := stub.MockInvokeWithSignedProposal("2", [][]byte{[]byte("JoinChain"), nil}, sProp)
   280  	require.Equal(t, int32(shim.ERROR), res.Status)
   281  
   282  	// Try fail path with block and nil payload header
   283  	payload, _ := proto.Marshal(&cb.Payload{})
   284  	env, _ := proto.Marshal(&cb.Envelope{
   285  		Payload: payload,
   286  	})
   287  	badBlock := &cb.Block{
   288  		Data: &cb.BlockData{
   289  			Data: [][]byte{env},
   290  		},
   291  	}
   292  	badBlockBytes := protoutil.MarshalOrPanic(badBlock)
   293  	mockStub.GetArgsReturns([][]byte{[]byte("JoinChain"), badBlockBytes})
   294  	res = cscc.Invoke(mockStub)
   295  	// res = stub.MockInvokeWithSignedProposal("2", [][]byte{[]byte("JoinChain"), badBlockBytes}, sProp)
   296  	require.Equal(t, int32(shim.ERROR), res.Status)
   297  
   298  	// Now, continue with valid execution path
   299  	mockStub.GetArgsReturns(args)
   300  	mockStub.GetSignedProposalReturns(sProp, nil)
   301  	res = cscc.Invoke(mockStub)
   302  	require.Equal(t, int32(shim.OK), res.Status, "invoke JoinChain failed with: %v", res.Message)
   303  
   304  	// This call must fail
   305  	sProp.Signature = nil
   306  	mockACLProvider.CheckACLReturns(errors.New("Failed authorization"))
   307  	mockStub.GetArgsReturns(args)
   308  	mockStub.GetSignedProposalReturns(sProp, nil)
   309  
   310  	res = cscc.Invoke(mockStub)
   311  	require.Equal(t, int32(shim.ERROR), res.Status)
   312  	require.Contains(t, res.Message, "access denied for [JoinChain][mytestchannelid]")
   313  	sProp.Signature = sProp.ProposalBytes
   314  
   315  	// Query the configuration block
   316  	// channelID := []byte{143, 222, 22, 192, 73, 145, 76, 110, 167, 154, 118, 66, 132, 204, 113, 168}
   317  	channelID, err := protoutil.GetChannelIDFromBlockBytes(blockBytes)
   318  	if err != nil {
   319  		t.Fatalf("cscc invoke JoinChain failed with: %v", err)
   320  	}
   321  
   322  	// Test an ACL failure on GetConfigBlock
   323  	mockACLProvider.CheckACLReturns(errors.New("Failed authorization"))
   324  	args = [][]byte{[]byte("GetConfigBlock"), []byte(channelID)}
   325  	mockStub.GetArgsReturns(args)
   326  	mockStub.GetSignedProposalReturns(sProp, nil)
   327  	res = cscc.Invoke(mockStub)
   328  	require.Equal(t, int32(shim.ERROR), res.Status, "invoke GetConfigBlock should have failed: %v", res.Message)
   329  	require.Contains(t, res.Message, "Failed authorization")
   330  
   331  	// Test with ACL okay
   332  	mockACLProvider.CheckACLReturns(nil)
   333  	res = cscc.Invoke(mockStub)
   334  	require.Equal(t, int32(shim.OK), res.Status, "invoke GetConfigBlock failed with: %v", res.Message)
   335  
   336  	// get channels for the peer
   337  	mockACLProvider.CheckACLReturns(nil)
   338  	args = [][]byte{[]byte(GetChannels)}
   339  	mockStub.GetArgsReturns(args)
   340  	res = cscc.Invoke(mockStub)
   341  	if res.Status != shim.OK {
   342  		t.FailNow()
   343  	}
   344  
   345  	cqr := &pb.ChannelQueryResponse{}
   346  	err = proto.Unmarshal(res.Payload, cqr)
   347  	if err != nil {
   348  		t.FailNow()
   349  	}
   350  
   351  	// peer joined one channel so query should return an array with one channel
   352  	if len(cqr.GetChannels()) != 1 {
   353  		t.FailNow()
   354  	}
   355  }
   356  
   357  func TestConfigerInvokeJoinChainBySnapshot(t *testing.T) {
   358  	testDir, err := ioutil.TempDir("", "cscc_test_bysnapshot")
   359  	require.NoError(t, err, "error in creating test dir")
   360  	defer os.RemoveAll(testDir)
   361  
   362  	ledgerInitializer := ledgermgmttest.NewInitializer(testDir)
   363  	ledgerInitializer.CustomTxProcessors = map[cb.HeaderType]ledger.CustomTxProcessor{
   364  		cb.HeaderType_CONFIG: &peer.ConfigTxProcessor{},
   365  	}
   366  	ledgerMgr := ledgermgmt.NewLedgerMgr(ledgerInitializer)
   367  	defer ledgerMgr.Close()
   368  
   369  	listener, err := net.Listen("tcp", "127.0.0.1:")
   370  	require.NoError(t, err)
   371  	grpcServer := grpc.NewServer()
   372  
   373  	cscc := newPeerConfiger(t, ledgerMgr, grpcServer, listener.Addr().String())
   374  
   375  	go grpcServer.Serve(listener)
   376  	defer grpcServer.Stop()
   377  
   378  	channelID := "testjoinchainbysnapshot"
   379  	sProp := validSignedProposal()
   380  	sProp.Signature = sProp.ProposalBytes
   381  
   382  	// set mocked ACLProcider and Stub
   383  	mockACLProvider := cscc.aclProvider.(*mocks.ACLProvider)
   384  	mockStub := &mocks.ChaincodeStub{}
   385  
   386  	snapshotDir := ledgermgmttest.CreateSnapshotWithGenesisBlock(t, testDir, channelID, &peer.ConfigTxProcessor{})
   387  
   388  	// successful path
   389  	mockACLProvider.CheckACLReturns(nil)
   390  	mockStub.GetSignedProposalReturns(sProp, nil)
   391  	mockStub.GetArgsReturns([][]byte{[]byte("JoinChainBySnapshot"), []byte(snapshotDir)})
   392  	res := cscc.Invoke(mockStub)
   393  	require.Equal(t, int32(shim.OK), res.Status)
   394  
   395  	// wait until ledger creation is done
   396  	ledgerCreationDone := func() bool {
   397  		resp := cscc.joinBySnapshotStatus()
   398  		require.Equal(t, shim.OK, int(resp.Status))
   399  		status := &pb.JoinBySnapshotStatus{}
   400  		err := proto.Unmarshal(resp.Payload, status)
   401  		require.NoError(t, err)
   402  		return !status.InProgress
   403  	}
   404  	require.Eventually(t, ledgerCreationDone, time.Minute, time.Second)
   405  
   406  	// verify get channels
   407  	mockStub.GetArgsReturns([][]byte{[]byte(GetChannels)})
   408  	res = cscc.Invoke(mockStub)
   409  	require.Equal(t, int32(shim.OK), res.Status)
   410  
   411  	cqr := &pb.ChannelQueryResponse{}
   412  	require.NoError(t, proto.Unmarshal(res.Payload, cqr))
   413  	require.Equal(t, 1, len(cqr.GetChannels()))
   414  	require.Equal(t, channelID, cqr.GetChannels()[0].GetChannelId())
   415  
   416  	// verify ledger is created
   417  	lgr := cscc.peer.GetLedger(channelID)
   418  	require.NotNil(t, lgr)
   419  	bcInfo, err := lgr.GetBlockchainInfo()
   420  	require.NoError(t, err)
   421  	require.Equal(t, uint64(1), bcInfo.Height)
   422  
   423  	// error path due to missing argument
   424  	mockStub.GetArgsReturns([][]byte{[]byte("JoinChainBySnapshot")})
   425  	res = cscc.Invoke(mockStub)
   426  	require.Equal(t, int32(shim.ERROR), res.Status)
   427  	require.Equal(t, "Incorrect number of arguments, 1", res.Message)
   428  
   429  	// error path due to invalid snapshot dir (ledger creation fails in this case)
   430  	mockStub.GetArgsReturns([][]byte{[]byte("JoinChainBySnapshot"), []byte("invalid-snapshot")})
   431  	res = cscc.Invoke(mockStub)
   432  	require.Equal(t, int32(shim.ERROR), res.Status)
   433  	require.Contains(t, res.Message, "no such file or directory")
   434  
   435  	// error path due to CheckACL error
   436  	mockACLProvider.CheckACLReturns(errors.New("Failed authorization"))
   437  	mockStub.GetArgsReturns([][]byte{[]byte("JoinChainBySnapshot"), []byte(snapshotDir)})
   438  	res = cscc.Invoke(mockStub)
   439  	require.Equal(t, int32(shim.ERROR), res.Status)
   440  	require.Contains(t, res.Message, "access denied for [JoinChainBySnapshot]")
   441  }
   442  
   443  func TestConfigerInvokeGetChannelConfig(t *testing.T) {
   444  	testDir, err := ioutil.TempDir("", "cscc_test_GetChannelConfig")
   445  	require.NoError(t, err)
   446  	defer os.RemoveAll(testDir)
   447  
   448  	ledgerInitializer := ledgermgmttest.NewInitializer(testDir)
   449  	ledgerInitializer.CustomTxProcessors = map[cb.HeaderType]ledger.CustomTxProcessor{
   450  		cb.HeaderType_CONFIG: &peer.ConfigTxProcessor{},
   451  	}
   452  	ledgerMgr := ledgermgmt.NewLedgerMgr(ledgerInitializer)
   453  	defer ledgerMgr.Close()
   454  
   455  	listener, err := net.Listen("tcp", "127.0.0.1:")
   456  	require.NoError(t, err)
   457  	grpcServer := grpc.NewServer()
   458  
   459  	cscc := newPeerConfiger(t, ledgerMgr, grpcServer, listener.Addr().String())
   460  
   461  	go grpcServer.Serve(listener)
   462  	defer grpcServer.Stop()
   463  
   464  	block, err := configtxtest.MakeGenesisBlock("test-channel-id")
   465  	require.NoError(t, err)
   466  	require.NoError(t,
   467  		cscc.peer.CreateChannel("test-channel-id", block, cscc.deployedCCInfoProvider, cscc.legacyLifecycle, cscc.newLifecycle),
   468  	)
   469  
   470  	initMocks := func() (*mocks.ACLProvider, *mocks.ChaincodeStub) {
   471  		mockACLProvider := cscc.aclProvider.(*mocks.ACLProvider)
   472  		mockACLProvider.CheckACLReturns(nil)
   473  
   474  		mockStub := &mocks.ChaincodeStub{}
   475  		mockStub.GetSignedProposalReturns(validSignedProposal(), nil)
   476  		mockStub.GetArgsReturns([][]byte{[]byte("GetChannelConfig"), []byte("test-channel-id")})
   477  		return mockACLProvider, mockStub
   478  	}
   479  
   480  	t.Run("green-path", func(t *testing.T) {
   481  		_, mockStub := initMocks()
   482  		res := cscc.Invoke(mockStub)
   483  		require.Equal(t, int32(shim.OK), res.Status)
   484  
   485  		retrievedChannelConfig := &cb.Config{}
   486  		require.NoError(t, proto.Unmarshal(res.Payload, retrievedChannelConfig))
   487  		require.True(t,
   488  			proto.Equal(
   489  				channelConfigFromBlock(t, block),
   490  				retrievedChannelConfig,
   491  			),
   492  		)
   493  	})
   494  
   495  	t.Run("acl-error", func(t *testing.T) {
   496  		mockACLProvider, mockStub := initMocks()
   497  		mockACLProvider.CheckACLReturns(errors.New("auth error"))
   498  		res := cscc.Invoke(mockStub)
   499  		require.Equal(t, int32(shim.ERROR), res.Status)
   500  		require.Equal(t, res.Message, "access denied for [GetChannelConfig][test-channel-id]: auth error")
   501  	})
   502  
   503  	t.Run("missing-channel-name-error", func(t *testing.T) {
   504  		_, mockStub := initMocks()
   505  		mockStub.GetArgsReturns([][]byte{[]byte("GetChannelConfig")})
   506  		res := cscc.Invoke(mockStub)
   507  		require.Equal(t, int32(shim.ERROR), res.Status)
   508  		require.Equal(t, "Incorrect number of arguments, 1", res.Message)
   509  	})
   510  
   511  	t.Run("nil-channel-name-error", func(t *testing.T) {
   512  		_, mockStub := initMocks()
   513  		mockStub.GetArgsReturns([][]byte{[]byte("GetChannelConfig"), {}})
   514  		res := cscc.Invoke(mockStub)
   515  		require.Equal(t, int32(shim.ERROR), res.Status)
   516  		require.Equal(t, "empty channel name provided", res.Message)
   517  	})
   518  
   519  	t.Run("non-existing-channel-name-error", func(t *testing.T) {
   520  		_, mockStub := initMocks()
   521  		mockStub.GetArgsReturns([][]byte{[]byte("GetChannelConfig"), []byte("non-existing-channel")})
   522  		res := cscc.Invoke(mockStub)
   523  		require.Equal(t, int32(shim.ERROR), res.Status)
   524  		require.Equal(t, "unknown channel ID, non-existing-channel", res.Message)
   525  	})
   526  }
   527  
   528  func TestPeerConfiger_SubmittingOrdererGenesis(t *testing.T) {
   529  	conf := genesisconfig.Load(genesisconfig.SampleSingleMSPSoloProfile, configtest.GetDevConfigDir())
   530  	conf.Application = nil
   531  	cg, err := encoder.NewChannelGroup(conf)
   532  	require.NoError(t, err)
   533  	block := genesis.NewFactoryImpl(cg).Block("mytestchannelid")
   534  	blockBytes := protoutil.MarshalOrPanic(block)
   535  
   536  	cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
   537  	require.NoError(t, err)
   538  	mockACLProvider := &mocks.ACLProvider{}
   539  	cscc := &PeerConfiger{
   540  		aclProvider: mockACLProvider,
   541  		bccsp:       cryptoProvider,
   542  	}
   543  	mockStub := &mocks.ChaincodeStub{}
   544  	// Failed path: wrong parameter type
   545  	args := [][]byte{[]byte("JoinChain"), []byte(blockBytes)}
   546  	mockStub.GetArgsReturns(args)
   547  	mockStub.GetSignedProposalReturns(validSignedProposal(), nil)
   548  	res := cscc.Invoke(mockStub)
   549  
   550  	require.NotEqual(
   551  		t,
   552  		int32(shim.OK),
   553  		res.Status,
   554  		"invoke JoinChain should have failed with wrong genesis block",
   555  	)
   556  	require.Contains(t, res.Message, "missing Application configuration group")
   557  }
   558  
   559  func newPeerConfiger(t *testing.T, ledgerMgr *ledgermgmt.LedgerMgr, grpcServer *grpc.Server, peerEndpoint string) *PeerConfiger {
   560  	viper.Set("chaincode.executetimeout", "3s")
   561  
   562  	config := chaincode.GlobalConfig()
   563  	config.StartupTimeout = 30 * time.Second
   564  
   565  	cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
   566  	require.NoError(t, err)
   567  
   568  	localMSP := mgmt.GetLocalMSP(cryptoProvider)
   569  	signer, err := localMSP.GetDefaultSigningIdentity()
   570  	require.NoError(t, err)
   571  	deserManager := peergossip.NewDeserializersManager(localMSP)
   572  
   573  	messageCryptoService := peergossip.NewMCS(
   574  		&mocks.ChannelPolicyManagerGetter{},
   575  		signer,
   576  		deserManager,
   577  		cryptoProvider,
   578  	)
   579  	secAdv := peergossip.NewSecurityAdvisor(deserManager)
   580  	defaultSecureDialOpts := func() []grpc.DialOption {
   581  		return []grpc.DialOption{grpc.WithInsecure()}
   582  	}
   583  	gossipConfig, err := gossip.GlobalConfig(peerEndpoint, nil)
   584  	require.NoError(t, err)
   585  
   586  	gossipService, err := service.New(
   587  		signer,
   588  		gossipmetrics.NewGossipMetrics(&disabled.Provider{}),
   589  		peerEndpoint,
   590  		grpcServer,
   591  		messageCryptoService,
   592  		secAdv,
   593  		defaultSecureDialOpts,
   594  		nil,
   595  		gossipConfig,
   596  		&service.ServiceConfig{},
   597  		&privdata.PrivdataConfig{},
   598  		&deliverservice.DeliverServiceConfig{
   599  			ReConnectBackoffThreshold:   deliverservice.DefaultReConnectBackoffThreshold,
   600  			ReconnectTotalTimeThreshold: deliverservice.DefaultReConnectTotalTimeThreshold,
   601  		},
   602  	)
   603  	require.NoError(t, err)
   604  
   605  	// setup cscc instance
   606  	mockACLProvider := &mocks.ACLProvider{}
   607  	cscc := &PeerConfiger{
   608  		aclProvider: mockACLProvider,
   609  		peer: &peer.Peer{
   610  			StoreProvider:  &mocks.StoreProvider{},
   611  			GossipService:  gossipService,
   612  			LedgerMgr:      ledgerMgr,
   613  			CryptoProvider: cryptoProvider,
   614  		},
   615  		bccsp: cryptoProvider,
   616  	}
   617  
   618  	return cscc
   619  }
   620  
   621  func mockConfigBlock() []byte {
   622  	var blockBytes []byte = nil
   623  	block, err := configtxtest.MakeGenesisBlock("mytestchannelid")
   624  	if err == nil {
   625  		blockBytes = protoutil.MarshalOrPanic(block)
   626  	}
   627  	return blockBytes
   628  }
   629  
   630  func validSignedProposal() *pb.SignedProposal {
   631  	return &pb.SignedProposal{
   632  		ProposalBytes: protoutil.MarshalOrPanic(&pb.Proposal{
   633  			Payload: protoutil.MarshalOrPanic(&pb.ChaincodeProposalPayload{
   634  				Input: protoutil.MarshalOrPanic(&pb.ChaincodeInvocationSpec{
   635  					ChaincodeSpec: &pb.ChaincodeSpec{
   636  						ChaincodeId: &pb.ChaincodeID{
   637  							Name: "cscc",
   638  						},
   639  					},
   640  				}),
   641  			}),
   642  		}),
   643  	}
   644  }
   645  
   646  func channelConfigFromBlock(t *testing.T, configBlock *cb.Block) *cb.Config {
   647  	envelopeConfig, err := protoutil.ExtractEnvelope(configBlock, 0)
   648  	require.NoError(t, err)
   649  	configEnv := &cb.ConfigEnvelope{}
   650  	_, err = protoutil.UnmarshalEnvelopeOfType(envelopeConfig, cb.HeaderType_CONFIG, configEnv)
   651  	require.NoError(t, err)
   652  	return configEnv.Config
   653  }