github.com/kchristidis/fabric@v1.0.4-0.20171028114726-837acd08cde1/core/chaincode/exectransaction_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 chaincode
    18  
    19  import (
    20  	"bytes"
    21  	"encoding/json"
    22  	"flag"
    23  	"fmt"
    24  	"math/rand"
    25  	"net"
    26  	"os"
    27  	"path/filepath"
    28  	"runtime"
    29  	"strconv"
    30  	"strings"
    31  	"sync"
    32  	"testing"
    33  	"time"
    34  
    35  	"github.com/golang/protobuf/proto"
    36  	"github.com/hyperledger/fabric/bccsp/factory"
    37  	mockpolicies "github.com/hyperledger/fabric/common/mocks/policies"
    38  	"github.com/hyperledger/fabric/common/policies"
    39  	"github.com/hyperledger/fabric/common/util"
    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/container/ccintf"
    44  	"github.com/hyperledger/fabric/core/ledger"
    45  	"github.com/hyperledger/fabric/core/ledger/ledgerconfig"
    46  	"github.com/hyperledger/fabric/core/ledger/ledgermgmt"
    47  	"github.com/hyperledger/fabric/core/ledger/util/couchdb"
    48  	"github.com/hyperledger/fabric/core/peer"
    49  	"github.com/hyperledger/fabric/core/policy"
    50  	"github.com/hyperledger/fabric/core/policy/mocks"
    51  	"github.com/hyperledger/fabric/core/scc"
    52  	"github.com/hyperledger/fabric/core/testutil"
    53  	"github.com/hyperledger/fabric/msp"
    54  	mspmgmt "github.com/hyperledger/fabric/msp/mgmt"
    55  	"github.com/hyperledger/fabric/msp/mgmt/testtools"
    56  	"github.com/hyperledger/fabric/protos/common"
    57  	pb "github.com/hyperledger/fabric/protos/peer"
    58  	putils "github.com/hyperledger/fabric/protos/utils"
    59  	"github.com/spf13/viper"
    60  	"golang.org/x/net/context"
    61  	"google.golang.org/grpc"
    62  	"google.golang.org/grpc/credentials"
    63  )
    64  
    65  var runTests bool
    66  
    67  func testForSkip(t *testing.T) {
    68  	//run tests
    69  	if !runTests {
    70  		t.SkipNow()
    71  	}
    72  }
    73  
    74  //initialize peer and start up. If security==enabled, login as vp
    75  func initPeer(chainIDs ...string) (net.Listener, error) {
    76  	//start clean
    77  	finitPeer(nil, chainIDs...)
    78  
    79  	peer.MockInitialize()
    80  
    81  	mspGetter := func(cid string) []string {
    82  		return []string{"DEFAULT"}
    83  	}
    84  
    85  	peer.MockSetMSPIDGetter(mspGetter)
    86  
    87  	var opts []grpc.ServerOption
    88  	if viper.GetBool("peer.tls.enabled") {
    89  		creds, err := credentials.NewServerTLSFromFile(config.GetPath("peer.tls.cert.file"), config.GetPath("peer.tls.key.file"))
    90  		if err != nil {
    91  			return nil, fmt.Errorf("Failed to generate credentials %v", err)
    92  		}
    93  		opts = []grpc.ServerOption{grpc.Creds(creds)}
    94  	}
    95  	grpcServer := grpc.NewServer(opts...)
    96  
    97  	peerAddress, err := peer.GetLocalAddress()
    98  	if err != nil {
    99  		return nil, fmt.Errorf("Error obtaining peer address: %s", err)
   100  	}
   101  	lis, err := net.Listen("tcp", peerAddress)
   102  	if err != nil {
   103  		return nil, fmt.Errorf("Error starting peer listener %s", err)
   104  	}
   105  
   106  	getPeerEndpoint := func() (*pb.PeerEndpoint, error) {
   107  		return &pb.PeerEndpoint{Id: &pb.PeerID{Name: "testpeer"}, Address: peerAddress}, nil
   108  	}
   109  
   110  	ccStartupTimeout := time.Duration(chaincodeStartupTimeoutDefault) * time.Millisecond
   111  	pb.RegisterChaincodeSupportServer(grpcServer, NewChaincodeSupport(getPeerEndpoint, false, ccStartupTimeout))
   112  
   113  	// Mock policy checker
   114  	policy.RegisterPolicyCheckerFactory(&mockPolicyCheckerFactory{})
   115  
   116  	scc.RegisterSysCCs()
   117  
   118  	for _, id := range chainIDs {
   119  		scc.DeDeploySysCCs(id)
   120  		if err = peer.MockCreateChain(id); err != nil {
   121  			closeListenerAndSleep(lis)
   122  			return nil, err
   123  		}
   124  		scc.DeploySysCCs(id)
   125  		// any chain other than the default testchainid does not have a MSP set up -> create one
   126  		if id != util.GetTestChainID() {
   127  			mspmgmt.XXXSetMSPManager(id, mspmgmt.GetManagerForChain(util.GetTestChainID()))
   128  		}
   129  	}
   130  
   131  	go grpcServer.Serve(lis)
   132  
   133  	return lis, nil
   134  }
   135  
   136  func finitPeer(lis net.Listener, chainIDs ...string) {
   137  	if lis != nil {
   138  		for _, c := range chainIDs {
   139  			scc.DeDeploySysCCs(c)
   140  			if lgr := peer.GetLedger(c); lgr != nil {
   141  				lgr.Close()
   142  			}
   143  		}
   144  		closeListenerAndSleep(lis)
   145  	}
   146  	ledgermgmt.CleanupTestEnv()
   147  	ledgerPath := config.GetPath("peer.fileSystemPath")
   148  	os.RemoveAll(ledgerPath)
   149  	os.RemoveAll(filepath.Join(os.TempDir(), "hyperledger"))
   150  
   151  	//if couchdb is enabled, then cleanup the test couchdb
   152  	if ledgerconfig.IsCouchDBEnabled() == true {
   153  
   154  		chainID := util.GetTestChainID()
   155  
   156  		connectURL := viper.GetString("ledger.state.couchDBConfig.couchDBAddress")
   157  		username := viper.GetString("ledger.state.couchDBConfig.username")
   158  		password := viper.GetString("ledger.state.couchDBConfig.password")
   159  		maxRetries := viper.GetInt("ledger.state.couchDBConfig.maxRetries")
   160  		maxRetriesOnStartup := viper.GetInt("ledger.state.couchDBConfig.maxRetriesOnStartup")
   161  		requestTimeout := viper.GetDuration("ledger.state.couchDBConfig.requestTimeout")
   162  
   163  		couchInstance, _ := couchdb.CreateCouchInstance(connectURL, username, password, maxRetries, maxRetriesOnStartup, requestTimeout)
   164  		db := couchdb.CouchDatabase{CouchInstance: *couchInstance, DBName: chainID}
   165  		//drop the test database
   166  		db.DropDatabase()
   167  
   168  	}
   169  }
   170  
   171  func startTxSimulation(ctxt context.Context, chainID string) (context.Context, ledger.TxSimulator, error) {
   172  	lgr := peer.GetLedger(chainID)
   173  	txsim, err := lgr.NewTxSimulator()
   174  	if err != nil {
   175  		return nil, nil, err
   176  	}
   177  	historyQueryExecutor, err := lgr.NewHistoryQueryExecutor()
   178  	if err != nil {
   179  		return nil, nil, err
   180  	}
   181  
   182  	ctxt = context.WithValue(ctxt, TXSimulatorKey, txsim)
   183  	ctxt = context.WithValue(ctxt, HistoryQueryExecutorKey, historyQueryExecutor)
   184  	return ctxt, txsim, nil
   185  }
   186  
   187  func endTxSimulationCDS(chainID string, _ string, txsim ledger.TxSimulator, payload []byte, commit bool, cds *pb.ChaincodeDeploymentSpec, blockNumber uint64) error {
   188  	// get serialized version of the signer
   189  	ss, err := signer.Serialize()
   190  	if err != nil {
   191  		return err
   192  	}
   193  
   194  	// get lscc ChaincodeID
   195  	lsccid := &pb.ChaincodeID{
   196  		Name:    "lscc",
   197  		Version: util.GetSysCCVersion(),
   198  	}
   199  
   200  	// get a proposal - we need it to get a transaction
   201  	prop, _, err := putils.CreateDeployProposalFromCDS(chainID, cds, ss, nil, nil, nil)
   202  	if err != nil {
   203  		return err
   204  	}
   205  
   206  	return endTxSimulation(chainID, lsccid, txsim, payload, commit, prop, blockNumber)
   207  }
   208  
   209  func endTxSimulationCIS(chainID string, ccid *pb.ChaincodeID, _ string, txsim ledger.TxSimulator, payload []byte, commit bool, cis *pb.ChaincodeInvocationSpec, blockNumber uint64) error {
   210  	// get serialized version of the signer
   211  	ss, err := signer.Serialize()
   212  	if err != nil {
   213  		return err
   214  	}
   215  
   216  	// get a proposal - we need it to get a transaction
   217  	prop, _, err := putils.CreateProposalFromCIS(common.HeaderType_ENDORSER_TRANSACTION, chainID, cis, ss)
   218  	if err != nil {
   219  		return err
   220  	}
   221  
   222  	return endTxSimulation(chainID, ccid, txsim, payload, commit, prop, blockNumber)
   223  }
   224  
   225  //getting a crash from ledger.Commit when doing concurrent invokes
   226  //It is likely intentional that ledger.Commit is serial (ie, the real
   227  //Committer will invoke this serially on each block). Mimic that here
   228  //by forcing serialization of the ledger.Commit call.
   229  //
   230  //NOTE-this should NOT have any effect on the older serial tests.
   231  //This affects only the tests in concurrent_test.go which call these
   232  //concurrently (100 concurrent invokes followed by 100 concurrent queries)
   233  var _commitLock_ sync.Mutex
   234  
   235  func endTxSimulation(chainID string, ccid *pb.ChaincodeID, txsim ledger.TxSimulator, _ []byte, commit bool, prop *pb.Proposal, blockNumber uint64) error {
   236  	txsim.Done()
   237  	if lgr := peer.GetLedger(chainID); lgr != nil {
   238  		if commit {
   239  			var txSimulationResults []byte
   240  			var err error
   241  
   242  			//get simulation results
   243  			if txSimulationResults, err = txsim.GetTxSimulationResults(); err != nil {
   244  				return err
   245  			}
   246  
   247  			// assemble a (signed) proposal response message
   248  			resp, err := putils.CreateProposalResponse(prop.Header, prop.Payload, &pb.Response{Status: 200}, txSimulationResults, nil, ccid, nil, signer)
   249  			if err != nil {
   250  				return err
   251  			}
   252  
   253  			// get the envelope
   254  			env, err := putils.CreateSignedTx(prop, signer, resp)
   255  			if err != nil {
   256  				return err
   257  			}
   258  
   259  			envBytes, err := putils.GetBytesEnvelope(env)
   260  			if err != nil {
   261  				return err
   262  			}
   263  
   264  			//create the block with 1 transaction
   265  			block := common.NewBlock(blockNumber, []byte{})
   266  			block.Data.Data = [][]byte{envBytes}
   267  			//commit the block
   268  
   269  			//see comment on _commitLock_
   270  			_commitLock_.Lock()
   271  			defer _commitLock_.Unlock()
   272  			if err := lgr.Commit(block); err != nil {
   273  				return err
   274  			}
   275  		}
   276  	}
   277  
   278  	return nil
   279  }
   280  
   281  // Build a chaincode.
   282  func getDeploymentSpec(_ context.Context, spec *pb.ChaincodeSpec) (*pb.ChaincodeDeploymentSpec, error) {
   283  	fmt.Printf("getting deployment spec for chaincode spec: %v\n", spec)
   284  	codePackageBytes, err := container.GetChaincodePackageBytes(spec)
   285  	if err != nil {
   286  		return nil, err
   287  	}
   288  	cdDeploymentSpec := &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec, CodePackage: codePackageBytes}
   289  	return cdDeploymentSpec, nil
   290  }
   291  
   292  //getDeployLSCCSpec gets the spec for the chaincode deployment to be sent to LSCC
   293  func getDeployLSCCSpec(chainID string, cds *pb.ChaincodeDeploymentSpec) (*pb.ChaincodeInvocationSpec, error) {
   294  	b, err := proto.Marshal(cds)
   295  	if err != nil {
   296  		return nil, err
   297  	}
   298  
   299  	sysCCVers := util.GetSysCCVersion()
   300  
   301  	//wrap the deployment in an invocation spec to lscc...
   302  	lsccSpec := &pb.ChaincodeInvocationSpec{ChaincodeSpec: &pb.ChaincodeSpec{Type: pb.ChaincodeSpec_GOLANG, ChaincodeId: &pb.ChaincodeID{Name: "lscc", Version: sysCCVers}, Input: &pb.ChaincodeInput{Args: [][]byte{[]byte("deploy"), []byte(chainID), b}}}}
   303  
   304  	return lsccSpec, nil
   305  }
   306  
   307  // Deploy a chaincode - i.e., build and initialize.
   308  func deploy(ctx context.Context, cccid *ccprovider.CCContext, spec *pb.ChaincodeSpec, blockNumber uint64) (b []byte, err error) {
   309  	// First build and get the deployment spec
   310  	cdDeploymentSpec, err := getDeploymentSpec(ctx, spec)
   311  	if err != nil {
   312  		return nil, err
   313  	}
   314  
   315  	return deploy2(ctx, cccid, cdDeploymentSpec, blockNumber)
   316  }
   317  
   318  func deploy2(ctx context.Context, cccid *ccprovider.CCContext, chaincodeDeploymentSpec *pb.ChaincodeDeploymentSpec, blockNumber uint64) (b []byte, err error) {
   319  	cis, err := getDeployLSCCSpec(cccid.ChainID, chaincodeDeploymentSpec)
   320  	if err != nil {
   321  		return nil, fmt.Errorf("Error creating lscc spec : %s\n", err)
   322  	}
   323  
   324  	ctx, txsim, err := startTxSimulation(ctx, cccid.ChainID)
   325  	if err != nil {
   326  		return nil, fmt.Errorf("Failed to get handle to simulator: %s ", err)
   327  	}
   328  
   329  	uuid := util.GenerateUUID()
   330  
   331  	cccid.TxID = uuid
   332  
   333  	defer func() {
   334  		//no error, lets try commit
   335  		if err == nil {
   336  			//capture returned error from commit
   337  			err = endTxSimulationCDS(cccid.ChainID, uuid, txsim, []byte("deployed"), true, chaincodeDeploymentSpec, blockNumber)
   338  		} else {
   339  			//there was an error, just close simulation and return that
   340  			endTxSimulationCDS(cccid.ChainID, uuid, txsim, []byte("deployed"), false, chaincodeDeploymentSpec, blockNumber)
   341  		}
   342  	}()
   343  
   344  	//ignore existence errors
   345  	ccprovider.PutChaincodeIntoFS(chaincodeDeploymentSpec)
   346  
   347  	sysCCVers := util.GetSysCCVersion()
   348  	sprop, prop := putils.MockSignedEndorserProposal2OrPanic(cccid.ChainID, cis.ChaincodeSpec, signer)
   349  	lsccid := ccprovider.NewCCContext(cccid.ChainID, cis.ChaincodeSpec.ChaincodeId.Name, sysCCVers, uuid, true, sprop, prop)
   350  
   351  	//write to lscc
   352  	if _, _, err = ExecuteWithErrorFilter(ctx, lsccid, cis); err != nil {
   353  		return nil, fmt.Errorf("Error deploying chaincode (1): %s", err)
   354  	}
   355  	if b, _, err = ExecuteWithErrorFilter(ctx, cccid, chaincodeDeploymentSpec); err != nil {
   356  		return nil, fmt.Errorf("Error deploying chaincode(2): %s", err)
   357  	}
   358  
   359  	return b, nil
   360  }
   361  
   362  // Invoke a chaincode.
   363  func invoke(ctx context.Context, chainID string, spec *pb.ChaincodeSpec, blockNumber uint64, creator []byte) (ccevt *pb.ChaincodeEvent, uuid string, retval []byte, err error) {
   364  	return invokeWithVersion(ctx, chainID, spec.GetChaincodeId().Version, spec, blockNumber, creator)
   365  }
   366  
   367  // Invoke a chaincode with version (needed for upgrade)
   368  func invokeWithVersion(ctx context.Context, chainID string, version string, spec *pb.ChaincodeSpec, blockNumber uint64, creator []byte) (ccevt *pb.ChaincodeEvent, uuid string, retval []byte, err error) {
   369  	cdInvocationSpec := &pb.ChaincodeInvocationSpec{ChaincodeSpec: spec}
   370  
   371  	// Now create the Transactions message and send to Peer.
   372  	uuid = util.GenerateUUID()
   373  
   374  	var txsim ledger.TxSimulator
   375  	ctx, txsim, err = startTxSimulation(ctx, chainID)
   376  	if err != nil {
   377  		return nil, uuid, nil, fmt.Errorf("Failed to get handle to simulator: %s ", err)
   378  	}
   379  
   380  	defer func() {
   381  		//no error, lets try commit
   382  		if err == nil {
   383  			//capture returned error from commit
   384  			err = endTxSimulationCIS(chainID, spec.ChaincodeId, uuid, txsim, []byte("invoke"), true, cdInvocationSpec, blockNumber)
   385  		} else {
   386  			//there was an error, just close simulation and return that
   387  			endTxSimulationCIS(chainID, spec.ChaincodeId, uuid, txsim, []byte("invoke"), false, cdInvocationSpec, blockNumber)
   388  		}
   389  	}()
   390  
   391  	if len(creator) == 0 {
   392  		creator = []byte("Admin")
   393  	}
   394  	sprop, prop := putils.MockSignedEndorserProposalOrPanic(chainID, spec, creator, []byte("msg1"))
   395  	cccid := ccprovider.NewCCContext(chainID, cdInvocationSpec.ChaincodeSpec.ChaincodeId.Name, version, uuid, false, sprop, prop)
   396  	retval, ccevt, err = ExecuteWithErrorFilter(ctx, cccid, cdInvocationSpec)
   397  	if err != nil {
   398  		return nil, uuid, nil, fmt.Errorf("Error invoking chaincode: %s", err)
   399  	}
   400  
   401  	return ccevt, uuid, retval, err
   402  }
   403  
   404  func closeListenerAndSleep(l net.Listener) {
   405  	if l != nil {
   406  		l.Close()
   407  		time.Sleep(2 * time.Second)
   408  	}
   409  }
   410  
   411  func executeDeployTransaction(t *testing.T, chainID string, name string, url string) {
   412  	lis, err := initPeer(chainID)
   413  	if err != nil {
   414  		t.Fail()
   415  		t.Logf("Error creating peer: %s", err)
   416  	}
   417  
   418  	defer finitPeer(lis, chainID)
   419  
   420  	var ctxt = context.Background()
   421  
   422  	f := "init"
   423  	args := util.ToChaincodeArgs(f, "a", "100", "b", "200")
   424  	spec := &pb.ChaincodeSpec{Type: 1, ChaincodeId: &pb.ChaincodeID{Name: name, Path: url, Version: "0"}, Input: &pb.ChaincodeInput{Args: args}}
   425  
   426  	cccid := ccprovider.NewCCContext(chainID, name, "0", "", false, nil, nil)
   427  
   428  	_, err = deploy(ctxt, cccid, spec, 0)
   429  
   430  	cID := spec.ChaincodeId.Name
   431  	if err != nil {
   432  		theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec})
   433  		t.Fail()
   434  		t.Logf("Error deploying <%s>: %s", cID, err)
   435  		return
   436  	}
   437  
   438  	theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec})
   439  }
   440  
   441  // chaincodeQueryChaincode function
   442  func _(chainID string, _ string) error {
   443  	var ctxt = context.Background()
   444  
   445  	// Deploy first chaincode
   446  	url1 := "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02"
   447  
   448  	cID1 := &pb.ChaincodeID{Name: "example02", Path: url1, Version: "0"}
   449  	f := "init"
   450  	args := util.ToChaincodeArgs(f, "a", "100", "b", "200")
   451  
   452  	spec1 := &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID1, Input: &pb.ChaincodeInput{Args: args}}
   453  
   454  	cccid1 := ccprovider.NewCCContext(chainID, "example02", "0", "", false, nil, nil)
   455  
   456  	var nextBlockNumber uint64
   457  
   458  	_, err := deploy(ctxt, cccid1, spec1, nextBlockNumber)
   459  	nextBlockNumber++
   460  
   461  	ccID1 := spec1.ChaincodeId.Name
   462  	if err != nil {
   463  		theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1})
   464  		return fmt.Errorf("Error initializing chaincode %s(%s)", ccID1, err)
   465  	}
   466  
   467  	time.Sleep(time.Second)
   468  
   469  	// Deploy second chaincode
   470  	url2 := "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example05"
   471  
   472  	cID2 := &pb.ChaincodeID{Name: "example05", Path: url2, Version: "0"}
   473  	f = "init"
   474  	args = util.ToChaincodeArgs(f, "sum", "0")
   475  
   476  	spec2 := &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID2, Input: &pb.ChaincodeInput{Args: args}}
   477  
   478  	cccid2 := ccprovider.NewCCContext(chainID, "example05", "0", "", false, nil, nil)
   479  
   480  	_, err = deploy(ctxt, cccid2, spec2, nextBlockNumber)
   481  	nextBlockNumber++
   482  	ccID2 := spec2.ChaincodeId.Name
   483  	if err != nil {
   484  		theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1})
   485  		theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2})
   486  		return fmt.Errorf("Error initializing chaincode %s(%s)", ccID2, err)
   487  	}
   488  
   489  	time.Sleep(time.Second)
   490  
   491  	// Invoke second chaincode, which will inturn query the first chaincode
   492  	f = "invoke"
   493  	args = util.ToChaincodeArgs(f, ccID1, "sum")
   494  
   495  	spec2 = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID2, Input: &pb.ChaincodeInput{Args: args}}
   496  	// Invoke chaincode
   497  	var retVal []byte
   498  	_, _, retVal, err = invoke(ctxt, chainID, spec2, nextBlockNumber, []byte("Alice"))
   499  	nextBlockNumber++
   500  
   501  	if err != nil {
   502  		theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1})
   503  		theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2})
   504  		return fmt.Errorf("Error invoking <%s>: %s", ccID2, err)
   505  	}
   506  
   507  	// Check the return value
   508  	result, err := strconv.Atoi(string(retVal))
   509  	if err != nil || result != 300 {
   510  		theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1})
   511  		theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2})
   512  		return fmt.Errorf("Incorrect final state after transaction for <%s>: %s", ccID1, err)
   513  	}
   514  
   515  	// Query second chaincode, which will inturn query the first chaincode
   516  	f = "query"
   517  	args = util.ToChaincodeArgs(f, ccID1, "sum")
   518  
   519  	spec2 = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID2, Input: &pb.ChaincodeInput{Args: args}}
   520  	// Invoke chaincode
   521  	_, _, retVal, err = invoke(ctxt, chainID, spec2, nextBlockNumber, []byte("Alice"))
   522  
   523  	if err != nil {
   524  		theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1})
   525  		theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2})
   526  		return fmt.Errorf("Error querying <%s>: %s", ccID2, err)
   527  	}
   528  
   529  	// Check the return value
   530  	result, err = strconv.Atoi(string(retVal))
   531  	if err != nil || result != 300 {
   532  		theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1})
   533  		theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2})
   534  		return fmt.Errorf("Incorrect final value after query for <%s>: %s", ccID1, err)
   535  	}
   536  
   537  	theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1})
   538  	theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2})
   539  
   540  	return nil
   541  }
   542  
   543  // Check the correctness of the final state after transaction execution.
   544  func checkFinalState(cccid *ccprovider.CCContext, a int, b int) error {
   545  	_, txsim, err := startTxSimulation(context.Background(), cccid.ChainID)
   546  	if err != nil {
   547  		return fmt.Errorf("Failed to get handle to simulator: %s ", err)
   548  	}
   549  
   550  	defer txsim.Done()
   551  
   552  	cName := cccid.GetCanonicalName()
   553  
   554  	// Invoke ledger to get state
   555  	var Aval, Bval int
   556  	resbytes, resErr := txsim.GetState(cccid.Name, "a")
   557  	if resErr != nil {
   558  		return fmt.Errorf("Error retrieving state from ledger for <%s>: %s", cName, resErr)
   559  	}
   560  	fmt.Printf("Got string: %s\n", string(resbytes))
   561  	Aval, resErr = strconv.Atoi(string(resbytes))
   562  	if resErr != nil {
   563  		return fmt.Errorf("Error retrieving state from ledger for <%s>: %s", cName, resErr)
   564  	}
   565  	if Aval != a {
   566  		return fmt.Errorf("Incorrect result. Aval %d != %d <%s>", Aval, a, cName)
   567  	}
   568  
   569  	resbytes, resErr = txsim.GetState(cccid.Name, "b")
   570  	if resErr != nil {
   571  		return fmt.Errorf("Error retrieving state from ledger for <%s>: %s", cName, resErr)
   572  	}
   573  	Bval, resErr = strconv.Atoi(string(resbytes))
   574  	if resErr != nil {
   575  		return fmt.Errorf("Error retrieving state from ledger for <%s>: %s", cName, resErr)
   576  	}
   577  	if Bval != b {
   578  		return fmt.Errorf("Incorrect result. Bval %d != %d <%s>", Bval, b, cName)
   579  	}
   580  
   581  	// Success
   582  	fmt.Printf("Aval = %d, Bval = %d\n", Aval, Bval)
   583  	return nil
   584  }
   585  
   586  // Invoke chaincode_example02
   587  func invokeExample02Transaction(ctxt context.Context, cccid *ccprovider.CCContext, cID *pb.ChaincodeID, chaincodeType pb.ChaincodeSpec_Type, args []string, destroyImage bool) error {
   588  	// the ledger is created with genesis block. Start block number 1 onwards
   589  	var nextBlockNumber uint64 = 1
   590  	f := "init"
   591  	argsDeploy := util.ToChaincodeArgs(f, "a", "100", "b", "200")
   592  	spec := &pb.ChaincodeSpec{Type: chaincodeType, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: argsDeploy}}
   593  	_, err := deploy(ctxt, cccid, spec, nextBlockNumber)
   594  	nextBlockNumber++
   595  	ccID := spec.ChaincodeId.Name
   596  	if err != nil {
   597  		return fmt.Errorf("Error deploying <%s>: %s", ccID, err)
   598  	}
   599  
   600  	time.Sleep(time.Second)
   601  
   602  	if destroyImage {
   603  		theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec})
   604  		dir := container.DestroyImageReq{CCID: ccintf.CCID{ChaincodeSpec: spec, NetworkID: theChaincodeSupport.peerNetworkID, PeerID: theChaincodeSupport.peerID, ChainID: cccid.ChainID}, Force: true, NoPrune: true}
   605  
   606  		_, err = container.VMCProcess(ctxt, container.DOCKER, dir)
   607  		if err != nil {
   608  			err = fmt.Errorf("Error destroying image: %s", err)
   609  			return err
   610  		}
   611  	}
   612  
   613  	f = "invoke"
   614  	invokeArgs := append([]string{f}, args...)
   615  	spec = &pb.ChaincodeSpec{ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: util.ToChaincodeArgs(invokeArgs...)}}
   616  	_, uuid, _, err := invoke(ctxt, cccid.ChainID, spec, nextBlockNumber, nil)
   617  	nextBlockNumber++
   618  	if err != nil {
   619  		return fmt.Errorf("Error invoking <%s>: %s", cccid.Name, err)
   620  	}
   621  
   622  	cccid.TxID = uuid
   623  	err = checkFinalState(cccid, 90, 210)
   624  	if err != nil {
   625  		return fmt.Errorf("Incorrect final state after transaction for <%s>: %s", ccID, err)
   626  	}
   627  
   628  	// Test for delete state
   629  	f = "delete"
   630  	delArgs := util.ToChaincodeArgs(f, "a")
   631  	spec = &pb.ChaincodeSpec{ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: delArgs}}
   632  	_, _, _, err = invoke(ctxt, cccid.ChainID, spec, nextBlockNumber, nil)
   633  	if err != nil {
   634  		return fmt.Errorf("Error deleting state in <%s>: %s", cccid.Name, err)
   635  	}
   636  
   637  	return nil
   638  }
   639  
   640  const (
   641  	chaincodeExample02GolangPath   = "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02"
   642  	chaincodeExample04GolangPath   = "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example04"
   643  	chaincodeEventSenderGolangPath = "github.com/hyperledger/fabric/examples/chaincode/go/eventsender"
   644  	chaincodeExample02JavaPath     = "../../examples/chaincode/java/chaincode_example02"
   645  	chaincodeExample04JavaPath     = "../../examples/chaincode/java/chaincode_example04"
   646  	chaincodeExample06JavaPath     = "../../examples/chaincode/java/chaincode_example06"
   647  	chaincodeEventSenderJavaPath   = "../../examples/chaincode/java/eventsender"
   648  )
   649  
   650  func runChaincodeInvokeChaincode(t *testing.T, channel1 string, channel2 string, tc tcicTc, cccid1 *ccprovider.CCContext, expectedA int, expectedB int, nextBlockNumber1, nextBlockNumber2 uint64) (uint64, uint64) {
   651  	var ctxt = context.Background()
   652  
   653  	// chaincode2: the chaincode that will call by chaincode1
   654  	chaincode2Name := generateChaincodeName(tc.chaincodeType)
   655  	chaincode2Version := "0"
   656  	chaincode2Type := tc.chaincodeType
   657  	chaincode2Path := tc.chaincodePath
   658  	chaincode2InitArgs := util.ToChaincodeArgs("init", "e", "0")
   659  	chaincode2Creator := []byte([]byte("Alice"))
   660  
   661  	// deploy second chaincode on channel1
   662  	_, cccid2, err := deployChaincode(ctxt, chaincode2Name, chaincode2Version, chaincode2Type, chaincode2Path, chaincode2InitArgs, chaincode2Creator, channel1, nextBlockNumber1)
   663  	if err != nil {
   664  		stopChaincode(ctxt, cccid1)
   665  		stopChaincode(ctxt, cccid2)
   666  		t.Fatalf("Error initializing chaincode %s(%s)", chaincode2Name, err)
   667  		return nextBlockNumber1, nextBlockNumber2
   668  	}
   669  	nextBlockNumber1++
   670  
   671  	time.Sleep(time.Second)
   672  
   673  	// Invoke second chaincode passing the first chaincode's name as first param,
   674  	// which will inturn invoke the first chaincode
   675  	chaincode2InvokeSpec := &pb.ChaincodeSpec{
   676  		Type: chaincode2Type,
   677  		ChaincodeId: &pb.ChaincodeID{
   678  			Name:    chaincode2Name,
   679  			Version: chaincode2Version,
   680  		},
   681  		Input: &pb.ChaincodeInput{
   682  			Args: util.ToChaincodeArgs("invoke", cccid1.Name, "e", "1"),
   683  		},
   684  	}
   685  	// Invoke chaincode
   686  	_, txID, _, err := invoke(ctxt, channel1, chaincode2InvokeSpec, nextBlockNumber1, []byte("Alice"))
   687  	if err != nil {
   688  		stopChaincode(ctxt, cccid1)
   689  		stopChaincode(ctxt, cccid2)
   690  		t.Fatalf("Error invoking <%s>: %s", chaincode2Name, err)
   691  		return nextBlockNumber1, nextBlockNumber2
   692  	}
   693  	nextBlockNumber1++
   694  
   695  	// TODO this doesn't seeem to be used, remove?
   696  	cccid1.TxID = txID
   697  
   698  	// Check the state in the ledger
   699  	err = checkFinalState(cccid1, expectedA, expectedB)
   700  	if err != nil {
   701  		stopChaincode(ctxt, cccid1)
   702  		stopChaincode(ctxt, cccid2)
   703  		t.Fatalf("Incorrect final state after transaction for <%s>: %s", cccid1.Name, err)
   704  		return nextBlockNumber1, nextBlockNumber2
   705  	}
   706  
   707  	// Change the policies of the two channels in such a way:
   708  	// 1. Alice has reader access to both the channels.
   709  	// 2. Bob has access only to chainID2.
   710  	// Therefore the chaincode invocation should fail.
   711  	pm := peer.GetPolicyManager(channel1)
   712  	pm.(*mockpolicies.Manager).PolicyMap = map[string]policies.Policy{
   713  		policies.ChannelApplicationWriters: &CreatorPolicy{Creators: [][]byte{[]byte("Alice")}},
   714  	}
   715  
   716  	pm = peer.GetPolicyManager(channel2)
   717  	pm.(*mockpolicies.Manager).PolicyMap = map[string]policies.Policy{
   718  		policies.ChannelApplicationWriters: &CreatorPolicy{Creators: [][]byte{[]byte("Alice"), []byte("Bob")}},
   719  	}
   720  
   721  	// deploy chaincode2 on channel2
   722  	_, cccid3, err := deployChaincode(ctxt, chaincode2Name, chaincode2Version, chaincode2Type, chaincode2Path, chaincode2InitArgs, chaincode2Creator, channel2, nextBlockNumber2)
   723  	if err != nil {
   724  		stopChaincode(ctxt, cccid1)
   725  		stopChaincode(ctxt, cccid2)
   726  		stopChaincode(ctxt, cccid3)
   727  		t.Fatalf("Error initializing chaincode %s/%s: %s", chaincode2Name, channel2, err)
   728  		return nextBlockNumber1, nextBlockNumber2
   729  	}
   730  	nextBlockNumber2++
   731  	time.Sleep(time.Second)
   732  
   733  	// as Bob, invoke chaincode2 on channel2 so that it invokes chaincode1 on channel1
   734  	chaincode2InvokeSpec = &pb.ChaincodeSpec{
   735  		Type: chaincode2Type,
   736  		ChaincodeId: &pb.ChaincodeID{
   737  			Name:    chaincode2Name,
   738  			Version: chaincode2Version,
   739  		},
   740  		Input: &pb.ChaincodeInput{
   741  			Args: util.ToChaincodeArgs("invoke", cccid1.Name, "e", "1", channel1),
   742  		},
   743  	}
   744  	_, _, _, err = invoke(ctxt, channel2, chaincode2InvokeSpec, nextBlockNumber2, []byte("Bob"))
   745  	if err == nil {
   746  		// Bob should not be able to call
   747  		stopChaincode(ctxt, cccid1)
   748  		stopChaincode(ctxt, cccid2)
   749  		stopChaincode(ctxt, cccid3)
   750  		nextBlockNumber2++
   751  		t.Fatalf("As Bob, invoking <%s/%s> via <%s/%s> should fail, but it succeeded.", cccid1.Name, cccid1.ChainID, chaincode2Name, channel2)
   752  		return nextBlockNumber1, nextBlockNumber2
   753  	}
   754  
   755  	// as Alice, invoke chaincode2 on channel2 so that it invokes chaincode1 on channel1
   756  	_, _, _, err = invoke(ctxt, channel2, chaincode2InvokeSpec, nextBlockNumber2, []byte("Alice"))
   757  	if err != nil {
   758  		// Alice should be able to call
   759  		stopChaincode(ctxt, cccid1)
   760  		stopChaincode(ctxt, cccid2)
   761  		stopChaincode(ctxt, cccid3)
   762  		t.Fatalf("As Alice, invoking <%s/%s> via <%s/%s> should should of succeeded, but it failed: %s", cccid1.Name, cccid1.ChainID, chaincode2Name, channel2, err)
   763  		return nextBlockNumber1, nextBlockNumber2
   764  	}
   765  	nextBlockNumber2++
   766  
   767  	stopChaincode(ctxt, cccid1)
   768  	stopChaincode(ctxt, cccid2)
   769  	stopChaincode(ctxt, cccid3)
   770  
   771  	return nextBlockNumber1, nextBlockNumber2
   772  }
   773  
   774  // Test deploy of a transaction
   775  func TestExecuteDeployTransaction(t *testing.T) {
   776  	//chaincoe is deployed as part of many tests. No need for a separate one for this
   777  	t.Skip()
   778  	chainID := util.GetTestChainID()
   779  
   780  	executeDeployTransaction(t, chainID, "example01", "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example01")
   781  }
   782  
   783  // Test deploy of a transaction with a GOPATH with multiple elements
   784  func TestGopathExecuteDeployTransaction(t *testing.T) {
   785  	//this is no longer critical as chaincode is assembled in the client side (SDK)
   786  	t.Skip()
   787  	chainID := util.GetTestChainID()
   788  
   789  	// add a trailing slash to GOPATH
   790  	// and a couple of elements - it doesn't matter what they are
   791  	os.Setenv("GOPATH", os.Getenv("GOPATH")+string(os.PathSeparator)+string(os.PathListSeparator)+"/tmp/foo"+string(os.PathListSeparator)+"/tmp/bar")
   792  	executeDeployTransaction(t, chainID, "example01", "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example01")
   793  }
   794  
   795  func TestExecuteInvokeTransaction(t *testing.T) {
   796  	testForSkip(t)
   797  
   798  	testCases := []struct {
   799  		chaincodeType pb.ChaincodeSpec_Type
   800  		chaincodePath string
   801  	}{
   802  		{pb.ChaincodeSpec_GOLANG, chaincodeExample02GolangPath},
   803  		{pb.ChaincodeSpec_JAVA, chaincodeExample02JavaPath},
   804  	}
   805  
   806  	for _, tc := range testCases {
   807  		t.Run(tc.chaincodeType.String(), func(t *testing.T) {
   808  
   809  			if tc.chaincodeType == pb.ChaincodeSpec_JAVA && runtime.GOARCH != "amd64" {
   810  				t.Skip("No Java chaincode support yet on non-x86_64.")
   811  			}
   812  
   813  			chainID := util.GetTestChainID()
   814  
   815  			lis, err := initPeer(chainID)
   816  			if err != nil {
   817  				t.Fail()
   818  				t.Logf("Error creating peer: %s", err)
   819  			}
   820  
   821  			defer finitPeer(lis, chainID)
   822  
   823  			var ctxt = context.Background()
   824  			chaincodeName := generateChaincodeName(tc.chaincodeType)
   825  			chaincodeVersion := "1.0.0.0"
   826  			cccid := ccprovider.NewCCContext(chainID, chaincodeName, chaincodeVersion, "", false, nil, nil)
   827  			ccID := &pb.ChaincodeID{Name: chaincodeName, Path: tc.chaincodePath, Version: chaincodeVersion}
   828  
   829  			args := []string{"a", "b", "10"}
   830  			err = invokeExample02Transaction(ctxt, cccid, ccID, tc.chaincodeType, args, true)
   831  			if err != nil {
   832  				t.Fail()
   833  				t.Logf("Error invoking transaction: %s", err)
   834  			} else {
   835  				fmt.Print("Invoke test passed\n")
   836  				t.Log("Invoke test passed")
   837  			}
   838  
   839  			theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: ccID}})
   840  
   841  		})
   842  	}
   843  
   844  }
   845  
   846  // Test the execution of an invalid transaction.
   847  func TestExecuteInvokeInvalidTransaction(t *testing.T) {
   848  	testForSkip(t)
   849  
   850  	chainID := util.GetTestChainID()
   851  
   852  	lis, err := initPeer(chainID)
   853  	if err != nil {
   854  		t.Fail()
   855  		t.Logf("Error creating peer: %s", err)
   856  	}
   857  
   858  	defer finitPeer(lis, chainID)
   859  
   860  	var ctxt = context.Background()
   861  
   862  	url := "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02"
   863  	ccID := &pb.ChaincodeID{Name: "example02", Path: url, Version: "0"}
   864  
   865  	cccid := ccprovider.NewCCContext(chainID, "example02", "0", "", false, nil, nil)
   866  
   867  	//FAIL, FAIL!
   868  	args := []string{"x", "-1"}
   869  	err = invokeExample02Transaction(ctxt, cccid, ccID, pb.ChaincodeSpec_GOLANG, args, false)
   870  
   871  	//this HAS to fail with expectedDeltaStringPrefix
   872  	if err != nil {
   873  		errStr := err.Error()
   874  		t.Logf("Got error %s\n", errStr)
   875  		t.Log("InvalidInvoke test passed")
   876  		theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: ccID}})
   877  
   878  		return
   879  	}
   880  
   881  	t.Fail()
   882  	t.Logf("Error invoking transaction %s", err)
   883  
   884  	theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: ccID}})
   885  }
   886  
   887  // testcase parameters for TestChaincodeInvokeChaincode
   888  type tcicTc struct {
   889  	chaincodeType pb.ChaincodeSpec_Type
   890  	chaincodePath string
   891  }
   892  
   893  // Test the execution of a chaincode that invokes another chaincode.
   894  func TestChaincodeInvokeChaincode(t *testing.T) {
   895  	testForSkip(t)
   896  	channel := util.GetTestChainID()
   897  	channel2 := channel + "2"
   898  	lis, err := initPeer(channel, channel2)
   899  	if err != nil {
   900  		t.Fail()
   901  		t.Logf("Error creating peer: %s", err)
   902  	}
   903  
   904  	defer finitPeer(lis, channel, channel2)
   905  
   906  	testCases := []tcicTc{
   907  		{pb.ChaincodeSpec_GOLANG, chaincodeExample04GolangPath},
   908  		{pb.ChaincodeSpec_JAVA, chaincodeExample04JavaPath},
   909  	}
   910  
   911  	ctx := context.Background()
   912  
   913  	var nextBlockNumber1 uint64 = 1
   914  	var nextBlockNumber2 uint64 = 1
   915  
   916  	// deploy the chaincode that will be called by the second chaincode
   917  	chaincode1Name := generateChaincodeName(pb.ChaincodeSpec_GOLANG)
   918  	chaincode1Version := "0"
   919  	chaincode1Type := pb.ChaincodeSpec_GOLANG
   920  	chaincode1Path := chaincodeExample02GolangPath
   921  	initialA := 100
   922  	initialB := 200
   923  	chaincode1InitArgs := util.ToChaincodeArgs("init", "a", strconv.Itoa(initialA), "b", strconv.Itoa(initialB))
   924  	chaincode1Creator := []byte([]byte("Alice"))
   925  
   926  	// Deploy first chaincode
   927  	_, chaincodeCtx, err := deployChaincode(ctx, chaincode1Name, chaincode1Version, chaincode1Type, chaincode1Path, chaincode1InitArgs, chaincode1Creator, channel, nextBlockNumber1)
   928  	if err != nil {
   929  		stopChaincode(ctx, chaincodeCtx)
   930  		t.Fatalf("Error initializing chaincode %s: %s", chaincodeCtx.Name, err)
   931  	}
   932  	nextBlockNumber1++
   933  	time.Sleep(time.Second)
   934  
   935  	expectedA := initialA
   936  	expectedB := initialB
   937  
   938  	for _, tc := range testCases {
   939  		t.Run(tc.chaincodeType.String(), func(t *testing.T) {
   940  
   941  			if tc.chaincodeType == pb.ChaincodeSpec_JAVA && runtime.GOARCH != "amd64" {
   942  				t.Skip("No Java chaincode support yet on non-x86_64.")
   943  			}
   944  
   945  			expectedA = expectedA - 10
   946  			expectedB = expectedB + 10
   947  			nextBlockNumber1, nextBlockNumber2 = runChaincodeInvokeChaincode(t, channel, channel2, tc, chaincodeCtx, expectedA, expectedB, nextBlockNumber1, nextBlockNumber2)
   948  		})
   949  	}
   950  
   951  	closeListenerAndSleep(lis)
   952  }
   953  
   954  func stopChaincode(ctx context.Context, chaincodeCtx *ccprovider.CCContext) {
   955  	theChaincodeSupport.Stop(ctx, chaincodeCtx,
   956  		&pb.ChaincodeDeploymentSpec{
   957  			ChaincodeSpec: &pb.ChaincodeSpec{
   958  				ChaincodeId: &pb.ChaincodeID{
   959  					Name:    chaincodeCtx.Name,
   960  					Version: chaincodeCtx.Version,
   961  				},
   962  			},
   963  		})
   964  }
   965  
   966  // Test the execution of a chaincode that invokes another chaincode with wrong parameters. Should receive error from
   967  // from the called chaincode
   968  func TestChaincodeInvokeChaincodeErrorCase(t *testing.T) {
   969  	testForSkip(t)
   970  	chainID := util.GetTestChainID()
   971  
   972  	lis, err := initPeer(chainID)
   973  	if err != nil {
   974  		t.Fail()
   975  		t.Logf("Error creating peer: %s", err)
   976  	}
   977  
   978  	defer finitPeer(lis, chainID)
   979  
   980  	var ctxt = context.Background()
   981  
   982  	// Deploy first chaincode
   983  	url1 := "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02"
   984  
   985  	cID1 := &pb.ChaincodeID{Name: "example02", Path: url1, Version: "0"}
   986  	f := "init"
   987  	args := util.ToChaincodeArgs(f, "a", "100", "b", "200")
   988  
   989  	spec1 := &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID1, Input: &pb.ChaincodeInput{Args: args}}
   990  
   991  	sProp, prop := putils.MockSignedEndorserProposalOrPanic(util.GetTestChainID(), spec1, []byte([]byte("Alice")), nil)
   992  	cccid1 := ccprovider.NewCCContext(chainID, "example02", "0", "", false, sProp, prop)
   993  
   994  	var nextBlockNumber uint64 = 1
   995  
   996  	_, err = deploy(ctxt, cccid1, spec1, nextBlockNumber)
   997  	nextBlockNumber++
   998  	ccID1 := spec1.ChaincodeId.Name
   999  	if err != nil {
  1000  		t.Fail()
  1001  		t.Logf("Error initializing chaincode %s(%s)", ccID1, err)
  1002  		theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1})
  1003  		return
  1004  	}
  1005  
  1006  	time.Sleep(time.Second)
  1007  
  1008  	// Deploy second chaincode
  1009  	url2 := "github.com/hyperledger/fabric/examples/chaincode/go/passthru"
  1010  
  1011  	cID2 := &pb.ChaincodeID{Name: "pthru", Path: url2, Version: "0"}
  1012  	f = "init"
  1013  	args = util.ToChaincodeArgs(f)
  1014  
  1015  	spec2 := &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID2, Input: &pb.ChaincodeInput{Args: args}}
  1016  
  1017  	cccid2 := ccprovider.NewCCContext(chainID, "pthru", "0", "", false, sProp, prop)
  1018  
  1019  	_, err = deploy(ctxt, cccid2, spec2, nextBlockNumber)
  1020  	nextBlockNumber++
  1021  	ccID2 := spec2.ChaincodeId.Name
  1022  	if err != nil {
  1023  		t.Fail()
  1024  		t.Logf("Error initializing chaincode %s(%s)", ccID2, err)
  1025  		theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1})
  1026  		theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2})
  1027  		return
  1028  	}
  1029  
  1030  	time.Sleep(time.Second)
  1031  
  1032  	// Invoke second chaincode, which will inturn invoke the first chaincode but pass bad params
  1033  	f = ccID1
  1034  	args = util.ToChaincodeArgs(f, "invoke", "a")
  1035  
  1036  	spec2 = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID2, Input: &pb.ChaincodeInput{Args: args}}
  1037  	// Invoke chaincode
  1038  	_, _, _, err = invoke(ctxt, chainID, spec2, nextBlockNumber, []byte("Alice"))
  1039  
  1040  	if err == nil {
  1041  		t.Fail()
  1042  		t.Logf("Error invoking <%s>: %s", ccID2, err)
  1043  		theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1})
  1044  		theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2})
  1045  		return
  1046  	}
  1047  
  1048  	if strings.Index(err.Error(), "Error invoking chaincode: Incorrect number of arguments. Expecting 3") < 0 {
  1049  		t.Fail()
  1050  		t.Logf("Unexpected error %s", err)
  1051  		theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1})
  1052  		theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2})
  1053  		return
  1054  	}
  1055  
  1056  	theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1})
  1057  	theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2})
  1058  }
  1059  
  1060  // Test the invocation of a transaction.
  1061  func TestQueries(t *testing.T) {
  1062  	testForSkip(t)
  1063  
  1064  	chainID := util.GetTestChainID()
  1065  
  1066  	lis, err := initPeer(chainID)
  1067  	if err != nil {
  1068  		t.Fail()
  1069  		t.Logf("Error creating peer: %s", err)
  1070  	}
  1071  
  1072  	defer finitPeer(lis, chainID)
  1073  
  1074  	var ctxt = context.Background()
  1075  
  1076  	url := "github.com/hyperledger/fabric/examples/chaincode/go/map"
  1077  	cID := &pb.ChaincodeID{Name: "tmap", Path: url, Version: "0"}
  1078  
  1079  	f := "init"
  1080  	args := util.ToChaincodeArgs(f)
  1081  
  1082  	spec := &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: args}}
  1083  
  1084  	cccid := ccprovider.NewCCContext(chainID, "tmap", "0", "", false, nil, nil)
  1085  
  1086  	var nextBlockNumber uint64 = 1
  1087  	_, err = deploy(ctxt, cccid, spec, nextBlockNumber)
  1088  	nextBlockNumber++
  1089  	ccID := spec.ChaincodeId.Name
  1090  	if err != nil {
  1091  		t.Fail()
  1092  		t.Logf("Error initializing chaincode %s(%s)", ccID, err)
  1093  		theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec})
  1094  		return
  1095  	}
  1096  
  1097  	// Add 101 marbles for testing range queries and rich queries (for capable ledgers)
  1098  	// The tests will test both range and rich queries and queries with query limits
  1099  	for i := 1; i <= 101; i++ {
  1100  		f = "put"
  1101  
  1102  		// 51 owned by tom, 50 by jerry
  1103  		owner := "tom"
  1104  		if i%2 == 0 {
  1105  			owner = "jerry"
  1106  		}
  1107  
  1108  		// one marble color is red, 100 are blue
  1109  		color := "blue"
  1110  		if i == 12 {
  1111  			color = "red"
  1112  		}
  1113  
  1114  		key := fmt.Sprintf("marble%03d", i)
  1115  		argsString := fmt.Sprintf("{\"docType\":\"marble\",\"name\":\"%s\",\"color\":\"%s\",\"size\":35,\"owner\":\"%s\"}", key, color, owner)
  1116  		args = util.ToChaincodeArgs(f, key, argsString)
  1117  		spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: args}}
  1118  		_, _, _, err = invoke(ctxt, chainID, spec, nextBlockNumber, nil)
  1119  		nextBlockNumber++
  1120  
  1121  		if err != nil {
  1122  			t.Fail()
  1123  			t.Logf("Error invoking <%s>: %s", ccID, err)
  1124  			theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec})
  1125  			return
  1126  		}
  1127  	}
  1128  
  1129  	//The following range query for "marble001" to "marble011" should return 10 marbles
  1130  	f = "keys"
  1131  	args = util.ToChaincodeArgs(f, "marble001", "marble011")
  1132  
  1133  	spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: args}}
  1134  	_, _, retval, err := invoke(ctxt, chainID, spec, nextBlockNumber, nil)
  1135  	nextBlockNumber++
  1136  	if err != nil {
  1137  		t.Fail()
  1138  		t.Logf("Error invoking <%s>: %s", ccID, err)
  1139  		theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec})
  1140  		return
  1141  	}
  1142  
  1143  	var keys []interface{}
  1144  	err = json.Unmarshal(retval, &keys)
  1145  	if len(keys) != 10 {
  1146  		t.Fail()
  1147  		t.Logf("Error detected with the range query, should have returned 10 but returned %v", len(keys))
  1148  		theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec})
  1149  		return
  1150  	}
  1151  
  1152  	//FAB-1163- The following range query should timeout and produce an error
  1153  	//the peer should handle this gracefully and not die
  1154  
  1155  	//save the original timeout and set a new timeout of 1 sec
  1156  	origTimeout := theChaincodeSupport.executetimeout
  1157  	theChaincodeSupport.executetimeout = time.Duration(1) * time.Second
  1158  
  1159  	//chaincode to sleep for 2 secs with timeout 1
  1160  	args = util.ToChaincodeArgs(f, "marble001", "marble002", "2000")
  1161  
  1162  	spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: args}}
  1163  	_, _, retval, err = invoke(ctxt, chainID, spec, nextBlockNumber, nil)
  1164  	if err == nil {
  1165  		t.Fail()
  1166  		t.Logf("expected timeout error but succeeded")
  1167  		theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec})
  1168  		return
  1169  	}
  1170  
  1171  	//restore timeout
  1172  	theChaincodeSupport.executetimeout = origTimeout
  1173  
  1174  	// querying for all marbles will return 101 marbles
  1175  	// this query should return exactly 101 results (one call to Next())
  1176  	//The following range query for "marble001" to "marble102" should return 101 marbles
  1177  	f = "keys"
  1178  	args = util.ToChaincodeArgs(f, "marble001", "marble102")
  1179  
  1180  	spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: args}}
  1181  	_, _, retval, err = invoke(ctxt, chainID, spec, nextBlockNumber, nil)
  1182  	nextBlockNumber++
  1183  	if err != nil {
  1184  		t.Fail()
  1185  		t.Logf("Error invoking <%s>: %s", ccID, err)
  1186  		theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec})
  1187  		return
  1188  	}
  1189  
  1190  	//unmarshal the results
  1191  	err = json.Unmarshal(retval, &keys)
  1192  
  1193  	//check to see if there are 101 values
  1194  	//default query limit of 10000 is used, this query is effectively unlimited
  1195  	if len(keys) != 101 {
  1196  		t.Fail()
  1197  		t.Logf("Error detected with the range query, should have returned 101 but returned %v", len(keys))
  1198  		theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec})
  1199  		return
  1200  	}
  1201  
  1202  	// querying for all simple key. This query should return exactly 101 simple keys (one
  1203  	// call to Next()) no composite keys.
  1204  	//The following open ended range query for "" to "" should return 101 marbles
  1205  	f = "keys"
  1206  	args = util.ToChaincodeArgs(f, "", "")
  1207  
  1208  	spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: args}}
  1209  	_, _, retval, err = invoke(ctxt, chainID, spec, nextBlockNumber, nil)
  1210  	nextBlockNumber++
  1211  	if err != nil {
  1212  		t.Fail()
  1213  		t.Logf("Error invoking <%s>: %s", ccID, err)
  1214  		theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec})
  1215  		return
  1216  	}
  1217  
  1218  	//unmarshal the results
  1219  	err = json.Unmarshal(retval, &keys)
  1220  
  1221  	//check to see if there are 101 values
  1222  	//default query limit of 10000 is used, this query is effectively unlimited
  1223  	if len(keys) != 101 {
  1224  		t.Fail()
  1225  		t.Logf("Error detected with the range query, should have returned 101 but returned %v", len(keys))
  1226  		theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec})
  1227  		return
  1228  	}
  1229  
  1230  	// ExecuteQuery supported only for CouchDB and
  1231  	// query limits apply for CouchDB range and rich queries only
  1232  	if ledgerconfig.IsCouchDBEnabled() == true {
  1233  
  1234  		// corner cases for shim batching. currnt shim batch size is 100
  1235  		// this query should return exactly 100 results (no call to Next())
  1236  		f = "query"
  1237  		args = util.ToChaincodeArgs(f, "{\"selector\":{\"color\":\"blue\"}}")
  1238  
  1239  		spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: args}}
  1240  		_, _, _, err = invoke(ctxt, chainID, spec, nextBlockNumber, nil)
  1241  		nextBlockNumber++
  1242  
  1243  		if err != nil {
  1244  			t.Fail()
  1245  			t.Logf("Error invoking <%s>: %s", ccID, err)
  1246  			theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec})
  1247  			return
  1248  		}
  1249  
  1250  		//unmarshal the results
  1251  		err = json.Unmarshal(retval, &keys)
  1252  
  1253  		//check to see if there are 100 values
  1254  		if len(keys) != 100 {
  1255  			t.Fail()
  1256  			t.Logf("Error detected with the rich query, should have returned 100 but returned %v %s", len(keys), keys)
  1257  			theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec})
  1258  			return
  1259  		}
  1260  
  1261  		//Reset the query limit to 5
  1262  		viper.Set("ledger.state.queryLimit", 5)
  1263  
  1264  		//The following range query for "marble01" to "marble11" should return 5 marbles due to the queryLimit
  1265  		f = "keys"
  1266  		args = util.ToChaincodeArgs(f, "marble001", "marble011")
  1267  
  1268  		spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: args}}
  1269  		_, _, retval, err := invoke(ctxt, chainID, spec, nextBlockNumber, nil)
  1270  		nextBlockNumber++
  1271  		if err != nil {
  1272  			t.Fail()
  1273  			t.Logf("Error invoking <%s>: %s", ccID, err)
  1274  			theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec})
  1275  			return
  1276  		}
  1277  
  1278  		//unmarshal the results
  1279  		err = json.Unmarshal(retval, &keys)
  1280  
  1281  		//check to see if there are 5 values
  1282  		if len(keys) != 5 {
  1283  			t.Fail()
  1284  			t.Logf("Error detected with the range query, should have returned 5 but returned %v", len(keys))
  1285  			theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec})
  1286  			return
  1287  		}
  1288  
  1289  		//Reset the query limit to 10000
  1290  		viper.Set("ledger.state.queryLimit", 10000)
  1291  
  1292  		//The following rich query for should return 50 marbles
  1293  		f = "query"
  1294  		args = util.ToChaincodeArgs(f, "{\"selector\":{\"owner\":\"jerry\"}}")
  1295  
  1296  		spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: args}}
  1297  		_, _, retval, err = invoke(ctxt, chainID, spec, nextBlockNumber, nil)
  1298  		nextBlockNumber++
  1299  
  1300  		if err != nil {
  1301  			t.Fail()
  1302  			t.Logf("Error invoking <%s>: %s", ccID, err)
  1303  			theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec})
  1304  			return
  1305  		}
  1306  
  1307  		//unmarshal the results
  1308  		err = json.Unmarshal(retval, &keys)
  1309  
  1310  		//check to see if there are 50 values
  1311  		//default query limit of 10000 is used, this query is effectively unlimited
  1312  		if len(keys) != 50 {
  1313  			t.Fail()
  1314  			t.Logf("Error detected with the rich query, should have returned 50 but returned %v", len(keys))
  1315  			theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec})
  1316  			return
  1317  		}
  1318  
  1319  		//Reset the query limit to 5
  1320  		viper.Set("ledger.state.queryLimit", 5)
  1321  
  1322  		//The following rich query should return 5 marbles due to the queryLimit
  1323  		f = "query"
  1324  		args = util.ToChaincodeArgs(f, "{\"selector\":{\"owner\":\"jerry\"}}")
  1325  
  1326  		spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: args}}
  1327  		_, _, retval, err = invoke(ctxt, chainID, spec, nextBlockNumber, nil)
  1328  		nextBlockNumber++
  1329  		if err != nil {
  1330  			t.Fail()
  1331  			t.Logf("Error invoking <%s>: %s", ccID, err)
  1332  			theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec})
  1333  			return
  1334  		}
  1335  
  1336  		//unmarshal the results
  1337  		err = json.Unmarshal(retval, &keys)
  1338  
  1339  		//check to see if there are 5 values
  1340  		if len(keys) != 5 {
  1341  			t.Fail()
  1342  			t.Logf("Error detected with the rich query, should have returned 5 but returned %v", len(keys))
  1343  			theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec})
  1344  			return
  1345  		}
  1346  
  1347  	}
  1348  
  1349  	// modifications for history query
  1350  	f = "put"
  1351  	args = util.ToChaincodeArgs(f, "marble012", "{\"docType\":\"marble\",\"name\":\"marble012\",\"color\":\"red\",\"size\":30,\"owner\":\"jerry\"}")
  1352  	spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: args}}
  1353  	_, _, _, err = invoke(ctxt, chainID, spec, nextBlockNumber, nil)
  1354  	nextBlockNumber++
  1355  	if err != nil {
  1356  		t.Fail()
  1357  		t.Logf("Error invoking <%s>: %s", ccID, err)
  1358  		theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec})
  1359  		return
  1360  	}
  1361  
  1362  	f = "put"
  1363  	args = util.ToChaincodeArgs(f, "marble012", "{\"docType\":\"marble\",\"name\":\"marble012\",\"color\":\"red\",\"size\":30,\"owner\":\"jerry\"}")
  1364  	spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: args}}
  1365  	_, _, _, err = invoke(ctxt, chainID, spec, nextBlockNumber, nil)
  1366  	nextBlockNumber++
  1367  	if err != nil {
  1368  		t.Fail()
  1369  		t.Logf("Error invoking <%s>: %s", ccID, err)
  1370  		theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec})
  1371  		return
  1372  	}
  1373  
  1374  	//The following history query for "marble12" should return 3 records
  1375  	f = "history"
  1376  	args = util.ToChaincodeArgs(f, "marble012")
  1377  	spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: args}}
  1378  	_, _, retval, err = invoke(ctxt, chainID, spec, nextBlockNumber, nil)
  1379  	nextBlockNumber++
  1380  	if err != nil {
  1381  		t.Fail()
  1382  		t.Logf("Error invoking <%s>: %s", ccID, err)
  1383  		theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec})
  1384  		return
  1385  	}
  1386  
  1387  	var history []interface{}
  1388  	err = json.Unmarshal(retval, &history)
  1389  	if len(history) != 3 {
  1390  		t.Fail()
  1391  		t.Logf("Error detected with the history query, should have returned 3 but returned %v", len(keys))
  1392  		theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec})
  1393  		return
  1394  	}
  1395  
  1396  	theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec})
  1397  }
  1398  
  1399  func TestGetEvent(t *testing.T) {
  1400  	testForSkip(t)
  1401  	testCases := []struct {
  1402  		chaincodeType pb.ChaincodeSpec_Type
  1403  		chaincodePath string
  1404  	}{
  1405  		{pb.ChaincodeSpec_GOLANG, chaincodeEventSenderGolangPath},
  1406  		{pb.ChaincodeSpec_JAVA, chaincodeEventSenderJavaPath},
  1407  	}
  1408  
  1409  	chainID := util.GetTestChainID()
  1410  	var nextBlockNumber uint64
  1411  
  1412  	lis, err := initPeer(chainID)
  1413  	if err != nil {
  1414  		t.Fail()
  1415  		t.Logf("Error creating peer: %s", err)
  1416  	}
  1417  
  1418  	nextBlockNumber++
  1419  
  1420  	defer finitPeer(lis, chainID)
  1421  
  1422  	for _, tc := range testCases {
  1423  		t.Run(tc.chaincodeType.String(), func(t *testing.T) {
  1424  
  1425  			if tc.chaincodeType == pb.ChaincodeSpec_JAVA && runtime.GOARCH != "amd64" {
  1426  				t.Skip("No Java chaincode support yet on non-x86_64.")
  1427  			}
  1428  
  1429  			var ctxt = context.Background()
  1430  
  1431  			cID := &pb.ChaincodeID{Name: generateChaincodeName(tc.chaincodeType), Path: tc.chaincodePath, Version: "0"}
  1432  			f := "init"
  1433  			spec := &pb.ChaincodeSpec{Type: tc.chaincodeType, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: util.ToChaincodeArgs(f)}}
  1434  
  1435  			cccid := ccprovider.NewCCContext(chainID, cID.Name, cID.Version, "", false, nil, nil)
  1436  			_, err = deploy(ctxt, cccid, spec, nextBlockNumber)
  1437  			nextBlockNumber++
  1438  			ccID := spec.ChaincodeId.Name
  1439  			if err != nil {
  1440  				t.Fail()
  1441  				t.Logf("Error initializing chaincode %s(%s)", ccID, err)
  1442  				theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec})
  1443  				return
  1444  			}
  1445  
  1446  			time.Sleep(time.Second)
  1447  
  1448  			args := util.ToChaincodeArgs("invoke", "i", "am", "satoshi")
  1449  
  1450  			spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: args}}
  1451  
  1452  			var ccevt *pb.ChaincodeEvent
  1453  			ccevt, _, _, err = invoke(ctxt, chainID, spec, nextBlockNumber, nil)
  1454  			nextBlockNumber++
  1455  
  1456  			if err != nil {
  1457  				t.Logf("Error invoking chaincode %s(%s)", ccID, err)
  1458  				t.Fail()
  1459  			}
  1460  
  1461  			if ccevt == nil {
  1462  				t.Logf("Error ccevt is nil %s(%s)", ccID, err)
  1463  				t.Fail()
  1464  			}
  1465  
  1466  			if ccevt.ChaincodeId != ccID {
  1467  				t.Logf("Error ccevt id(%s) != cid(%s)", ccevt.ChaincodeId, ccID)
  1468  				t.Fail()
  1469  			}
  1470  
  1471  			if strings.Index(string(ccevt.Payload), "i,am,satoshi") < 0 {
  1472  				t.Logf("Error expected event not found (%s)", string(ccevt.Payload))
  1473  				t.Fail()
  1474  			}
  1475  
  1476  			theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec})
  1477  		})
  1478  	}
  1479  
  1480  }
  1481  
  1482  // Test the execution of a chaincode that queries another chaincode
  1483  // example02 implements "query" as a function in Invoke. example05 calls example02
  1484  func TestChaincodeQueryChaincodeUsingInvoke(t *testing.T) {
  1485  	testForSkip(t)
  1486  	//this is essentially same as the ChaincodeInvokeChaincode now that
  1487  	//we don't distinguish between Invoke and Query (there's no separate "Query")
  1488  	t.Skip()
  1489  	chainID := util.GetTestChainID()
  1490  
  1491  	var peerLis net.Listener
  1492  	var err error
  1493  	if peerLis, err = initPeer(chainID); err != nil {
  1494  		t.Fail()
  1495  		t.Logf("Error registering user  %s", err)
  1496  		return
  1497  	}
  1498  
  1499  	defer finitPeer(peerLis, chainID)
  1500  
  1501  	var ctxt = context.Background()
  1502  
  1503  	// Deploy first chaincode
  1504  	url1 := "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02"
  1505  
  1506  	cID1 := &pb.ChaincodeID{Name: "example02", Path: url1, Version: "0"}
  1507  	f := "init"
  1508  	args := util.ToChaincodeArgs(f, "a", "100", "b", "200")
  1509  
  1510  	spec1 := &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID1, Input: &pb.ChaincodeInput{Args: args}}
  1511  
  1512  	sProp, prop := putils.MockSignedEndorserProposalOrPanic(util.GetTestChainID(), spec1, []byte([]byte("Alice")), nil)
  1513  	cccid1 := ccprovider.NewCCContext(chainID, "example02", "0", "", false, sProp, prop)
  1514  	var nextBlockNumber uint64
  1515  	_, err = deploy(ctxt, cccid1, spec1, nextBlockNumber)
  1516  	nextBlockNumber++
  1517  	ccID1 := spec1.ChaincodeId.Name
  1518  	if err != nil {
  1519  		theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1})
  1520  		t.Fail()
  1521  		t.Logf("Error initializing chaincode %s(%s)", ccID1, err)
  1522  		return
  1523  	}
  1524  
  1525  	time.Sleep(time.Second)
  1526  
  1527  	// Deploy second chaincode
  1528  	url2 := "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example05"
  1529  
  1530  	cID2 := &pb.ChaincodeID{Name: "example05", Path: url2, Version: "0"}
  1531  	f = "init"
  1532  	args = util.ToChaincodeArgs(f, "sum", "0")
  1533  
  1534  	spec2 := &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID2, Input: &pb.ChaincodeInput{Args: args}}
  1535  
  1536  	cccid2 := ccprovider.NewCCContext(chainID, "example05", "0", "", false, sProp, prop)
  1537  
  1538  	_, err = deploy(ctxt, cccid2, spec2, nextBlockNumber)
  1539  	nextBlockNumber++
  1540  	ccID2 := spec2.ChaincodeId.Name
  1541  	if err != nil {
  1542  		theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1})
  1543  		theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2})
  1544  		t.Fail()
  1545  		t.Logf("Error initializing chaincode %s(%s)", ccID2, err)
  1546  		return
  1547  	}
  1548  
  1549  	time.Sleep(time.Second)
  1550  
  1551  	// Invoke second chaincode, which will inturn query the first chaincode
  1552  	f = "invoke"
  1553  	args = util.ToChaincodeArgs(f, ccID1, "sum")
  1554  
  1555  	spec2 = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID2, Input: &pb.ChaincodeInput{Args: args}}
  1556  	// Invoke chaincode
  1557  	var retVal []byte
  1558  	_, _, retVal, err = invoke(ctxt, chainID, spec2, nextBlockNumber, []byte("Alice"))
  1559  	nextBlockNumber++
  1560  	if err != nil {
  1561  		theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1})
  1562  		theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2})
  1563  		t.Fail()
  1564  		t.Logf("Error invoking <%s>: %s", ccID2, err)
  1565  		return
  1566  	}
  1567  
  1568  	// Check the return value
  1569  	result, err := strconv.Atoi(string(retVal))
  1570  	if err != nil || result != 300 {
  1571  		theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1})
  1572  		theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2})
  1573  		t.Fail()
  1574  		t.Logf("Incorrect final state after transaction for <%s>: %s", ccID1, err)
  1575  		return
  1576  	}
  1577  
  1578  	// Query second chaincode, which will inturn query the first chaincode
  1579  	f = "query"
  1580  	args = util.ToChaincodeArgs(f, ccID1, "sum")
  1581  
  1582  	spec2 = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID2, Input: &pb.ChaincodeInput{Args: args}}
  1583  	// Invoke chaincode
  1584  	_, _, retVal, err = invoke(ctxt, chainID, spec2, nextBlockNumber, []byte("Alice"))
  1585  
  1586  	if err != nil {
  1587  		theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1})
  1588  		theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2})
  1589  		t.Fail()
  1590  		t.Logf("Error querying <%s>: %s", ccID2, err)
  1591  		return
  1592  	}
  1593  
  1594  	// Check the return value
  1595  	result, err = strconv.Atoi(string(retVal))
  1596  	if err != nil || result != 300 {
  1597  		theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1})
  1598  		theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2})
  1599  		t.Fail()
  1600  		t.Logf("Incorrect final value after query for <%s>: %s", ccID1, err)
  1601  		return
  1602  	}
  1603  
  1604  	theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1})
  1605  	theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2})
  1606  }
  1607  
  1608  // test that invoking a security-sensitive system chaincode fails
  1609  func TestChaincodeInvokesForbiddenSystemChaincode(t *testing.T) {
  1610  	testForSkip(t)
  1611  	chainID := util.GetTestChainID()
  1612  
  1613  	lis, err := initPeer(chainID)
  1614  	if err != nil {
  1615  		t.Fail()
  1616  		t.Logf("Error creating peer: %s", err)
  1617  	}
  1618  
  1619  	defer finitPeer(lis, chainID)
  1620  
  1621  	var ctxt = context.Background()
  1622  
  1623  	var nextBlockNumber uint64 = 1
  1624  
  1625  	// Deploy second chaincode
  1626  	url := "github.com/hyperledger/fabric/examples/chaincode/go/passthru"
  1627  
  1628  	cID := &pb.ChaincodeID{Name: "pthru", Path: url, Version: "0"}
  1629  	f := "init"
  1630  	args := util.ToChaincodeArgs(f)
  1631  
  1632  	spec := &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: args}}
  1633  
  1634  	cccid := ccprovider.NewCCContext(chainID, "pthru", "0", "", false, nil, nil)
  1635  
  1636  	_, err = deploy(ctxt, cccid, spec, nextBlockNumber)
  1637  	nextBlockNumber++
  1638  	ccID := spec.ChaincodeId.Name
  1639  	if err != nil {
  1640  		t.Fail()
  1641  		t.Logf("Error initializing chaincode %s(%s)", ccID, err)
  1642  		theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec})
  1643  		return
  1644  	}
  1645  
  1646  	time.Sleep(time.Second)
  1647  
  1648  	// send an invoke to pass thru to invoke "escc" system chaincode
  1649  	// this should fail
  1650  	args = util.ToChaincodeArgs("escc/"+chainID, "getid", chainID, "pthru")
  1651  
  1652  	spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: args}}
  1653  	// Invoke chaincode
  1654  	_, _, _, err = invoke(ctxt, chainID, spec, nextBlockNumber, nil)
  1655  	if err == nil {
  1656  		theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec})
  1657  		t.Logf("invoking <%s> should have failed", ccID)
  1658  		t.Fail()
  1659  		return
  1660  	}
  1661  }
  1662  
  1663  // Test the execution of a chaincode that invokes system chaincode
  1664  // uses the "pthru" chaincode to query "lscc" for the "pthru" chaincode
  1665  func TestChaincodeInvokesSystemChaincode(t *testing.T) {
  1666  	testForSkip(t)
  1667  	chainID := util.GetTestChainID()
  1668  
  1669  	lis, err := initPeer(chainID)
  1670  	if err != nil {
  1671  		t.Fail()
  1672  		t.Logf("Error creating peer: %s", err)
  1673  	}
  1674  
  1675  	defer finitPeer(lis, chainID)
  1676  
  1677  	var ctxt = context.Background()
  1678  
  1679  	var nextBlockNumber uint64 = 1
  1680  
  1681  	// Deploy second chaincode
  1682  	url := "github.com/hyperledger/fabric/examples/chaincode/go/passthru"
  1683  
  1684  	cID := &pb.ChaincodeID{Name: "pthru", Path: url, Version: "0"}
  1685  	f := "init"
  1686  	args := util.ToChaincodeArgs(f)
  1687  
  1688  	spec := &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: args}}
  1689  
  1690  	cccid := ccprovider.NewCCContext(chainID, "pthru", "0", "", false, nil, nil)
  1691  
  1692  	_, err = deploy(ctxt, cccid, spec, nextBlockNumber)
  1693  	nextBlockNumber++
  1694  	ccID := spec.ChaincodeId.Name
  1695  	if err != nil {
  1696  		t.Fail()
  1697  		t.Logf("Error initializing chaincode %s(%s)", ccID, err)
  1698  		theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec})
  1699  		return
  1700  	}
  1701  
  1702  	time.Sleep(time.Second)
  1703  
  1704  	//send an invoke to pass thru to query "lscc" system chaincode on chainID to get
  1705  	//information about "pthru"
  1706  	args = util.ToChaincodeArgs("lscc/"+chainID, "getid", chainID, "pthru")
  1707  
  1708  	spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: args}}
  1709  	// Invoke chaincode
  1710  	_, _, retval, err := invoke(ctxt, chainID, spec, nextBlockNumber, nil)
  1711  
  1712  	if err != nil {
  1713  		t.Fail()
  1714  		t.Logf("Error invoking <%s>: %s", ccID, err)
  1715  		theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec})
  1716  		return
  1717  	}
  1718  
  1719  	if string(retval) != "pthru" {
  1720  		t.Fail()
  1721  		t.Logf("Expected to get back \"pthru\" from lscc but got back %s", string(retval))
  1722  		theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec})
  1723  		return
  1724  	}
  1725  
  1726  	theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec})
  1727  }
  1728  
  1729  func TestChaincodeInitializeInitError(t *testing.T) {
  1730  	testForSkip(t)
  1731  	testCases := []struct {
  1732  		name          string
  1733  		chaincodeType pb.ChaincodeSpec_Type
  1734  		chaincodePath string
  1735  		args          []string
  1736  	}{
  1737  		{"NotSuccessResponse", pb.ChaincodeSpec_GOLANG, chaincodeExample02GolangPath, []string{"init", "not", "enough", "args"}},
  1738  		{"NotSuccessResponse", pb.ChaincodeSpec_JAVA, chaincodeExample02JavaPath, []string{"init", "not", "enough", "args"}},
  1739  		{"RuntimeException", pb.ChaincodeSpec_JAVA, chaincodeExample06JavaPath, []string{"runtimeException"}},
  1740  	}
  1741  
  1742  	channel := util.GetTestChainID()
  1743  
  1744  	for _, tc := range testCases {
  1745  		t.Run(tc.name+"_"+tc.chaincodeType.String(), func(t *testing.T) {
  1746  
  1747  			if tc.chaincodeType == pb.ChaincodeSpec_JAVA && runtime.GOARCH != "amd64" {
  1748  				t.Skip("No Java chaincode support yet on non-x86_64.")
  1749  			}
  1750  
  1751  			// initialize peer
  1752  			if listener, err := initPeer(channel); err != nil {
  1753  				t.Errorf("Error creating peer: %s", err)
  1754  			} else {
  1755  				defer finitPeer(listener, channel)
  1756  			}
  1757  
  1758  			var nextBlockNumber uint64
  1759  
  1760  			// the chaincode to install and instanciate
  1761  			chaincodeName := generateChaincodeName(tc.chaincodeType)
  1762  			chaincodePath := tc.chaincodePath
  1763  			chaincodeVersion := "1.0.0.0"
  1764  			chaincodeType := tc.chaincodeType
  1765  			chaincodeDeployArgs := util.ArrayToChaincodeArgs(tc.args)
  1766  
  1767  			// attempt to deploy chaincode
  1768  			_, chaincodeCtx, err := deployChaincode(context.Background(), chaincodeName, chaincodeVersion, chaincodeType, chaincodePath, chaincodeDeployArgs, nil, channel, nextBlockNumber)
  1769  
  1770  			// deploy should of failed
  1771  			if err == nil {
  1772  				stopChaincode(context.Background(), chaincodeCtx)
  1773  				t.Fatal("Deployment should have failed.")
  1774  			}
  1775  			t.Log(err)
  1776  
  1777  		})
  1778  	}
  1779  }
  1780  
  1781  func TestMain(m *testing.M) {
  1782  	var err error
  1783  
  1784  	msptesttools.LoadMSPSetupForTesting()
  1785  	signer, err = mspmgmt.GetLocalMSP().GetDefaultSigningIdentity()
  1786  	if err != nil {
  1787  		fmt.Print("Could not initialize msp/signer")
  1788  		os.Exit(-1)
  1789  		return
  1790  	}
  1791  
  1792  	setupTestConfig()
  1793  	os.Exit(m.Run())
  1794  }
  1795  
  1796  func setupTestConfig() {
  1797  	flag.Parse()
  1798  
  1799  	// Now set the configuration file
  1800  	viper.SetEnvPrefix("CORE")
  1801  	viper.AutomaticEnv()
  1802  	replacer := strings.NewReplacer(".", "_")
  1803  	viper.SetEnvKeyReplacer(replacer)
  1804  	viper.SetConfigName("chaincodetest") // name of config file (without extension)
  1805  	viper.AddConfigPath("./")            // path to look for the config file in
  1806  	err := viper.ReadInConfig()          // Find and read the config file
  1807  	if err != nil {                      // Handle errors reading the config file
  1808  		panic(fmt.Errorf("Fatal error config file: %s \n", err))
  1809  	}
  1810  
  1811  	testutil.SetupTestLogging()
  1812  
  1813  	// Set the number of maxprocs
  1814  	var numProcsDesired = viper.GetInt("peer.gomaxprocs")
  1815  	chaincodeLogger.Debugf("setting Number of procs to %d, was %d\n", numProcsDesired, runtime.GOMAXPROCS(numProcsDesired))
  1816  
  1817  	// Init the BCCSP
  1818  	err = factory.InitFactories(nil)
  1819  	if err != nil {
  1820  		panic(fmt.Errorf("Could not initialize BCCSP Factories [%s]", err))
  1821  	}
  1822  }
  1823  
  1824  func deployChaincode(ctx context.Context, name string, version string, chaincodeType pb.ChaincodeSpec_Type, path string, args [][]byte, creator []byte, channel string, nextBlockNumber uint64) ([]byte, *ccprovider.CCContext, error) {
  1825  	chaincodeSpec := &pb.ChaincodeSpec{
  1826  		ChaincodeId: &pb.ChaincodeID{
  1827  			Name:    name,
  1828  			Version: version,
  1829  			Path:    path,
  1830  		},
  1831  		Type: chaincodeType,
  1832  		Input: &pb.ChaincodeInput{
  1833  			Args: args,
  1834  		},
  1835  	}
  1836  
  1837  	signedProposal, proposal := putils.MockSignedEndorserProposal2OrPanic(channel, chaincodeSpec, signer)
  1838  
  1839  	chaincodeCtx := ccprovider.NewCCContext(channel, name, version, "", false, signedProposal, proposal)
  1840  
  1841  	result, err := deploy(ctx, chaincodeCtx, chaincodeSpec, nextBlockNumber)
  1842  	if err != nil {
  1843  		return nil, chaincodeCtx, fmt.Errorf("Error deploying <%s:%s>: %s", name, version, err)
  1844  	}
  1845  	return result, chaincodeCtx, nil
  1846  }
  1847  
  1848  var signer msp.SigningIdentity
  1849  
  1850  var rng *rand.Rand = rand.New(rand.NewSource(time.Now().UnixNano()))
  1851  
  1852  func generateChaincodeName(chaincodeType pb.ChaincodeSpec_Type) string {
  1853  	prefix := "cc_"
  1854  	switch chaincodeType {
  1855  	case pb.ChaincodeSpec_GOLANG:
  1856  		prefix = "cc_go_"
  1857  	case pb.ChaincodeSpec_JAVA:
  1858  		prefix = "cc_java_"
  1859  	case pb.ChaincodeSpec_NODE:
  1860  		prefix = "cc_js_"
  1861  	}
  1862  	return fmt.Sprintf("%s%06d", prefix, rng.Intn(999999))
  1863  }
  1864  
  1865  type CreatorPolicy struct {
  1866  	Creators [][]byte
  1867  }
  1868  
  1869  // Evaluate takes a set of SignedData and evaluates whether this set of signatures satisfies the policy
  1870  func (c *CreatorPolicy) Evaluate(signatureSet []*common.SignedData) error {
  1871  	for _, value := range c.Creators {
  1872  		if bytes.Compare(signatureSet[0].Identity, value) == 0 {
  1873  			return nil
  1874  		}
  1875  	}
  1876  	return fmt.Errorf("Creator not recognized [%s]", string(signatureSet[0].Identity))
  1877  }
  1878  
  1879  type mockPolicyCheckerFactory struct{}
  1880  
  1881  func (f *mockPolicyCheckerFactory) NewPolicyChecker() policy.PolicyChecker {
  1882  	return policy.NewPolicyChecker(
  1883  		peer.NewChannelPolicyManagerGetter(),
  1884  		&mocks.MockIdentityDeserializer{[]byte("Admin"), []byte("msg1")},
  1885  		&mocks.MockMSPPrincipalGetter{Principal: []byte("Admin")},
  1886  	)
  1887  }