github.com/darrenli6/fabric-sdk-example@v0.0.0-20220109053535-94b13b56df8c/core/endorser/endorser_test.go (about)

     1  /*
     2  Copyright IBM Corp. 2016 All Rights Reserved.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8  		 http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package endorser
    18  
    19  import (
    20  	"encoding/hex"
    21  	"errors"
    22  	"flag"
    23  	"fmt"
    24  	"io/ioutil"
    25  	"net"
    26  	"os"
    27  	"path/filepath"
    28  	"runtime"
    29  	"strings"
    30  	"testing"
    31  	"time"
    32  
    33  	"github.com/golang/protobuf/proto"
    34  	"github.com/hyperledger/fabric/bccsp"
    35  	"github.com/hyperledger/fabric/bccsp/factory"
    36  	mockpolicies "github.com/hyperledger/fabric/common/mocks/policies"
    37  	"github.com/hyperledger/fabric/common/policies"
    38  	"github.com/hyperledger/fabric/common/util"
    39  	"github.com/hyperledger/fabric/core/chaincode"
    40  	"github.com/hyperledger/fabric/core/common/ccprovider"
    41  	"github.com/hyperledger/fabric/core/config"
    42  	"github.com/hyperledger/fabric/core/container"
    43  	"github.com/hyperledger/fabric/core/peer"
    44  	syscc "github.com/hyperledger/fabric/core/scc"
    45  	"github.com/hyperledger/fabric/core/testutil"
    46  	"github.com/hyperledger/fabric/msp"
    47  	mspmgmt "github.com/hyperledger/fabric/msp/mgmt"
    48  	"github.com/hyperledger/fabric/msp/mgmt/testtools"
    49  	"github.com/hyperledger/fabric/protos/common"
    50  	pb "github.com/hyperledger/fabric/protos/peer"
    51  	pbutils "github.com/hyperledger/fabric/protos/utils"
    52  	"github.com/spf13/viper"
    53  	"github.com/stretchr/testify/assert"
    54  	"golang.org/x/net/context"
    55  	"google.golang.org/grpc"
    56  	"google.golang.org/grpc/credentials"
    57  )
    58  
    59  var endorserServer pb.EndorserServer
    60  var signer msp.SigningIdentity
    61  
    62  type testEnvironment struct {
    63  	tempDir  string
    64  	listener net.Listener
    65  }
    66  
    67  //initialize peer and start up. If security==enabled, login as vp
    68  func initPeer(chainID string) (*testEnvironment, error) {
    69  	//start clean
    70  	// finitPeer(nil)
    71  	var opts []grpc.ServerOption
    72  	if viper.GetBool("peer.tls.enabled") {
    73  		creds, err := credentials.NewServerTLSFromFile(config.GetPath("peer.tls.cert.file"), config.GetPath("peer.tls.key.file"))
    74  		if err != nil {
    75  			return nil, fmt.Errorf("Failed to generate credentials %v", err)
    76  		}
    77  		opts = []grpc.ServerOption{grpc.Creds(creds)}
    78  	}
    79  	grpcServer := grpc.NewServer(opts...)
    80  
    81  	tempDir := newTempDir()
    82  	viper.Set("peer.fileSystemPath", filepath.Join(tempDir, "hyperledger", "production"))
    83  
    84  	peerAddress, err := peer.GetLocalAddress()
    85  	if err != nil {
    86  		return nil, fmt.Errorf("Error obtaining peer address: %s", err)
    87  	}
    88  	lis, err := net.Listen("tcp", peerAddress)
    89  	if err != nil {
    90  		return nil, fmt.Errorf("Error starting peer listener %s", err)
    91  	}
    92  
    93  	//initialize ledger
    94  	peer.MockInitialize()
    95  
    96  	mspGetter := func(cid string) []string {
    97  		return []string{"DEFAULT"}
    98  	}
    99  
   100  	peer.MockSetMSPIDGetter(mspGetter)
   101  
   102  	getPeerEndpoint := func() (*pb.PeerEndpoint, error) {
   103  		return &pb.PeerEndpoint{Id: &pb.PeerID{Name: "testpeer"}, Address: peerAddress}, nil
   104  	}
   105  
   106  	ccStartupTimeout := time.Duration(30000) * time.Millisecond
   107  	pb.RegisterChaincodeSupportServer(grpcServer, chaincode.NewChaincodeSupport(getPeerEndpoint, false, ccStartupTimeout))
   108  
   109  	syscc.RegisterSysCCs()
   110  
   111  	if err = peer.MockCreateChain(chainID); err != nil {
   112  		closeListenerAndSleep(lis)
   113  		return nil, err
   114  	}
   115  
   116  	syscc.DeploySysCCs(chainID)
   117  
   118  	go grpcServer.Serve(lis)
   119  
   120  	return &testEnvironment{tempDir: tempDir, listener: lis}, nil
   121  }
   122  
   123  func finitPeer(tev *testEnvironment) {
   124  	closeListenerAndSleep(tev.listener)
   125  	os.RemoveAll(tev.tempDir)
   126  }
   127  
   128  func closeListenerAndSleep(l net.Listener) {
   129  	if l != nil {
   130  		l.Close()
   131  		time.Sleep(2 * time.Second)
   132  	}
   133  }
   134  
   135  // getInvokeProposal gets the proposal for the chaincode invocation
   136  // Currently supported only for Invokes
   137  // It returns the proposal and the transaction id associated to the proposal
   138  func getInvokeProposal(cis *pb.ChaincodeInvocationSpec, chainID string, creator []byte) (*pb.Proposal, string, error) {
   139  	return pbutils.CreateChaincodeProposal(common.HeaderType_ENDORSER_TRANSACTION, chainID, cis, creator)
   140  }
   141  
   142  // getInvokeProposalOverride allows to get a proposal for the chaincode invocation
   143  // overriding transaction id and nonce which are by default auto-generated.
   144  // It returns the proposal and the transaction id associated to the proposal
   145  func getInvokeProposalOverride(txid string, cis *pb.ChaincodeInvocationSpec, chainID string, nonce, creator []byte) (*pb.Proposal, string, error) {
   146  	return pbutils.CreateChaincodeProposalWithTxIDNonceAndTransient(txid, common.HeaderType_ENDORSER_TRANSACTION, chainID, cis, nonce, creator, nil)
   147  }
   148  
   149  func getDeployProposal(cds *pb.ChaincodeDeploymentSpec, chainID string, creator []byte) (*pb.Proposal, error) {
   150  	return getDeployOrUpgradeProposal(cds, chainID, creator, false)
   151  }
   152  
   153  func getUpgradeProposal(cds *pb.ChaincodeDeploymentSpec, chainID string, creator []byte) (*pb.Proposal, error) {
   154  	return getDeployOrUpgradeProposal(cds, chainID, creator, true)
   155  }
   156  
   157  //getDeployOrUpgradeProposal gets the proposal for the chaincode deploy or upgrade
   158  //the payload is a ChaincodeDeploymentSpec
   159  func getDeployOrUpgradeProposal(cds *pb.ChaincodeDeploymentSpec, chainID string, creator []byte, upgrade bool) (*pb.Proposal, error) {
   160  	//we need to save off the chaincode as we have to instantiate with nil CodePackage
   161  	var err error
   162  	if err = ccprovider.PutChaincodeIntoFS(cds); err != nil {
   163  		return nil, err
   164  	}
   165  
   166  	cds.CodePackage = nil
   167  
   168  	b, err := proto.Marshal(cds)
   169  	if err != nil {
   170  		return nil, err
   171  	}
   172  
   173  	var propType string
   174  	if upgrade {
   175  		propType = "upgrade"
   176  	} else {
   177  		propType = "deploy"
   178  	}
   179  	sccver := util.GetSysCCVersion()
   180  	//wrap the deployment in an invocation spec to lscc...
   181  	lsccSpec := &pb.ChaincodeInvocationSpec{ChaincodeSpec: &pb.ChaincodeSpec{Type: pb.ChaincodeSpec_GOLANG, ChaincodeId: &pb.ChaincodeID{Name: "lscc", Version: sccver}, Input: &pb.ChaincodeInput{Args: [][]byte{[]byte(propType), []byte(chainID), b}}}}
   182  
   183  	//...and get the proposal for it
   184  	var prop *pb.Proposal
   185  	if prop, _, err = getInvokeProposal(lsccSpec, chainID, creator); err != nil {
   186  		return nil, err
   187  	}
   188  
   189  	return prop, nil
   190  }
   191  
   192  func getSignedProposal(prop *pb.Proposal, signer msp.SigningIdentity) (*pb.SignedProposal, error) {
   193  	propBytes, err := pbutils.GetBytesProposal(prop)
   194  	if err != nil {
   195  		return nil, err
   196  	}
   197  
   198  	signature, err := signer.Sign(propBytes)
   199  	if err != nil {
   200  		return nil, err
   201  	}
   202  
   203  	return &pb.SignedProposal{ProposalBytes: propBytes, Signature: signature}, nil
   204  }
   205  
   206  func getDeploymentSpec(context context.Context, spec *pb.ChaincodeSpec) (*pb.ChaincodeDeploymentSpec, error) {
   207  	codePackageBytes, err := container.GetChaincodePackageBytes(spec)
   208  	if err != nil {
   209  		return nil, err
   210  	}
   211  	chaincodeDeploymentSpec := &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec, CodePackage: codePackageBytes}
   212  	return chaincodeDeploymentSpec, nil
   213  }
   214  
   215  func deploy(endorserServer pb.EndorserServer, chainID string, spec *pb.ChaincodeSpec, f func(*pb.ChaincodeDeploymentSpec)) (*pb.ProposalResponse, *pb.Proposal, error) {
   216  	return deployOrUpgrade(endorserServer, chainID, spec, f, false)
   217  }
   218  
   219  func upgrade(endorserServer pb.EndorserServer, chainID string, spec *pb.ChaincodeSpec, f func(*pb.ChaincodeDeploymentSpec)) (*pb.ProposalResponse, *pb.Proposal, error) {
   220  	return deployOrUpgrade(endorserServer, chainID, spec, f, true)
   221  }
   222  
   223  func deployOrUpgrade(endorserServer pb.EndorserServer, chainID string, spec *pb.ChaincodeSpec, f func(*pb.ChaincodeDeploymentSpec), upgrade bool) (*pb.ProposalResponse, *pb.Proposal, error) {
   224  	var err error
   225  	var depSpec *pb.ChaincodeDeploymentSpec
   226  
   227  	ctxt := context.Background()
   228  	depSpec, err = getDeploymentSpec(ctxt, spec)
   229  	if err != nil {
   230  		return nil, nil, err
   231  	}
   232  
   233  	if f != nil {
   234  		f(depSpec)
   235  	}
   236  
   237  	creator, err := signer.Serialize()
   238  	if err != nil {
   239  		return nil, nil, err
   240  	}
   241  
   242  	var prop *pb.Proposal
   243  	if upgrade {
   244  		prop, err = getUpgradeProposal(depSpec, chainID, creator)
   245  	} else {
   246  		prop, err = getDeployProposal(depSpec, chainID, creator)
   247  	}
   248  	if err != nil {
   249  		return nil, nil, err
   250  	}
   251  
   252  	var signedProp *pb.SignedProposal
   253  	signedProp, err = getSignedProposal(prop, signer)
   254  	if err != nil {
   255  		return nil, nil, err
   256  	}
   257  
   258  	var resp *pb.ProposalResponse
   259  	resp, err = endorserServer.ProcessProposal(context.Background(), signedProp)
   260  
   261  	return resp, prop, err
   262  }
   263  
   264  func invoke(chainID string, spec *pb.ChaincodeSpec) (*pb.Proposal, *pb.ProposalResponse, string, []byte, error) {
   265  	invocation := &pb.ChaincodeInvocationSpec{ChaincodeSpec: spec}
   266  
   267  	creator, err := signer.Serialize()
   268  	if err != nil {
   269  		return nil, nil, "", nil, err
   270  	}
   271  
   272  	var prop *pb.Proposal
   273  	prop, txID, err := getInvokeProposal(invocation, chainID, creator)
   274  	if err != nil {
   275  		return nil, nil, "", nil, fmt.Errorf("Error creating proposal  %s: %s\n", spec.ChaincodeId, err)
   276  	}
   277  
   278  	nonce, err := pbutils.GetNonce(prop)
   279  	if err != nil {
   280  		return nil, nil, "", nil, fmt.Errorf("Failed getting nonce  %s: %s\n", spec.ChaincodeId, err)
   281  	}
   282  
   283  	var signedProp *pb.SignedProposal
   284  	signedProp, err = getSignedProposal(prop, signer)
   285  	if err != nil {
   286  		return nil, nil, "", nil, err
   287  	}
   288  
   289  	resp, err := endorserServer.ProcessProposal(context.Background(), signedProp)
   290  	if err != nil {
   291  		return nil, nil, "", nil, err
   292  	}
   293  
   294  	return prop, resp, txID, nonce, err
   295  }
   296  
   297  func invokeWithOverride(txid string, chainID string, spec *pb.ChaincodeSpec, nonce []byte) (*pb.ProposalResponse, error) {
   298  	invocation := &pb.ChaincodeInvocationSpec{ChaincodeSpec: spec}
   299  
   300  	creator, err := signer.Serialize()
   301  	if err != nil {
   302  		return nil, err
   303  	}
   304  
   305  	var prop *pb.Proposal
   306  	prop, _, err = getInvokeProposalOverride(txid, invocation, chainID, nonce, creator)
   307  	if err != nil {
   308  		return nil, fmt.Errorf("Error creating proposal with override  %s %s: %s\n", txid, spec.ChaincodeId, err)
   309  	}
   310  
   311  	var signedProp *pb.SignedProposal
   312  	signedProp, err = getSignedProposal(prop, signer)
   313  	if err != nil {
   314  		return nil, err
   315  	}
   316  
   317  	resp, err := endorserServer.ProcessProposal(context.Background(), signedProp)
   318  	if err != nil {
   319  		return nil, fmt.Errorf("Error endorsing %s %s: %s\n", txid, spec.ChaincodeId, err)
   320  	}
   321  
   322  	return resp, err
   323  }
   324  
   325  func deleteChaincodeOnDisk(chaincodeID string) {
   326  	os.RemoveAll(filepath.Join(config.GetPath("peer.fileSystemPath"), "chaincodes", chaincodeID))
   327  }
   328  
   329  //begin tests. Note that we rely upon the system chaincode and peer to be created
   330  //once and be used for all the tests. In order to avoid dependencies / collisions
   331  //due to deployed chaincodes, trying to use different chaincodes for different
   332  //tests
   333  
   334  //TestDeploy deploy chaincode example01
   335  func TestDeploy(t *testing.T) {
   336  	chainID := util.GetTestChainID()
   337  	spec := &pb.ChaincodeSpec{Type: 1, ChaincodeId: &pb.ChaincodeID{Name: "ex01", Path: "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example01", Version: "0"}, Input: &pb.ChaincodeInput{Args: [][]byte{[]byte("init"), []byte("a"), []byte("100"), []byte("b"), []byte("200")}}}
   338  	defer deleteChaincodeOnDisk("ex01.0")
   339  
   340  	cccid := ccprovider.NewCCContext(chainID, "ex01", "0", "", false, nil, nil)
   341  
   342  	_, _, err := deploy(endorserServer, chainID, spec, nil)
   343  	if err != nil {
   344  		t.Fail()
   345  		t.Logf("Deploy-error in deploy %s", err)
   346  		chaincode.GetChain().Stop(context.Background(), cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec})
   347  		return
   348  	}
   349  	chaincode.GetChain().Stop(context.Background(), cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec})
   350  }
   351  
   352  //REMOVE WHEN JAVA CC IS ENABLED
   353  func TestJavaDeploy(t *testing.T) {
   354  	chainID := util.GetTestChainID()
   355  	//pretend this is a java CC (type 4)
   356  	spec := &pb.ChaincodeSpec{Type: 4, ChaincodeId: &pb.ChaincodeID{Name: "javacc", Path: "../../examples/chaincode/java/chaincode_example02", Version: "0"}, Input: &pb.ChaincodeInput{Args: [][]byte{[]byte("init"), []byte("a"), []byte("100"), []byte("b"), []byte("200")}}}
   357  	defer deleteChaincodeOnDisk("javacc.0")
   358  
   359  	cccid := ccprovider.NewCCContext(chainID, "javacc", "0", "", false, nil, nil)
   360  
   361  	_, _, err := deploy(endorserServer, chainID, spec, nil)
   362  	if err == nil {
   363  		t.Fail()
   364  		t.Logf("expected java CC deploy to fail")
   365  		chaincode.GetChain().Stop(context.Background(), cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec})
   366  		return
   367  	}
   368  	chaincode.GetChain().Stop(context.Background(), cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec})
   369  }
   370  
   371  func TestJavaCheckWithDifferentPackageTypes(t *testing.T) {
   372  	//try SignedChaincodeDeploymentSpec with go chaincode (type 1)
   373  	spec := &pb.ChaincodeSpec{Type: 1, ChaincodeId: &pb.ChaincodeID{Name: "gocc", Path: "path/to/cc", Version: "0"}, Input: &pb.ChaincodeInput{Args: [][]byte{[]byte("someargs")}}}
   374  	cds := &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec, CodePackage: []byte("some code")}
   375  	env := &common.Envelope{Payload: pbutils.MarshalOrPanic(&common.Payload{Data: pbutils.MarshalOrPanic(&pb.SignedChaincodeDeploymentSpec{ChaincodeDeploymentSpec: pbutils.MarshalOrPanic(cds)})})}
   376  	//wrap the package in an invocation spec to lscc...
   377  	b := pbutils.MarshalOrPanic(env)
   378  
   379  	lsccCID := &pb.ChaincodeID{Name: "lscc", Version: util.GetSysCCVersion()}
   380  	lsccSpec := &pb.ChaincodeInvocationSpec{ChaincodeSpec: &pb.ChaincodeSpec{Type: pb.ChaincodeSpec_GOLANG, ChaincodeId: lsccCID, Input: &pb.ChaincodeInput{Args: [][]byte{[]byte("install"), b}}}}
   381  
   382  	e := &Endorser{}
   383  	err := e.disableJavaCCInst(lsccCID, lsccSpec)
   384  	assert.Nil(t, err)
   385  
   386  	//now try plain ChaincodeDeploymentSpec...should succeed (go chaincode)
   387  	b = pbutils.MarshalOrPanic(cds)
   388  
   389  	lsccSpec = &pb.ChaincodeInvocationSpec{ChaincodeSpec: &pb.ChaincodeSpec{Type: pb.ChaincodeSpec_GOLANG, ChaincodeId: lsccCID, Input: &pb.ChaincodeInput{Args: [][]byte{[]byte("install"), b}}}}
   390  	err = e.disableJavaCCInst(lsccCID, lsccSpec)
   391  	assert.Nil(t, err)
   392  }
   393  
   394  //TestRedeploy - deploy two times, second time should fail but example02 should remain deployed
   395  func TestRedeploy(t *testing.T) {
   396  	chainID := util.GetTestChainID()
   397  
   398  	//invalid arguments
   399  	spec := &pb.ChaincodeSpec{Type: 1, ChaincodeId: &pb.ChaincodeID{Name: "ex02", Path: "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02", Version: "0"}, Input: &pb.ChaincodeInput{Args: [][]byte{[]byte("init"), []byte("a"), []byte("100"), []byte("b"), []byte("200")}}}
   400  
   401  	defer deleteChaincodeOnDisk("ex02.0")
   402  
   403  	cccid := ccprovider.NewCCContext(chainID, "ex02", "0", "", false, nil, nil)
   404  
   405  	_, _, err := deploy(endorserServer, chainID, spec, nil)
   406  	if err != nil {
   407  		t.Fail()
   408  		t.Logf("error in endorserServer.ProcessProposal %s", err)
   409  		chaincode.GetChain().Stop(context.Background(), cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec})
   410  		return
   411  	}
   412  
   413  	deleteChaincodeOnDisk("ex02.0")
   414  
   415  	//second time should not fail as we are just simulating
   416  	_, _, err = deploy(endorserServer, chainID, spec, nil)
   417  	if err != nil {
   418  		t.Fail()
   419  		t.Logf("error in endorserServer.ProcessProposal %s", err)
   420  		chaincode.GetChain().Stop(context.Background(), cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec})
   421  		return
   422  	}
   423  	chaincode.GetChain().Stop(context.Background(), cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec})
   424  }
   425  
   426  // TestDeployAndInvoke deploys and invokes chaincode_example01
   427  func TestDeployAndInvoke(t *testing.T) {
   428  	chainID := util.GetTestChainID()
   429  	var ctxt = context.Background()
   430  
   431  	url := "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example01"
   432  	chaincodeID := &pb.ChaincodeID{Path: url, Name: "ex01", Version: "0"}
   433  
   434  	defer deleteChaincodeOnDisk("ex01.0")
   435  
   436  	args := []string{"10"}
   437  
   438  	f := "init"
   439  	argsDeploy := util.ToChaincodeArgs(f, "a", "100", "b", "200")
   440  	spec := &pb.ChaincodeSpec{Type: 1, ChaincodeId: chaincodeID, Input: &pb.ChaincodeInput{Args: argsDeploy}}
   441  
   442  	cccid := ccprovider.NewCCContext(chainID, "ex01", "0", "", false, nil, nil)
   443  
   444  	resp, prop, err := deploy(endorserServer, chainID, spec, nil)
   445  	chaincodeID1 := spec.ChaincodeId.Name
   446  	if err != nil {
   447  		t.Fail()
   448  		t.Logf("Error deploying <%s>: %s", chaincodeID1, err)
   449  		chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}})
   450  		return
   451  	}
   452  	var nextBlockNumber uint64 = 1 // first block needs to be block number = 1. Genesis block is block 0
   453  	err = endorserServer.(*Endorser).commitTxSimulation(prop, chainID, signer, resp, nextBlockNumber)
   454  	if err != nil {
   455  		t.Fail()
   456  		t.Logf("Error committing deploy <%s>: %s", chaincodeID1, err)
   457  		chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}})
   458  		return
   459  	}
   460  
   461  	f = "invoke"
   462  	invokeArgs := append([]string{f}, args...)
   463  	spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: chaincodeID, Input: &pb.ChaincodeInput{Args: util.ToChaincodeArgs(invokeArgs...)}}
   464  	prop, resp, txid, nonce, err := invoke(chainID, spec)
   465  	if err != nil {
   466  		t.Fail()
   467  		t.Logf("Error invoking transaction: %s", err)
   468  		chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}})
   469  		return
   470  	}
   471  	// Commit invoke
   472  	nextBlockNumber++
   473  	err = endorserServer.(*Endorser).commitTxSimulation(prop, chainID, signer, resp, nextBlockNumber)
   474  	if err != nil {
   475  		t.Fail()
   476  		t.Logf("Error committing first invoke <%s>: %s", chaincodeID1, err)
   477  		chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}})
   478  		return
   479  	}
   480  
   481  	// Now test for an invalid TxID
   482  	f = "invoke"
   483  	invokeArgs = append([]string{f}, args...)
   484  	spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: chaincodeID, Input: &pb.ChaincodeInput{Args: util.ToChaincodeArgs(invokeArgs...)}}
   485  	_, err = invokeWithOverride("invalid_tx_id", chainID, spec, nonce)
   486  	if err == nil {
   487  		t.Fail()
   488  		t.Log("Replay attack protection faild. Transaction with invalid txid passed")
   489  		chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}})
   490  		return
   491  	}
   492  
   493  	// Now test for duplicated TxID
   494  	f = "invoke"
   495  	invokeArgs = append([]string{f}, args...)
   496  	spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: chaincodeID, Input: &pb.ChaincodeInput{Args: util.ToChaincodeArgs(invokeArgs...)}}
   497  	_, err = invokeWithOverride(txid, chainID, spec, nonce)
   498  	if err == nil {
   499  		t.Fail()
   500  		t.Log("Replay attack protection faild. Transaction with duplicaged txid passed")
   501  		chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}})
   502  		return
   503  	}
   504  
   505  	// Test chaincode endorsement failure when invalid function name supplied
   506  	f = "invokeinvalid"
   507  	invokeArgs = append([]string{f}, args...)
   508  	spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: chaincodeID, Input: &pb.ChaincodeInput{Args: util.ToChaincodeArgs(invokeArgs...)}}
   509  	prop, resp, txid, nonce, err = invoke(chainID, spec)
   510  	if err == nil {
   511  		t.Fail()
   512  		t.Logf("expecting fabric to report error from chaincode failure")
   513  		chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}})
   514  		return
   515  	} else if _, ok := err.(*chaincodeError); !ok {
   516  		t.Fail()
   517  		t.Logf("expecting chaincode error but found %v", err)
   518  		chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}})
   519  		return
   520  	}
   521  
   522  	if resp != nil {
   523  		assert.Equal(t, int32(500), resp.Response.Status, "Unexpected response status")
   524  	}
   525  
   526  	t.Logf("Invoke test passed")
   527  
   528  	chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}})
   529  }
   530  
   531  // TestUpgradeAndInvoke deploys chaincode_example01, upgrade it with chaincode_example02, then invoke it
   532  func TestDeployAndUpgrade(t *testing.T) {
   533  	chainID := util.GetTestChainID()
   534  	var ctxt = context.Background()
   535  
   536  	url1 := "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example01"
   537  	url2 := "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02"
   538  	chaincodeID1 := &pb.ChaincodeID{Path: url1, Name: "upgradeex01", Version: "0"}
   539  	chaincodeID2 := &pb.ChaincodeID{Path: url2, Name: "upgradeex01", Version: "1"}
   540  
   541  	defer deleteChaincodeOnDisk("upgradeex01.0")
   542  	defer deleteChaincodeOnDisk("upgradeex01.1")
   543  
   544  	f := "init"
   545  	argsDeploy := util.ToChaincodeArgs(f, "a", "100", "b", "200")
   546  	spec := &pb.ChaincodeSpec{Type: 1, ChaincodeId: chaincodeID1, Input: &pb.ChaincodeInput{Args: argsDeploy}}
   547  
   548  	cccid1 := ccprovider.NewCCContext(chainID, "upgradeex01", "0", "", false, nil, nil)
   549  	cccid2 := ccprovider.NewCCContext(chainID, "upgradeex01", "1", "", false, nil, nil)
   550  
   551  	resp, prop, err := deploy(endorserServer, chainID, spec, nil)
   552  
   553  	chaincodeName := spec.ChaincodeId.Name
   554  	if err != nil {
   555  		t.Fail()
   556  		chaincode.GetChain().Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID1}})
   557  		chaincode.GetChain().Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID2}})
   558  		t.Logf("Error deploying <%s>: %s", chaincodeName, err)
   559  		return
   560  	}
   561  
   562  	var nextBlockNumber uint64 = 3 // something above created block 0
   563  	err = endorserServer.(*Endorser).commitTxSimulation(prop, chainID, signer, resp, nextBlockNumber)
   564  	if err != nil {
   565  		t.Fail()
   566  		chaincode.GetChain().Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID1}})
   567  		chaincode.GetChain().Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID2}})
   568  		t.Logf("Error committing <%s>: %s", chaincodeName, err)
   569  		return
   570  	}
   571  
   572  	argsUpgrade := util.ToChaincodeArgs(f, "a", "150", "b", "300")
   573  	spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: chaincodeID2, Input: &pb.ChaincodeInput{Args: argsUpgrade}}
   574  	_, _, err = upgrade(endorserServer, chainID, spec, nil)
   575  	if err != nil {
   576  		t.Fail()
   577  		chaincode.GetChain().Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID1}})
   578  		chaincode.GetChain().Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID2}})
   579  		t.Logf("Error upgrading <%s>: %s", chaincodeName, err)
   580  		return
   581  	}
   582  
   583  	t.Logf("Upgrade test passed")
   584  
   585  	chaincode.GetChain().Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID1}})
   586  	chaincode.GetChain().Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID2}})
   587  }
   588  
   589  // TestWritersACLFail deploys a chaincode and then tries to invoke it;
   590  // however we inject a special policy for writers to simulate
   591  // the scenario in which the creator of this proposal is not among
   592  // the writers for the chain
   593  func TestWritersACLFail(t *testing.T) {
   594  	//skip pending FAB-2457 fix
   595  	t.Skip()
   596  	chainID := util.GetTestChainID()
   597  	var ctxt = context.Background()
   598  
   599  	url := "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example01"
   600  	chaincodeID := &pb.ChaincodeID{Path: url, Name: "ex01-fail", Version: "0"}
   601  
   602  	defer deleteChaincodeOnDisk("ex01-fail.0")
   603  
   604  	args := []string{"10"}
   605  
   606  	f := "init"
   607  	argsDeploy := util.ToChaincodeArgs(f, "a", "100", "b", "200")
   608  	spec := &pb.ChaincodeSpec{Type: 1, ChaincodeId: chaincodeID, Input: &pb.ChaincodeInput{Args: argsDeploy}}
   609  
   610  	cccid := ccprovider.NewCCContext(chainID, "ex01-fail", "0", "", false, nil, nil)
   611  
   612  	resp, prop, err := deploy(endorserServer, chainID, spec, nil)
   613  	chaincodeID1 := spec.ChaincodeId.Name
   614  	if err != nil {
   615  		t.Fail()
   616  		t.Logf("Error deploying <%s>: %s", chaincodeID1, err)
   617  		chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}})
   618  		return
   619  	}
   620  	var nextBlockNumber uint64 = 3 // The tests that ran before this test created blocks 0-2
   621  	err = endorserServer.(*Endorser).commitTxSimulation(prop, chainID, signer, resp, nextBlockNumber)
   622  	if err != nil {
   623  		t.Fail()
   624  		t.Logf("Error committing deploy <%s>: %s", chaincodeID1, err)
   625  		chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}})
   626  		return
   627  	}
   628  
   629  	// here we inject a reject policy for writers
   630  	// to simulate the scenario in which the invoker
   631  	// is not authorized to issue this proposal
   632  	rejectpolicy := &mockpolicies.Policy{
   633  		Err: errors.New("The creator of this proposal does not fulfil the writers policy of this chain"),
   634  	}
   635  	pm := peer.GetPolicyManager(chainID)
   636  	pm.(*mockpolicies.Manager).PolicyMap = map[string]policies.Policy{policies.ChannelApplicationWriters: rejectpolicy}
   637  
   638  	f = "invoke"
   639  	invokeArgs := append([]string{f}, args...)
   640  	spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: chaincodeID, Input: &pb.ChaincodeInput{Args: util.ToChaincodeArgs(invokeArgs...)}}
   641  	prop, resp, _, _, err = invoke(chainID, spec)
   642  	if err == nil {
   643  		t.Fail()
   644  		t.Logf("Invocation should have failed")
   645  		chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}})
   646  		return
   647  	}
   648  
   649  	t.Logf("TestWritersACLFail passed")
   650  
   651  	chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}})
   652  }
   653  
   654  func TestHeaderExtensionNoChaincodeID(t *testing.T) {
   655  	creator, _ := signer.Serialize()
   656  	nonce := []byte{1, 2, 3}
   657  	digest, err := factory.GetDefault().Hash(append(nonce, creator...), &bccsp.SHA256Opts{})
   658  	txID := hex.EncodeToString(digest)
   659  	spec := &pb.ChaincodeSpec{Type: 1, ChaincodeId: nil, Input: &pb.ChaincodeInput{Args: util.ToChaincodeArgs()}}
   660  	invocation := &pb.ChaincodeInvocationSpec{ChaincodeSpec: spec}
   661  	prop, _, _ := pbutils.CreateChaincodeProposalWithTxIDNonceAndTransient(txID, common.HeaderType_ENDORSER_TRANSACTION, util.GetTestChainID(), invocation, []byte{1, 2, 3}, creator, nil)
   662  	signedProp, _ := getSignedProposal(prop, signer)
   663  	_, err = endorserServer.ProcessProposal(context.Background(), signedProp)
   664  	assert.Error(t, err)
   665  	assert.Contains(t, err.Error(), "ChaincodeHeaderExtension.ChaincodeId is nil")
   666  }
   667  
   668  // TestAdminACLFail deploys tried to deploy a chaincode;
   669  // however we inject a special policy for admins to simulate
   670  // the scenario in which the creator of this proposal is not among
   671  // the admins for the chain
   672  func TestAdminACLFail(t *testing.T) {
   673  	//skip pending FAB-2457 fix
   674  	t.Skip()
   675  	chainID := util.GetTestChainID()
   676  
   677  	// here we inject a reject policy for admins
   678  	// to simulate the scenario in which the invoker
   679  	// is not authorized to issue this proposal
   680  	rejectpolicy := &mockpolicies.Policy{
   681  		Err: errors.New("The creator of this proposal does not fulfil the writers policy of this chain"),
   682  	}
   683  	pm := peer.GetPolicyManager(chainID)
   684  	pm.(*mockpolicies.Manager).PolicyMap = map[string]policies.Policy{policies.ChannelApplicationAdmins: rejectpolicy}
   685  
   686  	var ctxt = context.Background()
   687  
   688  	url := "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example01"
   689  	chaincodeID := &pb.ChaincodeID{Path: url, Name: "ex01-fail1", Version: "0"}
   690  
   691  	defer deleteChaincodeOnDisk("ex01-fail1.0")
   692  
   693  	f := "init"
   694  	argsDeploy := util.ToChaincodeArgs(f, "a", "100", "b", "200")
   695  	spec := &pb.ChaincodeSpec{Type: 1, ChaincodeId: chaincodeID, Input: &pb.ChaincodeInput{Args: argsDeploy}}
   696  
   697  	cccid := ccprovider.NewCCContext(chainID, "ex01-fail1", "0", "", false, nil, nil)
   698  
   699  	_, _, err := deploy(endorserServer, chainID, spec, nil)
   700  	if err == nil {
   701  		t.Fail()
   702  		t.Logf("Deploying chaincode should have failed!")
   703  		chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}})
   704  		return
   705  	}
   706  
   707  	t.Logf("TestATestAdminACLFailCLFail passed")
   708  
   709  	chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}})
   710  }
   711  
   712  // TestInvokeSccFail makes sure that invoking a system chaincode fails
   713  func TestInvokeSccFail(t *testing.T) {
   714  	chainID := util.GetTestChainID()
   715  
   716  	chaincodeID := &pb.ChaincodeID{Name: "escc"}
   717  	args := util.ToChaincodeArgs("someFunc", "someArg")
   718  	spec := &pb.ChaincodeSpec{Type: 1, ChaincodeId: chaincodeID, Input: &pb.ChaincodeInput{Args: args}}
   719  	_, _, _, _, err := invoke(chainID, spec)
   720  	if err == nil {
   721  		t.Logf("Invoking escc should have failed!")
   722  		t.Fail()
   723  		return
   724  	}
   725  }
   726  
   727  func newTempDir() string {
   728  	tempDir, err := ioutil.TempDir("", "fabric-")
   729  	if err != nil {
   730  		panic(err)
   731  	}
   732  	return tempDir
   733  }
   734  
   735  func TestMain(m *testing.M) {
   736  	setupTestConfig()
   737  
   738  	chainID := util.GetTestChainID()
   739  	tev, err := initPeer(chainID)
   740  	if err != nil {
   741  		os.Exit(-1)
   742  		fmt.Printf("Could not initialize tests")
   743  		finitPeer(tev)
   744  		return
   745  	}
   746  
   747  	endorserServer = NewEndorserServer()
   748  
   749  	// setup the MSP manager so that we can sign/verify
   750  	err = msptesttools.LoadMSPSetupForTesting()
   751  	if err != nil {
   752  		fmt.Printf("Could not initialize msp/signer, err %s", err)
   753  		finitPeer(tev)
   754  		os.Exit(-1)
   755  		return
   756  	}
   757  	signer, err = mspmgmt.GetLocalMSP().GetDefaultSigningIdentity()
   758  	if err != nil {
   759  		fmt.Printf("Could not initialize msp/signer")
   760  		finitPeer(tev)
   761  		os.Exit(-1)
   762  		return
   763  	}
   764  
   765  	retVal := m.Run()
   766  
   767  	finitPeer(tev)
   768  
   769  	os.Exit(retVal)
   770  }
   771  
   772  func setupTestConfig() {
   773  	flag.Parse()
   774  
   775  	// Now set the configuration file
   776  	viper.SetEnvPrefix("CORE")
   777  	viper.AutomaticEnv()
   778  	replacer := strings.NewReplacer(".", "_")
   779  	viper.SetEnvKeyReplacer(replacer)
   780  	viper.SetConfigName("endorser_test") // name of config file (without extension)
   781  	viper.AddConfigPath("./")            // path to look for the config file in
   782  	err := viper.ReadInConfig()          // Find and read the config file
   783  	if err != nil {                      // Handle errors reading the config file
   784  		panic(fmt.Errorf("Fatal error config file: %s \n", err))
   785  	}
   786  
   787  	testutil.SetupTestLogging()
   788  
   789  	// Set the number of maxprocs
   790  	runtime.GOMAXPROCS(viper.GetInt("peer.gomaxprocs"))
   791  
   792  	// Init the BCCSP
   793  	var bccspConfig *factory.FactoryOpts
   794  	err = viper.UnmarshalKey("peer.BCCSP", &bccspConfig)
   795  	if err != nil {
   796  		bccspConfig = nil
   797  	}
   798  
   799  	msp.SetupBCCSPKeystoreConfig(bccspConfig, viper.GetString("peer.mspConfigPath")+"/keystore")
   800  
   801  	err = factory.InitFactories(bccspConfig)
   802  	if err != nil {
   803  		panic(fmt.Errorf("Could not initialize BCCSP Factories [%s]", err))
   804  	}
   805  }