github.com/adnan-c/fabric_e2e_couchdb@v0.6.1-preview.0.20170228180935-21ce6b23cf91/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  	"fmt"
    21  	"net"
    22  	"os"
    23  	"path/filepath"
    24  	"strconv"
    25  	"strings"
    26  	"sync"
    27  	"testing"
    28  	"time"
    29  
    30  	"github.com/golang/protobuf/proto"
    31  	"github.com/hyperledger/fabric/common/util"
    32  	"github.com/hyperledger/fabric/core/common/ccprovider"
    33  	"github.com/hyperledger/fabric/core/container"
    34  	"github.com/hyperledger/fabric/core/container/ccintf"
    35  	"github.com/hyperledger/fabric/core/ledger"
    36  	"github.com/hyperledger/fabric/core/ledger/ledgerconfig"
    37  	"github.com/hyperledger/fabric/core/ledger/ledgermgmt"
    38  	"github.com/hyperledger/fabric/core/peer"
    39  	"github.com/hyperledger/fabric/core/scc"
    40  	"github.com/hyperledger/fabric/msp"
    41  	mspmgmt "github.com/hyperledger/fabric/msp/mgmt"
    42  	"github.com/hyperledger/fabric/msp/mgmt/testtools"
    43  	"github.com/hyperledger/fabric/protos/common"
    44  	pb "github.com/hyperledger/fabric/protos/peer"
    45  	putils "github.com/hyperledger/fabric/protos/utils"
    46  	"github.com/spf13/viper"
    47  	"golang.org/x/net/context"
    48  	"google.golang.org/grpc"
    49  	"google.golang.org/grpc/credentials"
    50  )
    51  
    52  //initialize peer and start up. If security==enabled, login as vp
    53  func initPeer(chainIDs ...string) (net.Listener, error) {
    54  	//start clean
    55  	finitPeer(nil, chainIDs...)
    56  
    57  	peer.MockInitialize()
    58  
    59  	var opts []grpc.ServerOption
    60  	if viper.GetBool("peer.tls.enabled") {
    61  		creds, err := credentials.NewServerTLSFromFile(viper.GetString("peer.tls.cert.file"), viper.GetString("peer.tls.key.file"))
    62  		if err != nil {
    63  			return nil, fmt.Errorf("Failed to generate credentials %v", err)
    64  		}
    65  		opts = []grpc.ServerOption{grpc.Creds(creds)}
    66  	}
    67  	grpcServer := grpc.NewServer(opts...)
    68  
    69  	peerAddress, err := peer.GetLocalAddress()
    70  	if err != nil {
    71  		return nil, fmt.Errorf("Error obtaining peer address: %s", err)
    72  	}
    73  	lis, err := net.Listen("tcp", peerAddress)
    74  	if err != nil {
    75  		return nil, fmt.Errorf("Error starting peer listener %s", err)
    76  	}
    77  
    78  	getPeerEndpoint := func() (*pb.PeerEndpoint, error) {
    79  		return &pb.PeerEndpoint{Id: &pb.PeerID{Name: "testpeer"}, Address: peerAddress}, nil
    80  	}
    81  
    82  	ccStartupTimeout := time.Duration(chaincodeStartupTimeoutDefault) * time.Millisecond
    83  	pb.RegisterChaincodeSupportServer(grpcServer, NewChaincodeSupport(getPeerEndpoint, false, ccStartupTimeout))
    84  
    85  	scc.RegisterSysCCs()
    86  
    87  	for _, id := range chainIDs {
    88  		scc.DeDeploySysCCs(id)
    89  		if err = peer.MockCreateChain(id); err != nil {
    90  			closeListenerAndSleep(lis)
    91  			return nil, err
    92  		}
    93  		scc.DeploySysCCs(id)
    94  	}
    95  
    96  	go grpcServer.Serve(lis)
    97  
    98  	return lis, nil
    99  }
   100  
   101  func finitPeer(lis net.Listener, chainIDs ...string) {
   102  	if lis != nil {
   103  		for _, c := range chainIDs {
   104  			scc.DeDeploySysCCs(c)
   105  			if lgr := peer.GetLedger(c); lgr != nil {
   106  				lgr.Close()
   107  			}
   108  		}
   109  		closeListenerAndSleep(lis)
   110  	}
   111  	ledgermgmt.CleanupTestEnv()
   112  	ledgerPath := viper.GetString("peer.fileSystemPath")
   113  	os.RemoveAll(ledgerPath)
   114  	os.RemoveAll(filepath.Join(os.TempDir(), "hyperledger"))
   115  }
   116  
   117  func startTxSimulation(ctxt context.Context, chainID string) (context.Context, ledger.TxSimulator, error) {
   118  	lgr := peer.GetLedger(chainID)
   119  	txsim, err := lgr.NewTxSimulator()
   120  	if err != nil {
   121  		return nil, nil, err
   122  	}
   123  
   124  	ctxt = context.WithValue(ctxt, TXSimulatorKey, txsim)
   125  	return ctxt, txsim, nil
   126  }
   127  
   128  func endTxSimulationCDS(chainID string, _ string, txsim ledger.TxSimulator, payload []byte, commit bool, cds *pb.ChaincodeDeploymentSpec, blockNumber uint64) error {
   129  	// get serialized version of the signer
   130  	ss, err := signer.Serialize()
   131  	if err != nil {
   132  		return err
   133  	}
   134  	// get a proposal - we need it to get a transaction
   135  	prop, _, err := putils.CreateDeployProposalFromCDS(chainID, cds, ss, nil, nil, nil)
   136  	if err != nil {
   137  		return err
   138  	}
   139  
   140  	return endTxSimulation(chainID, txsim, payload, commit, prop, blockNumber)
   141  }
   142  
   143  func endTxSimulationCIS(chainID string, _ string, txsim ledger.TxSimulator, payload []byte, commit bool, cis *pb.ChaincodeInvocationSpec, blockNumber uint64) error {
   144  	// get serialized version of the signer
   145  	ss, err := signer.Serialize()
   146  	if err != nil {
   147  		return err
   148  	}
   149  	// get a proposal - we need it to get a transaction
   150  	prop, _, err := putils.CreateProposalFromCIS(common.HeaderType_ENDORSER_TRANSACTION, chainID, cis, ss)
   151  	if err != nil {
   152  		return err
   153  	}
   154  
   155  	return endTxSimulation(chainID, txsim, payload, commit, prop, blockNumber)
   156  }
   157  
   158  //getting a crash from ledger.Commit when doing concurrent invokes
   159  //It is likely intentional that ledger.Commit is serial (ie, the real
   160  //Committer will invoke this serially on each block). Mimic that here
   161  //by forcing serialization of the ledger.Commit call.
   162  //
   163  //NOTE-this should NOT have any effect on the older serial tests.
   164  //This affects only the tests in concurrent_test.go which call these
   165  //concurrently (100 concurrent invokes followed by 100 concurrent queries)
   166  var _commitLock_ sync.Mutex
   167  
   168  func endTxSimulation(chainID string, txsim ledger.TxSimulator, _ []byte, commit bool, prop *pb.Proposal, blockNumber uint64) error {
   169  	txsim.Done()
   170  	if lgr := peer.GetLedger(chainID); lgr != nil {
   171  		if commit {
   172  			var txSimulationResults []byte
   173  			var err error
   174  
   175  			//get simulation results
   176  			if txSimulationResults, err = txsim.GetTxSimulationResults(); err != nil {
   177  				return err
   178  			}
   179  
   180  			// assemble a (signed) proposal response message
   181  			resp, err := putils.CreateProposalResponse(prop.Header, prop.Payload, &pb.Response{Status: 200}, txSimulationResults, nil, nil, signer)
   182  			if err != nil {
   183  				return err
   184  			}
   185  
   186  			// get the envelope
   187  			env, err := putils.CreateSignedTx(prop, signer, resp)
   188  			if err != nil {
   189  				return err
   190  			}
   191  
   192  			envBytes, err := putils.GetBytesEnvelope(env)
   193  			if err != nil {
   194  				return err
   195  			}
   196  
   197  			//create the block with 1 transaction
   198  			block := common.NewBlock(blockNumber, []byte{})
   199  			block.Data.Data = [][]byte{envBytes}
   200  			//commit the block
   201  
   202  			//see comment on _commitLock_
   203  			_commitLock_.Lock()
   204  			defer _commitLock_.Unlock()
   205  			if err := lgr.Commit(block); err != nil {
   206  				return err
   207  			}
   208  		}
   209  	}
   210  
   211  	return nil
   212  }
   213  
   214  // Build a chaincode.
   215  func getDeploymentSpec(_ context.Context, spec *pb.ChaincodeSpec) (*pb.ChaincodeDeploymentSpec, error) {
   216  	fmt.Printf("getting deployment spec for chaincode spec: %v\n", spec)
   217  	codePackageBytes, err := container.GetChaincodePackageBytes(spec)
   218  	if err != nil {
   219  		return nil, err
   220  	}
   221  	cdDeploymentSpec := &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec, CodePackage: codePackageBytes}
   222  	return cdDeploymentSpec, nil
   223  }
   224  
   225  //getDeployLCCCSpec gets the spec for the chaincode deployment to be sent to LCCC
   226  func getDeployLCCCSpec(chainID string, cds *pb.ChaincodeDeploymentSpec) (*pb.ChaincodeInvocationSpec, error) {
   227  	b, err := proto.Marshal(cds)
   228  	if err != nil {
   229  		return nil, err
   230  	}
   231  
   232  	sysCCVers := util.GetSysCCVersion()
   233  
   234  	//wrap the deployment in an invocation spec to lccc...
   235  	lcccSpec := &pb.ChaincodeInvocationSpec{ChaincodeSpec: &pb.ChaincodeSpec{Type: pb.ChaincodeSpec_GOLANG, ChaincodeId: &pb.ChaincodeID{Name: "lccc", Version: sysCCVers}, Input: &pb.ChaincodeInput{Args: [][]byte{[]byte("deploy"), []byte(chainID), b}}}}
   236  
   237  	return lcccSpec, nil
   238  }
   239  
   240  // Deploy a chaincode - i.e., build and initialize.
   241  func deploy(ctx context.Context, cccid *ccprovider.CCContext, spec *pb.ChaincodeSpec, blockNumber uint64) (b []byte, err error) {
   242  	// First build and get the deployment spec
   243  	cdDeploymentSpec, err := getDeploymentSpec(ctx, spec)
   244  	if err != nil {
   245  		return nil, err
   246  	}
   247  
   248  	return deploy2(ctx, cccid, cdDeploymentSpec, blockNumber)
   249  }
   250  
   251  func deploy2(ctx context.Context, cccid *ccprovider.CCContext, chaincodeDeploymentSpec *pb.ChaincodeDeploymentSpec, blockNumber uint64) (b []byte, err error) {
   252  	cis, err := getDeployLCCCSpec(cccid.ChainID, chaincodeDeploymentSpec)
   253  	if err != nil {
   254  		return nil, fmt.Errorf("Error creating lccc spec : %s\n", err)
   255  	}
   256  
   257  	ctx, txsim, err := startTxSimulation(ctx, cccid.ChainID)
   258  	if err != nil {
   259  		return nil, fmt.Errorf("Failed to get handle to simulator: %s ", err)
   260  	}
   261  
   262  	uuid := util.GenerateUUID()
   263  
   264  	cccid.TxID = uuid
   265  
   266  	defer func() {
   267  		//no error, lets try commit
   268  		if err == nil {
   269  			//capture returned error from commit
   270  			err = endTxSimulationCDS(cccid.ChainID, uuid, txsim, []byte("deployed"), true, chaincodeDeploymentSpec, blockNumber)
   271  		} else {
   272  			//there was an error, just close simulation and return that
   273  			endTxSimulationCDS(cccid.ChainID, uuid, txsim, []byte("deployed"), false, chaincodeDeploymentSpec, blockNumber)
   274  		}
   275  	}()
   276  
   277  	//ignore existence errors
   278  	ccprovider.PutChaincodeIntoFS(chaincodeDeploymentSpec)
   279  
   280  	sysCCVers := util.GetSysCCVersion()
   281  	lcccid := ccprovider.NewCCContext(cccid.ChainID, cis.ChaincodeSpec.ChaincodeId.Name, sysCCVers, uuid, true, nil, nil)
   282  
   283  	//write to lccc
   284  	if _, _, err = ExecuteWithErrorFilter(ctx, lcccid, cis); err != nil {
   285  		return nil, fmt.Errorf("Error deploying chaincode: %s", err)
   286  	}
   287  
   288  	if b, _, err = ExecuteWithErrorFilter(ctx, cccid, chaincodeDeploymentSpec); err != nil {
   289  		return nil, fmt.Errorf("Error deploying chaincode: %s", err)
   290  	}
   291  
   292  	return b, nil
   293  }
   294  
   295  // Invoke a chaincode.
   296  func invoke(ctx context.Context, chainID string, spec *pb.ChaincodeSpec, blockNumber uint64) (ccevt *pb.ChaincodeEvent, uuid string, retval []byte, err error) {
   297  	return invokeWithVersion(ctx, chainID, "0", spec, blockNumber)
   298  }
   299  
   300  // Invoke a chaincode with version (needed for upgrade)
   301  func invokeWithVersion(ctx context.Context, chainID string, version string, spec *pb.ChaincodeSpec, blockNumber uint64) (ccevt *pb.ChaincodeEvent, uuid string, retval []byte, err error) {
   302  	cdInvocationSpec := &pb.ChaincodeInvocationSpec{ChaincodeSpec: spec}
   303  
   304  	// Now create the Transactions message and send to Peer.
   305  	uuid = util.GenerateUUID()
   306  
   307  	var txsim ledger.TxSimulator
   308  	ctx, txsim, err = startTxSimulation(ctx, chainID)
   309  	if err != nil {
   310  		return nil, uuid, nil, fmt.Errorf("Failed to get handle to simulator: %s ", err)
   311  	}
   312  
   313  	defer func() {
   314  		//no error, lets try commit
   315  		if err == nil {
   316  			//capture returned error from commit
   317  			err = endTxSimulationCIS(chainID, uuid, txsim, []byte("invoke"), true, cdInvocationSpec, blockNumber)
   318  		} else {
   319  			//there was an error, just close simulation and return that
   320  			endTxSimulationCIS(chainID, uuid, txsim, []byte("invoke"), false, cdInvocationSpec, blockNumber)
   321  		}
   322  	}()
   323  
   324  	cccid := ccprovider.NewCCContext(chainID, cdInvocationSpec.ChaincodeSpec.ChaincodeId.Name, version, uuid, false, nil, nil)
   325  	retval, ccevt, err = ExecuteWithErrorFilter(ctx, cccid, cdInvocationSpec)
   326  	if err != nil {
   327  		return nil, uuid, nil, fmt.Errorf("Error invoking chaincode: %s", err)
   328  	}
   329  
   330  	return ccevt, uuid, retval, err
   331  }
   332  
   333  func closeListenerAndSleep(l net.Listener) {
   334  	if l != nil {
   335  		l.Close()
   336  		time.Sleep(2 * time.Second)
   337  	}
   338  }
   339  
   340  func executeDeployTransaction(t *testing.T, chainID string, name string, url string) {
   341  	lis, err := initPeer(chainID)
   342  	if err != nil {
   343  		t.Fail()
   344  		t.Logf("Error creating peer: %s", err)
   345  	}
   346  
   347  	defer finitPeer(lis, chainID)
   348  
   349  	var ctxt = context.Background()
   350  
   351  	f := "init"
   352  	args := util.ToChaincodeArgs(f, "a", "100", "b", "200")
   353  	spec := &pb.ChaincodeSpec{Type: 1, ChaincodeId: &pb.ChaincodeID{Name: name, Path: url, Version: "0"}, Input: &pb.ChaincodeInput{Args: args}}
   354  
   355  	cccid := ccprovider.NewCCContext(chainID, name, "0", "", false, nil, nil)
   356  
   357  	_, err = deploy(ctxt, cccid, spec, 0)
   358  
   359  	cID := spec.ChaincodeId.Name
   360  	if err != nil {
   361  		theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec})
   362  		t.Fail()
   363  		t.Logf("Error deploying <%s>: %s", cID, err)
   364  		return
   365  	}
   366  
   367  	theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec})
   368  }
   369  
   370  // chaincodeQueryChaincode function
   371  func _(chainID string, _ string) error {
   372  	var ctxt = context.Background()
   373  
   374  	// Deploy first chaincode
   375  	url1 := "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02"
   376  
   377  	cID1 := &pb.ChaincodeID{Name: "example02", Path: url1, Version: "0"}
   378  	f := "init"
   379  	args := util.ToChaincodeArgs(f, "a", "100", "b", "200")
   380  
   381  	spec1 := &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID1, Input: &pb.ChaincodeInput{Args: args}}
   382  
   383  	cccid1 := ccprovider.NewCCContext(chainID, "example02", "0", "", false, nil, nil)
   384  
   385  	var nextBlockNumber uint64
   386  
   387  	_, err := deploy(ctxt, cccid1, spec1, nextBlockNumber)
   388  	nextBlockNumber++
   389  
   390  	ccID1 := spec1.ChaincodeId.Name
   391  	if err != nil {
   392  		theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1})
   393  		return fmt.Errorf("Error initializing chaincode %s(%s)", ccID1, err)
   394  	}
   395  
   396  	time.Sleep(time.Second)
   397  
   398  	// Deploy second chaincode
   399  	url2 := "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example05"
   400  
   401  	cID2 := &pb.ChaincodeID{Name: "example05", Path: url2, Version: "0"}
   402  	f = "init"
   403  	args = util.ToChaincodeArgs(f, "sum", "0")
   404  
   405  	spec2 := &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID2, Input: &pb.ChaincodeInput{Args: args}}
   406  
   407  	cccid2 := ccprovider.NewCCContext(chainID, "example05", "0", "", false, nil, nil)
   408  
   409  	_, err = deploy(ctxt, cccid2, spec2, nextBlockNumber)
   410  	nextBlockNumber++
   411  	ccID2 := spec2.ChaincodeId.Name
   412  	if err != nil {
   413  		theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1})
   414  		theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2})
   415  		return fmt.Errorf("Error initializing chaincode %s(%s)", ccID2, err)
   416  	}
   417  
   418  	time.Sleep(time.Second)
   419  
   420  	// Invoke second chaincode, which will inturn query the first chaincode
   421  	f = "invoke"
   422  	args = util.ToChaincodeArgs(f, ccID1, "sum")
   423  
   424  	spec2 = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID2, Input: &pb.ChaincodeInput{Args: args}}
   425  	// Invoke chaincode
   426  	var retVal []byte
   427  	_, _, retVal, err = invoke(ctxt, chainID, spec2, nextBlockNumber)
   428  	nextBlockNumber++
   429  
   430  	if err != nil {
   431  		theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1})
   432  		theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2})
   433  		return fmt.Errorf("Error invoking <%s>: %s", ccID2, err)
   434  	}
   435  
   436  	// Check the return value
   437  	result, err := strconv.Atoi(string(retVal))
   438  	if err != nil || result != 300 {
   439  		theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1})
   440  		theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2})
   441  		return fmt.Errorf("Incorrect final state after transaction for <%s>: %s", ccID1, err)
   442  	}
   443  
   444  	// Query second chaincode, which will inturn query the first chaincode
   445  	f = "query"
   446  	args = util.ToChaincodeArgs(f, ccID1, "sum")
   447  
   448  	spec2 = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID2, Input: &pb.ChaincodeInput{Args: args}}
   449  	// Invoke chaincode
   450  	_, _, retVal, err = invoke(ctxt, chainID, spec2, nextBlockNumber)
   451  
   452  	if err != nil {
   453  		theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1})
   454  		theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2})
   455  		return fmt.Errorf("Error querying <%s>: %s", ccID2, err)
   456  	}
   457  
   458  	// Check the return value
   459  	result, err = strconv.Atoi(string(retVal))
   460  	if err != nil || result != 300 {
   461  		theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1})
   462  		theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2})
   463  		return fmt.Errorf("Incorrect final value after query for <%s>: %s", ccID1, err)
   464  	}
   465  
   466  	theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1})
   467  	theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2})
   468  
   469  	return nil
   470  }
   471  
   472  // Test deploy of a transaction
   473  func TestExecuteDeployTransaction(t *testing.T) {
   474  	chainID := util.GetTestChainID()
   475  
   476  	executeDeployTransaction(t, chainID, "example01", "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example01")
   477  }
   478  
   479  // Test deploy of a transaction with a GOPATH with multiple elements
   480  func TestGopathExecuteDeployTransaction(t *testing.T) {
   481  	chainID := util.GetTestChainID()
   482  
   483  	// add a trailing slash to GOPATH
   484  	// and a couple of elements - it doesn't matter what they are
   485  	os.Setenv("GOPATH", os.Getenv("GOPATH")+string(os.PathSeparator)+string(os.PathListSeparator)+"/tmp/foo"+string(os.PathListSeparator)+"/tmp/bar")
   486  	executeDeployTransaction(t, chainID, "example01", "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example01")
   487  }
   488  
   489  // Disable this temporarily.
   490  // TODO: Need to enable this after update chaincode interface of chaincode repo.
   491  // Test deploy of a transaction with a chaincode over HTTP.
   492  //func TestHTTPExecuteDeployTransaction(t *testing.T) {
   493  //	chainID := util.GetTestChainID()
   494  
   495  //	// The chaincode used here cannot be from the fabric repo
   496  //	// itself or it won't be downloaded because it will be found
   497  //	// in GOPATH, which would defeat the test
   498  //	executeDeployTransaction(t, chainID, "example01", "http://gopkg.in/mastersingh24/fabric-test-resources.v1")
   499  //}
   500  
   501  // Check the correctness of the final state after transaction execution.
   502  func checkFinalState(cccid *ccprovider.CCContext) error {
   503  	_, txsim, err := startTxSimulation(context.Background(), cccid.ChainID)
   504  	if err != nil {
   505  		return fmt.Errorf("Failed to get handle to simulator: %s ", err)
   506  	}
   507  
   508  	defer txsim.Done()
   509  
   510  	cName := cccid.GetCanonicalName()
   511  
   512  	// Invoke ledger to get state
   513  	var Aval, Bval int
   514  	resbytes, resErr := txsim.GetState(cccid.Name, "a")
   515  	if resErr != nil {
   516  		return fmt.Errorf("Error retrieving state from ledger for <%s>: %s", cName, resErr)
   517  	}
   518  	fmt.Printf("Got string: %s\n", string(resbytes))
   519  	Aval, resErr = strconv.Atoi(string(resbytes))
   520  	if resErr != nil {
   521  		return fmt.Errorf("Error retrieving state from ledger for <%s>: %s", cName, resErr)
   522  	}
   523  	if Aval != 90 {
   524  		return fmt.Errorf("Incorrect result. Aval %d != 90 <%s>", Aval, cName)
   525  	}
   526  
   527  	resbytes, resErr = txsim.GetState(cccid.Name, "b")
   528  	if resErr != nil {
   529  		return fmt.Errorf("Error retrieving state from ledger for <%s>: %s", cName, resErr)
   530  	}
   531  	Bval, resErr = strconv.Atoi(string(resbytes))
   532  	if resErr != nil {
   533  		return fmt.Errorf("Error retrieving state from ledger for <%s>: %s", cName, resErr)
   534  	}
   535  	if Bval != 210 {
   536  		return fmt.Errorf("Incorrect result. Bval %d != 210 <%s>", Bval, cName)
   537  	}
   538  
   539  	// Success
   540  	fmt.Printf("Aval = %d, Bval = %d\n", Aval, Bval)
   541  	return nil
   542  }
   543  
   544  // Invoke chaincode_example02
   545  func invokeExample02Transaction(ctxt context.Context, cccid *ccprovider.CCContext, cID *pb.ChaincodeID, args []string, destroyImage bool) error {
   546  
   547  	var nextBlockNumber uint64
   548  
   549  	f := "init"
   550  	argsDeploy := util.ToChaincodeArgs(f, "a", "100", "b", "200")
   551  	spec := &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: argsDeploy}}
   552  	_, err := deploy(ctxt, cccid, spec, nextBlockNumber)
   553  	nextBlockNumber++
   554  	ccID := spec.ChaincodeId.Name
   555  	if err != nil {
   556  		return fmt.Errorf("Error deploying <%s>: %s", ccID, err)
   557  	}
   558  
   559  	time.Sleep(time.Second)
   560  
   561  	if destroyImage {
   562  		theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec})
   563  		dir := container.DestroyImageReq{CCID: ccintf.CCID{ChaincodeSpec: spec, NetworkID: theChaincodeSupport.peerNetworkID, PeerID: theChaincodeSupport.peerID, ChainID: cccid.ChainID}, Force: true, NoPrune: true}
   564  
   565  		_, err = container.VMCProcess(ctxt, container.DOCKER, dir)
   566  		if err != nil {
   567  			err = fmt.Errorf("Error destroying image: %s", err)
   568  			return err
   569  		}
   570  	}
   571  
   572  	f = "invoke"
   573  	invokeArgs := append([]string{f}, args...)
   574  	spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: util.ToChaincodeArgs(invokeArgs...)}}
   575  	_, uuid, _, err := invoke(ctxt, cccid.ChainID, spec, nextBlockNumber)
   576  	nextBlockNumber++
   577  	if err != nil {
   578  		return fmt.Errorf("Error invoking <%s>: %s", cccid.Name, err)
   579  	}
   580  
   581  	cccid.TxID = uuid
   582  	err = checkFinalState(cccid)
   583  	if err != nil {
   584  		return fmt.Errorf("Incorrect final state after transaction for <%s>: %s", ccID, err)
   585  	}
   586  
   587  	// Test for delete state
   588  	f = "delete"
   589  	delArgs := util.ToChaincodeArgs(f, "a")
   590  	spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: delArgs}}
   591  	_, _, _, err = invoke(ctxt, cccid.ChainID, spec, nextBlockNumber)
   592  	if err != nil {
   593  		return fmt.Errorf("Error deleting state in <%s>: %s", cccid.Name, err)
   594  	}
   595  
   596  	return nil
   597  }
   598  
   599  func TestExecuteInvokeTransaction(t *testing.T) {
   600  	chainID := util.GetTestChainID()
   601  
   602  	lis, err := initPeer(chainID)
   603  	if err != nil {
   604  		t.Fail()
   605  		t.Logf("Error creating peer: %s", err)
   606  	}
   607  
   608  	defer finitPeer(lis, chainID)
   609  
   610  	var ctxt = context.Background()
   611  
   612  	cccid := ccprovider.NewCCContext(chainID, "example02", "0", "", false, nil, nil)
   613  	url := "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02"
   614  	ccID := &pb.ChaincodeID{Name: "example02", Path: url, Version: "0"}
   615  
   616  	args := []string{"a", "b", "10"}
   617  	err = invokeExample02Transaction(ctxt, cccid, ccID, args, true)
   618  	if err != nil {
   619  		t.Fail()
   620  		t.Logf("Error invoking transaction: %s", err)
   621  	} else {
   622  		fmt.Print("Invoke test passed\n")
   623  		t.Log("Invoke test passed")
   624  	}
   625  
   626  	theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: ccID}})
   627  }
   628  
   629  // Test the execution of an invalid transaction.
   630  func TestExecuteInvokeInvalidTransaction(t *testing.T) {
   631  	chainID := util.GetTestChainID()
   632  
   633  	lis, err := initPeer(chainID)
   634  	if err != nil {
   635  		t.Fail()
   636  		t.Logf("Error creating peer: %s", err)
   637  	}
   638  
   639  	defer finitPeer(lis, chainID)
   640  
   641  	var ctxt = context.Background()
   642  
   643  	url := "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02"
   644  	ccID := &pb.ChaincodeID{Name: "example02", Path: url, Version: "0"}
   645  
   646  	cccid := ccprovider.NewCCContext(chainID, "example02", "0", "", false, nil, nil)
   647  
   648  	//FAIL, FAIL!
   649  	args := []string{"x", "-1"}
   650  	err = invokeExample02Transaction(ctxt, cccid, ccID, args, false)
   651  
   652  	//this HAS to fail with expectedDeltaStringPrefix
   653  	if err != nil {
   654  		errStr := err.Error()
   655  		t.Logf("Got error %s\n", errStr)
   656  		t.Log("InvalidInvoke test passed")
   657  		theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: ccID}})
   658  
   659  		return
   660  	}
   661  
   662  	t.Fail()
   663  	t.Logf("Error invoking transaction %s", err)
   664  
   665  	theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: ccID}})
   666  }
   667  
   668  // Test the execution of a chaincode that invokes another chaincode.
   669  func TestChaincodeInvokeChaincode(t *testing.T) {
   670  	chainID := util.GetTestChainID()
   671  
   672  	lis, err := initPeer(chainID)
   673  	if err != nil {
   674  		t.Fail()
   675  		t.Logf("Error creating peer: %s", err)
   676  	}
   677  
   678  	defer finitPeer(lis, chainID)
   679  
   680  	err = runChaincodeInvokeChaincode(t, chainID, "")
   681  	if err != nil {
   682  		t.Fail()
   683  		t.Logf("Failed chaincode invoke chaincode : %s", err)
   684  		closeListenerAndSleep(lis)
   685  		return
   686  	}
   687  
   688  	closeListenerAndSleep(lis)
   689  }
   690  
   691  func runChaincodeInvokeChaincode(t *testing.T, chainID string, _ string) (err error) {
   692  	var ctxt = context.Background()
   693  
   694  	// Deploy first chaincode
   695  	url1 := "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02"
   696  
   697  	cID1 := &pb.ChaincodeID{Name: "example02", Path: url1, Version: "0"}
   698  	f := "init"
   699  	args := util.ToChaincodeArgs(f, "a", "100", "b", "200")
   700  
   701  	spec1 := &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID1, Input: &pb.ChaincodeInput{Args: args}}
   702  
   703  	cccid1 := ccprovider.NewCCContext(chainID, "example02", "0", "", false, nil, nil)
   704  
   705  	var nextBlockNumber uint64
   706  
   707  	_, err = deploy(ctxt, cccid1, spec1, nextBlockNumber)
   708  	nextBlockNumber++
   709  	ccID1 := spec1.ChaincodeId.Name
   710  	if err != nil {
   711  		t.Fail()
   712  		t.Logf("Error initializing chaincode %s(%s)", ccID1, err)
   713  		theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1})
   714  		return
   715  	}
   716  
   717  	t.Logf("deployed chaincode_example02 got cID1:% s,\n ccID1:% s", cID1, ccID1)
   718  
   719  	time.Sleep(time.Second)
   720  
   721  	// Deploy second chaincode
   722  	url2 := "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example04"
   723  
   724  	cID2 := &pb.ChaincodeID{Name: "example04", Path: url2, Version: "0"}
   725  	f = "init"
   726  	args = util.ToChaincodeArgs(f, "e", "0")
   727  
   728  	spec2 := &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID2, Input: &pb.ChaincodeInput{Args: args}}
   729  
   730  	cccid2 := ccprovider.NewCCContext(chainID, "example04", "0", "", false, nil, nil)
   731  
   732  	_, err = deploy(ctxt, cccid2, spec2, nextBlockNumber)
   733  	nextBlockNumber++
   734  	ccID2 := spec2.ChaincodeId.Name
   735  	if err != nil {
   736  		t.Fail()
   737  		t.Logf("Error initializing chaincode %s(%s)", ccID2, err)
   738  		theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1})
   739  		theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2})
   740  		return
   741  	}
   742  
   743  	time.Sleep(time.Second)
   744  
   745  	// Invoke second chaincode passing the first chaincode's name as first param,
   746  	// which will inturn invoke the first chaincode
   747  	f = "invoke"
   748  	cid := spec1.ChaincodeId.Name
   749  	args = util.ToChaincodeArgs(f, cid, "e", "1")
   750  
   751  	spec2 = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID2, Input: &pb.ChaincodeInput{Args: args}}
   752  	// Invoke chaincode
   753  	var uuid string
   754  	_, uuid, _, err = invoke(ctxt, chainID, spec2, nextBlockNumber)
   755  
   756  	if err != nil {
   757  		t.Fail()
   758  		t.Logf("Error invoking <%s>: %s", ccID2, err)
   759  		theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1})
   760  		theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2})
   761  		return
   762  	}
   763  
   764  	cccid1.TxID = uuid
   765  
   766  	// Check the state in the ledger
   767  	err = checkFinalState(cccid1)
   768  	if err != nil {
   769  		t.Fail()
   770  		t.Logf("Incorrect final state after transaction for <%s>: %s", ccID1, err)
   771  		theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1})
   772  		theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2})
   773  		return
   774  	}
   775  
   776  	theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1})
   777  	theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2})
   778  
   779  	return
   780  }
   781  
   782  // Test the execution of a chaincode that invokes another chaincode with wrong parameters. Should receive error from
   783  // from the called chaincode
   784  func TestChaincodeInvokeChaincodeErrorCase(t *testing.T) {
   785  	chainID := util.GetTestChainID()
   786  
   787  	lis, err := initPeer(chainID)
   788  	if err != nil {
   789  		t.Fail()
   790  		t.Logf("Error creating peer: %s", err)
   791  	}
   792  
   793  	defer finitPeer(lis, chainID)
   794  
   795  	var ctxt = context.Background()
   796  
   797  	// Deploy first chaincode
   798  	url1 := "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02"
   799  
   800  	cID1 := &pb.ChaincodeID{Name: "example02", Path: url1, Version: "0"}
   801  	f := "init"
   802  	args := util.ToChaincodeArgs(f, "a", "100", "b", "200")
   803  
   804  	spec1 := &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID1, Input: &pb.ChaincodeInput{Args: args}}
   805  
   806  	cccid1 := ccprovider.NewCCContext(chainID, "example02", "0", "", false, nil, nil)
   807  
   808  	var nextBlockNumber uint64
   809  
   810  	_, err = deploy(ctxt, cccid1, spec1, nextBlockNumber)
   811  	nextBlockNumber++
   812  	ccID1 := spec1.ChaincodeId.Name
   813  	if err != nil {
   814  		t.Fail()
   815  		t.Logf("Error initializing chaincode %s(%s)", ccID1, err)
   816  		theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1})
   817  		return
   818  	}
   819  
   820  	time.Sleep(time.Second)
   821  
   822  	// Deploy second chaincode
   823  	url2 := "github.com/hyperledger/fabric/examples/chaincode/go/passthru"
   824  
   825  	cID2 := &pb.ChaincodeID{Name: "pthru", Path: url2, Version: "0"}
   826  	f = "init"
   827  	args = util.ToChaincodeArgs(f)
   828  
   829  	spec2 := &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID2, Input: &pb.ChaincodeInput{Args: args}}
   830  
   831  	cccid2 := ccprovider.NewCCContext(chainID, "pthru", "0", "", false, nil, nil)
   832  
   833  	_, err = deploy(ctxt, cccid2, spec2, nextBlockNumber)
   834  	nextBlockNumber++
   835  	ccID2 := spec2.ChaincodeId.Name
   836  	if err != nil {
   837  		t.Fail()
   838  		t.Logf("Error initializing chaincode %s(%s)", ccID2, err)
   839  		theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1})
   840  		theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2})
   841  		return
   842  	}
   843  
   844  	time.Sleep(time.Second)
   845  
   846  	// Invoke second chaincode, which will inturn invoke the first chaincode but pass bad params
   847  	f = ccID1
   848  	args = util.ToChaincodeArgs(f, "invoke", "a")
   849  
   850  	spec2 = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID2, Input: &pb.ChaincodeInput{Args: args}}
   851  	// Invoke chaincode
   852  	_, _, _, err = invoke(ctxt, chainID, spec2, nextBlockNumber)
   853  
   854  	if err == nil {
   855  		t.Fail()
   856  		t.Logf("Error invoking <%s>: %s", ccID2, err)
   857  		theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1})
   858  		theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2})
   859  		return
   860  	}
   861  
   862  	if strings.Index(err.Error(), "Error invoking chaincode: Incorrect number of arguments. Expecting 3") < 0 {
   863  		t.Fail()
   864  		t.Logf("Unexpected error %s", err)
   865  		theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1})
   866  		theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2})
   867  		return
   868  	}
   869  
   870  	theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1})
   871  	theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2})
   872  }
   873  
   874  // Test the invocation of a transaction.
   875  func TestQueries(t *testing.T) {
   876  
   877  	chainID := util.GetTestChainID()
   878  
   879  	lis, err := initPeer(chainID)
   880  	if err != nil {
   881  		t.Fail()
   882  		t.Logf("Error creating peer: %s", err)
   883  	}
   884  
   885  	defer finitPeer(lis, chainID)
   886  
   887  	var ctxt = context.Background()
   888  
   889  	url := "github.com/hyperledger/fabric/examples/chaincode/go/map"
   890  	cID := &pb.ChaincodeID{Name: "tmap", Path: url, Version: "0"}
   891  
   892  	f := "init"
   893  	args := util.ToChaincodeArgs(f)
   894  
   895  	spec := &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: args}}
   896  
   897  	cccid := ccprovider.NewCCContext(chainID, "tmap", "0", "", false, nil, nil)
   898  
   899  	var nextBlockNumber uint64
   900  	_, err = deploy(ctxt, cccid, spec, nextBlockNumber)
   901  	nextBlockNumber++
   902  	ccID := spec.ChaincodeId.Name
   903  	if err != nil {
   904  		t.Fail()
   905  		t.Logf("Error initializing chaincode %s(%s)", ccID, err)
   906  		theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec})
   907  		return
   908  	}
   909  
   910  	// Invoke second chaincode, which will inturn invoke the first chaincode
   911  	f = "put"
   912  	args = util.ToChaincodeArgs(f, "key1", "{\"shipmentID\":\"161003PKC7300\",\"customsInvoice\":{\"methodOfTransport\":\"GROUND\",\"invoiceNumber\":\"00091622\"},\"weightUnitOfMeasure\":\"KGM\",\"volumeUnitOfMeasure\": \"CO\",\"dimensionUnitOfMeasure\":\"CM\",\"currency\":\"USD\"}")
   913  	spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: args}}
   914  	_, _, _, err = invoke(ctxt, chainID, spec, nextBlockNumber)
   915  	nextBlockNumber++
   916  
   917  	if err != nil {
   918  		t.Fail()
   919  		t.Logf("Error invoking <%s>: %s", ccID, err)
   920  		theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec})
   921  		return
   922  	}
   923  
   924  	f = "put"
   925  	args = util.ToChaincodeArgs(f, "key2", "{\"shipmentID\":\"161003PKC7300\",\"customsInvoice\":{\"methodOfTransport\":\"GROUND\",\"invoiceNumber\":\"00091622\"},\"weightUnitOfMeasure\":\"KGM\",\"volumeUnitOfMeasure\": \"CO\",\"dimensionUnitOfMeasure\":\"CM\",\"currency\":\"USD\"}")
   926  	spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: args}}
   927  	_, _, _, err = invoke(ctxt, chainID, spec, nextBlockNumber)
   928  	nextBlockNumber++
   929  
   930  	if err != nil {
   931  		t.Fail()
   932  		t.Logf("Error invoking <%s>: %s", ccID, err)
   933  		theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec})
   934  		return
   935  	}
   936  
   937  	f = "put"
   938  	args = util.ToChaincodeArgs(f, "key3", "{\"shipmentID\":\"161003PKC7300\",\"customsInvoice\":{\"methodOfTransport\":\"GROUND\",\"invoiceNumber\":\"00091622\"},\"weightUnitOfMeasure\":\"KGM\",\"volumeUnitOfMeasure\": \"CO\",\"dimensionUnitOfMeasure\":\"CM\",\"currency\":\"USD\"}")
   939  	spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: args}}
   940  	_, _, _, err = invoke(ctxt, chainID, spec, nextBlockNumber)
   941  	nextBlockNumber++
   942  	if err != nil {
   943  		t.Fail()
   944  		t.Logf("Error invoking <%s>: %s", ccID, err)
   945  		theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec})
   946  		return
   947  	}
   948  
   949  	f = "keys"
   950  	args = util.ToChaincodeArgs(f, "key0", "key3")
   951  
   952  	spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: args}}
   953  	_, _, _, err = invoke(ctxt, chainID, spec, nextBlockNumber)
   954  	nextBlockNumber++
   955  	if err != nil {
   956  		t.Fail()
   957  		t.Logf("Error invoking <%s>: %s", ccID, err)
   958  		theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec})
   959  		return
   960  	}
   961  
   962  	if ledgerconfig.IsCouchDBEnabled() == true {
   963  		f = "query"
   964  		args = util.ToChaincodeArgs(f, "{\"selector\":{\"currency\":\"USD\"}}")
   965  
   966  		spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: args}}
   967  		_, _, _, err = invoke(ctxt, chainID, spec, nextBlockNumber)
   968  		if err != nil {
   969  			t.Fail()
   970  			t.Logf("Error invoking <%s>: %s", ccID, err)
   971  			theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec})
   972  			return
   973  		}
   974  	}
   975  	theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec})
   976  }
   977  
   978  func TestGetEvent(t *testing.T) {
   979  	chainID := util.GetTestChainID()
   980  
   981  	lis, err := initPeer(chainID)
   982  	if err != nil {
   983  		t.Fail()
   984  		t.Logf("Error creating peer: %s", err)
   985  	}
   986  
   987  	defer finitPeer(lis, chainID)
   988  
   989  	var ctxt = context.Background()
   990  
   991  	url := "github.com/hyperledger/fabric/examples/chaincode/go/eventsender"
   992  
   993  	cID := &pb.ChaincodeID{Name: "esender", Path: url, Version: "0"}
   994  	f := "init"
   995  	spec := &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: util.ToChaincodeArgs(f)}}
   996  
   997  	cccid := ccprovider.NewCCContext(chainID, "esender", "0", "", false, nil, nil)
   998  	var nextBlockNumber uint64
   999  	_, err = deploy(ctxt, cccid, spec, nextBlockNumber)
  1000  	nextBlockNumber++
  1001  	ccID := spec.ChaincodeId.Name
  1002  	if err != nil {
  1003  		t.Fail()
  1004  		t.Logf("Error initializing chaincode %s(%s)", ccID, err)
  1005  		theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec})
  1006  		return
  1007  	}
  1008  
  1009  	time.Sleep(time.Second)
  1010  
  1011  	args := util.ToChaincodeArgs("invoke", "i", "am", "satoshi")
  1012  
  1013  	spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: args}}
  1014  
  1015  	var ccevt *pb.ChaincodeEvent
  1016  	ccevt, _, _, err = invoke(ctxt, chainID, spec, nextBlockNumber)
  1017  
  1018  	if err != nil {
  1019  		t.Logf("Error invoking chaincode %s(%s)", ccID, err)
  1020  		t.Fail()
  1021  	}
  1022  
  1023  	if ccevt == nil {
  1024  		t.Logf("Error ccevt is nil %s(%s)", ccID, err)
  1025  		t.Fail()
  1026  	}
  1027  
  1028  	if ccevt.ChaincodeId != ccID {
  1029  		t.Logf("Error ccevt id(%s) != cid(%s)", ccevt.ChaincodeId, ccID)
  1030  		t.Fail()
  1031  	}
  1032  
  1033  	if strings.Index(string(ccevt.Payload), "i,am,satoshi") < 0 {
  1034  		t.Logf("Error expected event not found (%s)", string(ccevt.Payload))
  1035  		t.Fail()
  1036  	}
  1037  
  1038  	theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec})
  1039  }
  1040  
  1041  // Test the execution of a chaincode that queries another chaincode
  1042  // example02 implements "query" as a function in Invoke. example05 calls example02
  1043  func TestChaincodeQueryChaincodeUsingInvoke(t *testing.T) {
  1044  	chainID := util.GetTestChainID()
  1045  
  1046  	var peerLis net.Listener
  1047  	var err error
  1048  	if peerLis, err = initPeer(chainID); err != nil {
  1049  		t.Fail()
  1050  		t.Logf("Error registering user  %s", err)
  1051  		return
  1052  	}
  1053  
  1054  	defer finitPeer(peerLis, chainID)
  1055  
  1056  	var ctxt = context.Background()
  1057  
  1058  	// Deploy first chaincode
  1059  	url1 := "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02"
  1060  
  1061  	cID1 := &pb.ChaincodeID{Name: "example02", Path: url1, Version: "0"}
  1062  	f := "init"
  1063  	args := util.ToChaincodeArgs(f, "a", "100", "b", "200")
  1064  
  1065  	spec1 := &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID1, Input: &pb.ChaincodeInput{Args: args}}
  1066  
  1067  	cccid1 := ccprovider.NewCCContext(chainID, "example02", "0", "", false, nil, nil)
  1068  	var nextBlockNumber uint64
  1069  	_, err = deploy(ctxt, cccid1, spec1, nextBlockNumber)
  1070  	nextBlockNumber++
  1071  	ccID1 := spec1.ChaincodeId.Name
  1072  	if err != nil {
  1073  		theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1})
  1074  		t.Fail()
  1075  		t.Logf("Error initializing chaincode %s(%s)", ccID1, err)
  1076  		return
  1077  	}
  1078  
  1079  	time.Sleep(time.Second)
  1080  
  1081  	// Deploy second chaincode
  1082  	url2 := "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example05"
  1083  
  1084  	cID2 := &pb.ChaincodeID{Name: "example05", Path: url2, Version: "0"}
  1085  	f = "init"
  1086  	args = util.ToChaincodeArgs(f, "sum", "0")
  1087  
  1088  	spec2 := &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID2, Input: &pb.ChaincodeInput{Args: args}}
  1089  
  1090  	cccid2 := ccprovider.NewCCContext(chainID, "example05", "0", "", false, nil, nil)
  1091  
  1092  	_, err = deploy(ctxt, cccid2, spec2, nextBlockNumber)
  1093  	nextBlockNumber++
  1094  	ccID2 := spec2.ChaincodeId.Name
  1095  	if err != nil {
  1096  		theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1})
  1097  		theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2})
  1098  		t.Fail()
  1099  		t.Logf("Error initializing chaincode %s(%s)", ccID2, err)
  1100  		return
  1101  	}
  1102  
  1103  	time.Sleep(time.Second)
  1104  
  1105  	// Invoke second chaincode, which will inturn query the first chaincode
  1106  	f = "invoke"
  1107  	args = util.ToChaincodeArgs(f, ccID1, "sum")
  1108  
  1109  	spec2 = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID2, Input: &pb.ChaincodeInput{Args: args}}
  1110  	// Invoke chaincode
  1111  	var retVal []byte
  1112  	_, _, retVal, err = invoke(ctxt, chainID, spec2, nextBlockNumber)
  1113  	nextBlockNumber++
  1114  	if err != nil {
  1115  		theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1})
  1116  		theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2})
  1117  		t.Fail()
  1118  		t.Logf("Error invoking <%s>: %s", ccID2, err)
  1119  		return
  1120  	}
  1121  
  1122  	// Check the return value
  1123  	result, err := strconv.Atoi(string(retVal))
  1124  	if err != nil || result != 300 {
  1125  		theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1})
  1126  		theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2})
  1127  		t.Fail()
  1128  		t.Logf("Incorrect final state after transaction for <%s>: %s", ccID1, err)
  1129  		return
  1130  	}
  1131  
  1132  	// Query second chaincode, which will inturn query the first chaincode
  1133  	f = "query"
  1134  	args = util.ToChaincodeArgs(f, ccID1, "sum")
  1135  
  1136  	spec2 = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID2, Input: &pb.ChaincodeInput{Args: args}}
  1137  	// Invoke chaincode
  1138  	_, _, retVal, err = invoke(ctxt, chainID, spec2, nextBlockNumber)
  1139  
  1140  	if err != nil {
  1141  		theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1})
  1142  		theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2})
  1143  		t.Fail()
  1144  		t.Logf("Error querying <%s>: %s", ccID2, err)
  1145  		return
  1146  	}
  1147  
  1148  	// Check the return value
  1149  	result, err = strconv.Atoi(string(retVal))
  1150  	if err != nil || result != 300 {
  1151  		theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1})
  1152  		theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2})
  1153  		t.Fail()
  1154  		t.Logf("Incorrect final value after query for <%s>: %s", ccID1, err)
  1155  		return
  1156  	}
  1157  
  1158  	theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1})
  1159  	theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2})
  1160  }
  1161  
  1162  var signer msp.SigningIdentity
  1163  
  1164  func TestMain(m *testing.M) {
  1165  	var err error
  1166  
  1167  	// setup the MSP manager so that we can sign/verify
  1168  	mspMgrConfigDir := "../../msp/sampleconfig/"
  1169  	msptesttools.LoadMSPSetupForTesting(mspMgrConfigDir)
  1170  	signer, err = mspmgmt.GetLocalMSP().GetDefaultSigningIdentity()
  1171  	if err != nil {
  1172  		os.Exit(-1)
  1173  		fmt.Print("Could not initialize msp/signer")
  1174  		return
  1175  	}
  1176  
  1177  	SetupTestConfig()
  1178  	os.Exit(m.Run())
  1179  }