github.com/kaituanwang/hyperledger@v2.0.1+incompatible/core/chaincode/exectransaction_test.go (about)

     1  /*
     2  Copyright IBM Corp. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package chaincode
     8  
     9  import (
    10  	"bytes"
    11  	"encoding/json"
    12  	"errors"
    13  	"flag"
    14  	"fmt"
    15  	"io/ioutil"
    16  	"net"
    17  	"os"
    18  	"path/filepath"
    19  	"reflect"
    20  	"strconv"
    21  	"strings"
    22  	"sync"
    23  	"testing"
    24  	"time"
    25  
    26  	"github.com/hyperledger/fabric/core/ledger/ledgermgmt/ledgermgmttest"
    27  
    28  	docker "github.com/fsouza/go-dockerclient"
    29  	"github.com/golang/protobuf/proto"
    30  	"github.com/hyperledger/fabric-chaincode-go/shim"
    31  	"github.com/hyperledger/fabric-protos-go/common"
    32  	pb "github.com/hyperledger/fabric-protos-go/peer"
    33  	"github.com/hyperledger/fabric/bccsp/factory"
    34  	"github.com/hyperledger/fabric/bccsp/sw"
    35  	"github.com/hyperledger/fabric/common/channelconfig"
    36  	"github.com/hyperledger/fabric/common/crypto/tlsgen"
    37  	"github.com/hyperledger/fabric/common/flogging"
    38  	"github.com/hyperledger/fabric/common/metrics/disabled"
    39  
    40  	"github.com/hyperledger/fabric/common/policies"
    41  	"github.com/hyperledger/fabric/common/util"
    42  	"github.com/hyperledger/fabric/core/aclmgmt"
    43  	"github.com/hyperledger/fabric/core/chaincode/lifecycle"
    44  	"github.com/hyperledger/fabric/core/chaincode/mock"
    45  	cm "github.com/hyperledger/fabric/core/chaincode/mock"
    46  	"github.com/hyperledger/fabric/core/chaincode/persistence"
    47  	"github.com/hyperledger/fabric/core/chaincode/platforms"
    48  	"github.com/hyperledger/fabric/core/chaincode/platforms/golang"
    49  	"github.com/hyperledger/fabric/core/comm"
    50  	"github.com/hyperledger/fabric/core/common/ccprovider"
    51  	"github.com/hyperledger/fabric/core/config"
    52  	"github.com/hyperledger/fabric/core/container"
    53  	"github.com/hyperledger/fabric/core/container/dockercontroller"
    54  	"github.com/hyperledger/fabric/core/ledger"
    55  	"github.com/hyperledger/fabric/core/ledger/ledgermgmt"
    56  	ledgermock "github.com/hyperledger/fabric/core/ledger/mock"
    57  	cut "github.com/hyperledger/fabric/core/ledger/util"
    58  	"github.com/hyperledger/fabric/core/peer"
    59  	"github.com/hyperledger/fabric/core/policy"
    60  	policymocks "github.com/hyperledger/fabric/core/policy/mocks"
    61  	"github.com/hyperledger/fabric/core/scc"
    62  	"github.com/hyperledger/fabric/core/scc/lscc"
    63  	"github.com/hyperledger/fabric/internal/peer/packaging"
    64  	"github.com/hyperledger/fabric/msp"
    65  	mspmgmt "github.com/hyperledger/fabric/msp/mgmt"
    66  	msptesttools "github.com/hyperledger/fabric/msp/mgmt/testtools"
    67  	"github.com/hyperledger/fabric/protoutil"
    68  	"github.com/spf13/viper"
    69  	"github.com/stretchr/testify/assert"
    70  	"github.com/stretchr/testify/require"
    71  	"google.golang.org/grpc"
    72  )
    73  
    74  //initialize peer and start up. If security==enabled, login as vp
    75  func initPeer(channelIDs ...string) (*cm.Lifecycle, net.Listener, *ChaincodeSupport, func(), error) {
    76  	cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
    77  	if err != nil {
    78  		return nil, nil, nil, nil, fmt.Errorf("failed to create cryptoProvider %s", err)
    79  	}
    80  
    81  	peerInstance := &peer.Peer{CryptoProvider: cryptoProvider}
    82  	grpcServer := grpc.NewServer()
    83  
    84  	lis, err := net.Listen("tcp", ":0")
    85  	if err != nil {
    86  		return nil, nil, nil, nil, fmt.Errorf("failed to start peer listener %s", err)
    87  	}
    88  	_, localPort, err := net.SplitHostPort(lis.Addr().String())
    89  	if err != nil {
    90  		return nil, nil, nil, nil, fmt.Errorf("failed to get port: %s", err)
    91  	}
    92  	localIP, err := comm.GetLocalIP()
    93  	if err != nil {
    94  		return nil, nil, nil, nil, fmt.Errorf("failed to get local IP: %s", err)
    95  	}
    96  
    97  	peerAddress := net.JoinHostPort(localIP, localPort)
    98  
    99  	tempdir, err := ioutil.TempDir("", "chaincode")
   100  	if err != nil {
   101  		panic(fmt.Sprintf("failed to create temporary directory: %s", err))
   102  	}
   103  
   104  	lgrInitializer := ledgermgmttest.NewInitializer(filepath.Join(tempdir, "ledgersData"))
   105  	lgrInitializer.Config.HistoryDBConfig = &ledger.HistoryDBConfig{
   106  		Enabled: true,
   107  	}
   108  	peerInstance.LedgerMgr = ledgermgmt.NewLedgerMgr(lgrInitializer)
   109  	ccprovider.SetChaincodesPath(tempdir)
   110  	ca, _ := tlsgen.NewCA()
   111  	pr := platforms.NewRegistry(&golang.Platform{})
   112  	mockAclProvider := &mock.ACLProvider{}
   113  	builtinSCCs := map[string]struct{}{"lscc": {}}
   114  
   115  	client, err := docker.NewClientFromEnv()
   116  	if err != nil {
   117  		return nil, nil, nil, nil, err
   118  	}
   119  
   120  	containerRouter := &container.Router{
   121  		DockerBuilder: &dockercontroller.DockerVM{
   122  			PeerID:       "",
   123  			NetworkID:    "",
   124  			BuildMetrics: dockercontroller.NewBuildMetrics(&disabled.Provider{}),
   125  			Client:       client,
   126  			PlatformBuilder: &platforms.Builder{
   127  				Registry: pr,
   128  				Client:   client,
   129  			},
   130  		},
   131  		PackageProvider: &persistence.FallbackPackageLocator{
   132  			ChaincodePackageLocator: &persistence.ChaincodePackageLocator{},
   133  			LegacyCCPackageLocator:  &ccprovider.CCInfoFSImpl{GetHasher: cryptoProvider},
   134  		},
   135  	}
   136  
   137  	buildRegistry := &container.BuildRegistry{}
   138  
   139  	lsccImpl := &lscc.SCC{
   140  		BuiltinSCCs: map[string]struct{}{"lscc": {}},
   141  		Support: &lscc.SupportImpl{
   142  			GetMSPIDs: peerInstance.GetMSPIDs,
   143  		},
   144  		SCCProvider:      &lscc.PeerShim{Peer: peerInstance},
   145  		ACLProvider:      mockAclProvider,
   146  		GetMSPIDs:        peerInstance.GetMSPIDs,
   147  		PolicyChecker:    newPolicyChecker(peerInstance),
   148  		BCCSP:            cryptoProvider,
   149  		BuildRegistry:    buildRegistry,
   150  		ChaincodeBuilder: containerRouter,
   151  	}
   152  
   153  	ml := &cm.Lifecycle{}
   154  	ml.ChaincodeEndorsementInfoStub = func(_, name string, _ ledger.SimpleQueryExecutor) (*lifecycle.ChaincodeEndorsementInfo, error) {
   155  		switch name {
   156  		case "lscc":
   157  			return &lifecycle.ChaincodeEndorsementInfo{
   158  				ChaincodeID: "lscc.syscc",
   159  			}, nil
   160  		default:
   161  			return &lifecycle.ChaincodeEndorsementInfo{
   162  				ChaincodeID: name + ":0",
   163  			}, nil
   164  		}
   165  	}
   166  	globalConfig := &Config{
   167  		TLSEnabled:      false,
   168  		Keepalive:       time.Second,
   169  		StartupTimeout:  3 * time.Minute,
   170  		ExecuteTimeout:  30 * time.Second,
   171  		LogLevel:        "info",
   172  		ShimLogLevel:    "warning",
   173  		LogFormat:       "TEST: [%{module}] %{shortfunc} -> %{level:.4s} %{id:03x}%{color:reset} %{message}",
   174  		TotalQueryLimit: 10000,
   175  	}
   176  	containerRuntime := &ContainerRuntime{
   177  		BuildRegistry:   buildRegistry,
   178  		ContainerRouter: containerRouter,
   179  	}
   180  	userRunsCC := false
   181  	metricsProviders := &disabled.Provider{}
   182  	chaincodeHandlerRegistry := NewHandlerRegistry(userRunsCC)
   183  	chaincodeLauncher := &RuntimeLauncher{
   184  		Metrics:        NewLaunchMetrics(metricsProviders),
   185  		Registry:       chaincodeHandlerRegistry,
   186  		Runtime:        containerRuntime,
   187  		StartupTimeout: globalConfig.StartupTimeout,
   188  		CACert:         ca.CertBytes(),
   189  		PeerAddress:    peerAddress,
   190  	}
   191  	chaincodeSupport := &ChaincodeSupport{
   192  		ACLProvider: aclmgmt.NewACLProvider(
   193  			func(string) channelconfig.Resources { return nil },
   194  			newPolicyChecker(peerInstance),
   195  		),
   196  		AppConfig:              peerInstance,
   197  		DeployedCCInfoProvider: &ledgermock.DeployedChaincodeInfoProvider{},
   198  		ExecuteTimeout:         globalConfig.ExecuteTimeout,
   199  		HandlerMetrics:         NewHandlerMetrics(metricsProviders),
   200  		HandlerRegistry:        chaincodeHandlerRegistry,
   201  		Keepalive:              globalConfig.Keepalive,
   202  		Launcher:               chaincodeLauncher,
   203  		Lifecycle:              ml,
   204  		Peer:                   peerInstance,
   205  		Runtime:                containerRuntime,
   206  		BuiltinSCCs:            builtinSCCs,
   207  		TotalQueryLimit:        globalConfig.TotalQueryLimit,
   208  		UserRunsCC:             userRunsCC,
   209  	}
   210  	pb.RegisterChaincodeSupportServer(grpcServer, chaincodeSupport)
   211  
   212  	scc.DeploySysCC(lsccImpl, chaincodeSupport)
   213  
   214  	go grpcServer.Serve(lis)
   215  
   216  	cleanup := func() {
   217  		finitPeer(peerInstance, lis, channelIDs...)
   218  		os.RemoveAll(tempdir)
   219  	}
   220  
   221  	return ml, lis, chaincodeSupport, cleanup, nil
   222  }
   223  
   224  func finitPeer(peerInstance *peer.Peer, lis net.Listener, chainIDs ...string) {
   225  	if lis != nil {
   226  		closeListenerAndSleep(lis)
   227  	}
   228  	for _, c := range chainIDs {
   229  		if lgr := peerInstance.GetLedger(c); lgr != nil {
   230  			lgr.Close()
   231  		}
   232  	}
   233  	peerInstance.LedgerMgr.Close()
   234  	ledgerPath := config.GetPath("peer.fileSystemPath")
   235  	os.RemoveAll(ledgerPath)
   236  	os.RemoveAll(filepath.Join(os.TempDir(), "hyperledger"))
   237  }
   238  
   239  func startTxSimulation(peerInstance *peer.Peer, channelID string, txid string) (ledger.TxSimulator, ledger.HistoryQueryExecutor, error) {
   240  	lgr := peerInstance.GetLedger(channelID)
   241  	txsim, err := lgr.NewTxSimulator(txid)
   242  	if err != nil {
   243  		return nil, nil, err
   244  	}
   245  	historyQueryExecutor, err := lgr.NewHistoryQueryExecutor()
   246  	if err != nil {
   247  		return nil, nil, err
   248  	}
   249  
   250  	return txsim, historyQueryExecutor, nil
   251  }
   252  
   253  func endTxSimulationCDS(peerInstance *peer.Peer, channelID string, txsim ledger.TxSimulator, payload []byte, commit bool, cds *pb.ChaincodeDeploymentSpec, blockNumber uint64) error {
   254  	// get serialized version of the signer
   255  	ss, err := signer.Serialize()
   256  	if err != nil {
   257  		return err
   258  	}
   259  
   260  	// get lscc ChaincodeID
   261  	lsccid := &pb.ChaincodeID{
   262  		Name: "lscc",
   263  	}
   264  
   265  	// get a proposal - we need it to get a transaction
   266  	prop, _, err := protoutil.CreateDeployProposalFromCDS(channelID, cds, ss, nil, nil, nil, nil)
   267  	if err != nil {
   268  		return err
   269  	}
   270  
   271  	return endTxSimulation(peerInstance, channelID, lsccid, txsim, payload, commit, prop, blockNumber)
   272  }
   273  
   274  func endTxSimulationCIS(peerInstance *peer.Peer, channelID string, ccid *pb.ChaincodeID, txid string, txsim ledger.TxSimulator, payload []byte, commit bool, cis *pb.ChaincodeInvocationSpec, blockNumber uint64) error {
   275  	// get serialized version of the signer
   276  	ss, err := signer.Serialize()
   277  	if err != nil {
   278  		return err
   279  	}
   280  
   281  	// get a proposal - we need it to get a transaction
   282  	prop, returnedTxid, err := protoutil.CreateProposalFromCISAndTxid(txid, common.HeaderType_ENDORSER_TRANSACTION, channelID, cis, ss)
   283  	if err != nil {
   284  		return err
   285  	}
   286  	if returnedTxid != txid {
   287  		return errors.New("txids are not same")
   288  	}
   289  
   290  	return endTxSimulation(peerInstance, channelID, ccid, txsim, payload, commit, prop, blockNumber)
   291  }
   292  
   293  //getting a crash from ledger.Commit when doing concurrent invokes
   294  //It is likely intentional that ledger.Commit is serial (ie, the real
   295  //Committer will invoke this serially on each block). Mimic that here
   296  //by forcing serialization of the ledger.Commit call.
   297  //
   298  //NOTE-this should NOT have any effect on the older serial tests.
   299  //This affects only the tests in concurrent_test.go which call these
   300  //concurrently (100 concurrent invokes followed by 100 concurrent queries)
   301  var _commitLock_ sync.Mutex
   302  
   303  func endTxSimulation(peerInstance *peer.Peer, channelID string, ccid *pb.ChaincodeID, txsim ledger.TxSimulator, _ []byte, commit bool, prop *pb.Proposal, blockNumber uint64) error {
   304  	txsim.Done()
   305  	if lgr := peerInstance.GetLedger(channelID); lgr != nil {
   306  		if commit {
   307  			var txSimulationResults *ledger.TxSimulationResults
   308  			var txSimulationBytes []byte
   309  			var err error
   310  
   311  			txsim.Done()
   312  
   313  			//get simulation results
   314  			if txSimulationResults, err = txsim.GetTxSimulationResults(); err != nil {
   315  				return err
   316  			}
   317  			if txSimulationBytes, err = txSimulationResults.GetPubSimulationBytes(); err != nil {
   318  				return err
   319  			}
   320  			// assemble a (signed) proposal response message
   321  			resp, err := protoutil.CreateProposalResponse(prop.Header, prop.Payload, &pb.Response{Status: 200},
   322  				txSimulationBytes, nil, ccid, signer)
   323  			if err != nil {
   324  				return err
   325  			}
   326  
   327  			// get the envelope
   328  			env, err := protoutil.CreateSignedTx(prop, signer, resp)
   329  			if err != nil {
   330  				return err
   331  			}
   332  
   333  			envBytes, err := protoutil.GetBytesEnvelope(env)
   334  			if err != nil {
   335  				return err
   336  			}
   337  
   338  			//create the block with 1 transaction
   339  			bcInfo, err := lgr.GetBlockchainInfo()
   340  			if err != nil {
   341  				return err
   342  			}
   343  			block := protoutil.NewBlock(blockNumber, bcInfo.CurrentBlockHash)
   344  			block.Data.Data = [][]byte{envBytes}
   345  			txsFilter := cut.NewTxValidationFlagsSetValue(len(block.Data.Data), pb.TxValidationCode_VALID)
   346  			block.Metadata.Metadata[common.BlockMetadataIndex_TRANSACTIONS_FILTER] = txsFilter
   347  
   348  			//commit the block
   349  
   350  			//see comment on _commitLock_
   351  			_commitLock_.Lock()
   352  			defer _commitLock_.Unlock()
   353  
   354  			blockAndPvtData := &ledger.BlockAndPvtData{
   355  				Block:   block,
   356  				PvtData: make(ledger.TxPvtDataMap),
   357  			}
   358  
   359  			// All tests are performed with just one transaction in a block.
   360  			// Hence, we can simiplify the procedure of constructing the
   361  			// block with private data. There is not enough need to
   362  			// add more than one transaction in a block for testing chaincode
   363  			// API.
   364  
   365  			// ASSUMPTION: Only one transaction in a block.
   366  			seqInBlock := uint64(0)
   367  
   368  			if txSimulationResults.PvtSimulationResults != nil {
   369  				blockAndPvtData.PvtData[seqInBlock] = &ledger.TxPvtData{
   370  					SeqInBlock: seqInBlock,
   371  					WriteSet:   txSimulationResults.PvtSimulationResults,
   372  				}
   373  			}
   374  
   375  			if err := lgr.CommitLegacy(blockAndPvtData, &ledger.CommitOptions{}); err != nil {
   376  				return err
   377  			}
   378  		}
   379  	}
   380  
   381  	return nil
   382  }
   383  
   384  // Build a chaincode.
   385  func getDeploymentSpec(spec *pb.ChaincodeSpec) (*pb.ChaincodeDeploymentSpec, error) {
   386  	fmt.Printf("getting deployment spec for chaincode spec: %v\n", spec)
   387  	codePackageBytes, err := packaging.NewRegistry(&golang.Platform{}).GetDeploymentPayload(spec.Type.String(), spec.ChaincodeId.Path)
   388  	if err != nil {
   389  		return nil, err
   390  	}
   391  
   392  	cdDeploymentSpec := &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec, CodePackage: codePackageBytes}
   393  	return cdDeploymentSpec, nil
   394  }
   395  
   396  //getDeployLSCCSpec gets the spec for the chaincode deployment to be sent to LSCC
   397  func getDeployLSCCSpec(channelID string, cds *pb.ChaincodeDeploymentSpec, ccp *pb.CollectionConfigPackage) (*pb.ChaincodeInvocationSpec, error) {
   398  	b, err := proto.Marshal(cds)
   399  	if err != nil {
   400  		return nil, err
   401  	}
   402  
   403  	var ccpBytes []byte
   404  	if ccp != nil {
   405  		if ccpBytes, err = proto.Marshal(ccp); err != nil {
   406  			return nil, err
   407  		}
   408  	}
   409  	invokeInput := &pb.ChaincodeInput{Args: [][]byte{
   410  		[]byte("deploy"),  // function name
   411  		[]byte(channelID), // chaincode name to deploy
   412  		b,                 // chaincode deployment spec
   413  	}}
   414  
   415  	if ccpBytes != nil {
   416  		// SignaturePolicyEnvelope, escc, vscc, CollectionConfigPackage
   417  		invokeInput.Args = append(invokeInput.Args, nil, nil, nil, ccpBytes)
   418  	}
   419  
   420  	//wrap the deployment in an invocation spec to lscc...
   421  	lsccSpec := &pb.ChaincodeInvocationSpec{
   422  		ChaincodeSpec: &pb.ChaincodeSpec{
   423  			Type:        pb.ChaincodeSpec_GOLANG,
   424  			ChaincodeId: &pb.ChaincodeID{Name: "lscc"},
   425  			Input:       invokeInput,
   426  		}}
   427  
   428  	return lsccSpec, nil
   429  }
   430  
   431  // Deploy a chaincode - i.e., build and initialize.
   432  func deploy(channelID string, ccContext *CCContext, spec *pb.ChaincodeSpec, blockNumber uint64, chaincodeSupport *ChaincodeSupport) (resp *pb.Response, err error) {
   433  	// First build and get the deployment spec
   434  	cdDeploymentSpec, err := getDeploymentSpec(spec)
   435  	if err != nil {
   436  		return nil, err
   437  	}
   438  	return deploy2(channelID, ccContext, cdDeploymentSpec, nil, blockNumber, chaincodeSupport)
   439  }
   440  
   441  func deployWithCollectionConfigs(channelID string, ccContext *CCContext, spec *pb.ChaincodeSpec,
   442  	collectionConfigPkg *pb.CollectionConfigPackage, blockNumber uint64, chaincodeSupport *ChaincodeSupport) (resp *pb.Response, err error) {
   443  	// First build and get the deployment spec
   444  	cdDeploymentSpec, err := getDeploymentSpec(spec)
   445  	if err != nil {
   446  		return nil, err
   447  	}
   448  	return deploy2(channelID, ccContext, cdDeploymentSpec, collectionConfigPkg, blockNumber, chaincodeSupport)
   449  }
   450  
   451  func deploy2(channelID string, ccContext *CCContext, chaincodeDeploymentSpec *pb.ChaincodeDeploymentSpec,
   452  	collectionConfigPkg *pb.CollectionConfigPackage, blockNumber uint64, chaincodeSupport *ChaincodeSupport) (resp *pb.Response, err error) {
   453  	cis, err := getDeployLSCCSpec(channelID, chaincodeDeploymentSpec, collectionConfigPkg)
   454  	if err != nil {
   455  		return nil, fmt.Errorf("Error creating lscc spec : %s\n", err)
   456  	}
   457  
   458  	uuid := util.GenerateUUID()
   459  	txsim, hqe, err := startTxSimulation(chaincodeSupport.Peer, channelID, uuid)
   460  	sprop, prop := protoutil.MockSignedEndorserProposal2OrPanic(channelID, cis.ChaincodeSpec, signer)
   461  	txParams := &ccprovider.TransactionParams{
   462  		TxID:                 uuid,
   463  		ChannelID:            channelID,
   464  		TXSimulator:          txsim,
   465  		HistoryQueryExecutor: hqe,
   466  		SignedProp:           sprop,
   467  		Proposal:             prop,
   468  	}
   469  	if err != nil {
   470  		return nil, fmt.Errorf("Failed to get handle to simulator: %s ", err)
   471  	}
   472  
   473  	defer func() {
   474  		//no error, lets try commit
   475  		if err == nil {
   476  			//capture returned error from commit
   477  			err = endTxSimulationCDS(chaincodeSupport.Peer, channelID, txsim, []byte("deployed"), true, chaincodeDeploymentSpec, blockNumber)
   478  		} else {
   479  			//there was an error, just close simulation and return that
   480  			endTxSimulationCDS(chaincodeSupport.Peer, channelID, txsim, []byte("deployed"), false, chaincodeDeploymentSpec, blockNumber)
   481  		}
   482  	}()
   483  
   484  	cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
   485  	if err != nil {
   486  		return nil, fmt.Errorf("Failed to create default cryptoProvider: %s ", err)
   487  	}
   488  	ccinfoFSImpl := &ccprovider.CCInfoFSImpl{GetHasher: cryptoProvider}
   489  	//ignore existence errors
   490  	ccinfoFSImpl.PutChaincode(chaincodeDeploymentSpec)
   491  
   492  	//write to lscc
   493  	if _, _, err = chaincodeSupport.Execute(txParams, "lscc", cis.ChaincodeSpec.Input); err != nil {
   494  		return nil, fmt.Errorf("Error deploying chaincode (1): %s", err)
   495  	}
   496  
   497  	if resp, _, err = chaincodeSupport.ExecuteLegacyInit(txParams, ccContext.Name, ccContext.Version, chaincodeDeploymentSpec.ChaincodeSpec.Input); err != nil {
   498  		return nil, fmt.Errorf("Error deploying chaincode(2): %s", err)
   499  	}
   500  
   501  	return resp, nil
   502  }
   503  
   504  // Invoke a chaincode.
   505  func invoke(channelID string, spec *pb.ChaincodeSpec, blockNumber uint64, creator []byte, chaincodeSupport *ChaincodeSupport) (ccevt *pb.ChaincodeEvent, uuid string, retval []byte, err error) {
   506  	return invokeWithVersion(channelID, spec.GetChaincodeId().Version, spec, blockNumber, creator, chaincodeSupport)
   507  }
   508  
   509  // Invoke a chaincode with version (needed for upgrade)
   510  func invokeWithVersion(channelID string, version string, spec *pb.ChaincodeSpec, blockNumber uint64, creator []byte, chaincodeSupport *ChaincodeSupport) (ccevt *pb.ChaincodeEvent, uuid string, retval []byte, err error) {
   511  	cdInvocationSpec := &pb.ChaincodeInvocationSpec{ChaincodeSpec: spec}
   512  
   513  	// Now create the Transactions message and send to Peer.
   514  	uuid = util.GenerateUUID()
   515  
   516  	txsim, hqe, err := startTxSimulation(chaincodeSupport.Peer, channelID, uuid)
   517  	if err != nil {
   518  		return nil, uuid, nil, fmt.Errorf("Failed to get handle to simulator: %s ", err)
   519  	}
   520  
   521  	defer func() {
   522  		//no error, lets try commit
   523  		if err == nil {
   524  			//capture returned error from commit
   525  			err = endTxSimulationCIS(chaincodeSupport.Peer, channelID, spec.ChaincodeId, uuid, txsim, []byte("invoke"), true, cdInvocationSpec, blockNumber)
   526  		} else {
   527  			//there was an error, just close simulation and return that
   528  			endTxSimulationCIS(chaincodeSupport.Peer, channelID, spec.ChaincodeId, uuid, txsim, []byte("invoke"), false, cdInvocationSpec, blockNumber)
   529  		}
   530  	}()
   531  
   532  	if len(creator) == 0 {
   533  		creator = []byte("Admin")
   534  	}
   535  	sprop, prop := protoutil.MockSignedEndorserProposalOrPanic(channelID, spec, creator, []byte("msg1"))
   536  	var resp *pb.Response
   537  	txParams := &ccprovider.TransactionParams{
   538  		TxID:                 uuid,
   539  		ChannelID:            channelID,
   540  		TXSimulator:          txsim,
   541  		HistoryQueryExecutor: hqe,
   542  		SignedProp:           sprop,
   543  		Proposal:             prop,
   544  	}
   545  
   546  	resp, ccevt, err = chaincodeSupport.Execute(txParams, cdInvocationSpec.ChaincodeSpec.ChaincodeId.Name, cdInvocationSpec.ChaincodeSpec.Input)
   547  	if err != nil {
   548  		return nil, uuid, nil, fmt.Errorf("Error invoking chaincode: %s", err)
   549  	}
   550  	if resp.Status != shim.OK {
   551  		return nil, uuid, nil, fmt.Errorf("Error invoking chaincode: %s", resp.Message)
   552  	}
   553  
   554  	return ccevt, uuid, resp.Payload, err
   555  }
   556  
   557  func closeListenerAndSleep(l net.Listener) {
   558  	if l != nil {
   559  		l.Close()
   560  		time.Sleep(2 * time.Second)
   561  	}
   562  }
   563  
   564  // Check the correctness of the final state after transaction execution.
   565  func checkFinalState(peerInstance *peer.Peer, channelID string, ccContext *CCContext, a int, b int) error {
   566  	txid := util.GenerateUUID()
   567  	txsim, _, err := startTxSimulation(peerInstance, channelID, txid)
   568  	if err != nil {
   569  		return fmt.Errorf("Failed to get handle to simulator: %s ", err)
   570  	}
   571  
   572  	defer txsim.Done()
   573  
   574  	cName := ccContext.Name + ":" + ccContext.Version
   575  
   576  	// Invoke ledger to get state
   577  	var Aval, Bval int
   578  	resbytes, resErr := txsim.GetState(ccContext.Name, "a")
   579  	if resErr != nil {
   580  		return fmt.Errorf("Error retrieving state from ledger for <%s>: %s", cName, resErr)
   581  	}
   582  	Aval, resErr = strconv.Atoi(string(resbytes))
   583  	if resErr != nil {
   584  		return fmt.Errorf("Error retrieving state from ledger for <%s>: %s", cName, resErr)
   585  	}
   586  	if Aval != a {
   587  		return fmt.Errorf("Incorrect result. Aval %d != %d <%s>", Aval, a, cName)
   588  	}
   589  
   590  	resbytes, resErr = txsim.GetState(ccContext.Name, "b")
   591  	if resErr != nil {
   592  		return fmt.Errorf("Error retrieving state from ledger for <%s>: %s", cName, resErr)
   593  	}
   594  	Bval, resErr = strconv.Atoi(string(resbytes))
   595  	if resErr != nil {
   596  		return fmt.Errorf("Error retrieving state from ledger for <%s>: %s", cName, resErr)
   597  	}
   598  	if Bval != b {
   599  		return fmt.Errorf("Incorrect result. Bval %d != %d <%s>", Bval, b, cName)
   600  	}
   601  
   602  	// Success
   603  	fmt.Printf("Aval = %d, Bval = %d\n", Aval, Bval)
   604  	return nil
   605  }
   606  
   607  const (
   608  	chaincodeExample02GolangPath = "github.com/hyperledger/fabric/core/chaincode/testdata/src/chaincodes/example02"
   609  	chaincodePassthruGolangPath  = "github.com/hyperledger/fabric/core/chaincode/testdata/src/chaincodes/passthru"
   610  )
   611  
   612  // Test the execution of a chaincode that invokes another chaincode.
   613  func TestChaincodeInvokeChaincode(t *testing.T) {
   614  	channel1 := "testchannelid"
   615  	channel2 := channel1 + "2"
   616  	ml, lis, chaincodeSupport, cleanup, err := initPeer(channel1, channel2)
   617  	if err != nil {
   618  		t.Fail()
   619  		t.Logf("Error creating peer: %s", err)
   620  	}
   621  	defer cleanup()
   622  	defer closeListenerAndSleep(lis)
   623  
   624  	mockPolicy := &mock.Policy{}
   625  	mockPolicy.EvaluateSignedDataReturns(nil)
   626  	capabilities := &mock.ApplicationCapabilities{}
   627  	config := &mock.ApplicationConfig{}
   628  	config.CapabilitiesReturns(capabilities)
   629  
   630  	polMgrChannel1 := &mock.PolicyManager{}
   631  	polMgrChannel1.GetPolicyReturns(mockPolicy, true)
   632  	resources1 := &mock.Resources{}
   633  	resources1.PolicyManagerReturns(polMgrChannel1)
   634  	resources1.ApplicationConfigReturns(config, true)
   635  	err = peer.CreateMockChannel(chaincodeSupport.Peer, channel1, resources1)
   636  	if err != nil {
   637  		t.Fatalf("Failed to create mock channel: %s", err)
   638  	}
   639  
   640  	polMgrChannel2 := &mock.PolicyManager{}
   641  	polMgrChannel2.GetPolicyReturns(mockPolicy, true)
   642  	resources2 := &mock.Resources{}
   643  	resources2.PolicyManagerReturns(polMgrChannel2)
   644  	resources2.ApplicationConfigReturns(config, true)
   645  	err = peer.CreateMockChannel(chaincodeSupport.Peer, channel2, resources2)
   646  	if err != nil {
   647  		t.Fatalf("Failed to create mock channel: %s", err)
   648  	}
   649  
   650  	peerInstance := chaincodeSupport.Peer
   651  
   652  	var nextBlockNumber1 uint64 = 1
   653  	var nextBlockNumber2 uint64 = 1
   654  
   655  	chaincode1Name := "cc_go_" + util.GenerateUUID()
   656  	chaincode2Name := "cc_go_" + util.GenerateUUID()
   657  
   658  	initialA, initialB := 100, 200
   659  
   660  	// Deploy first chaincode
   661  	ml.ChaincodeEndorsementInfoStub = func(_, name string, _ ledger.SimpleQueryExecutor) (*lifecycle.ChaincodeEndorsementInfo, error) {
   662  		switch name {
   663  		case "lscc":
   664  			return &lifecycle.ChaincodeEndorsementInfo{
   665  				ChaincodeID: "lscc.syscc",
   666  			}, nil
   667  		default:
   668  			return &lifecycle.ChaincodeEndorsementInfo{
   669  				ChaincodeID: name + ":0",
   670  			}, nil
   671  		}
   672  	}
   673  	_, ccContext1, err := deployChaincode(
   674  		chaincode1Name,
   675  		"0",
   676  		pb.ChaincodeSpec_GOLANG,
   677  		chaincodeExample02GolangPath,
   678  		util.ToChaincodeArgs("init", "a", strconv.Itoa(initialA), "b", strconv.Itoa(initialB)),
   679  		channel1,
   680  		nextBlockNumber1,
   681  		chaincodeSupport,
   682  	)
   683  	defer stopChaincode(ccContext1, chaincodeSupport)
   684  	require.NoErrorf(t, err, "error initializing chaincode %s: %s", chaincode1Name, err)
   685  	nextBlockNumber1++
   686  	time.Sleep(time.Second)
   687  
   688  	// chaincode2: the chaincode that will call by chaincode1
   689  	chaincode2Version := "0"
   690  	chaincode2Type := pb.ChaincodeSpec_GOLANG
   691  	chaincode2Path := chaincodePassthruGolangPath
   692  
   693  	// deploy second chaincode on channel
   694  	_, ccContext2, err := deployChaincode(
   695  		chaincode2Name,
   696  		chaincode2Version,
   697  		chaincode2Type,
   698  		chaincode2Path,
   699  		util.ToChaincodeArgs("init"),
   700  		channel1,
   701  		nextBlockNumber1,
   702  		chaincodeSupport,
   703  	)
   704  	defer stopChaincode(ccContext2, chaincodeSupport)
   705  	require.NoErrorf(t, err, "Error initializing chaincode %s: %s", chaincode2Name, err)
   706  	nextBlockNumber1++
   707  	time.Sleep(time.Second)
   708  
   709  	// Invoke second chaincode passing the first chaincode's name as first param,
   710  	// which will inturn invoke the first chaincode
   711  	chaincode2InvokeSpec := &pb.ChaincodeSpec{
   712  		Type: chaincode2Type,
   713  		ChaincodeId: &pb.ChaincodeID{
   714  			Name:    chaincode2Name,
   715  			Version: chaincode2Version,
   716  		},
   717  		Input: &pb.ChaincodeInput{
   718  			Args: util.ToChaincodeArgs(ccContext1.Name, "invoke", "a", "b", "10", ""),
   719  		},
   720  	}
   721  	_, _, _, err = invoke(channel1, chaincode2InvokeSpec, nextBlockNumber1, []byte("Alice"), chaincodeSupport)
   722  	require.NoErrorf(t, err, "error invoking %s: %s", chaincode2Name, err)
   723  	nextBlockNumber1++
   724  
   725  	// Check the state in the ledger
   726  	err = checkFinalState(peerInstance, channel1, ccContext1, initialA-10, initialB+10)
   727  	require.NoErrorf(t, err, "incorrect final state after transaction for %s: %s", chaincode1Name, err)
   728  
   729  	// Change the policies of the two channels in such a way:
   730  	// 1. Alice has reader access to both the channels.
   731  	// 2. Bob has access only to chainID2.
   732  	// Therefore the chaincode invocation should fail.
   733  
   734  	polMgrChannel1.GetPolicyReturns(&CreatorPolicy{Creators: [][]byte{[]byte("Alice")}}, true)
   735  	polMgrChannel2.GetPolicyReturns(&CreatorPolicy{Creators: [][]byte{[]byte("Alice"), []byte("Bob")}}, true)
   736  
   737  	// deploy chaincode2 on channel2
   738  	_, ccContext3, err := deployChaincode(
   739  		chaincode2Name,
   740  		chaincode2Version,
   741  		chaincode2Type,
   742  		chaincode2Path,
   743  		util.ToChaincodeArgs("init"),
   744  		channel2,
   745  		nextBlockNumber2,
   746  		chaincodeSupport,
   747  	)
   748  	defer stopChaincode(ccContext3, chaincodeSupport)
   749  	require.NoErrorf(t, err, "error initializing chaincode %s/%s: %s", chaincode2Name, channel2, err)
   750  	nextBlockNumber2++
   751  	time.Sleep(time.Second)
   752  
   753  	chaincode2InvokeSpec = &pb.ChaincodeSpec{
   754  		Type: chaincode2Type,
   755  		ChaincodeId: &pb.ChaincodeID{
   756  			Name:    chaincode2Name,
   757  			Version: chaincode2Version,
   758  		},
   759  		Input: &pb.ChaincodeInput{
   760  			Args: util.ToChaincodeArgs(ccContext1.Name, "invoke", "a", "b", "10", channel1),
   761  		},
   762  	}
   763  
   764  	// as Bob, invoke chaincode2 on channel2 so that it invokes chaincode1 on channel
   765  	_, _, _, err = invoke(channel2, chaincode2InvokeSpec, nextBlockNumber2, []byte("Bob"), chaincodeSupport)
   766  	require.Errorf(t, err, "as Bob, invoking <%s/%s> via <%s/%s> should fail, but it succeeded.", ccContext1.Name, channel1, chaincode2Name, channel2)
   767  	assert.True(t, strings.Contains(err.Error(), "[Creator not recognized [Bob]]"))
   768  
   769  	// as Alice, invoke chaincode2 on channel2 so that it invokes chaincode1 on channel
   770  	_, _, _, err = invoke(channel2, chaincode2InvokeSpec, nextBlockNumber2, []byte("Alice"), chaincodeSupport)
   771  	require.NoError(t, err, "as Alice, invoking <%s/%s> via <%s/%s> should should of succeeded, but it failed: %s", ccContext1.Name, channel1, chaincode2Name, channel2, err)
   772  	nextBlockNumber2++
   773  }
   774  
   775  func stopChaincode(chaincodeCtx *CCContext, chaincodeSupport *ChaincodeSupport) {
   776  	chaincodeSupport.Runtime.Stop(chaincodeCtx.Name + ":" + chaincodeCtx.Version)
   777  }
   778  
   779  // Test the execution of a chaincode that invokes another chaincode with wrong parameters. Should receive error from
   780  // from the called chaincode
   781  func TestChaincodeInvokeChaincodeErrorCase(t *testing.T) {
   782  	channelID := "testchannelid"
   783  
   784  	ml, _, chaincodeSupport, cleanup, err := initPeer(channelID)
   785  	if err != nil {
   786  		t.Fail()
   787  		t.Logf("Error creating peer: %s", err)
   788  	}
   789  	defer cleanup()
   790  
   791  	polMgr := &mock.PolicyManager{}
   792  	mockPolicy := &mock.Policy{}
   793  	mockPolicy.EvaluateIdentitiesReturns(nil)
   794  	mockPolicy.EvaluateSignedDataReturns(nil)
   795  	polMgr.GetPolicyReturns(mockPolicy, true)
   796  	capabilities := &mock.ApplicationCapabilities{}
   797  	config := &mock.ApplicationConfig{}
   798  	config.CapabilitiesReturns(capabilities)
   799  	resources := &mock.Resources{}
   800  	resources.PolicyManagerReturns(polMgr)
   801  	resources.ApplicationConfigReturns(config, true)
   802  
   803  	peer.CreateMockChannel(chaincodeSupport.Peer, channelID, resources)
   804  
   805  	ml.ChaincodeEndorsementInfoStub = func(_, name string, _ ledger.SimpleQueryExecutor) (*lifecycle.ChaincodeEndorsementInfo, error) {
   806  		switch name {
   807  		case "lscc":
   808  			return &lifecycle.ChaincodeEndorsementInfo{
   809  				ChaincodeID: "lscc.syscc",
   810  			}, nil
   811  		default:
   812  			return &lifecycle.ChaincodeEndorsementInfo{
   813  				ChaincodeID: name + ":0",
   814  			}, nil
   815  		}
   816  	}
   817  
   818  	// Deploy first chaincode
   819  	cID1 := &pb.ChaincodeID{Name: "example02", Path: chaincodeExample02GolangPath, Version: "0"}
   820  	f := "init"
   821  	args := util.ToChaincodeArgs(f, "a", "100", "b", "200")
   822  
   823  	spec1 := &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID1, Input: &pb.ChaincodeInput{Args: args}}
   824  
   825  	ccContext1 := &CCContext{
   826  		Name:    "example02",
   827  		Version: "0",
   828  	}
   829  
   830  	var nextBlockNumber uint64 = 1
   831  	defer chaincodeSupport.Runtime.Stop(cID1.Name + ":" + cID1.Version)
   832  
   833  	_, err = deploy(channelID, ccContext1, spec1, nextBlockNumber, chaincodeSupport)
   834  	nextBlockNumber++
   835  	ccID1 := spec1.ChaincodeId.Name
   836  	if err != nil {
   837  		t.Fail()
   838  		t.Logf("Error initializing chaincode %s(%s)", ccID1, err)
   839  		return
   840  	}
   841  
   842  	time.Sleep(time.Second)
   843  
   844  	// Deploy second chaincode
   845  	cID2 := &pb.ChaincodeID{Name: "pthru", Path: chaincodePassthruGolangPath, Version: "0"}
   846  	f = "init"
   847  	args = util.ToChaincodeArgs(f)
   848  
   849  	spec2 := &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID2, Input: &pb.ChaincodeInput{Args: args}}
   850  
   851  	ccContext2 := &CCContext{
   852  		Name:    "pthru",
   853  		Version: "0",
   854  	}
   855  
   856  	defer chaincodeSupport.Runtime.Stop(cID2.Name + ":" + cID2.Version)
   857  	_, err = deploy(channelID, ccContext2, spec2, nextBlockNumber, chaincodeSupport)
   858  	nextBlockNumber++
   859  	ccID2 := spec2.ChaincodeId.Name
   860  	if err != nil {
   861  		t.Fail()
   862  		t.Logf("Error initializing chaincode %s(%s)", ccID2, err)
   863  		return
   864  	}
   865  
   866  	time.Sleep(time.Second)
   867  
   868  	// Invoke second chaincode, which will inturn invoke the first chaincode but pass bad params
   869  	f = ccID1
   870  	args = util.ToChaincodeArgs(f, "invoke", "a", "")
   871  
   872  	spec2 = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID2, Input: &pb.ChaincodeInput{Args: args}}
   873  	// Invoke chaincode
   874  	_, _, _, err = invoke(channelID, spec2, nextBlockNumber, []byte("Alice"), chaincodeSupport)
   875  
   876  	if err == nil {
   877  		t.Fail()
   878  		t.Logf("Error invoking <%s>: %s", ccID2, err)
   879  		return
   880  	}
   881  
   882  	if !strings.Contains(err.Error(), "Incorrect number of arguments. Expecting 3") {
   883  		t.Fail()
   884  		t.Logf("Unexpected error %s", err)
   885  		return
   886  	}
   887  }
   888  
   889  func TestChaincodeInit(t *testing.T) {
   890  	channelID := "testchannelid"
   891  
   892  	_, _, chaincodeSupport, cleanup, err := initPeer(channelID)
   893  	if err != nil {
   894  		t.Fail()
   895  		t.Logf("Error creating peer: %s", err)
   896  	}
   897  
   898  	defer cleanup()
   899  
   900  	config := &mock.ApplicationConfig{}
   901  	config.CapabilitiesReturns(&mock.ApplicationCapabilities{})
   902  	resources := &mock.Resources{}
   903  	resources.ApplicationConfigReturns(config, true)
   904  	peer.CreateMockChannel(chaincodeSupport.Peer, channelID, resources)
   905  
   906  	url := "github.com/hyperledger/fabric/core/chaincode/testdata/src/chaincodes/init_private_data"
   907  	cID := &pb.ChaincodeID{Name: "init_pvtdata", Path: url, Version: "0"}
   908  
   909  	f := "init"
   910  	args := util.ToChaincodeArgs(f)
   911  
   912  	spec := &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: args}}
   913  
   914  	ccContext := &CCContext{
   915  		Name:    "init_pvtdata",
   916  		Version: "0",
   917  	}
   918  
   919  	defer chaincodeSupport.Runtime.Stop(cID.Name + ":" + cID.Version)
   920  
   921  	var nextBlockNumber uint64 = 1
   922  	_, err = deploy(channelID, ccContext, spec, nextBlockNumber, chaincodeSupport)
   923  	assert.Contains(t, err.Error(), "private data APIs are not allowed in chaincode Init")
   924  
   925  	url = "github.com/hyperledger/fabric/core/chaincode/testdata/src/chaincodes/init_public_data"
   926  	cID = &pb.ChaincodeID{Name: "init_public_data", Path: url, Version: "0"}
   927  
   928  	f = "init"
   929  	args = util.ToChaincodeArgs(f)
   930  
   931  	spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: args}}
   932  
   933  	ccContext = &CCContext{
   934  		Name:    "init_public_data",
   935  		Version: "0",
   936  	}
   937  
   938  	defer chaincodeSupport.Runtime.Stop(cID.Name + ":" + cID.Version)
   939  
   940  	resp, err := deploy(channelID, ccContext, spec, nextBlockNumber, chaincodeSupport)
   941  	assert.NoError(t, err)
   942  	// why response status is defined as int32 when the status codes are
   943  	// defined as int (i.e., constant)
   944  	assert.Equal(t, int32(shim.OK), resp.Status)
   945  }
   946  
   947  // Test the invocation of a transaction.
   948  func TestQueries(t *testing.T) {
   949  	// Allow queries test alone so that end to end test can be performed. It takes less than 5 seconds.
   950  	//testForSkip(t)
   951  
   952  	channelID := "testchannelid"
   953  
   954  	_, _, chaincodeSupport, cleanup, err := initPeer(channelID)
   955  	if err != nil {
   956  		t.Fail()
   957  		t.Logf("Error creating peer: %s", err)
   958  	}
   959  
   960  	defer cleanup()
   961  
   962  	config := &mock.ApplicationConfig{}
   963  	config.CapabilitiesReturns(&mock.ApplicationCapabilities{})
   964  	resources := &mock.Resources{}
   965  	resources.ApplicationConfigReturns(config, true)
   966  	peer.CreateMockChannel(chaincodeSupport.Peer, channelID, resources)
   967  
   968  	url := "github.com/hyperledger/fabric/core/chaincode/testdata/src/chaincodes/map"
   969  	cID := &pb.ChaincodeID{Name: "tmap", Path: url, Version: "0"}
   970  
   971  	f := "init"
   972  	args := util.ToChaincodeArgs(f)
   973  
   974  	spec := &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: args}}
   975  
   976  	ccContext := &CCContext{
   977  		Name:    "tmap",
   978  		Version: "0",
   979  	}
   980  
   981  	defer chaincodeSupport.Runtime.Stop(cID.Name + ":" + cID.Version)
   982  
   983  	var nextBlockNumber uint64 = 1
   984  	_, err = deploy(channelID, ccContext, spec, nextBlockNumber, chaincodeSupport)
   985  	nextBlockNumber++
   986  	ccID := spec.ChaincodeId.Name
   987  	if err != nil {
   988  		t.Fail()
   989  		t.Logf("Error initializing chaincode %s(%s)", ccID, err)
   990  		return
   991  	}
   992  
   993  	var keys []interface{}
   994  	// Add 101 marbles for testing range queries and rich queries (for capable ledgers)
   995  	// The tests will test both range and rich queries and queries with query limits
   996  	for i := 1; i <= 101; i++ {
   997  		f = "put"
   998  
   999  		// 51 owned by tom, 50 by jerry
  1000  		owner := "tom"
  1001  		if i%2 == 0 {
  1002  			owner = "jerry"
  1003  		}
  1004  
  1005  		// one marble color is red, 100 are blue
  1006  		color := "blue"
  1007  		if i == 12 {
  1008  			color = "red"
  1009  		}
  1010  
  1011  		key := fmt.Sprintf("marble%03d", i)
  1012  		argsString := fmt.Sprintf("{\"docType\":\"marble\",\"name\":\"%s\",\"color\":\"%s\",\"size\":35,\"owner\":\"%s\"}", key, color, owner)
  1013  		args = util.ToChaincodeArgs(f, key, argsString)
  1014  		spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: args}}
  1015  		_, _, _, err = invoke(channelID, spec, nextBlockNumber, nil, chaincodeSupport)
  1016  		nextBlockNumber++
  1017  
  1018  		if err != nil {
  1019  			t.Fail()
  1020  			t.Logf("Error invoking <%s>: %s", ccID, err)
  1021  			return
  1022  		}
  1023  
  1024  	}
  1025  
  1026  	//The following range query for "marble001" to "marble011" should return 10 marbles
  1027  	f = "keys"
  1028  	args = util.ToChaincodeArgs(f, "marble001", "marble011")
  1029  
  1030  	spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: args}}
  1031  	_, _, retval, err := invoke(channelID, spec, nextBlockNumber, nil, chaincodeSupport)
  1032  	nextBlockNumber++
  1033  	if err != nil {
  1034  		t.Fail()
  1035  		t.Logf("Error invoking <%s>: %s", ccID, err)
  1036  		return
  1037  	}
  1038  
  1039  	err = json.Unmarshal(retval, &keys)
  1040  	assert.NoError(t, err)
  1041  	if len(keys) != 10 {
  1042  		t.Fail()
  1043  		t.Logf("Error detected with the range query, should have returned 10 but returned %v", len(keys))
  1044  		return
  1045  	}
  1046  
  1047  	//FAB-1163- The following range query should timeout and produce an error
  1048  	//the peer should handle this gracefully and not die
  1049  
  1050  	//save the original timeout and set a new timeout of 1 sec
  1051  	origTimeout := chaincodeSupport.ExecuteTimeout
  1052  	chaincodeSupport.ExecuteTimeout = time.Duration(1) * time.Second
  1053  
  1054  	//chaincode to sleep for 2 secs with timeout 1
  1055  	args = util.ToChaincodeArgs(f, "marble001", "marble002", "2000")
  1056  
  1057  	spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: args}}
  1058  	_, _, _, err = invoke(channelID, spec, nextBlockNumber, nil, chaincodeSupport)
  1059  	if err == nil {
  1060  		t.Fail()
  1061  		t.Logf("expected timeout error but succeeded")
  1062  		return
  1063  	}
  1064  
  1065  	//restore timeout
  1066  	chaincodeSupport.ExecuteTimeout = origTimeout
  1067  
  1068  	// querying for all marbles will return 101 marbles
  1069  	// this query should return exactly 101 results (one call to Next())
  1070  	//The following range query for "marble001" to "marble102" should return 101 marbles
  1071  	f = "keys"
  1072  	args = util.ToChaincodeArgs(f, "marble001", "marble102")
  1073  
  1074  	spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: args}}
  1075  	_, _, retval, err = invoke(channelID, spec, nextBlockNumber, nil, chaincodeSupport)
  1076  	nextBlockNumber++
  1077  	if err != nil {
  1078  		t.Fail()
  1079  		t.Logf("Error invoking <%s>: %s", ccID, err)
  1080  		return
  1081  	}
  1082  
  1083  	//unmarshal the results
  1084  	err = json.Unmarshal(retval, &keys)
  1085  	assert.NoError(t, err)
  1086  
  1087  	//check to see if there are 101 values
  1088  	//default query limit of 10000 is used, this query is effectively unlimited
  1089  	if len(keys) != 101 {
  1090  		t.Fail()
  1091  		t.Logf("Error detected with the range query, should have returned 101 but returned %v", len(keys))
  1092  		return
  1093  	}
  1094  
  1095  	// querying for all simple key. This query should return exactly 101 simple keys (one
  1096  	// call to Next()) no composite keys.
  1097  	//The following open ended range query for "" to "" should return 101 marbles
  1098  	f = "keys"
  1099  	args = util.ToChaincodeArgs(f, "", "")
  1100  
  1101  	spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: args}}
  1102  	_, _, retval, err = invoke(channelID, spec, nextBlockNumber, nil, chaincodeSupport)
  1103  	nextBlockNumber++
  1104  	if err != nil {
  1105  		t.Fail()
  1106  		t.Logf("Error invoking <%s>: %s", ccID, err)
  1107  		return
  1108  	}
  1109  
  1110  	//unmarshal the results
  1111  	err = json.Unmarshal(retval, &keys)
  1112  	assert.NoError(t, err)
  1113  
  1114  	//check to see if there are 101 values
  1115  	//default query limit of 10000 is used, this query is effectively unlimited
  1116  	if len(keys) != 101 {
  1117  		t.Fail()
  1118  		t.Logf("Error detected with the range query, should have returned 101 but returned %v", len(keys))
  1119  		return
  1120  	}
  1121  
  1122  	type PageResponse struct {
  1123  		Bookmark string   `json:"bookmark"`
  1124  		Keys     []string `json:"keys"`
  1125  	}
  1126  
  1127  	//The following range query for "marble001" to "marble011" should return 10 marbles, in pages of 2
  1128  	f = "keysByPage"
  1129  	args = util.ToChaincodeArgs(f, "marble001", "marble011", "2", "")
  1130  
  1131  	spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: args}}
  1132  	_, _, retval, err = invoke(channelID, spec, nextBlockNumber, nil, chaincodeSupport)
  1133  	nextBlockNumber++
  1134  	if err != nil {
  1135  		t.Fail()
  1136  		t.Logf("Error invoking <%s>: %s", ccID, err)
  1137  		return
  1138  	}
  1139  	queryPage := &PageResponse{}
  1140  
  1141  	json.Unmarshal(retval, &queryPage)
  1142  
  1143  	expectedResult := []string{"marble001", "marble002"}
  1144  
  1145  	if !reflect.DeepEqual(expectedResult, queryPage.Keys) {
  1146  		t.Fail()
  1147  		t.Logf("Error detected with the paginated range query. Returned: %v  should have returned: %v", queryPage.Keys, expectedResult)
  1148  		return
  1149  	}
  1150  
  1151  	// query for the next page
  1152  	args = util.ToChaincodeArgs(f, "marble001", "marble011", "2", queryPage.Bookmark)
  1153  	spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: args}}
  1154  	_, _, retval, err = invoke(channelID, spec, nextBlockNumber, nil, chaincodeSupport)
  1155  	nextBlockNumber++
  1156  	if err != nil {
  1157  		t.Fail()
  1158  		t.Logf("Error invoking <%s>: %s", ccID, err)
  1159  		return
  1160  	}
  1161  
  1162  	json.Unmarshal(retval, &queryPage)
  1163  
  1164  	expectedResult = []string{"marble003", "marble004"}
  1165  
  1166  	if !reflect.DeepEqual(expectedResult, queryPage.Keys) {
  1167  		t.Fail()
  1168  		t.Logf("Error detected with the paginated range query second page. Returned: %v  should have returned: %v    %v", queryPage.Keys, expectedResult, queryPage.Bookmark)
  1169  		return
  1170  	}
  1171  
  1172  	// modifications for history query
  1173  	f = "put"
  1174  	args = util.ToChaincodeArgs(f, "marble012", "{\"docType\":\"marble\",\"name\":\"marble012\",\"color\":\"red\",\"size\":30,\"owner\":\"jerry\"}")
  1175  	spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: args}}
  1176  	_, _, _, err = invoke(channelID, spec, nextBlockNumber, nil, chaincodeSupport)
  1177  	nextBlockNumber++
  1178  	if err != nil {
  1179  		t.Fail()
  1180  		t.Logf("Error invoking <%s>: %s", ccID, err)
  1181  		return
  1182  	}
  1183  
  1184  	f = "put"
  1185  	args = util.ToChaincodeArgs(f, "marble012", "{\"docType\":\"marble\",\"name\":\"marble012\",\"color\":\"red\",\"size\":30,\"owner\":\"jerry\"}")
  1186  	spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: args}}
  1187  	_, _, _, err = invoke(channelID, spec, nextBlockNumber, nil, chaincodeSupport)
  1188  	nextBlockNumber++
  1189  	if err != nil {
  1190  		t.Fail()
  1191  		t.Logf("Error invoking <%s>: %s", ccID, err)
  1192  		return
  1193  	}
  1194  
  1195  	//The following history query for "marble12" should return 3 records
  1196  	f = "history"
  1197  	args = util.ToChaincodeArgs(f, "marble012")
  1198  	spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: args}}
  1199  	_, _, retval, err = invoke(channelID, spec, nextBlockNumber, nil, chaincodeSupport)
  1200  	nextBlockNumber++
  1201  	if err != nil {
  1202  		t.Fail()
  1203  		t.Logf("Error invoking <%s>: %s", ccID, err)
  1204  		return
  1205  	}
  1206  
  1207  	var history []interface{}
  1208  	err = json.Unmarshal(retval, &history)
  1209  	assert.NoError(t, err)
  1210  	if len(history) != 3 {
  1211  		t.Fail()
  1212  		t.Logf("Error detected with the history query, should have returned 3 but returned %v", len(history))
  1213  		return
  1214  	}
  1215  }
  1216  
  1217  func TestMain(m *testing.M) {
  1218  	var err error
  1219  
  1220  	msptesttools.LoadMSPSetupForTesting()
  1221  	cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
  1222  	if err != nil {
  1223  		fmt.Printf("Initialize cryptoProvider bccsp failed: %s", err)
  1224  		os.Exit(-1)
  1225  		return
  1226  	}
  1227  	signer, err = mspmgmt.GetLocalMSP(cryptoProvider).GetDefaultSigningIdentity()
  1228  	if err != nil {
  1229  		fmt.Print("Could not initialize msp/signer")
  1230  		os.Exit(-1)
  1231  		return
  1232  	}
  1233  
  1234  	setupTestConfig()
  1235  	flogging.ActivateSpec("chaincode=debug")
  1236  	os.Exit(m.Run())
  1237  }
  1238  
  1239  func setupTestConfig() {
  1240  	flag.Parse()
  1241  
  1242  	// Now set the configuration file
  1243  	viper.SetEnvPrefix("CORE")
  1244  	viper.AutomaticEnv()
  1245  	replacer := strings.NewReplacer(".", "_")
  1246  	viper.SetEnvKeyReplacer(replacer)
  1247  	viper.SetConfigName("chaincodetest") // name of config file (without extension)
  1248  	viper.AddConfigPath("./")            // path to look for the config file in
  1249  	err := viper.ReadInConfig()          // Find and read the config file
  1250  	if err != nil {                      // Handle errors reading the config file
  1251  		panic(fmt.Errorf("Fatal error config file: %s \n", err))
  1252  	}
  1253  
  1254  	// Init the BCCSP
  1255  	err = factory.InitFactories(nil)
  1256  	if err != nil {
  1257  		panic(fmt.Errorf("Could not initialize BCCSP Factories [%s]", err))
  1258  	}
  1259  }
  1260  
  1261  func deployChaincode(name string, version string, chaincodeType pb.ChaincodeSpec_Type, path string, args [][]byte, channel string, nextBlockNumber uint64, chaincodeSupport *ChaincodeSupport) (*pb.Response, *CCContext, error) {
  1262  	chaincodeSpec := &pb.ChaincodeSpec{
  1263  		ChaincodeId: &pb.ChaincodeID{
  1264  			Name:    name,
  1265  			Version: version,
  1266  			Path:    path,
  1267  		},
  1268  		Type: chaincodeType,
  1269  		Input: &pb.ChaincodeInput{
  1270  			Args: args,
  1271  		},
  1272  	}
  1273  
  1274  	chaincodeCtx := &CCContext{
  1275  		Name:    name,
  1276  		Version: version,
  1277  	}
  1278  
  1279  	result, err := deploy(channel, chaincodeCtx, chaincodeSpec, nextBlockNumber, chaincodeSupport)
  1280  	if err != nil {
  1281  		return nil, chaincodeCtx, fmt.Errorf("Error deploying <%s:%s>: %s", name, version, err)
  1282  	}
  1283  	return result, chaincodeCtx, nil
  1284  }
  1285  
  1286  var signer msp.SigningIdentity
  1287  
  1288  type CreatorPolicy struct {
  1289  	Creators [][]byte
  1290  }
  1291  
  1292  // EvaluateSignedData takes a set of SignedData and evaluates whether this set of signatures satisfies the policy
  1293  func (c *CreatorPolicy) EvaluateSignedData(signatureSet []*protoutil.SignedData) error {
  1294  	for _, value := range c.Creators {
  1295  		if bytes.Equal(signatureSet[0].Identity, value) {
  1296  			return nil
  1297  		}
  1298  	}
  1299  	return fmt.Errorf("Creator not recognized [%s]", string(signatureSet[0].Identity))
  1300  }
  1301  
  1302  // EvaluateIdentities takes an array of identities and evaluates whether
  1303  // they satisfy the policy
  1304  func (c *CreatorPolicy) EvaluateIdentities(identities []msp.Identity) error {
  1305  	return nil
  1306  }
  1307  
  1308  func newPolicyChecker(peerInstance *peer.Peer) policy.PolicyChecker {
  1309  	return policy.NewPolicyChecker(
  1310  		policies.PolicyManagerGetterFunc(peerInstance.GetPolicyManager),
  1311  		&policymocks.MockIdentityDeserializer{
  1312  			Identity: []byte("Admin"),
  1313  			Msg:      []byte("msg1"),
  1314  		},
  1315  		&policymocks.MockMSPPrincipalGetter{Principal: []byte("Admin")},
  1316  	)
  1317  }