github.com/inklabsfoundation/inkchain@v0.17.1-0.20181025012015-c3cef8062f19/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/inklabsfoundation/inkchain/bccsp"
    35  	"github.com/inklabsfoundation/inkchain/bccsp/factory"
    36  	mockpolicies "github.com/inklabsfoundation/inkchain/common/mocks/policies"
    37  	"github.com/inklabsfoundation/inkchain/common/policies"
    38  	"github.com/inklabsfoundation/inkchain/common/util"
    39  	"github.com/inklabsfoundation/inkchain/core/chaincode"
    40  	"github.com/inklabsfoundation/inkchain/core/common/ccprovider"
    41  	"github.com/inklabsfoundation/inkchain/core/config"
    42  	"github.com/inklabsfoundation/inkchain/core/container"
    43  	"github.com/inklabsfoundation/inkchain/core/peer"
    44  	syscc "github.com/inklabsfoundation/inkchain/core/scc"
    45  	"github.com/inklabsfoundation/inkchain/core/testutil"
    46  	"github.com/inklabsfoundation/inkchain/msp"
    47  	mspmgmt "github.com/inklabsfoundation/inkchain/msp/mgmt"
    48  	"github.com/inklabsfoundation/inkchain/msp/mgmt/testtools"
    49  	"github.com/inklabsfoundation/inkchain/protos/common"
    50  	pb "github.com/inklabsfoundation/inkchain/protos/peer"
    51  	pbutils "github.com/inklabsfoundation/inkchain/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, "inkchain", "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/inklabsfoundation/inkchain/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  //TestRedeploy - deploy two times, second time should fail but example02 should remain deployed
   372  func TestRedeploy(t *testing.T) {
   373  	chainID := util.GetTestChainID()
   374  
   375  	//invalid arguments
   376  	spec := &pb.ChaincodeSpec{Type: 1, ChaincodeId: &pb.ChaincodeID{Name: "ex02", Path: "github.com/inklabsfoundation/inkchain/examples/chaincode/go/chaincode_example02", Version: "0"}, Input: &pb.ChaincodeInput{Args: [][]byte{[]byte("init"), []byte("a"), []byte("100"), []byte("b"), []byte("200")}}}
   377  
   378  	defer deleteChaincodeOnDisk("ex02.0")
   379  
   380  	cccid := ccprovider.NewCCContext(chainID, "ex02", "0", "", false, nil, nil)
   381  
   382  	_, _, err := deploy(endorserServer, chainID, spec, nil)
   383  	if err != nil {
   384  		t.Fail()
   385  		t.Logf("error in endorserServer.ProcessProposal %s", err)
   386  		chaincode.GetChain().Stop(context.Background(), cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec})
   387  		return
   388  	}
   389  
   390  	deleteChaincodeOnDisk("ex02.0")
   391  
   392  	//second time should not fail as we are just simulating
   393  	_, _, err = deploy(endorserServer, chainID, spec, nil)
   394  	if err != nil {
   395  		t.Fail()
   396  		t.Logf("error in endorserServer.ProcessProposal %s", err)
   397  		chaincode.GetChain().Stop(context.Background(), cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec})
   398  		return
   399  	}
   400  	chaincode.GetChain().Stop(context.Background(), cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec})
   401  }
   402  
   403  // TestDeployAndInvoke deploys and invokes chaincode_example01
   404  func TestDeployAndInvoke(t *testing.T) {
   405  	chainID := util.GetTestChainID()
   406  	var ctxt = context.Background()
   407  
   408  	url := "github.com/inklabsfoundation/inkchain/examples/chaincode/go/chaincode_example01"
   409  	chaincodeID := &pb.ChaincodeID{Path: url, Name: "ex01", Version: "0"}
   410  
   411  	defer deleteChaincodeOnDisk("ex01.0")
   412  
   413  	args := []string{"10"}
   414  
   415  	f := "init"
   416  	argsDeploy := util.ToChaincodeArgs(f, "a", "100", "b", "200")
   417  	spec := &pb.ChaincodeSpec{Type: 1, ChaincodeId: chaincodeID, Input: &pb.ChaincodeInput{Args: argsDeploy}}
   418  
   419  	cccid := ccprovider.NewCCContext(chainID, "ex01", "0", "", false, nil, nil)
   420  
   421  	resp, prop, err := deploy(endorserServer, chainID, spec, nil)
   422  	chaincodeID1 := spec.ChaincodeId.Name
   423  	if err != nil {
   424  		t.Fail()
   425  		t.Logf("Error deploying <%s>: %s", chaincodeID1, err)
   426  		chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}})
   427  		return
   428  	}
   429  	var nextBlockNumber uint64 = 1 // first block needs to be block number = 1. Genesis block is block 0
   430  	err = endorserServer.(*Endorser).commitTxSimulation(prop, chainID, signer, resp, nextBlockNumber)
   431  	if err != nil {
   432  		t.Fail()
   433  		t.Logf("Error committing deploy <%s>: %s", chaincodeID1, err)
   434  		chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}})
   435  		return
   436  	}
   437  
   438  	f = "invoke"
   439  	invokeArgs := append([]string{f}, args...)
   440  	spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: chaincodeID, Input: &pb.ChaincodeInput{Args: util.ToChaincodeArgs(invokeArgs...)}}
   441  	prop, resp, txid, nonce, err := invoke(chainID, spec)
   442  	if err != nil {
   443  		t.Fail()
   444  		t.Logf("Error invoking transaction: %s", err)
   445  		chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}})
   446  		return
   447  	}
   448  	// Commit invoke
   449  	nextBlockNumber++
   450  	err = endorserServer.(*Endorser).commitTxSimulation(prop, chainID, signer, resp, nextBlockNumber)
   451  	if err != nil {
   452  		t.Fail()
   453  		t.Logf("Error committing first invoke <%s>: %s", chaincodeID1, err)
   454  		chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}})
   455  		return
   456  	}
   457  
   458  	// Now test for an invalid TxID
   459  	f = "invoke"
   460  	invokeArgs = append([]string{f}, args...)
   461  	spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: chaincodeID, Input: &pb.ChaincodeInput{Args: util.ToChaincodeArgs(invokeArgs...)}}
   462  	_, err = invokeWithOverride("invalid_tx_id", chainID, spec, nonce)
   463  	if err == nil {
   464  		t.Fail()
   465  		t.Log("Replay attack protection faild. Transaction with invalid txid passed")
   466  		chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}})
   467  		return
   468  	}
   469  
   470  	// Now test for duplicated TxID
   471  	f = "invoke"
   472  	invokeArgs = append([]string{f}, args...)
   473  	spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: chaincodeID, Input: &pb.ChaincodeInput{Args: util.ToChaincodeArgs(invokeArgs...)}}
   474  	_, err = invokeWithOverride(txid, chainID, spec, nonce)
   475  	if err == nil {
   476  		t.Fail()
   477  		t.Log("Replay attack protection faild. Transaction with duplicaged txid passed")
   478  		chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}})
   479  		return
   480  	}
   481  
   482  	// Test chaincode endorsement failure when invalid function name supplied
   483  	f = "invokeinvalid"
   484  	invokeArgs = append([]string{f}, args...)
   485  	spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: chaincodeID, Input: &pb.ChaincodeInput{Args: util.ToChaincodeArgs(invokeArgs...)}}
   486  	prop, resp, txid, nonce, err = invoke(chainID, spec)
   487  	if err == nil {
   488  		t.Fail()
   489  		t.Logf("expecting inkchain to report error from chaincode failure")
   490  		chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}})
   491  		return
   492  	} else if _, ok := err.(*chaincodeError); !ok {
   493  		t.Fail()
   494  		t.Logf("expecting chaincode error but found %v", err)
   495  		chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}})
   496  		return
   497  	}
   498  
   499  	if resp != nil {
   500  		assert.Equal(t, int32(500), resp.Response.Status, "Unexpected response status")
   501  	}
   502  
   503  	t.Logf("Invoke test passed")
   504  
   505  	chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}})
   506  }
   507  
   508  // TestUpgradeAndInvoke deploys chaincode_example01, upgrade it with chaincode_example02, then invoke it
   509  func TestDeployAndUpgrade(t *testing.T) {
   510  	chainID := util.GetTestChainID()
   511  	var ctxt = context.Background()
   512  
   513  	url1 := "github.com/inklabsfoundation/inkchain/examples/chaincode/go/chaincode_example01"
   514  	url2 := "github.com/inklabsfoundation/inkchain/examples/chaincode/go/chaincode_example02"
   515  	chaincodeID1 := &pb.ChaincodeID{Path: url1, Name: "upgradeex01", Version: "0"}
   516  	chaincodeID2 := &pb.ChaincodeID{Path: url2, Name: "upgradeex01", Version: "1"}
   517  
   518  	defer deleteChaincodeOnDisk("upgradeex01.0")
   519  	defer deleteChaincodeOnDisk("upgradeex01.1")
   520  
   521  	f := "init"
   522  	argsDeploy := util.ToChaincodeArgs(f, "a", "100", "b", "200")
   523  	spec := &pb.ChaincodeSpec{Type: 1, ChaincodeId: chaincodeID1, Input: &pb.ChaincodeInput{Args: argsDeploy}}
   524  
   525  	cccid1 := ccprovider.NewCCContext(chainID, "upgradeex01", "0", "", false, nil, nil)
   526  	cccid2 := ccprovider.NewCCContext(chainID, "upgradeex01", "1", "", false, nil, nil)
   527  
   528  	resp, prop, err := deploy(endorserServer, chainID, spec, nil)
   529  
   530  	chaincodeName := spec.ChaincodeId.Name
   531  	if err != nil {
   532  		t.Fail()
   533  		chaincode.GetChain().Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID1}})
   534  		chaincode.GetChain().Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID2}})
   535  		t.Logf("Error deploying <%s>: %s", chaincodeName, err)
   536  		return
   537  	}
   538  
   539  	var nextBlockNumber uint64 = 3 // something above created block 0
   540  	err = endorserServer.(*Endorser).commitTxSimulation(prop, chainID, signer, resp, nextBlockNumber)
   541  	if err != nil {
   542  		t.Fail()
   543  		chaincode.GetChain().Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID1}})
   544  		chaincode.GetChain().Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID2}})
   545  		t.Logf("Error committing <%s>: %s", chaincodeName, err)
   546  		return
   547  	}
   548  
   549  	argsUpgrade := util.ToChaincodeArgs(f, "a", "150", "b", "300")
   550  	spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: chaincodeID2, Input: &pb.ChaincodeInput{Args: argsUpgrade}}
   551  	_, _, err = upgrade(endorserServer, chainID, spec, nil)
   552  	if err != nil {
   553  		t.Fail()
   554  		chaincode.GetChain().Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID1}})
   555  		chaincode.GetChain().Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID2}})
   556  		t.Logf("Error upgrading <%s>: %s", chaincodeName, err)
   557  		return
   558  	}
   559  
   560  	t.Logf("Upgrade test passed")
   561  
   562  	chaincode.GetChain().Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID1}})
   563  	chaincode.GetChain().Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID2}})
   564  }
   565  
   566  // TestWritersACLFail deploys a chaincode and then tries to invoke it;
   567  // however we inject a special policy for writers to simulate
   568  // the scenario in which the creator of this proposal is not among
   569  // the writers for the chain
   570  func TestWritersACLFail(t *testing.T) {
   571  	//skip pending FAB-2457 fix
   572  	t.Skip()
   573  	chainID := util.GetTestChainID()
   574  	var ctxt = context.Background()
   575  
   576  	url := "github.com/inklabsfoundation/inkchain/examples/chaincode/go/chaincode_example01"
   577  	chaincodeID := &pb.ChaincodeID{Path: url, Name: "ex01-fail", Version: "0"}
   578  
   579  	defer deleteChaincodeOnDisk("ex01-fail.0")
   580  
   581  	args := []string{"10"}
   582  
   583  	f := "init"
   584  	argsDeploy := util.ToChaincodeArgs(f, "a", "100", "b", "200")
   585  	spec := &pb.ChaincodeSpec{Type: 1, ChaincodeId: chaincodeID, Input: &pb.ChaincodeInput{Args: argsDeploy}}
   586  
   587  	cccid := ccprovider.NewCCContext(chainID, "ex01-fail", "0", "", false, nil, nil)
   588  
   589  	resp, prop, err := deploy(endorserServer, chainID, spec, nil)
   590  	chaincodeID1 := spec.ChaincodeId.Name
   591  	if err != nil {
   592  		t.Fail()
   593  		t.Logf("Error deploying <%s>: %s", chaincodeID1, err)
   594  		chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}})
   595  		return
   596  	}
   597  	var nextBlockNumber uint64 = 3 // The tests that ran before this test created blocks 0-2
   598  	err = endorserServer.(*Endorser).commitTxSimulation(prop, chainID, signer, resp, nextBlockNumber)
   599  	if err != nil {
   600  		t.Fail()
   601  		t.Logf("Error committing deploy <%s>: %s", chaincodeID1, err)
   602  		chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}})
   603  		return
   604  	}
   605  
   606  	// here we inject a reject policy for writers
   607  	// to simulate the scenario in which the invoker
   608  	// is not authorized to issue this proposal
   609  	rejectpolicy := &mockpolicies.Policy{
   610  		Err: errors.New("The creator of this proposal does not fulfil the writers policy of this chain"),
   611  	}
   612  	pm := peer.GetPolicyManager(chainID)
   613  	pm.(*mockpolicies.Manager).PolicyMap = map[string]policies.Policy{policies.ChannelApplicationWriters: rejectpolicy}
   614  
   615  	f = "invoke"
   616  	invokeArgs := append([]string{f}, args...)
   617  	spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: chaincodeID, Input: &pb.ChaincodeInput{Args: util.ToChaincodeArgs(invokeArgs...)}}
   618  	prop, resp, _, _, err = invoke(chainID, spec)
   619  	if err == nil {
   620  		t.Fail()
   621  		t.Logf("Invocation should have failed")
   622  		chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}})
   623  		return
   624  	}
   625  
   626  	t.Logf("TestWritersACLFail passed")
   627  
   628  	chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}})
   629  }
   630  
   631  func TestHeaderExtensionNoChaincodeID(t *testing.T) {
   632  	creator, _ := signer.Serialize()
   633  	nonce := []byte{1, 2, 3}
   634  	digest, err := factory.GetDefault().Hash(append(nonce, creator...), &bccsp.SHA256Opts{})
   635  	txID := hex.EncodeToString(digest)
   636  	spec := &pb.ChaincodeSpec{Type: 1, ChaincodeId: nil, Input: &pb.ChaincodeInput{Args: util.ToChaincodeArgs()}}
   637  	invocation := &pb.ChaincodeInvocationSpec{ChaincodeSpec: spec}
   638  	prop, _, _ := pbutils.CreateChaincodeProposalWithTxIDNonceAndTransient(txID, common.HeaderType_ENDORSER_TRANSACTION, util.GetTestChainID(), invocation, []byte{1, 2, 3}, creator, nil)
   639  	signedProp, _ := getSignedProposal(prop, signer)
   640  	_, err = endorserServer.ProcessProposal(context.Background(), signedProp)
   641  	assert.Error(t, err)
   642  	assert.Contains(t, err.Error(), "ChaincodeHeaderExtension.ChaincodeId is nil")
   643  }
   644  
   645  // TestAdminACLFail deploys tried to deploy a chaincode;
   646  // however we inject a special policy for admins to simulate
   647  // the scenario in which the creator of this proposal is not among
   648  // the admins for the chain
   649  func TestAdminACLFail(t *testing.T) {
   650  	//skip pending FAB-2457 fix
   651  	t.Skip()
   652  	chainID := util.GetTestChainID()
   653  
   654  	// here we inject a reject policy for admins
   655  	// to simulate the scenario in which the invoker
   656  	// is not authorized to issue this proposal
   657  	rejectpolicy := &mockpolicies.Policy{
   658  		Err: errors.New("The creator of this proposal does not fulfil the writers policy of this chain"),
   659  	}
   660  	pm := peer.GetPolicyManager(chainID)
   661  	pm.(*mockpolicies.Manager).PolicyMap = map[string]policies.Policy{policies.ChannelApplicationAdmins: rejectpolicy}
   662  
   663  	var ctxt = context.Background()
   664  
   665  	url := "github.com/inklabsfoundation/inkchain/examples/chaincode/go/chaincode_example01"
   666  	chaincodeID := &pb.ChaincodeID{Path: url, Name: "ex01-fail1", Version: "0"}
   667  
   668  	defer deleteChaincodeOnDisk("ex01-fail1.0")
   669  
   670  	f := "init"
   671  	argsDeploy := util.ToChaincodeArgs(f, "a", "100", "b", "200")
   672  	spec := &pb.ChaincodeSpec{Type: 1, ChaincodeId: chaincodeID, Input: &pb.ChaincodeInput{Args: argsDeploy}}
   673  
   674  	cccid := ccprovider.NewCCContext(chainID, "ex01-fail1", "0", "", false, nil, nil)
   675  
   676  	_, _, err := deploy(endorserServer, chainID, spec, nil)
   677  	if err == nil {
   678  		t.Fail()
   679  		t.Logf("Deploying chaincode should have failed!")
   680  		chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}})
   681  		return
   682  	}
   683  
   684  	t.Logf("TestATestAdminACLFailCLFail passed")
   685  
   686  	chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}})
   687  }
   688  
   689  // TestInvokeSccFail makes sure that invoking a system chaincode fails
   690  func TestInvokeSccFail(t *testing.T) {
   691  	chainID := util.GetTestChainID()
   692  
   693  	chaincodeID := &pb.ChaincodeID{Name: "escc"}
   694  	args := util.ToChaincodeArgs("someFunc", "someArg")
   695  	spec := &pb.ChaincodeSpec{Type: 1, ChaincodeId: chaincodeID, Input: &pb.ChaincodeInput{Args: args}}
   696  	_, _, _, _, err := invoke(chainID, spec)
   697  	if err == nil {
   698  		t.Logf("Invoking escc should have failed!")
   699  		t.Fail()
   700  		return
   701  	}
   702  }
   703  
   704  func newTempDir() string {
   705  	tempDir, err := ioutil.TempDir("", "inkchain-")
   706  	if err != nil {
   707  		panic(err)
   708  	}
   709  	return tempDir
   710  }
   711  
   712  func TestMain(m *testing.M) {
   713  	setupTestConfig()
   714  
   715  	chainID := util.GetTestChainID()
   716  	tev, err := initPeer(chainID)
   717  	if err != nil {
   718  		os.Exit(-1)
   719  		fmt.Printf("Could not initialize tests")
   720  		finitPeer(tev)
   721  		return
   722  	}
   723  
   724  	endorserServer = NewEndorserServer()
   725  
   726  	// setup the MSP manager so that we can sign/verify
   727  	err = msptesttools.LoadMSPSetupForTesting()
   728  	if err != nil {
   729  		fmt.Printf("Could not initialize msp/signer, err %s", err)
   730  		finitPeer(tev)
   731  		os.Exit(-1)
   732  		return
   733  	}
   734  	signer, err = mspmgmt.GetLocalMSP().GetDefaultSigningIdentity()
   735  	if err != nil {
   736  		fmt.Printf("Could not initialize msp/signer")
   737  		finitPeer(tev)
   738  		os.Exit(-1)
   739  		return
   740  	}
   741  
   742  	retVal := m.Run()
   743  
   744  	finitPeer(tev)
   745  
   746  	os.Exit(retVal)
   747  }
   748  
   749  func setupTestConfig() {
   750  	flag.Parse()
   751  
   752  	// Now set the configuration file
   753  	viper.SetEnvPrefix("CORE")
   754  	viper.AutomaticEnv()
   755  	replacer := strings.NewReplacer(".", "_")
   756  	viper.SetEnvKeyReplacer(replacer)
   757  	viper.SetConfigName("endorser_test") // name of config file (without extension)
   758  	viper.AddConfigPath("./")            // path to look for the config file in
   759  	err := viper.ReadInConfig()          // Find and read the config file
   760  	if err != nil {                      // Handle errors reading the config file
   761  		panic(fmt.Errorf("Fatal error config file: %s \n", err))
   762  	}
   763  
   764  	testutil.SetupTestLogging()
   765  
   766  	// Set the number of maxprocs
   767  	runtime.GOMAXPROCS(viper.GetInt("peer.gomaxprocs"))
   768  
   769  	// Init the BCCSP
   770  	var bccspConfig *factory.FactoryOpts
   771  	err = viper.UnmarshalKey("peer.BCCSP", &bccspConfig)
   772  	if err != nil {
   773  		bccspConfig = nil
   774  	}
   775  
   776  	msp.SetupBCCSPKeystoreConfig(bccspConfig, viper.GetString("peer.mspConfigPath")+"/keystore")
   777  
   778  	err = factory.InitFactories(bccspConfig)
   779  	if err != nil {
   780  		panic(fmt.Errorf("Could not initialize BCCSP Factories [%s]", err))
   781  	}
   782  }